diff options
| author | Greg Ercolano <erco@seriss.com> | 2013-12-15 18:59:02 +0000 |
|---|---|---|
| committer | Greg Ercolano <erco@seriss.com> | 2013-12-15 18:59:02 +0000 |
| commit | d36882e67e2276a44336a63e498c46a73d21fcb6 (patch) | |
| tree | 519d7c91d077dce9dd1b21e20a7354a2a09f9658 /FL | |
| parent | 6bf1ddf2b1fcc62fa52007e477a848fc2518b4ba (diff) | |
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
Diffstat (limited to 'FL')
| -rw-r--r-- | FL/Fl_Tree.H | 155 | ||||
| -rw-r--r-- | FL/Fl_Tree_Item.H | 51 | ||||
| -rw-r--r-- | FL/Fl_Tree_Prefs.H | 2 |
3 files changed, 149 insertions, 59 deletions
diff --git a/FL/Fl_Tree.H b/FL/Fl_Tree.H index ed2a2d526..9446e08d1 100644 --- a/FL/Fl_Tree.H +++ b/FL/Fl_Tree.H @@ -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 *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 *next_selected_item(Fl_Tree_Item *item=0); + 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 diff --git a/FL/Fl_Tree_Item.H b/FL/Fl_Tree_Item.H index 81c73fd64..b51d90907 100644 --- a/FL/Fl_Tree_Item.H +++ b/FL/Fl_Tree_Item.H @@ -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. diff --git a/FL/Fl_Tree_Prefs.H b/FL/Fl_Tree_Prefs.H index 5ced88f4b..1b1a7b139 100644 --- a/FL/Fl_Tree_Prefs.H +++ b/FL/Fl_Tree_Prefs.H @@ -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 |
