diff options
Diffstat (limited to 'examples/tree-custom-draw-items.cxx')
| -rw-r--r-- | examples/tree-custom-draw-items.cxx | 163 |
1 files changed, 127 insertions, 36 deletions
diff --git a/examples/tree-custom-draw-items.cxx b/examples/tree-custom-draw-items.cxx index 57ac85c31..fbee62700 100644 --- a/examples/tree-custom-draw-items.cxx +++ b/examples/tree-custom-draw-items.cxx @@ -17,68 +17,159 @@ // http://www.fltk.org/str.php // #include <stdio.h> -#include <math.h> // sin(3) +#include <time.h> /* ctime.. */ #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Tree.H> +#ifndef MAX +#define MAX(a,b) ((a)>(b))?(a):(b) +#endif + #if FLTK_ABI_VERSION >= 10303 -static void draw_item(Fl_Tree_Item *item, void *data) { - Fl_Tree *tree = (Fl_Tree*)data; - int X=item->label_x(), Y=item->label_y(), - W=item->label_w(), H=item->label_h(); - // Draw the background - fl_color(item->is_selected() ? tree->selection_color() : item->labelbgcolor()); - fl_rectf(X,Y,W,H); - // Draw some red/grn/blu boxes - int x = X + 5; - fl_color(FL_RED); fl_rectf(x, Y+2, 10, H-4); x += 10; - fl_color(FL_GREEN); fl_rectf(x, Y+2, 10, H-4); x += 10; - fl_color(FL_BLUE); fl_rectf(x, Y+2, 10, H-4); x += 10; - x += 5; - // Draw text - fl_font(item->labelfont(), item->labelsize()); - fl_color(item->labelfgcolor()); - char s[80]; - sprintf(s, "Custom: '%s'", item->label()?item->label():"---"); - fl_draw(s, x+tree->labelmarginleft(),Y,W,H, FL_ALIGN_LEFT); - int fw=0,fh=0; - fl_measure(s,fw,fh); - x += fw + 10; - // Draw a red sine wave past the text to end of xywh area - fl_color(FL_RED); - for ( float a=0.0; x<(X+W); x++,a+=.1) { - int y = Y + sin(a) * ((H-2)/2) + (H/2); - fl_point(x,y); +// DERIVE CUSTOM CLASS FROM Fl_Tree_Item TO IMPLEMENT SHOWING THE TIME OF DAY +// This demonstrates that item content can be dynamic and highly customized. +// +class MyTimeItem : public Fl_Tree_Item { + const char *time_format; +protected: + // Remove trailing crlf + const char* StripCrlf(char *s) + { char *ss = strchr(s, '\n'); if (ss) *ss = 0; return s; } + const struct tm* GetTimeStruct() { + time_t t = time(NULL); + if ( strcmp(time_format, "Local") == 0 ) return localtime(&t); + if ( strcmp(time_format, "GMT" ) == 0 ) return gmtime(&t); + return 0; + } +public: + MyTimeItem(Fl_Tree *tree, const char *time_format) : Fl_Tree_Item(tree) { + label(time_format); + this->time_format = time_format; + } + // Handle custom drawing of the item + // Fl_Tree has already handled drawing everything to the left + // of the label area, including any 'user icon', collapse buttons, + // connector lines, etc. + // + // All we're responsible for is drawing the 'label' area of the item + // and it's background. Fl_Tree gives us a hint as to what the + // foreground and background colors should be via the fg/bg parameters, + // and whether we're supposed to render anything or not. + // + // The only other thing we must do is return the maximum X position + // of scrollable content, i.e. the right most X position of content + // that we want the user to be able to use the horizontal scrollbar + // to reach. + // + int draw_item_content(int render) { + Fl_Color fg = drawfgcolor(); + Fl_Color bg = drawbgcolor(); + // Show the date and time as two small strings + // one on top of the other in a single item. + // + // Our item's label dimensions + int X = label_x(), Y = label_y(), + W = label_w(), H = label_h(); + // Render background + if ( render ) { + if ( is_selected() ) { // Selected? Use selectbox() style + fl_draw_box(prefs().selectbox(),X,Y,W,H,bg); + } else { // Not Selected? use plain filled rectangle + fl_color(bg); fl_rectf(X,Y,W,H); + } + } + // Render the label + if ( render ) { + fl_color(fg); + if ( label() ) fl_draw(label(), X,Y,W,H, FL_ALIGN_LEFT); + } + int lw=0, lh=0; + if ( label() ) { + lw=0; lh=0; fl_measure(label(), lw, lh); + } + X += lw + 8; + // Draw some red/grn/blu boxes + if ( render ) { + fl_color(FL_RED); fl_rectf(X+0, Y+2, 10, H-4); + fl_color(FL_GREEN); fl_rectf(X+10, Y+2, 10, H-4); + fl_color(FL_BLUE); fl_rectf(X+20, Y+2, 10, H-4); + } + X += 35; + // Render the date and time, one over the other + fl_font(labelfont(), 8); // small font + const struct tm *tm = GetTimeStruct(); + char s[80]; + sprintf(s, "Date: %02d/%02d/%02d", tm->tm_mon+1, tm->tm_mday, tm->tm_year % 100); + lw=0, lh=0; fl_measure(s, lw, lh); // get box around text (including white space) + if ( render ) fl_draw(s, X,Y+4,W,H, FL_ALIGN_LEFT|FL_ALIGN_TOP); + sprintf(s, "Time: %02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); + if ( render ) fl_draw(s, X,Y+H/2,W,H/2, FL_ALIGN_LEFT|FL_ALIGN_TOP); + int lw2=0, lh2=0; fl_measure(s, lw2, lh2); + X += MAX(lw, lw2); + return X; // return right most edge of what we've rendered } +}; + +// TIMER TO HANDLE DYNAMIC CONTENT IN THE TREE +void Timer_CB(void *data) { + Fl_Tree *tree = (Fl_Tree*)data; + tree->redraw(); // keeps time updated + Fl::repeat_timeout(0.2, Timer_CB, data); } int main(int argc, char *argv[]) { Fl::scheme("gtk+"); - Fl_Double_Window *win = new Fl_Double_Window(250, 400, "Simple Tree"); + Fl_Double_Window *win = new Fl_Double_Window(350, 400, "Simple Tree"); win->begin(); { // Create the tree Fl_Tree *tree = new Fl_Tree(0, 0, win->w(), win->h()); - tree->showroot(0); // don't show root of tree - tree->item_draw_callback(draw_item, (void*)tree); // setup a callback for the tree + tree->showroot(0); // don't show root of tree + tree->selectmode(FL_TREE_SELECT_MULTI); // multiselect // Add some items tree->add("Flintstones/Fred"); tree->add("Flintstones/Wilma"); tree->add("Flintstones/Pebbles"); - tree->add("Simpsons/Homer"); - tree->add("Simpsons/Marge"); - tree->add("Simpsons/Bart"); - tree->add("Simpsons/Lisa"); + { + MyTimeItem *myitem; + myitem = new MyTimeItem(tree, "Local"); // create custom item + myitem->labelsize(20); + tree->add("Time Add Item/Local", myitem); + + myitem = new MyTimeItem(tree, "GMT"); // create custom item + myitem->labelsize(20); + tree->add("Time Add Item/GMT", myitem); + } + // 'Replace' approach + { + Fl_Tree_Item *item; + MyTimeItem *myitem; + item = tree->add("Time Replace Item/Local Time"); + // Replace the 'Local' item with our own + myitem = new MyTimeItem(tree, "Local"); // create custom item + myitem->labelsize(20); + item->replace(myitem); // replace normal item with custom + + item = tree->add("Time Replace Item/GMT Time"); + // Replace the 'GMT' item with our own + myitem = new MyTimeItem(tree, "GMT"); // create custom item + myitem->labelsize(20); + item->replace(myitem); // replace normal item with custom + } tree->add("Superjail/Warden"); tree->add("Superjail/Jared"); tree->add("Superjail/Alice"); tree->add("Superjail/Jailbot"); + tree->show_self(); + // Start with some items closed - tree->close("Simpsons"); tree->close("Superjail"); + + // Set up a timer to keep time in tree updated + Fl::add_timeout(0.2, Timer_CB, (void*)tree); } win->end(); win->resizable(win); |
