diff options
Diffstat (limited to 'native/src/widget/pane_grid.rs')
-rw-r--r-- | native/src/widget/pane_grid.rs | 125 |
1 files changed, 92 insertions, 33 deletions
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index faf8da4e..8fc423af 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -9,30 +9,34 @@ //! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.1/examples/pane_grid //! [`PaneGrid`]: struct.PaneGrid.html mod axis; +mod configuration; mod content; mod direction; mod node; mod pane; mod split; mod state; +mod title_bar; pub use axis::Axis; +pub use configuration::Configuration; pub use content::Content; pub use direction::Direction; pub use node::Node; pub use pane::Pane; pub use split::Split; pub use state::{Focus, State}; +pub use title_bar::TitleBar; use crate::{ - keyboard, layout, mouse, Clipboard, Element, Event, Hasher, Layout, Length, - Point, Rectangle, Size, Widget, + container, keyboard, layout, mouse, row, text, Clipboard, Element, Event, + Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget, }; /// A collection of panes distributed using either vertical or horizontal splits /// to completely fill the space available. /// -/// [](https://gfycat.com/mixedflatjellyfish) +/// [](https://gfycat.com/frailfreshairedaleterrier) /// /// This distribution of space is common in tiling window managers (like /// [`awesome`](https://awesomewm.org/), [`i3`](https://i3wm.org/), or even @@ -70,10 +74,10 @@ use crate::{ /// /// let pane_grid = /// PaneGrid::new(&mut state, |pane, state, focus| { -/// match state { +/// pane_grid::Content::new(match state { /// PaneState::SomePane => Text::new("This is some pane"), /// PaneState::AnotherKindOfPane => Text::new("This is another kind of pane"), -/// }.into() +/// }) /// }) /// .on_drag(Message::PaneDragged) /// .on_resize(10, Message::PaneResized); @@ -82,10 +86,9 @@ use crate::{ /// [`PaneGrid`]: struct.PaneGrid.html /// [`State`]: struct.State.html #[allow(missing_debug_implementations)] -pub struct PaneGrid<'a, Message, Renderer> { +pub struct PaneGrid<'a, Message, Renderer: self::Renderer> { state: &'a mut state::Internal, - pressed_modifiers: &'a mut keyboard::ModifiersState, - elements: Vec<(Pane, Element<'a, Message, Renderer>)>, + elements: Vec<(Pane, Content<'a, Message, Renderer>)>, width: Length, height: Length, spacing: u16, @@ -95,7 +98,10 @@ pub struct PaneGrid<'a, Message, Renderer> { on_key_press: Option<Box<dyn Fn(KeyPressEvent) -> Option<Message> + 'a>>, } -impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { +impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> +where + Renderer: self::Renderer, +{ /// Creates a [`PaneGrid`] with the given [`State`] and view function. /// /// The view function will be called to display each [`Pane`] present in the @@ -110,7 +116,7 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { Pane, &'a mut T, Option<Focus>, - ) -> Element<'a, Message, Renderer>, + ) -> Content<'a, Message, Renderer>, ) -> Self { let elements = { let action = state.internal.action(); @@ -136,7 +142,6 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { Self { state: &mut state.internal, - pressed_modifiers: &mut state.modifiers, elements, width: Length::Fill, height: Length::Fill, @@ -177,8 +182,7 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { /// Sets the modifier keys of the [`PaneGrid`]. /// - /// The modifier keys will need to be pressed to trigger dragging, and key - /// events. + /// The modifier keys will need to be pressed to trigger key events. /// /// The default modifier key is `Ctrl`. /// @@ -194,8 +198,6 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { /// Enables the drag and drop interactions of the [`PaneGrid`], which will /// use the provided function to produce messages. /// - /// Panes can be dragged using `Modifier keys + Left click`. - /// /// [`PaneGrid`]: struct.PaneGrid.html pub fn on_drag<F>(mut self, f: F) -> Self where @@ -248,7 +250,12 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { self.on_key_press = Some(Box::new(f)); self } +} +impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> +where + Renderer: self::Renderer, +{ fn click_pane( &mut self, layout: Layout<'_>, @@ -260,16 +267,24 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> { |(_, layout)| layout.bounds().contains(cursor_position), ); - if let Some(((pane, _), _)) = clicked_region.next() { + if let Some(((pane, content), layout)) = clicked_region.next() { match &self.on_drag { - Some(on_drag) - if self.pressed_modifiers.matches(self.modifier_keys) => - { - self.state.pick_pane(pane); + Some(on_drag) => { + if content.can_be_picked_at(layout, cursor_position) { + let pane_position = layout.position(); + + let origin = cursor_position + - Vector::new(pane_position.x, pane_position.y); - messages.push(on_drag(DragEvent::Picked { pane: *pane })); + self.state.pick_pane(pane, origin); + + messages + .push(on_drag(DragEvent::Picked { pane: *pane })); + } else { + self.state.focus(pane); + } } - _ => { + None => { self.state.focus(pane); } } @@ -390,7 +405,7 @@ pub struct KeyPressEvent { impl<'a, Message, Renderer> Widget<'a, Message, Renderer> for PaneGrid<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: self::Renderer + container::Renderer, { fn width(&self) -> Length { self.width @@ -485,7 +500,7 @@ where } } mouse::Event::ButtonReleased(mouse::Button::Left) => { - if let Some(pane) = self.state.picked_pane() { + if let Some((pane, _)) = self.state.picked_pane() { self.state.focus(&pane); if let Some(on_drag) = &self.on_drag { @@ -540,9 +555,6 @@ where } } } - keyboard::Event::ModifiersChanged(modifiers) => { - *self.pressed_modifiers = modifiers; - } _ => {} } } @@ -553,7 +565,7 @@ where { self.elements.iter_mut().zip(layout.children()).for_each( |((_, pane), layout)| { - pane.widget.on_event( + pane.on_event( event.clone(), layout, cursor_position, @@ -600,7 +612,8 @@ where }) .map(|(_, axis)| axis); - renderer.draw( + self::Renderer::draw( + renderer, defaults, &self.elements, self.state.picked_pane(), @@ -632,7 +645,9 @@ where /// /// [`PaneGrid`]: struct.PaneGrid.html /// [renderer]: ../../renderer/index.html -pub trait Renderer: crate::Renderer + Sized { +pub trait Renderer: + crate::Renderer + container::Renderer + text::Renderer + Sized +{ /// Draws a [`PaneGrid`]. /// /// It receives: @@ -648,18 +663,62 @@ pub trait Renderer: crate::Renderer + Sized { fn draw<Message>( &mut self, defaults: &Self::Defaults, - content: &[(Pane, Element<'_, Message, Self>)], - dragging: Option<Pane>, + content: &[(Pane, Content<'_, Message, Self>)], + dragging: Option<(Pane, Point)>, resizing: Option<Axis>, layout: Layout<'_>, cursor_position: Point, ) -> Self::Output; + + /// Draws a [`Pane`]. + /// + /// It receives: + /// - the [`TitleBar`] of the [`Pane`], if any + /// - the [`Content`] of the [`Pane`] + /// - the [`Layout`] of the [`Pane`] and its elements + /// - the cursor position + /// + /// [`Pane`]: struct.Pane.html + /// [`Layout`]: ../layout/struct.Layout.html + fn draw_pane<Message>( + &mut self, + defaults: &Self::Defaults, + bounds: Rectangle, + style: &Self::Style, + title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>, + body: (&Element<'_, Message, Self>, Layout<'_>), + cursor_position: Point, + ) -> Self::Output; + + /// Draws a [`TitleBar`]. + /// + /// It receives: + /// - the bounds, style of the [`TitleBar`] + /// - the style of the [`TitleBar`] + /// - the title of the [`TitleBar`] with its size, font, and bounds + /// - the controls of the [`TitleBar`] with their [`Layout`+, if any + /// - the cursor position + /// + /// [`TitleBar`]: struct.TitleBar.html + /// [`Layout`]: ../layout/struct.Layout.html + fn draw_title_bar<Message>( + &mut self, + defaults: &Self::Defaults, + bounds: Rectangle, + style: &Self::Style, + title: &str, + title_size: u16, + title_font: Self::Font, + title_bounds: Rectangle, + controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, + cursor_position: Point, + ) -> Self::Output; } impl<'a, Message, Renderer> From<PaneGrid<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer, + Renderer: 'a + self::Renderer + row::Renderer, Message: 'a, { fn from( |