mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 16:45:27 +00:00
implement shared features as traits
This commit is contained in:
parent
6d49c79a0d
commit
725e764701
3 changed files with 118 additions and 98 deletions
|
|
@ -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::<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,
|
||||
},
|
||||
);
|
||||
.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::<gtk::ListItem>().unwrap();
|
||||
let list_item = this.downcast_ref::<ListItem>().unwrap();
|
||||
let item = list_item.item().unwrap();
|
||||
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
|
||||
let file_info = item.downcast_ref::<FileInfo>().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::<gtk::ListItem>().unwrap();
|
||||
let list_item = this.downcast_ref::<ListItem>().unwrap();
|
||||
let item = list_item.item().unwrap();
|
||||
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
|
||||
let file_info = item.downcast_ref::<FileInfo>().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::<gtk::ListItem>().unwrap();
|
||||
let list_item = this.downcast_ref::<ListItem>().unwrap();
|
||||
let item = list_item.item().unwrap();
|
||||
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().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::<FileInfo>().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::<gtk::ListItem>().unwrap();
|
||||
let list_item = this.downcast_ref::<ListItem>().unwrap();
|
||||
let item = list_item.item().unwrap();
|
||||
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
|
||||
let file_info = item.downcast_ref::<FileInfo>().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::<gtk::ListItem>().unwrap();
|
||||
let list_item = this.downcast_ref::<ListItem>().unwrap();
|
||||
let item = list_item.item().unwrap();
|
||||
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
|
||||
let file_info = item.downcast_ref::<FileInfo>().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::<gtk::ListItem>().unwrap();
|
||||
let list_item = this.downcast_ref::<ListItem>().unwrap();
|
||||
let item = list_item.item().unwrap();
|
||||
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
|
||||
let file_info = item.downcast_ref::<FileInfo>().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(),
|
||||
));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue