RE: [fltk.general] Drawing a Grid.

95 views
Skip to first unread message

MacArthur, Ian (Selex ES, UK)

unread,
Feb 19, 2015, 7:56:21 AM2/19/15
to fltkg...@googlegroups.com
> My main is generated with FLUID and renders a fullscreen window with the
> following code:


Sometimes it can be more useful to state what you are trying to achieve, rather than showing us what you have done.

So; what *are* you trying to achieve with this?



> If the user types a key, I want to display a grid on the fullscreen
> window.

A grid? As in a grid of cells? Or just a Cartesian grid, or...? I guess a grid of entry cells, looking at the code.


> I've cobbled a function from here:
> http://seriss.com/people/erco/fltk/#CellTable as follows:

Good start... But, um... would an Fl_table not be easier for this sort of thing?



> Fl_Scroll *dbaseGrid;
> Fl_Tile *tile;
> Fl_Box *box;
> Fl_Input *in;
> void *cells;

> void databaseGrid(int rows, int cols, string headers[]){
> void *cell[rows][cols];
> int cellw=64;
> int cellh=32;
> int xx=5;
> int yy=5;
> int w=cellw*cols+cellw;
> int h=cellh*rows+cellw;
> canvas->begin();
> {
> dbaseGrid=new Fl_Scroll(0,0,w,h);


To be honest, once I've made a Fl_Scroll, the first thing I usually do is put an Fl_Group inside it, then parent all the other widgets to that group. Maybe that's just me...


> {
> tile = new Fl_Tile(5, 5, w-10, h-10);

What's the Fl_tile for?

> for(int r=0; r<rows; r++){
> printf("Buck here\n");
> for(int c=0; c<cols;c++){
> if(r==0){
> {
> box = new Fl_Box(xx,yy,cellw,cellh,headers[c].c_str());
> box->box(FL_BORDER_BOX);
> }
> cell[r][c]=(void *)box;
> }else{
> {
> Fl_Input *in = new Fl_Input(xx,yy,cellw,cellh);
> in->box(FL_BORDER_BOX);
> in->value("");
> }
> cell[r][c]=(void *)in;
> }
> xx += cellw;
> }
> xx = 5;
> yy += cellh;
> }
> cells=cell;
> tile->end();
> }
> dbaseGrid->end();
> }// Fl_Tile* dbaseGrid
> canvas->end();
> }


> How can I get my grid to display. I was hoping to add my grid to my
> 'canvas' box, but this hasn't worked.

What does your canvas derive from? We do not know what type an "event_grp" is. I guess if it derives from Fl_Group, then you'd expect to be able to add widgets to that and see them displayed.


> Also, I am cavalierly assuming that my array of void * cells will allow
> me to access the contents of my grid, but I suspect that the integrity
> of the data is suspect once the function ends.

That'll not work; your "void *cell[rows][cols];" goes out of scope when the function exits (the fact that you have assigned it to "cells" makes no difference here) as it will be stack automatic.

So once your function returns, "cells" will be pointing at random data on the stack, which is unlikely to be what you want.

That may be all that is wrong, perhaps?

Also, your "cell" array probably wants to be an array of "Fl_Widget*" rather than of "void*", since that will save casting and etc., and make other things simpler. (Most fltk classes derive from Fl_Widget, to casting them to Fl_Widget is "trivial".)





Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

Dave Coventry

unread,
Feb 20, 2015, 1:37:20 AM2/20/15
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Hi Ian, thanks for the assistance.


On Thursday, February 19, 2015 at 2:56:21 PM UTC+2, MacArthur, Ian (Selex ES, UK) wrote:
Sometimes it can be more useful to state what you are trying to achieve, rather than showing us what you have done.

So; what *are* you trying to achieve with this?
I want to display the results of multiple SQL queries. 
A grid? As in a grid of cells? Or just a Cartesian grid, or...? I guess a grid of entry cells, looking at the code.
I want a header row, plus a set of cells I want to fill with the results of the Query.
Good start... But, um... would an Fl_table not be easier for this sort of thing?
Probably. I couldn't find the documentation for the Fl_table.
I used FLUID to generate a table, but was unable to work out how to manipulate the cells.
In the course of searching for how to implement an Fl_table, I found Erco's FLTK page and thought it would work for what I wanted.
To be honest, once I've made a Fl_Scroll, the first thing I usually do is put an Fl_Group inside it, then parent all the other widgets to that group. Maybe that's just me...
Well , you know far more about FLTK, so I'd be happy to be guided. :+)
What does your canvas derive from? We do not know what type an "event_grp" is. I guess if it derives from Fl_Group, then you'd expect to be able to add widgets to that and see them displayed.
In the 'main' as posted previously:

  { Fl_Double_Window* o = new Fl_Double_Window(670, 445);
    w = o;
    { command_line = new Fl_Input(25, 25, 1095, 550, "input:");
      command_line->labeltype(FL_NO_LABEL);
    } // Fl_Input* command_line
    { canvas = new event_grp(370, 183, 505, 234, "label");
      canvas->box(FL_BORDER_BOX);
      canvas->color(FL_FOREGROUND_COLOR);
      canvas->selection_color(FL_BACKGROUND_COLOR);
      canvas->labeltype(FL_NO_LABEL);
      canvas->labelfont(0);
      canvas->labelsize(14);
      canvas->labelcolor(FL_FOREGROUND_COLOR);
      canvas->align(Fl_Align(FL_ALIGN_CENTER));
      canvas->when(FL_WHEN_RELEASE);
    } // event_grp* canvas
    o->end();
  } // Fl_Double_Window* o

 
