From 012b4adec7a87331b2d75f6bc5d2a0189dcd7ec5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 4 Mar 2020 04:10:26 +0100 Subject: Draft `Panes` widget and `panes` example --- wgpu/src/renderer/widget.rs | 1 + wgpu/src/renderer/widget/panes.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 wgpu/src/renderer/widget/panes.rs (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget.rs b/wgpu/src/renderer/widget.rs index 84f908e7..9a46552e 100644 --- a/wgpu/src/renderer/widget.rs +++ b/wgpu/src/renderer/widget.rs @@ -2,6 +2,7 @@ mod button; mod checkbox; mod column; mod container; +mod panes; mod progress_bar; mod radio; mod row; diff --git a/wgpu/src/renderer/widget/panes.rs b/wgpu/src/renderer/widget/panes.rs new file mode 100644 index 00000000..67f92f52 --- /dev/null +++ b/wgpu/src/renderer/widget/panes.rs @@ -0,0 +1,34 @@ +use crate::{Primitive, Renderer}; +use iced_native::{panes, Element, Layout, MouseCursor, Point}; + +impl panes::Renderer for Renderer { + fn draw( + &mut self, + defaults: &Self::Defaults, + content: &[Element<'_, Message, Self>], + layout: Layout<'_>, + cursor_position: Point, + ) -> Self::Output { + let mut mouse_cursor = MouseCursor::OutOfBounds; + + ( + Primitive::Group { + primitives: content + .iter() + .zip(layout.children()) + .map(|(child, layout)| { + let (primitive, new_mouse_cursor) = + child.draw(self, defaults, layout, cursor_position); + + if new_mouse_cursor > mouse_cursor { + mouse_cursor = new_mouse_cursor; + } + + primitive + }) + .collect(), + }, + mouse_cursor, + ) + } +} -- cgit From b6926d9ab4ae0c45049c3a8c19616939cbe9db95 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 4 Mar 2020 21:56:59 +0100 Subject: Improve `Debug` implementation of `cache::State` --- wgpu/src/widget/canvas/layer/cache.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'wgpu/src') diff --git a/wgpu/src/widget/canvas/layer/cache.rs b/wgpu/src/widget/canvas/layer/cache.rs index 3071cce0..8f265142 100644 --- a/wgpu/src/widget/canvas/layer/cache.rs +++ b/wgpu/src/widget/canvas/layer/cache.rs @@ -21,7 +21,6 @@ pub struct Cache { state: RefCell, } -#[derive(Debug)] enum State { Empty, Filled { @@ -99,3 +98,17 @@ where mesh } } + +impl std::fmt::Debug for State { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + State::Empty => write!(f, "Empty"), + State::Filled { mesh, bounds } => f + .debug_struct("Filled") + .field("vertices", &mesh.vertices.len()) + .field("indices", &mesh.indices.len()) + .field("bounds", bounds) + .finish(), + } + } +} -- cgit From d7f32d47ba352616328f72323cad18351b326ae8 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 4 Mar 2020 22:01:57 +0100 Subject: Compute `panes` regions and focus on click --- wgpu/src/renderer/widget/panes.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget/panes.rs b/wgpu/src/renderer/widget/panes.rs index 67f92f52..74e58895 100644 --- a/wgpu/src/renderer/widget/panes.rs +++ b/wgpu/src/renderer/widget/panes.rs @@ -5,7 +5,7 @@ impl panes::Renderer for Renderer { fn draw( &mut self, defaults: &Self::Defaults, - content: &[Element<'_, Message, Self>], + content: &[(panes::Pane, Element<'_, Message, Self>)], layout: Layout<'_>, cursor_position: Point, ) -> Self::Output { @@ -16,9 +16,9 @@ impl panes::Renderer for Renderer { primitives: content .iter() .zip(layout.children()) - .map(|(child, layout)| { + .map(|((_, pane), layout)| { let (primitive, new_mouse_cursor) = - child.draw(self, defaults, layout, cursor_position); + pane.draw(self, defaults, layout, cursor_position); if new_mouse_cursor > mouse_cursor { mouse_cursor = new_mouse_cursor; -- cgit From 6151c528241d0a6ece88e6e664df1b50f8174ecb Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 10 Mar 2020 02:57:13 +0100 Subject: Rename `Panes` widget to `PaneGrid` --- wgpu/src/renderer/widget.rs | 2 +- wgpu/src/renderer/widget/pane_grid.rs | 34 ++++++++++++++++++++++++++++++++++ wgpu/src/renderer/widget/panes.rs | 34 ---------------------------------- 3 files changed, 35 insertions(+), 35 deletions(-) create mode 100644 wgpu/src/renderer/widget/pane_grid.rs delete mode 100644 wgpu/src/renderer/widget/panes.rs (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget.rs b/wgpu/src/renderer/widget.rs index 9a46552e..37421fbe 100644 --- a/wgpu/src/renderer/widget.rs +++ b/wgpu/src/renderer/widget.rs @@ -2,7 +2,7 @@ mod button; mod checkbox; mod column; mod container; -mod panes; +mod pane_grid; mod progress_bar; mod radio; mod row; diff --git a/wgpu/src/renderer/widget/pane_grid.rs b/wgpu/src/renderer/widget/pane_grid.rs new file mode 100644 index 00000000..022fea70 --- /dev/null +++ b/wgpu/src/renderer/widget/pane_grid.rs @@ -0,0 +1,34 @@ +use crate::{Primitive, Renderer}; +use iced_native::{pane_grid, Element, Layout, MouseCursor, Point}; + +impl pane_grid::Renderer for Renderer { + fn draw( + &mut self, + defaults: &Self::Defaults, + content: &[(pane_grid::Pane, Element<'_, Message, Self>)], + layout: Layout<'_>, + cursor_position: Point, + ) -> Self::Output { + let mut mouse_cursor = MouseCursor::OutOfBounds; + + ( + Primitive::Group { + primitives: content + .iter() + .zip(layout.children()) + .map(|((_, pane), layout)| { + let (primitive, new_mouse_cursor) = + pane.draw(self, defaults, layout, cursor_position); + + if new_mouse_cursor > mouse_cursor { + mouse_cursor = new_mouse_cursor; + } + + primitive + }) + .collect(), + }, + mouse_cursor, + ) + } +} diff --git a/wgpu/src/renderer/widget/panes.rs b/wgpu/src/renderer/widget/panes.rs deleted file mode 100644 index 74e58895..00000000 --- a/wgpu/src/renderer/widget/panes.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::{Primitive, Renderer}; -use iced_native::{panes, Element, Layout, MouseCursor, Point}; - -impl panes::Renderer for Renderer { - fn draw( - &mut self, - defaults: &Self::Defaults, - content: &[(panes::Pane, Element<'_, Message, Self>)], - layout: Layout<'_>, - cursor_position: Point, - ) -> Self::Output { - let mut mouse_cursor = MouseCursor::OutOfBounds; - - ( - Primitive::Group { - primitives: content - .iter() - .zip(layout.children()) - .map(|((_, pane), layout)| { - let (primitive, new_mouse_cursor) = - pane.draw(self, defaults, layout, cursor_position); - - if new_mouse_cursor > mouse_cursor { - mouse_cursor = new_mouse_cursor; - } - - primitive - }) - .collect(), - }, - mouse_cursor, - ) - } -} -- cgit From 4e0e50ae273c24c8cfba7f190c2b69b2f9f91c54 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 10 Mar 2020 06:46:11 +0100 Subject: Fix `Debug` implementation of `layer::cache::State` --- wgpu/src/widget/canvas/layer/cache.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/widget/canvas/layer/cache.rs b/wgpu/src/widget/canvas/layer/cache.rs index be08d48d..f7002459 100644 --- a/wgpu/src/widget/canvas/layer/cache.rs +++ b/wgpu/src/widget/canvas/layer/cache.rs @@ -101,10 +101,9 @@ impl std::fmt::Debug for State { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { State::Empty => write!(f, "Empty"), - State::Filled { mesh, bounds } => f + State::Filled { primitive, bounds } => f .debug_struct("Filled") - .field("vertices", &mesh.vertices.len()) - .field("indices", &mesh.indices.len()) + .field("primitive", primitive) .field("bounds", bounds) .finish(), } -- cgit From eb070b965294707100b16472980f4794162cbc36 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 10 Mar 2020 06:47:32 +0100 Subject: Draft drag and drop support for `PaneGrid` --- wgpu/src/renderer/widget/pane_grid.rs | 80 +++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 18 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget/pane_grid.rs b/wgpu/src/renderer/widget/pane_grid.rs index 022fea70..8fb4a1a9 100644 --- a/wgpu/src/renderer/widget/pane_grid.rs +++ b/wgpu/src/renderer/widget/pane_grid.rs @@ -1,34 +1,78 @@ use crate::{Primitive, Renderer}; -use iced_native::{pane_grid, Element, Layout, MouseCursor, Point}; +use iced_native::{ + pane_grid::{self, Pane}, + Element, Layout, MouseCursor, Point, Rectangle, Vector, +}; impl pane_grid::Renderer for Renderer { fn draw( &mut self, defaults: &Self::Defaults, - content: &[(pane_grid::Pane, Element<'_, Message, Self>)], + content: &[(Pane, Element<'_, Message, Self>)], + dragging: Option, layout: Layout<'_>, cursor_position: Point, ) -> Self::Output { let mut mouse_cursor = MouseCursor::OutOfBounds; + let mut dragged_pane = None; + + let mut panes: Vec<_> = content + .iter() + .zip(layout.children()) + .enumerate() + .map(|(i, ((id, pane), layout))| { + let (primitive, new_mouse_cursor) = + pane.draw(self, defaults, layout, cursor_position); + + if new_mouse_cursor > mouse_cursor { + mouse_cursor = new_mouse_cursor; + } + + if Some(*id) == dragging { + dragged_pane = Some((i, layout)); + } + + primitive + }) + .collect(); + + let primitives = if let Some((index, layout)) = dragged_pane { + let pane = panes.remove(index); + let bounds = layout.bounds(); + + // TODO: Fix once proper layering is implemented. + // This is a pretty hacky way to achieve layering. + let clip = Primitive::Clip { + bounds: Rectangle { + x: cursor_position.x - bounds.width / 2.0, + y: cursor_position.y - bounds.height / 2.0, + width: bounds.width + 0.5, + height: bounds.height + 0.5, + }, + offset: Vector::new(0, 0), + content: Box::new(Primitive::Cached { + origin: Point::new( + cursor_position.x - bounds.x - bounds.width / 2.0, + cursor_position.y - bounds.y - bounds.height / 2.0, + ), + cache: std::sync::Arc::new(pane), + }), + }; + + panes.push(clip); + + panes + } else { + panes + }; ( - Primitive::Group { - primitives: content - .iter() - .zip(layout.children()) - .map(|((_, pane), layout)| { - let (primitive, new_mouse_cursor) = - pane.draw(self, defaults, layout, cursor_position); - - if new_mouse_cursor > mouse_cursor { - mouse_cursor = new_mouse_cursor; - } - - primitive - }) - .collect(), + Primitive::Group { primitives }, + if dragging.is_some() { + MouseCursor::Grabbing + } else { + mouse_cursor }, - mouse_cursor, ) } } -- cgit From f11397c31a4139fedb90671a5d154c17749f2a7f Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 10 Mar 2020 06:49:25 +0100 Subject: Clip `scrollable` primitives only when necessary --- wgpu/src/renderer/widget/scrollable.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget/scrollable.rs b/wgpu/src/renderer/widget/scrollable.rs index bfee7411..732523e3 100644 --- a/wgpu/src/renderer/widget/scrollable.rs +++ b/wgpu/src/renderer/widget/scrollable.rs @@ -58,14 +58,14 @@ impl scrollable::Renderer for Renderer { style_sheet: &Self::Style, (content, mouse_cursor): Self::Output, ) -> Self::Output { - let clip = Primitive::Clip { - bounds, - offset: Vector::new(0, offset), - content: Box::new(content), - }; - ( if let Some(scrollbar) = scrollbar { + let clip = Primitive::Clip { + bounds, + offset: Vector::new(0, offset), + content: Box::new(content), + }; + let style = if state.is_scroller_grabbed() { style_sheet.dragging() } else if is_mouse_over_scrollbar { @@ -115,7 +115,7 @@ impl scrollable::Renderer for Renderer { primitives: vec![clip, scrollbar, scroller], } } else { - clip + content }, if is_mouse_over_scrollbar || state.is_scroller_grabbed() { MouseCursor::Idle -- cgit From f08cb4ad565799689d07bacc190fbe0436a63648 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 14 Mar 2020 08:10:50 +0100 Subject: Implement mouse-based pane resizing for `PaneGrid` --- wgpu/src/renderer/widget/pane_grid.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget/pane_grid.rs b/wgpu/src/renderer/widget/pane_grid.rs index 8fb4a1a9..a00b49ea 100644 --- a/wgpu/src/renderer/widget/pane_grid.rs +++ b/wgpu/src/renderer/widget/pane_grid.rs @@ -1,6 +1,6 @@ use crate::{Primitive, Renderer}; use iced_native::{ - pane_grid::{self, Pane}, + pane_grid::{self, Axis, Pane}, Element, Layout, MouseCursor, Point, Rectangle, Vector, }; @@ -10,6 +10,7 @@ impl pane_grid::Renderer for Renderer { defaults: &Self::Defaults, content: &[(Pane, Element<'_, Message, Self>)], dragging: Option, + resizing: Option, layout: Layout<'_>, cursor_position: Point, ) -> Self::Output { @@ -70,6 +71,11 @@ impl pane_grid::Renderer for Renderer { Primitive::Group { primitives }, if dragging.is_some() { MouseCursor::Grabbing + } else if let Some(axis) = resizing { + match axis { + Axis::Horizontal => MouseCursor::ResizingHorizontally, + Axis::Vertical => MouseCursor::ResizingVertically, + } } else { mouse_cursor }, -- cgit From ec334bdd362243a49237c1f07b601dd6b28ddc3a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 14 Mar 2020 09:00:57 +0100 Subject: Improve pane selection when resizing a `PaneGrid` --- wgpu/src/renderer/widget/pane_grid.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget/pane_grid.rs b/wgpu/src/renderer/widget/pane_grid.rs index a00b49ea..741fe814 100644 --- a/wgpu/src/renderer/widget/pane_grid.rs +++ b/wgpu/src/renderer/widget/pane_grid.rs @@ -73,8 +73,8 @@ impl pane_grid::Renderer for Renderer { MouseCursor::Grabbing } else if let Some(axis) = resizing { match axis { - Axis::Horizontal => MouseCursor::ResizingHorizontally, - Axis::Vertical => MouseCursor::ResizingVertically, + Axis::Horizontal => MouseCursor::ResizingVertically, + Axis::Vertical => MouseCursor::ResizingHorizontally, } } else { mouse_cursor -- cgit From 20b142e8e3a674f27f9c9429449002086708ce11 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 18 Mar 2020 01:26:13 +0100 Subject: Make cursor unavailable when dragging panes --- wgpu/src/renderer/widget/pane_grid.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'wgpu/src') diff --git a/wgpu/src/renderer/widget/pane_grid.rs b/wgpu/src/renderer/widget/pane_grid.rs index 741fe814..2d201fec 100644 --- a/wgpu/src/renderer/widget/pane_grid.rs +++ b/wgpu/src/renderer/widget/pane_grid.rs @@ -14,6 +14,14 @@ impl pane_grid::Renderer for Renderer { layout: Layout<'_>, cursor_position: Point, ) -> Self::Output { + let pane_cursor_position = if dragging.is_some() { + // TODO: Remove once cursor availability is encoded in the type + // system + Point::new(-1.0, -1.0) + } else { + cursor_position + }; + let mut mouse_cursor = MouseCursor::OutOfBounds; let mut dragged_pane = None; @@ -23,7 +31,7 @@ impl pane_grid::Renderer for Renderer { .enumerate() .map(|(i, ((id, pane), layout))| { let (primitive, new_mouse_cursor) = - pane.draw(self, defaults, layout, cursor_position); + pane.draw(self, defaults, layout, pane_cursor_position); if new_mouse_cursor > mouse_cursor { mouse_cursor = new_mouse_cursor; -- cgit From bb898fa2e277d46642feec397efd753f133a0aae Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 19 Mar 2020 09:37:13 +0100 Subject: Create `PaneGrid` alias in `iced_wgpu` --- wgpu/src/widget.rs | 3 +++ wgpu/src/widget/pane_grid.rs | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 wgpu/src/widget/pane_grid.rs (limited to 'wgpu/src') diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index 73cce7e2..b39f2d91 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -10,6 +10,7 @@ pub mod button; pub mod checkbox; pub mod container; +pub mod pane_grid; pub mod progress_bar; pub mod radio; pub mod scrollable; @@ -23,6 +24,8 @@ pub use checkbox::Checkbox; #[doc(no_inline)] pub use container::Container; #[doc(no_inline)] +pub use pane_grid::PaneGrid; +#[doc(no_inline)] pub use progress_bar::ProgressBar; #[doc(no_inline)] pub use radio::Radio; diff --git a/wgpu/src/widget/pane_grid.rs b/wgpu/src/widget/pane_grid.rs new file mode 100644 index 00000000..7bc2f7c5 --- /dev/null +++ b/wgpu/src/widget/pane_grid.rs @@ -0,0 +1,17 @@ +//! Let your users split regions of your application and organize layout dynamically. +//! +//! [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish) +use crate::Renderer; + +pub use iced_native::pane_grid::{ + Axis, Direction, DragEvent, Focus, KeyPressEvent, Pane, ResizeEvent, Split, + State, +}; + +/// A collection of panes distributed using either vertical or horizontal splits +/// to completely fill the space available. +/// +/// [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish) +/// +/// This is an alias of an `iced_native` pane grid with an `iced_wgpu::Renderer`. +pub type PaneGrid<'a, Message> = iced_native::PaneGrid<'a, Message, Renderer>; -- cgit