Adds horizontal scrollbar to Fl_Tree as an ABI 1.3.3 feature.

***************************************************************
NOTE: You MUST uncomment the FLTK_ABI_VERSION in Enumerations.H
      to use these changes.
***************************************************************

Also: separated tree size calculation from draw() code,
so that one can cause the tree to recalculate immediately
after making modifications to the tree by calling Fl_Tree::calc_tree().

Numerous improvements to docs for the tree as well, enough
to create a rather large diff.

Large internal changes were needed to do this properly.
The following was added to the CHANGES file:

	- Fl_Tree: various related changes:
	    o Added horizontal scrollbar
	    o Separated draw() and tree size calculation
	    o Added new public methods:
	        > resize()           -- uses optimized dim calc, avoids tree recalc
		> next_item()        -- added parameters: direction, visibility
		> extend_selection() -- added parameters, improved algorithm
		> calc_dimensions()  -- calc tix/y/w/h, tox/y/w/h and scrollbars
		> calc_tree()        -- calc tree_w/tree_h
		> recalc_tree()      -- schedules calc_tree()
		> first_visible_item(), last_visible_item(), next_visible_item()
		> first_selected_item(), last_selected_item(), next_selected_item()
	    o Added protected variables:
	        > _tix/y/w/h      -- tree widget 'inner' dimension
		> _tox/y/w/h      -- tree widget 'outer' dimension
		> _tree_w,_tree_h -- entire tree hierarchy width/height
	    o Deprecated:
	        > item_clicked() -- use callback_item() instead
		> first_visible() -- use first_visible_item() instead
		> last_visible() -- use last_visible_item() instead

	- Fl_Tree_Item: various related changes:
	    o Added Fl_Tree ptr: needed for auto-recalc when item modified directly
	    o Added new methods tree(), recalc_tree()
	    o Added new ctor that accepts Fl_Tree*
	    o draw() parameters changed to include tree size calculations
	    o Deprecated:
	       > ctor using Fl_Tree_Prefs parameter (Fl_Tree* version better,
	         and must be used for 1.3.3 ABI features to work correctly)
	       > next_displayed() -- use next_visible() instead
	       > prev_displayed() -- use prev_visible() instead

	- test/tree: added tests for newly added features




git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10034 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Greg Ercolano 2013-12-15 18:59:02 +00:00
parent 6bf1ddf2b1
commit d36882e67e
7 changed files with 1652 additions and 507 deletions

32
CHANGES
View File

@ -29,6 +29,38 @@ CHANGES IN FLTK 1.3.3 RELEASED: MMM
- Added Fl_Tree::get_selected_items(), returns the selected items as an array
- Added Fl_Tree::item_draw_callback(), letting one define a custom draw function
for Fl_Tree_Item's.
- Fl_Tree: various related changes:
o Added horizontal scrollbar
o Separated draw() and tree size calculation
o Added new public methods:
> resize() -- uses optimized dim calc, avoids tree recalc
> next_item() -- added parameters: direction, visibility
> extend_selection() -- added parameters, improved algorithm
> calc_dimensions() -- calc tix/y/w/h, tox/y/w/h and scrollbars
> calc_tree() -- calc tree_w/tree_h
> recalc_tree() -- schedules calc_tree()
> first_visible_item(), last_visible_item(), next_visible_item()
> first_selected_item(), last_selected_item(), next_selected_item()
o Added protected variables:
> _tix/y/w/h -- tree widget 'inner' dimension
> _tox/y/w/h -- tree widget 'outer' dimension
> _tree_w,_tree_h -- entire tree hierarchy width/height
o Deprecated:
> item_clicked() -- use callback_item() instead
> first_visible() -- use first_visible_item() instead
> last_visible() -- use last_visible_item() instead
- Fl_Tree_Item: various related changes:
o Added Fl_Tree ptr: needed for auto-recalc when item modified directly
o Added new methods tree(), recalc_tree()
o Added new ctor that accepts Fl_Tree*
o draw() parameters changed to include tree size calculations
o Deprecated:
> ctor using Fl_Tree_Prefs parameter (Fl_Tree* version better,
and must be used for 1.3.3 ABI features to work correctly)
> next_displayed() -- use next_visible() instead
> prev_displayed() -- use prev_visible() instead
- test/tree: added tests for newly added features
CHANGES IN FLTK 1.3.2 RELEASED: Dec 12 2012

View File

