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,14 +5,17 @@ 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";
ScrolledWindow::builder()
.child(
&adw::Clamp::builder()
.child(&{
let column_view = gtk::ColumnView::builder() let column_view = gtk::ColumnView::builder()
// @TODO enable this option may cause core dumped errors
// .single_click_activate(true)
.model( .model(
&gtk::SingleSelection::builder() &gtk::SingleSelection::builder()
.model( .model(
@ -24,6 +27,7 @@ impl Directory {
.build(), .build(),
) )
.build(); .build();
column_view.append_column( column_view.append_column(
&gtk::ColumnViewColumn::builder() &gtk::ColumnViewColumn::builder()
.title("Type") .title("Type")
@ -32,13 +36,12 @@ impl Directory {
let factory = gtk::SignalListItemFactory::new(); let factory = gtk::SignalListItemFactory::new();
factory.connect_bind(|_, this| { factory.connect_bind(|_, this| {
use gtk::gio::FileType; use gtk::gio::FileType;
let list_item = let list_item = this.downcast_ref::<ListItem>().unwrap();
this.downcast_ref::<gtk::ListItem>().unwrap();
let image = gtk::Image::from_gicon( let image = gtk::Image::from_gicon(
&list_item &list_item
.item() .item()
.unwrap() .unwrap()
.downcast_ref::<gtk::gio::FileInfo>() .downcast_ref::<FileInfo>()
.unwrap() .unwrap()
.symbolic_icon() .symbolic_icon()
.unwrap(), .unwrap(),
@ -47,7 +50,7 @@ impl Directory {
match list_item match list_item
.item() .item()
.unwrap() .unwrap()
.downcast_ref::<gtk::gio::FileInfo>() .downcast_ref::<FileInfo>()
.unwrap() .unwrap()
.file_type() .file_type()
{ {
@ -61,8 +64,7 @@ impl Directory {
_ => None, _ => None,
}, },
); );
let container = let container = gtk::Box::builder().halign(Align::Center).build(); // prevents `gtk::Image` blur
gtk::Box::builder().halign(gtk::Align::Center).build(); // prevents `gtk::Image` blur
container.append(&image); container.append(&image);
list_item.set_child(Some(&container)); list_item.set_child(Some(&container));
}); });
@ -70,6 +72,7 @@ impl Directory {
}) })
.build(), .build(),
); );
column_view.append_column( column_view.append_column(
&gtk::ColumnViewColumn::builder() &gtk::ColumnViewColumn::builder()
.expand(true) .expand(true)
@ -77,18 +80,26 @@ impl Directory {
.factory(&{ .factory(&{
let factory = gtk::SignalListItemFactory::new(); let factory = gtk::SignalListItemFactory::new();
factory.connect_bind(|_, this| { factory.connect_bind(|_, this| {
use gtk::prelude::{Cast, ListItemExt}; use gtk::prelude::{Cast, FileExt, ListItemExt};
let list_item = let list_item = this.downcast_ref::<ListItem>().unwrap();
this.downcast_ref::<gtk::ListItem>().unwrap();
let item = list_item.item().unwrap(); let item = list_item.item().unwrap();
let file_info = let file_info = item.downcast_ref::<FileInfo>().unwrap();
item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
list_item.set_child(Some( list_item.set_child(Some(
&gtk::Label::builder() &gtk::Label::builder()
.halign(gtk::Align::Start) .halign(Align::Start)
.ellipsize(gtk::pango::EllipsizeMode::Middle) .ellipsize(gtk::pango::EllipsizeMode::Middle)
.label(file_info.display_name()) .label(file_info.display_name())
.tooltip_text(file_info.display_name()) .tooltip_text(
file_info
.attribute_object("standard::file")
.unwrap()
.downcast_ref::<File>()
.unwrap()
.path()
.unwrap()
.to_str()
.unwrap(),
)
.build(), .build(),
)); ));
}); });
@ -96,8 +107,32 @@ impl Directory {
}) })
.build(), .build(),
); );
column_view 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()
.child(
&adw::Clamp::builder()
.child(&column_view)
.css_classes(["view"]) .css_classes(["view"])
.build(), .build(),
) )