Fl_Tree.H 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. //
  2. // "$Id: Fl_Tree.H 7903 2010-11-28 21:06:39Z matt $"
  3. //
  4. #ifndef FL_TREE_H
  5. #define FL_TREE_H
  6. #include <FL/Fl.H>
  7. #include <FL/Fl_Group.H>
  8. #include <FL/Fl_Scrollbar.H>
  9. #include <FL/fl_draw.H>
  10. #include <FL/Fl_Tree_Item.H>
  11. #include <FL/Fl_Tree_Prefs.H>
  12. //////////////////////
  13. // FL/Fl_Tree.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; you can redistribute it and/or
  20. // modify it under the terms of the GNU Library General Public
  21. // License as published by the Free Software Foundation; either
  22. // version 2 of the License, or (at your option) any later version.
  23. //
  24. // This library is distributed in the hope that it will be useful,
  25. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  27. // Library General Public License for more details.
  28. //
  29. // You should have received a copy of the GNU Library General Public
  30. // License along with this library; if not, write to the Free Software
  31. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  32. // USA.
  33. //
  34. ///
  35. /// \file
  36. /// \brief This file contains the definitions of the Fl_Tree class
  37. ///
  38. /// \class Fl_Tree
  39. ///
  40. /// \brief Tree widget.
  41. ///
  42. /// \code
  43. /// Fl_Tree // Top level widget
  44. /// |--- Fl_Tree_Item // Items in the tree
  45. /// |--- Fl_Tree_Prefs // Preferences for the tree
  46. /// |--- Fl_Tree_Connector (enum) // Connection modes
  47. /// |--- Fl_Tree_Select (enum) // Selection modes
  48. /// |--- Fl_Tree_Sort (enum) // Sort behavior
  49. /// \endcode
  50. ///
  51. /// An expandable tree widget.
  52. ///
  53. /// Similar to Fl_Browser, Fl_Tree is browser of Fl_Tree_Item's, which can be
  54. /// in a parented hierarchy. Subtrees can be expanded or closed. Items can be
  55. /// added, deleted, inserted, sorted and re-ordered.
  56. ///
  57. /// The tree items may also contain other FLTK widgets, like buttons, input fields,
  58. /// or even "custom" widgets.
  59. ///
  60. /// The callback() is invoked depending on the value of when():
  61. ///
  62. /// - FL_WHEN_RELEASE -- callback invoked when left mouse button is released on an item
  63. /// - FL_WHEN_CHANGED -- callback invoked when left mouse changes selection state
  64. ///
  65. /// The simple way to define a tree:
  66. /// \code
  67. /// #include <FL/Fl_Tree.H>
  68. /// [..]
  69. /// Fl_Tree tree(X,Y,W,H);
  70. /// tree.begin();
  71. /// tree.add("Flintstones/Fred");
  72. /// tree.add("Flintstones/Wilma");
  73. /// tree.add("Flintstones/Pebbles");
  74. /// tree.add("Simpsons/Homer");
  75. /// tree.add("Simpsons/Marge");
  76. /// tree.add("Simpsons/Bart");
  77. /// tree.add("Simpsons/Lisa");
  78. /// tree.end();
  79. /// \endcode
  80. ///
  81. /// Items can be added with add(),
  82. /// removed with remove(),
  83. /// completely cleared with clear(),
  84. /// inserted with insert() and insert_above(),
  85. /// selected/deselected with select() and deselect(),
  86. /// open/closed with open() and closed().
  87. /// Children of an item can be swapped around with Fl_Tree_Item::swap_children(),
  88. /// sorting can be controlled when items are add()ed via sortorder().
  89. /// You can walk the entire tree with first() and next().
  90. /// You can walk selected items with first_selected_item() and
  91. /// next_selected_item().
  92. /// Items can be found by their pathname using find_item(const char*),
  93. /// and an item's pathname can be found with item_pathname().
  94. ///
  95. /// The tree can have different selection behaviors controlled by selectmode().
  96. ///
  97. /// FLTK widgets (including custom widgets) can be assigned to tree items via
  98. /// Fl_Tree_Item::widget().
  99. ///
  100. /// Icons for individual items can be changed with
  101. /// Fl_Tree_Item::openicon(),
  102. /// Fl_Tree_Item::closeicon(),
  103. /// Fl_Tree_Item::usericon().
  104. ///
  105. /// Various default preferences can be globally manipulated via Fl_Tree_Prefs,
  106. /// including colors, margins, icons, connection lines.
  107. ///
  108. /// The tree's callback() will be invoked when items change state or are open/closed.
  109. /// when() controls when mouse/keyboard events invoke the callback.
  110. /// callback_item() and callback_reason() can be used to determine the cause of the callback.
  111. ///
  112. /// \image html tree-elements.png
  113. ///
  114. /// \enum Fl_Tree_Reason
  115. /// The reason the callback was invoked.
  116. ///
  117. enum Fl_Tree_Reason {
  118. FL_TREE_REASON_NONE=0, ///< unknown reason
  119. FL_TREE_REASON_SELECTED, ///< an item was selected
  120. FL_TREE_REASON_DESELECTED, ///< an item was de-selected
  121. FL_TREE_REASON_OPENED, ///< an item was opened
  122. FL_TREE_REASON_CLOSED ///< an item was closed
  123. };
  124. class FL_EXPORT Fl_Tree : public Fl_Group {
  125. Fl_Tree_Item *_root; // can be null!
  126. Fl_Tree_Item *_item_focus; // item that has focus box
  127. Fl_Tree_Item *_callback_item; // item invoked during callback (can be NULL)
  128. Fl_Tree_Reason _callback_reason; // reason for the callback
  129. Fl_Tree_Prefs _prefs; // all the tree's settings
  130. int _scrollbar_size; // size of scrollbar trough
  131. protected:
  132. /// Vertical scrollbar
  133. Fl_Scrollbar *_vscroll;
  134. protected:
  135. void item_clicked(Fl_Tree_Item* val);
  136. /// Do the callback for the item, setting the item and reason
  137. void do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) {
  138. callback_reason(reason);
  139. callback_item(item);
  140. do_callback((Fl_Widget*)this, user_data());
  141. }
  142. Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
  143. public:
  144. Fl_Tree(int X, int Y, int W, int H, const char *L=0);
  145. ~Fl_Tree();
  146. int handle(int e);
  147. void draw();
  148. ///////////////////////
  149. // root methods
  150. ///////////////////////
  151. /// Set the label for the root item.
  152. ///
  153. /// Makes an internally managed copy of 'new_label'.
  154. ///
  155. void root_label(const char *new_label) {
  156. if ( ! _root ) return;
  157. _root->label(new_label);
  158. }
  159. /// Returns the root item.
  160. Fl_Tree_Item* root() {
  161. return(_root);
  162. }
  163. ////////////////////////////////
  164. // Item creation/removal methods
  165. ////////////////////////////////
  166. Fl_Tree_Item *add(const char *path);
  167. Fl_Tree_Item* add(Fl_Tree_Item *item, const char *name);
  168. Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name);
  169. Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos);
  170. /// Remove the specified \p item from the tree.
  171. /// If it has children, all those are removed too.
  172. /// \returns 0 if done, -1 if 'item' not found.
  173. ///
  174. int remove(Fl_Tree_Item *item) {
  175. if ( !item ) return(0);
  176. if ( item == _root ) {
  177. clear();
  178. } else {
  179. Fl_Tree_Item *parent = item->parent(); // find item's parent
  180. if ( ! parent ) return(-1);
  181. parent->remove_child(item); // remove child + children
  182. }
  183. return(0);
  184. }
  185. /// Clear all children from the tree.
  186. /// The tree will be left completely empty.
  187. ///
  188. void clear() {
  189. if ( ! _root ) return;
  190. _root->clear_children();
  191. delete _root; _root = 0;
  192. }
  193. /// Clear all the children of a particular node in the tree specified by \p item.
  194. void clear_children(Fl_Tree_Item *item) {
  195. if ( item->has_children() ) {
  196. item->clear_children();
  197. redraw(); // redraw only if there were children to clear
  198. }
  199. }
  200. ////////////////////////
  201. // Item lookup methods
  202. ////////////////////////
  203. Fl_Tree_Item *find_item(const char *path);
  204. const Fl_Tree_Item *find_item(const char *path) const;
  205. int item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *item) const;
  206. const Fl_Tree_Item *find_clicked() const;
  207. /// Return the item that was last clicked.
  208. ///
  209. /// Valid only from within the callback().
  210. ///
  211. /// Deprecated: use callback_item() instead.
  212. ///
  213. /// \returns the item clicked, or 0 if none.
  214. /// 0 may also be used to indicate several items were clicked/changed.
  215. ///
  216. Fl_Tree_Item *item_clicked() {
  217. return(_callback_item);
  218. }
  219. Fl_Tree_Item *first();
  220. Fl_Tree_Item *next(Fl_Tree_Item *item=0);
  221. Fl_Tree_Item *prev(Fl_Tree_Item *item=0);
  222. Fl_Tree_Item *last();
  223. Fl_Tree_Item *first_selected_item();
  224. Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0);
  225. //////////////////////////
  226. // Item open/close methods
  227. //////////////////////////
  228. /// Open the specified 'item'.
  229. /// This causes the item's children (if any) to be shown.
  230. /// Handles redrawing if anything was actually changed.
  231. /// Invokes the callback depending on the value of optional parameter \p docallback.
  232. ///
  233. /// The callback can use callback_item() and callback_reason() respectively to determine
  234. /// the item changed and the reason the callback was called.
  235. ///
  236. /// \param[in] item -- the item to be opened
  237. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  238. /// - 0 - callback() is not invoked
  239. /// - 1 - callback() is invoked if item changed,
  240. /// callback_reason() will be FL_TREE_REASON_OPENED
  241. ///
  242. /// \returns
  243. /// - 1 -- item was opened
  244. /// - 0 -- item was already open, no change
  245. ///
  246. /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
  247. ///
  248. int open(Fl_Tree_Item *item, int docallback=1) {
  249. if ( item->is_open() ) return(0);
  250. item->open();
  251. redraw();
  252. if ( docallback ) {
  253. do_callback_for_item(item, FL_TREE_REASON_OPENED);
  254. }
  255. return(1);
  256. }
  257. /// Opens the item specified by \p path (eg: "Parent/child/item").
  258. /// This causes the item's children (if any) to be shown.
  259. /// Handles redrawing if anything was actually changed.
  260. /// Invokes the callback depending on the value of optional parameter \p docallback.
  261. ///
  262. /// The callback can use callback_item() and callback_reason() respectively to determine
  263. /// the item changed and the reason the callback was called.
  264. ///
  265. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  266. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  267. /// - 0 - callback() is not invoked
  268. /// - 1 - callback() is invoked if item changed,
  269. /// callback_reason() will be FL_TREE_REASON_OPENED
  270. ///
  271. /// \returns
  272. /// - 1 -- OK: item opened
  273. /// - 0 -- OK: item was already open, no change
  274. /// - -1 -- ERROR: item was not found
  275. ///
  276. /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
  277. ///
  278. int open(const char *path, int docallback=1) {
  279. Fl_Tree_Item *item = find_item(path);
  280. if ( ! item ) return(-1);
  281. return(open(item, docallback));
  282. }
  283. /// Toggle the open state of \p item.
  284. /// Handles redrawing if anything was actually changed.
  285. /// Invokes the callback depending on the value of optional parameter \p docallback.
  286. ///
  287. /// The callback can use callback_item() and callback_reason() respectively to determine
  288. /// the item changed and the reason the callback was called.
  289. ///
  290. /// \param[in] item -- the item to be opened
  291. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  292. /// - 0 - callback() is not invoked
  293. /// - 1 - callback() is invoked, callback_reason() will be either
  294. /// FL_TREE_REASON_OPENED or FL_TREE_REASON_CLOSED
  295. ///
  296. /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
  297. ///
  298. void open_toggle(Fl_Tree_Item *item, int docallback=1) {
  299. if ( item->is_open() ) {
  300. close(item, docallback);
  301. } else {
  302. open(item, docallback);
  303. }
  304. }
  305. /// Closes the specified \p item.
  306. /// Handles redrawing if anything was actually changed.
  307. /// Invokes the callback depending on the value of optional parameter \p docallback.
  308. ///
  309. /// The callback can use callback_item() and callback_reason() respectively to determine
  310. /// the item changed and the reason the callback was called.
  311. ///
  312. /// \param[in] item -- the item to be closed
  313. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  314. /// - 0 - callback() is not invoked
  315. /// - 1 - callback() is invoked if item changed,
  316. /// callback_reason() will be FL_TREE_REASON_CLOSED
  317. ///
  318. /// \returns
  319. /// - 1 -- item was closed
  320. /// - 0 -- item was already closed, no change
  321. ///
  322. /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
  323. ///
  324. int close(Fl_Tree_Item *item, int docallback=1) {
  325. if ( item->is_close() ) return(0);
  326. item->close();
  327. redraw();
  328. if ( docallback ) {
  329. do_callback_for_item(item, FL_TREE_REASON_CLOSED);
  330. }
  331. return(1);
  332. }
  333. /// Closes the item specified by \p path, eg: "Parent/child/item".
  334. /// Handles redrawing if anything was actually changed.
  335. /// Invokes the callback depending on the value of optional parameter \p docallback.
  336. ///
  337. /// The callback can use callback_item() and callback_reason() respectively to determine
  338. /// the item changed and the reason the callback was called.
  339. ///
  340. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  341. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  342. /// - 0 - callback() is not invoked
  343. /// - 1 - callback() is invoked if item changed,
  344. /// callback_reason() will be FL_TREE_REASON_CLOSED
  345. ///
  346. /// \returns
  347. /// - 1 -- OK: item closed
  348. /// - 0 -- OK: item was already closed, no change
  349. /// - -1 -- ERROR: item was not found
  350. ///
  351. /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
  352. ///
  353. int close(const char *path, int docallback=1) {
  354. Fl_Tree_Item *item = find_item(path);
  355. if ( ! item ) return(-1);
  356. return(close(item, docallback));
  357. }
  358. /// See if \p item is open.
  359. ///
  360. /// Items that are 'open' are themselves not necessarily visible;
  361. /// one of the item's parents might be closed.
  362. ///
  363. /// \param[in] item -- the item to be tested
  364. ///
  365. /// \returns
  366. /// - 1 : item is open
  367. /// - 0 : item is closed
  368. ///
  369. int is_open(Fl_Tree_Item *item) const {
  370. return(item->is_open()?1:0);
  371. }
  372. /// See if item specified by \p path (eg: "Parent/child/item") is open.
  373. ///
  374. /// Items that are 'open' are themselves not necessarily visible;
  375. /// one of the item's parents might be closed.
  376. ///
  377. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  378. ///
  379. /// \returns
  380. /// - 1 - OK: item is open
  381. /// - 0 - OK: item is closed
  382. /// - -1 - ERROR: item was not found
  383. ///
  384. int is_open(const char *path) const {
  385. const Fl_Tree_Item *item = find_item(path);
  386. if ( ! item ) return(-1);
  387. return(item->is_open()?1:0);
  388. }
  389. /// See if the specified \p item is closed.
  390. ///
  391. /// \param[in] item -- the item to be tested
  392. ///
  393. /// \returns
  394. /// - 1 : item is open
  395. /// - 0 : item is closed
  396. ///
  397. int is_close(Fl_Tree_Item *item) const {
  398. return(item->is_close());
  399. }
  400. /// See if item specified by \p path (eg: "Parent/child/item") is closed.
  401. ///
  402. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  403. ///
  404. /// \returns
  405. /// - 1 - OK: item is closed
  406. /// - 0 - OK: item is open
  407. /// - -1 - ERROR: item was not found
  408. ///
  409. int is_close(const char *path) const {
  410. const Fl_Tree_Item *item = find_item(path);
  411. if ( ! item ) return(-1);
  412. return(item->is_close()?1:0);
  413. }
  414. /// Select the specified \p item. Use 'deselect()' to de-select it.
  415. /// Handles redrawing if anything was actually changed.
  416. /// Invokes the callback depending on the value of optional parameter \p docallback.
  417. ///
  418. /// The callback can use callback_item() and callback_reason() respectively to determine
  419. /// the item changed and the reason the callback was called.
  420. ///
  421. /// \param[in] item -- the item to be selected
  422. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  423. /// - 0 - the callback() is not invoked
  424. /// - 1 - the callback() is invoked if item changed state,
  425. /// callback_reason() will be FL_TREE_REASON_SELECTED
  426. ///
  427. /// \returns
  428. /// - 1 - item's state was changed
  429. /// - 0 - item was already selected, no change was made
  430. ///
  431. int select(Fl_Tree_Item *item, int docallback=1) {
  432. if ( ! item->is_selected() ) {
  433. item->select();
  434. set_changed();
  435. if ( docallback ) {
  436. do_callback_for_item(item, FL_TREE_REASON_SELECTED);
  437. }
  438. redraw();
  439. return(1);
  440. }
  441. return(0);
  442. }
  443. /// Select the item specified by \p path (eg: "Parent/child/item").
  444. /// Handles redrawing if anything was actually changed.
  445. /// Invokes the callback depending on the value of optional parameter \p docallback.
  446. ///
  447. /// The callback can use callback_item() and callback_reason() respectively to determine
  448. /// the item changed and the reason the callback was called.
  449. ///
  450. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  451. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  452. /// - 0 - the callback() is not invoked
  453. /// - 1 - the callback() is invoked if item changed state,
  454. /// callback_reason() will be FL_TREE_REASON_SELECTED
  455. ///
  456. /// \returns
  457. /// - 1 : OK: item's state was changed
  458. /// - 0 : OK: item was already selected, no change was made
  459. /// - -1 : ERROR: item was not found
  460. ///
  461. int select(const char *path, int docallback=1) {
  462. Fl_Tree_Item *item = find_item(path);
  463. if ( ! item ) return(-1);
  464. return(select(item, docallback));
  465. }
  466. /// Toggle the select state of the specified \p item.
  467. /// Handles redrawing if anything was actually changed.
  468. /// Invokes the callback depending on the value of optional parameter \p docallback.
  469. ///
  470. /// The callback can use callback_item() and callback_reason() respectively to determine
  471. /// the item changed and the reason the callback was called.
  472. ///
  473. /// \param[in] item -- the item to be selected
  474. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  475. /// - 0 - the callback() is not invoked
  476. /// - 1 - the callback() is invoked, callback_reason() will be
  477. /// either FL_TREE_REASON_SELECTED or FL_TREE_REASON_DESELECTED
  478. ///
  479. void select_toggle(Fl_Tree_Item *item, int docallback=1) {
  480. item->select_toggle();
  481. set_changed();
  482. if ( docallback ) {
  483. do_callback_for_item(item, item->is_selected() ? FL_TREE_REASON_SELECTED
  484. : FL_TREE_REASON_DESELECTED);
  485. }
  486. redraw();
  487. }
  488. /// De-select the specified \p item.
  489. /// Handles redrawing if anything was actually changed.
  490. /// Invokes the callback depending on the value of optional parameter \p docallback.
  491. ///
  492. /// The callback can use callback_item() and callback_reason() respectively to determine
  493. /// the item changed and the reason the callback was called.
  494. ///
  495. /// \param[in] item -- the item to be selected
  496. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  497. /// - 0 - the callback() is not invoked
  498. /// - 1 - the callback() is invoked if item changed state,
  499. /// callback_reason() will be FL_TREE_REASON_DESELECTED
  500. ///
  501. /// \returns
  502. /// - 0 - item was already deselected, no change was made
  503. /// - 1 - item's state was changed
  504. ///
  505. int deselect(Fl_Tree_Item *item, int docallback=1) {
  506. if ( item->is_selected() ) {
  507. item->deselect();
  508. set_changed();
  509. if ( docallback ) {
  510. do_callback_for_item(item, FL_TREE_REASON_DESELECTED);
  511. }
  512. redraw();
  513. return(1);
  514. }
  515. return(0);
  516. }
  517. /// Deselect an item specified by \p path (eg: "Parent/child/item").
  518. /// Handles redrawing if anything was actually changed.
  519. /// Invokes the callback depending on the value of optional parameter \p docallback.
  520. ///
  521. /// The callback can use callback_item() and callback_reason() respectively to determine
  522. /// the item changed and the reason the callback was called.
  523. ///
  524. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  525. /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
  526. /// - 0 - the callback() is not invoked
  527. /// - 1 - the callback() is invoked if item changed state,
  528. /// callback_reason() will be FL_TREE_REASON_DESELECTED
  529. ///
  530. /// \returns
  531. /// - 1 - OK: item's state was changed
  532. /// - 0 - OK: item was already deselected, no change was made
  533. /// - -1 - ERROR: item was not found
  534. ///
  535. int deselect(const char *path, int docallback=1) {
  536. Fl_Tree_Item *item = find_item(path);
  537. if ( ! item ) return(-1);
  538. return(deselect(item, docallback));
  539. }
  540. int deselect_all(Fl_Tree_Item *item=0, int docallback=1);
  541. int select_only(Fl_Tree_Item *selitem, int docallback=1);
  542. int select_all(Fl_Tree_Item *item=0, int docallback=1);
  543. void set_item_focus(Fl_Tree_Item *o);
  544. /// See if the specified \p item is selected.
  545. ///
  546. /// \param[in] item -- the item to be tested
  547. ///
  548. /// \return
  549. /// - 1 : item selected
  550. /// - 0 : item deselected
  551. ///
  552. int is_selected(Fl_Tree_Item *item) const {
  553. return(item->is_selected()?1:0);
  554. }
  555. /// See if item specified by \p path (eg: "Parent/child/item") is selected.
  556. ///
  557. /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
  558. ///
  559. /// \returns
  560. /// - 1 : item selected
  561. /// - 0 : item deselected
  562. /// - -1 : item was not found
  563. ///
  564. int is_selected(const char *path) {
  565. Fl_Tree_Item *item = find_item(path);
  566. if ( ! item ) return(-1);
  567. return(is_selected(item));
  568. }
  569. /// Print the tree as 'ascii art' to stdout.
  570. /// Used mainly for debugging.
  571. ///
  572. void show_self() {
  573. if ( ! _root ) return;
  574. _root->show_self();
  575. }
  576. /////////////////////////////////
  577. // Item attribute related methods
  578. /////////////////////////////////
  579. /// Get the default label fontsize used for creating new items.
  580. int labelsize() const {
  581. return(_prefs.labelsize());
  582. }
  583. /// Set the default label font size used for creating new items.
  584. /// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(int)
  585. ///
  586. void labelsize(int val) {
  587. _prefs.labelsize(val);
  588. }
  589. /// Get the default font face used for item's labels when new items are created.
  590. ///
  591. /// Don't use this if you want to change an existing label() size; use
  592. /// item->labelfont() instead.
  593. ///
  594. int labelfont() const {
  595. return(_prefs.labelfont());
  596. }
  597. /// Set the default font face used for item's labels when new items are created.
  598. ///
  599. /// Don't use this if you want to change an existing label() size; use
  600. /// item->labelfont(int) instead.
  601. ///
  602. void labelfont(int val) {
  603. _prefs.labelfont(val);
  604. }
  605. /// Get the amount of white space (in pixels) that should appear
  606. /// between the widget's left border and the tree's contents.
  607. ///
  608. int marginleft() const {
  609. return(_prefs.marginleft());
  610. }
  611. /// Set the amount of white space (in pixels) that should appear
  612. /// between the widget's left border and the left side of the tree's contents.
  613. ///
  614. void marginleft(int val) {
  615. _prefs.marginleft(val);
  616. redraw();
  617. }
  618. /// Get the amount of white space (in pixels) that should appear
  619. /// between the widget's top border and the top of the tree's contents.
  620. ///
  621. int margintop() const {
  622. return(_prefs.margintop());
  623. }
  624. /// Sets the amount of white space (in pixels) that should appear
  625. /// between the widget's top border and the top of the tree's contents.
  626. ///
  627. void margintop(int val) {
  628. _prefs.margintop(val);
  629. redraw();
  630. }
  631. /// Get the amount of white space (in pixels) that should appear
  632. /// below an open child tree's contents.
  633. ///
  634. int openchild_marginbottom() const {
  635. return(_prefs.openchild_marginbottom());
  636. }
  637. /// Set the amount of white space (in pixels) that should appear
  638. /// below an open child tree's contents.
  639. ///
  640. void openchild_marginbottom(int val) {
  641. _prefs.openchild_marginbottom(val);
  642. redraw();
  643. }
  644. /// Gets the width of the horizontal connection lines (in pixels)
  645. /// that appear to the left of each tree item's label.
  646. ///
  647. int connectorwidth() const {
  648. return(_prefs.connectorwidth());
  649. }
  650. /// Sets the width of the horizontal connection lines (in pixels)
  651. /// that appear to the left of each tree item's label.
  652. ///
  653. void connectorwidth(int val) {
  654. _prefs.connectorwidth(val);
  655. redraw();
  656. }
  657. /// Returns the Fl_Image being used as the default user icon for newly created items.
  658. /// Returns zero if no icon has been set, which is the default.
  659. ///
  660. Fl_Image *usericon() const {
  661. return(_prefs.usericon());
  662. }
  663. /// Sets the Fl_Image to be used as the default user icon for all
  664. /// newly created items.
  665. ///
  666. /// If you want to specify user icons on a per-item basis,
  667. /// use Fl_Tree_Item::usericon() instead.
  668. ///
  669. /// \param[in] val -- The new image to be used, or
  670. /// zero to disable user icons.
  671. ///
  672. void usericon(Fl_Image *val) {
  673. _prefs.usericon(val);
  674. redraw();
  675. }
  676. /// Returns the icon to be used as the 'open' icon.
  677. /// If none was set, the internal default is returned,
  678. /// a simple '[+]' icon.
  679. ///
  680. Fl_Image *openicon() const {
  681. return(_prefs.openicon());
  682. }
  683. /// Sets the icon to be used as the 'open' icon.
  684. /// This overrides the built in default '[+]' icon.
  685. ///
  686. /// \param[in] val -- The new image, or zero to use the default [+] icon.
  687. ///
  688. void openicon(Fl_Image *val) {
  689. _prefs.openicon(val);
  690. redraw();
  691. }
  692. /// Returns the icon to be used as the 'close' icon.
  693. /// If none was set, the internal default is returned,
  694. /// a simple '[-]' icon.
  695. ///
  696. Fl_Image *closeicon() const {
  697. return(_prefs.closeicon());
  698. }
  699. /// Sets the icon to be used as the 'close' icon.
  700. /// This overrides the built in default '[-]' icon.
  701. ///
  702. /// \param[in] val -- The new image, or zero to use the default [-] icon.
  703. ///
  704. void closeicon(Fl_Image *val) {
  705. _prefs.closeicon(val);
  706. redraw();
  707. }
  708. /// Returns 1 if the collapse icon is enabled, 0 if not.
  709. int showcollapse() const {
  710. return(_prefs.showcollapse());
  711. }
  712. /// Set if we should show the collapse icon or not.
  713. /// If collapse icons are disabled, the user will not be able
  714. /// to interactively collapse items in the tree, unless the application
  715. /// provides some other means via open() and close().
  716. ///
  717. /// \param[in] val 1: shows collapse icons (default),\n
  718. /// 0: hides collapse icons.
  719. ///
  720. void showcollapse(int val) {
  721. _prefs.showcollapse(val);
  722. redraw();
  723. }
  724. /// Returns 1 if the root item is to be shown, or 0 if not.
  725. int showroot() const {
  726. return(_prefs.showroot());
  727. }
  728. /// Set if the root item should be shown or not.
  729. /// \param[in] val 1 -- show the root item (default)\n
  730. /// 0 -- hide the root item.
  731. ///
  732. void showroot(int val) {
  733. _prefs.showroot(val);
  734. redraw();
  735. }
  736. /// Returns the line drawing style for inter-connecting items.
  737. Fl_Tree_Connector connectorstyle() const {
  738. return(_prefs.connectorstyle());
  739. }
  740. /// Sets the line drawing style for inter-connecting items.
  741. void connectorstyle(Fl_Tree_Connector val) {
  742. _prefs.connectorstyle(val);
  743. redraw();
  744. }
  745. /// Set the default sort order used when items are added to the tree.
  746. /// See Fl_Tree_Sort for possible values.
  747. ///
  748. Fl_Tree_Sort sortorder() const {
  749. return(_prefs.sortorder());
  750. }
  751. /// Gets the sort order used to add items to the tree.
  752. void sortorder(Fl_Tree_Sort val) {
  753. _prefs.sortorder(val);
  754. // no redraw().. only affects new add()itions
  755. }
  756. /// Sets the style of box used to draw selected items.
  757. /// This is an fltk Fl_Boxtype.
  758. /// The default is influenced by FLTK's current Fl::scheme()
  759. ///
  760. Fl_Boxtype selectbox() const {
  761. return(_prefs.selectbox());
  762. }
  763. /// Gets the style of box used to draw selected items.
  764. /// This is an fltk Fl_Boxtype.
  765. /// The default is influenced by FLTK's current Fl::scheme()
  766. ///
  767. void selectbox(Fl_Boxtype val) {
  768. _prefs.selectbox(val);
  769. redraw();
  770. }
  771. /// Gets the tree's current selection mode.
  772. Fl_Tree_Select selectmode() const {
  773. return(_prefs.selectmode());
  774. }
  775. /// Sets the tree's selection mode.
  776. void selectmode(Fl_Tree_Select val) {
  777. _prefs.selectmode(val);
  778. }
  779. int displayed(Fl_Tree_Item *item);
  780. void show_item(Fl_Tree_Item *item, int yoff);
  781. void show_item(Fl_Tree_Item *item);
  782. void show_item_bottom(Fl_Tree_Item *item);
  783. void show_item_middle(Fl_Tree_Item *item);
  784. void show_item_top(Fl_Tree_Item *item);
  785. void display(Fl_Tree_Item *item);
  786. int vposition() const;
  787. void vposition(int ypos);
  788. /// See if widget \p w is one of the Fl_Tree widget's scrollbars.
  789. /// Use this to skip over the scrollbars when walking the child() array. Example:
  790. /// \code
  791. /// for ( int i=0; i<tree->children(); i++ ) { // walk children
  792. /// Fl_Widget *w= tree->child(i);
  793. /// if ( brow->is_scrollbar(w) ) continue; // skip scrollbars
  794. /// ..do work here..
  795. /// }
  796. /// \endcode
  797. /// \param[in] w Widget to test
  798. /// \returns 1 if \p w is a scrollbar, 0 if not.
  799. ///
  800. int is_scrollbar(Fl_Widget *w) {
  801. return( ( w == _vscroll ) ? 1 : 0 );
  802. }
  803. /// Gets the current size of the scrollbars' troughs, in pixels.
  804. ///
  805. /// If this value is zero (default), this widget will use the global
  806. /// Fl::scrollbar_size() value as the scrollbar's width.
  807. ///
  808. /// \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used.
  809. /// \see Fl::scrollbar_size(int)
  810. ///
  811. int scrollbar_size() const {
  812. return(_scrollbar_size);
  813. }
  814. /// Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
  815. ///
  816. /// Normally you should not need this method, and should use the global
  817. /// Fl::scrollbar_size(int) instead to manage the size of ALL
  818. /// your widgets' scrollbars. This ensures your application
  819. /// has a consistent UI, is the default behavior, and is normally
  820. /// what you want.
  821. ///
  822. /// Only use THIS method if you really need to override the global
  823. /// scrollbar size. The need for this should be rare.
  824. ///
  825. /// Setting \p size to the special value of 0 causes the widget to
  826. /// track the global Fl::scrollbar_size(), which is the default.
  827. ///
  828. /// \param[in] size Sets the scrollbar size in pixels.\n
  829. /// If 0 (default), scrollbar size tracks the global Fl::scrollbar_size()
  830. /// \see Fl::scrollbar_size()
  831. ///
  832. void scrollbar_size(int size) {
  833. _scrollbar_size = size;
  834. int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size();
  835. if ( _vscroll->w() != scrollsize ) {
  836. _vscroll->resize(x()+w()-scrollsize, h(), scrollsize, _vscroll->h());
  837. }
  838. }
  839. ///////////////////////
  840. // callback related
  841. ///////////////////////
  842. /// Sets the item that was changed for this callback.
  843. /// Used internally to pass the item that invoked the callback.
  844. ///
  845. void callback_item(Fl_Tree_Item* item) {
  846. _callback_item = item;
  847. }
  848. /// Gets the item that caused the callback.
  849. /// The callback() can use this value to see which item changed.
  850. ///
  851. Fl_Tree_Item* callback_item() {
  852. return(_callback_item);
  853. }
  854. /// Sets the reason for this callback.
  855. /// Used internally to pass the reason the callback was invoked.
  856. ///
  857. void callback_reason(Fl_Tree_Reason reason) {
  858. _callback_reason = reason;
  859. }
  860. /// Gets the reason for this callback.
  861. ///
  862. /// The callback() can use this value to see why it was called. Example:
  863. /// \code
  864. /// void MyTreeCallback(Fl_Widget *w, void *userdata) {
  865. /// Fl_Tree *tree = (Fl_Tree*)w;
  866. /// Fl_Tree_Item *item = tree->callback_item(); // the item changed (can be NULL if more than one item was changed!)
  867. /// switch ( tree->callback_reason() ) { // reason callback was invoked
  868. /// case FL_TREE_REASON_OPENED: ..item was opened..
  869. /// case FL_TREE_REASON_CLOSED: ..item was closed..
  870. /// case FL_TREE_REASON_SELECTED: ..item was selected..
  871. /// case FL_TREE_REASON_DESELECTED: ..item was deselected..
  872. /// }
  873. /// }
  874. /// \endcode
  875. ///
  876. Fl_Tree_Reason callback_reason() const {
  877. return(_callback_reason);
  878. }
  879. /// Load FLTK preferences
  880. void load(class Fl_Preferences&);
  881. };
  882. #endif /*FL_TREE_H*/
  883. //
  884. // End of "$Id: Fl_Tree.H 7903 2010-11-28 21:06:39Z matt $".
  885. //