From 725e76470115f5c7bc6f06408a95f4c811c0e4cb Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 15 Feb 2025 03:09:26 +0200 Subject: [PATCH] implement shared features as traits --- .../tab/item/page/content/directory/column.rs | 160 +++++++----------- .../page/content/directory/column/display.rs | 20 +++ .../page/content/directory/column/format.rs | 36 ++++ 3 files changed, 118 insertions(+), 98 deletions(-) create mode 100644 src/app/browser/window/tab/item/page/content/directory/column/display.rs create mode 100644 src/app/browser/window/tab/item/page/content/directory/column/format.rs diff --git a/src/app/browser/window/tab/item/page/content/directory/column.rs b/src/app/browser/window/tab/item/page/content/directory/column.rs index f126e6bb..7b46a5c0 100644 --- a/src/app/browser/window/tab/item/page/content/directory/column.rs +++ b/src/app/browser/window/tab/item/page/content/directory/column.rs @@ -1,5 +1,13 @@ -const DEFAULT: &str = "-"; -const DATE_TIME_FORMAT: &str = "%Y.%m.%d %H:%M:%S"; +mod display; +mod format; + +use display::Display; +use format::Format; + +use gtk::{ + gio::FileInfo, pango::EllipsizeMode, Align, ColumnViewColumn, Label, ListItem, + SignalListItemFactory, +}; pub trait Column { fn icon() -> Self; @@ -11,10 +19,10 @@ pub trait Column { fn access_date_time(width: i32) -> Self; } -impl Column for gtk::ColumnViewColumn { +impl Column for ColumnViewColumn { fn icon() -> Self { use gtk::{ - gio::{FileInfo, FileType}, + gio::FileInfo, prelude::{BoxExt, Cast, ListItemExt, WidgetExt}, Align, ColumnViewColumn, ListItem, SignalListItemFactory, }; @@ -34,24 +42,15 @@ impl Column for gtk::ColumnViewColumn { .symbolic_icon() .unwrap(), ); - image.set_tooltip_text( - match list_item + image.set_tooltip_text(Some( + 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, - }, - ); + .as_str(), + )); let container = gtk::Box::builder().halign(Align::Center).build(); // prevents `gtk::Image` blur container.append(&image); list_item.set_child(Some(&container)); @@ -62,21 +61,21 @@ impl Column for gtk::ColumnViewColumn { } fn name(width: i32) -> Self { - gtk::ColumnViewColumn::builder() + ColumnViewColumn::builder() .fixed_width(width) .resizable(true) .title("Name") .factory(&{ - let factory = gtk::SignalListItemFactory::new(); + let factory = SignalListItemFactory::new(); factory.connect_bind(|_, this| { use gtk::prelude::{Cast, /*FileExt,*/ ListItemExt}; - let list_item = this.downcast_ref::().unwrap(); + let list_item = this.downcast_ref::().unwrap(); let item = list_item.item().unwrap(); - let file_info = item.downcast_ref::().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::builder() + .halign(Align::Start) + .ellipsize(EllipsizeMode::Middle) .label(file_info.display_name()) /*.tooltip_text( file_info @@ -98,22 +97,22 @@ impl Column for gtk::ColumnViewColumn { } fn size(width: i32) -> Self { - gtk::ColumnViewColumn::builder() + ColumnViewColumn::builder() .fixed_width(width) .resizable(true) .title("Size") .factory(&{ - let factory = gtk::SignalListItemFactory::new(); + let factory = SignalListItemFactory::new(); factory.connect_bind(|_, this| { use crate::tool::Format; use gtk::prelude::{Cast, ListItemExt}; - let list_item = this.downcast_ref::().unwrap(); + let list_item = this.downcast_ref::().unwrap(); let item = list_item.item().unwrap(); - let file_info = item.downcast_ref::().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::builder() + .halign(Align::Start) + .ellipsize(EllipsizeMode::Middle) .label((file_info.size() as usize).bytes()) .build(), )); @@ -124,39 +123,22 @@ impl Column for gtk::ColumnViewColumn { } fn content_type(width: i32) -> Self { - gtk::ColumnViewColumn::builder() + ColumnViewColumn::builder() .fixed_width(width) .resizable(true) .title("Content Type") .factory(&{ - let factory = gtk::SignalListItemFactory::new(); + let factory = SignalListItemFactory::new(); factory.connect_bind(|_, this| { use gtk::prelude::{Cast, ListItemExt}; - let list_item = this.downcast_ref::().unwrap(); + let list_item = this.downcast_ref::().unwrap(); let item = list_item.item().unwrap(); - let file_info = item.downcast_ref::().unwrap(); - let content_type: gtk::glib::GString = match file_info.content_type() { - Some(content_type) => { - let display_name = file_info.display_name(); - if content_type == "text/plain" { - if display_name.ends_with(".gmi") - || display_name.ends_with(".gemini") - { - "text/gemini".into() - } else { - content_type - } - } else { - content_type - } - } - None => DEFAULT.into(), - }; + 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(content_type) + &Label::builder() + .halign(Align::Start) + .ellipsize(EllipsizeMode::Middle) + .label(file_info.format_content_type()) .build(), )); }); @@ -166,28 +148,22 @@ impl Column for gtk::ColumnViewColumn { } fn creation_date_time(width: i32) -> Self { - gtk::ColumnViewColumn::builder() + ColumnViewColumn::builder() .fixed_width(width) .resizable(true) .title("Created") .factory(&{ - let factory = gtk::SignalListItemFactory::new(); + let factory = SignalListItemFactory::new(); factory.connect_bind(|_, this| { use gtk::prelude::{Cast, ListItemExt}; - let list_item = this.downcast_ref::().unwrap(); + let list_item = this.downcast_ref::().unwrap(); let item = list_item.item().unwrap(); - let file_info = item.downcast_ref::().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 - .creation_date_time() - .unwrap() - .format(DATE_TIME_FORMAT) // @TODO optional - .unwrap_or(DEFAULT.into()), - ) + &Label::builder() + .halign(Align::Start) + .ellipsize(EllipsizeMode::Middle) + .label(file_info.format_date_time()) .build(), )); }); @@ -197,28 +173,22 @@ impl Column for gtk::ColumnViewColumn { } fn modification_date_time(width: i32) -> Self { - gtk::ColumnViewColumn::builder() + ColumnViewColumn::builder() .fixed_width(width) .resizable(true) .title("Modified") .factory(&{ - let factory = gtk::SignalListItemFactory::new(); + let factory = SignalListItemFactory::new(); factory.connect_bind(|_, this| { use gtk::prelude::{Cast, ListItemExt}; - let list_item = this.downcast_ref::().unwrap(); + let list_item = this.downcast_ref::().unwrap(); let item = list_item.item().unwrap(); - let file_info = item.downcast_ref::().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 - .modification_date_time() - .unwrap() - .format(DATE_TIME_FORMAT) // @TODO optional - .unwrap_or(DEFAULT.into()), - ) + &Label::builder() + .halign(Align::Start) + .ellipsize(EllipsizeMode::Middle) + .label(file_info.format_date_time()) .build(), )); }); @@ -228,28 +198,22 @@ impl Column for gtk::ColumnViewColumn { } fn access_date_time(width: i32) -> Self { - gtk::ColumnViewColumn::builder() + ColumnViewColumn::builder() .fixed_width(width) .resizable(true) .title("Accessed") .factory(&{ - let factory = gtk::SignalListItemFactory::new(); + let factory = SignalListItemFactory::new(); factory.connect_bind(|_, this| { use gtk::prelude::{Cast, ListItemExt}; - let list_item = this.downcast_ref::().unwrap(); + let list_item = this.downcast_ref::().unwrap(); let item = list_item.item().unwrap(); - let file_info = item.downcast_ref::().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 - .access_date_time() - .unwrap() - .format(DATE_TIME_FORMAT) // @TODO optional - .unwrap_or(DEFAULT.into()), - ) + &Label::builder() + .halign(Align::Start) + .ellipsize(EllipsizeMode::Middle) + .label(file_info.format_date_time()) .build(), )); }); diff --git a/src/app/browser/window/tab/item/page/content/directory/column/display.rs b/src/app/browser/window/tab/item/page/content/directory/column/display.rs new file mode 100644 index 00000000..b9c5e8a4 --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/directory/column/display.rs @@ -0,0 +1,20 @@ +use gtk::gio::FileType; + +pub trait Display { + fn as_str(&self) -> &str; +} + +impl Display for FileType { + fn as_str(&self) -> &str { + match self { + FileType::Unknown => "Unknown", + FileType::Regular => "File", + FileType::Directory => "Directory", + FileType::SymbolicLink => "SymbolicLink", + FileType::Special => "Special", + FileType::Shortcut => "Shortcut", + FileType::Mountable => "Mountable", + _ => "Undefined", + } + } +} diff --git a/src/app/browser/window/tab/item/page/content/directory/column/format.rs b/src/app/browser/window/tab/item/page/content/directory/column/format.rs new file mode 100644 index 00000000..ba027dfb --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/directory/column/format.rs @@ -0,0 +1,36 @@ +use gtk::{gio::FileInfo, glib::GString}; + +const DEFAULT: &str = "-"; + +pub trait Format { + fn format_content_type(&self) -> GString; + fn format_date_time(&self) -> GString; +} + +impl Format for FileInfo { + fn format_content_type(&self) -> GString { + match self.content_type() { + Some(content_type) => { + let display_name = self.display_name(); + if content_type == "text/plain" { + if display_name.ends_with(".gmi") || display_name.ends_with(".gemini") { + "text/gemini".into() + } else { + content_type + } + } else { + content_type + } + } + None => DEFAULT.into(), + } + } + fn format_date_time(&self) -> GString { + match self.creation_date_time() { + Some(date_time) => date_time + .format("%Y.%m.%d %H:%M:%S") // @TODO optional + .unwrap_or(DEFAULT.into()), + None => DEFAULT.into(), + } + } +}