@ -80,36 +80,38 @@
/// tree.end();
/// \endcode
///
/// \b FEATURES
///
/// Items can be added with add(),
/// removed with remove(),
/// completely cleared with clear(),
/// inserted with insert() and insert_above(),
/// selected/deselected with select() and deselect(),
/// open/closed with open() and closed().
/// Children of an item can be swapped around with Fl_Tree_Item::swap_children(),
/// sorting can be controlled when items are add()ed via sortorder().
/// You can walk the entire tree with first() and next().
/// \par FEATURES
/// Items can be added with add(),<BR>
/// removed with remove(),<BR>
/// completely cleared with clear(),<BR>
/// inserted with insert() and insert_above(),<BR>
/// selected/deselected with select() and deselect(),<BR>
/// open/closed with open() and close(),<BR>
/// positioned on the screen with show_item_top(), show_item_middle() and
/// show_item_bottom(),<BR>
/// item children can be swapped around with Fl_Tree_Item::swap_children(),<BR>
/// sorting can be controlled when items are add()ed via sortorder().<BR>
/// You can walk the entire tree with first() and next().<BR>
/// You can walk visible items with first_visible_item()
/// and next_visible_item().<BR>
/// You can walk selected items with first_selected_item() and
/// next_selected_item().
/// next_selected_item().<BR>
/// 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).
/// and an item's pathname can be found with item_pathname().<BR>
/// The selected items' colors are controlled by selection_color()
/// (inherited from Fl_Widget).<BR>
/// 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
/// via Fl_Tree::item_draw_callback().<BR>
///
/// \par SELECTION OF ITEMS
/// The tree can have different selection behaviors controlled by selectmode().
/// The background color used for selected items is the Fl_Tree::selection_color().
/// The foreground color for selected items is controlled internally with fl_contrast().
///
/// \b CHILD WIDGETS
///
/// \par CHILD WIDGETS
/// FLTK widgets (including custom widgets) can be assigned to tree items via
/// Fl_Tree_Item::widget().
///
/// \par
/// When a widget() is defined, the default behavior is for the widget()
/// to be shown in place of the item's label (if it has one).
/// Only the widget()'s width will be used; the widget()'s x() and y() position
@ -120,41 +122,38 @@
/// adding the FL_TREE_ITEM_HEIGHT_FROM_WIDGET flag causes widget's height
/// to define the widget()'s height.
///
/// \b ICONS
///
/// \par ICONS
/// The tree's open/close icons can be redefined with
/// Fl_Tree::openicon(), Fl_Tree::closeicon(). User icons
/// can either be changed globally with Fl_Tree::usericon(),
/// or on a per-item basis with Fl_Tree_Item::usericon().
///
/// \par
/// Various default preferences can be globally manipulated via Fl_Tree_Prefs,
/// including colors, margins, icons, connection lines, etc.
///
/// \b FONTS AND COLORS
///
/// \par FONTS AND COLORS
/// When adding new items to the tree, the new items get the
/// defaults for fonts and colors from:
///
/// \par
/// - Fl_Tree::item_labelfont() -- The default item label font (default: FL_HELVETICA)
/// - Fl_Tree::item_labelsize() -- The default item label size (default: FL_NORMAL_SIZE)
/// - Fl_Tree::item_labelfgcolor() -- The default item label foreground color (default: FL_FOREGROUND_COLOR)
/// - Fl_Tree::item_labelbgcolor() -- The default item label background color (default: 0xffffffff, which tree uses as 'transparent')
///
/// \par
/// Each item (Fl_Tree_Item) inherits a copy of these font/color attributes when created,
/// and each item has its own methods to let the app change these values on a per-item basis
/// using methods of the same name:
///
/// \par
/// - Fl_Tree_Item::item_labelfont() -- The item's label font (default: FL_HELVETICA)
/// - Fl_Tree_Item::item_labelsize() -- The item's label size (default: FL_NORMAL_SIZE)
/// - Fl_Tree_Item::item_labelfgcolor() -- The item's label foreground color (default: FL_FOREGROUND_COLOR)
/// - Fl_Tree_Item::item_labelbgcolor() -- The item's label background color (default: 0xffffffff, which tree uses as 'transparent')
///
/// \b CALLBACKS
///
/// \par CALLBACKS
/// The tree's callback() will be invoked when items change state or are open/closed.
/// when() controls when mouse/keyboard events invoke the callback.
/// callback_item() and callback_reason() can be used to determine the cause of the callback. eg:
///
/// callback_item() and callback_reason() can be used to determine the cause of the callback. e.g.
/// \par
/// \code
/// void MyTreeCallback(Fl_Widget *w, void *data) {
/// Fl_Tree *tree = (Fl_Tree*)w;
@ -168,13 +167,18 @@
/// }
/// \endcode
///
/// To get the item's full menu pathname, you can use Fl_Tree::item_pathname(), eg:
///
/// \par SIMPLE EXAMPLES
/// To find all the selected items:
/// \code
/// for ( Fl_Tree_Item *i=first_selected_item(); i; i=next_selected_item(i) )
/// printf("Item %s is selected\n", i->label());
/// \endcode
/// To get an item's full menu pathname, use Fl_Tree::item_pathname(), e.g.
/// \code
/// char pathname[256] = "???";
/// tree->item_pathname(pathname, sizeof(pathname), item); // eg. "Parent/Child/Item"
/// \endcode
///
/// \par
/// To walk all the items of the tree from top to bottom:
/// \code
/// // Walk all the items in the tree, and print their labels
@ -182,7 +186,7 @@
/// printf("Item: %s\n", item->label());
/// }
/// \endcode
///
/// \par
/// To recursively walk all the children of a particular item,
/// define a function that uses recursion:
/// \code
@ -194,8 +198,8 @@
/// }
/// }
/// \endcode
///
/// To change the default label font and color for creating new items:
/// \par
/// To change the default label font and color when creating new items:
/// \code
/// tree = new Fl_Tree(..);
/// tree->item_labelfont(FL_COURIER); // Use Courier font for all new items
@ -206,8 +210,8 @@
/// tree->add("Bbb");
/// [..]
/// \endcode
///
/// To change the font and color of all items in the tree:
/// \par
/// To change the font and color of all existing items in the tree:
/// \code
/// // Change the font and color of all items currently in the tree
/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) ) {
@ -216,12 +220,19 @@
/// }
/// \endcode
///
/// \par DISPLAY DESCRIPTION
/// The following image shows the tree's various visual elements
/// and the methods that control them:
///
/// \par
/// \image html tree-elements.png
/// \image latex tree-elements.png "Fl_Tree dimensions" width=6cm
/// \image latex tree-elements.png "Fl_Tree elements" width=6cm
/// \par
/// The following shows the protected 'tree inner' (tix..)
/// and 'tree outer' (tox..) dimension variables:
/// \image html tree-dimensions.png "Fl_Tree inner/outer dimensions" width=6cm
/// \image latex tree-dimensions.png "Fl_Tree inner/outer dimensions" width=6cm
///
/// \par KEYBOARD BINDINGS
/// The following table lists keyboard bindings for navigating the tree:
///
/// <TABLE BORDER="1" SUMMARY="Fl_Tree keyboard bindings.">
@ -317,23 +328,36 @@ class FL_EXPORT Fl_Tree : public Fl_Group {
Fl_Tree_Reason _callback_reason; // reason for the callback
Fl_Tree_Prefs _prefs; // all the tree's settings
int _scrollbar_size; // size of scrollbar trough
#if FLTK_ABI_VERSION >= 10301
// NEW:
Fl_Tree_Item *_lastselect;
#else /*FLTK_ABI_VERSION*/
// OLD: static data inside handle() method
#endif /*FLTK_ABI_VERSION*/
void fix_scrollbar_order();
protected:
Fl_Scrollbar *_vscroll; ///< Vertical scrollbar
Fl_Scrollbar *_vscroll; ///< Vertical scrollbar
#if FLTK_ABI_VERSION >= 10303
Fl_Scrollbar *_hscroll; ///< Horizontal scrollbar
int _tox,_toy,_tow,_toh; ///< Tree widget outer xywh dimension: outside scrollbars, inside widget border
int _tix,_tiy,_tiw,_tih; ///< Tree widget inner xywh dimension: inside borders + scrollbars
/// the calculated width of the entire tree hierarchy. See calc_tree()
int _tree_w;
/// the calculated height of the entire tree hierarchy. See calc_tree()
int _tree_h;
#endif
void item_clicked(Fl_Tree_Item* val);
void do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason);
#if FLTK_ABI_VERSION >= 10303
// next_visible_item() and extend_selection() moved to 'public' in ABI 1.3.3
// undocmented draw_tree() dropped -- draw() does all the work now
#else
Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
void extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to);
int draw_tree();
#endif
public:
Fl_Tree(int X, int Y, int W, int H, const char *L=0);
@ -341,7 +365,8 @@ public:
int handle(int e);
void draw();
void show_self();
void resize(int,int,int,int);
///////////////////////
// root methods
///////////////////////
@ -352,7 +377,7 @@ public:
// Item creation/removal methods
////////////////////////////////
Fl_Tree_Item *add(const char *path);
Fl_Tree_Item* add(Fl_Tree_Item *item, const char *name);
Fl_Tree_Item* add(Fl_Tree_Item *parent_item, const char *name);
Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name);
Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos);
int remove(Fl_Tree_Item *item);
@ -368,15 +393,25 @@ public:
const Fl_Tree_Item *find_clicked() const;
Fl_Tree_Item *item_clicked();
Fl_Tree_Item *first();
Fl_Tree_Item *first_visible();
Fl_Tree_Item *first_visible(); // deprecated in ABI 10303
Fl_Tree_Item *first_visible_item();
Fl_Tree_Item *next(Fl_Tree_Item *item=0);
Fl_Tree_Item *prev(Fl_Tree_Item *item=0);
Fl_Tree_Item *last();
Fl_Tree_Item *last_visible();
Fl_Tree_Item *first_selected_item();
Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0);
Fl_Tree_Item *last_visible(); // deprecated in ABI 10303
Fl_Tree_Item *last_visible_item();
#if FLTK_ABI_VERSION >= 10303
Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
#endif
Fl_Tree_Item *first_selected_item();
Fl_Tree_Item *last_selected_item();
Fl_Tree_Item *next_item(Fl_Tree_Item *item, int dir=FL_Down, bool visible=false);
#if FLTK_ABI_VERSION >= 10303
Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0, int dir=FL_Down);
int get_selected_items(Fl_Tree_Item_Array &items);
#else
Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0);
Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item, int dir);
#endif
//////////////////////////
@ -403,6 +438,18 @@ public:
int deselect_all(Fl_Tree_Item *item=0, int docallback=1);
int select_only(Fl_Tree_Item *selitem, int docallback=1);
int select_all(Fl_Tree_Item *item=0, int docallback=1);
#if FLTK_ABI_VERSION >= 10303
void extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to);
int extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to, int dir, int val, bool visible);
int extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to, int val, bool visible);
#else
// Adding overload if not at least one overload breaks ABI, so avoid
// See: http://www.ros.org/reps/rep-0009.html
private:
int extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to, int dir, int val, bool visible);
int extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to, int val, bool visible);
public:
#endif
void set_item_focus(Fl_Tree_Item *item);
Fl_Tree_Item *get_item_focus() const;
int is_selected(Fl_Tree_Item *item) const;
@ -473,7 +520,10 @@ public:
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;
void calc_dimensions();
void calc_tree();
#endif
void recalc_tree();
int displayed(Fl_Tree_Item *item);
void show_item(Fl_Tree_Item *item, int yoff);
void show_item(Fl_Tree_Item *item);
@ -483,11 +533,14 @@ public:
void display(Fl_Tree_Item *item);
int vposition() const;
void vposition(int pos);
int hposition() const;
void hposition(int pos);
int is_scrollbar(Fl_Widget *w);
int scrollbar_size() const;
void scrollbar_size(int size);
int is_vscroll_visible() const;
int is_hscroll_visible() const;
///////////////////////
// callback related

View File