That'll not work; your "void *cell[rows][cols];" goes out of scope when the function exits (the fact that you have assigned it to "cells" makes no difference here) as it will be stack automatic.

So once your function returns, "cells" will be pointing at random data on the stack, which is unlikely to be what you want.
Yes. That's what I expected. 

That may be all that is wrong, perhaps?
Yes, but the grid is not displaying. Even if the cells are destroyed after the function exits, I'd expect the grid to be drawn on the canvas.
I take it that the encapsulating code:
  canvas->begin();
    ....
  canvas->end();
is sufficient for registering the grid on the canvas (and therefore in the window)?
  

Also, your "cell" array probably wants to be an array of "Fl_Widget*" rather than of "void*", since that will save casting and etc., and make other things simpler. (Most fltk classes derive from Fl_Widget, to casting them to Fl_Widget is "trivial".)
That's helpful: thanks.
I'll obviously need to set up a dynamic array of Fl_Widget to hold my cells, and I guess each cell needs to be copied to this so that once the function ends it is not destroyed.

MacArthur, Ian (Selex ES, UK)

unread,
Feb 20, 2015, 4:36:41 AM2/20/15
to fltkg...@googlegroups.com
> I want to display the results of multiple SQL queries.

> I want a header row, plus a set of cells I want to fill with the results
> of the Query.

> > Good start... But, um... would an Fl_table not be easier for this sort
> > of thing?

> Probably. I couldn't find the documentation for the Fl_table.
> I used FLUID to generate a table, but was unable to work out how to
> manipulate the cells.


The more complex widgets, such as Fl_Table, are not easy to use from fluid; fluid is great for laying stuff out and simple dialogs, but if you want to do tricky stuff (and it sounds like you do) then you are going to have to cut some code.

You need to be studying (i.e. ripping off) the table examples in the examples folder of the tarball.

Have you looked at them? I think they probably go a long way to demonstrating what you'd need.

In particular, I think "table-spreadsheet" and "table-spreadsheet-with-keyboard-nav" would be worth perusing.

Dave Coventry

unread,
Feb 20, 2015, 4:52:35 AM2/20/15
to fltkg...@googlegroups.com
Thanks Ian.
On 20 February 2015 at 11:36, MacArthur, Ian (Selex ES, UK)
<ian.ma...@selex-es.com> wrote:
> The more complex widgets, such as Fl_Table, are not easy to use from fluid; fluid is great for laying stuff out and simple dialogs, but if you want to do tricky stuff (and it sounds like you do) then you are going to have to cut some code.

I've used FLUID to set up my interface and my visual design continues
to be developed in this way.

However, my supplementary functions are held in separate .cxx files,
the implementation of this grid included.

> You need to be studying (i.e. ripping off) the table examples in the examples folder of the tarball.
>
> Have you looked at them? I think they probably go a long way to demonstrating what you'd need.
>
> In particular, I think "table-spreadsheet" and "table-spreadsheet-with-keyboard-nav" would be worth perusing.

Thanks.

I was looking at them earlier to handle Fl_image implementation, but
for some reason they weren't my first port of call implementing my
grid.

Cheers,

Dave.

Greg Ercolano

unread,
Feb 20, 2015, 5:00:08 AM2/20/15
to fltkg...@googlegroups.com
On 02/20/15 01:52, Dave Coventry wrote:
> I was looking at them earlier to handle Fl_image implementation, but
> for some reason they weren't my first port of call implementing my
> grid.

You should be able to use the original cheat page you started with,
as you may need individual widgets to do what you want, but..
the code you posted in the OP.. too many contradictions in that code;
I'd suggest starting from scratch.

There's widgets (like Fl_Input) created larger than the Fl_Window,
and widget that overlap each other (the canvas is created over the Fl_Input)
and then everything is resized at the end without calling init_sizes().. argh,
too much wrong stuff.

