diff options
| author | Greg Ercolano <erco@seriss.com> | 2012-04-18 15:20:20 +0000 |
|---|---|---|
| committer | Greg Ercolano <erco@seriss.com> | 2012-04-18 15:20:20 +0000 |
| commit | c7044ca0097432fad31f7e525f7d17a63ab5bd29 (patch) | |
| tree | 6cc5f90100c879a2fe436424f61977cac28f58c8 | |
| parent | d741da43175f7544ca090a240620a0bcafb9bc60 (diff) | |
Optimizations for when Fl_Tree is a container of FLTK widgets.
o Don't draw FLTK widgets outside tree's viewport.
o Added tree-as-container.cxx example program, demos tree
w/50k tree items each with 6 widgets (300k total)
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9356 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | examples/Makefile | 1 | ||||
| -rw-r--r-- | examples/tree-as-container.cxx | 90 | ||||
| -rw-r--r-- | src/Fl_Tree.cxx | 22 |
3 files changed, 112 insertions, 1 deletions
diff --git a/examples/Makefile b/examples/Makefile index f2e32a758..ca1fd9b68 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -22,6 +22,7 @@ ALL = howto-add_fd-and-popen$(EXEEXT) \ textdisplay-with-colors$(EXEEXT) \ texteditor-simple$(EXEEXT) \ tree-simple$(EXEEXT) \ + tree-as-container$(EXEEXT) \ wizard-simple$(EXEEXT) # default target -- build everything diff --git a/examples/tree-as-container.cxx b/examples/tree-as-container.cxx new file mode 100644 index 000000000..73a7fb580 --- /dev/null +++ b/examples/tree-as-container.cxx @@ -0,0 +1,90 @@ +// +// "$Id$" +// +// Fl_Tree as a container of FLTK widgets. - erco 04/15/2012 +// +// Copyright 2010,2012 Greg Ercolano. +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// http://www.fltk.org/COPYING.php +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +#include <stdio.h> +#include <FL/Fl.H> +#include <FL/Fl_Double_Window.H> +#include <FL/Fl_Tree.H> +#include <FL/Fl_Group.H> +#include <FL/Fl_Input.H> + +#define MAX_ROWS 80000 +#define MAX_FIELDS 5 +#define FIELD_WIDTH 70 +#define FIELD_HEIGHT 25 + +class MyData : public Fl_Group { + Fl_Input *fields[MAX_FIELDS]; +public: + MyData(int X,int Y,int W,int H) : Fl_Group(X,Y,W,H) { + static int colors[MAX_FIELDS] = { + 0xffffdd00, 0xffdddd00, 0xddffff00, 0xddffdd00, 0xddddff00 + }; + for ( int t=0; t<MAX_FIELDS; t++ ) { + fields[t] = new Fl_Input(X+t*FIELD_WIDTH,Y,FIELD_WIDTH,H); + fields[t]->color(colors[t]); + } + end(); + } + void SetData(int col, const char *val) { + if ( col >= 0 && col < MAX_FIELDS ) + fields[col]->value(val); + } +}; + +int main(int argc, char *argv[]) { + Fl_Double_Window *win = new Fl_Double_Window(450, 400, "Tree As FLTK Widget Container"); + win->begin(); + { + // Create the tree + Fl_Tree *tree = new Fl_Tree(10, 10, win->w()-20, win->h()-20); + tree->showroot(0); // don't show root of tree + // Add some regular text nodes + tree->add("Foo/Bar/001"); + tree->add("Foo/Bar/002"); + tree->add("Foo/Bla/Aaa"); + tree->add("Foo/Bla/Bbb"); + // Add items to the 'Data' node + for ( int t=0; t<MAX_ROWS; t++ ) { + // Add item to tree + static char s[80]; + sprintf(s, "FLTK Widgets/%d", t); + Fl_Tree_Item *item = tree->add(s); + // Reconfigure item to be an FLTK widget (MyData) + tree->begin(); + { + MyData *data = new MyData(0,0,FIELD_WIDTH*MAX_FIELDS, FIELD_HEIGHT); + item->widget(data); + // Initialize widget data + for ( int c=0; c<MAX_FIELDS; c++ ) { + sprintf(s, "%d-%d", t,c); + data->SetData(c,s); + } + } + tree->end(); + } + } + win->end(); + win->resizable(win); + win->show(argc, argv); + return(Fl::run()); +} + +// +// End of "$Id$". +// diff --git a/src/Fl_Tree.cxx b/src/Fl_Tree.cxx index 6dae729aa..b058df055 100644 --- a/src/Fl_Tree.cxx +++ b/src/Fl_Tree.cxx @@ -125,6 +125,7 @@ Fl_Tree::~Fl_Tree() { /// Standard FLTK event handler for this widget. int Fl_Tree::handle(int e) { + if (e == FL_NO_EVENT) return(0); // XXX: optimize to prevent slow resizes on large trees! int ret = 0; // Developer note: Fl_Browser_::handle() used for reference here.. // #include <FL/names.h> // for event debugging @@ -400,7 +401,26 @@ void Fl_Tree::draw() { } // Draw children fl_push_clip(cx,cy,cw-(_vscroll->visible()?_vscroll->w():0),ch); - Fl_Group::draw_children(); // draws any FLTK children set via Fl_Tree::widget() + // Similar to Fl_Group::draw(), but optimized to ignore drawing + // items outside the viewport. + // TODO: Suggest Fl_Group::draw() do this if clip_children() is enabled. + { + Fl_Widget*const* a = Fl_Group::array(); + if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: + for (int i=Fl_Group::children(); i--;) { + Fl_Widget& o = **a++; + if ( (o.y()+o.h()) < y() || (o.y() > (y()+h())) ) continue; + Fl_Group::draw_child(o); + Fl_Group::draw_outside_label(o); + } + } else { // only redraw the children that need it: + for (int i=Fl_Group::children(); i--;) { + Fl_Widget& o = **a++; + if ( (o.y()+o.h()) < y() || (o.y() > (y()+h())) ) continue; + Fl_Group::update_child(o); + } + } + } fl_pop_clip(); draw_child(*_vscroll); // draw scroll last } |
