Implement condensed list view
This commit is contained in:
parent
d485e51acb
commit
f8521d5b0d
4 changed files with 113 additions and 59 deletions
|
|
@ -546,7 +546,10 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the application, and optionally emits command on initialize.
|
/// Creates the application, and optionally emits command on initialize.
|
||||||
fn init(core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
||||||
|
//TODO: make set_nav_bar_toggle_condensed pub
|
||||||
|
core.nav_bar_toggle_condensed();
|
||||||
|
|
||||||
let app_themes = vec![fl!("match-desktop"), fl!("dark"), fl!("light")];
|
let app_themes = vec![fl!("match-desktop"), fl!("dark"), fl!("light")];
|
||||||
|
|
||||||
let mut nav_model = segmented_button::ModelBuilder::default();
|
let mut nav_model = segmented_button::ModelBuilder::default();
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ pub const CONFIG_VERSION: u64 = 1;
|
||||||
|
|
||||||
// Default icon sizes
|
// Default icon sizes
|
||||||
const ICON_SIZE_LIST: u16 = 24;
|
const ICON_SIZE_LIST: u16 = 24;
|
||||||
|
const ICON_SIZE_LIST_CONDENSED: u16 = 48;
|
||||||
const ICON_SIZE_GRID: u16 = 64;
|
const ICON_SIZE_GRID: u16 = 64;
|
||||||
// TODO: 5 is an arbitrary number. Maybe there's a better icon size max
|
// TODO: 5 is an arbitrary number. Maybe there's a better icon size max
|
||||||
const ICON_SCALE_MAX: u16 = 5;
|
const ICON_SCALE_MAX: u16 = 5;
|
||||||
|
|
@ -98,6 +99,10 @@ impl IconSizes {
|
||||||
percent!(self.list, ICON_SIZE_LIST) as _
|
percent!(self.list, ICON_SIZE_LIST) as _
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_condensed(&self) -> u16 {
|
||||||
|
percent!(self.list, ICON_SIZE_LIST_CONDENSED) as _
|
||||||
|
}
|
||||||
|
|
||||||
pub fn grid(&self) -> u16 {
|
pub fn grid(&self) -> u16 {
|
||||||
percent!(self.grid, ICON_SIZE_GRID) as _
|
percent!(self.grid, ICON_SIZE_GRID) as _
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,8 @@ impl Application for App {
|
||||||
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Message>) {
|
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Message>) {
|
||||||
core.window.show_maximize = false;
|
core.window.show_maximize = false;
|
||||||
core.window.show_minimize = false;
|
core.window.show_minimize = false;
|
||||||
|
//TODO: make set_nav_bar_toggle_condensed pub
|
||||||
|
core.nav_bar_toggle_condensed();
|
||||||
|
|
||||||
let mut nav_model = segmented_button::ModelBuilder::default();
|
let mut nav_model = segmented_button::ModelBuilder::default();
|
||||||
if let Some(dir) = dirs::home_dir() {
|
if let Some(dir) = dirs::home_dir() {
|
||||||
|
|
|
||||||
160
src/tab.rs
160
src/tab.rs
|
|
@ -226,17 +226,20 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
|
||||||
|
|
||||||
let mime_guess = MimeGuess::from_path(&path);
|
let mime_guess = MimeGuess::from_path(&path);
|
||||||
|
|
||||||
let (icon_handle_grid, icon_handle_list) = if metadata.is_dir() {
|
let (icon_handle_grid, icon_handle_list, icon_handle_list_condensed) =
|
||||||
(
|
if metadata.is_dir() {
|
||||||
folder_icon(&path, sizes.grid()),
|
(
|
||||||
folder_icon(&path, sizes.list()),
|
folder_icon(&path, sizes.grid()),
|
||||||
)
|
folder_icon(&path, sizes.list()),
|
||||||
} else {
|
folder_icon(&path, sizes.list_condensed()),
|
||||||
(
|
)
|
||||||
mime_icon(&path, sizes.grid()),
|
} else {
|
||||||
mime_icon(&path, sizes.list()),
|
(
|
||||||
)
|
mime_icon(&path, sizes.grid()),
|
||||||
};
|
mime_icon(&path, sizes.list()),
|
||||||
|
mime_icon(&path, sizes.list_condensed()),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let children = if metadata.is_dir() {
|
let children = if metadata.is_dir() {
|
||||||
//TODO: calculate children in the background (and make it cancellable?)
|
//TODO: calculate children in the background (and make it cancellable?)
|
||||||
|
|
@ -259,6 +262,7 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
|
||||||
mime_guess,
|
mime_guess,
|
||||||
icon_handle_grid,
|
icon_handle_grid,
|
||||||
icon_handle_list,
|
icon_handle_list,
|
||||||
|
icon_handle_list_condensed,
|
||||||
thumbnail_res_opt: match mime_guess.first() {
|
thumbnail_res_opt: match mime_guess.first() {
|
||||||
Some(mime) if mime.type_() == "image" => None,
|
Some(mime) if mime.type_() == "image" => None,
|
||||||
_ => Some(Err(())),
|
_ => Some(Err(())),
|
||||||
|
|
@ -326,16 +330,19 @@ pub fn scan_trash(sizes: IconSizes) -> Vec<Item> {
|
||||||
|
|
||||||
let mime_guess = MimeGuess::from_path(&path);
|
let mime_guess = MimeGuess::from_path(&path);
|
||||||
|
|
||||||
let (icon_handle_grid, icon_handle_list) = match metadata.size {
|
let (icon_handle_grid, icon_handle_list, icon_handle_list_condensed) =
|
||||||
trash::TrashItemSize::Entries(_) => (
|
match metadata.size {
|
||||||
folder_icon(&path, sizes.grid()),
|
trash::TrashItemSize::Entries(_) => (
|
||||||
folder_icon(&path, sizes.list()),
|
folder_icon(&path, sizes.grid()),
|
||||||
),
|
folder_icon(&path, sizes.list()),
|
||||||
trash::TrashItemSize::Bytes(_) => (
|
folder_icon(&path, sizes.list_condensed()),
|
||||||
mime_icon(&path, sizes.grid()),
|
),
|
||||||
mime_icon(&path, sizes.list()),
|
trash::TrashItemSize::Bytes(_) => (
|
||||||
),
|
mime_icon(&path, sizes.grid()),
|
||||||
};
|
mime_icon(&path, sizes.list()),
|
||||||
|
mime_icon(&path, sizes.list_condensed()),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
items.push(Item {
|
items.push(Item {
|
||||||
name,
|
name,
|
||||||
|
|
@ -345,6 +352,7 @@ pub fn scan_trash(sizes: IconSizes) -> Vec<Item> {
|
||||||
mime_guess,
|
mime_guess,
|
||||||
icon_handle_grid,
|
icon_handle_grid,
|
||||||
icon_handle_list,
|
icon_handle_list,
|
||||||
|
icon_handle_list_condensed,
|
||||||
thumbnail_res_opt: Some(Err(())),
|
thumbnail_res_opt: Some(Err(())),
|
||||||
button_id: widget::Id::unique(),
|
button_id: widget::Id::unique(),
|
||||||
pos_opt: Cell::new(None),
|
pos_opt: Cell::new(None),
|
||||||
|
|
@ -450,6 +458,7 @@ pub struct Item {
|
||||||
pub mime_guess: MimeGuess,
|
pub mime_guess: MimeGuess,
|
||||||
pub icon_handle_grid: widget::icon::Handle,
|
pub icon_handle_grid: widget::icon::Handle,
|
||||||
pub icon_handle_list: widget::icon::Handle,
|
pub icon_handle_list: widget::icon::Handle,
|
||||||
|
pub icon_handle_list_condensed: widget::icon::Handle,
|
||||||
pub thumbnail_res_opt: Option<Result<image::RgbaImage, ()>>,
|
pub thumbnail_res_opt: Option<Result<image::RgbaImage, ()>>,
|
||||||
pub button_id: widget::Id,
|
pub button_id: widget::Id,
|
||||||
pub pos_opt: Cell<Option<(usize, usize)>>,
|
pub pos_opt: Cell<Option<(usize, usize)>>,
|
||||||
|
|
@ -1483,11 +1492,23 @@ impl Tab {
|
||||||
space_m, space_xxs, ..
|
space_m, space_xxs, ..
|
||||||
} = theme::active().cosmic().spacing;
|
} = theme::active().cosmic().spacing;
|
||||||
|
|
||||||
|
let TabConfig {
|
||||||
|
show_hidden,
|
||||||
|
icon_sizes,
|
||||||
|
} = self.config;
|
||||||
|
|
||||||
let size = self.size_opt.unwrap_or_else(|| Size::new(0.0, 0.0));
|
let size = self.size_opt.unwrap_or_else(|| Size::new(0.0, 0.0));
|
||||||
let row_height = 40;
|
//TODO: allow resizing?
|
||||||
//TODO: make adaptive?
|
let name_width = 300.0;
|
||||||
let modified_width = Length::Fixed(200.0);
|
let modified_width = 200.0;
|
||||||
let size_width = Length::Fixed(100.0);
|
let size_width = 100.0;
|
||||||
|
let condensed = size.width < (name_width + modified_width + size_width);
|
||||||
|
let icon_size = if condensed {
|
||||||
|
icon_sizes.list_condensed()
|
||||||
|
} else {
|
||||||
|
icon_sizes.list()
|
||||||
|
};
|
||||||
|
let row_height = icon_size + 2 * space_xxs;
|
||||||
|
|
||||||
let heading_item = |name, width, msg| {
|
let heading_item = |name, width, msg| {
|
||||||
let mut row = widget::row::with_capacity(2)
|
let mut row = widget::row::with_capacity(2)
|
||||||
|
|
@ -1511,31 +1532,33 @@ impl Tab {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut children: Vec<Element<_>> = Vec::new();
|
let mut children: Vec<Element<_>> = Vec::new();
|
||||||
children.push(
|
let mut y = 0;
|
||||||
widget::row::with_children(vec![
|
if !condensed {
|
||||||
heading_item(fl!("name"), Length::Fill, HeadingOptions::Name),
|
children.push(
|
||||||
//TODO: do not show modified column when in the trash
|
widget::row::with_children(vec![
|
||||||
heading_item(fl!("modified"), modified_width, HeadingOptions::Modified),
|
heading_item(fl!("name"), Length::Fill, HeadingOptions::Name),
|
||||||
heading_item(fl!("size"), size_width, HeadingOptions::Size),
|
//TODO: do not show modified column when in the trash
|
||||||
])
|
heading_item(
|
||||||
.align_items(Alignment::Center)
|
fl!("modified"),
|
||||||
.height(Length::Fixed(row_height as f32))
|
Length::Fixed(modified_width),
|
||||||
.padding(space_xxs)
|
HeadingOptions::Modified,
|
||||||
.spacing(space_xxs)
|
),
|
||||||
.into(),
|
heading_item(fl!("size"), Length::Fixed(size_width), HeadingOptions::Size),
|
||||||
);
|
])
|
||||||
let mut y = row_height;
|
.align_items(Alignment::Center)
|
||||||
|
.height(Length::Fixed(row_height as f32))
|
||||||
children.push(horizontal_rule(1).into());
|
.padding(space_xxs)
|
||||||
y += 1;
|
.spacing(space_xxs)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
y += row_height;
|
||||||
|
children.push(horizontal_rule(1).into());
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(items) = self.column_sort() {
|
if let Some(items) = self.column_sort() {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let mut hidden = 0;
|
let mut hidden = 0;
|
||||||
let TabConfig {
|
|
||||||
show_hidden,
|
|
||||||
icon_sizes,
|
|
||||||
} = self.config;
|
|
||||||
for (i, item) in items {
|
for (i, item) in items {
|
||||||
if !show_hidden && item.hidden {
|
if !show_hidden && item.hidden {
|
||||||
item.pos_opt.set(None);
|
item.pos_opt.set(None);
|
||||||
|
|
@ -1585,25 +1608,46 @@ impl Tab {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: align columns
|
let row = if condensed {
|
||||||
let button = widget::button(
|
widget::row::with_children(vec![
|
||||||
|
widget::icon::icon(item.icon_handle_list_condensed.clone())
|
||||||
|
.content_fit(ContentFit::Contain)
|
||||||
|
.size(icon_size)
|
||||||
|
.into(),
|
||||||
|
widget::column::with_children(vec![
|
||||||
|
widget::text(item.name.clone()).into(),
|
||||||
|
//TODO: translate?
|
||||||
|
widget::text(format!("{} - {}", modified_text, size_text)).into(),
|
||||||
|
])
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.spacing(space_xxs)
|
||||||
|
} else {
|
||||||
widget::row::with_children(vec![
|
widget::row::with_children(vec![
|
||||||
widget::icon::icon(item.icon_handle_list.clone())
|
widget::icon::icon(item.icon_handle_list.clone())
|
||||||
.content_fit(ContentFit::Contain)
|
.content_fit(ContentFit::Contain)
|
||||||
.size(icon_sizes.list())
|
.size(icon_size)
|
||||||
.into(),
|
.into(),
|
||||||
widget::text(item.name.clone()).width(Length::Fill).into(),
|
widget::text(item.name.clone()).width(Length::Fill).into(),
|
||||||
widget::text(modified_text).width(modified_width).into(),
|
widget::text(modified_text)
|
||||||
widget::text(size_text).width(size_width).into(),
|
.width(Length::Fixed(modified_width))
|
||||||
|
.into(),
|
||||||
|
widget::text(size_text)
|
||||||
|
.width(Length::Fixed(size_width))
|
||||||
|
.into(),
|
||||||
])
|
])
|
||||||
.align_items(Alignment::Center)
|
.align_items(Alignment::Center)
|
||||||
.spacing(space_xxs),
|
.spacing(space_xxs)
|
||||||
)
|
};
|
||||||
.height(Length::Fixed(row_height as f32))
|
|
||||||
.id(item.button_id.clone())
|
let button = widget::button(row)
|
||||||
.padding(space_xxs)
|
.width(Length::Fill)
|
||||||
.style(button_style(item.selected, true))
|
.height(Length::Fixed(row_height as f32))
|
||||||
.on_press(Message::Click(Some(i)));
|
.id(item.button_id.clone())
|
||||||
|
.padding(space_xxs)
|
||||||
|
.style(button_style(item.selected, true))
|
||||||
|
.on_press(Message::Click(Some(i)));
|
||||||
if self.context_menu.is_some() {
|
if self.context_menu.is_some() {
|
||||||
children.push(button.into());
|
children.push(button.into());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue