FLTK logo

Re: [fltk.general] Re: Fl_Tabs

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.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: Re: Fl_Tabs Greg Ercolano Sep 02, 2021  
 

On 9/2/21 6:38 PM, Bill Spitzak wrote:

It does seem like a bug, calling value() should not have any side-effects. Especially because the tabs widget works even if nobody calls value().

    I think the problem here is with value(Fl_Widget*) which changes
    the current tab.

    What I've found is when you click on a tab, the Fl_Tabs::handle()
    changes the value of the tab using value(Fl_Widget*), which sets
    the new value, and returns 1 if it was changed or 0 if not.

    And based on that return value, handle() invokes do_callback()
    if a change was made.

    The problem is the value(Fl_Widget*) method is improperly returning
    0 even though the tab was indeed changed.

    This is because the logic in Fl_Tabs::value(Fl_Widget*) to detect a change
    assumes it can walk the loop calling hide() and show() on the children,
    and can check the visible() of the new tab as a way to detect if there was
    a change.

    The problem is when the loop calls hide() to deselect the first child, "Tab A",
    this single call to hide()..

        1. Sends "Tab A" an FL_HIDE event   -- OK
        2. Sends "Tab C" an FL_SHOW event -- THIS HERE IS THE PROBLEM
        3. Sends "Tab C" an FL_FOCUS event

    Step #2 causes Tab C to be shown before the loop expects it to be,
    and this confuses the loop's logic to detect that a change was made.

    Assuming that the above hide() event behavior is not a bug, this can
    I think be fixed/avoided by rewriting the value(Fl_Widget*) code this way:

 int Fl_Tabs::value(Fl_Widget *newvalue) {
+  Fl_Widget *oldvalue = value();
   Fl_Widget*const* a = array();
-  int ret = 0;
   for (int i=children(); i--;) {
     Fl_Widget* o = *a++;
     if (o == newvalue) {
-      if (!o->visible()) ret = 1;
       o->show();
     } else {
       o->hide();
     }
   }
-  return ret;
+  return oldvalue != newvalue ? 1 : 0;  // change detected
 }

    The only problem with that, and I think is the reason the code is the way it is,
    is that call to value() is non-trivial; it goes thru a loop just to find the current value(),
    so perhaps it was an efficiency call.

    But there really cant be very many tabs; there's a visual limit to how many
    there can be, so perhaps efficiency here is unwarranted.

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/73b35908-4dcf-6340-68bd-67053c2f292e%40seriss.com.
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'.