FLTK logo

Re: [fltk.coredev] Insomnia, Fl_Flex, and resizable

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.coredev  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: Insomnia, Fl_Flex, and resizable Albrecht Schlosser Oct 26, 2022  
 
On 10/26/22 12:21 'melcher....@googlemail.com' via fltk.coredev wrote:
tl;dr Proposal to add Fl_Widget::resizable(int width_factor, int height_factor) and merge Fl_Flex into Fl_Pack.

I was looking into how Fl_Flex differs from Fl_Pack, and apart from the margins, Fl_Flex adds the option the make individual children resizable while the rest stays fixed. So instead of introducing a new widget, wouldn't it be better to add this functionality to Fl_Pack?

No. Fl_Pack has some properties that differ from Fl_Flex and all other widgets and groups: Fl_Pack "shrink-wraps" itself around its children, and it does this during its draw() method which leads to all sorts of unexpected behavior. You can't really say that an Fl_Pack has a pre-determined size because of this "feature".

Fl_Pack also uses the resizable() widget in a very special way that is not used elsewhere and leads to unpredictable behavior, particularly in nested Fl_Pack widgets.

Fl_Flex is a better alternative to Fl_Pack because it doesn't have all these IMHO negative properties. You can give it a specific size and it fills its space with its children. The *standard* behavior is "flexible", i.e. all children adjust their sizes to the available space, not vice versa. The *exception* is to give some widgets a fixed size for special layout options.

If we could choose I would remove Fl_Pack and use Fl_Flex instead as the new "Fl_Pack" widget. However, changing Fl_Pack is not an option, and that's why I "ported" the existing Fl_Flex widget to FLTK as an alternative and Fl_Pack should be considered deprecated. The design and API of Fl_Flex have in parts been chosen such that it can be used as a drop-in replacement of Fl_Pack without Fl_Pack's problems. Hopefully.

Fl_Pack may be used in existing programs, and therefore we should keep it as is to avoid backwards compatibility issues.

Which brings me to the second point. Fl_Group::resizable(Fl_Widget*) is a horrible interface. First of all, we reference a child widget, wich may disappear, giving us a dangling pointer. Second of all, we can only have one resizable child, which generated the need for Fl_Flex.

Yep, maybe. But that's not a bug, it's a "feature" since FLTK 1.0, isn't it? And it works...

Now, Fl_Flex maintains a list of children that are resizable, and the list is not updated if children are removed because Fl_Group::remove() and clear() are not virtual (delete_child() is, but that is not enough). Again, we get dangling pointers.

That's true, as it is now, and it is a known problem. I have been working on a general solution to be applied to Fl_Group and inherited by Fl_Flex and other derived widget to overcome this issue. Unfortunately helping to get the Wayland support working distracted me and this work was not yet applied to Fl_Flex although it's almost ready.

My proposal is to remove Fl_Group::resizable_ and instead add either a flag or an integer to Fl_Widget to indicate if the widget is resizable (flag) or even better, by what factor a widget is resizable (int). Adding the functionality of Fl_Flex to Fl_Pack would be ten lines of code.

I strongly recommend NOT to change Fl_Pack at all. As said above, leave it as is for backwards compatibility and get rid of its odd behavior for new development.

Fl_Group::resizable(Fl_Widget*) could be implemented with the exact same API and functionality, but without the risk of dangling pointers.

Fl_Group does already "know about" deleted widgets and if it doesn't take the deletion of the resizable() widget into account that is probably a bug. It would be easy to do this, however the decision would be harder: what should be done?

Option one: set resizable(0) which would make the Fl_Group widget no longer reiszable.

Option two: set resizable(this) seems the more appropriate option which would leave the group resizable.


I suggest to discuss options to implement a feature to observe widget deletion in a separate thread. I'd like to see your (and others') comments on my proposal and we should find a proper way

Since the resizable() method name is already taken, we need a new method name. We could use Fl_Widget::flexible(bool), but how about Fl_Widget::resizable(int width, int height) where width and height are factors in the given direction. It's a bit of a stretch, as Fl_Group::resizable(child) would be the same as child->resizable(100, 100), but it can't all be perfect. This would add two integers, eight bytes, to every Fl_Widget, and remove one pointer from Fl_Group and more pointers from Fl_Pack/Fl_Flex.

If we had both these features, i.e. Fl_Group::resizable(Fl_Widget *) and Fl_Widget::resizable(...) then we would likely have a contradiction if both is given. Which one would determine the resizing algorithm of the group? I don't see (at a first glance) how this could be resolved - and it would make the resizing algorithm even more complicated. Note that neither Fl_Flex nor Fl_Grid (see below) use the resizable() widget (it's entirely ignored).

That said, besides Fl_Flex I'm still working on Fl_Grid which provides even more flexibility to the resizing of widgets inside the grid container. It's like a two-dimensional Fl_Flex or HTML <table> with options of overlapping widgets like HTML `colspan` and `rowspan` attributes. This Fl_Grid widget is also on the "Release 1.4.0" milestone and almost ready to go.

I'm sure I can resolve the "dangling pointers" issue in both widgets - and in some other core widgets. My proposal would be usable in derived classes as well. @Matthias: I sent you a proposal a while ago but I changed it meanwhile a little bit. The basics are the same though.

Many users have requested better layout widgets, and Fl_Flex has even already been integrated in fltk-rs (Rust bindings for FLTK).

Summary (my conclusion):

Fl_Flex and Fl_Grid provide the requested better layout widgets w/o touching the "standard" FLTK resizing algorithm and should be added because they are really needed. Touching Fl_Pack would open a can of worms and should be avoided.

Everything else can and should be discussed after the release of FLTK 1.4.0.

--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/5ab5e3a1-aaa9-1df6-4d51-3cb50837f676%40online.de.
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.