summaryrefslogtreecommitdiffstats
path: root/widget
diff options
context:
space:
mode:
Diffstat (limited to 'widget')
-rw-r--r--widget/src/button.rs4
-rw-r--r--widget/src/checkbox.rs2
-rw-r--r--widget/src/container.rs2
-rw-r--r--widget/src/overlay/menu.rs4
-rw-r--r--widget/src/pane_grid.rs111
-rw-r--r--widget/src/pane_grid/state.rs41
-rw-r--r--widget/src/pick_list.rs2
-rw-r--r--widget/src/progress_bar.rs4
-rw-r--r--widget/src/rule.rs2
-rw-r--r--widget/src/scrollable.rs26
-rw-r--r--widget/src/slider.rs22
-rw-r--r--widget/src/text_input.rs2
-rw-r--r--widget/src/vertical_slider.rs22
13 files changed, 193 insertions, 51 deletions
diff --git a/widget/src/button.rs b/widget/src/button.rs
index 7eee69cb..70fed1d5 100644
--- a/widget/src/button.rs
+++ b/widget/src/button.rs
@@ -395,7 +395,7 @@ where
y: bounds.y + styling.shadow_offset.y,
..bounds
},
- border_radius: styling.border_radius.into(),
+ border_radius: styling.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
@@ -406,7 +406,7 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
- border_radius: styling.border_radius.into(),
+ border_radius: styling.border_radius,
border_width: styling.border_width,
border_color: styling.border_color,
},
diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs
index 7d43bb4a..4c8a989b 100644
--- a/widget/src/checkbox.rs
+++ b/widget/src/checkbox.rs
@@ -269,7 +269,7 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
- border_radius: custom_style.border_radius.into(),
+ border_radius: custom_style.border_radius,
border_width: custom_style.border_width,
border_color: custom_style.border_color,
},
diff --git a/widget/src/container.rs b/widget/src/container.rs
index 9d932772..13e76551 100644
--- a/widget/src/container.rs
+++ b/widget/src/container.rs
@@ -332,7 +332,7 @@ pub fn draw_background<Renderer>(
renderer.fill_quad(
renderer::Quad {
bounds,
- border_radius: appearance.border_radius.into(),
+ border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
},
diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs
index 0acc6f79..84cc800c 100644
--- a/widget/src/overlay/menu.rs
+++ b/widget/src/overlay/menu.rs
@@ -307,7 +307,7 @@ where
bounds,
border_color: appearance.border_color,
border_width: appearance.border_width,
- border_radius: appearance.border_radius.into(),
+ border_radius: appearance.border_radius,
},
appearance.background,
);
@@ -515,7 +515,7 @@ where
},
border_color: Color::TRANSPARENT,
border_width: 0.0,
- border_radius: appearance.border_radius.into(),
+ border_radius: appearance.border_radius,
},
appearance.selected_background,
);
diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs
index 67145e8e..7bddc4a6 100644
--- a/widget/src/pane_grid.rs
+++ b/widget/src/pane_grid.rs
@@ -30,7 +30,7 @@ pub use split::Split;
pub use state::State;
pub use title_bar::TitleBar;
-pub use crate::style::pane_grid::{Line, StyleSheet};
+pub use crate::style::pane_grid::{Appearance, Line, StyleSheet};
use crate::container;
use crate::core::event::{self, Event};
@@ -594,13 +594,18 @@ pub fn update<'a, Message, T: Draggable>(
if let Some(on_drag) = on_drag {
let mut dropped_region = contents
.zip(layout.children())
- .filter(|(_, layout)| {
- layout.bounds().contains(cursor_position)
+ .filter_map(|(target, layout)| {
+ layout_region(layout, cursor_position)
+ .map(|region| (target, region))
});
let event = match dropped_region.next() {
- Some(((target, _), _)) if pane != target => {
- DragEvent::Dropped { pane, target }
+ Some(((target, _), region)) if pane != target => {
+ DragEvent::Dropped {
+ pane,
+ target,
+ region,
+ }
}
_ => DragEvent::Canceled { pane },
};
@@ -657,6 +662,28 @@ pub fn update<'a, Message, T: Draggable>(
event_status
}
+fn layout_region(layout: Layout<'_>, cursor_position: Point) -> Option<Region> {
+ let bounds = layout.bounds();
+
+ if !bounds.contains(cursor_position) {
+ return None;
+ }
+
+ let region = if cursor_position.x < (bounds.x + bounds.width / 3.0) {
+ Region::Left
+ } else if cursor_position.x > (bounds.x + 2.0 * bounds.width / 3.0) {
+ Region::Right
+ } else if cursor_position.y < (bounds.y + bounds.height / 3.0) {
+ Region::Top
+ } else if cursor_position.y > (bounds.y + 2.0 * bounds.height / 3.0) {
+ Region::Bottom
+ } else {
+ Region::Center
+ };
+
+ Some(region)
+}
+
fn click_pane<'a, Message, T>(
action: &mut state::Action,
layout: Layout<'_>,
@@ -810,6 +837,35 @@ pub fn draw<Renderer, T>(
Some((dragging, origin)) if id == dragging => {
render_picked_pane = Some((pane, origin, layout));
}
+ Some((dragging, _)) if id != dragging => {
+ draw_pane(
+ pane,
+ renderer,
+ default_style,
+ layout,
+ pane_cursor_position,
+ viewport,
+ );
+
+ if picked_pane.is_some() {
+ if let Some(region) = layout_region(layout, cursor_position)
+ {
+ let bounds = layout_region_bounds(layout, region);
+ let hovered_region_style = theme.hovered_region(style);
+
+ renderer.fill_quad(
+ renderer::Quad {
+ bounds,
+ border_radius: hovered_region_style
+ .border_radius,
+ border_width: hovered_region_style.border_width,
+ border_color: hovered_region_style.border_color,
+ },
+ theme.hovered_region(style).background,
+ );
+ }
+ }
+ }
_ => {
draw_pane(
pane,
@@ -884,6 +940,32 @@ pub fn draw<Renderer, T>(
}
}
+fn layout_region_bounds(layout: Layout<'_>, region: Region) -> Rectangle {
+ let bounds = layout.bounds();
+
+ match region {
+ Region::Center => bounds,
+ Region::Top => Rectangle {
+ height: bounds.height / 2.0,
+ ..bounds
+ },
+ Region::Left => Rectangle {
+ width: bounds.width / 2.0,
+ ..bounds
+ },
+ Region::Right => Rectangle {
+ x: bounds.x + bounds.width / 2.0,
+ width: bounds.width / 2.0,
+ ..bounds
+ },
+ Region::Bottom => Rectangle {
+ y: bounds.y + bounds.height / 2.0,
+ height: bounds.height / 2.0,
+ ..bounds
+ },
+ }
+}
+
/// An event produced during a drag and drop interaction of a [`PaneGrid`].
#[derive(Debug, Clone, Copy)]
pub enum DragEvent {
@@ -900,6 +982,9 @@ pub enum DragEvent {
/// The [`Pane`] where the picked one was dropped on.
target: Pane,
+
+ /// The [`Region`] of the target [`Pane`] where the picked one was dropped on.
+ region: Region,
},
/// A [`Pane`] was picked and then dropped outside of other [`Pane`]
@@ -910,6 +995,22 @@ pub enum DragEvent {
},
}
+/// The region of a [`Pane`].
+#[derive(Debug, Clone, Copy, Default)]
+pub enum Region {
+ /// Center region.
+ #[default]
+ Center,
+ /// Top region.
+ Top,
+ /// Left region.
+ Left,
+ /// Right region.
+ Right,
+ /// Bottom region.
+ Bottom,
+}
+
/// An event produced during a resize interaction of a [`PaneGrid`].
#[derive(Debug, Clone, Copy)]
pub struct ResizeEvent {
diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs
index a6e2ec7f..1f034ca3 100644
--- a/widget/src/pane_grid/state.rs
+++ b/widget/src/pane_grid/state.rs
@@ -2,7 +2,9 @@
//!
//! [`PaneGrid`]: crate::widget::PaneGrid
use crate::core::{Point, Size};
-use crate::pane_grid::{Axis, Configuration, Direction, Node, Pane, Split};
+use crate::pane_grid::{
+ Axis, Configuration, Direction, Node, Pane, Region, Split,
+};
use std::collections::HashMap;
@@ -165,6 +167,43 @@ impl<T> State<T> {
Some((new_pane, new_split))
}
+ /// Split a target [`Pane`] with a given [`Pane`] on a given [`Region`].
+ ///
+ /// Panes will be swapped by default for [`Region::Center`].
+ pub fn split_with(&mut self, target: &Pane, pane: &Pane, region: Region) {
+ match region {
+ Region::Center => self.swap(pane, target),
+ Region::Top => {
+ self.split_and_swap(Axis::Horizontal, target, pane, true)
+ }
+ Region::Bottom => {
+ self.split_and_swap(Axis::Horizontal, target, pane, false)
+ }
+ Region::Left => {
+ self.split_and_swap(Axis::Vertical, target, pane, true)
+ }
+ Region::Right => {
+ self.split_and_swap(Axis::Vertical, target, pane, false)
+ }
+ }
+ }
+
+ fn split_and_swap(
+ &mut self,
+ axis: Axis,
+ target: &Pane,
+ pane: &Pane,
+ swap: bool,
+ ) {
+ if let Some((state, _)) = self.close(pane) {
+ if let Some((new_pane, _)) = self.split(axis, target, state) {
+ if swap {
+ self.swap(target, &new_pane);
+ }
+ }
+ }
+ }
+
/// Swaps the position of the provided panes in the [`State`].
///
/// If you want to swap panes on drag and drop in your [`PaneGrid`], you
diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs
index 8c445dda..dcd0629b 100644
--- a/widget/src/pick_list.rs
+++ b/widget/src/pick_list.rs
@@ -624,7 +624,7 @@ pub fn draw<'a, T, Renderer>(
bounds,
border_color: style.border_color,
border_width: style.border_width,
- border_radius: style.border_radius.into(),
+ border_radius: style.border_radius,
},
style.background,
);
diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs
index ef0d87d5..9e1e9131 100644
--- a/widget/src/progress_bar.rs
+++ b/widget/src/progress_bar.rs
@@ -133,7 +133,7 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle { ..bounds },
- border_radius: style.border_radius.into(),
+ border_radius: style.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
@@ -147,7 +147,7 @@ where
width: active_progress_width,
..bounds
},
- border_radius: style.border_radius.into(),
+ border_radius: style.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
diff --git a/widget/src/rule.rs b/widget/src/rule.rs
index 3749d7ce..272bd2b3 100644
--- a/widget/src/rule.rs
+++ b/widget/src/rule.rs
@@ -125,7 +125,7 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
- border_radius: style.radius.into(),
+ border_radius: style.radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs
index fd51a6a8..12e544c5 100644
--- a/widget/src/scrollable.rs
+++ b/widget/src/scrollable.rs
@@ -128,9 +128,8 @@ impl Properties {
}
/// Sets the scrollbar width of the [`Scrollable`] .
- /// Silently enforces a minimum width of 1.
pub fn width(mut self, width: impl Into<Pixels>) -> Self {
- self.width = width.into().0.max(1.0);
+ self.width = width.into().0.max(0.0);
self
}
@@ -141,9 +140,8 @@ impl Properties {
}
/// Sets the scroller width of the [`Scrollable`] .
- /// Silently enforces a minimum width of 1.
pub fn scroller_width(mut self, scroller_width: impl Into<Pixels>) -> Self {
- self.scroller_width = scroller_width.into().0.max(1.0);
+ self.scroller_width = scroller_width.into().0.max(0.0);
self
}
}
@@ -811,14 +809,16 @@ pub fn draw<Renderer>(
style: Scrollbar,
scrollbar: &internals::Scrollbar| {
//track
- if style.background.is_some()
- || (style.border_color != Color::TRANSPARENT
- && style.border_width > 0.0)
+ if scrollbar.bounds.width > 0.0
+ && scrollbar.bounds.height > 0.0
+ && (style.background.is_some()
+ || (style.border_color != Color::TRANSPARENT
+ && style.border_width > 0.0))
{
renderer.fill_quad(
renderer::Quad {
bounds: scrollbar.bounds,
- border_radius: style.border_radius.into(),
+ border_radius: style.border_radius,
border_width: style.border_width,
border_color: style.border_color,
},
@@ -829,14 +829,16 @@ pub fn draw<Renderer>(
}
//thumb
- if style.scroller.color != Color::TRANSPARENT
- || (style.scroller.border_color != Color::TRANSPARENT
- && style.scroller.border_width > 0.0)
+ if scrollbar.scroller.bounds.width > 0.0
+ && scrollbar.scroller.bounds.height > 0.0
+ && (style.scroller.color != Color::TRANSPARENT
+ || (style.scroller.border_color != Color::TRANSPARENT
+ && style.scroller.border_width > 0.0))
{
renderer.fill_quad(
renderer::Quad {
bounds: scrollbar.scroller.bounds,
- border_radius: style.scroller.border_radius.into(),
+ border_radius: style.scroller.border_radius,
border_width: style.scroller.border_width,
border_color: style.scroller.border_color,
},
diff --git a/widget/src/slider.rs b/widget/src/slider.rs
index 18a49665..2851d8c3 100644
--- a/widget/src/slider.rs
+++ b/widget/src/slider.rs
@@ -368,16 +368,16 @@ pub fn draw<T, R>(
style_sheet.active(style)
};
- let (handle_width, handle_height, handle_border_radius) = match style
- .handle
- .shape
- {
- HandleShape::Circle { radius } => (radius * 2.0, radius * 2.0, radius),
- HandleShape::Rectangle {
- width,
- border_radius,
- } => (f32::from(width), bounds.height, border_radius),
- };
+ let (handle_width, handle_height, handle_border_radius) =
+ match style.handle.shape {
+ HandleShape::Circle { radius } => {
+ (radius * 2.0, radius * 2.0, radius.into())
+ }
+ HandleShape::Rectangle {
+ width,
+ border_radius,
+ } => (f32::from(width), bounds.height, border_radius),
+ };
let value = value.into() as f32;
let (range_start, range_end) = {
@@ -433,7 +433,7 @@ pub fn draw<T, R>(
width: handle_width,
height: handle_height,
},
- border_radius: handle_border_radius.into(),
+ border_radius: handle_border_radius,
border_width: style.handle.border_width,
border_color: style.handle.border_color,
},
diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs
index bbc07dac..8f243c1a 100644
--- a/widget/src/text_input.rs
+++ b/widget/src/text_input.rs
@@ -982,7 +982,7 @@ pub fn draw<Renderer>(
renderer.fill_quad(
renderer::Quad {
bounds,
- border_radius: appearance.border_radius.into(),
+ border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
},
diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs
index 2635611d..3b2430c4 100644
--- a/widget/src/vertical_slider.rs
+++ b/widget/src/vertical_slider.rs
@@ -366,16 +366,16 @@ pub fn draw<T, R>(
style_sheet.active(style)
};
- let (handle_width, handle_height, handle_border_radius) = match style
- .handle
- .shape
- {
- HandleShape::Circle { radius } => (radius * 2.0, radius * 2.0, radius),
- HandleShape::Rectangle {
- width,
- border_radius,
- } => (f32::from(width), bounds.width, border_radius),
- };
+ let (handle_width, handle_height, handle_border_radius) =
+ match style.handle.shape {
+ HandleShape::Circle { radius } => {
+ (radius * 2.0, radius * 2.0, radius.into())
+ }
+ HandleShape::Rectangle {
+ width,
+ border_radius,
+ } => (f32::from(width), bounds.width, border_radius),
+ };
let value = value.into() as f32;
let (range_start, range_end) = {
@@ -431,7 +431,7 @@ pub fn draw<T, R>(
width: handle_height,
height: handle_width,
},
- border_radius: handle_border_radius.into(),
+ border_radius: handle_border_radius,
border_width: style.handle.border_width,
border_color: style.handle.border_color,
},