summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/styling/src/main.rs35
-rw-r--r--glow/src/widget.rs3
-rw-r--r--glow/src/widget/rule.rs10
-rw-r--r--graphics/src/widget.rs3
-rw-r--r--graphics/src/widget/rule.rs89
-rw-r--r--native/src/widget.rs3
-rw-r--r--native/src/widget/rule.rs125
-rw-r--r--src/widget.rs6
-rw-r--r--style/src/lib.rs1
-rw-r--r--style/src/rule.rs51
-rw-r--r--wgpu/src/widget.rs3
-rw-r--r--wgpu/src/widget/rule.rs10
12 files changed, 331 insertions, 8 deletions
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs
index 63ab9d62..c969526c 100644
--- a/examples/styling/src/main.rs
+++ b/examples/styling/src/main.rs
@@ -1,7 +1,7 @@
use iced::{
button, scrollable, slider, text_input, Align, Button, Checkbox, Column,
- Container, Element, Length, ProgressBar, Radio, Row, Sandbox, Scrollable,
- Settings, Slider, Space, Text, TextInput,
+ Container, Element, Length, ProgressBar, Radio, Row, Rule, Sandbox,
+ Scrollable, Settings, Slider, Space, Text, TextInput,
};
pub fn main() {
@@ -113,14 +113,17 @@ impl Sandbox for Styling {
.padding(20)
.max_width(600)
.push(choose_theme)
+ .push(Rule::horizontal(38).style(self.theme))
.push(Row::new().spacing(10).push(text_input).push(button))
.push(slider)
.push(progress_bar)
.push(
Row::new()
.spacing(10)
+ .height(Length::Units(100))
.align_items(Align::Center)
.push(scrollable)
+ .push(Rule::vertical(38).style(self.theme))
.push(checkbox),
);
@@ -136,8 +139,8 @@ impl Sandbox for Styling {
mod style {
use iced::{
- button, checkbox, container, progress_bar, radio, scrollable, slider,
- text_input,
+ button, checkbox, container, progress_bar, radio, rule, scrollable,
+ slider, text_input,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -228,6 +231,15 @@ mod style {
}
}
+ impl From<Theme> for Box<dyn rule::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Rule.into(),
+ }
+ }
+ }
+
mod light {
use iced::{button, Background, Color, Vector};
@@ -258,7 +270,7 @@ mod style {
mod dark {
use iced::{
- button, checkbox, container, progress_bar, radio, scrollable,
+ button, checkbox, container, progress_bar, radio, rule, scrollable,
slider, text_input, Background, Color,
};
@@ -516,5 +528,18 @@ mod style {
}
}
}
+
+ pub struct Rule;
+
+ impl rule::StyleSheet for Rule {
+ fn style(&self) -> rule::Style {
+ rule::Style {
+ color: SURFACE,
+ width: 2,
+ radius: 1,
+ fill_percent: 90,
+ }
+ }
+ }
}
}
diff --git a/glow/src/widget.rs b/glow/src/widget.rs
index 4e2fedc5..0e33909d 100644
--- a/glow/src/widget.rs
+++ b/glow/src/widget.rs
@@ -16,6 +16,7 @@ pub mod pane_grid;
pub mod pick_list;
pub mod progress_bar;
pub mod radio;
+pub mod rule;
pub mod scrollable;
pub mod slider;
pub mod text_input;
@@ -35,6 +36,8 @@ pub use progress_bar::ProgressBar;
#[doc(no_inline)]
pub use radio::Radio;
#[doc(no_inline)]
+pub use rule::Rule;
+#[doc(no_inline)]
pub use scrollable::Scrollable;
#[doc(no_inline)]
pub use slider::Slider;
diff --git a/glow/src/widget/rule.rs b/glow/src/widget/rule.rs
new file mode 100644
index 00000000..16eaa267
--- /dev/null
+++ b/glow/src/widget/rule.rs
@@ -0,0 +1,10 @@
+//! Display a horizontal or vertical rule for dividing content.
+
+use crate::Renderer;
+
+pub use iced_graphics::rule::{Style, StyleSheet};
+
+/// Display a horizontal or vertical rule for dividing content.
+///
+/// This is an alias of an `iced_native` rule with an `iced_glow::Renderer`.
+pub type Rule = iced_native::Rule<Renderer>;
diff --git a/graphics/src/widget.rs b/graphics/src/widget.rs
index 94a65011..f87b558a 100644
--- a/graphics/src/widget.rs
+++ b/graphics/src/widget.rs
@@ -15,6 +15,7 @@ pub mod pane_grid;
pub mod pick_list;
pub mod progress_bar;
pub mod radio;
+pub mod rule;
pub mod scrollable;
pub mod slider;
pub mod svg;
@@ -40,6 +41,8 @@ pub use progress_bar::ProgressBar;
#[doc(no_inline)]
pub use radio::Radio;
#[doc(no_inline)]
+pub use rule::Rule;
+#[doc(no_inline)]
pub use scrollable::Scrollable;
#[doc(no_inline)]
pub use slider::Slider;
diff --git a/graphics/src/widget/rule.rs b/graphics/src/widget/rule.rs
new file mode 100644
index 00000000..5ff5197d
--- /dev/null
+++ b/graphics/src/widget/rule.rs
@@ -0,0 +1,89 @@
+//! Display a horizontal or vertical rule for dividing content.
+
+use crate::{Backend, Primitive, Renderer};
+use iced_native::mouse;
+use iced_native::rule;
+use iced_native::{Background, Color, Rectangle};
+
+pub use iced_style::rule::{Style, StyleSheet};
+
+/// Display a horizontal or vertical rule for dividing content.
+///
+/// This is an alias of an `iced_native` rule with an `iced_graphics::Renderer`.
+pub type Rule<Backend> = iced_native::Rule<Renderer<Backend>>;
+
+impl<B> rule::Renderer for Renderer<B>
+where
+ B: Backend,
+{
+ type Style = Box<dyn StyleSheet>;
+
+ fn draw(
+ &mut self,
+ bounds: Rectangle,
+ style_sheet: &Self::Style,
+ is_horizontal: bool,
+ ) -> Self::Output {
+ let style = style_sheet.style();
+
+ let line = if is_horizontal {
+ let line_y = (bounds.y + (bounds.height / 2.0)
+ - (style.width as f32 / 2.0))
+ .round();
+
+ let (line_x, line_width) = if style.fill_percent >= 100 {
+ (bounds.x, bounds.width)
+ } else {
+ let percent_width =
+ (bounds.width * style.fill_percent as f32 / 100.0).round();
+ (
+ bounds.x + ((bounds.width - percent_width) / 2.0).round(),
+ percent_width,
+ )
+ };
+
+ Primitive::Quad {
+ bounds: Rectangle {
+ x: line_x,
+ y: line_y,
+ width: line_width,
+ height: style.width as f32,
+ },
+ background: Background::Color(style.color),
+ border_radius: style.radius,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ }
+ } else {
+ let line_x = (bounds.x + (bounds.width / 2.0)
+ - (style.width as f32 / 2.0))
+ .round();
+
+ let (line_y, line_height) = if style.fill_percent >= 100 {
+ (bounds.y, bounds.height)
+ } else {
+ let percent_height =
+ (bounds.height * style.fill_percent as f32 / 100.0).round();
+ (
+ bounds.y + ((bounds.height - percent_height) / 2.0).round(),
+ percent_height,
+ )
+ };
+
+ Primitive::Quad {
+ bounds: Rectangle {
+ x: line_x,
+ y: line_y,
+ width: style.width as f32,
+ height: line_height,
+ },
+ background: Background::Color(style.color),
+ border_radius: style.radius,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ }
+ };
+
+ (line, mouse::Interaction::default())
+ }
+}
diff --git a/native/src/widget.rs b/native/src/widget.rs
index 8539e519..a10281df 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -30,6 +30,7 @@ pub mod pick_list;
pub mod progress_bar;
pub mod radio;
pub mod row;
+pub mod rule;
pub mod scrollable;
pub mod slider;
pub mod space;
@@ -58,6 +59,8 @@ pub use radio::Radio;
#[doc(no_inline)]
pub use row::Row;
#[doc(no_inline)]
+pub use rule::Rule;
+#[doc(no_inline)]
pub use scrollable::Scrollable;
#[doc(no_inline)]
pub use slider::Slider;
diff --git a/native/src/widget/rule.rs b/native/src/widget/rule.rs
new file mode 100644
index 00000000..25cec53b
--- /dev/null
+++ b/native/src/widget/rule.rs
@@ -0,0 +1,125 @@
+//! Display a horizontal or vertical rule for dividing content.
+
+use std::hash::Hash;
+
+use crate::{
+ layout, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,
+};
+
+/// Display a horizontal or vertical rule for dividing content.
+#[derive(Debug, Copy, Clone)]
+pub struct Rule<Renderer: self::Renderer> {
+ width: Length,
+ height: Length,
+ style: Renderer::Style,
+ is_horizontal: bool,
+}
+
+impl<Renderer: self::Renderer> Rule<Renderer> {
+ /// Creates a horizontal [`Rule`] for dividing content by the given vertical spacing.
+ ///
+ /// [`Rule`]: struct.Rule.html
+ pub fn horizontal(spacing: u16) -> Self {
+ Rule {
+ width: Length::Fill,
+ height: Length::from(Length::Units(spacing)),
+ style: Renderer::Style::default(),
+ is_horizontal: true,
+ }
+ }
+
+ /// Creates a vertical [`Rule`] for dividing content by the given horizontal spacing.
+ ///
+ /// [`Rule`]: struct.Rule.html
+ pub fn vertical(spacing: u16) -> Self {
+ Rule {
+ width: Length::from(Length::Units(spacing)),
+ height: Length::Fill,
+ style: Renderer::Style::default(),
+ is_horizontal: false,
+ }
+ }
+
+ /// Sets the style of the [`Rule`].
+ ///
+ /// [`Rule`]: struct.Rule.html
+ pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self {
+ self.style = style.into();
+ self
+ }
+}
+
+impl<Message, Renderer> Widget<Message, Renderer> for Rule<Renderer>
+where
+ Renderer: self::Renderer,
+{
+ fn width(&self) -> Length {
+ self.width
+ }
+
+ fn height(&self) -> Length {
+ self.height
+ }
+
+ fn layout(
+ &self,
+ _renderer: &Renderer,
+ limits: &layout::Limits,
+ ) -> layout::Node {
+ let limits = limits.width(self.width).height(self.height);
+
+ layout::Node::new(limits.resolve(Size::ZERO))
+ }
+
+ fn draw(
+ &self,
+ renderer: &mut Renderer,
+ _defaults: &Renderer::Defaults,
+ layout: Layout<'_>,
+ _cursor_position: Point,
+ ) -> Renderer::Output {
+ renderer.draw(layout.bounds(), &self.style, self.is_horizontal)
+ }
+
+ fn hash_layout(&self, state: &mut Hasher) {
+ struct Marker;
+ std::any::TypeId::of::<Marker>().hash(state);
+
+ self.width.hash(state);
+ self.height.hash(state);
+ }
+}
+
+/// The renderer of a [`Rule`].
+///
+/// [`Rule`]: struct.Rule.html
+pub trait Renderer: crate::Renderer {
+ /// The style supported by this renderer.
+ type Style: Default;
+
+ /// Draws a [`Rule`].
+ ///
+ /// It receives:
+ /// * the bounds of the [`Rule`]
+ /// * the style of the [`Rule`]
+ /// * whether the [`Rule`] is horizontal (true) or vertical (false)
+ ///
+ /// [`Rule`]: struct.Rule.html
+ fn draw(
+ &mut self,
+ bounds: Rectangle,
+ style: &Self::Style,
+ is_horizontal: bool,
+ ) -> Self::Output;
+}
+
+impl<'a, Message, Renderer> From<Rule<Renderer>>
+ for Element<'a, Message, Renderer>
+where
+ Renderer: 'a + self::Renderer,
+ Message: 'a,
+{
+ fn from(rule: Rule<Renderer>) -> Element<'a, Message, Renderer> {
+ Element::new(rule)
+ }
+}
diff --git a/src/widget.rs b/src/widget.rs
index b26f14d4..e8fff9cc 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -20,7 +20,7 @@
mod platform {
pub use crate::renderer::widget::{
button, checkbox, container, pane_grid, pick_list, progress_bar, radio,
- scrollable, slider, text_input, Column, Row, Space, Text,
+ rule, scrollable, slider, text_input, Column, Row, Space, Text,
};
#[cfg(any(feature = "canvas", feature = "glow_canvas"))]
@@ -46,8 +46,8 @@ mod platform {
pub use {
button::Button, checkbox::Checkbox, container::Container, image::Image,
pane_grid::PaneGrid, pick_list::PickList, progress_bar::ProgressBar,
- radio::Radio, scrollable::Scrollable, slider::Slider, svg::Svg,
- text_input::TextInput,
+ radio::Radio, rule::Rule, scrollable::Scrollable, slider::Slider,
+ svg::Svg, text_input::TextInput,
};
#[cfg(any(feature = "canvas", feature = "glow_canvas"))]
diff --git a/style/src/lib.rs b/style/src/lib.rs
index 8e402bb1..3d23d990 100644
--- a/style/src/lib.rs
+++ b/style/src/lib.rs
@@ -11,6 +11,7 @@ pub mod menu;
pub mod pick_list;
pub mod progress_bar;
pub mod radio;
+pub mod rule;
pub mod scrollable;
pub mod slider;
pub mod text_input;
diff --git a/style/src/rule.rs b/style/src/rule.rs
new file mode 100644
index 00000000..dbd72d41
--- /dev/null
+++ b/style/src/rule.rs
@@ -0,0 +1,51 @@
+//! Display a horizontal or vertical rule for dividing content.
+
+use iced_core::Color;
+
+/// The appearance of a rule.
+#[derive(Debug, Clone, Copy)]
+pub struct Style {
+ /// The color of the rule.
+ pub color: Color,
+ /// The width (thickness) of the rule line.
+ pub width: u16,
+ /// The radius of the rectangle corners.
+ pub radius: u16,
+ /// The percent from [0, 100] of the filled space the rule
+ /// will be drawn.
+ pub fill_percent: u16,
+}
+
+/// A set of rules that dictate the style of a rule.
+pub trait StyleSheet {
+ /// Produces the style of a rule.
+ fn style(&self) -> Style;
+}
+
+struct Default;
+
+impl StyleSheet for Default {
+ fn style(&self) -> Style {
+ Style {
+ color: [0.6, 0.6, 0.6, 0.49].into(),
+ width: 1,
+ radius: 0,
+ fill_percent: 90,
+ }
+ }
+}
+
+impl std::default::Default for Box<dyn StyleSheet> {
+ fn default() -> Self {
+ Box::new(Default)
+ }
+}
+
+impl<T> From<T> for Box<dyn StyleSheet>
+where
+ T: 'static + StyleSheet,
+{
+ fn from(style: T) -> Self {
+ Box::new(style)
+ }
+}
diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs
index ced64332..1dae26f5 100644
--- a/wgpu/src/widget.rs
+++ b/wgpu/src/widget.rs
@@ -16,6 +16,7 @@ pub mod pane_grid;
pub mod pick_list;
pub mod progress_bar;
pub mod radio;
+pub mod rule;
pub mod scrollable;
pub mod slider;
pub mod text_input;
@@ -35,6 +36,8 @@ pub use progress_bar::ProgressBar;
#[doc(no_inline)]
pub use radio::Radio;
#[doc(no_inline)]
+pub use rule::Rule;
+#[doc(no_inline)]
pub use scrollable::Scrollable;
#[doc(no_inline)]
pub use slider::Slider;
diff --git a/wgpu/src/widget/rule.rs b/wgpu/src/widget/rule.rs
new file mode 100644
index 00000000..630a6f33
--- /dev/null
+++ b/wgpu/src/widget/rule.rs
@@ -0,0 +1,10 @@
+//! Display a horizontal or vertical rule for dividing content.
+
+use crate::Renderer;
+
+pub use iced_graphics::rule::{Style, StyleSheet};
+
+/// Display a horizontal or vertical rule for dividing content.
+///
+/// This is an alias of an `iced_native` rule with an `iced_wgpu::Renderer`.
+pub type Rule = iced_native::Rule<Renderer>;