On 13.04.2012 22:35, David Lopez wrote: > Thanks Edzard and Greg for the answers, but I did not explained the issue > clearly. > I wanted to give a simple example, but indeed the parent (window) may have > tens or hundreds of children (boxes). Each of the boxes must be redrawn at a > different time independently of the rest (for example to change its fill > color according to an asynchronous event). > And in some cases, two (or more) of the boxes may be overlapped (the layer > order is static). > > So, a real situation could be: > There are 100 boxes in the window (box #1 to box #100). > The boxes #90 and #91 are overlapped. > The box #91 is above the #90. > The box #90 must be redrawn (because must change its color). > It redraws OK but overwrites box #91. > I would like to get boxes #90 and #91 to be redrawn but not the other 98 > boxes. > > I think that there is no way to do this other than add to each widget a list > of references to the widgets that need to be redrawn if the current widget is > drawn (that is the boxes that are above it). > Am I right?
FLTK is not designed to support such overlapping widgets. You may experience (re)drawing problems if you create such widget layouts. Of course, widgets must overlap their parents, but that's it - child widgets shouldn't overlap each other. That said, drawing always happens in the order of children in a group, so that such overlapping widgets seem to work as intended, but you're on your own if things like partial occlusion by other windows happen, or redrawing as in your description. So, the more specific answer to your question is: yes, you're on your own with this, and if you really need it, you will have to manage overlapping hierarchies in your code. There are ways to use damage() with areas though, but I'm not very familiar with this. Maybe this can help: if your box #90 (b90) in Fl_Group g changed, try something like this: g->damage(FL_DAMAGE_ALL, b90->x(), b90->y(), b90->w(), b90->h()); instead of calling redraw(). This *should* have the same effect as calling redraw() for the box, but should also redraw all other overlapping widgets, if I'm right. You should give it a try and report whether it helps (or not). ... well, I tested it myself, and it seems to work as intended. Please see attached demo program. There are still cases where it might not work. Look at box 3 (B3). Why does it stay "on top of B2" if the damage() button is clicked ? It is as intended, but... Albrecht // overlap.cxx - overlapping widget demo. // This shows how damage() can be used to redraw overlapping widgets. // Use at your own risk. Usage: // fltk-config --compile overlap.cxx && ./overlap // Use both buttons to see the difference: // button1_cb() redraws B1 only, // button2_cb() redraws B1 and B2, // resizing the window redraws all boxes. #include <stdio.h> #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Widget.H> #include <FL/Fl_Group.H> #include <FL/Fl_Box.H> #include <FL/Fl_Button.H> Fl_Box *b1, *b2, *b3; Fl_Color c = 0; // This derived class is only to print which box is drawn. class MyBox : public Fl_Box { public: MyBox(int x, int y, int w, int h, const char *L) : Fl_Box(x,y,w,h,L) { align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT|FL_ALIGN_TOP); box(FL_FLAT_BOX); } void draw() { printf("draw() box %s\n",label()); fflush(stdout); Fl_Box::draw(); } }; // Button 1 doesn't draw overlapping widgets void button1_cb(Fl_Widget *, void *) { printf("button 1: redraw()\n"); if (++c > 7) c = 1; b1->color(c); b1->redraw(); } // Button 2 draws overlapping widgets void button2_cb(Fl_Widget *, void *) { printf("button 2: damage()\n"); if (++c > 7) c = 1; b1->color(c); b1->parent()->damage(FL_DAMAGE_ALL, b1->x(), b1->y(), b1->w(), b1->h()); } int main(int argc, char **argv) { Fl_Window *window = new Fl_Window(500, 300, "Overlapping widget test"); Fl_Group *g = new Fl_Group(0,0,300,300); b1 = new MyBox(10,10,200,200,"B1"); b1->color(FL_WHITE); b2 = new MyBox(90,90,200,200,"B2"); b2->color(fl_lighter(fl_lighter(FL_BLUE))); b3 = new MyBox(230,30,80,80,"B3"); b3->color(FL_YELLOW); g->end(); Fl_Button *button1 = new Fl_Button(350, 50,100,50,"redraw()"); button1->callback(button1_cb); Fl_Button *button2 = new Fl_Button(350,150,100,50,"damage()"); button2->callback(button2_cb); window->end(); window->resizable(window); window->show(); return Fl::run(); } _______________________________________________ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk