Use widget::responsive for tab responsiveness, fixes #204

This commit is contained in:
Jeremy Soller 2024-05-31 09:51:34 -06:00
parent a51adf8b6a
commit aab8d310df
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
3 changed files with 28 additions and 38 deletions

View file

@ -14,7 +14,7 @@ use cosmic::{
window, Event, Length, Size,
},
theme,
widget::{self, segmented_button},
widget::{self, menu::KeyBind, segmented_button},
Application, ApplicationExt, Element,
};
use notify_debouncer_full::{
@ -31,6 +31,7 @@ use std::{
};
use crate::{
app::Action,
config::TabConfig,
fl, home_dir,
tab::{self, ItemMetadata, Location, Tab},
@ -224,6 +225,7 @@ struct App {
result_opt: Option<DialogResult>,
replace_dialog: bool,
tab: Tab,
key_binds: HashMap<KeyBind, Action>,
watcher_opt: Option<(Debouncer<RecommendedWatcher, FileIdMap>, HashSet<PathBuf>)>,
}
@ -375,6 +377,7 @@ impl Application for App {
result_opt: None,
replace_dialog: false,
tab,
key_binds: HashMap::new(),
watcher_opt: None,
};
@ -674,7 +677,7 @@ impl Application for App {
tab_column = tab_column.push(
//TODO: key binds for dialog
self.tab
.view(&HashMap::new())
.view(&self.key_binds)
.map(move |message| Message::TabMessage(message)),
);

View file

@ -30,7 +30,6 @@ pub struct MouseArea<'a, Message> {
on_press: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
on_drag_end: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
on_release: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
on_resize: Option<Box<dyn Fn(Size) -> Message + 'a>>,
on_right_press: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
on_right_press_no_capture: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
on_right_release: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
@ -79,12 +78,6 @@ impl<'a, Message> MouseArea<'a, Message> {
self
}
#[must_use]
pub fn on_resize(mut self, message: impl Fn(Size) -> Message + 'a) -> Self {
self.on_resize = Some(Box::new(message));
self
}
/// The message to emit on a right button press.
#[must_use]
pub fn on_right_press(mut self, message: impl Fn(Option<Point>) -> Message + 'a) -> Self {
@ -168,7 +161,6 @@ impl<'a, Message> MouseArea<'a, Message> {
/// Local state of the [`MouseArea`].
#[derive(Default)]
struct State {
last_size: Option<Size>,
// TODO: Support on_mouse_enter and on_mouse_exit
drag_initiated: Option<Point>,
@ -226,7 +218,6 @@ impl<'a, Message> MouseArea<'a, Message> {
on_double_click: None,
on_press: None,
on_release: None,
on_resize: None,
on_right_press: None,
on_right_press_no_capture: None,
on_right_release: None,
@ -436,14 +427,6 @@ fn update<Message: Clone>(
) -> event::Status {
let layout_bounds = layout.bounds();
if let Some(message) = widget.on_resize.as_ref() {
let size = layout_bounds.size();
if state.last_size != Some(size) {
shell.publish(message(size));
state.last_size = Some(size);
}
}
if state.drag_initiated.is_none() && !cursor.is_over(layout_bounds) {
return event::Status::Ignored;
}

View file

@ -461,7 +461,6 @@ pub enum Message {
Location(Location),
LocationUp,
Open,
Resize(Size),
RightClick(usize),
Scroll(Viewport),
SelectAll,
@ -704,7 +703,7 @@ pub struct Tab {
pub context_menu: Option<Point>,
pub dialog: Option<DialogKind>,
pub scroll_opt: Option<AbsoluteOffset>,
pub size_opt: Option<Size>,
pub size_opt: Cell<Option<Size>>,
pub edit_location: Option<Location>,
pub edit_location_id: widget::Id,
pub history_i: usize,
@ -728,7 +727,7 @@ impl Tab {
context_menu: None,
dialog: None,
scroll_opt: None,
size_opt: None,
size_opt: Cell::new(None),
edit_location: None,
edit_location_id: widget::Id::unique(),
history_i: 0,
@ -904,7 +903,7 @@ impl Tab {
Some(offset) => Point::new(0.0, offset.y),
None => Point::new(0.0, 0.0),
};
let size = self.size_opt.unwrap_or_else(|| Size::new(0.0, 0.0));
let size = self.size_opt.get().unwrap_or_else(|| Size::new(0.0, 0.0));
Rectangle::new(point, size)
};
@ -1347,9 +1346,6 @@ impl Tab {
}
}
}
Message::Resize(size) => {
self.size_opt = Some(size);
}
Message::RightClick(click_i) => {
*self.cached_selected.borrow_mut() = None;
if let Some(ref mut items) = self.items_opt {
@ -1791,7 +1787,7 @@ impl Tab {
let item_height =
(space_xxxs + icon_sizes.grid() + space_xxxs + text_height + space_xxxs) as usize;
let (width, height) = match self.size_opt {
let (width, height) = match self.size_opt.get() {
Some(size) => (
(size.width.floor() as usize)
.checked_sub(2 * (space_m as usize))
@ -2059,7 +2055,7 @@ impl Tab {
..
} = self.config;
let size = self.size_opt.unwrap_or_else(|| Size::new(0.0, 0.0));
let size = self.size_opt.get().unwrap_or_else(|| Size::new(0.0, 0.0));
//TODO: allow resizing?
let name_width = 300.0;
let modified_width = 200.0;
@ -2364,7 +2360,14 @@ impl Tab {
)
}
pub fn view(&self, key_binds: &HashMap<KeyBind, Action>) -> Element<Message> {
pub fn view_responsive(
&self,
key_binds: &HashMap<KeyBind, Action>,
size: Size,
) -> Element<Message> {
// Update cached size
self.size_opt.set(Some(size));
let location_view = self.location_view();
let (drag_list, mut item_view, can_scroll) = match self.config.view {
View::Grid => self.grid_view(),
@ -2428,14 +2431,11 @@ impl Tab {
tab_column = tab_column.push(location_view);
if can_scroll {
tab_column = tab_column.push(
mouse_area::MouseArea::new(
widget::scrollable(popover)
.id(self.scrollable_id.clone())
.on_scroll(Message::Scroll)
.width(Length::Fill)
.height(Length::Fill),
)
.on_resize(Message::Resize),
widget::scrollable(popover)
.id(self.scrollable_id.clone())
.on_scroll(Message::Scroll)
.width(Length::Fill)
.height(Length::Fill),
);
} else {
tab_column = tab_column.push(popover);
@ -2505,6 +2505,10 @@ impl Tab {
dnd_dest.into()
}
pub fn view<'a>(&'a self, key_binds: &'a HashMap<KeyBind, Action>) -> Element<Message> {
widget::responsive(|size| self.view_responsive(key_binds, size)).into()
}
pub fn subscription(&self) -> Subscription<Message> {
if let Some(items) = &self.items_opt {
//TODO: how many thumbnail loads should be in flight at once?
@ -2517,7 +2521,7 @@ impl Tab {
Some(offset) => Point::new(0.0, offset.y),
None => Point::new(0.0, 0.0),
};
let size = self.size_opt.unwrap_or_else(|| Size::new(0.0, 0.0));
let size = self.size_opt.get().unwrap_or_else(|| Size::new(0.0, 0.0));
Rectangle::new(point, size)
};