FLTK logo

[Library] r10018 - /branches/branch-1.3/examples /branches/branch-1.3/FL /branches/branch-1.3/src

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Library      Forums      Links      Apps     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[Library] r10018 - /branches/branch-1.3/examples /branches/branch-1.3/FL /branches/branch-1.3/src [greg.ercolano] Nov 09, 2013  
 
 ------------------------------------------------------------------------
 r10018 | greg.ercolano | 2013-11-09 23:33:44 -0500 (Sat, 09 Nov 2013) | 5 lines
 Changed paths:
    M /branches/branch-1.3/FL/Fl_Tree.H
    M /branches/branch-1.3/FL/Fl_Tree_Item.H
    M /branches/branch-1.3/FL/Fl_Tree_Prefs.H
    M /branches/branch-1.3/examples/Makefile
    A /branches/branch-1.3/examples/tree-custom-draw-items.cxx
    M /branches/branch-1.3/src/Fl_Tree.cxx
    M /branches/branch-1.3/src/Fl_Tree_Item.cxx
    M /branches/branch-1.3/src/Fl_Tree_Prefs.cxx
 
 o Added Fl_Tree::item_draw_callback(), letting one define a custom draw function for Fl_Tree_Item's.
 o Added examples/tree-custom-draw-items.cxx to demonstrate its use.
 o Fixed small doc error for recent Fl_Tree::get_selected_items()
 
 
 ------------------------------------------------------------------------
Index: branches/branch-1.3/FL/Fl_Tree_Prefs.H
===================================================================
--- branches/branch-1.3/FL/Fl_Tree_Prefs.H	(revision 10017)
+++ branches/branch-1.3/FL/Fl_Tree_Prefs.H	(revision 10018)
@@ -93,6 +93,11 @@
 };
 #endif /*FLTK_ABI_VERSION*/
 
+#if FLTK_ABI_VERSION >= 10303
+class Fl_Tree_Item;
+typedef void (Fl_Tree_Item_Draw_Callback)(Fl_Tree_Item*, void*);
+#endif
+
 /// \class Fl_Tree_Prefs
 ///
 /// \brief Fl_Tree's Preferences class.
@@ -134,6 +139,10 @@
   Fl_Tree_Item_Reselect_Mode _itemreselectmode;	// controls item selection callback() behavior
   Fl_Tree_Item_Draw_Mode     _itemdrawmode;	// controls how items draw label + widget()
 #endif /*FLTK_ABI_VERSION*/
+#if FLTK_ABI_VERSION >= 10303
+  Fl_Tree_Item_Draw_Callback *_itemdrawcallback;	// callback to handle drawing items (0=none)
+  void                       *_itemdrawuserdata;	// data for drawing items (0=none)
+#endif
 public:
   Fl_Tree_Prefs();
   
@@ -412,7 +421,22 @@
   inline void item_draw_mode(Fl_Tree_Item_Draw_Mode val) {
     _itemdrawmode = val;
   }
-#endif /*FLTK_ABI_VERSION*/
+#endif
+#if FLTK_ABI_VERSION >= 10303
+  void item_draw_callback(Fl_Tree_Item_Draw_Callback *cb, void *data=0) {
+    _itemdrawcallback = cb;
+    _itemdrawuserdata = data;
+  }
+  Fl_Tree_Item_Draw_Callback* item_draw_callback() const {
+    return(_itemdrawcallback);
+  }
+  void* item_draw_user_data() const {
+    return(_itemdrawuserdata);
+  }
+  void do_item_draw_callback(Fl_Tree_Item *o) const {
+    _itemdrawcallback(o, _itemdrawuserdata);
+  }
+#endif
 };
 
 #endif /*FL_TREE_PREFS_H*/
Index: branches/branch-1.3/FL/Fl_Tree_Item.H
===================================================================
--- branches/branch-1.3/FL/Fl_Tree_Item.H	(revision 10017)
+++ branches/branch-1.3/FL/Fl_Tree_Item.H	(revision 10018)
@@ -98,6 +98,10 @@
   int y() const { return(_xywh[1]); }
   int w() const { return(_xywh[2]); }
   int h() const { return(_xywh[3]); }
+  int label_x() const { return(_label_xywh[0]); }
+  int label_y() const { return(_label_xywh[1]); }
+  int label_w() const { return(_label_xywh[2]); }
+  int label_h() const { return(_label_xywh[3]); }
   int calc_item_height(const Fl_Tree_Prefs &prefs) const;
   void draw(int X, int &Y, int W, Fl_Widget *tree, Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1);
   void show_self(const char *indent = "") const;
Index: branches/branch-1.3/FL/Fl_Tree.H
===================================================================
--- branches/branch-1.3/FL/Fl_Tree.H	(revision 10017)
+++ branches/branch-1.3/FL/Fl_Tree.H	(revision 10018)
@@ -96,6 +96,8 @@
 ///     Items can be found by their pathname using find_item(const char*),
 ///     and an item's pathname can be found with item_pathname().
 ///     The selected items' colors are controlled by selection_color() (inherited from Fl_Widget).
+///     A hook is provided to allow you to redefine how item's labels are drawn
+///     via Fl_Tree::item_draw_callback().
 ///
 /// \b SELECTION OF ITEMS
 ///
@@ -465,7 +467,13 @@
   Fl_Tree_Item_Draw_Mode item_draw_mode() const;
   void item_draw_mode(Fl_Tree_Item_Draw_Mode mode);
   void item_draw_mode(int mode);
-#endif /*FLTK_ABI_VERSION*/
+#endif
+#if FLTK_ABI_VERSION >= 10303
+  void item_draw_callback(Fl_Tree_Item_Draw_Callback *cb, void *data=0);
+  Fl_Tree_Item_Draw_Callback* item_draw_callback() const;
+  void* item_draw_user_data() const;
+  void do_item_draw_callback(Fl_Tree_Item *o) const;
+#endif
   int displayed(Fl_Tree_Item *item);
   void show_item(Fl_Tree_Item *item, int yoff);
   void show_item(Fl_Tree_Item *item);
Index: branches/branch-1.3/src/Fl_Tree.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Tree.cxx	(revision 10017)
+++ branches/branch-1.3/src/Fl_Tree.cxx	(revision 10018)
@@ -936,7 +936,7 @@
 ///       ..do stuff with each selected item..
 ///   }
 /// \endcode
-/// \param[in] items The returned array of selected items.
+/// \param[in] ret_items The returned array of selected items.
 /// \returns The number of items in the returned array.
 /// \see first_selected_item(), next_selected_item()
 ///
@@ -1787,7 +1787,9 @@
 void Fl_Tree::item_reselect_mode(Fl_Tree_Item_Reselect_Mode mode) {
   _prefs.item_reselect_mode(mode);
 }
+#endif
 
