Fl_Tree_Item.H 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. //
  2. // "$Id: Fl_Tree_Item.H 10157 2014-05-22 15:38:27Z greg.ercolano $"
  3. //
  4. #ifndef FL_TREE_ITEM_H
  5. #define FL_TREE_ITEM_H
  6. #include <FL/Fl.H>
  7. #include <FL/Fl_Widget.H>
  8. #include <FL/Fl_Image.H>
  9. #include <FL/fl_draw.H>
  10. #include <FL/Fl_Tree_Item_Array.H>
  11. #include <FL/Fl_Tree_Prefs.H>
  12. //////////////////////
  13. // FL/Fl_Tree_Item.H
  14. //////////////////////
  15. //
  16. // Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
  17. // Copyright (C) 2009-2010 by Greg Ercolano.
  18. //
  19. // This library is free software. Distribution and use rights are outlined in
  20. // the file "COPYING" which should have been included with this file. If this
  21. // file is missing or damaged, see the license at:
  22. //
  23. // http://www.fltk.org/COPYING.php
  24. //
  25. // Please report all bugs and problems on the following page:
  26. //
  27. // http://www.fltk.org/str.php
  28. //
  29. ///
  30. /// \file
  31. /// \brief This file contains the definitions for Fl_Tree_Item
  32. ///
  33. /// \class Fl_Tree_Item
  34. /// \brief Tree widget item.
  35. ///
  36. /// This class is a single tree item, and manages all of the item's attributes.
  37. /// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item.
  38. ///
  39. /// Fl_Tree_Item is hierarchical; it dynamically manages an Fl_Tree_Item_Array of children
  40. /// that are themselves instances of Fl_Tree_Item. Each item can have zero or more children.
  41. /// When an item has children, close() and open() can be used to hide or show them.
  42. ///
  43. /// Items have their own attributes; font size, face, color.
  44. /// Items maintain their own hierarchy of children.
  45. ///
  46. /// When you make changes to items, you'll need to tell the tree to redraw()
  47. /// for the changes to show up.
  48. ///
  49. /// New 1.3.3 ABI feature:
  50. /// You can define custom items by either adding a custom widget to the item
  51. /// with Fl_Tree_Item::widget(), or override the draw_item_content() method
  52. /// if you want to just redefine how the label is drawn.
  53. ///
  54. /// The following shows the Fl_Tree_Item's dimensions, useful when overriding
  55. /// the draw_item_content() method:
  56. ///
  57. /// \image html Fl_Tree_Item-dimensions.png "Fl_Tree_Item's internal dimensions." width=6cm
  58. /// \image latex Fl_Tree_Item-dimensions.png "Fl_Tree_Item's internal dimensions." width=6cm
  59. ///
  60. class Fl_Tree;
  61. class FL_EXPORT Fl_Tree_Item {
  62. #if FLTK_ABI_VERSION >= 10303
  63. Fl_Tree *_tree; // parent tree
  64. #endif
  65. const char *_label; // label (memory managed)
  66. Fl_Font _labelfont; // label's font face
  67. Fl_Fontsize _labelsize; // label's font size
  68. Fl_Color _labelfgcolor; // label's fg color
  69. Fl_Color _labelbgcolor; // label's bg color (0xffffffff is 'transparent')
  70. #if FLTK_ABI_VERSION >= 10303
  71. /// \enum Fl_Tree_Item_Flags
  72. enum Fl_Tree_Item_Flags {
  73. #else
  74. /// \enum
  75. enum {
  76. #endif
  77. OPEN = 1<<0, ///> item is open
  78. VISIBLE = 1<<1, ///> item is visible
  79. ACTIVE = 1<<2, ///> item is active
  80. SELECTED = 1<<3 ///> item is selected
  81. };
  82. #if FLTK_ABI_VERSION >= 10301
  83. // NEW
  84. unsigned short _flags; // misc flags
  85. #else /*FLTK_ABI_VERSION*/
  86. // OLD: this will go away after 1.3.x
  87. char _open; // item is open?
  88. char _visible; // item is visible?
  89. char _active; // item activated?
  90. char _selected; // item selected?
  91. #endif /*FLTK_ABI_VERSION*/
  92. int _xywh[4]; // xywh of this widget (if visible)
  93. int _collapse_xywh[4]; // xywh of collapse icon (if visible)
  94. int _label_xywh[4]; // xywh of label
  95. Fl_Widget *_widget; // item's label widget (optional)
  96. Fl_Image *_usericon; // item's user-specific icon (optional)
  97. Fl_Tree_Item_Array _children; // array of child items
  98. Fl_Tree_Item *_parent; // parent item (=0 if root)
  99. void *_userdata; // user data that can be associated with an item
  100. #if FLTK_ABI_VERSION >= 10301
  101. Fl_Tree_Item *_prev_sibling; // previous sibling (same level)
  102. Fl_Tree_Item *_next_sibling; // next sibling (same level)
  103. #endif /*FLTK_ABI_VERSION*/
  104. // Protected methods
  105. protected:
  106. void _Init(const Fl_Tree_Prefs &prefs, Fl_Tree *tree);
  107. void show_widgets();
  108. void hide_widgets();
  109. void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs);
  110. void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs);
  111. void recalc_tree();
  112. int calc_item_height(const Fl_Tree_Prefs &prefs) const;
  113. #if FLTK_ABI_VERSION >= 10303
  114. Fl_Color drawfgcolor() const;
  115. Fl_Color drawbgcolor() const;
  116. #endif
  117. public:
  118. Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR -- backwards compatible
  119. #if FLTK_ABI_VERSION >= 10303
  120. Fl_Tree_Item(Fl_Tree *tree); // CTOR -- ABI 1.3.3+
  121. virtual ~Fl_Tree_Item(); // DTOR -- ABI 1.3.3+
  122. #else
  123. ~Fl_Tree_Item(); // DTOR -- backwards compatible
  124. #endif
  125. Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR
  126. /// The item's x position relative to the window
  127. int x() const { return(_xywh[0]); }
  128. /// The item's y position relative to the window
  129. int y() const { return(_xywh[1]); }
  130. /// The entire item's width to right edge of Fl_Tree's inner width
  131. /// within scrollbars.
  132. int w() const { return(_xywh[2]); }
  133. /// The item's height
  134. int h() const { return(_xywh[3]); }
  135. /// The item's label x position relative to the window
  136. /// \version 1.3.3
  137. int label_x() const { return(_label_xywh[0]); }
  138. /// The item's label y position relative to the window
  139. /// \version 1.3.3
  140. int label_y() const { return(_label_xywh[1]); }
  141. /// The item's maximum label width to right edge of Fl_Tree's inner width
  142. /// within scrollbars.
  143. /// \version 1.3.3
  144. int label_w() const { return(_label_xywh[2]); }
  145. /// The item's label height
  146. /// \version 1.3.3
  147. int label_h() const { return(_label_xywh[3]); }
  148. #if FLTK_ABI_VERSION >= 10303
  149. virtual int draw_item_content(int render);
  150. void draw(int X, int &Y, int W, Fl_Tree_Item *itemfocus,
  151. int &tree_item_xmax, int lastchild=1, int render=1);
  152. #else
  153. void draw(int X, int &Y, int W, Fl_Widget *tree,
  154. Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1);
  155. #endif
  156. void show_self(const char *indent = "") const;
  157. void label(const char *val);
  158. const char *label() const;
  159. /// Set a user-data value for the item.
  160. inline void user_data( void* data ) { _userdata = data; }
  161. /// Retrieve the user-data value that has been assigned to the item.
  162. inline void* user_data() const { return _userdata; }
  163. /// Set item's label font face.
  164. void labelfont(Fl_Font val) {
  165. _labelfont = val;
  166. recalc_tree(); // may change tree geometry
  167. }
  168. /// Get item's label font face.
  169. Fl_Font labelfont() const {
  170. return(_labelfont);
  171. }
  172. /// Set item's label font size.
  173. void labelsize(Fl_Fontsize val) {
  174. _labelsize = val;
  175. recalc_tree(); // may change tree geometry
  176. }
  177. /// Get item's label font size.
  178. Fl_Fontsize labelsize() const {
  179. return(_labelsize);
  180. }
  181. /// Set item's label foreground text color.
  182. void labelfgcolor(Fl_Color val) {
  183. _labelfgcolor = val;
  184. }
  185. /// Return item's label foreground text color.
  186. Fl_Color labelfgcolor() const {
  187. return(_labelfgcolor);
  188. }
  189. /// Set item's label text color. Alias for labelfgcolor(Fl_Color)).
  190. void labelcolor(Fl_Color val) {
  191. labelfgcolor(val);
  192. }
  193. /// Return item's label text color. Alias for labelfgcolor() const).
  194. Fl_Color labelcolor() const {
  195. return labelfgcolor();
  196. }
  197. /// Set item's label background color.
  198. /// A special case is made for color 0xffffffff which uses the parent tree's bg color.
  199. void labelbgcolor(Fl_Color val) {
  200. _labelbgcolor = val;
  201. }
  202. /// Return item's label background text color.
  203. /// If the color is 0xffffffff, the default behavior is the parent tree's
  204. /// bg color will be used. (An overloaded draw_item_content() can override
  205. /// this behavior.)
  206. Fl_Color labelbgcolor() const {
  207. return(_labelbgcolor);
  208. }
  209. /// Assign an FLTK widget to this item.
  210. void widget(Fl_Widget *val) {
  211. _widget = val;
  212. recalc_tree(); // may change tree geometry
  213. }
  214. /// Return FLTK widget assigned to this item.
  215. virtual Fl_Widget *widget() const {
  216. return(_widget);
  217. }
  218. /// Return the number of children this item has.
  219. int children() const {
  220. return(_children.total());
  221. }
  222. /// Return the child item for the given 'index'.
  223. Fl_Tree_Item *child(int index) {
  224. return(_children[index]);
  225. }
  226. /// Return the const child item for the given 'index'.
  227. const Fl_Tree_Item *child(int t) const;
  228. /// See if this item has children.
  229. int has_children() const {
  230. return(children());
  231. }
  232. int find_child(const char *name);
  233. int find_child(Fl_Tree_Item *item);
  234. int remove_child(Fl_Tree_Item *item);
  235. int remove_child(const char *new_label);
  236. void clear_children();
  237. void swap_children(int ax, int bx);
  238. int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b);
  239. const Fl_Tree_Item *find_child_item(const char *name) const;
  240. Fl_Tree_Item *find_child_item(const char *name);
  241. const Fl_Tree_Item *find_child_item(char **arr) const;
  242. Fl_Tree_Item *find_child_item(char **arr);
  243. const Fl_Tree_Item *find_item(char **arr) const;
  244. Fl_Tree_Item *find_item(char **arr);
  245. //////////////////
  246. // Adding items
  247. //////////////////
  248. virtual Fl_Tree_Item *new_fl_tree_item(const Fl_Tree_Prefs &prefs);
  249. Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
  250. const char *new_label,
  251. Fl_Tree_Item *newitem);
  252. Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
  253. const char *new_label);
  254. Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
  255. char **arr,
  256. Fl_Tree_Item *newitem);
  257. Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
  258. char **arr);
  259. #if FLTK_ABI_VERSION >= 10303
  260. Fl_Tree_Item *replace(Fl_Tree_Item *new_item);
  261. Fl_Tree_Item *replace_child(Fl_Tree_Item *olditem, Fl_Tree_Item *newitem);
  262. #endif
  263. Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0);
  264. Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label);
  265. int depth() const;
  266. Fl_Tree_Item *prev();
  267. Fl_Tree_Item *next();
  268. Fl_Tree_Item *next_sibling();
  269. Fl_Tree_Item *prev_sibling();
  270. void update_prev_next(int index);
  271. Fl_Tree_Item *next_displayed(Fl_Tree_Prefs &prefs); // deprecated
  272. Fl_Tree_Item *prev_displayed(Fl_Tree_Prefs &prefs); // deprecated
  273. Fl_Tree_Item *next_visible(Fl_Tree_Prefs &prefs);
  274. Fl_Tree_Item *prev_visible(Fl_Tree_Prefs &prefs);
  275. /// Return the parent for this item. Returns NULL if we are the root.
  276. Fl_Tree_Item *parent() {
  277. return(_parent);
  278. }
  279. /// Return the const parent for this item. Returns NULL if we are the root.
  280. const Fl_Tree_Item *parent() const {
  281. return(_parent);
  282. }
  283. /// Set the parent for this item.
  284. /// Should only be used by Fl_Tree's internals.
  285. ///
  286. void parent(Fl_Tree_Item *val) {
  287. _parent = val;
  288. }
  289. #if FLTK_ABI_VERSION >= 10303
  290. const Fl_Tree_Prefs& prefs() const;
  291. /// Return the tree for this item.
  292. const Fl_Tree *tree() const {
  293. return(_tree);
  294. }
  295. #endif
  296. //////////////////
  297. // State
  298. //////////////////
  299. void open();
  300. void close();
  301. /// See if the item is 'open'.
  302. int is_open() const {
  303. return(is_flag(OPEN));
  304. }
  305. /// See if the item is 'closed'.
  306. int is_close() const {
  307. return(is_flag(OPEN)?0:1);
  308. }
  309. /// Toggle the item's open/closed state.
  310. void open_toggle() {
  311. is_open()?close():open(); // handles calling recalc_tree()
  312. }
  313. /// Change the item's selection state to the optionally specified 'val'.
  314. /// If 'val' is not specified, the item will be selected.
  315. ///
  316. void select(int val=1) {
  317. set_flag(SELECTED, val);
  318. }
  319. /// Toggle the item's selection state.
  320. void select_toggle() {
  321. if ( is_selected() ) {
  322. deselect(); // deselect if selected
  323. } else {
  324. select(); // select if deselected
  325. }
  326. }
  327. /// Select item and all its children.
  328. /// Returns count of how many items were in the 'deselected' state,
  329. /// ie. how many items were "changed".
  330. ///
  331. int select_all() {
  332. int count = 0;
  333. if ( ! is_selected() ) {
  334. select();
  335. ++count;
  336. }
  337. for ( int t=0; t<children(); t++ ) {
  338. count += child(t)->select_all();
  339. }
  340. return(count);
  341. }
  342. /// Disable the item's selection state.
  343. void deselect() {
  344. set_flag(SELECTED, 0);
  345. }
  346. /// Deselect item and all its children.
  347. /// Returns count of how many items were in the 'selected' state,
  348. /// ie. how many items were "changed".
  349. ///
  350. int deselect_all() {
  351. int count = 0;
  352. if ( is_selected() ) {
  353. deselect();
  354. ++count;
  355. }
  356. for ( int t=0; t<children(); t++ ) {
  357. count += child(t)->deselect_all();
  358. }
  359. return(count);
  360. }
  361. /// See if the item is selected.
  362. char is_selected() const {
  363. return(is_flag(SELECTED));
  364. }
  365. /// Change the item's activation state to the optionally specified 'val'.
  366. ///
  367. /// When deactivated, the item will be 'grayed out'; the callback()
  368. /// won't be invoked if the user clicks on the label. If a widget()
  369. /// is associated with the item, its activation state will be changed as well.
  370. ///
  371. /// If 'val' is not specified, the item will be activated.
  372. ///
  373. void activate(int val=1) {
  374. set_flag(ACTIVE,val);
  375. if ( _widget && val != (int)_widget->active() ) {
  376. if ( val ) {
  377. _widget->activate();
  378. } else {
  379. _widget->deactivate();
  380. }
  381. _widget->redraw();
  382. }
  383. }
  384. /// Deactivate the item; the callback() won't be invoked when clicked.
  385. /// Same as activate(0)
  386. ///
  387. void deactivate() {
  388. activate(0);
  389. }
  390. /// See if the item is activated.
  391. char is_activated() const {
  392. return(is_flag(ACTIVE));
  393. }
  394. /// See if the item is activated. Alias for is_activated().
  395. char is_active() const {
  396. return(is_activated());
  397. }
  398. /// See if the item is visible. Alias for is_visible().
  399. int visible() const {
  400. return(is_visible());
  401. }
  402. /// See if the item is visible.
  403. int is_visible() const {
  404. return(is_flag(VISIBLE));
  405. }
  406. int visible_r() const;
  407. /// Set the item's user icon to an Fl_Image. '0' will disable.
  408. void usericon(Fl_Image *val) {
  409. _usericon = val;
  410. recalc_tree(); // may change tree geometry
  411. }
  412. /// Get the item's user icon as an Fl_Image. Returns '0' if disabled.
  413. Fl_Image *usericon() const {
  414. return(_usericon);
  415. }
  416. //////////////////
  417. // Events
  418. //////////////////
  419. #if FLTK_ABI_VERSION >= 10303
  420. const Fl_Tree_Item* find_clicked(const Fl_Tree_Prefs &prefs, int yonly=0) const;
  421. Fl_Tree_Item* find_clicked(const Fl_Tree_Prefs &prefs, int yonly=0);
  422. #else
  423. const Fl_Tree_Item* find_clicked(const Fl_Tree_Prefs &prefs) const;
  424. Fl_Tree_Item* find_clicked(const Fl_Tree_Prefs &prefs);
  425. #endif
  426. int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const;
  427. int event_on_label(const Fl_Tree_Prefs &prefs) const;
  428. /// Is this item the root of the tree?
  429. int is_root() const {
  430. return(_parent==0?1:0);
  431. }
  432. // Protected methods
  433. // TODO: move these to top 'protected:' section
  434. protected:
  435. #if FLTK_ABI_VERSION >= 10301
  436. /// Set a flag to an on or off value. val is 0 or 1.
  437. inline void set_flag(unsigned short flag,int val) {
  438. if ( flag==OPEN || flag==VISIBLE ) {
  439. recalc_tree(); // may change tree geometry
  440. }
  441. if ( val ) _flags |= flag; else _flags &= ~flag;
  442. }
  443. /// See if flag set. Returns 0 or 1.
  444. inline int is_flag(unsigned short val) const {
  445. return(_flags & val ? 1 : 0);
  446. }
  447. #else /*FLTK_ABI_VERSION*/
  448. /// Set a flag to an on or off value. val is 0 or 1.
  449. void set_flag(unsigned short flag,int val) {
  450. switch (flag) {
  451. case OPEN: _open = val; break;
  452. case VISIBLE: _visible = val; break;
  453. case ACTIVE: _active = val; break;
  454. case SELECTED: _selected = val; break;
  455. }
  456. }
  457. /// See if flag set. Returns 0 or 1.
  458. int is_flag(unsigned short flag) const {
  459. switch (flag) {
  460. case OPEN: return(_open ? 1 : 0);
  461. case VISIBLE: return(_visible ? 1 : 0);
  462. case ACTIVE: return(_active ? 1 : 0);
  463. case SELECTED: return(_selected ? 1 : 0);
  464. default: return(0);
  465. }
  466. }
  467. #endif /*FLTK_ABI_VERSION*/
  468. };
  469. #endif /*FL_TREE_ITEM_H*/
  470. //
  471. // End of "$Id: Fl_Tree_Item.H 10157 2014-05-22 15:38:27Z greg.ercolano $".
  472. //