fix: drag selection
Fixes bug where drag selection only worked if the pointer passed through an item.
This commit is contained in:
parent
fe71aca0e5
commit
c0b8a8c60a
2 changed files with 28 additions and 24 deletions
|
|
@ -214,8 +214,9 @@ impl<'a, Message, F> OnAutoScroll<'a, Message> for F where F: Fn(Option<f32>) ->
|
|||
pub trait OnMouseButton<'a, Message>: Fn(Option<Point>) -> Message + 'a {}
|
||||
impl<'a, Message, F> OnMouseButton<'a, Message> for F where F: Fn(Option<Point>) -> Message + 'a {}
|
||||
|
||||
pub trait OnDrag<'a, Message>: Fn(Option<Rectangle>) -> Message + 'a {}
|
||||
impl<'a, Message, F> OnDrag<'a, Message> for F where F: Fn(Option<Rectangle>) -> Message + 'a {}
|
||||
pub trait OnDrag<'a, Message>: Fn(Option<Rectangle>) -> Option<Message> + 'a {}
|
||||
impl<'a, Message, F> OnDrag<'a, Message> for F where F: Fn(Option<Rectangle>) -> Option<Message> + 'a
|
||||
{}
|
||||
|
||||
pub trait OnResize<'a, Message>: Fn(Rectangle) -> Message + 'a {}
|
||||
impl<'a, Message, F> OnResize<'a, Message> for F where F: Fn(Rectangle) -> Message + 'a {}
|
||||
|
|
@ -798,12 +799,13 @@ fn update<Message: Clone>(
|
|||
}
|
||||
|
||||
if let Some((message, drag_rect)) = widget.on_drag.as_ref().zip(state.drag_rect(cursor)) {
|
||||
shell.publish(message(drag_rect.intersection(&layout_bounds).map(
|
||||
|mut rect| {
|
||||
rect.x -= layout_bounds.x;
|
||||
rect.y -= layout_bounds.y;
|
||||
rect
|
||||
},
|
||||
)));
|
||||
let rect_opt = drag_rect.intersection(&layout_bounds).map(|mut rect| {
|
||||
rect.x -= layout_bounds.x;
|
||||
rect.y -= layout_bounds.y;
|
||||
rect
|
||||
});
|
||||
if let Some(message) = message(rect_opt) {
|
||||
shell.publish(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
src/tab.rs
32
src/tab.rs
|
|
@ -2834,7 +2834,6 @@ pub struct Tab {
|
|||
search_context: Option<SearchContext>,
|
||||
date_time_formatter: DateTimeFormatter<fieldsets::YMDT>,
|
||||
time_formatter: DateTimeFormatter<fieldsets::T>,
|
||||
watch_drag: bool,
|
||||
window_id: Option<window::Id>,
|
||||
large_image_manager: LargeImageManager,
|
||||
}
|
||||
|
|
@ -2979,7 +2978,6 @@ impl Tab {
|
|||
search_context: None,
|
||||
date_time_formatter: date_time_formatter(config.military_time),
|
||||
time_formatter: time_formatter(config.military_time),
|
||||
watch_drag: true,
|
||||
window_id,
|
||||
large_image_manager: LargeImageManager::new(),
|
||||
}
|
||||
|
|
@ -3586,7 +3584,6 @@ impl Tab {
|
|||
}
|
||||
Message::DragEnd => {
|
||||
self.clicked = None;
|
||||
self.watch_drag = true;
|
||||
}
|
||||
Message::DoubleClick(click_i_opt) => {
|
||||
if let Some(clicked_item) = self
|
||||
|
|
@ -3826,7 +3823,6 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
Message::Drag(rect_opt) => {
|
||||
self.watch_drag = false;
|
||||
if let Some(rect) = rect_opt {
|
||||
if self.mode.multiple() {
|
||||
self.select_rect(rect, mod_ctrl, mod_shift);
|
||||
|
|
@ -4464,13 +4460,11 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
Message::HighlightDeactivate(i) => {
|
||||
self.watch_drag = true;
|
||||
if let Some(item) = self.items_opt.as_mut().and_then(|f| f.get_mut(i)) {
|
||||
item.highlighted = false;
|
||||
}
|
||||
}
|
||||
Message::HighlightActivate(i) => {
|
||||
self.watch_drag = true;
|
||||
if let Some(item) = self.items_opt.as_mut().and_then(|f| f.get_mut(i)) {
|
||||
item.highlighted = true;
|
||||
}
|
||||
|
|
@ -4496,7 +4490,6 @@ impl Tab {
|
|||
}
|
||||
Message::Scroll(viewport) => {
|
||||
self.scroll_opt = Some(viewport.absolute_offset());
|
||||
self.watch_drag = true;
|
||||
}
|
||||
Message::ScrollTab(scroll_speed) => {
|
||||
commands.push(Command::Iced(
|
||||
|
|
@ -6003,15 +5996,13 @@ impl Tab {
|
|||
Element::from(dnd_grid)
|
||||
});
|
||||
|
||||
let mut mouse_area = mouse_area::MouseArea::new(column.width(Length::Fill))
|
||||
let mouse_area = mouse_area::MouseArea::new(column.width(Length::Fill))
|
||||
.on_press(|_| Message::Click(None))
|
||||
.on_auto_scroll(Message::AutoScroll)
|
||||
.on_drag(move |rect_opt| self.on_drag(rect_opt))
|
||||
.on_drag_end(|_| Message::DragEnd)
|
||||
.show_drag_rect(self.mode.multiple())
|
||||
.on_release(|_| Message::ClickRelease(None));
|
||||
if self.watch_drag {
|
||||
mouse_area = mouse_area.on_drag(Message::Drag);
|
||||
}
|
||||
|
||||
(drag_list, mouse_area.into(), true)
|
||||
}
|
||||
|
|
@ -6395,16 +6386,14 @@ impl Tab {
|
|||
let drag_col = (!drag_items.is_empty())
|
||||
.then(|| Element::from(widget::column::with_children(drag_items)));
|
||||
|
||||
let mut mouse_area = mouse_area::MouseArea::new(column.padding([0, space_s]))
|
||||
let mouse_area = mouse_area::MouseArea::new(column.padding([0, space_s]))
|
||||
.with_id(Id::new("list-view"))
|
||||
.on_press(|_| Message::Click(None))
|
||||
.on_auto_scroll(Message::AutoScroll)
|
||||
.on_drag(move |rect_opt| self.on_drag(rect_opt))
|
||||
.on_drag_end(|_| Message::DragEnd)
|
||||
.show_drag_rect(self.mode.multiple())
|
||||
.on_release(|_| Message::ClickRelease(None));
|
||||
if self.watch_drag {
|
||||
mouse_area = mouse_area.on_drag(Message::Drag);
|
||||
}
|
||||
|
||||
(drag_col, mouse_area.into(), true)
|
||||
}
|
||||
|
|
@ -7397,6 +7386,19 @@ impl Tab {
|
|||
const fn format_time(&self, time: SystemTime) -> FormatTime<'_> {
|
||||
format_time(time, &self.date_time_formatter, &self.time_formatter)
|
||||
}
|
||||
|
||||
fn on_drag<'a>(&self, rect_opt: Option<Rectangle>) -> Option<Message> {
|
||||
let rect = rect_opt?;
|
||||
// We only want to publish a drag message if the overlapped items of the drag rect change,
|
||||
// otherwise a view rebuild is triggered on every drag event.
|
||||
let changed = self.items_opt.as_ref().is_some_and(|items| {
|
||||
items.iter().any(|item| {
|
||||
let overlaps = item.rect_opt.get().is_some_and(|r| r.intersects(&rect));
|
||||
overlaps != item.overlaps_drag_rect
|
||||
})
|
||||
});
|
||||
changed.then_some(Message::Drag(Some(rect)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn respond_to_scroll_direction(delta: ScrollDelta, modifiers: &Modifiers) -> Option<Message> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue