Understanding Widget Damage in FLTK - rust

Because I'm unsatisfied with the styling of fltk's built in Scroll group, I would like to create my own scroll group component , with similar functionality. Reading over the source code for FL_Scroll, I
gather that the process of "masking out" unneeded parts of the scroll groups children involves using fltk's damage functionality. I'm finding widget damage a difficult concept to understand. It seems like it relates to the way widgets are drawn, but I don't understand how it can be used to selectively draw parts of a widget.
Based on the fltk-rs docs for WidgetExt::set_damage() and WidgetExt::damage(), it seems like damaged is some kind of on/off state, like set_resizeable().
Yet in the FLTK docs I see this definition:
When redrawing your widgets you should look at the damage bits to see what parts of your widget need redrawing.
The handle() method can then set individual damage bits to limit the amount of drawing that needs to be done:
MyClass::handle(int event) {
...
if (change_to_part1) damage(1);
if (change_to_part2) damage(2);
if (change_to_part3) damage(4);
}
MyClass::draw() {
if (damage() & fltk::DAMAGE_ALL) {
... draw frame/box and other static stuff ...
}
if (damage() & (fltk::DAMAGE_ALL | 1)) draw_part1();
if (damage() & (fltk::DAMAGE_ALL | 2)) draw_part2();
if (damage() & (fltk::DAMAGE_ALL | 4)) draw_part3();
}
This description makes it seem like widget damage is referring to some kind of array of byte data about the widgets. I'm guessing for the scroll group,
you just want to draw the byte data within the scroll group's area. But where is this byte data stored? How can one access it? What does damage have to do with this data?

Related

Is there a `HVBoxContainer` for Godot?

Think of an RPG game where you might need to present a list of buttons. A user might enter a room where they have to select from a series of options (buttons). Is there a type of container/panel that would show clickable buttons horizontally, but wrap if needed?
The best analogy I can think of to picture the situation is, Imagine needing to click on an item in a backpack, but each item is potentially a different width. (I can make them all the same height but the width then varies)
.---[My Backpack]------.
| aaa bbb cccc ddd |
| ee fff g |
| |
| |
`----------------------'
(The options come from a database, so its unknown at compile time how many options might be in a room, so I am going to need to programmatically add options.)
The very bottom of this godot document introduces custom container layouts, but it's unclear to me how this would work in practice
Flow container for Godot 3.5 or newer
Godot 3.5 (currently in beta) introduces HFlowContainer and VFlowContainer that will serve the propuse described.
The HFlowContainer will fill a row and when they overflow, it will add a new row and continue there. The VFlowContainer will work on a similar fashion but with columns.
Flow containers before Godot 3.5
For older versions of Godot you can use the HFlowContainer addon which you can find it in the asset library (here). Note that there is no VFlowContainer counterpart.
As everything on the asset library it is free and open source, so feel free to read the code and modify it, which can be serve as starting point if you want to make your own custom Container.
Making your own custom Container
The gist of making a custom Container is that it must position its children.
For that effect you react to NOTIFICATION_SORT_CHILDREN in the _notification method. You might also want to react to NOTIFICATION_RESIZED.
You can have a method - which I'll call layout - that you call when you get the notifications:
func _notification(what):
if what == NOTIFICATION_SORT_CHILDREN:
layout()
And also call layout from the setters (setget) of the properties that define how the Container must organize its children. To call layout from anywhere other than _notification, you might want to use call_deferred("layout") to prevent any possible re-layout loops from hanging or crashing the game.
The layout method would iterate over the visible children Controls and use get_combined_minimum_size to figure out their size.
Something like this:
func layout() -> void:
# …
for child in get_children():
var control := child as Control
if not is_instance_valid(control) or not control.visible:
continue
var size := control.get_combined_minimum_size()
# …
Then using that information compute the position and size for the children Controls. When there is room for the Controls to grow, you may want to split it among them according to their size_flags_stretch_ratio.
Once you have the position and size for a Control decided, use fit_child_in_rect to position them, which will take into account grow and size flags.
Thus - barring the simplest Containers - you will need to iterate over the children Controls twice. And for that you might find useful to have an auxiliary data structure to temporarily store them.

Hide/Show of Amcharts bullets doesn't work

I'm using amcharts4 to create large data charts (XY). I want to include two different types of bullets in it. Then these different types shall be switched on/off by the user. I managed to switch off, but not on again.
As my real usecase loads a lot(!) of data, I implemented the bullets in an unusual way to keep performance up: The bullets are disabled and then enabled with propertyfield.disabled.
var smallBullet11 = series1.bullets.push(new am4charts.LabelBullet());
smallBullet11.disabled = true;
smallBullet11.propertyFields.disabled = "hideBullet1";
As a result I can hide, but later on not show the bullets again.
Here is the full example: https://jsfiddle.net/9uwgp85s/
Click on "Hide X-Bullets" first (will work) and then "Show X-Bullets" (won't work).
Has anyone an idea how to switch the bullets on again?
Thanks for any hint!
You'll need to call show/hide on the individual bullets, for example:
function hidebullets() {
smallBullet11.clones.each(function(bullet) {
bullet.hide();
});
}
function showbullets() {
smallBullet11.clones.each(function(bullet) {
bullet.show();
});
}
You might also find the minBulletDistance property helpful in improving performance on a line chart with a ton of bullets. It allows you to specify a minimum distance between each point before a bullet is drawn; the larger the distance, the fewer the bullets that will get drawn until you zoom in. You can find more performance tips like this one here.

iPhone SDK building an Omnigraffle like app

I have been trying to find an example or some hints on how to create an app that I could drag, resize, rotate images onto a UIView and then save the individual pieces (including their size, rotation and placement) and the entire UIView into CoreData. Kind of like the omnigraffle app.
Any tutorials, examples or anything on any piece of the app would be greatly appreciated.
for dragging a view
http://www.cocoacontrols.com/platforms/ios/controls/tkdragview
for roting a view http://www.cocoacontrols.com/platforms/ios/controls/ktonefingerrotationgesturerecognizer
for resizing a view
http://www.cocoacontrols.com/platforms/ios/controls/spuserresizableview
What respects to core data, its actually pretty straightforward just, gather the classes in one view, see the properties you need to save, and the new one you will need for your app and thats it.
Like:
Object Canvas containing a many relationship to morphlingViews wich contain all the properties as center, color, width, height, angle, UIPath (if you plan to create custom shapes) layer position (so it gets drawn correctly) and if you plan to connect the views as omnigraffle add a many realtionship to self (in morphlingViews) so you can take the center of different morphlingViews and add a simple line between them. (and a string if you plan to add drawInRect method to allow users to write in the objects, then it will be a good idea to add the text properties as well).
You can also add Quartz Composer drawing styles properties to the object, as shadow, shadowColor, shadowOffset, or add patterColor to add resizable background.

How should I go about making game menus that I want to fit inside a container?

I have to write an XNA game for a project in my college program. I'm making a turn-based RPG in the vein of the Gameboy Pokemon games. I'd like to align the menu options with a container at the bottom of the screen, with never more than 4 options. This should give you a rough idea about how I want the combat screen to look:
I currently have a menu system that aligns all the menu items with the center of the screen, meaning menus end up looking like this:
Start Game
Options
Quit
but in the center of the screen.
What is the best way to position the menu items in a similar fashion to the image above? Should I hardcode in the positions for the menu items, should I try and make some kind of class to act as the container for these items and have their position be relative to the size and position of the container, or use some other method?
If you don't want to hardcode the positions it could get pretty complex, depending on how much flexibility you want.
I would create a container class which is part of a tree structure, (see scene graph), with a parent container and a list of child containers. That is the most common way of handling relative positioning. Here a quick example:
public class Container
{
public Container Parent { get; set; }
public List<Container> Children { get; set; }
public Vector2 RelativePosition { get; set; }
public Vector2 AbsolutePosition
{
get
{
// The container is the root node
if (Parent == null)
return RelativePosition;
else
return RelativePosition + Parent.AbsolutePosition;
}
}
}
If you need even more flexibilty you could create a floated layout, where the elements are positioned dynamically depending on their size.
As stated by Lucius, creating a Container class is the best solution.
Currently I'm developing an UI application for the XBox.
Therefor I needed something like a positioning engine, with everything being relative, so I didn't need to calculate pixel stuff everytime.
What I did was creating a Container class, which contains roughly following attributes:
VectorTopLeft (Which the element which contains a Container object uses for drawing)
VectorTopRight
VectorBottomLeft
VectorBottomRight
Align (Enum: Right, Center, Left)
VerticalAlign (Enum: Top, Middle, Bottom)
NewRow (bool)
PreviousContainer (Container)
ParentContainer (Container)
Width (Getter)
Height (Getter)
PercentageHeight (getter/setter) (Percentage of the height of the parent container)
PercentageWidth (getter/setter) (Percentage of the width of the parent container)
PixelHeight (getter/setter) (Absolute height in pixels)
PixelWidth (getter/setter) (Absolute width in pixels)
AspectRatio: Used for setting the width to a ratio of the height, usefull for different screen aspects (4/3 or 16/9 for example)
MarginLeft
MarginRight
MarginTop
MarginBottom
The following vectors include margins, these are vectors used by the alignment procedure.
AbsoluteVectorTopLeft
AbsoluteVectorTopRight
AbsoluteVectorBottomLeft
AbsoluteVectorBottomRight
The following size attributes also include margins, usefull for calculating remaining sizes
AbsoluteWidth (getter)
AbsoluteHeight (getter)
And then some flags which get set to true if something crucial changes, and vectors/size stuff needs to be recalculated.
The alignment stuff is pretty complex, as in the fact that it uses recursion, and also calls previous container functions to shift everything to the right place.
The newrow attribute tells the system that it needs to start the element at a new row in the parent container, and is used for keeping the vertical alignment in mind.
The system might have some minor flaws, but at this moment it works as a charm for all my GUI related positioning stuff, and it works pretty damn fast!

How to know the number of pixels that a String is occupying?

I have an item ( TextField, or TextArea, ...). It has a content value , say "hello world". How to know the number of pixels that this "hello world" String value is occupying on the screen ?
You can get the preferred width/height to get a rough estimation (you would also need to add the margin's to get accurate sizing). However the layout manager views these as guidelines not as final sizes and can decide on placing a component anywhere.
During runtime e.g. paint etc. the getX/Y/Width/Height argument provide accurate component size and position. However, these are only valid for the current paint operation since a device may be rotated or might require layout reflow.
You need to be more specific on what you are trying to accomplish.

Resources