implement navigation callback

This commit is contained in:
yggverse 2025-02-14 22:07:54 +02:00
parent 454ebe0170
commit 8ddd90bb11
3 changed files with 140 additions and 93 deletions

View file

@ -1,12 +1,24 @@
use gtk::{gio::File, prelude::FileExt}; use gtk::{gio::File, prelude::FileExt};
use std::rc::Rc;
pub struct Directory { pub struct Directory {
pub file: File, pub file: File,
} }
impl Directory { impl Directory {
pub fn handle(&self, page: &super::Page) { pub fn handle(&self, page: &Rc<super::Page>) {
page.content.to_directory(&self.file); 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_title(&self.file.parse_name());
page.set_progress(0.0); page.set_progress(0.0);
page.window_action.find.simple_action.set_enabled(false); page.window_action.find.simple_action.set_enabled(false);

View file

@ -131,9 +131,9 @@ impl Content {
text text
} }
pub fn to_directory(&self, file: &File) { pub fn to_directory(&self, file: &File, callback: impl Fn(&File) + 'static) {
self.clean(); self.clean();
self.g_box.append(&Directory::for_file(file)) self.g_box.append(&Directory::for_file(file, callback))
} }
/// * system `source:` /// * system `source:`

View file

@ -5,99 +5,134 @@ pub struct Directory;
impl Directory { impl Directory {
// Constructors // Constructors
pub fn for_file(file: &File) -> ScrolledWindow { pub fn for_file(file: &File, callback: impl Fn(&File) + 'static) -> ScrolledWindow {
const ATTRIBUTES:&str = "standard::name,standard::display-name,standard::symbolic-icon,standard::size,standard::content-type"; 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(
&gtk::SingleSelection::builder()
.model(
&gtk::DirectoryList::builder()
.file(file)
.attributes(ATTRIBUTES)
.build(),
)
.build(),
)
.build();
column_view.append_column(
&gtk::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::<ListItem>().unwrap();
let image = gtk::Image::from_gicon(
&list_item
.item()
.unwrap()
.downcast_ref::<FileInfo>()
.unwrap()
.symbolic_icon()
.unwrap(),
);
image.set_tooltip_text(
match list_item
.item()
.unwrap()
.downcast_ref::<FileInfo>()
.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(
&gtk::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::<ListItem>().unwrap();
let item = list_item.item().unwrap();
let file_info = item.downcast_ref::<FileInfo>().unwrap();
list_item.set_child(Some(
&gtk::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::<File>()
.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::<FileInfo>()
.unwrap()
.attribute_object("standard::file")
.unwrap()
.downcast_ref::<File>()
.unwrap(),
)
});
// Build main widget
ScrolledWindow::builder() ScrolledWindow::builder()
.child( .child(
&adw::Clamp::builder() &adw::Clamp::builder()
.child(&{ .child(&column_view)
let column_view = gtk::ColumnView::builder()
.model(
&gtk::SingleSelection::builder()
.model(
&gtk::DirectoryList::builder()
.file(file)
.attributes(ATTRIBUTES)
.build(),
)
.build(),
)
.build();
column_view.append_column(
&gtk::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::<gtk::ListItem>().unwrap();
let image = gtk::Image::from_gicon(
&list_item
.item()
.unwrap()
.downcast_ref::<gtk::gio::FileInfo>()
.unwrap()
.symbolic_icon()
.unwrap(),
);
image.set_tooltip_text(
match list_item
.item()
.unwrap()
.downcast_ref::<gtk::gio::FileInfo>()
.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(
&gtk::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::<gtk::ListItem>().unwrap();
let item = list_item.item().unwrap();
let file_info =
item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
list_item.set_child(Some(
&gtk::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
})
.css_classes(["view"]) .css_classes(["view"])
.build(), .build(),
) )