Only build widgets for visible items
This commit is contained in:
parent
10f234bf79
commit
5e4d4523f4
2 changed files with 311 additions and 271 deletions
|
|
@ -5363,7 +5363,7 @@ impl Application for App {
|
||||||
fn system_theme_update(
|
fn system_theme_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
_keys: &[&'static str],
|
_keys: &[&'static str],
|
||||||
new_theme: &cosmic::cosmic_theme::Theme,
|
_new_theme: &cosmic::cosmic_theme::Theme,
|
||||||
) -> Task<Self::Message> {
|
) -> Task<Self::Message> {
|
||||||
self.update(Message::SystemThemeModeChange)
|
self.update(Message::SystemThemeModeChange)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
580
src/tab.rs
580
src/tab.rs
|
|
@ -4738,6 +4738,16 @@ impl Tab {
|
||||||
rows_m1 + 1
|
rows_m1 + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//TODO: move to function
|
||||||
|
let visible_rect = {
|
||||||
|
let point = match self.scroll_opt {
|
||||||
|
Some(offset) => Point::new(0.0, offset.y),
|
||||||
|
None => Point::new(0.0, 0.0),
|
||||||
|
};
|
||||||
|
let size = self.size_opt.get().unwrap_or_else(|| Size::new(0.0, 0.0));
|
||||||
|
Rectangle::new(point, size)
|
||||||
|
};
|
||||||
|
|
||||||
let mut grid = widget::grid()
|
let mut grid = widget::grid()
|
||||||
.column_spacing(column_spacing)
|
.column_spacing(column_spacing)
|
||||||
.row_spacing(grid_spacing)
|
.row_spacing(grid_spacing)
|
||||||
|
|
@ -4765,93 +4775,106 @@ impl Tab {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
item.pos_opt.set(Some((row, col)));
|
item.pos_opt.set(Some((row, col)));
|
||||||
item.rect_opt.set(Some(Rectangle::new(
|
let item_rect = Rectangle::new(
|
||||||
Point::new(
|
Point::new(
|
||||||
(col * (item_width + column_spacing as usize) + space_m as usize) as f32,
|
(col * (item_width + column_spacing as usize) + space_m as usize) as f32,
|
||||||
(row * (item_height + grid_spacing as usize)) as f32,
|
(row * (item_height + grid_spacing as usize)) as f32,
|
||||||
),
|
),
|
||||||
Size::new(item_width as f32, item_height as f32),
|
Size::new(item_width as f32, item_height as f32),
|
||||||
)));
|
);
|
||||||
|
item.rect_opt.set(Some(item_rect));
|
||||||
//TODO: one focus group per grid item (needs custom widget)
|
|
||||||
let buttons: Vec<Element<Message>> = vec![
|
|
||||||
widget::button::custom(
|
|
||||||
widget::icon::icon(item.icon_handle_grid.clone())
|
|
||||||
.content_fit(ContentFit::Contain)
|
|
||||||
.size(icon_sizes.grid())
|
|
||||||
.width(Length::Shrink),
|
|
||||||
)
|
|
||||||
.padding(space_xxxs)
|
|
||||||
.class(button_style(
|
|
||||||
item.selected,
|
|
||||||
item.highlighted,
|
|
||||||
item.cut,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
))
|
|
||||||
.into(),
|
|
||||||
widget::tooltip(
|
|
||||||
widget::button::custom(widget::text::body(&item.display_name))
|
|
||||||
.id(item.button_id.clone())
|
|
||||||
.padding([0, space_xxxs])
|
|
||||||
.class(button_style(
|
|
||||||
item.selected,
|
|
||||||
item.highlighted,
|
|
||||||
item.cut,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
matches!(self.mode, Mode::Desktop),
|
|
||||||
)),
|
|
||||||
widget::text::body(&item.name),
|
|
||||||
widget::tooltip::Position::Bottom,
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut column = widget::column::with_capacity(buttons.len())
|
|
||||||
.align_x(Alignment::Center)
|
|
||||||
.height(Length::Fixed(item_height as f32))
|
|
||||||
.width(Length::Fixed(item_width as f32));
|
|
||||||
for button in buttons {
|
|
||||||
if self.context_menu.is_some() {
|
|
||||||
column = column.push(button)
|
|
||||||
} else {
|
|
||||||
column = column.push(
|
|
||||||
mouse_area::MouseArea::new(button).on_right_press_no_capture(
|
|
||||||
move |_point_opt| Message::RightClick(Some(i)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let column: Element<Message> =
|
|
||||||
if item.metadata.is_dir() && item.location_opt.is_some() {
|
|
||||||
self.dnd_dest(&item.location_opt.clone().unwrap(), column)
|
|
||||||
} else {
|
|
||||||
column.into()
|
|
||||||
};
|
|
||||||
|
|
||||||
if item.selected {
|
|
||||||
dnd_items.push((i, (row, col), item));
|
|
||||||
drag_w_i = drag_w_i.min(col);
|
|
||||||
drag_n_i = drag_n_i.min(row);
|
|
||||||
drag_e_i = drag_e_i.max(col);
|
|
||||||
drag_s_i = drag_s_i.max(row);
|
|
||||||
}
|
|
||||||
let mouse_area = crate::mouse_area::MouseArea::new(column)
|
|
||||||
.on_press(move |_| Message::Click(Some(i)))
|
|
||||||
.on_double_click(move |_| Message::DoubleClick(Some(i)))
|
|
||||||
.on_release(move |_| Message::ClickRelease(Some(i)))
|
|
||||||
.on_middle_press(move |_| Message::MiddleClick(i))
|
|
||||||
.on_enter(move || Message::HighlightActivate(i))
|
|
||||||
.on_exit(move || Message::HighlightDeactivate(i));
|
|
||||||
|
|
||||||
//TODO: error if the row or col is already set?
|
//TODO: error if the row or col is already set?
|
||||||
while grid_elements.len() <= row {
|
while grid_elements.len() <= row {
|
||||||
grid_elements.push(Vec::new());
|
grid_elements.push(Vec::new());
|
||||||
}
|
}
|
||||||
grid_elements[row].push(mouse_area);
|
|
||||||
|
// Only build elements if visible (for performance)
|
||||||
|
if item_rect.intersects(&visible_rect) {
|
||||||
|
//TODO: one focus group per grid item (needs custom widget)
|
||||||
|
let buttons: Vec<Element<Message>> = vec![
|
||||||
|
widget::button::custom(
|
||||||
|
widget::icon::icon(item.icon_handle_grid.clone())
|
||||||
|
.content_fit(ContentFit::Contain)
|
||||||
|
.size(icon_sizes.grid())
|
||||||
|
.width(Length::Shrink),
|
||||||
|
)
|
||||||
|
.padding(space_xxxs)
|
||||||
|
.class(button_style(
|
||||||
|
item.selected,
|
||||||
|
item.highlighted,
|
||||||
|
item.cut,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
))
|
||||||
|
.into(),
|
||||||
|
widget::tooltip(
|
||||||
|
widget::button::custom(widget::text::body(&item.display_name))
|
||||||
|
.id(item.button_id.clone())
|
||||||
|
.padding([0, space_xxxs])
|
||||||
|
.class(button_style(
|
||||||
|
item.selected,
|
||||||
|
item.highlighted,
|
||||||
|
item.cut,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
matches!(self.mode, Mode::Desktop),
|
||||||
|
)),
|
||||||
|
widget::text::body(&item.name),
|
||||||
|
widget::tooltip::Position::Bottom,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut column = widget::column::with_capacity(buttons.len())
|
||||||
|
.align_x(Alignment::Center)
|
||||||
|
.height(Length::Fixed(item_height as f32))
|
||||||
|
.width(Length::Fixed(item_width as f32));
|
||||||
|
for button in buttons {
|
||||||
|
if self.context_menu.is_some() {
|
||||||
|
column = column.push(button)
|
||||||
|
} else {
|
||||||
|
column = column.push(
|
||||||
|
mouse_area::MouseArea::new(button).on_right_press_no_capture(
|
||||||
|
move |_point_opt| Message::RightClick(Some(i)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let column: Element<Message> =
|
||||||
|
if item.metadata.is_dir() && item.location_opt.is_some() {
|
||||||
|
self.dnd_dest(&item.location_opt.clone().unwrap(), column)
|
||||||
|
} else {
|
||||||
|
column.into()
|
||||||
|
};
|
||||||
|
|
||||||
|
if item.selected {
|
||||||
|
dnd_items.push((i, (row, col), item));
|
||||||
|
drag_w_i = drag_w_i.min(col);
|
||||||
|
drag_n_i = drag_n_i.min(row);
|
||||||
|
drag_e_i = drag_e_i.max(col);
|
||||||
|
drag_s_i = drag_s_i.max(row);
|
||||||
|
}
|
||||||
|
let mouse_area = crate::mouse_area::MouseArea::new(column)
|
||||||
|
.on_press(move |_| Message::Click(Some(i)))
|
||||||
|
.on_double_click(move |_| Message::DoubleClick(Some(i)))
|
||||||
|
.on_release(move |_| Message::ClickRelease(Some(i)))
|
||||||
|
.on_middle_press(move |_| Message::MiddleClick(i))
|
||||||
|
.on_enter(move || Message::HighlightActivate(i))
|
||||||
|
.on_exit(move || Message::HighlightDeactivate(i));
|
||||||
|
grid_elements[row].push(Element::from(mouse_area));
|
||||||
|
} else {
|
||||||
|
// Add a spacer if the row is empty, so scroll works
|
||||||
|
if grid_elements[row].is_empty() {
|
||||||
|
grid_elements[row].push(Element::from(
|
||||||
|
widget::column()
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fixed(item_height as f32)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
if matches!(self.mode, Mode::Desktop) {
|
if matches!(self.mode, Mode::Desktop) {
|
||||||
|
|
@ -5028,9 +5051,18 @@ impl Tab {
|
||||||
|
|
||||||
let rule_padding = theme::active().cosmic().corner_radii.radius_xs[0] as u16;
|
let rule_padding = theme::active().cosmic().corner_radii.radius_xs[0] as u16;
|
||||||
|
|
||||||
let items = self.column_sort();
|
//TODO: move to function
|
||||||
|
let visible_rect = {
|
||||||
|
let point = match self.scroll_opt {
|
||||||
|
Some(offset) => Point::new(0.0, offset.y),
|
||||||
|
None => Point::new(0.0, 0.0),
|
||||||
|
};
|
||||||
|
let size = self.size_opt.get().unwrap_or_else(|| Size::new(0.0, 0.0));
|
||||||
|
Rectangle::new(point, size)
|
||||||
|
};
|
||||||
|
|
||||||
let mut drag_items = Vec::new();
|
let mut drag_items = Vec::new();
|
||||||
if let Some(items) = items {
|
if let Some(items) = self.column_sort() {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let mut hidden = 0;
|
let mut hidden = 0;
|
||||||
for (i, item) in items {
|
for (i, item) in items {
|
||||||
|
|
@ -5041,10 +5073,11 @@ impl Tab {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
item.pos_opt.set(Some((count, 0)));
|
item.pos_opt.set(Some((count, 0)));
|
||||||
item.rect_opt.set(Some(Rectangle::new(
|
let item_rect = Rectangle::new(
|
||||||
Point::new(space_m as f32, y),
|
Point::new(space_m as f32, y),
|
||||||
Size::new(size.width - (2 * space_m) as f32, row_height as f32),
|
Size::new(size.width - (2 * space_m) as f32, row_height as f32),
|
||||||
)));
|
);
|
||||||
|
item.rect_opt.set(Some(item_rect));
|
||||||
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
children.push(
|
children.push(
|
||||||
|
|
@ -5055,190 +5088,86 @@ impl Tab {
|
||||||
y += 1.0;
|
y += 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modified_text = match &item.metadata {
|
// Only build elements if visible (for performance)
|
||||||
ItemMetadata::Path { metadata, .. } => match metadata.modified() {
|
let button_row = if item_rect.intersects(&visible_rect) {
|
||||||
Ok(time) => self.format_time(time).to_string(),
|
let modified_text = match &item.metadata {
|
||||||
Err(_) => String::new(),
|
ItemMetadata::Path { metadata, .. } => match metadata.modified() {
|
||||||
},
|
Ok(time) => self.format_time(time).to_string(),
|
||||||
ItemMetadata::Trash { entry, .. } => FormatTime::from_secs(
|
Err(_) => String::new(),
|
||||||
entry.time_deleted,
|
},
|
||||||
&self.date_time_formatter,
|
ItemMetadata::Trash { entry, .. } => FormatTime::from_secs(
|
||||||
&self.time_formatter,
|
entry.time_deleted,
|
||||||
)
|
&self.date_time_formatter,
|
||||||
.map(|t| t.to_string())
|
&self.time_formatter,
|
||||||
.unwrap_or_default(),
|
)
|
||||||
#[cfg(feature = "gvfs")]
|
.map(|t| t.to_string())
|
||||||
ItemMetadata::GvfsPath { .. } => match item.metadata.modified() {
|
.unwrap_or_default(),
|
||||||
Some(mtime) => self.format_time(mtime).to_string(),
|
#[cfg(feature = "gvfs")]
|
||||||
None => String::new(),
|
ItemMetadata::GvfsPath { .. } => match item.metadata.modified() {
|
||||||
},
|
Some(mtime) => self.format_time(mtime).to_string(),
|
||||||
_ => String::new(),
|
None => String::new(),
|
||||||
};
|
},
|
||||||
|
_ => String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let size_text = match &item.metadata {
|
let size_text = match &item.metadata {
|
||||||
ItemMetadata::Path {
|
ItemMetadata::Path {
|
||||||
metadata,
|
metadata,
|
||||||
children_opt,
|
children_opt,
|
||||||
} => {
|
} => {
|
||||||
if metadata.is_dir() {
|
if metadata.is_dir() {
|
||||||
//TODO: translate
|
//TODO: translate
|
||||||
if let Some(children) = children_opt {
|
if let Some(children) = children_opt {
|
||||||
if *children == 1 {
|
if *children == 1 {
|
||||||
format!("{} item", children)
|
format!("{} item", children)
|
||||||
|
} else {
|
||||||
|
format!("{} items", children)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
format!("{} items", children)
|
String::new()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
format_size(metadata.len())
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
format_size(metadata.len())
|
|
||||||
}
|
}
|
||||||
}
|
ItemMetadata::Trash { metadata, .. } => match metadata.size {
|
||||||
ItemMetadata::Trash { metadata, .. } => match metadata.size {
|
trash::TrashItemSize::Entries(entries) => {
|
||||||
trash::TrashItemSize::Entries(entries) => {
|
//TODO: translate
|
||||||
|
if entries == 1 {
|
||||||
|
format!("{} item", entries)
|
||||||
|
} else {
|
||||||
|
format!("{} items", entries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trash::TrashItemSize::Bytes(bytes) => format_size(bytes),
|
||||||
|
},
|
||||||
|
ItemMetadata::SimpleDir { entries } => {
|
||||||
//TODO: translate
|
//TODO: translate
|
||||||
if entries == 1 {
|
if *entries == 1 {
|
||||||
format!("{} item", entries)
|
format!("{} item", entries)
|
||||||
} else {
|
} else {
|
||||||
format!("{} items", entries)
|
format!("{} items", entries)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trash::TrashItemSize::Bytes(bytes) => format_size(bytes),
|
ItemMetadata::SimpleFile { size } => format_size(*size),
|
||||||
},
|
#[cfg(feature = "gvfs")]
|
||||||
ItemMetadata::SimpleDir { entries } => {
|
ItemMetadata::GvfsPath {
|
||||||
//TODO: translate
|
size_opt,
|
||||||
if *entries == 1 {
|
children_opt,
|
||||||
format!("{} item", entries)
|
..
|
||||||
} else {
|
} => match children_opt {
|
||||||
format!("{} items", entries)
|
Some(child_count) => {
|
||||||
}
|
if *child_count == 1 {
|
||||||
}
|
format!("{} item", child_count)
|
||||||
ItemMetadata::SimpleFile { size } => format_size(*size),
|
} else {
|
||||||
#[cfg(feature = "gvfs")]
|
format!("{} items", child_count)
|
||||||
ItemMetadata::GvfsPath {
|
}
|
||||||
size_opt,
|
|
||||||
children_opt,
|
|
||||||
..
|
|
||||||
} => match children_opt {
|
|
||||||
Some(child_count) => {
|
|
||||||
if *child_count == 1 {
|
|
||||||
format!("{} item", child_count)
|
|
||||||
} else {
|
|
||||||
format!("{} items", child_count)
|
|
||||||
}
|
}
|
||||||
}
|
None => format_size(size_opt.unwrap_or_default()),
|
||||||
None => format_size(size_opt.unwrap_or_default()),
|
},
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let row = if condensed {
|
|
||||||
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::body(item.display_name.clone()).into(),
|
|
||||||
//TODO: translate?
|
|
||||||
widget::text::caption(format!("{} - {}", modified_text, size_text))
|
|
||||||
.into(),
|
|
||||||
])
|
|
||||||
.into(),
|
|
||||||
])
|
|
||||||
.height(Length::Fixed(row_height as f32))
|
|
||||||
.align_y(Alignment::Center)
|
|
||||||
.spacing(space_xxs)
|
|
||||||
} else if is_search {
|
|
||||||
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::body(item.display_name.clone()).into(),
|
|
||||||
widget::text::caption(match item.path_opt() {
|
|
||||||
Some(path) => path.display().to_string(),
|
|
||||||
None => String::new(),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
])
|
|
||||||
.width(Length::Fill)
|
|
||||||
.into(),
|
|
||||||
widget::text::body(modified_text.clone())
|
|
||||||
.width(Length::Fixed(modified_width))
|
|
||||||
.into(),
|
|
||||||
widget::text::body(size_text.clone())
|
|
||||||
.width(Length::Fixed(size_width))
|
|
||||||
.into(),
|
|
||||||
])
|
|
||||||
.height(Length::Fixed(row_height as f32))
|
|
||||||
.align_y(Alignment::Center)
|
|
||||||
.spacing(space_xxs)
|
|
||||||
} else {
|
|
||||||
widget::row::with_children(vec![
|
|
||||||
widget::icon::icon(item.icon_handle_list.clone())
|
|
||||||
.content_fit(ContentFit::Contain)
|
|
||||||
.size(icon_size)
|
|
||||||
.into(),
|
|
||||||
widget::text::body(item.display_name.clone())
|
|
||||||
.width(Length::Fill)
|
|
||||||
.into(),
|
|
||||||
widget::text::body(modified_text.clone())
|
|
||||||
.width(Length::Fixed(modified_width))
|
|
||||||
.into(),
|
|
||||||
widget::text::body(size_text.clone())
|
|
||||||
.width(Length::Fixed(size_width))
|
|
||||||
.into(),
|
|
||||||
])
|
|
||||||
.height(Length::Fixed(row_height as f32))
|
|
||||||
.align_y(Alignment::Center)
|
|
||||||
.spacing(space_xxs)
|
|
||||||
};
|
|
||||||
|
|
||||||
let button = |row| {
|
|
||||||
let mouse_area = crate::mouse_area::MouseArea::new(
|
|
||||||
widget::button::custom(row)
|
|
||||||
.width(Length::Fill)
|
|
||||||
.id(item.button_id.clone())
|
|
||||||
.padding([0, space_xxs])
|
|
||||||
.class(button_style(
|
|
||||||
item.selected,
|
|
||||||
item.highlighted,
|
|
||||||
item.cut,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
.on_press(move |_| Message::Click(Some(i)))
|
|
||||||
.on_double_click(move |_| Message::DoubleClick(Some(i)))
|
|
||||||
.on_release(move |_| Message::ClickRelease(Some(i)))
|
|
||||||
.on_middle_press(move |_| Message::MiddleClick(i))
|
|
||||||
.on_enter(move || Message::HighlightActivate(i))
|
|
||||||
.on_exit(move || Message::HighlightDeactivate(i));
|
|
||||||
|
|
||||||
if self.context_menu.is_some() {
|
|
||||||
mouse_area
|
|
||||||
} else {
|
|
||||||
mouse_area.on_right_press_no_capture(move |_point_opt| {
|
|
||||||
Message::RightClick(Some(i))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let button_row = button(row.into());
|
|
||||||
let button_row: Element<_> =
|
|
||||||
if item.metadata.is_dir() && item.location_opt.is_some() {
|
|
||||||
self.dnd_dest(item.location_opt.as_ref().unwrap(), button_row)
|
|
||||||
} else {
|
|
||||||
button_row.into()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if item.selected || !drag_items.is_empty() {
|
let row = if condensed {
|
||||||
let dnd_row = if !item.selected {
|
|
||||||
Element::from(Space::with_height(Length::Fixed(row_height as f32)))
|
|
||||||
} else if condensed {
|
|
||||||
widget::row::with_children(vec![
|
widget::row::with_children(vec![
|
||||||
widget::icon::icon(item.icon_handle_list_condensed.clone())
|
widget::icon::icon(item.icon_handle_list_condensed.clone())
|
||||||
.content_fit(ContentFit::Contain)
|
.content_fit(ContentFit::Contain)
|
||||||
|
|
@ -5247,14 +5176,14 @@ impl Tab {
|
||||||
widget::column::with_children(vec![
|
widget::column::with_children(vec![
|
||||||
widget::text::body(item.display_name.clone()).into(),
|
widget::text::body(item.display_name.clone()).into(),
|
||||||
//TODO: translate?
|
//TODO: translate?
|
||||||
widget::text::body(format!("{} - {}", modified_text, size_text))
|
widget::text::caption(format!("{} - {}", modified_text, size_text))
|
||||||
.into(),
|
.into(),
|
||||||
])
|
])
|
||||||
.into(),
|
.into(),
|
||||||
])
|
])
|
||||||
|
.height(Length::Fixed(row_height as f32))
|
||||||
.align_y(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.spacing(space_xxs)
|
.spacing(space_xxs)
|
||||||
.into()
|
|
||||||
} else if is_search {
|
} else if is_search {
|
||||||
widget::row::with_children(vec![
|
widget::row::with_children(vec![
|
||||||
widget::icon::icon(item.icon_handle_list_condensed.clone())
|
widget::icon::icon(item.icon_handle_list_condensed.clone())
|
||||||
|
|
@ -5278,9 +5207,9 @@ impl Tab {
|
||||||
.width(Length::Fixed(size_width))
|
.width(Length::Fixed(size_width))
|
||||||
.into(),
|
.into(),
|
||||||
])
|
])
|
||||||
|
.height(Length::Fixed(row_height as f32))
|
||||||
.align_y(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.spacing(space_xxs)
|
.spacing(space_xxs)
|
||||||
.into()
|
|
||||||
} else {
|
} 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())
|
||||||
|
|
@ -5290,27 +5219,144 @@ impl Tab {
|
||||||
widget::text::body(item.display_name.clone())
|
widget::text::body(item.display_name.clone())
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.into(),
|
.into(),
|
||||||
widget::text(modified_text)
|
widget::text::body(modified_text.clone())
|
||||||
.width(Length::Fixed(modified_width))
|
.width(Length::Fixed(modified_width))
|
||||||
.into(),
|
.into(),
|
||||||
widget::text::body(size_text)
|
widget::text::body(size_text.clone())
|
||||||
.width(Length::Fixed(size_width))
|
.width(Length::Fixed(size_width))
|
||||||
.into(),
|
.into(),
|
||||||
])
|
])
|
||||||
|
.height(Length::Fixed(row_height as f32))
|
||||||
.align_y(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.spacing(space_xxs)
|
.spacing(space_xxs)
|
||||||
.into()
|
|
||||||
};
|
};
|
||||||
if item.selected {
|
|
||||||
drag_items.push(
|
let button = |row| {
|
||||||
widget::container(button(dnd_row))
|
let mouse_area = crate::mouse_area::MouseArea::new(
|
||||||
.width(Length::Shrink)
|
widget::button::custom(row)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.id(item.button_id.clone())
|
||||||
|
.padding([0, space_xxs])
|
||||||
|
.class(button_style(
|
||||||
|
item.selected,
|
||||||
|
item.highlighted,
|
||||||
|
item.cut,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.on_press(move |_| Message::Click(Some(i)))
|
||||||
|
.on_double_click(move |_| Message::DoubleClick(Some(i)))
|
||||||
|
.on_release(move |_| Message::ClickRelease(Some(i)))
|
||||||
|
.on_middle_press(move |_| Message::MiddleClick(i))
|
||||||
|
.on_enter(move || Message::HighlightActivate(i))
|
||||||
|
.on_exit(move || Message::HighlightDeactivate(i));
|
||||||
|
|
||||||
|
if self.context_menu.is_some() {
|
||||||
|
mouse_area
|
||||||
|
} else {
|
||||||
|
mouse_area.on_right_press_no_capture(move |_point_opt| {
|
||||||
|
Message::RightClick(Some(i))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let button_row = button(row.into());
|
||||||
|
let button_row: Element<_> =
|
||||||
|
if item.metadata.is_dir() && item.location_opt.is_some() {
|
||||||
|
self.dnd_dest(item.location_opt.as_ref().unwrap(), button_row)
|
||||||
|
} else {
|
||||||
|
button_row.into()
|
||||||
|
};
|
||||||
|
|
||||||
|
if item.selected || !drag_items.is_empty() {
|
||||||
|
let dnd_row = if !item.selected {
|
||||||
|
Element::from(Space::with_height(Length::Fixed(row_height as f32)))
|
||||||
|
} else if condensed {
|
||||||
|
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::body(item.display_name.clone()).into(),
|
||||||
|
//TODO: translate?
|
||||||
|
widget::text::body(format!(
|
||||||
|
"{} - {}",
|
||||||
|
modified_text, size_text
|
||||||
|
))
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
.into(),
|
.into(),
|
||||||
);
|
])
|
||||||
} else {
|
.align_y(Alignment::Center)
|
||||||
drag_items.push(dnd_row);
|
.spacing(space_xxs)
|
||||||
|
.into()
|
||||||
|
} else if is_search {
|
||||||
|
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::body(item.display_name.clone()).into(),
|
||||||
|
widget::text::caption(match item.path_opt() {
|
||||||
|
Some(path) => path.display().to_string(),
|
||||||
|
None => String::new(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
|
.width(Length::Fill)
|
||||||
|
.into(),
|
||||||
|
widget::text::body(modified_text.clone())
|
||||||
|
.width(Length::Fixed(modified_width))
|
||||||
|
.into(),
|
||||||
|
widget::text::body(size_text.clone())
|
||||||
|
.width(Length::Fixed(size_width))
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
|
.align_y(Alignment::Center)
|
||||||
|
.spacing(space_xxs)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
widget::row::with_children(vec![
|
||||||
|
widget::icon::icon(item.icon_handle_list.clone())
|
||||||
|
.content_fit(ContentFit::Contain)
|
||||||
|
.size(icon_size)
|
||||||
|
.into(),
|
||||||
|
widget::text::body(item.display_name.clone())
|
||||||
|
.width(Length::Fill)
|
||||||
|
.into(),
|
||||||
|
widget::text(modified_text)
|
||||||
|
.width(Length::Fixed(modified_width))
|
||||||
|
.into(),
|
||||||
|
widget::text::body(size_text)
|
||||||
|
.width(Length::Fixed(size_width))
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
|
.align_y(Alignment::Center)
|
||||||
|
.spacing(space_xxs)
|
||||||
|
.into()
|
||||||
|
};
|
||||||
|
if item.selected {
|
||||||
|
drag_items.push(
|
||||||
|
widget::container(button(dnd_row))
|
||||||
|
.width(Length::Shrink)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
drag_items.push(dnd_row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
button_row
|
||||||
|
} else {
|
||||||
|
widget::column()
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fixed(row_height as f32))
|
||||||
|
.into()
|
||||||
|
};
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
y += row_height as f32;
|
y += row_height as f32;
|
||||||
|
|
@ -5557,12 +5603,6 @@ impl Tab {
|
||||||
Rectangle::new(point, size)
|
Rectangle::new(point, size)
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: HACK to ensure positions are up to date since subscription runs before view
|
|
||||||
match self.config.view {
|
|
||||||
View::Grid => _ = self.grid_view(),
|
|
||||||
View::List => _ = self.list_view(),
|
|
||||||
};
|
|
||||||
|
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
if item.thumbnail_opt.is_some() {
|
if item.thumbnail_opt.is_some() {
|
||||||
// Skip items that already have a mime type and thumbnail
|
// Skip items that already have a mime type and thumbnail
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue