Thanks, I'll look into this as well.
I'd really be interested (and in this case I assume I'm also
speaking for the FLTK Team) to integrate more layout capabilities in
FLTK as has been requested multiple times and especially recently.
Currently we have at least one layout proposal (Fl_Flex) which can
be used similar to Fl_Pack in a horizontal (row) and a vertical
(column) mode. There are also thoughts about adding a grid widget.
Unfortunately Fl_Flex uses std::vector (IIRC, or something similar)
which is incompatible with the FLTK coding style and constraints.
I created two GitHub Issues to reflect this situation:
"Add a flexible row/column container widget"
https://github.com/fltk/fltk/issues/255
"Consider to add a simple grid container widget"
https://github.com/fltk/fltk/issues/256
Your proposal would be able to fill another gap (or maybe replace
one or both?).
That said, thank you very much for offering your code. I looked into
it and I tested it. Here are my results (I apologize for the long
message):
(1) All the template code can be removed easily (I did it in a
minute). It's useless in the code as it is now. Has there been a
reason in another version (maybe in your program)?
(2) I also removed exceptions, but this was more like a quick fix (I
replaced throw with printf). I'd appreciate if you could do this in
your code base (better than my quick fix).
(3) I believe std::vector and std::string are likely harder to
remove, but since you have an old (C89) version it's probably
doable. I'm looking forward to seeing a version that is compatible
with FLTK.
(4) Coding style: there's not much "wrong" with your code. To
simplify a potential conversion I suggest to use `clang-format -i
filename` if your code is inside the FLTK source tree or to copy our
'.clang-format' file to the root of your code tree and use
clang-format as above. This is not "perfect" yet, still work in
progress but pretty well usable.
I noticed that the constructors were rewritten by clang-format in a
questionable way. You may keep yours but I suggest to use
clang-format for everything else, particularly the opening braces
and to assert the correct indenting. That's just a suggestion though
and if you don't have clang-format installed we can certainly do
this before integration into FLTK.
(5) As others said already we need the FLTK license which is LGPL
with exceptions. If you agree we can add our license to your files
for integration.
(6) There are a lot of additional (maybe internal) Fl_Something
classes (structs) in your code. Having everything in one header file
makes these structs publicly available. In the final version this
could probably be avoided by splitting the code in header +
implementation and having the local classes/structs only in the
implementation (.cxx). But that's something to consider later, it's
not important for now.
(7) I'm not sure about the (correct) usage of Fl_Widget_Tracker
though. This class was intended to be used only inside event
handling code that called callbacks so we could know if the user
(callback) code deleted the widget. The class was designed to be a
short-lived local (stack) variable that would automatically be
deleted when it went out of scope.
The reason for this ("short-lived") restriction is that widget
tracking uses a simple list and thus can be very inefficient if many
widgets are watched. I think your code requires something like this
(I didn't actually understand everything yet, I'm still looking and
testing) but before I try to find out all the fine details myself,
can you please explain the exact reasons? Would there be a potential
to access deleted widgets if you didn't use it?
(8) A minor issue in my tests (using FLTK 1.4 on Linux, BTW) was
that your code seems to need at least one actual resize() to be
effective. If you run the (demo) programs as given they don't
position the widgets correctly after the first show(). I used code
like the following to work around this:
win.size(win.w(), win.h()+1);
win.size(win.w(), win.h()-1);
win.show();
Did you see this as well and what is your workaround?
(9) I also noticed strange effects when the window is resized to a
smaller size than required to hold all widgets. Are there any ideas
how to deal with this situation? The following small demo shows the
effect if you resize the window width to less than the button width
or both the width and height to something smaller than necessary.
Suddenly all buttons "jump" to the bottom of the window or hide
behind other buttons. One obvious "solution" is to limit resizing by
setting a size_range().
Example code + screenshot:
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Flow.H>
int main() {
char buf[20];
Fl_Double_Window win(640, 480);
Fl_Flow flow(0, 0, win.w(), win.h());
for (int i = 0; i < 10; i++) {
Fl_Button *but = new Fl_Button(0, 0, 100, 30);
sprintf(buf, "Button %d", i+1);
but->copy_label(buf);
flow.rule(but, "^<");
}
win.resizable(flow);
win.size(win.w(), win.h()+1); // make sure that the "flow"
win.size(win.w(), win.h()-1); // is resized initially
win.show();
return Fl::run();
}
Summary: the functionality is great and could be a real enhancement
for FLTK. If the coding style issues can be resolved I'd like to
include it, i.e. my vote would most likely be +1. Thank you very
much!