diff options
author | 2020-06-04 07:13:38 +0200 | |
---|---|---|
committer | 2020-06-04 07:13:38 +0200 | |
commit | a11bcf5af0be26671ba90097c64021014ab2092d (patch) | |
tree | 80cc87df6ddcb7bbe8cdeb36baecb1bf80421e34 /native | |
parent | 4c494c724435d05d1b46d19bf890a8aaef962b15 (diff) | |
download | iced-a11bcf5af0be26671ba90097c64021014ab2092d.tar.gz iced-a11bcf5af0be26671ba90097c64021014ab2092d.tar.bz2 iced-a11bcf5af0be26671ba90097c64021014ab2092d.zip |
Draft first-class `TitleBar` in `pane_grid`
Diffstat (limited to 'native')
-rw-r--r-- | native/src/lib.rs | 4 | ||||
-rw-r--r-- | native/src/widget/pane_grid.rs | 46 | ||||
-rw-r--r-- | native/src/widget/pane_grid/configuration.rs | 30 | ||||
-rw-r--r-- | native/src/widget/pane_grid/content.rs | 112 | ||||
-rw-r--r-- | native/src/widget/pane_grid/state.rs | 21 | ||||
-rw-r--r-- | native/src/widget/pane_grid/title_bar.rs | 6 |
6 files changed, 171 insertions, 48 deletions
diff --git a/native/src/lib.rs b/native/src/lib.rs index b67ff2a1..86046f63 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -30,8 +30,8 @@ //! [`Widget`]: widget/trait.Widget.html //! [`UserInterface`]: struct.UserInterface.html //! [renderer]: renderer/index.html -#![deny(missing_docs)] -#![deny(missing_debug_implementations)] +//#![deny(missing_docs)] +//#![deny(missing_debug_implementations)] #![deny(unused_results)] #![forbid(unsafe_code)] #![forbid(rust_2018_idioms)] diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index 076ae76f..4c037ee9 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -9,20 +9,24 @@ //! [`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, @@ -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(Message::PaneResized); @@ -85,7 +89,7 @@ use crate::{ pub struct PaneGrid<'a, Message, 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, @@ -110,7 +114,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(); @@ -416,12 +420,15 @@ where }, ); - 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) => + if content.is_over_drag_target( + layout, + cursor_position, + ) => { self.state.pick_pane(pane); @@ -576,7 +583,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, @@ -645,12 +652,31 @@ pub trait Renderer: crate::Renderer + Sized { fn draw<Message>( &mut self, defaults: &Self::Defaults, - content: &[(Pane, Element<'_, Message, Self>)], + content: &[(Pane, Content<'_, Message, Self>)], dragging: Option<Pane>, 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, + title_bar: Option<&TitleBar<'_, Message, Self>>, + body: &Element<'_, Message, Self>, + layout: Layout<'_>, + cursor_position: Point, + ) -> Self::Output; } impl<'a, Message, Renderer> From<PaneGrid<'a, Message, Renderer>> diff --git a/native/src/widget/pane_grid/configuration.rs b/native/src/widget/pane_grid/configuration.rs new file mode 100644 index 00000000..1fed98b7 --- /dev/null +++ b/native/src/widget/pane_grid/configuration.rs @@ -0,0 +1,30 @@ +use crate::pane_grid::Axis; + +/// The arrangement of a [`PaneGrid`]. +/// +/// [`PaneGrid`]: struct.PaneGrid.html +#[derive(Debug, Clone)] +pub enum Configuration<T> { + /// A split of the available space. + Split { + /// The direction of the split. + axis: Axis, + + /// The ratio of the split in [0.0, 1.0]. + ratio: f32, + + /// The left/top [`Content`] of the split. + /// + /// [`Configuration`]: enum.Node.html + a: Box<Configuration<T>>, + + /// The right/bottom [`Content`] of the split. + /// + /// [`Configuration`]: enum.Node.html + b: Box<Configuration<T>>, + }, + /// A [`Pane`]. + /// + /// [`Pane`]: struct.Pane.html + Pane(T), +} diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index 8822083e..e1374c82 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,30 +1,88 @@ -use crate::pane_grid::Axis; +use crate::layout; +use crate::pane_grid::{self, TitleBar}; +use crate::{Clipboard, Element, Event, Hasher, Layout, Point}; -/// The content of a [`PaneGrid`]. +/// The content of a [`Pane`]. /// -/// [`PaneGrid`]: struct.PaneGrid.html -#[derive(Debug, Clone)] -pub enum Content<T> { - /// A split of the available space. - Split { - /// The direction of the split. - axis: Axis, - - /// The ratio of the split in [0.0, 1.0]. - ratio: f32, - - /// The left/top [`Content`] of the split. - /// - /// [`Content`]: enum.Node.html - a: Box<Content<T>>, - - /// The right/bottom [`Content`] of the split. - /// - /// [`Content`]: enum.Node.html - b: Box<Content<T>>, - }, - /// A [`Pane`]. - /// - /// [`Pane`]: struct.Pane.html - Pane(T), +/// [`Pane`]: struct.Pane.html +pub struct Content<'a, Message, Renderer> { + title_bar: Option<TitleBar<'a, Message, Renderer>>, + body: Element<'a, Message, Renderer>, +} + +impl<'a, Message, Renderer> Content<'a, Message, Renderer> { + pub fn new(body: impl Into<Element<'a, Message, Renderer>>) -> Self { + Self { + title_bar: None, + body: body.into(), + } + } + + pub fn title_bar( + mut self, + title_bar: TitleBar<'a, Message, Renderer>, + ) -> Self { + self.title_bar = Some(title_bar); + self + } +} + +impl<'a, Message, Renderer> Content<'a, Message, Renderer> +where + Renderer: pane_grid::Renderer, +{ + pub fn draw( + &self, + renderer: &mut Renderer, + defaults: &Renderer::Defaults, + layout: Layout<'_>, + cursor_position: Point, + ) -> Renderer::Output { + renderer.draw_pane( + defaults, + self.title_bar.as_ref(), + &self.body, + layout, + cursor_position, + ) + } + + pub(crate) fn is_over_drag_target( + &self, + _layout: Layout<'_>, + _cursor_position: Point, + ) -> bool { + false + } + + pub(crate) fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + self.body.layout(renderer, limits) + } + + pub(crate) fn on_event( + &mut self, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + messages: &mut Vec<Message>, + renderer: &Renderer, + clipboard: Option<&dyn Clipboard>, + ) { + self.body.on_event( + event, + layout, + cursor_position, + messages, + renderer, + clipboard, + ) + } + + pub(crate) fn hash_layout(&self, state: &mut Hasher) { + self.body.hash_layout(state); + } } diff --git a/native/src/widget/pane_grid/state.rs b/native/src/widget/pane_grid/state.rs index 4b13fb8e..943120e3 100644 --- a/native/src/widget/pane_grid/state.rs +++ b/native/src/widget/pane_grid/state.rs @@ -1,6 +1,6 @@ use crate::{ keyboard, - pane_grid::{Axis, Content, Direction, Node, Pane, Split}, + pane_grid::{Axis, Configuration, Direction, Node, Pane, Split}, Hasher, Point, Rectangle, Size, }; @@ -53,18 +53,21 @@ impl<T> State<T> { /// [`State`]: struct.State.html /// [`Pane`]: struct.Pane.html pub fn new(first_pane_state: T) -> (Self, Pane) { - (Self::with_content(Content::Pane(first_pane_state)), Pane(0)) + ( + Self::with_configuration(Configuration::Pane(first_pane_state)), + Pane(0), + ) } - /// Creates a new [`State`] with the given [`Content`]. + /// Creates a new [`State`] with the given [`Configuration`]. /// /// [`State`]: struct.State.html - /// [`Content`]: enum.Content.html - pub fn with_content(content: impl Into<Content<T>>) -> Self { + /// [`Configuration`]: enum.Configuration.html + pub fn with_configuration(config: impl Into<Configuration<T>>) -> Self { let mut panes = HashMap::new(); let (layout, last_id) = - Self::distribute_content(&mut panes, content.into(), 0); + Self::distribute_content(&mut panes, config.into(), 0); State { panes, @@ -274,11 +277,11 @@ impl<T> State<T> { fn distribute_content( panes: &mut HashMap<Pane, T>, - content: Content<T>, + content: Configuration<T>, next_id: usize, ) -> (Node, usize) { match content { - Content::Split { axis, ratio, a, b } => { + Configuration::Split { axis, ratio, a, b } => { let (a, next_id) = Self::distribute_content(panes, *a, next_id); let (b, next_id) = Self::distribute_content(panes, *b, next_id); @@ -293,7 +296,7 @@ impl<T> State<T> { next_id + 1, ) } - Content::Pane(state) => { + Configuration::Pane(state) => { let id = Pane(next_id); let _ = panes.insert(id, state); diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs new file mode 100644 index 00000000..fa868a20 --- /dev/null +++ b/native/src/widget/pane_grid/title_bar.rs @@ -0,0 +1,6 @@ +use crate::Element; + +pub struct TitleBar<'a, Message, Renderer> { + title: String, + buttons: Option<Element<'a, Message, Renderer>>, +} |