On 14.05.2012 16:41, Eugenio Bargiacchi wrote:
Well it IS pretty convenient, for avoiding to precisely place every component. 
Less lines of code, less bloated.

I've posted my code a couple of replies above, so tell me what you think of it! 
=)

Fl_Scroll changes the x/y positions of its children to scroll
the contents, and Fl_Pack tries to calculate x/y positions
depending on the order of its children. Both widgets are doing
this during their draw() methods, which is a restriction that
can make things difficult.

Additionally, resizing Fl_Group changes its childrens' sizes
as well, so there are lots of effects coming together in this
scenario. Once you resize a group and/or rearrange a its children
you should also call init_sizes() to make your changes "permanent".
Otherwise the group will always try to resize the children
according to the first saved state.

Although I believe that nesting Fl_Scroll and Fl_Pack should be
avoided, I believe that I found a solution for your problem.
See the appended (reformatted and modified) sample code you posted.
You should also note that it would have been easier to understand
(at least for me ;-)) if you hadn't used templates for this sample
code.

See the comments in asker.h for what I changed, and also in asker.cxx
(your main.cpp) for additional changes:

(1) top_box was added to maintain the border (left and to spacing of
widgets inside the Fl_Scroll widget.

(2) rb (resize-box) was added to maintain the other widgets's sizes.

(3) Make both boxes invisible by commenting out their box and color
statements.

If I wanted to do such a special resizing, I would derive my own
container widget and override the resize() method to arrange the
widgets as needed (at least for the Fl_Pack).

Albrecht

// asker.h
#ifndef ASKER_H
#define ASKER_H

#include <FL/Fl_Pack.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
#include <FL/fl_ask.H>

template <class T>
class Asker : public Fl_Pack
{
  public:
    Asker(int a, int b, int c, int d, const char * itemName, int s);
  private:
    Fl_Button * addButton;
    static void add_cb( Fl_Widget * button, void * a );
    int s;
    int d;
};

template <class T>
Asker<T>::Asker(int a, int b, int c, int d2, const char * itemName, int s2) : 
Fl_Pack( a, b, c, d2 ) , s(s2), d(d2)
{
  add(addButton = new Fl_Button( a, b, c, d, itemName));        // Creates the 
gen button
  addButton->callback((Fl_Callback*) add_cb, this );            // Creates the 
gen callback
  end();
  spacing(s);
}

template <class T>
void Asker<T>::add_cb( Fl_Widget * button, void * a ) {
  Asker<T> * asker = ( Asker<T> * ) a;          // Gets the caller
  Fl_Group *group = (Fl_Group *)asker->parent();    // parent = Fl_Group (!)
  Fl_Scroll *scroll = (Fl_Scroll *)group->parent(); // group's parent = 
Fl_Scroll (!)
  T * newWidget = new T(0 , 0 , 0 ,asker->d);   // Creates the new widget, only 
height matters because Fl_Pack
  asker->insert(*newWidget, 0);                 // Inserts the new Widget on top
  group->size(group->w(), group->h() + asker->d + asker->s );   // Increases 
the Height of the parent by the new Widget + 1 Spacing
  group->init_sizes(); // THIS IS IMPORTANT
  group->redraw();     // maybe not needed (?)
  scroll->redraw();    // must be done
}

#endif // ASKER_H
// end of asker.h
//----------------------------------------------------------
// asker.cxx
// (MAIN.CPP)
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Input.H>
#include "asker.h"

int main(int argc, char **argv) {
  Fl_Window *window = new Fl_Window(340,400);
    Fl_Scroll *Z = new Fl_Scroll(0,0,340,400);
      Fl_Box * top_box = new Fl_Box(0,0,3,3);           // to keep spacing in 
Fl_Scroll
      top_box->color(FL_RED); top_box->box(FL_FLAT_BOX); // make it visible 
(comment this out!)
      Fl_Group * A = new Fl_Group(20,40,300,300,"A");
        Fl_Box * rb = new Fl_Box(320-3,340-3,3,3);   // resize box
        rb->color(FL_BLUE); rb->box(FL_FLAT_BOX);    // make it visible 
(comment this out!)
        A->resizable(rb); // needed to keep the other widgets in their original 
sizes
        Fl_Input * A1 = new Fl_Input( 30, 50, 280, 40, "A1" );
        Asker<Fl_Input> * B = new Asker<Fl_Input>(30, 100, 280, 40, "TEST", 10 
);       // Each Input will be 40 height, spacing is 10
      A->end();
      A->box(FL_UP_BOX);
    Z->end();
  window->end();
  window->resizable(window);
  window->show(argc, argv);
  return Fl::run();
}
// end of asker.cxx
//----------------------------------------------------------
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to