Improve PaneGrid API by introducing DragEvent

This commit is contained in:
Héctor Ramón Jiménez 2020-03-13 07:35:44 +01:00
parent 2d8d420949
commit c2ced4cd59

View file

@ -12,7 +12,7 @@ pub struct PaneGrid<'a, Message, Renderer> {
elements: Vec<(Pane, Element<'a, Message, Renderer>)>, elements: Vec<(Pane, Element<'a, Message, Renderer>)>,
width: Length, width: Length,
height: Length, height: Length,
on_drop: Option<Box<dyn Fn(Drop) -> Message>>, on_drag: Option<Box<dyn Fn(DragEvent) -> Message>>,
} }
impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
@ -49,7 +49,7 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
elements, elements,
width: Length::Fill, width: Length::Fill,
height: Length::Fill, height: Length::Fill,
on_drop: None, on_drag: None,
} }
} }
@ -69,16 +69,20 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
self self
} }
pub fn on_drop(mut self, f: impl Fn(Drop) -> Message + 'static) -> Self { pub fn on_drag(
self.on_drop = Some(Box::new(f)); mut self,
f: impl Fn(DragEvent) -> Message + 'static,
) -> Self {
self.on_drag = Some(Box::new(f));
self self
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Drop { pub enum DragEvent {
pub pane: Pane, Picked { pane: Pane },
pub target: Pane, Dropped { pane: Pane, target: Pane },
Canceled { pane: Pane },
} }
impl<'a, Message, Renderer> Widget<Message, Renderer> impl<'a, Message, Renderer> Widget<Message, Renderer>
@ -147,28 +151,38 @@ where
); );
if let Some(((pane, _), _)) = clicked_region.next() { if let Some(((pane, _), _)) = clicked_region.next() {
self.state.focused_pane = if self.on_drop.is_some() match &self.on_drag {
&& self.state.modifiers.alt Some(on_drag) if self.state.modifiers.alt => {
{ self.state.focused_pane = FocusedPane::Some {
FocusedPane::Some { pane: *pane,
pane: *pane, focus: Focus::Dragging,
focus: Focus::Dragging, };
messages.push(on_drag(DragEvent::Picked {
pane: *pane,
}));
} }
} else { _ => {
FocusedPane::Some { self.state.focused_pane = FocusedPane::Some {
pane: *pane, pane: *pane,
focus: Focus::Idle, focus: Focus::Idle,
};
} }
} }
} }
} }
ButtonState::Released => { ButtonState::Released => {
if let Some(on_drop) = &self.on_drop { if let FocusedPane::Some {
if let FocusedPane::Some { pane,
focus: Focus::Dragging,
} = self.state.focused_pane
{
self.state.focused_pane = FocusedPane::Some {
pane, pane,
focus: Focus::Dragging, focus: Focus::Idle,
} = self.state.focused_pane };
{
if let Some(on_drag) = &self.on_drag {
let mut dropped_region = self let mut dropped_region = self
.elements .elements
.iter() .iter()
@ -177,21 +191,17 @@ where
layout.bounds().contains(cursor_position) layout.bounds().contains(cursor_position)
}); });
if let Some(((target, _), _)) = let event = match dropped_region.next() {
dropped_region.next() Some(((target, _), _)) if pane != *target => {
{ DragEvent::Dropped {
if pane != *target {
messages.push(on_drop(Drop {
pane, pane,
target: *target, target: *target,
})); }
} }
} _ => DragEvent::Canceled { pane },
self.state.focused_pane = FocusedPane::Some {
pane,
focus: Focus::Idle,
}; };
messages.push(on_drag(event));
} }
} }
} }