Fl_Grid layout widget

101 views
Skip to first unread message

Albrecht Schlosser

unread,
Nov 17, 2021, 5:42:29 PM11/17/21
to fltk.coredev
All, FYI

I started working on Fl_Grid, a new container widget and I have a
working prototype with a minimal set of features.

It's too early to post code (I'll push it to my fork when I made more
progress) but I wanted to let you know.

Please see GitHub issue #256 "Consider to add a simple grid container
widget" for more info:

https://github.com/fltk/fltk/issues/256

with my latest comment and info:

https://github.com/fltk/fltk/issues/256#issuecomment-972163983


The resizing and alignment algorithms are not yet ready, all columns
have the same width and all rows have the same height. This will be
improved in the future.

Features to be implemented: flexible row and column widths, full widget
alignment inside grid cells, and more...

Albrecht Schlosser

unread,
Nov 29, 2021, 4:03:46 PM11/29/21
to fltkc...@googlegroups.com
On 11/17/21 11:42 PM Albrecht Schlosser wrote:
> All, FYI
>
> I started working on Fl_Grid, a new container widget and I have a
> working prototype with a minimal set of features.
>
> It's too early to post code (I'll push it to my fork when I made more
> progress) but I wanted to let you know.

Meanwhile I made good progress but the new widget is not yet feature
complete. Anyway, I wanted to let you know and share the code for
testing. My branch Fl_Grid (
https://github.com/Albrecht-S/fltk/tree/Fl_Grid ) has all the new code
and demo programs (test/grid_*.cxx).

Since we discussed recently about the resizing features of test/cube.cxx
with the center group with fixed size and left and right boxes resizing
symmetrically I created a demo program for such a layout with Fl_Grid,
see https://github.com/Albrecht-S/fltk/blob/Fl_Grid/test/grid_cube.cxx .

Updates will be posted to GitHub Issue #256:
https://github.com/fltk/fltk/issues/256

Test reports will be appreciated and feature requests will be
considered. TIA

Have fun!

Greg Ercolano

unread,
Nov 29, 2021, 6:32:41 PM11/29/21
to fltkc...@googlegroups.com


On 11/29/21 1:03 PM, Albrecht Schlosser wrote:
On 11/17/21 11:42 PM Albrecht Schlosser wrote:

Meanwhile I made good progress but the new widget is not yet feature complete. Anyway, I wanted to let you know and share the code for testing. My branch Fl_Grid ( https://github.com/Albrecht-S/fltk/tree/Fl_Grid ) has all the new code and demo programs (test/grid_*.cxx).

    Would like to suggest before the final commit the OP's copyright/date be added
    to the comment header for the Fl_Grid's .cxx/.H files vis a vis Tree/Table/FNFC, etc.

Albrecht Schlosser

unread,
Nov 29, 2021, 7:33:23 PM11/29/21
to fltkc...@googlegroups.com
Fl_Grid is a new widget written from scratch by me, not one of the widgets posted in fltk.general recently. I deliberately chose to use the standard FLTK copyright "Bill Spitzak and others" but I can also write my own name if you like ;-)

Greg Ercolano

unread,
Nov 29, 2021, 8:18:19 PM11/29/21
to fltkc...@googlegroups.com
    Ya, if you rewrote it, use your name. I think it's good for externally
    contributed projects to have the name of the contributor, esp. if it's
    a signficant work. Even if they're devs.

    And add the OP if your design was inspired by theirs.

    In the case of Fl_Table, credit was given to the Flvw folks in the docs because
    I used their existing Flvw_Table widget as initial inspiration (the MVP design),
    but wrote Fl_Table from scratch.

    I noticed Matthias included my name when he added my widgets (I wasn't a dev at that time),
    and appreciated it. I think Fl_Table and Fl_Input_Choice were my first contributions.



Albrecht Schlosser

unread,
Nov 30, 2021, 5:27:12 PM11/30/21
to fltkc...@googlegroups.com
On 11/29/21 10:03 PM Albrecht Schlosser wrote:
> On 11/17/21 11:42 PM Albrecht Schlosser wrote:
>> I started working on Fl_Grid, a new container widget and I have a
>> working prototype with a minimal set of features.
>>
> Meanwhile I made good progress but the new widget is not yet feature
> complete. Anyway, I wanted to let you know and share the code for
> testing. My branch Fl_Grid (
> https://github.com/Albrecht-S/fltk/tree/Fl_Grid ) has all the new code
> and demo programs (test/grid_*.cxx).
>
> Updates will be posted to GitHub Issue #256:
> https://github.com/fltk/fltk/issues/256
>
> Test reports will be appreciated and feature requests will be
> considered. TIA

Dear fellow developers,

I feel that the time has come to ask you for your votes to include the
new Fl_Grid widget in the FLTK core.

I believe that we have seen enough evidence that this widget is able to
fill a lot of gaps in the classic layout with Fl_Group (at least it can
make things much easier and more comfortable). For instance, the
buttons-with-gaps example was a no-brainer with Fl_Grid. ;-)

I wrote it because the other layout managers I saw so far (Fl_Flex,
Fl_Flow, TableBox from FLTK 2 (Greg's port)) didn't fulfill my
expectations. Maybe Fl_Flex and Fl_Flow can also be integrated for some
special cases but for now I propose to use Fl_Grid.

This would be the (one) long requested "Layout Manager" !

Fl_Grid is still not complete but before I do all the polishing and
complete the code I need confirmation that this work and time would not
be wasted. Hence I ask you to vote for this new widget (or abstain (0)
so we get at least three votes!). I'll complete my work if this vote is
accepted.

I'm attaching the current (incomplete) doxygen docs. Some methods are
not yet documented, but everything written for columns can be used for
rows accordingly, and the methods to set row heights, column widths, and
row or column weights are all similar.

Don't worry about the lot of methods. Many of these are only for some
special cases and conveniency. Most of the features have sensible
default values so simple tasks can be simple.

Examples can be found in my branch Fl_Grid in test/grid_*.cxx. For
instance, test/grid_cube.cxx shows a much simplified layout of FLTK's
test/cube.cxx. Compare its simplicity with test/cube's complexity (I
removed 26 variables that were use to calculate pixel values of the
layout!).


To check my branch out and test it:

$ git clone https://github.com/Albrecht-S/fltk.git fltk_Fl_Grid
Cloning into 'fltk_Fl_Grid'...
remote: Enumerating objects: 76129, done.
remote: Counting objects: 100% (1970/1970), done.
remote: Compressing objects: 100% (1017/1017), done.
remote: Total 76129 (delta 1234), reused 1482 (delta 947), pack-reused 74159
Receiving objects: 100% (76129/76129), 28.43 MiB | 8.75 MiB/s, done.
Resolving deltas: 100% (62210/62210), done.
$ cd fltk_Fl_Grid
fltk_Fl_Grid$ git branch Fl_Grid
fltk_Fl_Grid$

You can now use either configure/make or CMake to build the project and
run the test/grid_* demo programs.

Besides votes all comments, suggestions, RFE's and even requests for API
changes would be appreciated.

Thanks in advance

Fl_Grid-Reference.pdf

Albrecht Schlosser

unread,
Nov 30, 2021, 6:34:30 PM11/30/21
to fltkc...@googlegroups.com
Correction:


On 11/30/21 11:27 PM Albrecht Schlosser wrote:
To check my branch out and test it:

$ git clone https://github.com/Albrecht-S/fltk.git fltk_Fl_Grid
Cloning into 'fltk_Fl_Grid'...
remote: Enumerating objects: 76129, done.
remote: Counting objects: 100% (1970/1970), done.
remote: Compressing objects: 100% (1017/1017), done.
remote: Total 76129 (delta 1234), reused 1482 (delta 947), pack-reused 74159
Receiving objects: 100% (76129/76129), 28.43 MiB | 8.75 MiB/s, done.
Resolving deltas: 100% (62210/62210), done.
$ cd fltk_Fl_Grid
fltk_Fl_Grid$ git branch Fl_Grid
fltk_Fl_Grid$

Sorry, the last statement should read:

fltk_Fl_Grid $ git checkout Fl_Grid
Branch 'Fl_Grid' set up to track remote branch 'Fl_Grid' from 'origin'.
Switched to a new branch 'Fl_Grid'
fltk_Fl_Grid $

Manolo

unread,
Dec 1, 2021, 3:59:12 AM12/1/21
to fltk.coredev
Le mardi 30 novembre 2021 à 23:27:12 UTC+1, Albrecht Schlosser a écrit :
Dear fellow developers,

I feel that the time has come to ask you for your votes to include the
new Fl_Grid widget in the FLTK core.

Besides votes all comments, suggestions, RFE's and even requests for API
changes would be appreciated.
 
After reading the Doxygen doc of Fl_Grid, I would suggest not to use the word "pixels"
therein because it's wrong under macOS on a retina display and everywhere after the GUI was scaled.

The FLTK doc currently uses "FLTK units" to mean that unit used by the FLTK API
which is invariant by GUI scaling operations, and which corresponds to varying pixel numbers:

Manolo

unread,
Dec 1, 2021, 5:03:42 AM12/1/21
to fltk.coredev
Le mardi 30 novembre 2021 à 23:27:12 UTC+1, Albrecht Schlosser a écrit :
Dear fellow developers,

Besides votes all comments, suggestions, RFE's and even requests for API
changes would be appreciated.
==================================
 
Could you, please, describe briefly what, if any, is the use of Fl_Group::resizable() in the
context of the proposed Fl_Grid class ?

Also, is Fl_Grid able to produce all resize behaviours produced by combinations of
nested Fl_Group objects and Fl_Group::resizable() calls ?

Manolo

unread,
Dec 1, 2021, 5:23:18 AM12/1/21
to fltk.coredev
Le mardi 30 novembre 2021 à 23:27:12 UTC+1, Albrecht Schlosser a écrit :
On 11/29/21 10:03 PM Albrecht Schlosser wrote:
Dear fellow developers,

I feel that the time has come to ask you for your votes to include the
new Fl_Grid widget in the FLTK core.


Besides votes all comments, suggestions, RFE's and even requests for API
changes would be appreciated.

Under macOS, the grid_xxx demo programs randomly crash at start.
That's because
    Cols_ = 0; Rows_ = 0;
must be added to the Fl_Grid constructor.

Albrecht Schlosser

unread,
Dec 1, 2021, 6:22:03 AM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 9:59 AM Manolo wrote:
After reading the Doxygen doc of Fl_Grid, I would suggest not to use the word "pixels"
therein because it's wrong under macOS on a retina display and everywhere after the GUI was scaled.

Thanks, point taken, I'll change this. However, I'll probably leave the phrase 'w/o "counting pixels" ' (in quotes) in the docs.

Albrecht Schlosser

unread,
Dec 1, 2021, 6:55:24 AM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 11:03 AM Manolo wrote:
> Could you, please, describe briefly what, if any, is the use of
> Fl_Group::resizable() in the
> context of the proposed Fl_Grid class ?

Short anwer: nothing. Fl_Grid is designed to be resizable as a whole and
has its own resizing rules (widget and column/row sizes and "weights")
which is much more flexible than a single Fl_Group widget. Basically you
can have more than one "resizable" column and row.

You can achieve something at least similar to the Fl_Group::resizable()
child widget if you set only one column's and one row's weight to a
non-zero value (or more than one adjacent rows/columns). But Fl_Grid can
do much more, for instance the "button row with two resizing gaps" in a
single Fl_Grid widget whereas you'd need complex Fl_Group nesting to
achieve the same. See my test/grid_buttons.cxx example vs. Ian's example
in fltk.general.

> Also, is Fl_Grid able to produce all resize behaviours produced by
> combinations of
> nested Fl_Group objects and Fl_Group::resizable() calls ?

This question is a difficult to answer. First of all, this is not the
goal of Fl_Grid, but Fl_Grid can be combined (nested) with "classic"
Fl_Group widgets and with Fl_Grid's. The example test/grid_cube.cxx
demonstrates this: I used a normal Fl_Group for the control buttons and
sliders in the center column of the Fl_Grid with the same slider as
resizable() widget as in the "classic" test/cube.cxx demo. However, I
could also have chosen to use an Fl_Grid as the inner group.

Even in this example it's (IMHO) obvious that the Fl_Grid as the main
container has the advantage that the x/y coordinates of the inner
Fl_Group widget are relative to the group rather than to the window
which makes designing and eventually moving nested groups much easier.

Fl_Grid is one tool and it is particularly powerful if your overall
widget design can be arranged in a grid which is very often the case.
You can have widgets spanning multiple columns and rows like in a HTML
<table> but if your widgets overlap in a chaos w/o a clear structure
then Fl_Grid wouldn't be the right tool (use Fl_Group instead).

Fl_Grid is not a replacement of Fl_Group. It has its own purpose like
Fl_Pack, Fl_Flex, Fl_Flow and other special purpose container widgets.
It can simplify the design of the GUI because you don't need to position
the members exactly at "FLTK units" relative to the window. You can use
rows and columns instead.

Side note: I was tempted to "redesign" the test/device.cxx example
program with Fl_Grid but this would have been too much work just for
testing although I believe it's trivial. Maybe I'll try it later or once
Fl_Grid is in the official FLTK repo.

Albrecht Schlosser

unread,
Dec 1, 2021, 6:59:35 AM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 11:23 AM Manolo wrote:
Under macOS, the grid_xxx demo programs randomly crash at start.
That's because
    Cols_ = 0; Rows_ = 0;
must be added to the Fl_Grid constructor.

Thanks, the Rows_ and Cols_ arrays were a later addition and I obviously forgot this.

The entire code is still in pre-beta development status and functionality was my first goal.

I need to check the entire code for memory errors (and leaks) and I'll run tests with valgrind when time permits.

imacarthur

unread,
Dec 1, 2021, 7:13:17 AM12/1/21
to fltk.coredev
On Wednesday, 1 December 2021 at 11:55:24 UTC Albrecht Schlosser wrote:

You can achieve something at least similar to the Fl_Group::resizable()
child widget if you set only one column's and one row's weight to a
non-zero value (or more than one adjacent rows/columns). But Fl_Grid can
do much more, for instance the "button row with two resizing gaps" in a
single Fl_Grid widget whereas you'd need complex Fl_Group nesting to
achieve the same. See my test/grid_buttons.cxx example vs. Ian's example
in fltk.general.

And this, I think, is a good example of where a mechanism like Fl_Grid can be useful.
The objective of having the 3 button sets, aligned left, centre, right seems like a natural and simple thing - and the Fl_Grid approach handles that in a way that I imagine most users would find fairly intuitive.
My posted example shows how you can do "the same" using the default group resizable behaviour, but I imagine that many (most?) people looking at that code would have a hard time comprehending what all the nested groups were doing (particularly in that example as I did not add any comments!) or how that end result even arises.
The default fltk group resizable behaviour is actually very neat and simple, but it can be counter-intuitive and works in a way that is unlike what most users visualize...

So, I like the current behaviour (given that I spent a long time over the years getting used to it's foibles!) but I'm still +1 on having other options like Fl_Grid that might be "simpler" for other cases.


Manolo

unread,
Dec 1, 2021, 11:21:04 AM12/1/21
to fltk.coredev
Le mardi 30 novembre 2021 à 23:27:12 UTC+1, Albrecht Schlosser a écrit :
Dear fellow developers,

I feel that the time has come to ask you for your votes to include the
new Fl_Grid widget in the FLTK core.

My vote is +1 to include class Fl_Grid in the FLTK core,
under the assumption that its relation to the existing  way to control
resizing will be clearly stated in its documentation.

Manolo

Greg Ercolano

unread,
Dec 1, 2021, 11:48:22 AM12/1/21
to fltkc...@googlegroups.com


On 12/1/21 3:55 AM, Albrecht Schlosser wrote:

Side note: I was tempted to "redesign" the test/device.cxx example program with Fl_Grid but this would have been too much work just for testing although I believe it's trivial. Maybe I'll try it later or once Fl_Grid is in the official FLTK repo.


    A possibly good candidate for redesign might be test/cube.cxx.
    If you recall I had to do a bit of work to get that to behave properly
    so that both windows and buttons resized nicely.

    While I was happy with the end result in the code (it wasn't too lengthly),
    it sounds like using Fl_Grid might result in clearer/shorter code, which
    would be an indication of its success..! :-D

Albrecht Schlosser

unread,
Dec 1, 2021, 11:49:21 AM12/1/21
to fltkc...@googlegroups.com
Sure, I'll improve the docs to make this clear.

Summary including my vote: 3 votes, +3

Thanks to all who commented and voted so far.

Greg Ercolano

unread,
Dec 1, 2021, 12:04:11 PM12/1/21
to fltkc...@googlegroups.com

    It sounds great to me; I haven't had time to actully try it, but
    I will though, and fully expect to give it a +1.

    I've seen your examples.. seems intuitive, and interesting use of
    (apparently) using the x,y position value of widgets as the row/col hints.
    That's pretty clever!

    I take it the ascii art layout hints (in the OP's widget) was redone
    in favor of this.

    Look forward to seeing it as a development branch  on the origin fltk repo
    so I can try to integrate it into my commercial build/testing.


Albrecht Schlosser

unread,
Dec 1, 2021, 12:42:50 PM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 5:48 PM Greg Ercolano wrote:
On 12/1/21 3:55 AM, Albrecht Schlosser wrote:

Side note: I was tempted to "redesign" the test/device.cxx example program with Fl_Grid but this would have been too much work just for testing although I believe it's trivial. Maybe I'll try it later or once Fl_Grid is in the official FLTK repo.

    A possibly good candidate for redesign might be test/cube.cxx.
    If you recall I had to do a bit of work to get that to behave properly
    so that both windows and buttons resized nicely.

I did that already, see test/grid_cube.cxx. Honestly, this was one of the triggers that made me write a new layout manager (Fl_Grid).


    While I was happy with the end result in the code (it wasn't too lengthly),
    it sounds like using Fl_Grid might result in clearer/shorter code, which
    would be an indication of its success..! :-D

It is, indeed. The code of the full, modified test/cube demo was about 1K bytes shorter than the original (8K vs. 9K IIRC) but later I removed all functional code and reduced the demo to only the layout stuff.

I managed to remove 26 (!) variables that were used to calculate layout positions and sizes (and more stuff) without losing clarity (IMHO).

You can still view the fully functional test/grid_cube.cxx demo code:
https://raw.githubusercontent.com/Albrecht-S/fltk/467086d3268f2e4431437bce09d5ae483a57db1a/test/grid_cube.cxx

... or you can clone my fork, checkout commit 467086d3268f and build test/grid_cube (likely only with CMake or fltk-config because I updated the Makefile's later).

The grid layout portion starts here:
https://github.com/Albrecht-S/fltk/blob/467086d3268f2e4431437bce09d5ae483a57db1a/test/grid_cube.cxx#L197

The latest version is reduced to the layout stuff with simple boxes rather than the GL windows. I used Fl_Grid *only* for symmetric resizing of the basic layout (three columns) while retaining the Fl_Group of controls nested in the center column. If you compare this with the first test version you may notice that the first version used only *one* Fl_Grid with multiple rows and columns (10 x 16 to compensate for some deficiencies of the code at that time).

There are several potential models to achieve the same layout:

1. Fl_Grid (1x3) with nested Fl_Group for controls in center column (like in current test/grid_cube.cxx)
2. Fl_Grid (1x3) with nested Fl_Grid (5x2) for controls in center column
3. Fl_Grid (5x4) with all widgets in one Fl_Grid

Note that you need 5 rows in layout options 2 and 3 with a placeholder row for the labels below the sliders or you can use four rows and extend the gap below the sliders to use for the labels. It's your choice.

I would likely go for model 2 with extended gap (nested Fl_Grid with 4 rows and 2 columns) if I would rewrite the original test/cube demo.

An image says more than a thousand words... See attached screenshot (layout model 1).

grid_cube_with_nested_Fl_Group.png

Greg Ercolano

unread,
Dec 1, 2021, 1:25:11 PM12/1/21
to fltkc...@googlegroups.com

On 12/1/21 9:42 AM, Albrecht Schlosser wrote:

The grid layout portion starts here:
https://github.com/Albrecht-S/fltk/blob/467086d3268f2e4431437bce09d5ae483a57db1a/test/grid_cube.cxx#L197

    Neat -- yeah, looks much cleaner!

    One question, having not read the docs yet and just trying to intuit by reading,
    how is there a "row 9" without rows 3 thru 8 specified? (shown in red below)

  // RS=rowspan, cs=colspan: R, C, RS, CS
  grid->widget(lt_cube,      0, 0, 10,  7);
  grid->widget(wire,         0, 7,  1,  2, FL_ALIGN_CENTER);
  grid->widget(flat,         1, 7,  1,  2, FL_ALIGN_CENTER);
  grid->widget(speed,        2, 7,  6,  1, FL_GRID_VERTICAL);
  grid->widget(size,         2, 8,  6,  1, FL_GRID_VERTICAL);
  grid->widget(exit_button,  9, 7,  1,  2, FL_ALIGN_CENTER);
  grid->widget(rt_cube,      0, 9, 10,  7);

    Is there actually a 10x10 grid (perhaps hence the name) of fixed spacing,
    and the exit_button is 10 spaces down on that grid, and rows 3 thru 8 are
    simply empty?

    [EDIT: Oh wait, I get it, there's a "row span" of 6 for the 'speed' and 'size'
    (shown in green above), so that must fill in the rows, kinda like how an
    an html <table> works, I expect.]

    What's interesting about html tables is the number of rows/cols doesn't
    have to be specified at the top, it's implied by the creation of the cells,
    so by the end of the table definition, the table knows how many total
    rows/cols, and is somewhat forgiving if the user, due to editing, left
    some rows unspecified.

    Is this something Fl_Grid could do too (calculate the total rows/cols on the fly)?

    Also: it seems from the above it's a two stage process; create the widgets
    then attach them with grid->widget() to specify the row/cols.
    But is it possible to use grid->begin() and grid->end() so that just
    creating the widgets with the row/col info in the x/y positions can
    let one create the widgets/layout in a single step?

    Perhaps you allow both ways to work, and were just demonstrating
    the former approach in this case.

    I guess I should really read the docs, lol, but it seems clear enough
    to intuit.

Greg Ercolano

unread,
Dec 1, 2021, 2:08:16 PM12/1/21
to fltkc...@googlegroups.com
    Oh, that's weird, that test/grid_cube.cxx code looks quite different
    from the grid_cube.cxx code I'm seeing when I cloned and checked out
    the Fl_Grid branch and looking at test/grid_cube.cxx.

    In the github link above, it appears all the widgets are put into the grid
    arrangement this way:


  // RS=rowspan, cs=colspan: R, C, RS, CS
  grid->widget(lt_cube,      0, 0, 10,  7);
  grid->widget(wire,         0, 7,  1,  2, FL_ALIGN_CENTER);
  grid->widget(flat,         1, 7,  1,  2, FL_ALIGN_CENTER);
  grid->widget(speed,        2, 7,  6,  1, FL_GRID_VERTICAL);
  grid->widget(size,         2, 8,  6,  1, FL_GRID_VERTICAL);
  grid->widget(exit_button,  9, 7,  1,  2, FL_ALIGN_CENTER);
  grid->widget(rt_cube,      0, 9, 10,  7);

    ..but in the clone/checkout it seems some widgets remain in a regular Fl_Group,
    and the grid is used just used for the cube/group/cube widgets this way:

  // define grid layout, assign widgets to grid cells, set resizing parameters
  grid->layout(1, 3, MARGIN, 10);     // set layout, margins, and gaps
  grid->widget(lt_cube, 0, 0);        // row 0, col 0
  grid->widget(ct_grp,  0, 1);        // row 0, col 1
  grid->widget(rt_cube, 0, 2);        // row 0, col 2
  grid->col_weight(1, 0);             // no horizontal resizing
  grid->layout();                     // calculate layout (needed once)

    (scratches head) Perhaps you determined the latter technique is shorter,
    leveraging both the old school Fl_Group behavior where it works fine,
    and the layout behavior for handling the things Fl_Group can't easily.

    Hmm, using "gitk test/grid_cube.cxx" seems to show that was the
    development evolution, which seems right to keep the cube demo
    short and sweet for its own purpose, and the older code is probably
    good to just demo Fl_Grid itself (in a separate demo).

    I take it the API is evolving, so I should probably go back through
    the docs (TBD I take it) and your posts to see if I can determine
    the different techniques Fl_Grid can use, as I take it there's several
    ways to use it.
   
   

Albrecht Schlosser

unread,
Dec 1, 2021, 3:36:21 PM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 8:08 PM Greg Ercolano wrote:

The grid layout portion starts here:
https://github.com/Albrecht-S/fltk/blob/467086d3268f2e4431437bce09d5ae483a57db1a/test/grid_cube.cxx#L197


    Oh, that's weird, that test/grid_cube.cxx code looks quite different
    from the grid_cube.cxx code I'm seeing when I cloned and checked out
    the Fl_Grid branch and looking at test/grid_cube.cxx.

    In the github link above, it appears all the widgets are put into the grid
    arrangement this way:

The link above is to the *old* version of an old development stage. The long number in the URL above (467086d3268...) is the old git commit SHA1. You can use your clone and checkout that particular commit:

$ git log -1 467086d3268f2e44
commit 467086d3268f2e4431437bce09d5ae483a57db1a
Author: Albrecht Schlosser <albrech...@online.de>
Date:   Mon Nov 22 02:28:45 2021 +0100

    Convert 'cube' demo program to use Fl_Grid
   
    There are some minor resizing issues remaining since Fl_Grid is
    not yet feature complete but it demonstrates its capabilities.


[end of commit message]

... and try how it works if you're interested.


    (scratches head) Perhaps you determined the latter technique is shorter,
    leveraging both the old school Fl_Group behavior where it works fine,
    and the layout behavior for handling the things Fl_Group can't easily.

It was just the progress of development and testing examples. I first tried everything in one Fl_Grid but that was not really working at that time (colspan and rowspan were not yet working correctly). I worked around the issues by using a 10x16 grid ('grid->layout(10, 16, MARGIN, 4);') but this is no longer a problem.


    Hmm, using "gitk test/grid_cube.cxx" seems to show that was the
    development evolution, which seems right to keep the cube demo
    short and sweet for its own purpose, and the older code is probably
    good to just demo Fl_Grid itself (in a separate demo).

I've just been working on another potential future 'test/cube_new.cxx' version which uses a much smaller grid, just as large as necessary:

grid->layout(4, 4, MARGIN, GAP);

Four rows are required for the buttons and sliders, four columns are for the left GL box, two sliders, and the right GL box.

Row and column spanning is the hardest thing to implement and still not entirely functional, at least not as one may expect. It needs a little help WRT row and column sizes, but that's another story. I'm going to work further on this...


    I take it the API is evolving, so I should probably go back through
    the docs (TBD I take it) and your posts to see if I can determine
    the different techniques Fl_Grid can use, as I take it there's several
    ways to use it.

Yes, there are often different ways and I'm still trying to find the best way(s) to use it. Depending on my test results I'm also changing and (hopefully) improving the API.

One of my next changes will be to remove the usage of FL_ALIGN_* flags for alignment and use FL_GRID_* flags consequently because the current alignment algorithm turned out to be insufficient. I decided to add a new bit FL_GRID_[FILL|STRETCH]_PROPORTIONAL to the alignment flags. Imagine an image in a grid which should be able to resize proportionally.

I'll post details and push changes to my branch when I made enough progress.

Albrecht Schlosser

unread,
Dec 1, 2021, 4:08:26 PM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 7:25 PM Greg Ercolano wrote:
>
> On 12/1/21 9:42 AM, Albrecht Schlosser wrote:
>
>> The grid layout portion starts here:
>> https://github.com/Albrecht-S/fltk/blob/467086d3268f2e4431437bce09d5ae483a57db1a/test/grid_cube.cxx#L197
>
>     Neat -- yeah, looks much cleaner!
>
>     One question, having not read the docs yet and just trying to
> intuit by reading,
>     how is there a "row 9" without rows 3 thru 8 specified? ...
> ...
>
>     [EDIT: Oh wait, I get it, there's a "row span" of 6 for the
> 'speed' and 'size'
>     (shown in green above), so that must fill in the rows, kinda like
> how an
>     an html <table> works, I expect.]

Yep, rowspan and colspan should work like in html tables.

> What's interesting about html tables is the number of rows/cols doesn't
>     have to be specified at the top, it's implied by the creation of
> the cells,
>     so by the end of the table definition, the table knows how many total
>     rows/cols, and is somewhat forgiving if the user, due to editing, left
>     some rows unspecified.
>
>     Is this something Fl_Grid could do too (calculate the total
> rows/cols on the fly)?
>

Basically yes, I did already document it but it's not yet implemented.
The crux with such dynamic allocation of grid cells (which is implied by
this approach) is that ... it needs dynamic allocation of cells. My
current version is based on pre-allocation of all (rows*cols) cells when
you call layout(rows, cols, ...). I also documented that you can resize
the grid by calling this again with other values (this is implemented
but yet untested) but that it's kinda inefficient because all cells need
to be re-allocated. Consequently cell assignments outside the current
grid dimensions are currently ignored but this may be changed in the future.

It was easier for me in the early development to work with a simple n*m
array than allocating the cells dynamically at assignment time. There
are however reasons to do the latter, particularly because it is
possible to have a sparse assignment to grid cells with a lot of "empty"
cells. Searches in the sparse array would be much more efficient than in
the full cell array.

Maybe it makes sense to have both: let the user pre-allocate the grid
but also extend it dynamically if the user assigns cells outside the
current grid. Or ... forget about it if all cells are allocated
dynamically at assignment time.

Hmm, I think I'll investigate this dynamic assignment route ...

> Also: it seems from the above it's a two stage process; create the widgets
>     then attach them with grid->widget() to specify the row/cols.
>     But is it possible to use grid->begin() and grid->end() so that just
>     creating the widgets with the row/col info in the x/y positions can
>     let one create the widgets/layout in a single step?

Yes and no, I'd say. I really considered this but I dismissed this
thought because it seemed like an "abuse" of widget coordinates - and
also because I was still developing the API and wanted to be open for
more parameters than only x/y/w/h.

In my first attempts I used argument order (column, row, colspan,
rowspan) like (x, y, w, h) in widgets which seemed to be consequent. In
this model using the widget's x as the column and y as the row would
also have been kinda intuitive. But then MoAlyoussef mentioned that the
order "row, column" would be more intuitive and I noticed that he was
right when I coded some examples, hence I switched row and column order
everywhere.

After that switch we'd likely have to use the first ('x') value of the
widget for the row and 'y' for the column which would again be
counter-intuitive. Sure, we could do this, but I'm not keen on doing it
this way for said reasons.

Also, if we had such a feature, this would imply that all other
parameters would have to be defaulted, i.e. colspan = rowspan = 1,
alignment = "FILL" and nothing else. Otherwise you'd have a two stage
assignment anyway...

Anyway, I'm open for discussion.

> Perhaps you allow both ways to work, and were just demonstrating
>     the former approach in this case.

In the beginning I used yet another way to create and assign a widget
like this:

  Fl_Grid::Cell *c = grid->cell( (new Fl_Button(x,y,w,h) ), row, col, ...);

Short but not really readable. My preferred way (as I found out during
my tests) is:

Fl_Grid *grid = new Fl_Grid(...);
// note: grid->begin() is implied

// create widgets
Fl_Button *b1 = new Fl_Button(...);
...
grid->end();

// assign layout and widgets to cells
grid->widget(b1, row, col, rowspan, colspan, align);
...

// calculate layout
grid->layout();

YMMV.

>     I guess I should really read the docs, lol, but it seems clear enough
>     to intuit.

If you read the docs this could also help me to develop a better API
based on your comments. ;-)

Albrecht Schlosser

unread,
Dec 1, 2021, 5:39:20 PM12/1/21
to fltkc...@googlegroups.com
On 12/1/21 9:36 PM Albrecht Schlosser wrote:
> On 12/1/21 8:08 PM Greg Ercolano wrote:
>>>
>>> The grid layout portion starts here:
>>> https://github.com/Albrecht-S/fltk/blob/467086d3268f2e4431437bce09d5ae483a57db1a/test/grid_cube.cxx#L197
>>>
>>
>>     Oh, that's weird, that test/grid_cube.cxx code looks quite different
>>     from the grid_cube.cxx code I'm seeing when I cloned and checked out
>>     the Fl_Grid branch and looking at test/grid_cube.cxx.

I just pushed new commits including a new demo program test/cube_new.cxx.

This new demo in my branch Fl_Grid is yet another version of the cube
demo program. It is fully functional and functionally identical to
test/cube.cxx. I used a new name (cube_new.cxx) so you can compare the
source files and run the old and new demo side by side.

It was a little extra work to make the layout *identical* to the old
test/cube.cxx demo program but I did it as a proof of concept.

In a real world program I'd probably use less fine tuning of gaps and
such and let the Fl_Grid widget figure out what I want. ;-)

We have now three different layouts doing roughly the same:

1. test/cube.cxx: old Fl_Group layout with lots of variables and
formulas to generate the layout

2. test/grid_cube.cxx: Fl_Grid demo program with a simple Fl_Grid (1x3)
and embedded Fl_Group for the controls

3. test/cube_new.cxx: fully functional "copy" of test/cube.cxx with one
Fl_Grid that contains the GL windows and all controls w/o nested groups

The latter would be one option to replace the existing test/cube.cxx
using Fl_Grid, but the layout of example 1. (Fl_Grid with nested
Fl_Group) would be another option.

Note: I'm using all these different test and demo programs (a) as a
proof of concept and (b) for further development and test of Fl_Grid.
You may use them for your own tests (or not). Any feedback would be
appreciated.

melcher....@googlemail.com

unread,
Dec 3, 2021, 6:14:14 PM12/3/21
to fltk.coredev
+1: I love it. It solves a long-standing issue that could not be solved with Fl_Group.

Albrecht Schlosser

unread,
Dec 3, 2021, 7:16:25 PM12/3/21
to fltkc...@googlegroups.com
On 12/4/21 12:14 AM 'melcher....@googlemail.com' via fltk.coredev wrote:
> +1: I love it. It solves a long-standing issue that could not be
> solved with Fl_Group.

Thanks.

Yes, I think it's a valuable tool and I believe I can finish it in about
a week, hopefully.

Reply all
Reply to author
Forward
0 new messages