Skip to content

Commit a083632

Browse files
committed
hide fs events handling from public file browser message
1 parent e100c75 commit a083632

File tree

1 file changed

+95
-83
lines changed
  • fyrox-ui/src/file_browser

1 file changed

+95
-83
lines changed

fyrox-ui/src/file_browser/mod.rs

Lines changed: 95 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ pub enum FileBrowserMessage {
6767
Root(Option<PathBuf>),
6868
Path(PathBuf),
6969
Filter(PathFilter),
70-
Add(PathBuf),
71-
Remove(PathBuf),
7270
FocusCurrentPath,
7371
Rescan,
7472
Drop {
@@ -81,6 +79,13 @@ pub enum FileBrowserMessage {
8179
}
8280
impl MessageData for FileBrowserMessage {}
8381

82+
#[derive(Debug, Clone, PartialEq)]
83+
enum FsEventMessage {
84+
Add(PathBuf),
85+
Remove(PathBuf),
86+
}
87+
impl MessageData for FsEventMessage {}
88+
8489
#[derive(Default, Clone, PartialEq, Eq, Hash, Debug, Visit, Reflect)]
8590
pub enum FileBrowserMode {
8691
#[default]
@@ -210,6 +215,88 @@ impl FileBrowser {
210215
self.rebuild_fs_tree(ui)
211216
}
212217
}
218+
219+
fn set_root(&mut self, root: &Option<PathBuf>, ui: &mut UserInterface) {
220+
let watcher_replacement = match self.watcher.take() {
221+
Some((mut watcher, converter)) => {
222+
let current_root = match &self.root {
223+
Some(path) => path.clone(),
224+
None => self.path.clone(),
225+
};
226+
if current_root.exists() {
227+
let _ = watcher.unwatch(&current_root);
228+
}
229+
let new_root = match &root {
230+
Some(path) => path.clone(),
231+
None => self.path.clone(),
232+
};
233+
let _ = watcher.watch(&new_root, notify::RecursiveMode::Recursive);
234+
Some((watcher, converter))
235+
}
236+
None => None,
237+
};
238+
self.root.clone_from(root);
239+
self.path = root.clone().unwrap_or_default();
240+
self.rebuild_fs_tree(ui);
241+
self.watcher = watcher_replacement;
242+
}
243+
244+
fn make_root_relative_path(&self, path: &Path) -> PathBuf {
245+
match self.root {
246+
Some(ref root) => {
247+
let remove_prefix = if root == Path::new(".") {
248+
std::env::current_dir().unwrap()
249+
} else {
250+
root.clone()
251+
};
252+
PathBuf::from("./").join(path.strip_prefix(remove_prefix).unwrap_or(path))
253+
}
254+
None => path.to_owned(),
255+
}
256+
}
257+
258+
fn on_file_added(&mut self, path: &Path, ui: &mut UserInterface) {
259+
let path = self.make_root_relative_path(path);
260+
if !self.filter.passes(&path) {
261+
return;
262+
}
263+
let parent_path = parent_path(&path);
264+
let existing_parent_node = fs_tree::find_tree_item(self.tree_root, &parent_path, ui);
265+
if existing_parent_node.is_some() {
266+
if let Some(tree) = ui.node(existing_parent_node).cast::<Tree>() {
267+
if tree.is_expanded {
268+
fs_tree::build_tree(
269+
existing_parent_node,
270+
existing_parent_node == self.tree_root,
271+
path,
272+
parent_path,
273+
self.item_context_menu.clone(),
274+
self.root_title.as_deref(),
275+
ui,
276+
);
277+
} else if !tree.always_show_expander {
278+
ui.send(tree.handle(), TreeMessage::SetExpanderShown(true))
279+
}
280+
}
281+
}
282+
}
283+
284+
fn on_file_removed(&mut self, path: &Path, ui: &mut UserInterface) {
285+
let path = self.make_root_relative_path(path);
286+
let node = fs_tree::find_tree_item(self.tree_root, &path, ui);
287+
if node.is_some() {
288+
let parent_path = parent_path(&path);
289+
let parent_node = fs_tree::find_tree_item(self.tree_root, &parent_path, ui);
290+
ui.send(parent_node, TreeMessage::RemoveItem(node))
291+
}
292+
}
293+
294+
fn handle_fs_event_message(&mut self, msg: &FsEventMessage, ui: &mut UserInterface) {
295+
match msg {
296+
FsEventMessage::Add(path) => self.on_file_added(path, ui),
297+
FsEventMessage::Remove(path) => self.on_file_removed(path, ui),
298+
}
299+
}
213300
}
214301

215302
uuid_provider!(FileBrowser = "b7f4610e-4b0c-4671-9b4a-60bb45268928");
@@ -218,7 +305,9 @@ impl Control for FileBrowser {
218305
fn handle_routed_message(&mut self, ui: &mut UserInterface, message: &mut UiMessage) {
219306
self.widget.handle_routed_message(ui, message);
220307

221-
if let Some(msg) = message.data::<FileBrowserMessage>() {
308+
if let Some(msg) = message.data_for::<FsEventMessage>(self.handle()) {
309+
self.handle_fs_event_message(msg, ui);
310+
} else if let Some(msg) = message.data::<FileBrowserMessage>() {
222311
if message.destination() == self.handle() {
223312
match msg {
224313
FileBrowserMessage::Path(path) => {
@@ -229,29 +318,7 @@ impl Control for FileBrowser {
229318
}
230319
FileBrowserMessage::Root(root) => {
231320
if &self.root != root {
232-
let watcher_replacement = match self.watcher.take() {
233-
Some((mut watcher, converter)) => {
234-
let current_root = match &self.root {
235-
Some(path) => path.clone(),
236-
None => self.path.clone(),
237-
};
238-
if current_root.exists() {
239-
let _ = watcher.unwatch(&current_root);
240-
}
241-
let new_root = match &root {
242-
Some(path) => path.clone(),
243-
None => self.path.clone(),
244-
};
245-
let _ =
246-
watcher.watch(&new_root, notify::RecursiveMode::Recursive);
247-
Some((watcher, converter))
248-
}
249-
None => None,
250-
};
251-
self.root.clone_from(root);
252-
self.path = root.clone().unwrap_or_default();
253-
self.rebuild_fs_tree(ui);
254-
self.watcher = watcher_replacement;
321+
self.set_root(root, ui)
255322
}
256323
}
257324
FileBrowserMessage::Filter(filter) => {
@@ -260,44 +327,6 @@ impl Control for FileBrowser {
260327
self.rebuild_fs_tree(ui);
261328
}
262329
}
263-
FileBrowserMessage::Add(path) => {
264-
let path =
265-
make_fs_watcher_event_path_relative_to_tree_root(&self.root, path);
266-
if !self.filter.passes(&path) {
267-
return;
268-
}
269-
let parent_path = parent_path(&path);
270-
let existing_parent_node =
271-
fs_tree::find_tree_item(self.tree_root, &parent_path, ui);
272-
if existing_parent_node.is_some() {
273-
if let Some(tree) = ui.node(existing_parent_node).cast::<Tree>() {
274-
if tree.is_expanded {
275-
fs_tree::build_tree(
276-
existing_parent_node,
277-
existing_parent_node == self.tree_root,
278-
path,
279-
parent_path,
280-
self.item_context_menu.clone(),
281-
self.root_title.as_deref(),
282-
ui,
283-
);
284-
} else if !tree.always_show_expander {
285-
ui.send(tree.handle(), TreeMessage::SetExpanderShown(true))
286-
}
287-
}
288-
}
289-
}
290-
FileBrowserMessage::Remove(path) => {
291-
let path =
292-
make_fs_watcher_event_path_relative_to_tree_root(&self.root, path);
293-
let node = fs_tree::find_tree_item(self.tree_root, &path, ui);
294-
if node.is_some() {
295-
let parent_path = parent_path(&path);
296-
let parent_node =
297-
fs_tree::find_tree_item(self.tree_root, &parent_path, ui);
298-
ui.send(parent_node, TreeMessage::RemoveItem(node))
299-
}
300-
}
301330
FileBrowserMessage::Rescan | FileBrowserMessage::Drop { .. } => (),
302331
FileBrowserMessage::FocusCurrentPath => {
303332
if let Ok(canonical_path) = self.path.canonicalize() {
@@ -452,10 +481,10 @@ impl Control for FileBrowser {
452481
for path in event.paths.iter() {
453482
match event.kind {
454483
notify::EventKind::Remove(_) => {
455-
ui.send(self.handle, FileBrowserMessage::Remove(path.clone()));
484+
ui.send(self.handle, FsEventMessage::Remove(path.clone()));
456485
}
457486
notify::EventKind::Create(_) => {
458-
ui.send(self.handle, FileBrowserMessage::Add(path.clone()));
487+
ui.send(self.handle, FsEventMessage::Add(path.clone()));
459488
}
460489
_ => (),
461490
}
@@ -478,23 +507,6 @@ fn parent_path(path: &Path) -> PathBuf {
478507
parent_path
479508
}
480509

481-
fn make_fs_watcher_event_path_relative_to_tree_root(
482-
root: &Option<PathBuf>,
483-
path: &Path,
484-
) -> PathBuf {
485-
match root {
486-
Some(ref root) => {
487-
let remove_prefix = if root == Path::new(".") {
488-
std::env::current_dir().unwrap()
489-
} else {
490-
root.clone()
491-
};
492-
PathBuf::from("./").join(path.strip_prefix(remove_prefix).unwrap_or(path))
493-
}
494-
None => path.to_owned(),
495-
}
496-
}
497-
498510
pub struct FileBrowserBuilder {
499511
widget_builder: WidgetBuilder,
500512
path: PathBuf,

0 commit comments

Comments
 (0)