diff options
-rw-r--r-- | graphics/src/layer.rs | 9 | ||||
-rw-r--r-- | graphics/src/primitive.rs | 2 | ||||
-rw-r--r-- | graphics/src/renderer.rs | 27 | ||||
-rw-r--r-- | native/src/renderer.rs | 7 | ||||
-rw-r--r-- | native/src/renderer/null.rs | 8 | ||||
-rw-r--r-- | native/src/user_interface.rs | 22 | ||||
-rw-r--r-- | native/src/widget/pane_grid.rs | 57 | ||||
-rw-r--r-- | native/src/widget/pane_grid/content.rs | 36 | ||||
-rw-r--r-- | native/src/widget/pane_grid/title_bar.rs | 30 | ||||
-rw-r--r-- | native/src/widget/scrollable.rs | 25 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 8 |
11 files changed, 166 insertions, 65 deletions
diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index e5cb64c3..7a32c850 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -175,11 +175,7 @@ impl<'a> Layer<'a> { }); } } - Primitive::Clip { - bounds, - offset, - content, - } => { + Primitive::Clip { bounds, content } => { let layer = &mut layers[current_layer]; let translated_bounds = *bounds + translation; @@ -192,8 +188,7 @@ impl<'a> Layer<'a> { Self::process_primitive( layers, - translation - - Vector::new(offset.x as f32, offset.y as f32), + translation, content, layers.len() - 1, ); diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index 32f8383d..b984feaa 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -66,8 +66,6 @@ pub enum Primitive { Clip { /// The bounds of the clip bounds: Rectangle, - /// The offset transformation of the clip - offset: Vector<u32>, /// The content of the clip content: Box<Primitive>, }, diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index d90a3f1e..8b6c2217 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -51,10 +51,26 @@ where layout } - fn with_layer( + fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { + let current_primitives = + std::mem::replace(&mut self.primitives, Vec::new()); + + f(self); + + let layer_primitives = + std::mem::replace(&mut self.primitives, current_primitives); + + self.primitives.push(Primitive::Clip { + bounds, + content: Box::new(Primitive::Group { + primitives: layer_primitives, + }), + }); + } + + fn with_translation( &mut self, - bounds: Rectangle, - offset: Vector<u32>, + translation: Vector, f: impl FnOnce(&mut Self), ) { let current_primitives = @@ -65,9 +81,8 @@ where let layer_primitives = std::mem::replace(&mut self.primitives, current_primitives); - self.primitives.push(Primitive::Clip { - bounds, - offset, + self.primitives.push(Primitive::Translate { + translation, content: Box::new(Primitive::Group { primitives: layer_primitives, }), diff --git a/native/src/renderer.rs b/native/src/renderer.rs index e48c701d..6d12edae 100644 --- a/native/src/renderer.rs +++ b/native/src/renderer.rs @@ -46,10 +46,11 @@ pub trait Renderer: Sized { element.layout(self, limits) } - fn with_layer( + fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)); + + fn with_translation( &mut self, - bounds: Rectangle, - offset: Vector<u32>, + translation: Vector, f: impl FnOnce(&mut Self), ); diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index 485c5b2c..cc1d41ba 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -1,4 +1,3 @@ -use crate::pane_grid; use crate::progress_bar; use crate::renderer::{self, Renderer}; use crate::text; @@ -19,10 +18,11 @@ impl Null { } impl Renderer for Null { - fn with_layer( + fn with_layer(&mut self, _bounds: Rectangle, _f: impl FnOnce(&mut Self)) {} + + fn with_translation( &mut self, - _bounds: Rectangle, - _offset: Vector<u32>, + _translation: Vector, _f: impl FnOnce(&mut Self), ) { } diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index d9338524..c3a8394c 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -3,7 +3,7 @@ use crate::layout; use crate::mouse; use crate::overlay; use crate::renderer; -use crate::{Clipboard, Element, Layout, Point, Rectangle, Size, Vector}; +use crate::{Clipboard, Element, Layout, Point, Rectangle, Size}; use std::hash::Hasher; @@ -359,18 +359,14 @@ where let overlay_bounds = layer.layout.bounds(); - renderer.with_layer( - overlay_bounds, - Vector::new(0, 0), - |renderer| { - overlay.draw( - renderer, - &renderer::Style::default(), - Layout::new(&layer.layout), - cursor_position, - ); - }, - ); + renderer.with_layer(overlay_bounds, |renderer| { + overlay.draw( + renderer, + &renderer::Style::default(), + Layout::new(&layer.layout), + cursor_position, + ); + }); self.overlay = Some(layer); diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index cb386959..5f0e73e4 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -471,6 +471,33 @@ where .fold(event_status, event::Status::merge) } + fn mouse_interaction( + &self, + layout: Layout<'_>, + viewport: &Rectangle, + cursor_position: Point, + ) -> mouse::Interaction { + if self.state.picked_pane().is_some() { + return mouse::Interaction::Grab; + } + + if let Some((_, axis)) = self.state.picked_split() { + return match axis { + Axis::Horizontal => mouse::Interaction::ResizingHorizontally, + Axis::Vertical => mouse::Interaction::ResizingVertically, + }; + } + + self.elements + .iter() + .zip(layout.children()) + .map(|((_pane, content), layout)| { + content.mouse_interaction(layout, viewport, cursor_position) + }) + .max() + .unwrap_or_default() + } + fn draw( &self, renderer: &mut Renderer, @@ -543,22 +570,22 @@ where Some((dragging, origin)) if *id == dragging => { let bounds = layout.bounds(); - renderer.with_layer( - Rectangle { - x: cursor_position.x - origin.x, - y: cursor_position.y - origin.y, - width: bounds.width + 0.5, - height: bounds.height + 0.5, - }, - Vector::new(0, 0), + renderer.with_translation( + cursor_position + - Point::new( + bounds.x + origin.x, + bounds.y + origin.y, + ), |renderer| { - pane.draw( - renderer, - style, - layout, - pane_cursor_position, - viewport, - ); + renderer.with_layer(bounds, |renderer| { + pane.draw( + renderer, + style, + layout, + pane_cursor_position, + viewport, + ); + }); }, ); } diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index e74e3c84..ddc659cc 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,6 +1,7 @@ use crate::container; use crate::event::{self, Event}; use crate::layout; +use crate::mouse; use crate::overlay; use crate::pane_grid::TitleBar; use crate::renderer; @@ -194,6 +195,41 @@ where event_status.merge(body_status) } + pub(crate) fn mouse_interaction( + &self, + layout: Layout<'_>, + viewport: &Rectangle, + cursor_position: Point, + ) -> mouse::Interaction { + let mut children = layout.children(); + + let (body_layout, title_bar_interaction) = + if let Some(title_bar) = &self.title_bar { + let title_bar_layout = children.next().unwrap(); + + let is_over_pick_area = title_bar + .is_over_pick_area(title_bar_layout, cursor_position); + + if is_over_pick_area { + return mouse::Interaction::Grab; + } + + let mouse_interaction = title_bar.mouse_interaction( + title_bar_layout, + viewport, + cursor_position, + ); + + (children.next().unwrap(), mouse_interaction) + } else { + (children.next().unwrap(), mouse::Interaction::default()) + }; + + self.body + .mouse_interaction(body_layout, viewport, cursor_position) + .max(title_bar_interaction) + } + pub(crate) fn hash_layout(&self, state: &mut Hasher) { if let Some(title_bar) = &self.title_bar { title_bar.hash_layout(state); diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index 161eb9bc..493c74db 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -1,6 +1,7 @@ use crate::container; use crate::event::{self, Event}; use crate::layout; +use crate::mouse; use crate::overlay; use crate::renderer; use crate::{ @@ -249,6 +250,35 @@ where control_status.merge(title_status) } + pub(crate) fn mouse_interaction( + &self, + layout: Layout<'_>, + viewport: &Rectangle, + cursor_position: Point, + ) -> mouse::Interaction { + let mut children = layout.children(); + let padded = children.next().unwrap(); + + let mut children = padded.children(); + let title_layout = children.next().unwrap(); + + let title_interaction = self.content.mouse_interaction( + title_layout, + viewport, + cursor_position, + ); + + if let Some(controls) = &self.controls { + let controls_layout = children.next().unwrap(); + + controls + .mouse_interaction(controls_layout, viewport, cursor_position) + .max(title_interaction) + } else { + title_interaction + } + } + pub(crate) fn overlay( &mut self, layout: Layout<'_>, diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index 76badbde..563ea370 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -485,15 +485,20 @@ where }; if let Some(scrollbar) = scrollbar { - renderer.with_layer(bounds, Vector::new(0, offset), |renderer| { - self.content.draw( - renderer, - style, - content_layout, - cursor_position, - &Rectangle { - y: bounds.y + offset as f32, - ..bounds + renderer.with_layer(bounds, |renderer| { + renderer.with_translation( + Vector::new(0.0, -(offset as f32)), + |renderer| { + self.content.draw( + renderer, + style, + content_layout, + cursor_position, + &Rectangle { + y: bounds.y + offset as f32, + ..bounds + }, + ); }, ); }); @@ -509,7 +514,7 @@ where let is_scrollbar_visible = style.background.is_some() || style.border_width > 0.0; - renderer.with_layer(bounds, Vector::new(0, 0), |renderer| { + renderer.with_layer(bounds, |renderer| { if is_scrollbar_visible { renderer.fill_rectangle(renderer::Quad { bounds: scrollbar.bounds, diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 0a2b19a3..c2950db9 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -751,11 +751,9 @@ where }; if text_width > text_bounds.width { - renderer.with_layer( - text_bounds, - Vector::new(offset as u32, 0), - render, - ); + renderer.with_layer(text_bounds, |renderer| { + renderer.with_translation(Vector::new(-offset, 0.0), render) + }); } else { render(renderer); } |