FL_Table redraw when losing focus

12 views
Skip to first unread message

Rob McDonald

unread,
Jun 12, 2024, 7:57:41 PMJun 12
to fltk.general
I am working on adding a spreadsheet-like capability to my program.  I am largely following  examples/table-spreadsheet.cxx  as my guide.

At present, the currently selected box is drawn in FL_YELLOW at all times.  I would like it to be drawn in FL_WHITE when the spreadsheet does not have Fl::focus().

I believe I have made the correct changes to draw_cell.

if ( is_selected( R, C ) && ( Fl::focus() == this ) )
{
    fl_draw_box( FL_THIN_UP_BOX, X, Y, W, H, FL_YELLOW );
}
else
{
    fl_draw_box( FL_THIN_UP_BOX, X, Y, W, H, FL_WHITE );
}

This part generally seems to work.  I believe the problem is that the spreadsheet is not getting redrawn when it loses focus.

I tried adding this to the event _callback2(), but it doesn't seem to work.

switch ( Fl::event() ) // see what FLTK event caused it
{
case FL_UNFOCUS:
    damage_zone( current_row, current_col, select_row, select_col, R, C );
    return;


When I look at Fl_Table::handle(), I see this...

case FL_UNFOCUS:
  _stop_auto_drag();
  ret = 1;
  break;

which makes me think it is handling the FL_UNFOCUS event and not passing it down -- which would mean I should over-ride handle(), take care of FL_UNFOCUS and then call Fl_Table::handle() for everything else.

Or, perhaps the FL_UNFOCUS handling here should also call damage_zone() by default.

Am I missing something?  Is there a better way to get the spreadsheet to redraw when losing focus?

Thanks,

Rob

Rob McDonald

unread,
Jun 12, 2024, 8:05:08 PMJun 12
to fltk.general
On Wednesday, June 12, 2024 at 4:57:41 PM UTC-7 Rob McDonald wrote:
When I look at Fl_Table::handle(), I see this...

case FL_UNFOCUS:
  _stop_auto_drag();
  ret = 1;
  break;

which makes me think it is handling the FL_UNFOCUS event and not passing it down -- which would mean I should over-ride handle(), take care of FL_UNFOCUS and then call Fl_Table::handle() for everything else.

Or, perhaps the FL_UNFOCUS handling here should also call damage_zone() by default.

Am I missing something?  Is there a better way to get the spreadsheet to redraw when losing focus?

After that bit of rubber-ducking, I went ahead and tried over-riding handle() to call damage_zone() on FL_UNFOCUS.  It works as intended.  Thanks for letting me talk aloud here.

I still think it might be a reasonable default to change Fl_Table's behavior to do this by default, this seems like a fairly common case given that folks are required to write their own draw_cell() to use Fl_Table.

Best,

Rob
 


 

Greg Ercolano

unread,
Jun 12, 2024, 10:02:30 PMJun 12
to fltkg...@googlegroups.com

On 6/12/24 16:57, Rob McDonald wrote:

When I look at Fl_Table::handle(), I see this...

case FL_UNFOCUS:
  _stop_auto_drag();
  ret = 1;
  break;

which makes me think it is handling the FL_UNFOCUS event and not passing it down


    No -- not true.
    I think you're missing what's at the top of the Fl_Table::handle() method:

_____________________________________________

/**
  Handle FLTK events.
*/
int Fl_Table::handle(int event) {
  PRINTEVENT;
  int ret = Fl_Group::handle(event);    // let FLTK group handle events first
  [..]

_____________________________________________

    It lets children handle all the events first.

-- which would mean I should over-ride handle(),

    ..yes.

take care of FL_UNFOCUS

    ..and FL_FOCUS, yes.

and then call Fl_Table::handle() for everything else.

    Well, no, call Fl_Table::handle() regardless of how you handle the focus events.

    If you don't, you'll eclipse those events from FL_Table and all the children.

    When you overload handle(), all events go to you, and won't get to the widget you're deriving from unless you pass them through.

    As a general rule, don't eclipse events from the derived widget when you override handle() unless you're doing something very specific in mind.


Or, perhaps the FL_UNFOCUS handling here should also call damage_zone() by default.

    Well, because you're changing the look of the widget during focus changes,
    then you should called damage() or redraw().

    Fl_Table's default behavior does not change its appearance during focus changes, so it's default behavior should not call damage() or redraw() unless it did.

    In your case, since you're adding behavior that changes the appearance on focus changes, it makes sense you should also trigger damage or redraw.

Am I missing something?

    The above should hopefully clear that up.


  Is there a better way to get the spreadsheet to redraw when losing focus?

    No, I think what you're doing, overriding handle() and adding the desired behavior for focus/unfocus events is the right thing to do here.
    A callback would not be good for these kind of low level events.


Reply all
Reply to author
Forward
0 new messages