Introduce `on_click` handler in `PaneGrid`

This commit is contained in:
Héctor Ramón Jiménez 2020-11-10 01:48:11 +01:00
parent 5681c83d3c
commit 8008ea5286
3 changed files with 42 additions and 14 deletions

View File

@ -6,4 +6,4 @@ edition = "2018"
publish = false publish = false
[dependencies] [dependencies]
iced = { path = "../.." } iced = { path = "../..", features = ["debug"] }

View File

@ -19,6 +19,7 @@ enum Message {
Split(pane_grid::Axis, pane_grid::Pane), Split(pane_grid::Axis, pane_grid::Pane),
SplitFocused(pane_grid::Axis), SplitFocused(pane_grid::Axis),
FocusAdjacent(pane_grid::Direction), FocusAdjacent(pane_grid::Direction),
Clicked(pane_grid::Pane),
Dragged(pane_grid::DragEvent), Dragged(pane_grid::DragEvent),
Resized(pane_grid::ResizeEvent), Resized(pane_grid::ResizeEvent),
Close(pane_grid::Pane), Close(pane_grid::Pane),
@ -45,22 +46,30 @@ impl Sandbox for Example {
fn update(&mut self, message: Message) { fn update(&mut self, message: Message) {
match message { match message {
Message::Split(axis, pane) => { Message::Split(axis, pane) => {
let _ = self.panes.split( let result = self.panes.split(
axis, axis,
&pane, &pane,
Content::new(self.panes_created), Content::new(self.panes_created),
); );
if let Some((pane, _)) = result {
self.focus = Some(pane);
}
self.panes_created += 1; self.panes_created += 1;
} }
Message::SplitFocused(axis) => { Message::SplitFocused(axis) => {
if let Some(pane) = self.focus { if let Some(pane) = self.focus {
let _ = self.panes.split( let result = self.panes.split(
axis, axis,
&pane, &pane,
Content::new(self.panes_created), Content::new(self.panes_created),
); );
if let Some((pane, _)) = result {
self.focus = Some(pane);
}
self.panes_created += 1; self.panes_created += 1;
} }
} }
@ -73,6 +82,9 @@ impl Sandbox for Example {
} }
} }
} }
Message::Clicked(pane) => {
self.focus = Some(pane);
}
Message::Resized(pane_grid::ResizeEvent { split, ratio }) => { Message::Resized(pane_grid::ResizeEvent { split, ratio }) => {
self.panes.resize(&split, ratio); self.panes.resize(&split, ratio);
} }
@ -113,6 +125,7 @@ impl Sandbox for Example {
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.spacing(10) .spacing(10)
.on_click(Message::Clicked)
.on_drag(Message::Dragged) .on_drag(Message::Dragged)
.on_resize(10, Message::Resized); .on_resize(10, Message::Resized);

View File

@ -92,6 +92,7 @@ pub struct PaneGrid<'a, Message, Renderer: self::Renderer> {
width: Length, width: Length,
height: Length, height: Length,
spacing: u16, spacing: u16,
on_click: Option<Box<dyn Fn(Pane) -> Message + 'a>>,
on_drag: Option<Box<dyn Fn(DragEvent) -> Message + 'a>>, on_drag: Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
on_resize: Option<(u16, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>, on_resize: Option<(u16, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,
} }
@ -126,6 +127,7 @@ where
width: Length::Fill, width: Length::Fill,
height: Length::Fill, height: Length::Fill,
spacing: 0, spacing: 0,
on_click: None,
on_drag: None, on_drag: None,
on_resize: None, on_resize: None,
} }
@ -155,6 +157,19 @@ where
self self
} }
/// Sets the message that will be produced when a [`Pane`] of the
/// [`PaneGrid`] is clicked.
///
/// [`Pane`]: struct.Pane.html
/// [`PaneGrid`]: struct.PaneGrid.html
pub fn on_click<F>(mut self, f: F) -> Self
where
F: 'a + Fn(Pane) -> Message,
{
self.on_click = Some(Box::new(f));
self
}
/// Enables the drag and drop interactions of the [`PaneGrid`], which will /// Enables the drag and drop interactions of the [`PaneGrid`], which will
/// use the provided function to produce messages. /// use the provided function to produce messages.
/// ///
@ -203,21 +218,21 @@ where
); );
if let Some(((pane, content), layout)) = clicked_region.next() { if let Some(((pane, content), layout)) = clicked_region.next() {
match &self.on_drag { if let Some(on_click) = &self.on_click {
Some(on_drag) => { messages.push(on_click(*pane));
if content.can_be_picked_at(layout, cursor_position) { }
let pane_position = layout.position();
let origin = cursor_position if let Some(on_drag) = &self.on_drag {
- Vector::new(pane_position.x, pane_position.y); if content.can_be_picked_at(layout, cursor_position) {
let pane_position = layout.position();
self.state.pick_pane(pane, origin); let origin = cursor_position
- Vector::new(pane_position.x, pane_position.y);
messages self.state.pick_pane(pane, origin);
.push(on_drag(DragEvent::Picked { pane: *pane }));
} messages.push(on_drag(DragEvent::Picked { pane: *pane }));
} }
None => {}
} }
} }
} }