+#if FLTK_ABI_VERSION >= 10303
 /// Get the 'item draw mode' used for the tree
 Fl_Tree_Item_Draw_Mode Fl_Tree::item_draw_mode() const {
   return(_prefs.item_draw_mode());
@@ -1804,8 +1806,52 @@
 void Fl_Tree::item_draw_mode(int val) {
   _prefs.item_draw_mode(Fl_Tree_Item_Draw_Mode(val));
 }
-#endif /*FLTK_ABI_VERSION*/
 
+/// Set a callback to be invoked to handle drawing the Fl_Tree_Item
+/// instead of the default label drawing behavior. Lets one define
+/// custom drawing behavior for Fl_Tree_Item's. eg:
+/// \code
+///    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 text
+///        fl_font(item->labelfont(), item->labelsize());
+///        fl_color(item->labelfgcolor());
+///        fl_draw("Some text", X+tree->labelmarginleft(),Y,W,H, FL_ALIGN_LEFT);
+///    }
+///    ..
+/// int main() {
+///    Fl_Tree *tree = new Fl_Tree(0,0,100,100);
+///    tree->item_draw_callback(draw_item, (void*)tree);
+///    [..]
+/// \endcode
+///
+/// Note: This only affects the drawing of item's labels;
+/// it does not affect the drawing of widgets assigned with
+/// Fl_Tree_Item::widget().
+///
+void Fl_Tree::item_draw_callback(Fl_Tree_Item_Draw_Callback *cb, void *data) {
+  _prefs.item_draw_callback(cb,data);
+}
+/// Get the current item draw callback. Returns 0 if none.
+Fl_Tree_Item_Draw_Callback* Fl_Tree::item_draw_callback() const {
+  return(_prefs.item_draw_callback());
+}
+/// Get the current item draw callback's user data.
+void* Fl_Tree::item_draw_user_data() const {
+  return(_prefs.item_draw_user_data());
+}
+/// Invoke the configured item_draw_callback().
+//  Do NOT call this if no item_draw_callback() was configured.
+void Fl_Tree::do_item_draw_callback(Fl_Tree_Item *o) const {
+  _prefs.do_item_draw_callback(o);
+}
+#endif
+
 /// See if \p item is currently displayed on-screen (visible within the widget).
 /// This can be used to detect if the item is scrolled off-screen.
 /// Checks to see if the item's vertical position is within the top and bottom
Index: branches/branch-1.3/src/Fl_Tree_Prefs.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Tree_Prefs.cxx	(revision 10017)
+++ branches/branch-1.3/src/Fl_Tree_Prefs.cxx	(revision 10018)
@@ -156,6 +156,10 @@
   _itemreselectmode       = FL_TREE_SELECTABLE_ONCE;
   _itemdrawmode           = FL_TREE_ITEM_DRAW_DEFAULT;
 #endif
+#if FLTK_ABI_VERSION >= 10303
+  _itemdrawcallback       = 0;
+  _itemdrawuserdata       = 0;
+#endif
   // Let fltk's current 'scheme' affect defaults
   if ( Fl::scheme() ) {
     if ( strcmp(Fl::scheme(), "gtk+") == 0 ) {
Index: branches/branch-1.3/src/Fl_Tree_Item.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Tree_Item.cxx	(revision 10017)
+++ branches/branch-1.3/src/Fl_Tree_Item.cxx	(revision 10018)
@@ -529,7 +529,7 @@
   return(0);
 }
 
-static void draw_item_focus(Fl_Boxtype B, Fl_Color C, int X, int Y, int W, int H) {
+static void draw_item_focus(Fl_Boxtype B, Fl_Color fg, Fl_Color bg, int X, int Y, int W, int H) {
   if (!Fl::visible_focus()) return;
   switch (B) {
     case FL_DOWN_BOX:
@@ -541,7 +541,7 @@
     default:
       break;
   }
-  fl_color(fl_contrast(FL_BLACK, C));
+  fl_color(fl_contrast(fg, bg));
 
 #if defined(USE_X11) || defined(__APPLE_QUARTZ__)
   fl_line_style(FL_DOT);
@@ -719,41 +719,51 @@
 	    prefs.openicon()->draw(icon_x,icon_y);
 	  }
 	}
-	// Background for this item
-	// Draw bg only if different from tree's bg
-	if ( bg != tree->color() || is_selected() ) {
-	  if ( is_selected() ) {			// Selected? Use selectbox() style
-	    fl_draw_box(prefs.selectbox(),bg_x,bg_y,bg_w,bg_h,bg);
-	  } else {					// Not Selected? use plain filled rectangle
-	    fl_color(bg);
-	    fl_rectf(bg_x,bg_y,bg_w,bg_h);
+	// Draw the item
+#if FLTK_ABI_VERSION >= 10303
+	if ( !widget() && prefs.item_draw_callback() ) {
+	  // Draw item using user supplied custom item draw callback
+	  prefs.do_item_draw_callback(this);
+        }
+	else
+#endif
+	{
+	  // Background for this item
+	  // Draw bg only if different from tree's bg
+	  if ( bg != tree->color() || is_selected() ) {
+	    if ( is_selected() ) {			// Selected? Use selectbox() style
+	      fl_draw_box(prefs.selectbox(),bg_x,bg_y,bg_w,bg_h,bg);
+	    } else {					// Not Selected? use plain filled rectangle
+	      fl_color(bg);
+	      fl_rectf(bg_x,bg_y,bg_w,bg_h);
+	    }
+	    if ( widget() ) widget()->damage(FL_DAMAGE_ALL);	// if there's a child widget, we just damaged it
 	  }
-	  if ( widget() ) widget()->damage(FL_DAMAGE_ALL);	// if there's a child widget, we just damaged it
-	}
-	// Draw user icon (if any)
-	if ( usericon() ) {
-	  // Item has user icon? Use it
-	  int uicon_y = item_y_center - (usericon()->h() >> 1);
-	  usericon()->draw(uicon_x,uicon_y);
-	} else if ( prefs.usericon() ) {
-	  // Prefs has user icon? Use it
-	  int uicon_y = item_y_center - (prefs.usericon()->h() >> 1);
-	  prefs.usericon()->draw(uicon_x,uicon_y);
-	}
-	// Draw label
+	  // Draw user icon (if any)
+	  if ( usericon() ) {
+	    // Item has user icon? Use it
+	    int uicon_y = item_y_center - (usericon()->h() >> 1);
+	    usericon()->draw(uicon_x,uicon_y);
+	  } else if ( prefs.usericon() ) {
+	    // Prefs has user icon? Use it
+	    int uicon_y = item_y_center - (prefs.usericon()->h() >> 1);
+	    prefs.usericon()->draw(uicon_x,uicon_y);
+	  }
+	  // Draw label
 #if FLTK_ABI_VERSION >= 10301
-        if ( _label && 
-	     ( !widget() || 
-	       (prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) )
+	  if ( _label && 
+	       ( !widget() || 
+		 (prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) )
 #else /*FLTK_ABI_VERSION*/
-        if ( _label && !widget() )	// back compat: don't draw label if widget() present
+	  if ( _label && !widget() )	// back compat: don't draw label if widget() present
 #endif /*FLTK_ABI_VERSION*/
-        {
-	  fl_color(fg);
-	  fl_font(_labelfont, _labelsize);
-	  int label_y = Y+(H/2)+(_labelsize/2)-fl_descent()/2;
-	  fl_draw(_label, label_x, label_y);
-	}
+	  {
+	    fl_color(fg);
+	    fl_font(_labelfont, _labelsize);
+	    int label_y = Y+(H/2)+(_labelsize/2)-fl_descent()/2;
+	    fl_draw(_label, label_x, label_y);
+	  }
+        }		// end non-custom draw
       }			// end non-child damage
       // Draw child FLTK widget?
       if ( widget() ) {
@@ -766,7 +776,7 @@
            Fl::visible_focus() && 
 	   Fl::focus() == tree &&
 	   prefs.selectmode() != FL_TREE_SELECT_NONE ) {
-	draw_item_focus(FL_NO_BOX,bg,bg_x+1,bg_y+1,bg_w-1,bg_h-1);
+	draw_item_focus(FL_NO_BOX,fg,bg,bg_x+1,bg_y+1,bg_w-1,bg_h-1);
       }
     }			// end drawthis
   }			// end clipped
Index: branches/branch-1.3/examples/Makefile
===================================================================
--- branches/branch-1.3/examples/Makefile	(revision 10017)
+++ branches/branch-1.3/examples/Makefile	(revision 10018)
@@ -24,6 +24,7 @@
       texteditor-simple$(EXEEXT) \
       tree-simple$(EXEEXT) \
       tree-as-container$(EXEEXT) \
+      tree-custom-draw-items$(EXEEXT) \
       tree-of-tables$(EXEEXT) \
       wizard-simple$(EXEEXT)
 
Index: branches/branch-1.3/examples/tree-custom-draw-items.cxx
===================================================================
--- branches/branch-1.3/examples/tree-custom-draw-items.cxx	(revision 0)
+++ branches/branch-1.3/examples/tree-custom-draw-items.cxx	(revision 10018)
@@ -0,0 +1,100 @@
+//
+// "$Id$"
+//
+//	Demonstrate Fl_Tree custom item draw callback. - erco 11/09/2013
+//
+// Copyright 2013 Greg Ercolano.
+// Copyright 1998-2013 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 <math.h>	// sin(3)
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Tree.H>
+
+#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);
+  }
+}
+
+int main(int argc, char *argv[]) {
+  Fl::scheme("gtk+");
+  Fl_Double_Window *win = new Fl_Double_Window(250, 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
+
+    // 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");
+    tree->add("Superjail/Warden");
+    tree->add("Superjail/Jared");
+    tree->add("Superjail/Alice");
+    tree->add("Superjail/Jailbot");
+
+    // Start with some items closed
+    tree->close("Simpsons");
+    tree->close("Superjail");
+  }
+  win->end();
+  win->resizable(win);
+  win->show(argc, argv);
+  return(Fl::run());
+}
+#else
+#include <FL/Fl.H>
+#include <FL/fl_message.H>
+int main(int, char**) {
+  fl_alert("This demo is dependent on an ABI feature.\n"
+           "FLTK_ABI_VERSION must be set to 10303 (or higher) in Enumerations.H");
+  return 1;
+}
+#endif
+
+//
+// End of "$Id$".
+//

Property changes on: branches/branch-1.3/examples/tree-custom-draw-items.cxx
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+author date id revision
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property

Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2025 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.