@ -36,7 +36,8 @@
/// \brief This file contains the definitions for Fl_Tree_Item
///
/// \brief Tree item
/// \class Fl_Tree_Item
/// \brief Tree widget item.
///
/// This class is a single tree item, and manages all of the item's attributes.
/// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item.
@ -51,13 +52,23 @@
/// When you make changes to items, you'll need to tell the tree to redraw()
/// for the changes to show up.
///
class Fl_Tree;
class FL_EXPORT Fl_Tree_Item {
#if FLTK_ABI_VERSION >= 10303
Fl_Tree *_tree; // parent tree
#endif
const char *_label; // label (memory managed)
Fl_Font _labelfont; // label's font face
Fl_Fontsize _labelsize; // label's font size
Fl_Color _labelfgcolor; // label's fg color
Fl_Color _labelbgcolor; // label's bg color (0xffffffff is 'transparent')
#if FLTK_ABI_VERSION >= 10303
/// \enum Fl_Tree_Item_Flags
enum Fl_Tree_Item_Flags {
#else
/// \enum
enum {
#endif
OPEN = 1<<0, ///> item is open
VISIBLE = 1<<1, ///> item is visible
ACTIVE = 1<<2, ///> item is active
@ -86,12 +97,18 @@ class FL_EXPORT Fl_Tree_Item {
Fl_Tree_Item *_next_sibling; // next sibling (same level)
#endif /*FLTK_ABI_VERSION*/
protected:
void _Init(const Fl_Tree_Prefs &prefs, Fl_Tree *tree);
void show_widgets();
void hide_widgets();
void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs);
void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs);
void recalc_tree();
const Fl_Tree_Item* find_clicked_(const Fl_Tree_Prefs &prefs, int yonly=0) const; // internal
public:
Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR
Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR -- backwards compatible
#if FLTK_ABI_VERSION >= 10303
Fl_Tree_Item(Fl_Tree *tree); // CTOR -- ABI 1.3.3+
#endif
~Fl_Tree_Item(); // DTOR
Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR
int x() const { return(_xywh[0]); }
@ -103,7 +120,12 @@ public:
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;
#if FLTK_ABI_VERSION >= 10303
void draw(int X, int &Y, int W, Fl_Tree_Item *itemfocus,
int &tree_item_xmax, int lastchild=1, int render=1);
#else
void draw(int X, int &Y, int W, Fl_Widget *tree, Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1);
#endif
void show_self(const char *indent = "") const;
void label(const char *val);
const char *label() const;
@ -117,6 +139,7 @@ public:
/// Set item's label font face.
void labelfont(Fl_Font val) {
_labelfont = val;
recalc_tree(); // may change tree geometry
}
/// Get item's label font face.
Fl_Font labelfont() const {
@ -125,6 +148,7 @@ public:
/// Set item's label font size.
void labelsize(Fl_Fontsize val) {
_labelsize = val;
recalc_tree(); // may change tree geometry
}
/// Get item's label font size.
Fl_Fontsize labelsize() const {
@ -159,6 +183,7 @@ public:
/// Assign an FLTK widget to this item.
void widget(Fl_Widget *val) {
_widget = val;
recalc_tree(); // may change tree geometry
}
/// Return FLTK widget assigned to this item.
Fl_Widget *widget() const {
@ -202,8 +227,10 @@ public:
Fl_Tree_Item *next_sibling();
Fl_Tree_Item *prev_sibling();
void update_prev_next(int index);
Fl_Tree_Item *next_displayed(Fl_Tree_Prefs &prefs);
Fl_Tree_Item *prev_displayed(Fl_Tree_Prefs &prefs);
Fl_Tree_Item *next_displayed(Fl_Tree_Prefs &prefs); // deprecated
Fl_Tree_Item *prev_displayed(Fl_Tree_Prefs &prefs); // deprecated
Fl_Tree_Item *next_visible(Fl_Tree_Prefs &prefs);
Fl_Tree_Item *prev_visible(Fl_Tree_Prefs &prefs);
/// Return the parent for this item. Returns NULL if we are the root.
Fl_Tree_Item *parent() {
@ -219,6 +246,12 @@ public:
void parent(Fl_Tree_Item *val) {
_parent = val;
}
#if FLTK_ABI_VERSION >= 10303
/// Return the tree for this item.
const Fl_Tree *tree() const {
return(_tree);
}
#endif
//////////////////
// State
//////////////////
@ -234,7 +267,7 @@ public:
}
/// Toggle the item's open/closed state.
void open_toggle() {
is_open()?close():open();
is_open()?close():open(); // handles calling recalc_tree()
}
/// Change the item's selection state to the optionally specified 'val'.
/// If 'val' is not specified, the item will be selected.
@ -335,6 +368,7 @@ public:
/// Set the item's user icon to an Fl_Image. '0' will disable.
void usericon(Fl_Image *val) {
_usericon = val;
recalc_tree(); // may change tree geometry
}
/// Get the item's user icon as an Fl_Image. Returns '0' if disabled.
Fl_Image *usericon() const {
@ -343,8 +377,8 @@ public:
//////////////////
// Events
//////////////////
const Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs) const;
Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs);
const Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs, int yonly=0) const;
Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs, int yonly=0);
int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const;
int event_on_label(const Fl_Tree_Prefs &prefs) const;
/// Is this item the root of the tree?
@ -357,6 +391,9 @@ protected:
#if FLTK_ABI_VERSION >= 10301
/// Set a flag to an on or off value. val is 0 or 1.
inline void set_flag(unsigned short flag,int val) {
if ( flag==OPEN || flag==VISIBLE ) {
recalc_tree(); // may change tree geometry
}
if ( val ) _flags |= flag; else _flags &= ~flag;
}
/// See if flag set. Returns 0 or 1.

View File

@ -11,7 +11,7 @@
// FL/Fl_Tree_Prefs.H
//////////////////////
//
// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
// Fl_Tree_Prefs -- This file is part of the Fl_Tree widget for FLTK
// Copyright (C) 2009-2010 by Greg Ercolano.
//
// This library is free software. Distribution and use rights are outlined in

File diff suppressed because it is too large Load Diff

View File

@ -35,9 +35,20 @@ static int event_inside(const int xywh[4]) {
}
/// Constructor.
/// Makes a new instance of Fl_Tree_Item using defaults from 'prefs'.
/// Makes a new instance of Fl_Tree_Item using defaults from \p 'prefs'.
/// \deprecated in 1.3.3 ABI -- use Fl_Tree_Item(Fl_Tree*) instead.
///
Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) {
_Init(prefs, 0);
}
// Initialize the tree item
// Used by constructors
//
void Fl_Tree_Item::_Init(const Fl_Tree_Prefs &prefs, Fl_Tree *tree) {
#if FLTK_ABI_VERSION >= 10303
_tree = tree;
#endif
_label = 0;
_labelfont = prefs.labelfont();
_labelsize = prefs.labelsize();
@ -76,6 +87,15 @@ Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) {
#endif /*FLTK_ABI_VERSION*/
}
#if FLTK_ABI_VERSION >= 10303
/// Constructor.
/// Makes a new instance of Fl_Tree_Item for \p 'tree'.
///
Fl_Tree_Item::Fl_Tree_Item(Fl_Tree *tree) {
_Init(tree->_prefs, tree);
}
#endif
// DTOR
Fl_Tree_Item::~Fl_Tree_Item() {
if ( _label ) {
@ -89,6 +109,9 @@ Fl_Tree_Item::~Fl_Tree_Item() {
/// Copy constructor.
Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) {
#if FLTK_ABI_VERSION >= 10303
_tree = o->_tree;
#endif
_label = o->label() ? strdup(o->label()) : 0;
_labelfont = o->labelfont();
_labelsize = o->labelsize();
@ -149,10 +172,13 @@ void Fl_Tree_Item::show_self(const char *indent) const {
fflush(stdout);
}
/// Set the label. Makes a copy of the name.
/// Set the label to \p 'name'.
/// Makes and manages an internal copy of \p 'name'.
///
void Fl_Tree_Item::label(const char *name) {
if ( _label ) { free((void*)_label); _label = 0; }
_label = name ? strdup(name) : 0;
recalc_tree(); // may change label geometry
}
/// Return the label.
@ -168,9 +194,11 @@ const Fl_Tree_Item *Fl_Tree_Item::child(int index) const {
/// Clear all the children for this item.
void Fl_Tree_Item::clear_children() {
_children.clear();
recalc_tree(); // may change tree geometry
}
/// Return the index of the immediate child of this item that has the label 'name'.
/// Return the index of the immediate child of this item
/// that has the label \p 'name'.
///
/// \returns index of found item, or -1 if not found.
///
@ -187,7 +215,8 @@ int Fl_Tree_Item::find_child(const char *name) {
return(-1);
}
/// Find child item by descending array of names. Does not include self in search.
/// Find child item by descending array \p 'arr' of names.
/// Does not include self in search.
/// Only Fl_Tree should need this method.
///
/// \returns item, or 0 if not found
@ -207,7 +236,8 @@ const Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) const {
return(0);
}
/// Find child item by descending array of names. Does not include self in search.
/// Find child item by descending array \p 'arr' of names.
/// Does not include self in search.
/// Only Fl_Tree should need this method. Use Fl_Tree::find_item() instead.
///
/// \returns item, or 0 if not found
@ -227,7 +257,8 @@ Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) {
return(0);
}
/// Find item by descending array of \p names. Includes self in search.
/// Find item by descending array of \p 'names'.
/// Includes self in search.
/// Only Fl_Tree should need this method. Use Fl_Tree::find_item() instead.
///
/// \returns item, or 0 if not found
@ -244,7 +275,8 @@ const Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) const {
return(0);
}
/// Find item by descending array of \p names. Includes self in search.
/// Find item by descending array of \p 'names'.
/// Includes self in search.
/// Only Fl_Tree should need this method.
///
/// \returns item, or 0 if not found
@ -261,7 +293,7 @@ Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) {
return(0);
}
/// Find the index number for the specified 'item'
/// Find the index number for the specified \p 'item'
/// in the current item's list of children.
///
/// \returns the index, or -1 if not found.
@ -275,12 +307,18 @@ int Fl_Tree_Item::find_child(Fl_Tree_Item *item) {
return(-1);
}
/// Add a new child to this item with the name 'new_label', with defaults from 'prefs'.
/// Add a new child to this item with the name \p 'new_label'
/// and defaults from \p 'prefs'.
/// An internally managed copy is made of the label string.
/// Adds the item based on the value of prefs.sortorder().
///
Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_label) {
#if FLTK_ABI_VERSION >= 10303
Fl_Tree_Item *item = new Fl_Tree_Item(_tree);
#else
Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
#endif
recalc_tree(); // may change tree geometry
item->label(new_label);
item->_parent = this;
switch ( prefs.sortorder() ) {
@ -314,7 +352,7 @@ Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_labe
return(item);
}
/// Descend into the path specified by \p arr, and add a new child there.
/// Descend into the path specified by \p 'arr', and add a new child there.
/// Should be used only by Fl_Tree's internals.
/// Adds the item based on the value of prefs.sortorder().
/// \returns the item added.
@ -327,6 +365,7 @@ Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) {
} else {
item = (Fl_Tree_Item*)child(t);
}
recalc_tree(); // may change tree geometry
if ( *(arr+1) ) { // descend?
return(item->add(prefs, arr+1));
} else {
@ -334,18 +373,24 @@ Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) {
}
}
/// Insert a new item into current item's children at a specified position.
/// Insert a new item named \p 'new_label' into current item's
/// children at a specified position \p 'pos'.
/// \returns the new item inserted.
///
Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) {
#if FLTK_ABI_VERSION >= 10303
Fl_Tree_Item *item = new Fl_Tree_Item(_tree);
#else
Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
#endif
item->label(new_label);
item->_parent = this;
_children.insert(pos, item);
recalc_tree(); // may change tree geometry
return(item);
}
/// Insert a new item above this item.
/// Insert a new item named \p 'new_label' above this item.
/// \returns the new item inserted, or 0 if an error occurred.
///
Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char *new_label) {
@ -361,21 +406,22 @@ Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char
return(0);
}
/// Remove child by item.
/// \returns 0 if removed, -1 if item not an immediate child.
/// Remove \p 'item' from the current item's children.
/// \returns 0 if removed, -1 if item not an immediate child.
///
int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) {
for ( int t=0; t<children(); t++ ) {
if ( child(t) == item ) {
item->clear_children();
_children.remove(t);
recalc_tree(); // may change tree geometry
return(0);
}
}
return(-1);
}
/// Remove immediate child (and its children) by its label 'name'.
/// Remove immediate child (and its children) by its label \p 'name'.
/// \returns 0 if removed, -1 if not found.
///
int Fl_Tree_Item::remove_child(const char *name) {
@ -383,6 +429,7 @@ int Fl_Tree_Item::remove_child(const char *name) {
if ( child(t)->label() ) {
if ( strcmp(child(t)->label(), name) == 0 ) {
_children.remove(t);
recalc_tree(); // may change tree geometry
return(0);
}
}
@ -390,30 +437,23 @@ int Fl_Tree_Item::remove_child(const char *name) {
return(-1);
}
/// Swap two of our children, given two child index values.
/// Use this eg. for sorting.
///
/// This method is FAST, and does not involve lookups.
///
/// Swap two of our children, given two child index values \p 'ax' and \p 'bx'.
/// Use e.g. for sorting.<br>
/// This method is FAST, and does not involve lookups.<br>
/// No range checking is done on either index value.
///
/// \returns
/// - 0 : OK
/// - -1 : failed: 'a' or 'b' is not our immediate child
///
void Fl_Tree_Item::swap_children(int ax, int bx) {
_children.swap(ax, bx);
}
/// Swap two of our children, given item pointers.
/// Use this eg. for sorting.
/// Swap two of our immediate children, given item pointers.
/// Use e.g. for sorting.
///
/// This method is SLOW because it involves linear lookups.
/// This method is SLOW because it involves linear lookups.<br>
/// For speed, use swap_children(int,int) instead.
///
/// \returns
/// - 0 : OK
/// - -1 : failed: 'a' or 'b' is not our immediate child
/// - -1 : failed: item \p 'a' or \p 'b' is not our child.
///
int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) {
int ax = -1, bx = -1;
@ -470,28 +510,31 @@ void Fl_Tree_Item::draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_
}
}
/// Find the item that the last event was over.
///
/// Returns the item if it is visible, and mouse is over it.
/// Works even if widget deactivated.
/// Use event_on_collapse_icon() to determine if collapse button was pressed.
///
/// \returns const visible item under the event if found, or 0 if none.
///
const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) const {
// Internal
// Find the item that the last event was over.
// If \p 'yonly' is 1, only check event's y value, don't care about x.
//
const Fl_Tree_Item *Fl_Tree_Item::find_clicked_(const Fl_Tree_Prefs &prefs, int yonly) const {
if ( ! is_visible() ) return(0);
if ( is_root() && !prefs.showroot() ) {
// skip event check if we're root but root not being shown
} else {
// See if event is over us
if ( event_inside(_xywh) ) { // event within this item?
return(this); // found
if ( yonly ) {
if ( Fl::event_y() >= _xywh[1] &&
Fl::event_y() <= (_xywh[1]+_xywh[3]) ) {
return(this);
}
} else {
if ( event_inside(_xywh) ) { // event within this item?
return(this); // found
}
}
}
if ( is_open() ) { // open? check children of this item
for ( int t=0; t<children(); t++ ) {
const Fl_Tree_Item *item;
if ( ( item = _children[t]->find_clicked(prefs) ) != NULL) { // check child and its descendents
if ( (item = _children[t]->find_clicked(prefs, yonly)) != NULL) { // check child and its descendents
return(item); // found?
}
}
@ -499,34 +542,24 @@ const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) const
return(0);
}
/// Non-const version of the above.
/// Find the item that the last event was over.
/// There is both a const and non-const version of this method.
///
/// Returns the item if it is visible, and mouse is over it.
/// Works even if widget deactivated.
/// Use event_on_collapse_icon() to determine if collapse button was pressed.
/// Returns the item if it is visible, and mouse is over it.
/// Works even if widget deactivated.
/// Use event_on_collapse_icon() to determine if collapse button was pressed.
///
/// \returns the visible item under the event if found, or 0 if none.
/// If \a yonly is set, only the mouse Y position is checked.
///
Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) {
if ( ! is_visible() ) return(0);
if ( is_root() && !prefs.showroot() ) {
// skip event check if we're root but root not being shown
} else {
// See if event is over us
if ( event_inside(_xywh) ) { // event within this item?
return(this); // found
}
}
if ( is_open() ) { // open? check children of this item
for ( int t=0; t<children(); t++ ) {
Fl_Tree_Item *item;
if ( ( item = _children[t]->find_clicked(prefs) ) != NULL ) { // check child and its descendents
return(item); // found?
}
}
}
return(0);
/// \returns const visible item under the event if found, or 0 if none.
///
const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs, int yonly) const {
return(find_clicked_(prefs, yonly));
}
/// A const version of Fl_Tree_Item::find_clicked()
Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs, int yonly) {
return((Fl_Tree_Item*)find_clicked_(prefs, yonly));
}
static void draw_item_focus(Fl_Boxtype B, Fl_Color fg, Fl_Color bg, int X, int Y, int W, int H) {
@ -570,7 +603,7 @@ static void draw_item_focus(Fl_Boxtype B, Fl_Color fg, Fl_Color bg, int X, int Y
}
/// Return the item's 'visible' height.
/// Doesn't include linespacing(); prevents affecting eg. height of widget().
/// Doesn't include linespacing(); prevents affecting e.g. height of widget().
///
int Fl_Tree_Item::calc_item_height(const Fl_Tree_Prefs &prefs) const {
if ( ! is_visible() ) return(0);
@ -593,7 +626,235 @@ int Fl_Tree_Item::calc_item_height(const Fl_Tree_Prefs &prefs) const {
return(H);
}
#if FLTK_ABI_VERSION >= 10303
/// Draw this item and its children.
///
/// \param[in] X Horizontal position for item being drawn
/// \param[in,out] Y Vertical position for item being drawn, returns new position for next item
/// \param[in] W Recommended width of item
/// \param[in] itemfocus The tree's current focus item (if any)
/// \param[in,out] tree_item_xmax The tree's running xmax (right-most edge so far).
/// Mainly used by parent tree when render==0 to calculate tree's max width.
/// \param[in] lastchild Is this item the last child in a subtree?
/// \param[in] render Whether or not to render the item:
/// - 0 -- no rendering, just calculate size.
/// (used to calculate size of tree without doing drawing)
/// - 1 -- render the item as well as doing size calculations
///
void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Tree_Item *itemfocus,
int &tree_item_xmax, int lastchild, int render) {
Fl_Tree_Prefs &prefs = _tree->_prefs;
if ( !is_visible() ) return;
int tree_top = _tree->_tiy;
int tree_bot = tree_top + _tree->_tih;
int H = calc_item_height(prefs); // height of item
int H2 = H + prefs.linespacing(); // height of item with line spacing
// Update the xywh of this item
_xywh[0] = X;
_xywh[1] = Y;
_xywh[2] = W;
_xywh[3] = H;
// Determine collapse icon's xywh
// Note: calculate collapse icon's xywh for possible mouse click detection.
// We don't care about items clipped off the viewport; they won't get mouse events.
//
int item_y_center = Y+(H/2);
_collapse_xywh[2] = prefs.openicon()->w();
int &icon_w = _collapse_xywh[2];
_collapse_xywh[0] = X + (icon_w + prefs.connectorwidth())/2 - 3;
int &icon_x = _collapse_xywh[0];
_collapse_xywh[1] = item_y_center - (prefs.openicon()->h()/2);
int &icon_y = _collapse_xywh[1];
_collapse_xywh[3] = prefs.openicon()->h();
// Horizontal connector values
// Must calculate these even if(clipped) because 'draw children' code (below)
// needs hconn_x_center value. (Otherwise, these calculations could be 'clipped')
//
int hconn_x = X+icon_w/2-1;
int hconn_x2 = hconn_x + prefs.connectorwidth();
int hconn_x_center = X + icon_w + ((hconn_x2 - (X + icon_w)) / 2);
int cw1 = icon_w+prefs.connectorwidth()/2, cw2 = prefs.connectorwidth();
int conn_w = cw1>cw2 ? cw1 : cw2;
// Background xywh
int &bg_x = _label_xywh[0] = X+(icon_w/2-1+conn_w);
int &bg_y = _label_xywh[1] = Y;
int &bg_w = _label_xywh[2] = _tree->_tix + _tree->_tiw - bg_x;
int &bg_h = _label_xywh[3] = H;
// Usericon position
int uicon_x = bg_x + ( (usericon() || prefs.usericon()) ? prefs.usericonmarginleft() : 0);
int uicon_w = usericon() ? usericon()->w() : prefs.usericon() ? prefs.usericon()->w() : 0;
// Label position
int label_x = uicon_x + uicon_w + (_label ? prefs.labelmarginleft() : 0);
// Begin calc of this item's max width..
// It might not even be visible, so start at zero.
//
int ixmax = 0;
// Recalc widget position
// Do this whether clipped or not, so that when scrolled,
// the widgets move to appropriate 'offscreen' positions
// (so that they don't get mouse events, etc)
//
if ( widget() ) {
int wx = label_x;
int wy = bg_y;
int ww = widget()->w(); // use widget's width
int wh = (prefs.item_draw_mode() & FL_TREE_ITEM_HEIGHT_FROM_WIDGET)
? widget()->h() : H;
if ( _label &&
(prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) {
fl_font(_labelfont, _labelsize); // fldescent() needs this
int lw=0, lh=0;
fl_measure(_label,lw,lh); // get box around text (including white space)
wx += (lw + prefs.widgetmarginleft());
}
if ( widget()->x() != wx || widget()->y() != wy ||
widget()->w() != ww || widget()->h() != wh ) {
widget()->resize(wx,wy,ww,wh); // we'll handle redraw below
}
}
char clipped = ((Y+H) < tree_top) || (Y>tree_bot) ? 1 : 0;
if (!render) clipped = 0; // NOT rendering? Then don't clip, so we calc unclipped items
char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1;
if ( !clipped ) {
Fl_Color fg = is_selected() ? fl_contrast(_labelfgcolor, _tree->selection_color())
: is_active() ? _labelfgcolor
: fl_inactive(_labelfgcolor);
Fl_Color bg = is_selected() ? is_active() ? _tree->selection_color()
: fl_inactive(_tree->selection_color())
: _labelbgcolor == 0xffffffff ? _tree->color() // transparent bg?
: _labelbgcolor;
// See if we should draw this item
// If this item is root, and showroot() is disabled, don't draw.
// 'clipped' is an optimization to prevent drawing anything offscreen.
//
if ( drawthis ) { // draw this item at all?
if ( (_tree->damage() & ~FL_DAMAGE_CHILD) || !render ) { // non-child damage?
// Draw connectors
if ( render && prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) {
// Horiz connector between center of icon and text
// if this is root, the connector should not dangle in thin air on the left
if (is_root()) draw_horizontal_connector(hconn_x_center, hconn_x2, item_y_center, prefs);
else draw_horizontal_connector(hconn_x, hconn_x2, item_y_center, prefs);
// Small vertical line down to children
if ( has_children() && is_open() )
draw_vertical_connector(hconn_x_center, item_y_center, Y+H2, prefs);
// Connectors for last child
if ( !is_root() ) {
if ( lastchild ) draw_vertical_connector(hconn_x, Y, item_y_center, prefs);
else draw_vertical_connector(hconn_x, Y, Y+H2, prefs);
}
}
// Draw collapse icon
if ( render && has_children() && prefs.showcollapse() ) {
// Draw icon image
if ( is_open() ) {
prefs.closeicon()->draw(icon_x,icon_y);
} else {
prefs.openicon()->draw(icon_x,icon_y);
}
}
// Background for this item
// Draw bg only if different from tree's bg
if ( render && (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
}
// Draw user icon (if any)
if ( render && usericon() ) {
// Item has user icon? Use it
int uicon_y = item_y_center - (usericon()->h() >> 1);
usericon()->draw(uicon_x,uicon_y);
} else if ( render && 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 ( _label &&
( !widget() ||
(prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) ) {
if ( render ) {
fl_color(fg);
fl_font(_labelfont, _labelsize);
}
int label_y = Y+(H/2)+(_labelsize/2)-fl_descent()/2;
int lw=0, lh=0;
fl_measure(_label, lw, lh); // get box around text (including white space)
if ( render ) fl_draw(_label, label_x, label_y);
ixmax = label_x + lw; // update max width of drawn item
}
} // end non-child damage
// Draw child FLTK widget?
if ( widget() ) {
if (render)
_tree->draw_child(*widget()); // let group handle drawing child
if ( widget()->label() && render )
_tree->draw_outside_label(*widget()); // label too
ixmax = widget()->x() + widget()->w(); // update max width of widget
}
// Draw focus box around item's bg last
if ( render &&
this == itemfocus &&
Fl::visible_focus() &&
Fl::focus() == _tree &&
prefs.selectmode() != FL_TREE_SELECT_NONE ) {
draw_item_focus(FL_NO_BOX,fg,bg,bg_x+1,bg_y+1,bg_w-1,bg_h-1);
}
} // end drawthis
} // end clipped
if ( drawthis ) Y += H2; // adjust Y (even if clipped)
// Manage tree_item_xmax
if ( ixmax > tree_item_xmax )
tree_item_xmax = ixmax;
// Draw child items (if any)
if ( has_children() && is_open() ) {
int child_x = drawthis ? (hconn_x_center - (icon_w/2) + 1) // offset children to right,
: X; // unless didn't drawthis
int child_w = W - (child_x-X);
int child_y_start = Y;
for ( int t=0; t<children(); t++ ) {
int lastchild = ((t+1)==children()) ? 1 : 0;
_children[t]->draw(child_x, Y, child_w, itemfocus, tree_item_xmax, lastchild, render);
}
if ( has_children() && is_open() ) {
Y += prefs.openchild_marginbottom(); // offset below open child tree
}
if ( ! lastchild ) {
// Special 'clipped' calculation. (intentional variable shadowing)
int clipped = ((child_y_start < tree_top) && (Y < tree_top)) ||
((child_y_start > tree_bot) && (Y > tree_bot));
if (render && !clipped )
draw_vertical_connector(hconn_x, child_y_start, Y, prefs);
}
}
}
#else
/// Draw this item and its children.
///
/// \param[in] X Horizontal position for item being drawn
/// \param[in,out] Y Vertical position for item being drawn, returns new position for next item
/// \param[in] W Recommended width of item
/// \param[in] tree The parent tree
/// \param[in] itemfocus The tree's current focus item (if any)
/// \param[in] prefs The tree's preferences
/// \param[in] lastchild Is this item the last child in a subtree?
///
void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
Fl_Tree_Item *itemfocus,
const Fl_Tree_Prefs &prefs, int lastchild) {
@ -802,8 +1063,9 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
}
}
}
#endif
/// Was the event on the 'collapse' button?
/// Was the event on the 'collapse' button of this item?
///
int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const {
if ( is_visible() && is_active() && has_children() && prefs.showcollapse() ) {
@ -813,7 +1075,7 @@ int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const {
}
}
/// Was event on the label()?
/// Was event on the label() of this item?
///
int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const {
if ( is_visible() && is_active() ) {
@ -852,6 +1114,7 @@ void Fl_Tree_Item::open() {
for ( int t=0; t<_children.total(); t++ ) {
_children[t]->show_widgets();
}
recalc_tree(); // may change tree geometry
}
/// Close this item and all its children.
@ -861,12 +1124,14 @@ void Fl_Tree_Item::close() {
for ( int t=0; t<_children.total(); t++ ) {
_children[t]->hide_widgets();
}
recalc_tree(); // may change tree geometry
}
/// Returns how many levels deep this item is in the hierarchy.
///
/// For instance; root has a depth of zero, and its immediate children
/// would have a depth of 1, and so on.
/// would have a depth of 1, and so on. Use e.g. for determining the
/// horizontal indent of this item during drawing.
///
int Fl_Tree_Item::depth() const {
int count = 0;
@ -914,7 +1179,8 @@ Fl_Tree_Item *Fl_Tree_Item::next() {
/// This method can be used to walk the tree backwards.
/// For an example of how to use this method, see Fl_Tree::last().
///
/// \returns the previous item in the tree, or 0 if there's no item above this one (hit the root).
/// \returns the previous item in the tree,
/// or 0 if there's no item above this one (hit the root).
///
Fl_Tree_Item *Fl_Tree_Item::prev() {
#if FLTK_ABI_VERSION >= 10301
@ -965,7 +1231,7 @@ Fl_Tree_Item *Fl_Tree_Item::prev() {
/// Return this item's next sibling.
///
/// Moves to the next item below us at the same level (sibling).
/// Use this to move down the tree without moving deeper into the tree,
/// Use this to move down the tree without changing depth().
/// effectively skipping over this item's children/descendents.
///
/// \returns item's next sibling, or 0 if none.
@ -988,7 +1254,7 @@ Fl_Tree_Item *Fl_Tree_Item::next_sibling() {
/// Return this item's previous sibling.
///
/// Moves to the previous item above us at the same level (sibling).
/// Use this to move up the tree without moving deeper into the tree.
/// Use this to move up the tree without changing depth().
///
/// \returns This item's previous sibling, or 0 if none.
///
@ -1006,7 +1272,7 @@ Fl_Tree_Item *Fl_Tree_Item::prev_sibling() {
#endif /*FLTK_ABI_VERSION*/
}
/// Update our _prev_sibling and _next_sibling pointers to point to neighbors,
/// Update our _prev_sibling and _next_sibling pointers to point to neighbors
/// given \p index as being our current position in the parent's item array.
/// Call this whenever items in the array are added/removed/moved/swapped.
///
@ -1031,14 +1297,16 @@ void Fl_Tree_Item::update_prev_next(int index) {
#endif /*FLTK_ABI_VERSION*/
}
/// Return the next visible item. (If this item has children and is closed, children are skipped)
/// Return the next open(), visible() item.
/// (If this item has children and is closed, children are skipped)
///
/// This method can be used to walk the tree forward, skipping items
/// that are not currently visible to the user.
/// that are not currently open/visible to the user.
///
/// \returns the next visible item below us, or 0 if there's no more items.
/// \returns the next open() visible() item below us,
/// or 0 if there's no more items.
///
Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) {
Fl_Tree_Item *Fl_Tree_Item::next_visible(Fl_Tree_Prefs &prefs) {
Fl_Tree_Item *item = this;
while ( 1 ) {
item = item->next();
@ -1048,14 +1316,22 @@ Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) {
}
}
/// Return the previous visible item. (If this item above us has children and is closed, its children are skipped)
/// Same as next_visible().
/// \deprecated in 1.3.3 ABI for confusing name, use next_visible()
Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) {
return next_visible(prefs);
}
/// Return the previous open(), visible() item.
/// (If this item above us has children and is closed, its children are skipped)
///
/// This method can be used to walk the tree backward,
/// skipping items that are not currently visible to the user.
/// skipping items that are not currently open/visible to the user.
///
/// \returns the previous visible item above us, or 0 if there's no more items.
/// \returns the previous open() visible() item above us,
/// or 0 if there's no more items.
///
Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) {
Fl_Tree_Item *Fl_Tree_Item::prev_visible(Fl_Tree_Prefs &prefs) {
Fl_Tree_Item *c = this;
while ( c ) {
c = c->prev(); // previous item
@ -1075,11 +1351,17 @@ Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) {
return(0); // hit end: no more items
}
/// Returns if item and all its parents are visible.
/// Also takes into consideration if any parent is close()ed.
/// Same as prev_visible().
/// \deprecated in 1.3.3 ABI for confusing name, use prev_visible()
///
Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) {
return prev_visible(prefs);
}
/// See if item and all its parents are open() and visible().
/// \returns
/// 1 -- item and its parents are visible/open()
/// 0 -- item (or parents) invisible or close()ed.
/// 1 -- item and its parents are open() and visible()
/// 0 -- item (or one of its parents) are invisible or close()ed.
///
int Fl_Tree_Item::visible_r() const {
if ( !visible() ) return(0);
@ -1088,6 +1370,16 @@ int Fl_Tree_Item::visible_r() const {
return(1);
}
/// Call this when our geometry is changed. (Font size, label contents, etc)
/// Schedules tree to recalculate itself, as changes to us may affect tree
/// widget's scrollbar visibility and tab sizes.
///
void Fl_Tree_Item::recalc_tree() {
#if FLTK_ABI_VERSION >= 10303
_tree->recalc_tree();
#endif
}
//
// End of "$Id$".
//

View File

@ -1,5 +1,5 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0300
version 1.0302
header_name {.h}
code_name {.cxx}
decl {\#include <stdio.h>} {public global
@ -8,6 +8,9 @@ decl {\#include <stdio.h>} {public global
decl {\#include <FL/Fl.H>} {public global
}
decl {\#include <FL/Fl_Tooltip.H>} {public global
}
decl {\#include <FL/Fl_Pixmap.H>} {public global
}
@ -233,11 +236,17 @@ tree->add("Descending/Bbb");
tree->add("Descending/Yyy");
tree->add("Descending/Ccc");
// Add 500 items in numerical order
// Add a long line to trigger horiz scrollbar
tree->sortorder(FL_TREE_SORT_NONE);
tree->add("Long Line")->close();
tree->add("Long Line/The quick brown fox jumped over the lazy dog. 0123456789");
tree->add("Long Line/Longer Line")->close();
tree->add("Long Line/Longer Line/The quick brown fox jumped over the lazy dog. ---------------- 0123456789");
// Add 500 items in numerical order
for ( int t=0; t<500; t++ ) {
static char s[80];
sprintf(s, "500 Items/item %04d", t);
sprintf(s, "500 Items/item %04d", t+1);
tree->add(s);
}
tree->close("500 Items"); // close the 500 items by default
@ -336,7 +345,7 @@ Function {} {open
} {
Fl_Window window {
label tree open
xywh {5 44 1045 580} type Double visible
xywh {0 234 1045 580} type Double visible
} {
Fl_Group tree {
label Tree
@ -367,7 +376,7 @@ tree->clear_changed();} open
class Fl_Tree
} {}
Fl_Group {} {open
xywh {300 5 731 615}
xywh {350 5 681 615}
code0 {o->resizable(0);}
} {
Fl_Box {} {
@ -393,7 +402,7 @@ tree->marginleft(val);
tree->redraw();}
tooltip {Changes the left margin for the tree widget} xywh {505 60 155 16} type Horizontal color 46 selection_color 1 labelsize 10 align 4 textsize 9
code0 {o->value(tree->marginleft());}
code1 {o->range(0.0, 100.0);}
code1 {o->range(0.0, 200.0);}
code2 {o->step(1.0);}
}
Fl_Value_Slider marginbottom_slider {
@ -409,7 +418,7 @@ tree->redraw();
marginbottom_slider->deactivate(); // deactivate if this ABI feature is disabled
marginbottom_slider->tooltip("DISABLED.\\n"
"Set FLTK_ABI_VERSION to 10301 (or higher)\\n"
"to get this feature");
"to enable this feature");
\#endif}
tooltip {Changes the bottom margin for the tree
Sets how far beyond bottom of tree you can scroll} xywh {505 80 155 16} type Horizontal color 46 selection_color 1 labelsize 10 align 4 textsize 9
@ -462,9 +471,11 @@ tree->redraw();
widgetmarginleft_slider->deactivate();
widgetmarginleft_slider->tooltip("DISABLED.\\n"
"Set FLTK_ABI_VERSION to 10301 (or higher)\\n"
"to get this feature");
"to enable this feature");
\#endif}
tooltip {Changes the margin to the left of child FLTK widget()} xywh {505 160 155 16} type Horizontal color 46 selection_color 1 labelsize 10 align 4 textsize 9
tooltip {Changes the margin to the left of child FLTK widget()
"Show label + widget" must be 'on' for this to take effect, i.e.
item_draw_mode(FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET)} xywh {505 160 155 16} type Horizontal color 46 selection_color 1 labelsize 10 align 4 textsize 9
code0 {o->value(GetTreeWidgetMarginLeft()); // handle ABI feature}
code1 {o->range(0.0, 100.0);}
code2 {o->step(1.0);}
@ -580,7 +591,7 @@ switch ( collapseicons_chooser->value() ) {
tree->showcollapse(0);
break;
}}
tooltip {Tests Fl_Tree::openicon() and Fl_Tree::closeicon()} xywh {520 225 140 21} down_box BORDER_BOX labelsize 12 textsize 11
tooltip {Tests Fl_Tree::openicon(), Fl_Tree::closeicon() and Fl_Tree::showcollapse().} xywh {520 225 140 21} down_box BORDER_BOX labelsize 12 textsize 11
} {
MenuItem {} {
label Normal
@ -603,7 +614,7 @@ switch ( connectorstyle_chooser->value() ) {
case 1: tree->connectorstyle(FL_TREE_CONNECTOR_DOTTED); break;
case 2: tree->connectorstyle(FL_TREE_CONNECTOR_SOLID); break;
}}
tooltip {Tests connectorstyle() bit flags} xywh {520 249 140 21} down_box BORDER_BOX labelsize 12 textsize 11
tooltip {Tests Fl_Tree::connectorstyle() bit flags} xywh {520 249 140 21} down_box BORDER_BOX labelsize 12 textsize 11
code0 {switch (tree->connectorstyle()) { case FL_TREE_CONNECTOR_NONE: connectorstyle_chooser->value(0); break; case FL_TREE_CONNECTOR_DOTTED: connectorstyle_chooser->value(1); break; case FL_TREE_CONNECTOR_SOLID: connectorstyle_chooser->value(2); break; }}
} {
MenuItem {} {
@ -628,7 +639,11 @@ switch ( selectmode_chooser->value() ) {
case 2: tree->selectmode(FL_TREE_SELECT_MULTI); break; // Multi
default: tree->selectmode(FL_TREE_SELECT_SINGLE); break; // Single
}}
tooltip {Sets how Fl_Tree handles mouse selection of tree items} xywh {520 273 140 21} down_box BORDER_BOX labelsize 12 textsize 11
tooltip {Tests Fl_Tree::selectmode()
Sets how Fl_Tree handles mouse selection of tree items.
NONE -- Not selectable by keyboard/mouse
SINGLE -- Only one item at a time selectable by keyboard/mouse
MULTI -- Multiple items selectable} xywh {520 273 140 21} down_box BORDER_BOX labelsize 12 textsize 11
code0 {selectmode_chooser->value(2);}
code1 {cb_selectmode_chooser(selectmode_chooser, (void*)0);}
} {
@ -659,11 +674,13 @@ switch ( reselectmode_chooser->value() ) {
reselectmode_chooser->deactivate(); // deactivate if this ABI feature is disabled
reselectmode_chooser->tooltip("DISABLED.\\n"
"Set FLTK_ABI_VERSION to 10301 (or higher)\\n"
"to get this feature");
"to enable this feature");
window->redraw(); // deactivated
\#endif}
tooltip {Enable 'reselect' events
These happen when mouse drags or multi-clicks an item} xywh {520 297 140 21} down_box BORDER_BOX labelsize 12 textsize 11
tooltip {Tests Fl_Tree::item_reselect_mode().
Enables 'reselect' events.
These happen when someone selects an item already selected
(mouse drags or multi-clicks)} xywh {520 297 140 21} down_box BORDER_BOX labelsize 12 textsize 11
code0 {reselectmode_chooser->value(1);}
code1 {reselectmode_chooser->do_callback();}
} {
@ -727,7 +744,7 @@ tree->visible_focus(onoff);}
}
Fl_Check_Button labelandwidget_radio {
label {Show label + widget}
callback {\#if FLTK_ABI_VERSION >= 10301
callback {\#if FLTK_ABI_VERSION >= 10303
// NEW
int flags = tree->item_draw_mode();
if ( labelandwidget_radio->value() )
@ -740,18 +757,20 @@ tree->redraw();
// OLD
labelandwidget_radio->deactivate(); // deactivate if this ABI feature is disabled
labelandwidget_radio->tooltip("DISABLED.\\n"
"Set FLTK_ABI_VERSION to 10301 (or higher)\\n"
"to get this feature");
"Set FLTK_ABI_VERSION to 10303 (or higher)\\n"
"to enable this feature");
window->redraw(); // deactivated
\#endif}
tooltip {Enables both label and widget() for display.
When enabled, widget should appear to the right of the item's label. By default, the widget() is shown in place of the item's label.} xywh {645 356 20 16} down_box DOWN_BOX labelsize 11 align 7
tooltip {Tests Fl_Tree::item_draw_mode(FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET)
Enables both label and widget() for display.
When enabled, widget should appear to the right of the item's label.
By default, the widget() is shown in place of the item's label.} xywh {645 356 20 16} down_box DOWN_BOX labelsize 11 align 7
code0 {labelandwidget_radio->value(0);}
code1 {labelandwidget_radio->do_callback();}
}
Fl_Check_Button itemheightfromwidget_radio {
label {Item h() from widget}
callback {\#if FLTK_ABI_VERSION >= 10301
callback {\#if FLTK_ABI_VERSION >= 10303
// NEW
int flags = tree->item_draw_mode();
if ( itemheightfromwidget_radio->value() )
@ -764,11 +783,12 @@ tree->redraw();
// OLD
itemheightfromwidget_radio->deactivate(); // deactivate if this ABI feature is disabled
itemheightfromwidget_radio->tooltip("DISABLED.\\n"
"Set FLTK_ABI_VERSION to 10301 (or higher)\\n"
"to get this feature");
"Set FLTK_ABI_VERSION to 10303 (or higher)\\n"
"to enable this feature");
window->redraw(); // deactivated
\#endif}
tooltip {If enabled, item's height will track the widget()'s height.
tooltip {Tests Fl_Tree::item_draw_mode(FL_TREE_ITEM_HEIGHT_FROM_WIDGET)
If enabled, item's height will track the widget()'s height.
When enabled, click 'ccc' or 'D1/D2' buttons to test.} xywh {645 371 20 16} down_box DOWN_BOX labelsize 11 align 7
code0 {itemheightfromwidget_radio->value(0);}
code1 {itemheightfromwidget_radio->do_callback();}
@ -877,7 +897,8 @@ switch ( tree->item_pathname(pathname, sizeof(pathname), item) ) {
case -1: fl_message("item_pathname() returned -1 (NOT FOUND)"); break;
case -2: fl_message("item_pathname() returned -2 (STRING TOO LONG)"); break;
}}
tooltip {Show the pathname for the selected item. Tests the Fl_Tree::item_pathname() method.} xywh {470 531 95 16} labelsize 9
tooltip {Tests Fl_Tree::item_pathname()
Show the pathname for the selected item.} xywh {470 531 95 16} labelsize 9
}
Fl_Button closeall_button {
label {Close All}
@ -895,8 +916,8 @@ tree->redraw();}
label {Clear All}
callback {tree->clear();
tree->redraw();}
tooltip {Clears all items
Tests Fl_Tree::clear()} xywh {570 471 95 16} labelsize 9
tooltip {Tests Fl_Tree::clear().
Clears all items} xywh {570 471 95 16} labelsize 9
}
Fl_Button testcallbackflag_button {
label {Test Callback Flag}
@ -1021,7 +1042,9 @@ if ( ! count ) {
}
tree->redraw();}
tooltip {Changes the font for the selected items's labels. If none selected, all are changed. Tests Fl_Tree_Item::labelfont();} xywh {863 31 140 21} down_box BORDER_BOX labelsize 11 textsize 11
tooltip {Tests Fl_Tree_Item::labelfont();
Changes the font for the selected items's labels.
If none selected, all are changed.} xywh {863 31 140 21} down_box BORDER_BOX labelsize 11 textsize 11
code0 {o->value((int)tree->item_labelfont()); // get tree's current font, assign to chooser}
} {
MenuItem {} {
@ -1112,7 +1135,9 @@ if ( ! count ) {
}
tree->redraw();}
tooltip {Changes the font size of the selected items's labels. If none selected, all are changed. Tests Fl_Tree_Item::labelsize();} xywh {863 55 140 16} type Horizontal color 46 selection_color 1 labelsize 11 align 4 textsize 12
tooltip {Tests Fl_Tree_Item::labelsize();
Changes the font size of the selected items's labels.
If none selected, all are changed.} xywh {863 55 140 16} type Horizontal color 46 selection_color 1 labelsize 11 align 4 textsize 12
code0 {o->value(tree->item_labelsize());}
code1 {o->range(5.0, 200.0);}
code2 {o->step(1.0);}
@ -1289,6 +1314,20 @@ tree->redraw();}
tree->redraw();}
tooltip {Deselects all items in the tree} xywh {724 219 95 16} labelsize 9
}
Fl_Button nextselected_button {
label {next_selected()}
callback {printf("--- TEST next_selected():\\n");
printf(" // Walk down the tree (forwards)\\n");
for ( Fl_Tree_Item *i=tree->first_selected_item(); i; i=tree->next_selected_item(i, FL_Down) ) {
printf(" Selected item: %s\\n", i->label()?i->label():"<nolabel>");
}
printf(" // Walk up the tree (backwards)\\n");
for ( Fl_Tree_Item *i=tree->last_selected_item(); i; i=tree->next_selected_item(i, FL_Up) ) {
printf(" Selected item: %s\\n", i->label()?i->label():"<nolabel>");
}}
tooltip {Tests the Fl_Tree::next_selected() function} xywh {723 239 95 16} labelsize 9
}
Fl_Light_Button bbbselect_toggle {
label { Select Bbb}
callback {// Toggle select of just the Bbb item (not children)
@ -1354,19 +1393,19 @@ if ( !item) {
}
int onoff = rootselect2_toggle->value();
if ( onoff ) tree->select_all(item); // select /ROOT and its children
else tree->deselect_all(item); // deselect /ROOT and its children}
else tree->deselect_all(item); // deselect /ROOT and its children} selected
tooltip {Toggle selection of the ROOT item and all children} xywh {914 219 95 16} selection_color 1 labelsize 9
}
Fl_Box {} {
label {Tree Fonts + Colors}
tooltip {These controls only affect the selected items. If no items are selected, all existing items in tree are modified.} xywh {695 298 335 244} box GTK_DOWN_BOX color 47 labelsize 12 align 1
tooltip {These controls only affect the selected items. If no items are selected, all existing items in tree are modified.} xywh {695 298 335 186} box GTK_DOWN_BOX color 47 labelsize 12 align 1
}
Fl_Choice labelfont_choice {
label {labelfont()}
callback {Fl_Font val = (Fl_Font)labelfont_choice->value();
tree->labelfont(val);
window->redraw();}
tooltip {Sets the default font used for new items created. Does NOT affect existing items.} xywh {850 319 140 21} down_box BORDER_BOX labelsize 12 textsize 12
tooltip {Sets the default font used for new items created. Does NOT affect existing items.} xywh {848 314 140 21} down_box BORDER_BOX labelsize 12 textsize 12
code0 {o->value((int)tree->labelfont()); // get tree's current font, assign to chooser}
} {
MenuItem {} {
@ -1440,7 +1479,7 @@ window->redraw();}
callback {tree->labelsize((int)labelsize_slider->value());
window->redraw();}
tooltip {Sets the font size for the tree's label().
This is also the font size that will be used to draw the items IF their size hasn't been set with Fl_Tree_Item::labelsize() or Fl_Tree::item_labelsize()} xywh {850 343 140 16} type Horizontal color 46 selection_color 1 labelsize 12 align 4 textsize 12
This is also the font size that will be used to draw the items IF their size hasn't been set with Fl_Tree_Item::labelsize() or Fl_Tree::item_labelsize()} xywh {848 338 140 16} type Horizontal color 46 selection_color 1 labelsize 12 align 4 textsize 12
code0 {o->value((int)tree->labelsize());}
code1 {o->range(1.0, 50.0);}
code2 {o->step(1.0);}
@ -1452,7 +1491,7 @@ This is also the font size that will be used to draw the items IF their size has
tree->item_labelfont(val);
tree->redraw();}
tooltip {Sets the default font used for new items created.
.Also affects any items whose font has NOT specifically been set with item->labelfont().} xywh {850 363 140 21} down_box BORDER_BOX labelsize 12 textsize 12
.Also affects any items whose font has NOT specifically been set with item->labelfont().} xywh {848 358 140 21} down_box BORDER_BOX labelsize 12 textsize 12
code0 {o->value((int)tree->item_labelfont());}
} {
MenuItem {} {
@ -1526,7 +1565,7 @@ tree->redraw();}
callback {tree->item_labelsize((int)item_labelsize_slider->value());
tree->redraw();}
tooltip {Sets the default font size used for new items created.
.Also affects any items whose font size has NOT specifically been set with item->labelsize().} xywh {850 388 140 16} type Horizontal color 46 selection_color 1 labelsize 12 align 4 textsize 12
.Also affects any items whose font size has NOT specifically been set with item->labelsize().} xywh {848 383 140 16} type Horizontal color 46 selection_color 1 labelsize 12 align 4 textsize 12
code0 {o->value((int)tree->item_labelsize());}
code1 {o->range(1.0, 50.0);}
code2 {o->step(1.0);}
@ -1540,7 +1579,7 @@ labelcolor_button->color(val); // update modified color to button
tree->labelcolor(val);
window->redraw(); // affects window (tree's label is outside tree's area)}
tooltip {Changes Fl_Tree::labelcolor().
This affects the text color of the widget's label.} xywh {815 458 16 16} box DOWN_BOX labelsize 11 align 7
This affects the text color of the widget's label.} xywh {813 414 16 16} box DOWN_BOX labelsize 11 align 7
code0 {o->color(tree->labelcolor());}
}
Fl_Button color_button {
@ -1552,7 +1591,7 @@ tree->color(val);
UpdateColorChips();
tree->redraw();}
tooltip {Changes Fl_Tree::color().
This affects the background color of the widget. It also affects the bg color of newly created items *if* Fl_Tree::item_labelbgcolor() hasn't been changed.} xywh {815 477 16 16} box DOWN_BOX labelsize 11 align 7
This affects the background color of the widget. It also affects the bg color of newly created items *if* Fl_Tree::item_labelbgcolor() hasn't been changed.} xywh {813 433 16 16} box DOWN_BOX labelsize 11 align 7
code0 {o->color(tree->color());}
}
Fl_Button selection_color_button {
@ -1563,7 +1602,7 @@ selection_color_button->color(val); // update modified color to button
tree->selection_color(val);
tree->redraw();}
tooltip {Sets the Fl_Tree::selection_color().
This affects the item's colors when they're selected.} xywh {815 496 16 16} box DOWN_BOX labelsize 11 align 7
This affects the item's colors when they're selected.} xywh {813 452 16 16} box DOWN_BOX labelsize 11 align 7
code0 {o->color(tree->selection_color());}
}
Fl_Button item_labelfgcolor_button {
@ -1573,7 +1612,7 @@ if ( EditColor(val) == 0 ) return; // Let user edit color. (return if they hit
tree->item_labelfgcolor(val); // apply modified color to tree
item_labelfgcolor_button->color(val); // update modified color to button
tree->redraw();}
tooltip {Sets the default label fg color for newly created items.} xywh {975 458 16 16} box DOWN_BOX labelsize 12 align 7
tooltip {Sets the default label fg color for newly created items.} xywh {973 414 16 16} box DOWN_BOX labelsize 12 align 7
code0 {o->color(tree->item_labelfgcolor());}
}
Fl_Button item_labelbgcolor_button {
@ -1583,7 +1622,7 @@ if ( EditColor(val) == 0 ) return; // Let user edit color. (return if they hit
tree->item_labelbgcolor(val); // apply modified color to tree
item_labelbgcolor_button->color(val); // update modified color to button
tree->redraw();}
tooltip {Sets the default label bg color for newly created items. When set, this overrides the default behavior of using Fl_Tree::color().} xywh {975 477 16 16} box DOWN_BOX labelsize 12 align 7
tooltip {Sets the default label bg color for newly created items. When set, this overrides the default behavior of using Fl_Tree::color().} xywh {973 433 16 16} box DOWN_BOX labelsize 12 align 7
code0 {item_labelbgcolor_button->color(tree->item_labelbgcolor());}
}
Fl_Button x_item_labelbgcolor_button {
@ -1591,7 +1630,7 @@ tree->redraw();}
callback {tree->item_labelbgcolor(0xffffffff);
UpdateColorChips();
tree->redraw();}
tooltip {Make the bgcolor 'transparent' (0xffffffff)} xywh {995 477 16 16} labelsize 10 align 16
tooltip {Make the bgcolor 'transparent' (0xffffffff)} xywh {993 433 16 16} labelsize 10 align 16
}
Fl_Button testsuggs_button {
label {Test Suggestions}
@ -1620,23 +1659,50 @@ tree->redraw();}
" 3) Disable same, item labels should disappear,\\n"
" showing the widgets in their place.\\n"
"\\n"
" COLORS\\n"
" ======\\n"
" 1) Start program\\n"
" 2) Change 'Tree Fonts+Colors' -> color()\\n"
" 3) Entire tree's background color will change, including items.\\n"
" 4) Change the 'Tree Fonts + Colors -> item_labelbgcolor()'\\n"
" 6) Click the '111' item to select it.\\n"
" 7) Click 'Test Operations -> Insert Above'\\n"
" New items should appear above the selected item using the new color.\\n"
" This color will be different from the background color.\\n"
" 8) Change the 'Tree Fonts+Colors' -> color()\\n"
" The entire tree's bg should change, except the new items.\\n"
" 9) Click the Tree Fonts+Colors -> item_labelbgcolor() 'X' button.\\n"
" This resets item_labelbgcolor() to the default 'transparent' color (0xffffffff)\\n"
" 10) Again, click the 'Insert Above' button.\\n"
" New items will be created in the background color, and changing the color()\\n"
" should affect the new items too.\\n"
"COLORS\\n"
"======\\n"
" 1) Start program\\n"
" 2) Change 'Tree Fonts+Colors' -> color()\\n"
" 3) Entire tree's background color will change, including items.\\n"
" 4) Change the 'Tree Fonts + Colors -> item_labelbgcolor()'\\n"
" 6) Click the '111' item to select it.\\n"
" 7) Click 'Test Operations -> Insert Above'\\n"
" New items should appear above the selected item using the new color.\\n"
" This color will be different from the background color.\\n"
" 8) Change the 'Tree Fonts+Colors' -> color()\\n"
" The entire tree's bg should change, except the new items.\\n"
" 9) Click the Tree Fonts+Colors -> item_labelbgcolor() 'X' button.\\n"
" This resets item_labelbgcolor() to the default 'transparent' color (0xffffffff)\\n"
" 10) Again, click the 'Insert Above' button.\\n"
" New items will be created in the background color, and changing the color()\\n"
" should affect the new items too.\\n"
"\\n"
"SCROLLING\\n"
"=========\\n"
" 1) Open '500 items' and 'Long Line' so that both scrollbars appear:\\n"
" * The 'focus box' for the selected item should not be clipped\\n"
" horizontally by the vertical scrollbar.\\n"
" * Resizing the window horizontally should resize the focus box\\n"
" * Scrolling vertically/horizontally should show reveal all\\n"
" edges of the tree. One *exception* is the widget label\\n"
" to the right of the 'ccc button'; labels aren't part\\n"
" of the widget, and therefore don't affect scroll tabs\\n"
" 2) Scroll vertical scroller to the middle of the tree\\n"
" 3) Left click and drag up/down to extend the selection:\\n"
" * Selection should autoscroll if you drag off the top/bottom\\n"
" * Selection should work *even* if you drag horizontally\\n"
" off the window edge; moving up/down outside the window\\n"
" should continue to autoscroll\\n"
" 4) Click either of the the scrollbar tabs and drag:\\n"
" * Even if you drag off the scrollbar, the scrollbar\\n"
" tab should continue to move\\n"
" * Should continue to work if you drag off the window edge\\n"
" horizontally drag off the window.\\n"
" 5) Click 'Bbb' and hit 'Add 20,000', then position the\\n"
" 'ccc button' so it's partially obscured by a scrollbar tab:\\n"
" * Clicking the obscured button should work\\n"
" * Clicking on the tab over the button should not 'click through'\\n"
" to the button.\\n"
"";
static Fl_Double_Window *helpwin = 0;
@ -1654,9 +1720,31 @@ if ( !helpwin ) {
helpwin->end();
}
helpwin->resizable(helpdisp);
helpwin->show();} selected
helpwin->show();}
tooltip {Suggestions on how to do tests} xywh {935 554 95 16} labelsize 9
}
Fl_Value_Slider tree_scrollbar_size_slider {
label {Fl_Tree::scrollbar_size()}
callback {tree->scrollbar_size(tree_scrollbar_size_slider->value());
tree->redraw();}
tooltip {Tests Fl_Tree::scrollbar_size() effects on tree clipping.
The value is normally 0, which causes Fl_Tree to use the global Fl::scrollbar_size() instead.
} xywh {835 499 180 16} type Horizontal color 46 selection_color 1 labelsize 11 align 4 textsize 9
code0 {o->value(tree->scrollbar_size());}
code1 {o->range(0.0, 30.0);}
code2 {o->step(1.0);}
code3 {o->color(46); o->selection_color(FL_RED);}
}
Fl_Value_Slider scrollbar_size_slider {
label {Fl::scrollbar_size()}
callback {Fl::scrollbar_size(scrollbar_size_slider->value());
tree->redraw();}
tooltip {Tests Fl::scrollbar_size() effects on tree clipping} xywh {835 519 180 16} type Horizontal color 46 selection_color 1 labelsize 11 align 4 textsize 9
code0 {o->value(Fl::scrollbar_size());}
code1 {o->range(5.0, 30.0);}
code2 {o->step(1.0);}
code3 {o->color(46); o->selection_color(FL_RED);}
}
}
Fl_Box resizer_box {
xywh {0 263 15 14}
@ -1673,6 +1761,8 @@ RebuildTree();
//Fl::scheme("gtk+");
Fl_Tooltip::size(10); // small font for tooltips
window->resizable(tree);
window->size_range(window->w(), window->h(), 0, 0);