I'd suggest starting with the example code, and fleshing it out a little
at a time to be more like the program you want, and do test compiles each
time you add a little, and stop whenever something doesn't look right and
check your docs.


Dave Coventry

unread,
Feb 20, 2015, 5:46:31 AM2/20/15
to fltkg...@googlegroups.com
Thanks Greg.

On 20 February 2015 at 12:00, Greg Ercolano <erco_...@seriss.com> wrote:
> On 02/20/15 01:52, Dave Coventry wrote:
> You should be able to use the original cheat page you started with,
> as you may need individual widgets to do what you want, but..
> the code you posted in the OP.. too many contradictions in that code;
> I'd suggest starting from scratch.

Ok, if I call this:
canvas->begin();
{dbaseGrid=new Fl_Scroll(0,0,w,h);
......
dbaseGrid->end();
}
canvas->end();

Does this add a new Fl_Scroll widget to my canvas which is already
declared in main()?
If it does, why doesn't it show? Do I have to flush something or
trigger a redraw?

> There's widgets (like Fl_Input) created larger than the Fl_Window,
> and widget that overlap each other (the canvas is created over the Fl_Input)
> and then everything is resized at the end without calling init_sizes().. argh,
> too much wrong stuff.

I'm using Fl_Scroll because I'm assuming (obviously incorrectly) that
any overlaps will automatically be handled by scrolling borders.

> I'd suggest starting with the example code, and fleshing it out a little
> at a time to be more like the program you want, and do test compiles each
> time you add a little, and stop whenever something doesn't look right and
> check your docs.

Again, I'm assuming that adding an Fl_Tile item within the scroll
element can be done with:

{dbaseGrid=new Fl_Scroll(0,0,w,h);
tile = new Fl_Tile(5, 5, w-10, h-10);
tile->end();
dbaseGrid->end();
}

if I put a cell in that tile, do I do it like this?

tile = new Fl_Tile(5, 5, w-10, h-10);
Fl_Input *in = new Fl_Input(xx,yy,cellw,cellh);
in->box(FL_BORDER_BOX);
in->value("");
//<---- possible error? should have in->end();?
tile->end();

Or have I got the wrong end of the stick?

MacArthur, Ian (Selex ES, UK)

unread,
Feb 20, 2015, 6:04:56 AM2/20/15
to fltkg...@googlegroups.com

> Again, I'm assuming that adding an Fl_Tile item within the scroll
> element can be done with:

Going off at a tangent (and ignoring your questions for now...) but what's the tile for?

I'm not sure why you (think you) need it, and it can be a tricky thing to use right.

Note that *all* fltk widgets are resizable by default (unless you explicitly disable resizing) so using a tile just to get resizing behaviour is not necessary in general...

Dave Coventry

unread,
Feb 20, 2015, 6:10:50 AM2/20/15
to fltkg...@googlegroups.com
On 20 February 2015 at 13:04, MacArthur, Ian (Selex ES, UK)
<ian.ma...@selex-es.com> wrote:
> Going off at a tangent (and ignoring your questions for now...) but what's the tile for?

I'm not sure.

I want the grid to be constrained in a row/column configuration and
I'm working under the impression that the Fl_Tile controls that.

Greg's cheat page example uses it and it takes number of rows and
columns as arguments which has probably led me to jump to that
conclusion.

MacArthur, Ian (Selex ES, UK)

unread,
Feb 20, 2015, 6:22:41 AM2/20/15
to fltkg...@googlegroups.com

> Ok, if I call this:
> canvas->begin();
> {dbaseGrid=new Fl_Scroll(0,0,w,h);
> ......
> dbaseGrid->end();
> }
> canvas->end();
>
> Does this add a new Fl_Scroll widget to my canvas which is already
> declared in main()?

Should do, if:-

- your canvas is a container widget type (i.e. derives from Fl_Group)

- the same "canvas" is in scope at the point it is called

> If it does, why doesn't it show? Do I have to flush something or
> trigger a redraw?

You trigger a redraw by calling redraw... probably canvas->redraw(); in this case.



> I'm using Fl_Scroll because I'm assuming (obviously incorrectly) that
> any overlaps will automatically be handled by scrolling borders.

You are responsible for coding your widgets so that they fit, are the right size, don't fall outside their parents, etc. Overlaps are something you need to be careful of, as the resulting behaviour can be unexpected.

If your child widgets are poorly sized or positioned wrt their parents, they will probably not be drawn. Or will be drawn oddly...

This is still true of Fl_Scroll.

*However*:
If you make an Fl_Scroll the size you want to display, you can then put something else (e.g. an Fl_Group for example) inside it that is *bigger* than the scroll, and get scrollbars and such... (I'm guessing this is what you'd want.)

