Skip to main content

basic/
basic.rs

1//! A minimal iced application using [`DirectoryTree`] with the text
2//! icon fallback (no `icons` feature required).
3//!
4//! Run with:
5//!
6//! ```sh
7//! cargo run --example basic -- /path/to/browse
8//! ```
9//!
10//! Defaults to the current working directory if no path is given.
11
12use std::path::PathBuf;
13
14use iced::{Element, Length, Task};
15use iced_swdir_tree::{DirectoryFilter, DirectoryTree, DirectoryTreeEvent};
16
17#[derive(Debug, Clone)]
18enum Message {
19    Tree(DirectoryTreeEvent),
20    SetFilter(DirectoryFilter),
21}
22
23struct App {
24    tree: DirectoryTree,
25    last_selected: Option<PathBuf>,
26}
27
28impl App {
29    fn new() -> (Self, Task<Message>) {
30        let root = std::env::args()
31            .nth(1)
32            .map(PathBuf::from)
33            .unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
34        let tree = DirectoryTree::new(root).with_filter(DirectoryFilter::FilesAndFolders);
35        (
36            Self {
37                tree,
38                last_selected: None,
39            },
40            Task::none(),
41        )
42    }
43
44    fn update(&mut self, message: Message) -> Task<Message> {
45        match message {
46            Message::Tree(event) => {
47                // Side-effect: remember the last selection so we can
48                // show it in the status bar.
49                if let DirectoryTreeEvent::Selected(p, _, _) = &event {
50                    self.last_selected = Some(p.clone());
51                }
52                self.tree.update(event).map(Message::Tree)
53            }
54            Message::SetFilter(filter) => {
55                self.tree.set_filter(filter);
56                Task::none()
57            }
58        }
59    }
60
61    fn view(&self) -> Element<'_, Message> {
62        use iced::widget::{button, column, container, row, text};
63
64        // Three plain buttons for filter selection. Keeps the example
65        // dependency-free of `Display` impls or pick_list complexity.
66        let filter_row = row![
67            text("Filter:"),
68            button("Folders only")
69                .on_press(Message::SetFilter(DirectoryFilter::FoldersOnly))
70                .style(if self.tree.filter() == DirectoryFilter::FoldersOnly {
71                    button::primary
72                } else {
73                    button::secondary
74                }),
75            button("Files + folders")
76                .on_press(Message::SetFilter(DirectoryFilter::FilesAndFolders))
77                .style(if self.tree.filter() == DirectoryFilter::FilesAndFolders {
78                    button::primary
79                } else {
80                    button::secondary
81                }),
82            button("All (w/ hidden)")
83                .on_press(Message::SetFilter(DirectoryFilter::AllIncludingHidden))
84                .style(
85                    if self.tree.filter() == DirectoryFilter::AllIncludingHidden {
86                        button::primary
87                    } else {
88                        button::secondary
89                    },
90                ),
91        ]
92        .spacing(8.0);
93
94        let status = text(match &self.last_selected {
95            Some(p) => format!("Selected: {}", p.display()),
96            None => "No selection yet. Click any row to select; click folders to expand.".into(),
97        });
98
99        container(
100            column![filter_row, self.tree.view(Message::Tree), status]
101                .spacing(8.0)
102                .padding(8.0),
103        )
104        .width(Length::Fill)
105        .height(Length::Fill)
106        .into()
107    }
108}
109
110fn main() -> iced::Result {
111    iced::application(App::new, App::update, App::view)
112        .title("iced-swdir-tree ยท basic example")
113        .run()
114}