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 Apps      FLTK Library      Forums      Links     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-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.