fltk/
browser.rs

1use crate::enums::{Color, Font};
2use crate::prelude::*;
3use crate::utils::FlString;
4use fltk_sys::browser::*;
5use std::{
6    ffi::{CStr, CString},
7    mem,
8    os::raw,
9};
10
11/**
12    Creates a normal browser.
13    Example usage:
14    ```rust,no_run
15    use fltk::{prelude::*, *};
16    fn main() {
17        let app = app::App::default();
18        let mut win = window::Window::default().with_size(900, 300);
19        let mut b = browser::Browser::new(10, 10, 900 - 20, 300 - 20, "");
20        let widths = &[50, 50, 50, 70, 70, 40, 40, 70, 70, 50];
21        b.set_column_widths(widths);
22        b.set_column_char('\t');
23        b.add("USER\tPID\t%CPU\t%MEM\tVSZ\tRSS\tTTY\tSTAT\tSTART\tTIME\tCOMMAND");
24        b.add("root\t2888\t0.0\t0.0\t1352\t0\ttty3\tSW\tAug15\t0:00\t@b@f/sbin/mingetty tty3");
25        b.add("erco\t2889\t0.0\t13.0\t221352\t0\ttty3\tR\tAug15\t1:34\t@b@f/usr/local/bin/render a35 0004");
26        b.add("uucp\t2892\t0.0\t0.0\t1352\t0\tttyS0\tSW\tAug15\t0:00\t@b@f/sbin/agetty -h 19200 ttyS0 vt100");
27        b.add("root\t13115\t0.0\t0.0\t1352\t0\ttty2\tSW\tAug30\t0:00\t@b@f/sbin/mingetty tty2");
28        b.add(
29            "root\t13464\t0.0\t0.0\t1352\t0\ttty1\tSW\tAug30\t0:00\t@b@f/sbin/mingetty tty1 --noclear",
30        );
31        win.end();
32        win.show();
33        app.run().unwrap();
34    }
35    ```
36*/
37#[derive(Debug)]
38pub struct Browser {
39    inner: crate::widget::WidgetTracker,
40    is_derived: bool,
41}
42
43crate::macros::widget::impl_widget_ext!(Browser, Fl_Browser);
44crate::macros::widget::impl_widget_base!(Browser, Fl_Browser);
45crate::macros::widget::impl_widget_default!(Browser, Fl_Browser);
46crate::macros::browser::impl_browser_ext!(Browser, Fl_Browser);
47
48/// Defines the browser type
49#[repr(i32)]
50#[derive(Debug, Copy, Clone, PartialEq, Eq)]
51pub enum BrowserType {
52    /// Normal browser
53    Normal = 0,
54    /// Enable select
55    Select = 1,
56    /// Enable holding
57    Hold = 2,
58    /// Multi selection
59    Multi = 3,
60}
61
62crate::macros::widget::impl_widget_type!(BrowserType);
63
64/// Defines the type of Scrollbar associated with the browser
65#[repr(u8)]
66#[derive(Debug, Copy, Clone, PartialEq, Eq)]
67pub enum BrowserScrollbar {
68    /// Never show bars
69    None = 0,
70    /// Show vertical bar
71    Horizontal = 1,
72    /// Show vertical bar
73    Vertical = 2,
74    /// Show both horizontal and vertical bars
75    Both = 3,
76    /// Always show bars
77    AlwaysOn = 4,
78    /// Show horizontal bar always
79    HorizontalAlways = 5,
80    /// Show vertical bar always
81    VerticalAlways = 6,
82    /// Always show both horizontal and vertical bars
83    BothAlways = 7,
84}
85
86/// Creates a select browser
87#[derive(Debug)]
88pub struct SelectBrowser {
89    inner: crate::widget::WidgetTracker,
90    is_derived: bool,
91}
92
93crate::macros::widget::impl_widget_ext!(SelectBrowser, Fl_Select_Browser);
94crate::macros::widget::impl_widget_base!(SelectBrowser, Fl_Select_Browser);
95crate::macros::widget::impl_widget_default!(SelectBrowser, Fl_Select_Browser);
96crate::macros::browser::impl_browser_ext!(SelectBrowser, Fl_Select_Browser);
97
98/// Creates a multi-browser
99#[derive(Debug)]
100pub struct MultiBrowser {
101    inner: crate::widget::WidgetTracker,
102    is_derived: bool,
103}
104
105crate::macros::widget::impl_widget_ext!(MultiBrowser, Fl_Multi_Browser);
106crate::macros::widget::impl_widget_base!(MultiBrowser, Fl_Multi_Browser);
107crate::macros::widget::impl_widget_default!(MultiBrowser, Fl_Multi_Browser);
108crate::macros::browser::impl_browser_ext!(MultiBrowser, Fl_Multi_Browser);
109
110/// Creates a hold browser
111#[derive(Debug)]
112pub struct HoldBrowser {
113    inner: crate::widget::WidgetTracker,
114    is_derived: bool,
115}
116
117crate::macros::widget::impl_widget_ext!(HoldBrowser, Fl_Hold_Browser);
118crate::macros::widget::impl_widget_base!(HoldBrowser, Fl_Hold_Browser);
119crate::macros::widget::impl_widget_default!(HoldBrowser, Fl_Hold_Browser);
120crate::macros::browser::impl_browser_ext!(HoldBrowser, Fl_Hold_Browser);
121
122/// Creates a file browser
123#[derive(Debug)]
124pub struct FileBrowser {
125    inner: crate::widget::WidgetTracker,
126    is_derived: bool,
127}
128
129crate::macros::widget::impl_widget_ext!(FileBrowser, Fl_File_Browser);
130crate::macros::widget::impl_widget_base!(FileBrowser, Fl_File_Browser);
131crate::macros::widget::impl_widget_default!(FileBrowser, Fl_File_Browser);
132crate::macros::browser::impl_browser_ext!(FileBrowser, Fl_File_Browser);
133
134/// File types for the `FileBrowser`
135#[repr(i32)]
136#[derive(Copy, Clone, Debug)]
137pub enum FileType {
138    /// Show files
139    Files = 0,
140    /// Show dirs
141    Dirs,
142}
143
144impl FileBrowser {
145    /// Gets the icon size
146    pub fn icon_size(&self) -> u32 {
147        unsafe { Fl_File_Browser_iconsize(self.inner.widget() as _) }
148    }
149
150    /// Sets the icon size
151    pub fn set_icon_size(&mut self, s: u32) {
152        unsafe { Fl_File_Browser_set_iconsize(self.inner.widget() as _, s) }
153    }
154
155    /// Sets the filter for the `FileBrowser`.
156    /// The following syntax is used for the pattern:
157    /// `*` matches any sequence of 0 or more characters.
158    /// `?` matches any single character.
159    /// `[set]` matches any character in the set. The set can contain any single characters, or a-z to represent a range.
160    /// To match `]` or `-`, they must be the first characters. To match `^` or `!`, they must not be the first characters.
161    /// `[^set]` or `[!set]` matches any character not in the set.
162    /// `{X|Y|Z}` or `{X,Y,Z}` matches any one of the subexpressions literally.
163    /// `\x` quotes the character `x` so it has no special meaning.
164    /// `x` all other characters must be matched exactly.
165    pub fn set_filter(&mut self, pattern: &'static str) {
166        let pattern = CString::safe_new(pattern);
167        unsafe {
168            // This is deleted on the C++ side
169            Fl_File_Browser_set_filter(self.inner.widget() as _, pattern.into_raw() as _);
170        }
171    }
172
173    /// Gets the filter for the `FileBrowser`
174    pub fn filter(&self) -> Option<String> {
175        unsafe {
176            let ptr = Fl_File_Browser_filter(self.inner.widget() as _);
177            if ptr.is_null() {
178                None
179            } else {
180                Some(
181                    CStr::from_ptr(ptr as *mut raw::c_char)
182                        .to_string_lossy()
183                        .to_string(),
184                )
185            }
186        }
187    }
188
189    /// Gets the `FileType` of the `FileBrowser`
190    pub fn filetype(&self) -> FileType {
191        unsafe { mem::transmute(Fl_File_Browser_filetype(self.inner.widget() as _)) }
192    }
193
194    /// Sets the `FileType` of the `FileBrowser`
195    pub fn set_filetype(&mut self, t: FileType) {
196        unsafe { Fl_File_Browser_set_filetype(self.inner.widget() as _, t as i32) }
197    }
198}
199
200/// Creates a `CheckBrowser` widget
201#[derive(Debug)]
202pub struct CheckBrowser {
203    inner: crate::widget::WidgetTracker,
204    is_derived: bool,
205}
206
207crate::macros::widget::impl_widget_ext!(CheckBrowser, Fl_Check_Browser);
208crate::macros::widget::impl_widget_base!(CheckBrowser, Fl_Check_Browser);
209crate::macros::widget::impl_widget_default!(CheckBrowser, Fl_Check_Browser);
210
211impl CheckBrowser {
212    /// Add an item, returns the number of current items
213    pub fn add(&mut self, s: &str, checked: bool) -> i32 {
214        let s = CString::safe_new(s);
215        unsafe { Fl_Check_Browser_add(self.inner.widget() as _, s.as_ptr(), i32::from(checked)) }
216    }
217
218    /// Remove item at index, returns the number of current items
219    pub fn remove(&mut self, item: usize) -> i32 {
220        if item > 0 && item <= self.size() {
221            unsafe { Fl_Check_Browser_remove(self.inner.widget() as _, item as i32) }
222        } else {
223            self.nitems() as _
224        }
225    }
226
227    /// Clear the browser
228    pub fn clear(&mut self) {
229        unsafe { Fl_Check_Browser_clear(self.inner.widget() as _) }
230    }
231
232    /// Return the number of items
233    pub fn nitems(&self) -> usize {
234        unsafe { Fl_Check_Browser_nitems(self.inner.widget() as _) as usize }
235    }
236
237    /// Return the number of items
238    pub fn size(&self) -> usize {
239        self.nitems()
240    }
241
242    /// Get the number of checked items
243    pub fn nchecked(&self) -> usize {
244        unsafe { Fl_Check_Browser_nchecked(self.inner.widget() as _) as usize }
245    }
246
247    /// Returns whether an item is checked
248    pub fn checked(&self, item: i32) -> bool {
249        if item > 0 && item <= self.size() as i32 {
250            unsafe { Fl_Check_Browser_checked(self.inner.widget() as _, item) != 0 }
251        } else {
252            false
253        }
254    }
255
256    /// Check selected item
257    pub fn set_checked(&mut self, item: i32) {
258        if item > 0 && item <= self.size() as i32 {
259            unsafe { Fl_Check_Browser_set_checked(self.inner.widget() as _, item) }
260        }
261    }
262
263    /// Check all of the items
264    pub fn check_all(&mut self) {
265        unsafe { Fl_Check_Browser_check_all(self.inner.widget() as _) }
266    }
267
268    /// Check none of the items
269    pub fn check_none(&mut self) {
270        unsafe { Fl_Check_Browser_check_none(self.inner.widget() as _) }
271    }
272
273    /// Returns the selected line, returns 0 if no line is selected
274    pub fn value(&self) -> i32 {
275        unsafe { Fl_Check_Browser_value(self.inner.widget() as _) }
276    }
277
278    /// Get the text of the item
279    pub fn text(&self, item: i32) -> Option<String> {
280        unsafe {
281            let ptr = Fl_Check_Browser_text(self.inner.widget() as _, item);
282            if ptr.is_null() {
283                None
284            } else {
285                Some(CStr::from_ptr(ptr).to_string_lossy().to_string())
286            }
287        }
288    }
289
290    /// Gets the text font
291    pub fn text_font(&self) -> Font {
292        unsafe { std::mem::transmute(Fl_Check_Browser_text_font(self.inner.widget() as _)) }
293    }
294
295    /// Sets the text font
296    pub fn set_text_font(&mut self, f: Font) {
297        unsafe { Fl_Check_Browser_set_text_font(self.inner.widget() as _, f.bits()) }
298    }
299
300    /// Gets the text size
301    pub fn text_size(&self) -> i32 {
302        unsafe { Fl_Check_Browser_text_size(self.inner.widget() as _) }
303    }
304
305    /// Sets the text size
306    pub fn set_text_size(&mut self, s: i32) {
307        unsafe { Fl_Check_Browser_set_text_size(self.inner.widget() as _, s) }
308    }
309
310    /// Gets the text's color
311    pub fn text_color(&self) -> Color {
312        unsafe { std::mem::transmute(Fl_Check_Browser_text_color(self.inner.widget() as _)) }
313    }
314
315    /// Sets the text's color
316    pub fn set_text_color(&mut self, color: Color) {
317        unsafe { Fl_Check_Browser_set_text_color(self.inner.widget() as _, color.bits()) }
318    }
319
320    /// Gets the vertical scroll position of the list as a pixel position
321    pub fn position(&self) -> i32 {
322        unsafe { Fl_Check_Browser_position(self.inner.widget() as _) }
323    }
324
325    /// Sets the vertical scroll position of the list as a pixel position
326    pub fn set_position(&mut self, pos: i32) {
327        unsafe { Fl_Check_Browser_set_position(self.inner.widget() as _, pos) }
328    }
329
330    /// Gets the horizontal scroll position of the list as a pixel position
331    pub fn hposition(&self) -> i32 {
332        unsafe { Fl_Check_Browser_hposition(self.inner.widget() as _) }
333    }
334
335    /// Sets the horizontal scroll position of the list as a pixel position
336    pub fn set_hposition(&mut self, pos: i32) {
337        unsafe { Fl_Check_Browser_set_hposition(self.inner.widget() as _, pos) }
338    }
339
340    /// Returns the type of scrollbar associated with the browser
341    pub fn has_scrollbar(&self) -> BrowserScrollbar {
342        unsafe { mem::transmute(Fl_Check_Browser_has_scrollbar(self.inner.widget() as _)) }
343    }
344
345    /// Sets the type of scrollbar associated with the browser
346    pub fn set_has_scrollbar(&mut self, mode: BrowserScrollbar) {
347        unsafe {
348            Fl_Check_Browser_set_has_scrollbar(self.inner.widget() as _, mode as raw::c_uchar);
349        }
350    }
351
352    /// Gets the scrollbar size
353    pub fn scrollbar_size(&self) -> i32 {
354        unsafe { Fl_Check_Browser_scrollbar_size(self.inner.widget() as _) }
355    }
356
357    /// Sets the scrollbar size
358    pub fn set_scrollbar_size(&mut self, new_size: i32) {
359        unsafe { Fl_Check_Browser_set_scrollbar_size(self.inner.widget() as _, new_size) }
360    }
361
362    /// Sort browser elements
363    pub fn sort(&mut self) {
364        unsafe { Fl_Check_Browser_sort(self.inner.widget() as _) }
365    }
366
367    /// Returns the vertical scrollbar
368    pub fn scrollbar(&self) -> crate::valuator::Scrollbar {
369        unsafe {
370            let ptr = Fl_Check_Browser_scrollbar(self.inner.widget() as _);
371            assert!(!ptr.is_null());
372            crate::valuator::Scrollbar::from_widget_ptr(ptr as *mut fltk_sys::widget::Fl_Widget)
373        }
374    }
375
376    /// Returns the horizontal scrollbar
377    pub fn hscrollbar(&self) -> crate::valuator::Scrollbar {
378        unsafe {
379            let ptr = Fl_Check_Browser_hscrollbar(self.inner.widget() as _);
380            assert!(!ptr.is_null());
381            crate::valuator::Scrollbar::from_widget_ptr(ptr as *mut fltk_sys::widget::Fl_Widget)
382        }
383    }
384}