Improve PaneGrid API by introducing DragEvent
This commit is contained in:
parent
2d8d420949
commit
c2ced4cd59
1 changed files with 43 additions and 33 deletions
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue