summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--graphics/src/layer.rs9
-rw-r--r--graphics/src/primitive.rs2
-rw-r--r--graphics/src/renderer.rs27
-rw-r--r--native/src/renderer.rs7
-rw-r--r--native/src/renderer/null.rs8
-rw-r--r--native/src/user_interface.rs22
-rw-r--r--native/src/widget/pane_grid.rs57
-rw-r--r--native/src/widget/pane_grid/content.rs36
-rw-r--r--native/src/widget/pane_grid/title_bar.rs30
-rw-r--r--native/src/widget/scrollable.rs25
-rw-r--r--native/src/widget/text_input.rs8
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);
}