diff --git a/src/app/browser/window/tab/item/client/driver/file/directory.rs b/src/app/browser/window/tab/item/client/driver/file/directory.rs index 665c08c1..693cba5c 100644 --- a/src/app/browser/window/tab/item/client/driver/file/directory.rs +++ b/src/app/browser/window/tab/item/client/driver/file/directory.rs @@ -1,12 +1,24 @@ use gtk::{gio::File, prelude::FileExt}; +use std::rc::Rc; pub struct Directory { pub file: File, } impl Directory { - pub fn handle(&self, page: &super::Page) { - page.content.to_directory(&self.file); + pub fn handle(&self, page: &Rc) { + page.content.to_directory(&self.file, { + let page = page.clone(); + move |file| { + page.item_action.load.activate( + Some(&format!( + "file://{}", + file.path().unwrap().to_str().unwrap() + )), + true, + ) + } + }); page.set_title(&self.file.parse_name()); page.set_progress(0.0); page.window_action.find.simple_action.set_enabled(false); diff --git a/src/app/browser/window/tab/item/page/content.rs b/src/app/browser/window/tab/item/page/content.rs index cc934204..97e615d9 100644 --- a/src/app/browser/window/tab/item/page/content.rs +++ b/src/app/browser/window/tab/item/page/content.rs @@ -131,9 +131,9 @@ impl Content { text } - pub fn to_directory(&self, file: &File) { + pub fn to_directory(&self, file: &File, callback: impl Fn(&File) + 'static) { self.clean(); - self.g_box.append(&Directory::for_file(file)) + self.g_box.append(&Directory::for_file(file, callback)) } /// * system `source:` diff --git a/src/app/browser/window/tab/item/page/content/directory.rs b/src/app/browser/window/tab/item/page/content/directory.rs index af848243..1f9e11a8 100644 --- a/src/app/browser/window/tab/item/page/content/directory.rs +++ b/src/app/browser/window/tab/item/page/content/directory.rs @@ -5,99 +5,134 @@ pub struct Directory; impl Directory { // Constructors - pub fn for_file(file: &File) -> ScrolledWindow { - const ATTRIBUTES:&str = "standard::name,standard::display-name,standard::symbolic-icon,standard::size,standard::content-type"; + pub fn for_file(file: &File, callback: impl Fn(&File) + 'static) -> ScrolledWindow { + use gtk::{gio::FileInfo, Align, ListItem}; + // Init children widget + let column_view = { + const ATTRIBUTES: &str = + "standard::display-name,standard::symbolic-icon,standard::size,standard::content-type"; + + let column_view = gtk::ColumnView::builder() + // @TODO enable this option may cause core dumped errors + // .single_click_activate(true) + .model( + >k::SingleSelection::builder() + .model( + >k::DirectoryList::builder() + .file(file) + .attributes(ATTRIBUTES) + .build(), + ) + .build(), + ) + .build(); + + column_view.append_column( + >k::ColumnViewColumn::builder() + .title("Type") + .factory(&{ + use gtk::prelude::{BoxExt, Cast, ListItemExt, WidgetExt}; + let factory = gtk::SignalListItemFactory::new(); + factory.connect_bind(|_, this| { + use gtk::gio::FileType; + let list_item = this.downcast_ref::().unwrap(); + let image = gtk::Image::from_gicon( + &list_item + .item() + .unwrap() + .downcast_ref::() + .unwrap() + .symbolic_icon() + .unwrap(), + ); + image.set_tooltip_text( + match list_item + .item() + .unwrap() + .downcast_ref::() + .unwrap() + .file_type() + { + FileType::Unknown => Some("Unknown"), + FileType::Regular => Some("File"), + FileType::Directory => Some("Directory"), + FileType::SymbolicLink => Some("SymbolicLink"), + FileType::Special => Some("Special"), + FileType::Shortcut => Some("Shortcut"), + FileType::Mountable => Some("Mountable"), + _ => None, + }, + ); + let container = gtk::Box::builder().halign(Align::Center).build(); // prevents `gtk::Image` blur + container.append(&image); + list_item.set_child(Some(&container)); + }); + factory + }) + .build(), + ); + + column_view.append_column( + >k::ColumnViewColumn::builder() + .expand(true) + .title("Name") + .factory(&{ + let factory = gtk::SignalListItemFactory::new(); + factory.connect_bind(|_, this| { + use gtk::prelude::{Cast, FileExt, ListItemExt}; + let list_item = this.downcast_ref::().unwrap(); + let item = list_item.item().unwrap(); + let file_info = item.downcast_ref::().unwrap(); + list_item.set_child(Some( + >k::Label::builder() + .halign(Align::Start) + .ellipsize(gtk::pango::EllipsizeMode::Middle) + .label(file_info.display_name()) + .tooltip_text( + file_info + .attribute_object("standard::file") + .unwrap() + .downcast_ref::() + .unwrap() + .path() + .unwrap() + .to_str() + .unwrap(), + ) + .build(), + )); + }); + factory + }) + .build(), + ); + + column_view + }; + + // Connect events + column_view.connect_activate(move |this, i| { + use gtk::prelude::{Cast, ListModelExt}; + callback( + this.model() + .unwrap() + .item(i) + .unwrap() + .downcast_ref::() + .unwrap() + .attribute_object("standard::file") + .unwrap() + .downcast_ref::() + .unwrap(), + ) + }); + + // Build main widget ScrolledWindow::builder() .child( &adw::Clamp::builder() - .child(&{ - let column_view = gtk::ColumnView::builder() - .model( - >k::SingleSelection::builder() - .model( - >k::DirectoryList::builder() - .file(file) - .attributes(ATTRIBUTES) - .build(), - ) - .build(), - ) - .build(); - column_view.append_column( - >k::ColumnViewColumn::builder() - .title("Type") - .factory(&{ - use gtk::prelude::{BoxExt, Cast, ListItemExt, WidgetExt}; - let factory = gtk::SignalListItemFactory::new(); - factory.connect_bind(|_, this| { - use gtk::gio::FileType; - let list_item = - this.downcast_ref::().unwrap(); - let image = gtk::Image::from_gicon( - &list_item - .item() - .unwrap() - .downcast_ref::() - .unwrap() - .symbolic_icon() - .unwrap(), - ); - image.set_tooltip_text( - match list_item - .item() - .unwrap() - .downcast_ref::() - .unwrap() - .file_type() - { - FileType::Unknown => Some("Unknown"), - FileType::Regular => Some("File"), - FileType::Directory => Some("Directory"), - FileType::SymbolicLink => Some("SymbolicLink"), - FileType::Special => Some("Special"), - FileType::Shortcut => Some("Shortcut"), - FileType::Mountable => Some("Mountable"), - _ => None, - }, - ); - let container = - gtk::Box::builder().halign(gtk::Align::Center).build(); // prevents `gtk::Image` blur - container.append(&image); - list_item.set_child(Some(&container)); - }); - factory - }) - .build(), - ); - column_view.append_column( - >k::ColumnViewColumn::builder() - .expand(true) - .title("Name") - .factory(&{ - let factory = gtk::SignalListItemFactory::new(); - factory.connect_bind(|_, this| { - use gtk::prelude::{Cast, ListItemExt}; - let list_item = - this.downcast_ref::().unwrap(); - let item = list_item.item().unwrap(); - let file_info = - item.downcast_ref::().unwrap(); - list_item.set_child(Some( - >k::Label::builder() - .halign(gtk::Align::Start) - .ellipsize(gtk::pango::EllipsizeMode::Middle) - .label(file_info.display_name()) - .tooltip_text(file_info.display_name()) - .build(), - )); - }); - factory - }) - .build(), - ); - column_view - }) + .child(&column_view) .css_classes(["view"]) .build(), )