libnotcurses_sys/widgets/tree/methods/
tree.rs

1use crate::{
2    c_api::{self, nctree_create, NCRESULT_ERR},
3    error, error_ref_mut,
4    widgets::{NcTree, NcTreeItem, NcTreeOptions},
5    NcError, NcInput, NcPlane, NcResult,
6};
7
8/// # `NcTree` constructors & destructors
9impl NcTree {
10    /// Creates an [NcTree] with the specified options.
11    ///
12    /// *C style function: [nctree_create()][c_api::nctree_create].*
13    pub fn new<'a>(plane: &mut NcPlane, options: NcTreeOptions) -> NcResult<&'a mut Self> {
14        error_ref_mut![unsafe { nctree_create(plane, &options) }, "Creating NcTree"]
15    }
16
17    /// Destroys an NcTree created with [new()][NcTree#method.new].
18    ///
19    /// *C style function: [nctree_destroy()][c_api::nctree_destroy].*
20    pub fn destroy(&mut self) {
21        unsafe { c_api::nctree_destroy(self) };
22    }
23}
24
25/// # `NcTree` methods
26impl NcTree {
27    // NOTE: not implemented yet in C API
28    //
29    // /// Goes to the item specified by the array |spec|, terminated by UINT_MAX.
30    // ///
31    // /// If the spec is invalid, returns an error and the depth of the first
32    // /// invalid spec is written to *|failspec|.
33    // ///
34    // /// Otherwise, the true depth is written to *|failspec|,
35    // /// and the curry is returned (|failspec| is necessary because the
36    // /// curry could itself be NULL).
37    // ///
38    // /// *C style function: [nctree_goto()][c_api::nctree_goto].*
39    // pub fn goto(&mut self, spec: ... , failspec: ...) -> NcResult<&mut NcTreeItem> {
40    //     let res = unsafe { c_api::nctree_goto(self) };
41    //     if !res.is_null() {
42    //         Ok(unsafe { &mut *(res as *mut NcTreeItem) })
43    //     } else {
44    //         Err(NcError::with_msg(NCRESULT_ERR, "NcTree.goto()"))
45    //     }
46    // }
47
48    /// Inserts `item` at `spec`.
49    ///
50    /// The path up to the last element must already exist. If an item already
51    /// exists at the path, it will be moved to make room for `item`.
52    ///
53    /// *C style function: [nctree_add()][c_api::nctree_add].*
54    pub fn add(&mut self, spec: &u32, item: &NcTreeItem) -> NcResult<()> {
55        error![unsafe { c_api::nctree_add(self, spec, item) }]
56    }
57
58    /// Deletes the item at `spec`, including any subitems.
59    ///
60    /// *C style function: [nctree_del()][c_api::nctree_del].*
61    pub fn del(&mut self, spec: &u32) -> NcResult<()> {
62        error![unsafe { c_api::nctree_del(self, spec) }]
63    }
64
65    /// Returns the focused item, if any items are present.
66    ///
67    /// This is not a copy; be careful to use it only for the duration of a
68    /// critical section.
69    ///
70    /// *C style function: [nctree_focused()][c_api::nctree_focused].*
71    pub fn focused(&mut self) -> NcResult<&mut NcTreeItem> {
72        let res = unsafe { c_api::nctree_focused(self) };
73        if !res.is_null() {
74            Ok(unsafe { &mut *(res as *mut NcTreeItem) })
75        } else {
76            Err(NcError::with_msg(NCRESULT_ERR, "NcTree.focused()"))
77        }
78    }
79
80    /// Changes the focus to the next item, and returns it.
81    ///
82    /// *C style function: [nctree_next()][c_api::nctree_next].*
83    #[allow(clippy::should_implement_trait)]
84    pub fn next(&mut self) -> NcResult<&mut NcTreeItem> {
85        let res = unsafe { c_api::nctree_next(self) };
86        if !res.is_null() {
87            Ok(unsafe { &mut *(res as *mut NcTreeItem) })
88        } else {
89            Err(NcError::with_msg(NCRESULT_ERR, "NcTree.next()"))
90        }
91    }
92
93    /// Changes the focus to the previous item, and returns it.
94    ///
95    /// *C style function: [nctree_prev()][c_api::nctree_prev].*
96    pub fn prev(&mut self) -> NcResult<&mut NcTreeItem> {
97        let res = unsafe { c_api::nctree_prev(self) };
98        if !res.is_null() {
99            Ok(unsafe { &mut *(res as *mut NcTreeItem) })
100        } else {
101            Err(NcError::with_msg(NCRESULT_ERR, "NcTree.prev()"))
102        }
103    }
104
105    /// Offers the `input` to this NcTree.
106    ///
107    /// If it's relevant, this function returns true,
108    /// and the input ought not be processed further.
109    /// If it's irrelevant to the tree, false is returned.
110    ///
111    /// Relevant inputs include:
112    ///
113    /// - a mouse click on an item (focuses item)
114    /// - a mouse scrollwheel event (srolls tree)
115    /// - up, down, pgup, or pgdown (navigates among items)
116    ///
117    /// *C style function: [nctree_offer_input()][c_api::nctree_offer_input].*
118    pub fn offer_input(&mut self, input: NcInput) -> bool {
119        unsafe { c_api::nctree_offer_input(self, &input) }
120    }
121
122    /// Returns the [NcPlane] backing this NcTree.
123    ///
124    /// *C style function: [nctree_plane()][c_api::nctree_plane].*
125    pub fn plane(&mut self) -> NcResult<&NcPlane> {
126        error_ref_mut![unsafe { c_api::nctree_plane(self) }, "NcTree.plane()"]
127    }
128
129    /// Redraws the NcTree in its entirety.
130    ///
131    /// The tree will be cleared, and items will be laid out, using the focused
132    /// item as a fulcrum.
133    ///
134    /// Item-drawing callbacks will be invoked for each visible item.
135    ///
136    /// *C style function: [nctree_redraw()][c_api::nctree_redraw].*
137    pub fn redraw(&mut self) -> NcResult<()> {
138        error![unsafe { c_api::nctree_redraw(self) }, "NcTree.redraw()"]
139    }
140}