Anything you subsequently add, still has to fit inside that group, mind you (and should be added to the group, not the scroll, in this case.)


> Again, I'm assuming that adding an Fl_Tile item within the scroll
> element can be done with:

Comments in another post about Fl_Tile.
I'm almost certain you do not want it...


> if I put a cell in that tile, do I do it like this?
>
> tile = new Fl_Tile(5, 5, w-10, h-10);
> Fl_Input *in = new Fl_Input(xx,yy,cellw,cellh);
> in->box(FL_BORDER_BOX);
> in->value("");
> //<---- possible error? should have in->end();?
> tile->end();
>
> Or have I got the wrong end of the stick?

Fl_Tile can be a tricky thing to use.
You *must* fill it with widgets, and they have to fit *exactly*, edges aligned against each other *exactly*, and not overlap...

I'm still puzzled why you want it; it doesn’t seem a useful thing to have in a data grid.

--
Ian

Dave Coventry

unread,
Feb 20, 2015, 6:29:10 AM2/20/15
to fltkg...@googlegroups.com
Cheers, Ian.

On 20 February 2015 at 13:22, MacArthur, Ian (Selex ES, UK)
<ian.ma...@selex-es.com> wrote:
> Should do, if:-
>
> - your canvas is a container widget type (i.e. derives from Fl_Group)
>
> - the same "canvas" is in scope at the point it is called

I don't get any errors, so I'm hoping it is being implemented correctly.

> You trigger a redraw by calling redraw... probably canvas->redraw(); in this case.

Thanks. I'll try that.

> You are responsible for coding your widgets so that they fit, are the right size, don't fall outside their parents, etc. Overlaps are something you need to be careful of, as the resulting behaviour can be unexpected.

Ok, useful to know.

> *However*:
> If you make an Fl_Scroll the size you want to display, you can then put something else (e.g. an Fl_Group for example) inside it that is *bigger* than the scroll, and get scrollbars and such... (I'm guessing this is what you'd want.)

Yes, thanks.

> Fl_Tile can be a tricky thing to use.
> You *must* fill it with widgets, and they have to fit *exactly*, edges aligned against each other *exactly*, and not overlap...
>
> I'm still puzzled why you want it; it doesn’t seem a useful thing to have in a data grid.

Well, it seems that I don't after all!

MacArthur, Ian (Selex ES, UK)

unread,
Feb 20, 2015, 6:33:51 AM2/20/15
to fltkg...@googlegroups.com

> > Going off at a tangent (and ignoring your questions for now...) but
> > what's the tile for?
>
> I'm not sure.
>
> I want the grid to be constrained in a row/column configuration and
> I'm working under the impression that the Fl_Tile controls that.

No, not really; that's not what it does. It controls the resizing of widgets within its surface area so that you can have movable dividers and that sort of thing.

If you want a simple grid, it's the wrong way to go...


> Greg's cheat page example uses it and it takes number of rows and
> columns as arguments which has probably led me to jump to that
> conclusion.

Yes, Greg was showing how to make dynamically resizable columns and rows in that example, whilst using "ordinary" widgets, so he used a tile to help with that, but for the basic case that's an added distraction you don't need.

I'd remove it for now; I'm pretty sure it is breaking your code!

I still think starting from one of the Fl_Table examples would be a better bet for you.

The examples/table-spreadsheet sample is the better place to start I think.

MacArthur, Ian (Selex ES, UK)

unread,
Feb 20, 2015, 6:38:15 AM2/20/15
to fltkg...@googlegroups.com

> I still think starting from one of the Fl_Table examples would be a
> better bet for you.
>
> The examples/table-spreadsheet sample is the better place to start I
> think.

Actually; changed my mind:- "examples/table-as-container" is maybe a better staring point! (It's a bit shorter!)

Dave Coventry

unread,
Feb 20, 2015, 6:39:13 AM2/20/15
to fltkg...@googlegroups.com
Thanks, Ian, I'll take your advice.

Dave

On 20 February 2015 at 13:38, MacArthur, Ian (Selex ES, UK)
> --
> You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/8PG3qIWvH0c/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Greg Ercolano

unread,
Feb 20, 2015, 10:57:30 AM2/20/15
to fltkg...@googlegroups.com
The Fl_Tile makes all the rows and columns interactively resizable.

If you run the demo, when you hover over the cell boundaries,
the cursor changes to a resizing cursor; when that happens
if you click and drag, you can resize the rows + columns.

From the description below the demo screenshot:

A table of Fl_Box, Fl_Input and Fl_Float_Input
widgets. You can change both the size of the window,
*and interactively resize the individual cell rows and columns.*
Reply all
Reply to author
Forward
0 new messages