Stan wrote:

> [..]
>> > What is often lost in this discussion is the fact that
>> >   begin();  new Thing(..);  new Thing(); end()
>> > is NOT exactly the same as
>> >   add(new Thing(..)); add(new Thing(..));
>>
>> I'm probably forgetting something about FLTK2; what's the difference?
> 
> I've never used fltk2.  In the context of fltk1:
> 
> // Example 1
> Fl_Group* g = new Fl_Group(..)  // implicit begin()
> g->end();
> g->add(new X(..))   //  adds an X* to g
> 
> // Example 2
> Fl_Group* g = new Fl_Group(..)  // implicit begin()
> new X(...)   // adds all widgets created by the execution of
>              // X::X() to Fl_Group::current()
> g->end()


There are further differences: g->end() sets the *global* Fl_Group::current_
pointer to g->parent(), and this can change the global "adding situation",
whereat g->add() doesn't. Assume, I have a group MyGroup with an extra_add()
method coded like that:

    void MyGroup::extra_add() {
      begin()
        new Fl_Button(...);
        new Fl_Box(...);  etc.
      end();                            // --> Fl_Group::current_ =
    }                                                    this->parent()
    
and now the following usage of extra_add():

    int main() 
    {
      Fl_Window* win1;
      MyGroup* g;

      win1 = new Fl_Window(...);        // --> Fl_Group::current_ = win1
        g = new MyGroup(...);
        g->end();
      win1->end();                      // --> Fl_Group::current_ = 0

      if( something ) 
        g->extra_add();                 // --> Fl_Group::current_ = win1
                                        
      Fl_Window* win2 = new Fl_Window(...);
      ....
    }

If 'something' is false, win2 becomes a top level window, because at its
construction moment Fl_Group::current_ was 0, but if 'something' is true, 
win2 becomes a sub-window of win1, what was probably not intended. 
A save way would be using add() instead of begin()/end() in extra_add().

Unfortunately, add() has also a disadvantage, namely in situations where
the global Fl_Group::current_ pointer is *not* 0. The call 

    g->add( new SomeWidget(...) );

adds the new constructed widget then nevertheless at first to the current
open group (the wrong group), and g->add() must move it following from
there to g. This can imply a wasted reallocation of the children array of
the wrong group. 

An effective *and* save way of extra_add() leaving the global environment
unchanged should be

    void MyGroup::extra_add() 
    {
      Fl_Group* previous = Fl_Group::current();
      begin();                          // Fl_Group::current_ = this
        new Fl_Button(...);             // adds immediately to 'this'
        ....
      Fl_Group::current (previous);     // Restore previous open group
                                        //  (instead of end())
    }  


Hartmut
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to