|
------------------------------------------------------------------------
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 ] | |