Skip to main content

with_icons/
with_icons.rs

1//! The same functionality as [`basic`], but with real lucide-icons
2//! glyphs via the `icons` feature.
3//!
4//! Run with:
5//!
6//! ```sh
7//! cargo run --example with_icons --features icons -- /path/to/browse
8//! ```
9//!
10//! The only difference from `basic` is the `iced::application` call:
11//! we have to register the bundled lucide TTF with iced, otherwise the
12//! glyphs render as tofu squares. The crate re-exports
13//! [`LUCIDE_FONT_BYTES`] for exactly this purpose.
14
15use std::path::PathBuf;
16
17use iced::{Element, Length, Task};
18use iced_swdir_tree::{DirectoryFilter, DirectoryTree, DirectoryTreeEvent, LUCIDE_FONT_BYTES};
19
20#[derive(Debug, Clone)]
21enum Message {
22    Tree(DirectoryTreeEvent),
23    SetFilter(DirectoryFilter),
24}
25
26struct App {
27    tree: DirectoryTree,
28    last_selected: Option<PathBuf>,
29}
30
31impl App {
32    fn new() -> (Self, Task<Message>) {
33        let root = std::env::args()
34            .nth(1)
35            .map(PathBuf::from)
36            .unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
37        let tree = DirectoryTree::new(root).with_filter(DirectoryFilter::FilesAndFolders);
38        (
39            Self {
40                tree,
41                last_selected: None,
42            },
43            Task::none(),
44        )
45    }
46
47    fn update(&mut self, message: Message) -> Task<Message> {
48        match message {
49            Message::Tree(event) => {
50                if let DirectoryTreeEvent::Selected(p, _, _) = &event {
51                    self.last_selected = Some(p.clone());
52                }
53                self.tree.update(event).map(Message::Tree)
54            }
55            Message::SetFilter(filter) => {
56                self.tree.set_filter(filter);
57                Task::none()
58            }
59        }
60    }
61
62    fn view(&self) -> Element<'_, Message> {
63        use iced::widget::{button, column, container, row, text};
64
65        let filter_row = row![
66            text("Filter:"),
67            button("Folders only")
68                .on_press(Message::SetFilter(DirectoryFilter::FoldersOnly))
69                .style(if self.tree.filter() == DirectoryFilter::FoldersOnly {
70                    button::primary
71                } else {
72                    button::secondary
73                }),
74            button("Files + folders")
75                .on_press(Message::SetFilter(DirectoryFilter::FilesAndFolders))
76                .style(if self.tree.filter() == DirectoryFilter::FilesAndFolders {
77                    button::primary
78                } else {
79                    button::secondary
80                }),
81            button("All (w/ hidden)")
82                .on_press(Message::SetFilter(DirectoryFilter::AllIncludingHidden))
83                .style(
84                    if self.tree.filter() == DirectoryFilter::AllIncludingHidden {
85                        button::primary
86                    } else {
87                        button::secondary
88                    },
89                ),
90        ]
91        .spacing(8.0);
92
93        let status = text(match &self.last_selected {
94            Some(p) => format!("Selected: {}", p.display()),
95            None => "No selection yet. Click any row to select; click folders to expand.".into(),
96        });
97
98        container(
99            column![filter_row, self.tree.view(Message::Tree), status]
100                .spacing(8.0)
101                .padding(8.0),
102        )
103        .width(Length::Fill)
104        .height(Length::Fill)
105        .into()
106    }
107}
108
109fn main() -> iced::Result {
110    // Register the lucide TTF *before* rendering, otherwise the icon
111    // widget emits text that the default font can't draw. This is the
112    // one extra step compared to the `basic` example.
113    iced::application(App::new, App::update, App::view)
114        .title("iced-swdir-tree ยท with-icons example")
115        .font(LUCIDE_FONT_BYTES)
116        .run()
117}