mirror of
https://github.com/fltk/fltk.git
synced 2026-05-10 05:27:55 +08:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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$".
|
||||
//
|
||||
+21
-1
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user