From c901f40fd6c5aa39f4dc056b2b59bc7133b287e6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 14 Apr 2020 12:11:10 +0200 Subject: Introduce `Widget::overlay` :tada: --- native/src/overlay.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 native/src/overlay.rs (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs new file mode 100644 index 00000000..d34432a4 --- /dev/null +++ b/native/src/overlay.rs @@ -0,0 +1,33 @@ +use crate::{layout, Clipboard, Event, Hasher, Layout, Point}; + +pub trait Overlay +where + Renderer: crate::Renderer, +{ + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node; + + fn draw( + &self, + renderer: &mut Renderer, + defaults: &Renderer::Defaults, + layout: Layout<'_>, + cursor_position: Point, + ) -> Renderer::Output; + + fn hash_layout(&self, state: &mut Hasher); + + fn on_event( + &mut self, + _event: Event, + _layout: Layout<'_>, + _cursor_position: Point, + _messages: &mut Vec, + _renderer: &Renderer, + _clipboard: Option<&dyn Clipboard>, + ) { + } +} -- cgit From f064f0482b653a1fbee4afbddcecf91e3a399004 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 16 Apr 2020 13:22:00 +0200 Subject: Introduce `Layer` trait --- native/src/overlay.rs | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index d34432a4..a4bd5ea3 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -1,26 +1,41 @@ -use crate::{layout, Clipboard, Event, Hasher, Layout, Point}; +use crate::{layout, Clipboard, Event, Hasher, Layer, Layout, Point, Size}; -pub trait Overlay +#[allow(missing_debug_implementations)] +pub struct Overlay<'a, Message, Renderer> { + position: Point, + layer: Box + 'a>, +} + +impl<'a, Message, Renderer> Overlay<'a, Message, Renderer> where Renderer: crate::Renderer, { - fn layout( - &self, - renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node; + pub fn new( + position: Point, + layer: Box + 'a>, + ) -> Self { + Self { position, layer } + } - fn draw( + pub fn layout(&self, renderer: &Renderer, bounds: Size) -> layout::Node { + self.layer.layout(renderer, bounds, self.position) + } + + pub fn draw( &self, renderer: &mut Renderer, defaults: &Renderer::Defaults, layout: Layout<'_>, cursor_position: Point, - ) -> Renderer::Output; + ) -> Renderer::Output { + self.layer.draw(renderer, defaults, layout, cursor_position) + } - fn hash_layout(&self, state: &mut Hasher); + pub fn hash_layout(&self, state: &mut Hasher) { + self.layer.hash_layout(state, self.position); + } - fn on_event( + pub fn on_event( &mut self, _event: Event, _layout: Layout<'_>, -- cgit From afd9274de26ccf65285df02007b4ddb697bea9a3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 18 Apr 2020 14:42:48 +0200 Subject: Draft `ComboBox` and `Menu` layer --- native/src/overlay.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 6 deletions(-) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index a4bd5ea3..d7a1e082 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -1,4 +1,5 @@ use crate::{layout, Clipboard, Event, Hasher, Layer, Layout, Point, Size}; +use std::rc::Rc; #[allow(missing_debug_implementations)] pub struct Overlay<'a, Message, Renderer> { @@ -17,6 +18,18 @@ where Self { position, layer } } + pub fn map(self, f: Rc B>) -> Overlay<'a, B, Renderer> + where + Message: 'static, + Renderer: 'a, + B: 'static, + { + Overlay { + position: self.position, + layer: Box::new(Map::new(self.layer, f)), + } + } + pub fn layout(&self, renderer: &Renderer, bounds: Size) -> layout::Node { self.layer.layout(renderer, bounds, self.position) } @@ -37,12 +50,87 @@ where pub fn on_event( &mut self, - _event: Event, - _layout: Layout<'_>, - _cursor_position: Point, - _messages: &mut Vec, - _renderer: &Renderer, - _clipboard: Option<&dyn Clipboard>, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + messages: &mut Vec, + renderer: &Renderer, + clipboard: Option<&dyn Clipboard>, ) { + self.layer.on_event( + event, + layout, + cursor_position, + messages, + renderer, + clipboard, + ) + } +} + +struct Map<'a, A, B, Renderer> { + layer: Box + 'a>, + mapper: Rc B>, +} + +impl<'a, A, B, Renderer> Map<'a, A, B, Renderer> { + pub fn new( + layer: Box + 'a>, + mapper: Rc B + 'static>, + ) -> Map<'a, A, B, Renderer> { + Map { layer, mapper } + } +} + +impl<'a, A, B, Renderer> Layer for Map<'a, A, B, Renderer> +where + Renderer: crate::Renderer, +{ + fn layout( + &self, + renderer: &Renderer, + bounds: Size, + position: Point, + ) -> layout::Node { + self.layer.layout(renderer, bounds, position) + } + + fn on_event( + &mut self, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + messages: &mut Vec, + renderer: &Renderer, + clipboard: Option<&dyn Clipboard>, + ) { + let mut original_messages = Vec::new(); + + self.layer.on_event( + event, + layout, + cursor_position, + &mut original_messages, + renderer, + clipboard, + ); + + original_messages + .drain(..) + .for_each(|message| messages.push((self.mapper)(message))); + } + + fn draw( + &self, + renderer: &mut Renderer, + defaults: &Renderer::Defaults, + layout: Layout<'_>, + cursor_position: Point, + ) -> Renderer::Output { + self.layer.draw(renderer, defaults, layout, cursor_position) + } + + fn hash_layout(&self, state: &mut Hasher, position: Point) { + self.layer.hash_layout(state, position); } } -- cgit From f7a370b6b9b5d33d1d3c078d2865eacf813cd652 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 18 Apr 2020 19:27:54 +0200 Subject: Implement `Overlay::translate` --- native/src/overlay.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index d7a1e082..57f11fbf 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -1,4 +1,6 @@ -use crate::{layout, Clipboard, Event, Hasher, Layer, Layout, Point, Size}; +use crate::{ + layout, Clipboard, Event, Hasher, Layer, Layout, Point, Size, Vector, +}; use std::rc::Rc; #[allow(missing_debug_implementations)] @@ -18,6 +20,11 @@ where Self { position, layer } } + pub fn translate(mut self, translation: Vector) -> Self { + self.position = self.position + translation; + self + } + pub fn map(self, f: Rc B>) -> Overlay<'a, B, Renderer> where Message: 'static, -- cgit From 0ff5a02550e5d5de8fb5fd0643ea424d9e508888 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 23 May 2020 01:07:59 +0200 Subject: Rename `Layer` to `overlay::Content` --- native/src/overlay.rs | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index 57f11fbf..96390348 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -1,12 +1,17 @@ -use crate::{ - layout, Clipboard, Event, Hasher, Layer, Layout, Point, Size, Vector, -}; +mod content; + +pub mod menu; + +pub use content::Content; +pub use menu::Menu; + +use crate::{layout, Clipboard, Event, Hasher, Layout, Point, Size, Vector}; use std::rc::Rc; #[allow(missing_debug_implementations)] pub struct Overlay<'a, Message, Renderer> { position: Point, - layer: Box + 'a>, + content: Box + 'a>, } impl<'a, Message, Renderer> Overlay<'a, Message, Renderer> @@ -15,9 +20,9 @@ where { pub fn new( position: Point, - layer: Box + 'a>, + content: Box + 'a>, ) -> Self { - Self { position, layer } + Self { position, content } } pub fn translate(mut self, translation: Vector) -> Self { @@ -33,12 +38,12 @@ where { Overlay { position: self.position, - layer: Box::new(Map::new(self.layer, f)), + content: Box::new(Map::new(self.content, f)), } } pub fn layout(&self, renderer: &Renderer, bounds: Size) -> layout::Node { - self.layer.layout(renderer, bounds, self.position) + self.content.layout(renderer, bounds, self.position) } pub fn draw( @@ -48,11 +53,12 @@ where layout: Layout<'_>, cursor_position: Point, ) -> Renderer::Output { - self.layer.draw(renderer, defaults, layout, cursor_position) + self.content + .draw(renderer, defaults, layout, cursor_position) } pub fn hash_layout(&self, state: &mut Hasher) { - self.layer.hash_layout(state, self.position); + self.content.hash_layout(state, self.position); } pub fn on_event( @@ -64,7 +70,7 @@ where renderer: &Renderer, clipboard: Option<&dyn Clipboard>, ) { - self.layer.on_event( + self.content.on_event( event, layout, cursor_position, @@ -76,20 +82,20 @@ where } struct Map<'a, A, B, Renderer> { - layer: Box + 'a>, + content: Box + 'a>, mapper: Rc B>, } impl<'a, A, B, Renderer> Map<'a, A, B, Renderer> { pub fn new( - layer: Box + 'a>, + content: Box + 'a>, mapper: Rc B + 'static>, ) -> Map<'a, A, B, Renderer> { - Map { layer, mapper } + Map { content, mapper } } } -impl<'a, A, B, Renderer> Layer for Map<'a, A, B, Renderer> +impl<'a, A, B, Renderer> Content for Map<'a, A, B, Renderer> where Renderer: crate::Renderer, { @@ -99,7 +105,7 @@ where bounds: Size, position: Point, ) -> layout::Node { - self.layer.layout(renderer, bounds, position) + self.content.layout(renderer, bounds, position) } fn on_event( @@ -113,7 +119,7 @@ where ) { let mut original_messages = Vec::new(); - self.layer.on_event( + self.content.on_event( event, layout, cursor_position, @@ -134,10 +140,11 @@ where layout: Layout<'_>, cursor_position: Point, ) -> Renderer::Output { - self.layer.draw(renderer, defaults, layout, cursor_position) + self.content + .draw(renderer, defaults, layout, cursor_position) } fn hash_layout(&self, state: &mut Hasher, position: Point) { - self.layer.hash_layout(state, position); + self.content.hash_layout(state, position); } } -- cgit From 1c12bad866d06b320f16609576d5937413418a0c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 8 Jul 2020 06:55:22 +0200 Subject: Split `Menu::new` into multiple builder methods --- native/src/overlay.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index 96390348..b8c8bb48 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -32,7 +32,7 @@ where pub fn map(self, f: Rc B>) -> Overlay<'a, B, Renderer> where - Message: 'static, + Message: 'a, Renderer: 'a, B: 'static, { -- cgit From 1070b61f3408539f6c9cb9d265f3295e6d055db7 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 10 Jul 2020 01:31:56 +0200 Subject: Rename `overlay::Content` trait to `Overlay` The `Overlay` struct is now `overlay::Element`. --- native/src/overlay.rs | 143 ++++++-------------------------------------------- 1 file changed, 17 insertions(+), 126 deletions(-) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index b8c8bb48..b6cbbec3 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -1,101 +1,13 @@ -mod content; +mod element; pub mod menu; -pub use content::Content; +pub use element::Element; pub use menu::Menu; -use crate::{layout, Clipboard, Event, Hasher, Layout, Point, Size, Vector}; -use std::rc::Rc; +use crate::{layout, Clipboard, Event, Hasher, Layout, Point, Size}; -#[allow(missing_debug_implementations)] -pub struct Overlay<'a, Message, Renderer> { - position: Point, - content: Box + 'a>, -} - -impl<'a, Message, Renderer> Overlay<'a, Message, Renderer> -where - Renderer: crate::Renderer, -{ - pub fn new( - position: Point, - content: Box + 'a>, - ) -> Self { - Self { position, content } - } - - pub fn translate(mut self, translation: Vector) -> Self { - self.position = self.position + translation; - self - } - - pub fn map(self, f: Rc B>) -> Overlay<'a, B, Renderer> - where - Message: 'a, - Renderer: 'a, - B: 'static, - { - Overlay { - position: self.position, - content: Box::new(Map::new(self.content, f)), - } - } - - pub fn layout(&self, renderer: &Renderer, bounds: Size) -> layout::Node { - self.content.layout(renderer, bounds, self.position) - } - - pub fn draw( - &self, - renderer: &mut Renderer, - defaults: &Renderer::Defaults, - layout: Layout<'_>, - cursor_position: Point, - ) -> Renderer::Output { - self.content - .draw(renderer, defaults, layout, cursor_position) - } - - pub fn hash_layout(&self, state: &mut Hasher) { - self.content.hash_layout(state, self.position); - } - - pub fn on_event( - &mut self, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - messages: &mut Vec, - renderer: &Renderer, - clipboard: Option<&dyn Clipboard>, - ) { - self.content.on_event( - event, - layout, - cursor_position, - messages, - renderer, - clipboard, - ) - } -} - -struct Map<'a, A, B, Renderer> { - content: Box + 'a>, - mapper: Rc B>, -} - -impl<'a, A, B, Renderer> Map<'a, A, B, Renderer> { - pub fn new( - content: Box + 'a>, - mapper: Rc B + 'static>, - ) -> Map<'a, A, B, Renderer> { - Map { content, mapper } - } -} - -impl<'a, A, B, Renderer> Content for Map<'a, A, B, Renderer> +pub trait Overlay where Renderer: crate::Renderer, { @@ -104,34 +16,7 @@ where renderer: &Renderer, bounds: Size, position: Point, - ) -> layout::Node { - self.content.layout(renderer, bounds, position) - } - - fn on_event( - &mut self, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - messages: &mut Vec, - renderer: &Renderer, - clipboard: Option<&dyn Clipboard>, - ) { - let mut original_messages = Vec::new(); - - self.content.on_event( - event, - layout, - cursor_position, - &mut original_messages, - renderer, - clipboard, - ); - - original_messages - .drain(..) - .for_each(|message| messages.push((self.mapper)(message))); - } + ) -> layout::Node; fn draw( &self, @@ -139,12 +24,18 @@ where defaults: &Renderer::Defaults, layout: Layout<'_>, cursor_position: Point, - ) -> Renderer::Output { - self.content - .draw(renderer, defaults, layout, cursor_position) - } + ) -> Renderer::Output; + + fn hash_layout(&self, state: &mut Hasher, position: Point); - fn hash_layout(&self, state: &mut Hasher, position: Point) { - self.content.hash_layout(state, position); + fn on_event( + &mut self, + _event: Event, + _layout: Layout<'_>, + _cursor_position: Point, + _messages: &mut Vec, + _renderer: &Renderer, + _clipboard: Option<&dyn Clipboard>, + ) { } } -- cgit From 2118a726f8b6134820e1ca5b7b802fa1344e453a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 10 Jul 2020 02:39:12 +0200 Subject: Write documentation for the new `overlay` API --- native/src/overlay.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'native/src/overlay.rs') diff --git a/native/src/overlay.rs b/native/src/overlay.rs index b6cbbec3..7c3bec32 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -1,3 +1,4 @@ +//! Display interactive elements on top of other widgets. mod element; pub mod menu; @@ -7,10 +8,19 @@ pub use menu::Menu; use crate::{layout, Clipboard, Event, Hasher, Layout, Point, Size}; +/// An interactive component that can be displayed on top of other widgets. pub trait Overlay where Renderer: crate::Renderer, { + /// Returns the layout [`Node`] of the [`Overlay`]. + /// + /// This [`Node`] is used by the runtime to compute the [`Layout`] of the + /// user interface. + /// + /// [`Node`]: ../layout/struct.Node.html + /// [`Widget`]: trait.Overlay.html + /// [`Layout`]: ../layout/struct.Layout.html fn layout( &self, renderer: &Renderer, @@ -18,6 +28,9 @@ where position: Point, ) -> layout::Node; + /// Draws the [`Overlay`] using the associated `Renderer`. + /// + /// [`Overlay`]: trait.Overlay.html fn draw( &self, renderer: &mut Renderer, @@ -26,8 +39,38 @@ where cursor_position: Point, ) -> Renderer::Output; + /// Computes the _layout_ hash of the [`Overlay`]. + /// + /// The produced hash is used by the runtime to decide if the [`Layout`] + /// needs to be recomputed between frames. Therefore, to ensure maximum + /// efficiency, the hash should only be affected by the properties of the + /// [`Overlay`] that can affect layouting. + /// + /// For example, the [`Text`] widget does not hash its color property, as + /// its value cannot affect the overall [`Layout`] of the user interface. + /// + /// [`Overlay`]: trait.Overlay.html + /// [`Layout`]: ../layout/struct.Layout.html + /// [`Text`]: text/struct.Text.html fn hash_layout(&self, state: &mut Hasher, position: Point); + /// Processes a runtime [`Event`]. + /// + /// It receives: + /// * an [`Event`] describing user interaction + /// * the computed [`Layout`] of the [`Overlay`] + /// * the current cursor position + /// * a mutable `Message` list, allowing the [`Overlay`] to produce + /// new messages based on user interaction. + /// * the `Renderer` + /// * a [`Clipboard`], if available + /// + /// By default, it does nothing. + /// + /// [`Event`]: ../enum.Event.html + /// [`Overlay`]: trait.Widget.html + /// [`Layout`]: ../layout/struct.Layout.html + /// [`Clipboard`]: ../trait.Clipboard.html fn on_event( &mut self, _event: Event, -- cgit