summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-01-07 02:54:54 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-01-07 02:54:54 +0100
commited30b487d649ffa0967ab8bfd66f4820ee2150fd (patch)
treead526010370f4e17f6131a28dd77a91a2a3660c4
parent387fc0be26ccd1adc66c1dc80420f9b08d0c023a (diff)
downloadiced-ed30b487d649ffa0967ab8bfd66f4820ee2150fd.tar.gz
iced-ed30b487d649ffa0967ab8bfd66f4820ee2150fd.tar.bz2
iced-ed30b487d649ffa0967ab8bfd66f4820ee2150fd.zip
Implement styling for `Checkbox`
-rw-r--r--examples/styling.rs81
-rw-r--r--native/src/renderer/null.rs3
-rw-r--r--native/src/widget/checkbox.rs41
-rw-r--r--src/native.rs4
-rw-r--r--style/src/checkbox.rs55
-rw-r--r--style/src/lib.rs1
-rw-r--r--wgpu/src/renderer/widget/checkbox.rs31
-rw-r--r--wgpu/src/widget.rs1
-rw-r--r--wgpu/src/widget/checkbox.rs9
9 files changed, 180 insertions, 46 deletions
diff --git a/examples/styling.rs b/examples/styling.rs
index b5600e85..97095cff 100644
--- a/examples/styling.rs
+++ b/examples/styling.rs
@@ -1,7 +1,7 @@
use iced::{
- button, scrollable, slider, text_input, Button, Column, Container, Element,
- Length, ProgressBar, Radio, Row, Sandbox, Scrollable, Settings, Slider,
- Text, TextInput,
+ button, scrollable, slider, text_input, Button, Checkbox, Column,
+ Container, Element, Length, ProgressBar, Radio, Row, Sandbox, Scrollable,
+ Settings, Slider, Text, TextInput,
};
pub fn main() {
@@ -17,6 +17,7 @@ struct Styling {
button: button::State,
slider: slider::State,
slider_value: f32,
+ debug: bool,
}
#[derive(Debug, Clone)]
@@ -25,6 +26,7 @@ enum Message {
InputChanged(String),
ButtonPressed,
SliderChanged(f32),
+ DebugToggled(bool),
}
impl Sandbox for Styling {
@@ -44,6 +46,7 @@ impl Sandbox for Styling {
Message::InputChanged(value) => self.input_value = value,
Message::ButtonPressed => (),
Message::SliderChanged(value) => self.slider_value = value,
+ Message::DebugToggled(debug) => self.debug = debug,
}
}
@@ -89,18 +92,34 @@ impl Sandbox for Styling {
let progress_bar =
ProgressBar::new(0.0..=100.0, self.slider_value).style(self.theme);
- let content = Column::new()
+ let checkbox = Checkbox::new(
+ self.debug,
+ "Enable layout debugger",
+ Message::DebugToggled,
+ )
+ .style(self.theme);
+
+ let content: Element<_> = Column::new()
.spacing(20)
.padding(20)
.max_width(600)
.push(choose_theme)
.push(Row::new().spacing(10).push(text_input).push(button))
.push(slider)
- .push(progress_bar);
-
- let scrollable = Scrollable::new(&mut self.scroll)
- .style(self.theme)
- .push(Container::new(content).width(Length::Fill).center_x());
+ .push(progress_bar)
+ .push(checkbox)
+ .into();
+
+ let scrollable =
+ Scrollable::new(&mut self.scroll).style(self.theme).push(
+ Container::new(if self.debug {
+ content.explain(self.theme.debug_color())
+ } else {
+ content
+ })
+ .width(Length::Fill)
+ .center_x(),
+ );
Container::new(scrollable)
.width(Length::Fill)
@@ -113,7 +132,8 @@ impl Sandbox for Styling {
mod style {
use iced::{
- button, container, progress_bar, radio, scrollable, slider, text_input,
+ button, checkbox, container, progress_bar, radio, scrollable, slider,
+ text_input, Color,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -124,6 +144,13 @@ mod style {
impl Theme {
pub const ALL: [Theme; 2] = [Theme::Light, Theme::Dark];
+
+ pub fn debug_color(&self) -> Color {
+ match self {
+ Theme::Light => Color::BLACK,
+ Theme::Dark => Color::WHITE,
+ }
+ }
}
impl Default for Theme {
@@ -195,6 +222,15 @@ mod style {
}
}
+ impl From<Theme> for Box<dyn checkbox::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Checkbox.into(),
+ }
+ }
+ }
+
mod light {
use iced::{button, Background, Color, Vector};
@@ -225,8 +261,8 @@ mod style {
mod dark {
use iced::{
- button, container, progress_bar, radio, scrollable, slider,
- text_input, Background, Color,
+ button, checkbox, container, progress_bar, radio, scrollable,
+ slider, text_input, Background, Color,
};
const SURFACE: Color = Color::from_rgb(
@@ -432,5 +468,26 @@ mod style {
}
}
}
+
+ pub struct Checkbox;
+
+ impl checkbox::StyleSheet for Checkbox {
+ fn active(&self) -> checkbox::Style {
+ checkbox::Style {
+ background: Background::Color(SURFACE),
+ checkmark_color: Color::WHITE,
+ border_radius: 2,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ }
+ }
+
+ fn hovered(&self) -> checkbox::Style {
+ checkbox::Style {
+ background: Background::Color(Color { a: 0.5, ..SURFACE }),
+ ..self.active()
+ }
+ }
+ }
}
}
diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs
index 4fb4f2d5..bd5bba23 100644
--- a/native/src/renderer/null.rs
+++ b/native/src/renderer/null.rs
@@ -170,6 +170,8 @@ impl radio::Renderer for Null {
}
impl checkbox::Renderer for Null {
+ type Style = ();
+
fn default_size(&self) -> u32 {
20
}
@@ -180,6 +182,7 @@ impl checkbox::Renderer for Null {
_is_checked: bool,
_is_mouse_over: bool,
_label: Self::Output,
+ _style: &Self::Style,
) {
}
}
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index 87a7f629..13a59410 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -3,7 +3,7 @@ use std::hash::Hash;
use crate::{
input::{mouse, ButtonState},
- layout, row, text, Align, Clipboard, Color, Element, Event, Font, Hasher,
+ layout, row, text, Align, Clipboard, Element, Event, Font, Hasher,
HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
VerticalAlignment, Widget,
};
@@ -13,7 +13,7 @@ use crate::{
/// # Example
///
/// ```
-/// # use iced_native::Checkbox;
+/// # type Checkbox<Message> = iced_native::Checkbox<Message, iced_native::renderer::Null>;
/// #
/// pub enum Message {
/// CheckboxToggled(bool),
@@ -26,15 +26,15 @@ use crate::{
///
/// ![Checkbox drawn by `iced_wgpu`](https://github.com/hecrj/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/checkbox.png?raw=true)
#[allow(missing_debug_implementations)]
-pub struct Checkbox<Message> {
+pub struct Checkbox<Message, Renderer: self::Renderer> {
is_checked: bool,
on_toggle: Box<dyn Fn(bool) -> Message>,
label: String,
- label_color: Option<Color>,
width: Length,
+ style: Renderer::Style,
}
-impl<Message> Checkbox<Message> {
+impl<Message, Renderer: self::Renderer> Checkbox<Message, Renderer> {
/// Creates a new [`Checkbox`].
///
/// It expects:
@@ -53,29 +53,30 @@ impl<Message> Checkbox<Message> {
is_checked,
on_toggle: Box::new(f),
label: String::from(label),
- label_color: None,
width: Length::Fill,
+ style: Renderer::Style::default(),
}
}
- /// Sets the color of the label of the [`Checkbox`].
+ /// Sets the width of the [`Checkbox`].
///
/// [`Checkbox`]: struct.Checkbox.html
- pub fn label_color<C: Into<Color>>(mut self, color: C) -> Self {
- self.label_color = Some(color.into());
+ pub fn width(mut self, width: Length) -> Self {
+ self.width = width;
self
}
- /// Sets the width of the [`Checkbox`].
+ /// Sets the style of the [`Checkbox`].
///
/// [`Checkbox`]: struct.Checkbox.html
- pub fn width(mut self, width: Length) -> Self {
- self.width = width;
+ pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self {
+ self.style = style.into();
self
}
}
-impl<Message, Renderer> Widget<Message, Renderer> for Checkbox<Message>
+impl<Message, Renderer> Widget<Message, Renderer>
+ for Checkbox<Message, Renderer>
where
Renderer: self::Renderer + text::Renderer + row::Renderer,
{
@@ -152,7 +153,7 @@ where
&self.label,
text::Renderer::default_size(renderer),
Font::Default,
- self.label_color,
+ None,
HorizontalAlignment::Left,
VerticalAlignment::Center,
);
@@ -165,6 +166,7 @@ where
self.is_checked,
is_mouse_over,
label,
+ &self.style,
)
}
@@ -181,6 +183,8 @@ where
/// [`Checkbox`]: struct.Checkbox.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer {
+ type Style: Default;
+
/// Returns the default size of a [`Checkbox`].
///
/// [`Checkbox`]: struct.Checkbox.html
@@ -201,16 +205,19 @@ pub trait Renderer: crate::Renderer {
is_checked: bool,
is_mouse_over: bool,
label: Self::Output,
+ style: &Self::Style,
) -> Self::Output;
}
-impl<'a, Message, Renderer> From<Checkbox<Message>>
+impl<'a, Message, Renderer> From<Checkbox<Message, Renderer>>
for Element<'a, Message, Renderer>
where
- Renderer: self::Renderer + text::Renderer + row::Renderer,
+ Renderer: 'static + self::Renderer + text::Renderer + row::Renderer,
Message: 'static,
{
- fn from(checkbox: Checkbox<Message>) -> Element<'a, Message, Renderer> {
+ fn from(
+ checkbox: Checkbox<Message, Renderer>,
+ ) -> Element<'a, Message, Renderer> {
Element::new(checkbox)
}
}
diff --git a/src/native.rs b/src/native.rs
index 2f2182ff..35441a3e 100644
--- a/src/native.rs
+++ b/src/native.rs
@@ -34,11 +34,11 @@ pub mod widget {
pub use iced_winit::svg::{Handle, Svg};
}
- pub use iced_winit::{Checkbox, Text};
+ pub use iced_winit::Text;
#[doc(no_inline)]
pub use {
- button::Button, container::Container, image::Image,
+ button::Button, checkbox::Checkbox, container::Container, image::Image,
progress_bar::ProgressBar, radio::Radio, scrollable::Scrollable,
slider::Slider, svg::Svg, text_input::TextInput,
};
diff --git a/style/src/checkbox.rs b/style/src/checkbox.rs
new file mode 100644
index 00000000..e84dfd18
--- /dev/null
+++ b/style/src/checkbox.rs
@@ -0,0 +1,55 @@
+//! Show toggle controls using checkboxes.
+use iced_core::{Background, Color};
+
+/// The appearance of a checkbox.
+#[derive(Debug)]
+pub struct Style {
+ pub background: Background,
+ pub checkmark_color: Color,
+ pub border_radius: u16,
+ pub border_width: u16,
+ pub border_color: Color,
+}
+
+/// A set of rules that dictate the style of a checkbox.
+pub trait StyleSheet {
+ fn active(&self) -> Style;
+
+ fn hovered(&self) -> Style;
+}
+
+struct Default;
+
+impl StyleSheet for Default {
+ fn active(&self) -> Style {
+ Style {
+ background: Background::Color(Color::from_rgb(0.95, 0.95, 0.95)),
+ checkmark_color: Color::from_rgb(0.3, 0.3, 0.3),
+ border_radius: 5,
+ border_width: 1,
+ border_color: Color::from_rgb(0.6, 0.6, 0.6),
+ }
+ }
+
+ fn hovered(&self) -> Style {
+ Style {
+ background: Background::Color(Color::from_rgb(0.90, 0.90, 0.90)),
+ ..self.active()
+ }
+ }
+}
+
+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/style/src/lib.rs b/style/src/lib.rs
index 991e0644..e0f56594 100644
--- a/style/src/lib.rs
+++ b/style/src/lib.rs
@@ -1,4 +1,5 @@
pub mod button;
+pub mod checkbox;
pub mod container;
pub mod progress_bar;
pub mod radio;
diff --git a/wgpu/src/renderer/widget/checkbox.rs b/wgpu/src/renderer/widget/checkbox.rs
index 1ed27ff7..cd90be5e 100644
--- a/wgpu/src/renderer/widget/checkbox.rs
+++ b/wgpu/src/renderer/widget/checkbox.rs
@@ -1,12 +1,13 @@
-use crate::{Primitive, Renderer};
+use crate::{checkbox::StyleSheet, Primitive, Renderer};
use iced_native::{
- checkbox, Background, Color, HorizontalAlignment, MouseCursor, Rectangle,
- VerticalAlignment,
+ checkbox, HorizontalAlignment, MouseCursor, Rectangle, VerticalAlignment,
};
const SIZE: f32 = 28.0;
impl checkbox::Renderer for Renderer {
+ type Style = Box<dyn StyleSheet>;
+
fn default_size(&self) -> u32 {
SIZE as u32
}
@@ -17,20 +18,20 @@ impl checkbox::Renderer for Renderer {
is_checked: bool,
is_mouse_over: bool,
(label, _): Self::Output,
+ style_sheet: &Self::Style,
) -> Self::Output {
+ let style = if is_mouse_over {
+ style_sheet.hovered()
+ } else {
+ style_sheet.active()
+ };
+
let checkbox = Primitive::Quad {
bounds,
- background: Background::Color(
- if is_mouse_over {
- [0.90, 0.90, 0.90]
- } else {
- [0.95, 0.95, 0.95]
- }
- .into(),
- ),
- border_radius: 5,
- border_width: 1,
- border_color: Color::from_rgb(0.6, 0.6, 0.6),
+ background: style.background,
+ border_radius: style.border_radius,
+ border_width: style.border_width,
+ border_color: style.border_color,
};
(
@@ -41,7 +42,7 @@ impl checkbox::Renderer for Renderer {
font: crate::text::BUILTIN_ICONS,
size: bounds.height * 0.7,
bounds: bounds,
- color: [0.3, 0.3, 0.3].into(),
+ color: style.checkmark_color,
horizontal_alignment: HorizontalAlignment::Center,
vertical_alignment: VerticalAlignment::Center,
};
diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs
index 991e0644..e0f56594 100644
--- a/wgpu/src/widget.rs
+++ b/wgpu/src/widget.rs
@@ -1,4 +1,5 @@
pub mod button;
+pub mod checkbox;
pub mod container;
pub mod progress_bar;
pub mod radio;
diff --git a/wgpu/src/widget/checkbox.rs b/wgpu/src/widget/checkbox.rs
new file mode 100644
index 00000000..da0d7a84
--- /dev/null
+++ b/wgpu/src/widget/checkbox.rs
@@ -0,0 +1,9 @@
+//! Show toggle controls using checkboxes.
+use crate::Renderer;
+
+pub use iced_style::checkbox::{Style, StyleSheet};
+
+/// A box that can be checked.
+///
+/// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`.
+pub type Checkbox<Message> = iced_native::Checkbox<Message, Renderer>;