From c7b170da6d180f80e539910cccb543720fa3713c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 29 Dec 2019 10:57:01 +0100 Subject: Draft `Style` and `StyleSheet` for `Button` --- wgpu/src/lib.rs | 14 +++-- wgpu/src/renderer.rs | 4 +- wgpu/src/renderer/widget/button.rs | 28 ++++----- wgpu/src/renderer/widget/button/style.rs | 1 + wgpu/src/widget.rs | 1 + wgpu/src/widget/button.rs | 97 ++++++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 wgpu/src/renderer/widget/button/style.rs create mode 100644 wgpu/src/widget.rs create mode 100644 wgpu/src/widget/button.rs (limited to 'wgpu') diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 9f9ed8db..55f93546 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -19,11 +19,13 @@ //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs //! [WebGPU API]: https://gpuweb.github.io/gpuweb/ //! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph -#![deny(missing_docs)] +//#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![deny(unsafe_code)] #![deny(rust_2018_idioms)] +pub mod widget; + mod image; mod primitive; mod quad; @@ -31,9 +33,11 @@ mod renderer; mod text; mod transformation; -pub(crate) use crate::image::Image; -pub(crate) use quad::Quad; -pub(crate) use transformation::Transformation; - pub use primitive::Primitive; pub use renderer::{Renderer, Target}; +#[doc(no_inline)] +pub use widget::*; + +pub(crate) use self::image::Image; +pub(crate) use quad::Quad; +pub(crate) use transformation::Transformation; diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 365ef1ef..4984d4fe 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -22,7 +22,7 @@ pub struct Renderer { device: Device, queue: Queue, quad_pipeline: quad::Pipeline, - image_pipeline: crate::image::Pipeline, + image_pipeline: image::Pipeline, text_pipeline: text::Pipeline, } @@ -63,7 +63,7 @@ impl Renderer { let text_pipeline = text::Pipeline::new(&mut device); let quad_pipeline = quad::Pipeline::new(&mut device); - let image_pipeline = crate::image::Pipeline::new(&mut device); + let image_pipeline = image::Pipeline::new(&mut device); Self { device, diff --git a/wgpu/src/renderer/widget/button.rs b/wgpu/src/renderer/widget/button.rs index 86963053..f3817374 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/wgpu/src/renderer/widget/button.rs @@ -1,50 +1,50 @@ -use crate::{Primitive, Renderer}; -use iced_native::{button, Background, MouseCursor, Point, Rectangle}; +use crate::{button::StyleSheet, Primitive, Renderer}; +use iced_native::{Background, MouseCursor, Point, Rectangle}; + +impl iced_native::button::Renderer for Renderer { + type Style = Box; -impl button::Renderer for Renderer { fn draw( &mut self, bounds: Rectangle, cursor_position: Point, is_pressed: bool, - background: Option, - border_radius: u16, + style: &Box, (content, _): Self::Output, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); // TODO: Render proper shadows - // TODO: Make hovering and pressed styles configurable - let shadow_offset = if is_mouse_over { + let styling = if is_mouse_over { if is_pressed { - 0.0 + style.pressed() } else { - 2.0 + style.hovered() } } else { - 1.0 + style.active() }; ( - match background { + match styling.background { None => content, Some(background) => Primitive::Group { primitives: vec![ Primitive::Quad { bounds: Rectangle { x: bounds.x + 1.0, - y: bounds.y + shadow_offset, + y: bounds.y + styling.shadow_offset, ..bounds }, background: Background::Color( [0.0, 0.0, 0.0, 0.5].into(), ), - border_radius, + border_radius: styling.border_radius, }, Primitive::Quad { bounds, background, - border_radius, + border_radius: styling.border_radius, }, content, ], diff --git a/wgpu/src/renderer/widget/button/style.rs b/wgpu/src/renderer/widget/button/style.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/wgpu/src/renderer/widget/button/style.rs @@ -0,0 +1 @@ + diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs new file mode 100644 index 00000000..aa200ca2 --- /dev/null +++ b/wgpu/src/widget.rs @@ -0,0 +1 @@ +pub mod button; diff --git a/wgpu/src/widget/button.rs b/wgpu/src/widget/button.rs new file mode 100644 index 00000000..7827f8b2 --- /dev/null +++ b/wgpu/src/widget/button.rs @@ -0,0 +1,97 @@ +//! Allow your users to perform actions by pressing a button. +//! +//! A [`Button`] has some local [`State`]. +//! +//! [`Button`]: type.Button.html +//! [`State`]: struct.State.html +use crate::Renderer; +use iced_native::Background; + +pub use iced_native::button::State; + +/// A widget that produces a message when clicked. +/// +/// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`. +pub type Button<'a, Message> = iced_native::Button<'a, Message, Renderer>; + +#[derive(Debug)] +pub struct Style { + pub shadow_offset: f32, + pub background: Option, + pub border_radius: u16, +} + +pub trait StyleSheet { + fn active(&self) -> Style; + + fn hovered(&self) -> Style { + let active = self.active(); + + Style { + shadow_offset: active.shadow_offset + 1.0, + ..active + } + } + + fn pressed(&self) -> Style { + Style { + shadow_offset: 0.0, + ..self.active() + } + } + + fn disabled(&self) -> Style { + self.active() + } +} + +struct Default; + +impl StyleSheet for Default { + fn active(&self) -> Style { + Style { + shadow_offset: 1.0, + background: Some(Background::Color([0.5, 0.5, 0.5].into())), + border_radius: 5, + } + } + + fn hovered(&self) -> Style { + Style { + shadow_offset: 2.0, + background: Some(Background::Color([0.5, 0.5, 0.5].into())), + border_radius: 5, + } + } + + fn pressed(&self) -> Style { + Style { + shadow_offset: 0.0, + background: Some(Background::Color([0.5, 0.5, 0.5].into())), + border_radius: 5, + } + } + + fn disabled(&self) -> Style { + Style { + shadow_offset: 0.0, + background: Some(Background::Color([0.7, 0.7, 0.7].into())), + border_radius: 5, + } + } +} + +impl std::default::Default for Box { + fn default() -> Self { + Box::new(Default) + } +} + +impl From for Box +where + T: 'static + StyleSheet, +{ + fn from(style: T) -> Self { + Box::new(style) + } +} -- cgit From f74ab463d44dd0bb025b0cea466d2861576253dd Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 29 Dec 2019 12:29:47 +0100 Subject: Add `background_color` to `Settings` --- wgpu/src/renderer.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 4984d4fe..47b258ed 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -76,6 +76,7 @@ impl Renderer { fn draw>( &mut self, + clear_color: Color, (primitive, mouse_cursor): &(Primitive, MouseCursor), overlay: &[T], target: &mut Target, @@ -97,11 +98,15 @@ impl Renderer { resolve_target: None, load_op: wgpu::LoadOp::Clear, store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 1.0, - g: 1.0, - b: 1.0, - a: 1.0, + clear_color: { + let [r, g, b, a] = clear_color.into_linear(); + + wgpu::Color { + r: f64::from(r), + g: f64::from(g), + b: f64::from(b), + a: f64::from(a), + } }, }], depth_stencil_attachment: None, @@ -428,11 +433,12 @@ impl Windowed for Renderer { fn draw>( &mut self, + clear_color: Color, output: &Self::Output, overlay: &[T], target: &mut Target, ) -> MouseCursor { - self.draw(output, overlay, target) + self.draw(clear_color, output, overlay, target) } } -- cgit From 8caa66be2708b1c83e20d905d69902c2567c4692 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 30 Dec 2019 12:14:26 +0100 Subject: Add `Renderer::Defaults` and style inheritance --- wgpu/src/defaults.rs | 27 +++++++++++++++++++ wgpu/src/lib.rs | 2 ++ wgpu/src/renderer.rs | 9 +++++-- wgpu/src/renderer/widget/button.rs | 27 +++++++++++++++---- wgpu/src/renderer/widget/button/style.rs | 1 - wgpu/src/renderer/widget/column.rs | 3 ++- wgpu/src/renderer/widget/row.rs | 3 ++- wgpu/src/renderer/widget/text.rs | 3 ++- wgpu/src/widget/button.rs | 45 ++++++++++++++------------------ 9 files changed, 83 insertions(+), 37 deletions(-) create mode 100644 wgpu/src/defaults.rs delete mode 100644 wgpu/src/renderer/widget/button/style.rs (limited to 'wgpu') diff --git a/wgpu/src/defaults.rs b/wgpu/src/defaults.rs new file mode 100644 index 00000000..8de8258b --- /dev/null +++ b/wgpu/src/defaults.rs @@ -0,0 +1,27 @@ +use iced_native::Color; + +#[derive(Debug, Clone, Copy)] +pub struct Defaults { + pub text: Text, +} + +impl Default for Defaults { + fn default() -> Defaults { + Defaults { + text: Text::default(), + } + } +} + +#[derive(Debug, Clone, Copy)] +pub struct Text { + pub color: Color, +} + +impl Default for Text { + fn default() -> Text { + Text { + color: Color::BLACK, + } + } +} diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 55f93546..786b6872 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -24,6 +24,7 @@ #![deny(unused_results)] #![deny(unsafe_code)] #![deny(rust_2018_idioms)] +pub mod defaults; pub mod widget; mod image; @@ -33,6 +34,7 @@ mod renderer; mod text; mod transformation; +pub use defaults::Defaults; pub use primitive::Primitive; pub use renderer::{Renderer, Target}; #[doc(no_inline)] diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 47b258ed..1b143d90 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -1,4 +1,6 @@ -use crate::{image, quad, text, Image, Primitive, Quad, Transformation}; +use crate::{ + image, quad, text, Defaults, Image, Primitive, Quad, Transformation, +}; use iced_native::{ renderer::{Debugger, Windowed}, Background, Color, Layout, MouseCursor, Point, Rectangle, Vector, Widget, @@ -411,6 +413,7 @@ impl Renderer { impl iced_native::Renderer for Renderer { type Output = (Primitive, MouseCursor); + type Defaults = Defaults; fn layout<'a, Message>( &mut self, @@ -445,13 +448,15 @@ impl Windowed for Renderer { impl Debugger for Renderer { fn explain( &mut self, + defaults: &Defaults, widget: &dyn Widget, layout: Layout<'_>, cursor_position: Point, color: Color, ) -> Self::Output { let mut primitives = Vec::new(); - let (primitive, cursor) = widget.draw(self, layout, cursor_position); + let (primitive, cursor) = + widget.draw(self, defaults, layout, cursor_position); explain_layout(layout, color, &mut primitives); primitives.push(primitive); diff --git a/wgpu/src/renderer/widget/button.rs b/wgpu/src/renderer/widget/button.rs index f3817374..4fbd90d7 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/wgpu/src/renderer/widget/button.rs @@ -1,21 +1,26 @@ -use crate::{button::StyleSheet, Primitive, Renderer}; -use iced_native::{Background, MouseCursor, Point, Rectangle}; +use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer}; +use iced_native::{Background, Element, Layout, MouseCursor, Point, Rectangle}; impl iced_native::button::Renderer for Renderer { type Style = Box; - fn draw( + fn draw( &mut self, + defaults: &Defaults, bounds: Rectangle, cursor_position: Point, + is_disabled: bool, is_pressed: bool, style: &Box, - (content, _): Self::Output, + content: &Element<'_, Message, Self>, + content_layout: Layout<'_>, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); // TODO: Render proper shadows - let styling = if is_mouse_over { + let styling = if is_disabled { + style.disabled() + } else if is_mouse_over { if is_pressed { style.pressed() } else { @@ -25,6 +30,18 @@ impl iced_native::button::Renderer for Renderer { style.active() }; + let (content, _) = content.draw( + self, + &Defaults { + text: defaults::Text { + color: styling.text_color, + }, + ..*defaults + }, + content_layout, + cursor_position, + ); + ( match styling.background { None => content, diff --git a/wgpu/src/renderer/widget/button/style.rs b/wgpu/src/renderer/widget/button/style.rs deleted file mode 100644 index 8b137891..00000000 --- a/wgpu/src/renderer/widget/button/style.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/wgpu/src/renderer/widget/column.rs b/wgpu/src/renderer/widget/column.rs index 6c31af90..95a7463a 100644 --- a/wgpu/src/renderer/widget/column.rs +++ b/wgpu/src/renderer/widget/column.rs @@ -4,6 +4,7 @@ use iced_native::{column, Element, Layout, MouseCursor, Point}; impl column::Renderer for Renderer { fn draw( &mut self, + defaults: &Self::Defaults, content: &[Element<'_, Message, Self>], layout: Layout<'_>, cursor_position: Point, @@ -17,7 +18,7 @@ impl column::Renderer for Renderer { .zip(layout.children()) .map(|(child, layout)| { let (primitive, new_mouse_cursor) = - child.draw(self, layout, cursor_position); + child.draw(self, defaults, layout, cursor_position); if new_mouse_cursor > mouse_cursor { mouse_cursor = new_mouse_cursor; diff --git a/wgpu/src/renderer/widget/row.rs b/wgpu/src/renderer/widget/row.rs index f082dc61..bd9f1a04 100644 --- a/wgpu/src/renderer/widget/row.rs +++ b/wgpu/src/renderer/widget/row.rs @@ -4,6 +4,7 @@ use iced_native::{row, Element, Layout, MouseCursor, Point}; impl row::Renderer for Renderer { fn draw( &mut self, + defaults: &Self::Defaults, children: &[Element<'_, Message, Self>], layout: Layout<'_>, cursor_position: Point, @@ -17,7 +18,7 @@ impl row::Renderer for Renderer { .zip(layout.children()) .map(|(child, layout)| { let (primitive, new_mouse_cursor) = - child.draw(self, layout, cursor_position); + child.draw(self, defaults, layout, cursor_position); if new_mouse_cursor > mouse_cursor { mouse_cursor = new_mouse_cursor; diff --git a/wgpu/src/renderer/widget/text.rs b/wgpu/src/renderer/widget/text.rs index 08a162ba..d61c5523 100644 --- a/wgpu/src/renderer/widget/text.rs +++ b/wgpu/src/renderer/widget/text.rs @@ -27,6 +27,7 @@ impl text::Renderer for Renderer { fn draw( &mut self, + defaults: &Self::Defaults, bounds: Rectangle, content: &str, size: u16, @@ -40,7 +41,7 @@ impl text::Renderer for Renderer { content: content.to_string(), size: f32::from(size), bounds, - color: color.unwrap_or(Color::BLACK), + color: color.unwrap_or(defaults.text.color), font, horizontal_alignment, vertical_alignment, diff --git a/wgpu/src/widget/button.rs b/wgpu/src/widget/button.rs index 7827f8b2..2c4e174f 100644 --- a/wgpu/src/widget/button.rs +++ b/wgpu/src/widget/button.rs @@ -5,7 +5,7 @@ //! [`Button`]: type.Button.html //! [`State`]: struct.State.html use crate::Renderer; -use iced_native::Background; +use iced_native::{Background, Color}; pub use iced_native::button::State; @@ -19,6 +19,7 @@ pub struct Style { pub shadow_offset: f32, pub background: Option, pub border_radius: u16, + pub text_color: Color, } pub trait StyleSheet { @@ -41,7 +42,22 @@ pub trait StyleSheet { } fn disabled(&self) -> Style { - self.active() + let active = self.active(); + + Style { + shadow_offset: 0.0, + background: active.background.map(|background| match background { + Background::Color(color) => Background::Color(Color { + a: color.a * 0.5, + ..color + }), + }), + text_color: Color { + a: active.text_color.a * 0.5, + ..active.text_color + }, + ..active + } } } @@ -53,30 +69,7 @@ impl StyleSheet for Default { shadow_offset: 1.0, background: Some(Background::Color([0.5, 0.5, 0.5].into())), border_radius: 5, - } - } - - fn hovered(&self) -> Style { - Style { - shadow_offset: 2.0, - background: Some(Background::Color([0.5, 0.5, 0.5].into())), - border_radius: 5, - } - } - - fn pressed(&self) -> Style { - Style { - shadow_offset: 0.0, - background: Some(Background::Color([0.5, 0.5, 0.5].into())), - border_radius: 5, - } - } - - fn disabled(&self) -> Style { - Style { - shadow_offset: 0.0, - background: Some(Background::Color([0.7, 0.7, 0.7].into())), - border_radius: 5, + text_color: Color::BLACK, } } } -- cgit From fb9cc0262b30a953e8188897b74abb5106ea1fd8 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 31 Dec 2019 11:36:54 +0100 Subject: Draft basic styling for `Container` --- wgpu/src/renderer/widget.rs | 1 + wgpu/src/renderer/widget/container.rs | 46 +++++++++++++++++++++++++++++++++++ wgpu/src/widget.rs | 1 + wgpu/src/widget/container.rs | 37 ++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 wgpu/src/renderer/widget/container.rs create mode 100644 wgpu/src/widget/container.rs (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget.rs b/wgpu/src/renderer/widget.rs index 91f107e8..8cf79cb0 100644 --- a/wgpu/src/renderer/widget.rs +++ b/wgpu/src/renderer/widget.rs @@ -1,6 +1,7 @@ mod button; mod checkbox; mod column; +mod container; mod image; mod radio; mod row; diff --git a/wgpu/src/renderer/widget/container.rs b/wgpu/src/renderer/widget/container.rs new file mode 100644 index 00000000..29c709f8 --- /dev/null +++ b/wgpu/src/renderer/widget/container.rs @@ -0,0 +1,46 @@ +use crate::{container, defaults, Defaults, Primitive, Renderer}; +use iced_native::{Element, Layout, Point, Rectangle}; + +impl iced_native::container::Renderer for Renderer { + type Style = Box; + + fn draw( + &mut self, + defaults: &Defaults, + bounds: Rectangle, + cursor_position: Point, + style_sheet: &Self::Style, + content: &Element<'_, Message, Self>, + content_layout: Layout<'_>, + ) -> Self::Output { + let style = style_sheet.style(); + + let defaults = Defaults { + text: defaults::Text { + color: style.text_color.unwrap_or(defaults.text.color), + }, + ..*defaults + }; + + let (content, mouse_cursor) = + content.draw(self, &defaults, content_layout, cursor_position); + + match style.background { + Some(background) => { + let quad = Primitive::Quad { + bounds, + background, + border_radius: style.border_radius, + }; + + ( + Primitive::Group { + primitives: vec![quad, content], + }, + mouse_cursor, + ) + } + None => (content, mouse_cursor), + } + } +} diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index aa200ca2..c6f34301 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1 +1,2 @@ pub mod button; +pub mod container; diff --git a/wgpu/src/widget/container.rs b/wgpu/src/widget/container.rs new file mode 100644 index 00000000..1fc0ec98 --- /dev/null +++ b/wgpu/src/widget/container.rs @@ -0,0 +1,37 @@ +use iced_native::{Background, Color}; + +#[derive(Debug, Clone, Copy)] +pub struct Style { + pub text_color: Option, + pub background: Option, + pub border_radius: u16, +} + +pub trait StyleSheet { + fn style(&self) -> Style { + Style { + text_color: None, + background: None, + border_radius: 0, + } + } +} + +struct Default; + +impl StyleSheet for Default {} + +impl std::default::Default for Box { + fn default() -> Self { + Box::new(Default) + } +} + +impl From for Box +where + T: 'static + StyleSheet, +{ + fn from(style: T) -> Self { + Box::new(style) + } +} -- cgit From 9ab7c47dc7d834ee73bc068f9f34eea4d6946436 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 31 Dec 2019 21:35:42 +0100 Subject: Add `border_width` and `border_color` to `Quad` --- wgpu/src/primitive.rs | 4 +++ wgpu/src/quad.rs | 17 ++++++++-- wgpu/src/renderer.rs | 9 +++-- wgpu/src/renderer/widget/button.rs | 8 ++++- wgpu/src/renderer/widget/checkbox.rs | 44 ++++++++++--------------- wgpu/src/renderer/widget/container.rs | 4 ++- wgpu/src/renderer/widget/radio.rs | 46 +++++++++++--------------- wgpu/src/renderer/widget/scrollable.rs | 8 ++++- wgpu/src/renderer/widget/slider.rs | 58 +++++++++++++++------------------ wgpu/src/renderer/widget/text_input.rs | 33 +++++++------------ wgpu/src/shader/quad.frag | 51 ++++++++++++++++++++++++----- wgpu/src/shader/quad.frag.spv | Bin 3044 -> 4212 bytes wgpu/src/shader/quad.vert | 14 +++++--- wgpu/src/shader/quad.vert.spv | Bin 3020 -> 3372 bytes 14 files changed, 169 insertions(+), 127 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 6c61f800..f4609151 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -38,6 +38,10 @@ pub enum Primitive { background: Background, /// The border radius of the quad border_radius: u16, + /// The border width of the quad + border_width: u16, + /// The border color of the quad + border_color: Color, }, /// An image primitive Image { diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index c292dec3..fe3276a3 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -125,9 +125,19 @@ impl Pipeline { }, wgpu::VertexAttributeDescriptor { shader_location: 4, - format: wgpu::VertexFormat::Float, + format: wgpu::VertexFormat::Float4, offset: 4 * (2 + 2 + 4), }, + wgpu::VertexAttributeDescriptor { + shader_location: 5, + format: wgpu::VertexFormat::Float, + offset: 4 * (2 + 2 + 4 + 4), + }, + wgpu::VertexAttributeDescriptor { + shader_location: 6, + format: wgpu::VertexFormat::Float, + offset: 4 * (2 + 2 + 4 + 4 + 1), + }, ], }, ], @@ -233,7 +243,8 @@ impl Pipeline { bounds.x, bounds.y, bounds.width, - bounds.height, + // TODO: Address anti-aliasing adjustments properly + bounds.height + 1, ); render_pass.draw_indexed( @@ -277,7 +288,9 @@ pub struct Quad { pub position: [f32; 2], pub scale: [f32; 2], pub color: [f32; 4], + pub border_color: [f32; 4], pub border_radius: f32, + pub border_width: f32, } impl Quad { diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 1b143d90..efda046b 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -223,6 +223,8 @@ impl Renderer { bounds, background, border_radius, + border_width, + border_color, } => { // TODO: Move some of this computations to the GPU (?) layer.quads.push(Quad { @@ -235,6 +237,8 @@ impl Renderer { Background::Color(color) => color.into_linear(), }, border_radius: *border_radius as f32, + border_width: *border_width as f32, + border_color: border_color.into_linear(), }); } Primitive::Image { handle, bounds } => { @@ -470,11 +474,12 @@ fn explain_layout( color: Color, primitives: &mut Vec, ) { - // TODO: Draw borders instead primitives.push(Primitive::Quad { bounds: layout.bounds(), - background: Background::Color([0.0, 0.0, 0.0, 0.05].into()), + background: Background::Color(Color::TRANSPARENT), border_radius: 0, + border_width: 1, + border_color: [0.6, 0.6, 0.6, 0.5].into(), }); for child in layout.children() { diff --git a/wgpu/src/renderer/widget/button.rs b/wgpu/src/renderer/widget/button.rs index 4fbd90d7..d00a43a5 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/wgpu/src/renderer/widget/button.rs @@ -1,5 +1,7 @@ use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer}; -use iced_native::{Background, Element, Layout, MouseCursor, Point, Rectangle}; +use iced_native::{ + Background, Color, Element, Layout, MouseCursor, Point, Rectangle, +}; impl iced_native::button::Renderer for Renderer { type Style = Box; @@ -57,11 +59,15 @@ impl iced_native::button::Renderer for Renderer { [0.0, 0.0, 0.0, 0.5].into(), ), border_radius: styling.border_radius, + border_width: 0, + border_color: Color::TRANSPARENT, }, Primitive::Quad { bounds, background, border_radius: styling.border_radius, + border_width: 0, + border_color: Color::TRANSPARENT, }, content, ], diff --git a/wgpu/src/renderer/widget/checkbox.rs b/wgpu/src/renderer/widget/checkbox.rs index 54b4b1cc..1ed27ff7 100644 --- a/wgpu/src/renderer/widget/checkbox.rs +++ b/wgpu/src/renderer/widget/checkbox.rs @@ -1,6 +1,6 @@ use crate::{Primitive, Renderer}; use iced_native::{ - checkbox, Background, HorizontalAlignment, MouseCursor, Rectangle, + checkbox, Background, Color, HorizontalAlignment, MouseCursor, Rectangle, VerticalAlignment, }; @@ -18,30 +18,20 @@ impl checkbox::Renderer for Renderer { is_mouse_over: bool, (label, _): Self::Output, ) -> Self::Output { - let (checkbox_border, checkbox_box) = ( - Primitive::Quad { - bounds, - background: Background::Color([0.6, 0.6, 0.6].into()), - border_radius: 6, - }, - Primitive::Quad { - bounds: Rectangle { - x: bounds.x + 1.0, - y: bounds.y + 1.0, - width: bounds.width - 2.0, - height: bounds.height - 2.0, - }, - background: Background::Color( - if is_mouse_over { - [0.90, 0.90, 0.90] - } else { - [0.95, 0.95, 0.95] - } - .into(), - ), - border_radius: 5, - }, - ); + 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), + }; ( Primitive::Group { @@ -56,9 +46,9 @@ impl checkbox::Renderer for Renderer { vertical_alignment: VerticalAlignment::Center, }; - vec![checkbox_border, checkbox_box, check, label] + vec![checkbox, check, label] } else { - vec![checkbox_border, checkbox_box, label] + vec![checkbox, label] }, }, if is_mouse_over { diff --git a/wgpu/src/renderer/widget/container.rs b/wgpu/src/renderer/widget/container.rs index 29c709f8..18908571 100644 --- a/wgpu/src/renderer/widget/container.rs +++ b/wgpu/src/renderer/widget/container.rs @@ -1,5 +1,5 @@ use crate::{container, defaults, Defaults, Primitive, Renderer}; -use iced_native::{Element, Layout, Point, Rectangle}; +use iced_native::{Color, Element, Layout, Point, Rectangle}; impl iced_native::container::Renderer for Renderer { type Style = Box; @@ -31,6 +31,8 @@ impl iced_native::container::Renderer for Renderer { bounds, background, border_radius: style.border_radius, + border_width: 0, + border_color: Color::TRANSPARENT, }; ( diff --git a/wgpu/src/renderer/widget/radio.rs b/wgpu/src/renderer/widget/radio.rs index 3c00a4c2..aa1dbadc 100644 --- a/wgpu/src/renderer/widget/radio.rs +++ b/wgpu/src/renderer/widget/radio.rs @@ -1,5 +1,5 @@ use crate::{Primitive, Renderer}; -use iced_native::{radio, Background, MouseCursor, Rectangle}; +use iced_native::{radio, Background, Color, MouseCursor, Rectangle}; const SIZE: f32 = 28.0; const DOT_SIZE: f32 = SIZE / 2.0; @@ -16,30 +16,20 @@ impl radio::Renderer for Renderer { is_mouse_over: bool, (label, _): Self::Output, ) -> Self::Output { - let (radio_border, radio_box) = ( - Primitive::Quad { - bounds, - background: Background::Color([0.6, 0.6, 0.6].into()), - border_radius: (SIZE / 2.0) as u16, - }, - Primitive::Quad { - bounds: Rectangle { - x: bounds.x + 1.0, - y: bounds.y + 1.0, - width: bounds.width - 2.0, - height: bounds.height - 2.0, - }, - background: Background::Color( - if is_mouse_over { - [0.90, 0.90, 0.90] - } else { - [0.95, 0.95, 0.95] - } - .into(), - ), - border_radius: (SIZE / 2.0 - 1.0) as u16, - }, - ); + let radio = 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: (SIZE / 2.0) as u16, + border_width: 1, + border_color: Color::from_rgb(0.6, 0.6, 0.6), + }; ( Primitive::Group { @@ -53,11 +43,13 @@ impl radio::Renderer for Renderer { }, background: Background::Color([0.3, 0.3, 0.3].into()), border_radius: (DOT_SIZE / 2.0) as u16, + border_width: 0, + border_color: Color::TRANSPARENT, }; - vec![radio_border, radio_box, radio_circle, label] + vec![radio, radio_circle, label] } else { - vec![radio_border, radio_box, label] + vec![radio, label] }, }, if is_mouse_over { diff --git a/wgpu/src/renderer/widget/scrollable.rs b/wgpu/src/renderer/widget/scrollable.rs index 6ef57185..42a4a743 100644 --- a/wgpu/src/renderer/widget/scrollable.rs +++ b/wgpu/src/renderer/widget/scrollable.rs @@ -1,5 +1,7 @@ use crate::{Primitive, Renderer}; -use iced_native::{scrollable, Background, MouseCursor, Rectangle, Vector}; +use iced_native::{ + scrollable, Background, Color, MouseCursor, Rectangle, Vector, +}; const SCROLLBAR_WIDTH: u16 = 10; const SCROLLBAR_MARGIN: u16 = 2; @@ -68,6 +70,8 @@ impl scrollable::Renderer for Renderer { [0.0, 0.0, 0.0, 0.7].into(), ), border_radius: 5, + border_width: 0, + border_color: Color::TRANSPARENT, }; if is_mouse_over_scrollbar || state.is_scroller_grabbed() { @@ -83,6 +87,8 @@ impl scrollable::Renderer for Renderer { [0.0, 0.0, 0.0, 0.3].into(), ), border_radius: 5, + border_width: 0, + border_color: Color::TRANSPARENT, }; Primitive::Group { diff --git a/wgpu/src/renderer/widget/slider.rs b/wgpu/src/renderer/widget/slider.rs index c73a4e56..386decb5 100644 --- a/wgpu/src/renderer/widget/slider.rs +++ b/wgpu/src/renderer/widget/slider.rs @@ -29,8 +29,10 @@ impl slider::Renderer for Renderer { width: bounds.width, height: 2.0, }, - background: Color::from_rgb(0.6, 0.6, 0.6).into(), + background: Background::Color([0.6, 0.6, 0.6, 0.5].into()), border_radius: 0, + border_width: 0, + border_color: Color::TRANSPARENT, }, Primitive::Quad { bounds: Rectangle { @@ -41,6 +43,8 @@ impl slider::Renderer for Renderer { }, background: Background::Color(Color::WHITE), border_radius: 0, + border_width: 0, + border_color: Color::TRANSPARENT, }, ); @@ -49,41 +53,31 @@ impl slider::Renderer for Renderer { let handle_offset = (bounds.width - HANDLE_WIDTH) * ((value - range_start) / (range_end - range_start).max(1.0)); - let (handle_border, handle) = ( - Primitive::Quad { - bounds: Rectangle { - x: bounds.x + handle_offset.round() - 1.0, - y: rail_y - HANDLE_HEIGHT / 2.0 - 1.0, - width: HANDLE_WIDTH + 2.0, - height: HANDLE_HEIGHT + 2.0, - }, - background: Color::from_rgb(0.6, 0.6, 0.6).into(), - border_radius: 5, - }, - Primitive::Quad { - bounds: Rectangle { - x: bounds.x + handle_offset.round(), - y: rail_y - HANDLE_HEIGHT / 2.0, - width: HANDLE_WIDTH, - height: HANDLE_HEIGHT, - }, - background: Background::Color( - if is_dragging { - [0.85, 0.85, 0.85] - } else if is_mouse_over { - [0.90, 0.90, 0.90] - } else { - [0.95, 0.95, 0.95] - } - .into(), - ), - border_radius: 4, + let handle = Primitive::Quad { + bounds: Rectangle { + x: bounds.x + handle_offset.round(), + y: rail_y - HANDLE_HEIGHT / 2.0, + width: HANDLE_WIDTH, + height: HANDLE_HEIGHT, }, - ); + background: Background::Color( + if is_dragging { + [0.85, 0.85, 0.85] + } else if is_mouse_over { + [0.90, 0.90, 0.90] + } else { + [0.95, 0.95, 0.95] + } + .into(), + ), + border_radius: 4, + border_width: 1, + border_color: Color::from_rgb(0.6, 0.6, 0.6), + }; ( Primitive::Group { - primitives: vec![rail_top, rail_bottom, handle_border, handle], + primitives: vec![rail_top, rail_bottom, handle], }, if is_dragging { MouseCursor::Grabbing diff --git a/wgpu/src/renderer/widget/text_input.rs b/wgpu/src/renderer/widget/text_input.rs index 929f94db..cf3a31ab 100644 --- a/wgpu/src/renderer/widget/text_input.rs +++ b/wgpu/src/renderer/widget/text_input.rs @@ -64,28 +64,17 @@ impl text_input::Renderer for Renderer { ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); - let border = Primitive::Quad { - bounds, - background: Background::Color( - if is_mouse_over || state.is_focused() { - [0.5, 0.5, 0.5] - } else { - [0.7, 0.7, 0.7] - } - .into(), - ), - border_radius: 5, - }; - let input = Primitive::Quad { - bounds: Rectangle { - x: bounds.x + 1.0, - y: bounds.y + 1.0, - width: bounds.width - 2.0, - height: bounds.height - 2.0, - }, + bounds, background: Background::Color(Color::WHITE), - border_radius: 4, + border_radius: 5, + border_width: 1, + border_color: if is_mouse_over || state.is_focused() { + [0.5, 0.5, 0.5] + } else { + [0.7, 0.7, 0.7] + } + .into(), }; let text = value.to_string(); @@ -130,6 +119,8 @@ impl text_input::Renderer for Renderer { }, background: Background::Color(Color::BLACK), border_radius: 0, + border_width: 0, + border_color: Color::TRANSPARENT, }; ( @@ -150,7 +141,7 @@ impl text_input::Renderer for Renderer { ( Primitive::Group { - primitives: vec![border, input, contents], + primitives: vec![input, contents], }, if is_mouse_over { MouseCursor::Text diff --git a/wgpu/src/shader/quad.frag b/wgpu/src/shader/quad.frag index 2ee77e71..ad1af1ad 100644 --- a/wgpu/src/shader/quad.frag +++ b/wgpu/src/shader/quad.frag @@ -1,14 +1,17 @@ #version 450 layout(location = 0) in vec4 v_Color; -layout(location = 1) in vec2 v_Pos; -layout(location = 2) in vec2 v_Scale; -layout(location = 3) in float v_BorderRadius; +layout(location = 1) in vec4 v_BorderColor; +layout(location = 2) in vec2 v_Pos; +layout(location = 3) in vec2 v_Scale; +layout(location = 4) in float v_BorderRadius; +layout(location = 5) in float v_BorderWidth; layout(location = 0) out vec4 o_Color; -float rounded(in vec2 frag_coord, in vec2 position, in vec2 size, float radius, float s) +float distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius) { + // TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN vec2 inner_size = size - vec2(radius, radius) * 2.0; vec2 top_left = position + vec2(radius, radius); vec2 bottom_right = top_left + inner_size; @@ -21,13 +24,43 @@ float rounded(in vec2 frag_coord, in vec2 position, in vec2 size, float radius, max(max(top_left_distance.y, bottom_right_distance.y), 0) ); - float d = sqrt(distance.x * distance.x + distance.y * distance.y); - - return 1.0 - smoothstep(radius - s, radius + s, d); + return sqrt(distance.x * distance.x + distance.y * distance.y); } void main() { - float radius_alpha = rounded(gl_FragCoord.xy, v_Pos, v_Scale, v_BorderRadius, 0.5); + vec4 mixed_color; + + // TODO: Remove branching (?) + if(v_BorderWidth > 0) { + float internal_border = max(v_BorderRadius - v_BorderWidth, 0); + + float internal_distance = distance( + gl_FragCoord.xy, + v_Pos + vec2(v_BorderWidth), + v_Scale - vec2(v_BorderWidth * 2.0), + internal_border + ); + + float border_mix = smoothstep( + max(internal_border - 0.5, 0.0), + internal_border + 0.5, + internal_distance + ); + + mixed_color = mix(v_Color, v_BorderColor, border_mix); + } else { + mixed_color = v_Color; + } + + float d = distance( + gl_FragCoord.xy, + v_Pos, + v_Scale, + v_BorderRadius + ); + + float radius_alpha = + 1.0 - smoothstep(max(v_BorderRadius - 0.5, 0), v_BorderRadius + 0.5, d); - o_Color = vec4(v_Color.xyz, v_Color.w * radius_alpha); + o_Color = vec4(mixed_color.xyz, mixed_color.w * radius_alpha); } diff --git a/wgpu/src/shader/quad.frag.spv b/wgpu/src/shader/quad.frag.spv index 17bd8f46..519f5f01 100644 Binary files a/wgpu/src/shader/quad.frag.spv and b/wgpu/src/shader/quad.frag.spv differ diff --git a/wgpu/src/shader/quad.vert b/wgpu/src/shader/quad.vert index 539755cb..1d9a4fd2 100644 --- a/wgpu/src/shader/quad.vert +++ b/wgpu/src/shader/quad.vert @@ -4,7 +4,9 @@ layout(location = 0) in vec2 v_Pos; layout(location = 1) in vec2 i_Pos; layout(location = 2) in vec2 i_Scale; layout(location = 3) in vec4 i_Color; -layout(location = 4) in float i_BorderRadius; +layout(location = 4) in vec4 i_BorderColor; +layout(location = 5) in float i_BorderRadius; +layout(location = 6) in float i_BorderWidth; layout (set = 0, binding = 0) uniform Globals { mat4 u_Transform; @@ -12,9 +14,11 @@ layout (set = 0, binding = 0) uniform Globals { }; layout(location = 0) out vec4 o_Color; -layout(location = 1) out vec2 o_Pos; -layout(location = 2) out vec2 o_Scale; -layout(location = 3) out float o_BorderRadius; +layout(location = 1) out vec4 o_BorderColor; +layout(location = 2) out vec2 o_Pos; +layout(location = 3) out vec2 o_Scale; +layout(location = 4) out float o_BorderRadius; +layout(location = 5) out float o_BorderWidth; void main() { vec2 p_Pos = i_Pos * u_Scale; @@ -28,9 +32,11 @@ void main() { ); o_Color = i_Color; + o_BorderColor = i_BorderColor; o_Pos = p_Pos; o_Scale = p_Scale; o_BorderRadius = i_BorderRadius * u_Scale; + o_BorderWidth = i_BorderWidth * u_Scale; gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0); } diff --git a/wgpu/src/shader/quad.vert.spv b/wgpu/src/shader/quad.vert.spv index 9050adfb..7059b51b 100644 Binary files a/wgpu/src/shader/quad.vert.spv and b/wgpu/src/shader/quad.vert.spv differ -- cgit From e1062a02d17f5748e4809b76ddcc132f1c912886 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 1 Jan 2020 14:16:10 +0100 Subject: Move styling to a brand new `iced_style` crate --- wgpu/Cargo.toml | 1 + wgpu/src/widget/button.rs | 77 +------------------------------------------- wgpu/src/widget/container.rs | 43 +++++-------------------- 3 files changed, 10 insertions(+), 111 deletions(-) (limited to 'wgpu') diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index bb241914..19d41bba 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -12,6 +12,7 @@ svg = ["resvg"] [dependencies] iced_native = { version = "0.1.0", path = "../native" } +iced_style = { version = "0.1.0-alpha", path = "../style" } wgpu = "0.4" glyph_brush = "0.6" wgpu_glyph = { version = "0.7", git = "https://github.com/hecrj/wgpu_glyph", branch = "fix/font-load-panic" } diff --git a/wgpu/src/widget/button.rs b/wgpu/src/widget/button.rs index 2c4e174f..b738c55e 100644 --- a/wgpu/src/widget/button.rs +++ b/wgpu/src/widget/button.rs @@ -5,86 +5,11 @@ //! [`Button`]: type.Button.html //! [`State`]: struct.State.html use crate::Renderer; -use iced_native::{Background, Color}; pub use iced_native::button::State; +pub use iced_style::button::{Style, StyleSheet}; /// A widget that produces a message when clicked. /// /// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`. pub type Button<'a, Message> = iced_native::Button<'a, Message, Renderer>; - -#[derive(Debug)] -pub struct Style { - pub shadow_offset: f32, - pub background: Option, - pub border_radius: u16, - pub text_color: Color, -} - -pub trait StyleSheet { - fn active(&self) -> Style; - - fn hovered(&self) -> Style { - let active = self.active(); - - Style { - shadow_offset: active.shadow_offset + 1.0, - ..active - } - } - - fn pressed(&self) -> Style { - Style { - shadow_offset: 0.0, - ..self.active() - } - } - - fn disabled(&self) -> Style { - let active = self.active(); - - Style { - shadow_offset: 0.0, - background: active.background.map(|background| match background { - Background::Color(color) => Background::Color(Color { - a: color.a * 0.5, - ..color - }), - }), - text_color: Color { - a: active.text_color.a * 0.5, - ..active.text_color - }, - ..active - } - } -} - -struct Default; - -impl StyleSheet for Default { - fn active(&self) -> Style { - Style { - shadow_offset: 1.0, - background: Some(Background::Color([0.5, 0.5, 0.5].into())), - border_radius: 5, - text_color: Color::BLACK, - } - } -} - -impl std::default::Default for Box { - fn default() -> Self { - Box::new(Default) - } -} - -impl From for Box -where - T: 'static + StyleSheet, -{ - fn from(style: T) -> Self { - Box::new(style) - } -} diff --git a/wgpu/src/widget/container.rs b/wgpu/src/widget/container.rs index 1fc0ec98..9a93a246 100644 --- a/wgpu/src/widget/container.rs +++ b/wgpu/src/widget/container.rs @@ -1,37 +1,10 @@ -use iced_native::{Background, Color}; +//! Decorate content and apply alignment. +use crate::Renderer; -#[derive(Debug, Clone, Copy)] -pub struct Style { - pub text_color: Option, - pub background: Option, - pub border_radius: u16, -} +pub use iced_style::container::{Style, StyleSheet}; -pub trait StyleSheet { - fn style(&self) -> Style { - Style { - text_color: None, - background: None, - border_radius: 0, - } - } -} - -struct Default; - -impl StyleSheet for Default {} - -impl std::default::Default for Box { - fn default() -> Self { - Box::new(Default) - } -} - -impl From for Box -where - T: 'static + StyleSheet, -{ - fn from(style: T) -> Self { - Box::new(style) - } -} +/// An element decorating some content. +/// +/// This is an alias of an `iced_native` container with a default +/// `Renderer`. +pub type Container<'a, Message> = iced_native::Container<'a, Message, Renderer>; -- cgit From d96ced8e2da703117a43399110ef2b8fa21a7546 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 1 Jan 2020 17:49:48 +0100 Subject: Allow configuration of default font --- wgpu/src/lib.rs | 2 ++ wgpu/src/renderer.rs | 13 ++++++++----- wgpu/src/settings.rs | 4 ++++ wgpu/src/text.rs | 11 +++++++---- 4 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 wgpu/src/settings.rs (limited to 'wgpu') diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 786b6872..80ebc2a7 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -31,12 +31,14 @@ mod image; mod primitive; mod quad; mod renderer; +mod settings; mod text; mod transformation; pub use defaults::Defaults; pub use primitive::Primitive; pub use renderer::{Renderer, Target}; +pub use settings::Settings; #[doc(no_inline)] pub use widget::*; diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index efda046b..7f0f0b89 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -1,5 +1,6 @@ use crate::{ - image, quad, text, Defaults, Image, Primitive, Quad, Transformation, + image, quad, text, Defaults, Image, Primitive, Quad, Settings, + Transformation, }; use iced_native::{ renderer::{Debugger, Windowed}, @@ -49,7 +50,7 @@ impl<'a> Layer<'a> { } impl Renderer { - fn new() -> Self { + fn new(settings: Settings) -> Self { let adapter = Adapter::request(&RequestAdapterOptions { power_preference: PowerPreference::Default, backends: BackendBit::all(), @@ -63,7 +64,8 @@ impl Renderer { limits: Limits { max_bind_groups: 2 }, }); - let text_pipeline = text::Pipeline::new(&mut device); + let text_pipeline = + text::Pipeline::new(&mut device, settings.default_font); let quad_pipeline = quad::Pipeline::new(&mut device); let image_pipeline = image::Pipeline::new(&mut device); @@ -432,10 +434,11 @@ impl iced_native::Renderer for Renderer { } impl Windowed for Renderer { + type Settings = Settings; type Target = Target; - fn new() -> Self { - Self::new() + fn new(settings: Settings) -> Self { + Self::new(settings) } fn draw>( diff --git a/wgpu/src/settings.rs b/wgpu/src/settings.rs new file mode 100644 index 00000000..c6d8369b --- /dev/null +++ b/wgpu/src/settings.rs @@ -0,0 +1,4 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub struct Settings { + pub default_font: Option<&'static [u8]>, +} diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 880ad1a6..ab9a2f71 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -22,13 +22,16 @@ pub struct Pipeline { } impl Pipeline { - pub fn new(device: &mut wgpu::Device) -> Self { + pub fn new(device: &mut wgpu::Device, default_font: Option<&[u8]>) -> Self { // TODO: Font customization let font_source = font::Source::new(); - let default_font = font_source - .load(&[font::Family::SansSerif, font::Family::Serif]) - .unwrap_or_else(|_| FALLBACK_FONT.to_vec()); + let default_font = + default_font.map(|slice| slice.to_vec()).unwrap_or_else(|| { + font_source + .load(&[font::Family::SansSerif, font::Family::Serif]) + .unwrap_or_else(|_| FALLBACK_FONT.to_vec()) + }); let load_glyph_brush = |font: Vec| { let builder = -- cgit From 5af4159848341b14f6ff9ae14a9a222d8d8b0fb8 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 1 Jan 2020 18:26:49 +0100 Subject: Draft basic styling for `TextInput` --- wgpu/src/renderer/widget/text_input.rs | 32 +++++++++++++++++++------------- wgpu/src/widget.rs | 1 + wgpu/src/widget/text_input.rs | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 wgpu/src/widget/text_input.rs (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/text_input.rs b/wgpu/src/renderer/widget/text_input.rs index cf3a31ab..8b774a48 100644 --- a/wgpu/src/renderer/widget/text_input.rs +++ b/wgpu/src/renderer/widget/text_input.rs @@ -1,4 +1,4 @@ -use crate::{Primitive, Renderer}; +use crate::{text_input::StyleSheet, Primitive, Renderer}; use iced_native::{ text_input, Background, Color, Font, HorizontalAlignment, MouseCursor, @@ -7,6 +7,8 @@ use iced_native::{ use std::f32; impl text_input::Renderer for Renderer { + type Style = Box; + fn default_size(&self) -> u16 { // TODO: Make this configurable 20 @@ -61,20 +63,24 @@ impl text_input::Renderer for Renderer { placeholder: &str, value: &text_input::Value, state: &text_input::State, + style_sheet: &Self::Style, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); + let style = if state.is_focused() { + style_sheet.focused() + } else if is_mouse_over { + style_sheet.hovered() + } else { + style_sheet.active() + }; + let input = Primitive::Quad { bounds, - background: Background::Color(Color::WHITE), - border_radius: 5, - border_width: 1, - border_color: if is_mouse_over || state.is_focused() { - [0.5, 0.5, 0.5] - } else { - [0.7, 0.7, 0.7] - } - .into(), + background: style.background, + border_radius: style.border_radius, + border_width: style.border_width, + border_color: style.border_color, }; let text = value.to_string(); @@ -86,9 +92,9 @@ impl text_input::Renderer for Renderer { text.clone() }, color: if text.is_empty() { - [0.7, 0.7, 0.7] + style_sheet.placeholder_color() } else { - [0.3, 0.3, 0.3] + style_sheet.value_color() } .into(), font: Font::Default, @@ -117,7 +123,7 @@ impl text_input::Renderer for Renderer { width: 1.0, height: text_bounds.height, }, - background: Background::Color(Color::BLACK), + background: Background::Color(style_sheet.value_color()), border_radius: 0, border_width: 0, border_color: Color::TRANSPARENT, diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index c6f34301..1d7e57c4 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,2 +1,3 @@ pub mod button; pub mod container; +pub mod text_input; diff --git a/wgpu/src/widget/text_input.rs b/wgpu/src/widget/text_input.rs new file mode 100644 index 00000000..260fe3a6 --- /dev/null +++ b/wgpu/src/widget/text_input.rs @@ -0,0 +1,15 @@ +//! Display fields that can be filled with text. +//! +//! A [`TextInput`] has some local [`State`]. +//! +//! [`TextInput`]: struct.TextInput.html +//! [`State`]: struct.State.html +use crate::Renderer; + +pub use iced_native::text_input::State; +pub use iced_style::text_input::{Style, StyleSheet}; + +/// A field that can be filled with text. +/// +/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`. +pub type TextInput<'a, Message> = iced_native::TextInput<'a, Message, Renderer>; -- cgit From 8d6f86b317303c06a0daf1ca3ce91c29670dd674 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 5 Jan 2020 18:11:54 +0100 Subject: Remove `background` from `Settings` --- wgpu/src/renderer.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 7f0f0b89..8f0b2020 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -80,7 +80,6 @@ impl Renderer { fn draw>( &mut self, - clear_color: Color, (primitive, mouse_cursor): &(Primitive, MouseCursor), overlay: &[T], target: &mut Target, @@ -102,15 +101,11 @@ impl Renderer { resolve_target: None, load_op: wgpu::LoadOp::Clear, store_op: wgpu::StoreOp::Store, - clear_color: { - let [r, g, b, a] = clear_color.into_linear(); - - wgpu::Color { - r: f64::from(r), - g: f64::from(g), - b: f64::from(b), - a: f64::from(a), - } + clear_color: wgpu::Color { + r: 1.0, + g: 1.0, + b: 1.0, + a: 1.0, }, }], depth_stencil_attachment: None, @@ -443,12 +438,11 @@ impl Windowed for Renderer { fn draw>( &mut self, - clear_color: Color, output: &Self::Output, overlay: &[T], target: &mut Target, ) -> MouseCursor { - self.draw(clear_color, output, overlay, target) + self.draw(output, overlay, target) } } -- cgit From 2116fbb3c2412030a676c60d65784b9dfa467a0a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 5 Jan 2020 18:38:03 +0100 Subject: Add border styling to `Container` --- wgpu/src/renderer/widget/container.rs | 37 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/container.rs b/wgpu/src/renderer/widget/container.rs index 18908571..2d4d1db8 100644 --- a/wgpu/src/renderer/widget/container.rs +++ b/wgpu/src/renderer/widget/container.rs @@ -1,5 +1,5 @@ use crate::{container, defaults, Defaults, Primitive, Renderer}; -use iced_native::{Color, Element, Layout, Point, Rectangle}; +use iced_native::{Background, Color, Element, Layout, Point, Rectangle}; impl iced_native::container::Renderer for Renderer { type Style = Box; @@ -25,24 +25,25 @@ impl iced_native::container::Renderer for Renderer { let (content, mouse_cursor) = content.draw(self, &defaults, content_layout, cursor_position); - match style.background { - Some(background) => { - let quad = Primitive::Quad { - bounds, - background, - border_radius: style.border_radius, - border_width: 0, - border_color: Color::TRANSPARENT, - }; + if style.background.is_some() || style.border_width > 0 { + let quad = Primitive::Quad { + bounds, + background: style + .background + .unwrap_or(Background::Color(Color::TRANSPARENT)), + border_radius: style.border_radius, + border_width: style.border_width, + border_color: style.border_color, + }; - ( - Primitive::Group { - primitives: vec![quad, content], - }, - mouse_cursor, - ) - } - None => (content, mouse_cursor), + ( + Primitive::Group { + primitives: vec![quad, content], + }, + mouse_cursor, + ) + } else { + (content, mouse_cursor) } } } -- cgit From 1a0effa961344677daf17b4192243423a154f1bf Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 5 Jan 2020 19:29:12 +0100 Subject: Add border and shadow styling to `Button` --- wgpu/src/renderer/widget/button.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/button.rs b/wgpu/src/renderer/widget/button.rs index d00a43a5..63a53473 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/wgpu/src/renderer/widget/button.rs @@ -51,8 +51,8 @@ impl iced_native::button::Renderer for Renderer { primitives: vec![ Primitive::Quad { bounds: Rectangle { - x: bounds.x + 1.0, - y: bounds.y + styling.shadow_offset, + x: bounds.x + styling.shadow_offset.x, + y: bounds.y + styling.shadow_offset.y, ..bounds }, background: Background::Color( @@ -66,8 +66,8 @@ impl iced_native::button::Renderer for Renderer { bounds, background, border_radius: styling.border_radius, - border_width: 0, - border_color: Color::TRANSPARENT, + border_width: styling.border_width, + border_color: styling.border_color, }, content, ], -- cgit From a848306b89053ef4ba2aeb4eb7899bec94d93cb3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 5 Jan 2020 19:48:27 +0100 Subject: Fix styling in `button::Renderer` implementation --- wgpu/src/renderer/widget/button.rs | 64 ++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/button.rs b/wgpu/src/renderer/widget/button.rs index 63a53473..eb5d7c09 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/wgpu/src/renderer/widget/button.rs @@ -1,6 +1,6 @@ use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer}; use iced_native::{ - Background, Color, Element, Layout, MouseCursor, Point, Rectangle, + Background, Color, Element, Layout, MouseCursor, Point, Rectangle, Vector, }; impl iced_native::button::Renderer for Renderer { @@ -45,33 +45,43 @@ impl iced_native::button::Renderer for Renderer { ); ( - match styling.background { - None => content, - Some(background) => Primitive::Group { - primitives: vec![ - Primitive::Quad { - bounds: Rectangle { - x: bounds.x + styling.shadow_offset.x, - y: bounds.y + styling.shadow_offset.y, - ..bounds - }, - background: Background::Color( - [0.0, 0.0, 0.0, 0.5].into(), - ), - border_radius: styling.border_radius, - border_width: 0, - border_color: Color::TRANSPARENT, - }, - Primitive::Quad { - bounds, - background, - border_radius: styling.border_radius, - border_width: styling.border_width, - border_color: styling.border_color, + if styling.background.is_some() || styling.border_width > 0 { + let background = Primitive::Quad { + bounds, + background: styling + .background + .unwrap_or(Background::Color(Color::TRANSPARENT)), + border_radius: styling.border_radius, + border_width: styling.border_width, + border_color: styling.border_color, + }; + + if styling.shadow_offset == Vector::default() { + Primitive::Group { + primitives: vec![background, content], + } + } else { + // TODO: Implement proper shadow support + let shadow = Primitive::Quad { + bounds: Rectangle { + x: bounds.x + styling.shadow_offset.x, + y: bounds.y + styling.shadow_offset.y, + ..bounds }, - content, - ], - }, + background: Background::Color( + [0.0, 0.0, 0.0, 0.5].into(), + ), + border_radius: styling.border_radius, + border_width: 0, + border_color: Color::TRANSPARENT, + }; + + Primitive::Group { + primitives: vec![shadow, background, content], + } + } + } else { + content }, if is_mouse_over { MouseCursor::Pointer -- cgit From 2bbd395d5dcdf9c92ffb354b8b05444478e4b344 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 6 Jan 2020 18:44:45 +0100 Subject: Draft `styling` example --- wgpu/src/renderer/widget/button.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/button.rs b/wgpu/src/renderer/widget/button.rs index eb5d7c09..a9209f64 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/wgpu/src/renderer/widget/button.rs @@ -19,7 +19,6 @@ impl iced_native::button::Renderer for Renderer { ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); - // TODO: Render proper shadows let styling = if is_disabled { style.disabled() } else if is_mouse_over { -- cgit From d0dc7cebf9c352f4d14827fe47489788f59e61a1 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 6 Jan 2020 21:01:09 +0100 Subject: Implement styling for `Scrollable` --- wgpu/src/renderer/widget/scrollable.rs | 33 +++++++++++++++++++++------------ wgpu/src/widget.rs | 1 + wgpu/src/widget/scrollable.rs | 13 +++++++++++++ 3 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 wgpu/src/widget/scrollable.rs (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/scrollable.rs b/wgpu/src/renderer/widget/scrollable.rs index 42a4a743..30d7f337 100644 --- a/wgpu/src/renderer/widget/scrollable.rs +++ b/wgpu/src/renderer/widget/scrollable.rs @@ -7,6 +7,8 @@ const SCROLLBAR_WIDTH: u16 = 10; const SCROLLBAR_MARGIN: u16 = 2; impl scrollable::Renderer for Renderer { + type Style = Box; + fn scrollbar( &self, bounds: Rectangle, @@ -53,6 +55,7 @@ impl scrollable::Renderer for Renderer { is_mouse_over_scrollbar: bool, scrollbar: Option, offset: u32, + style_sheet: &Self::Style, (content, mouse_cursor): Self::Output, ) -> Self::Output { let clip = Primitive::Clip { @@ -64,17 +67,23 @@ impl scrollable::Renderer for Renderer { ( if let Some(scrollbar) = scrollbar { if is_mouse_over || state.is_scroller_grabbed() { + let style = if state.is_scroller_grabbed() { + style_sheet.dragging() + } else if is_mouse_over_scrollbar { + style_sheet.hovered() + } else { + style_sheet.active() + }; + let scroller = Primitive::Quad { bounds: scrollbar.scroller.bounds, - background: Background::Color( - [0.0, 0.0, 0.0, 0.7].into(), - ), - border_radius: 5, - border_width: 0, - border_color: Color::TRANSPARENT, + background: Background::Color(style.scroller.color), + border_radius: style.scroller.border_radius, + border_width: style.scroller.border_width, + border_color: style.scroller.border_color, }; - if is_mouse_over_scrollbar || state.is_scroller_grabbed() { + if style.background.is_some() || style.border_width > 0 { let scrollbar = Primitive::Quad { bounds: Rectangle { x: scrollbar.bounds.x @@ -83,12 +92,12 @@ impl scrollable::Renderer for Renderer { - f32::from(2 * SCROLLBAR_MARGIN), ..scrollbar.bounds }, - background: Background::Color( - [0.0, 0.0, 0.0, 0.3].into(), + background: style.background.unwrap_or( + Background::Color(Color::TRANSPARENT), ), - border_radius: 5, - border_width: 0, - border_color: Color::TRANSPARENT, + border_radius: style.border_radius, + border_width: style.border_width, + border_color: style.border_color, }; Primitive::Group { diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index 1d7e57c4..fb90b2b5 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,3 +1,4 @@ pub mod button; pub mod container; +pub mod scrollable; pub mod text_input; diff --git a/wgpu/src/widget/scrollable.rs b/wgpu/src/widget/scrollable.rs new file mode 100644 index 00000000..1d236105 --- /dev/null +++ b/wgpu/src/widget/scrollable.rs @@ -0,0 +1,13 @@ +//! Navigate an endless amount of content with a scrollbar. +use crate::Renderer; + +pub use iced_native::scrollable::State; +pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet}; + +/// A widget that can vertically display an infinite amount of content +/// with a scrollbar. +/// +/// This is an alias of an `iced_native` scrollable with a default +/// `Renderer`. +pub type Scrollable<'a, Message> = + iced_native::Scrollable<'a, Message, Renderer>; -- cgit From b329003c8fdcdc3378c8fda93af54be5686fc9ae Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 7 Jan 2020 00:28:08 +0100 Subject: Implement styling for `Slider` --- wgpu/src/renderer/widget/slider.rs | 57 ++++++++++++++++++++++++-------------- wgpu/src/widget.rs | 1 + wgpu/src/widget/slider.rs | 16 +++++++++++ 3 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 wgpu/src/widget/slider.rs (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/slider.rs b/wgpu/src/renderer/widget/slider.rs index 386decb5..c8ebd0da 100644 --- a/wgpu/src/renderer/widget/slider.rs +++ b/wgpu/src/renderer/widget/slider.rs @@ -1,10 +1,14 @@ -use crate::{Primitive, Renderer}; +use crate::{ + slider::{HandleShape, StyleSheet}, + Primitive, Renderer, +}; use iced_native::{slider, Background, Color, MouseCursor, Point, Rectangle}; -const HANDLE_WIDTH: f32 = 8.0; const HANDLE_HEIGHT: f32 = 22.0; impl slider::Renderer for Renderer { + type Style = Box; + fn height(&self) -> u32 { 30 } @@ -16,9 +20,18 @@ impl slider::Renderer for Renderer { range: std::ops::RangeInclusive, value: f32, is_dragging: bool, + style_sheet: &Self::Style, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); + let style = if is_dragging { + style_sheet.dragging() + } else if is_mouse_over { + style_sheet.hovered() + } else { + style_sheet.active() + }; + let rail_y = bounds.y + (bounds.height / 2.0).round(); let (rail_top, rail_bottom) = ( @@ -29,7 +42,7 @@ impl slider::Renderer for Renderer { width: bounds.width, height: 2.0, }, - background: Background::Color([0.6, 0.6, 0.6, 0.5].into()), + background: Background::Color(style.rail_colors.0), border_radius: 0, border_width: 0, border_color: Color::TRANSPARENT, @@ -41,7 +54,7 @@ impl slider::Renderer for Renderer { width: bounds.width, height: 2.0, }, - background: Background::Color(Color::WHITE), + background: Background::Color(style.rail_colors.1), border_radius: 0, border_width: 0, border_color: Color::TRANSPARENT, @@ -50,29 +63,31 @@ impl slider::Renderer for Renderer { let (range_start, range_end) = range.into_inner(); - let handle_offset = (bounds.width - HANDLE_WIDTH) + let (handle_width, handle_height, handle_border_radius) = + match style.handle.shape { + HandleShape::Circle { radius } => { + (f32::from(radius * 2), f32::from(radius * 2), radius) + } + HandleShape::Rectangle { + width, + border_radius, + } => (f32::from(width), HANDLE_HEIGHT, border_radius), + }; + + let handle_offset = (bounds.width - handle_width) * ((value - range_start) / (range_end - range_start).max(1.0)); let handle = Primitive::Quad { bounds: Rectangle { x: bounds.x + handle_offset.round(), - y: rail_y - HANDLE_HEIGHT / 2.0, - width: HANDLE_WIDTH, - height: HANDLE_HEIGHT, + y: rail_y - handle_height / 2.0, + width: handle_width, + height: handle_height, }, - background: Background::Color( - if is_dragging { - [0.85, 0.85, 0.85] - } else if is_mouse_over { - [0.90, 0.90, 0.90] - } else { - [0.95, 0.95, 0.95] - } - .into(), - ), - border_radius: 4, - border_width: 1, - border_color: Color::from_rgb(0.6, 0.6, 0.6), + background: Background::Color(style.handle.color), + border_radius: handle_border_radius, + border_width: style.handle.border_width, + border_color: style.handle.border_color, }; ( diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index fb90b2b5..4b8d339e 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,4 +1,5 @@ pub mod button; pub mod container; pub mod scrollable; +pub mod slider; pub mod text_input; diff --git a/wgpu/src/widget/slider.rs b/wgpu/src/widget/slider.rs new file mode 100644 index 00000000..4e47978f --- /dev/null +++ b/wgpu/src/widget/slider.rs @@ -0,0 +1,16 @@ +//! Display an interactive selector of a single value from a range of values. +//! +//! A [`Slider`] has some local [`State`]. +//! +//! [`Slider`]: struct.Slider.html +//! [`State`]: struct.State.html +use crate::Renderer; + +pub use iced_native::slider::State; +pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet}; + +/// An horizontal bar and a handle that selects a single value from a range of +/// values. +/// +/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`. +pub type Slider<'a, Message> = iced_native::Slider<'a, Message, Renderer>; -- cgit From 48b3b78a3840778eef1035f4585d5ba9dd3d6291 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 7 Jan 2020 01:53:26 +0100 Subject: Implement styling for `ProgressBar` --- wgpu/src/renderer/widget/progress_bar.rs | 27 +++++++++++++-------------- wgpu/src/widget.rs | 1 + wgpu/src/widget/progress_bar.rs | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 wgpu/src/widget/progress_bar.rs (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/progress_bar.rs b/wgpu/src/renderer/widget/progress_bar.rs index e9346fda..8bb9db03 100644 --- a/wgpu/src/renderer/widget/progress_bar.rs +++ b/wgpu/src/renderer/widget/progress_bar.rs @@ -1,7 +1,9 @@ -use crate::{Primitive, Renderer}; -use iced_native::{progress_bar, Background, Color, MouseCursor, Rectangle}; +use crate::{progress_bar::StyleSheet, Primitive, Renderer}; +use iced_native::{progress_bar, Color, MouseCursor, Rectangle}; impl progress_bar::Renderer for Renderer { + type Style = Box; + const DEFAULT_HEIGHT: u16 = 30; fn draw( @@ -9,9 +11,10 @@ impl progress_bar::Renderer for Renderer { bounds: Rectangle, range: std::ops::RangeInclusive, value: f32, - background: Option, - active_color: Option, + style_sheet: &Self::Style, ) -> Self::Output { + let style = style_sheet.style(); + let (range_start, range_end) = range.into_inner(); let active_progress_width = bounds.width * ((value - range_start) / (range_end - range_start).max(1.0)); @@ -19,31 +22,27 @@ impl progress_bar::Renderer for Renderer { let background = Primitive::Group { primitives: vec![Primitive::Quad { bounds: Rectangle { ..bounds }, - background: background - .unwrap_or(Background::Color([0.6, 0.6, 0.6].into())) - .into(), - border_radius: 5, + background: style.background, + border_radius: style.border_radius, border_width: 0, border_color: Color::TRANSPARENT, }], }; - let active_progress = Primitive::Quad { + let bar = Primitive::Quad { bounds: Rectangle { width: active_progress_width, ..bounds }, - background: Background::Color( - active_color.unwrap_or([0.0, 0.95, 0.0].into()), - ), - border_radius: 5, + background: style.bar, + border_radius: style.border_radius, border_width: 0, border_color: Color::TRANSPARENT, }; ( Primitive::Group { - primitives: vec![background, active_progress], + primitives: vec![background, bar], }, MouseCursor::OutOfBounds, ) diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index 4b8d339e..3f3dc0b0 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,5 +1,6 @@ pub mod button; pub mod container; +pub mod progress_bar; pub mod scrollable; pub mod slider; pub mod text_input; diff --git a/wgpu/src/widget/progress_bar.rs b/wgpu/src/widget/progress_bar.rs new file mode 100644 index 00000000..34450b5e --- /dev/null +++ b/wgpu/src/widget/progress_bar.rs @@ -0,0 +1,15 @@ +//! Allow your users to perform actions by pressing a button. +//! +//! A [`Button`] has some local [`State`]. +//! +//! [`Button`]: type.Button.html +//! [`State`]: struct.State.html +use crate::Renderer; + +pub use iced_style::progress_bar::{Style, StyleSheet}; + +/// A bar that displays progress. +/// +/// This is an alias of an `iced_native` progress bar with an +/// `iced_wgpu::Renderer`. +pub type ProgressBar = iced_native::ProgressBar; -- cgit From 387fc0be26ccd1adc66c1dc80420f9b08d0c023a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 7 Jan 2020 02:25:57 +0100 Subject: Implement styling for `Radio` --- wgpu/src/renderer/widget/radio.rs | 26 ++++++++++++++------------ wgpu/src/widget.rs | 1 + wgpu/src/widget/radio.rs | 10 ++++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 wgpu/src/widget/radio.rs (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/radio.rs b/wgpu/src/renderer/widget/radio.rs index aa1dbadc..564f066b 100644 --- a/wgpu/src/renderer/widget/radio.rs +++ b/wgpu/src/renderer/widget/radio.rs @@ -1,10 +1,12 @@ -use crate::{Primitive, Renderer}; +use crate::{radio::StyleSheet, Primitive, Renderer}; use iced_native::{radio, Background, Color, MouseCursor, Rectangle}; const SIZE: f32 = 28.0; const DOT_SIZE: f32 = SIZE / 2.0; impl radio::Renderer for Renderer { + type Style = Box; + fn default_size(&self) -> u32 { SIZE as u32 } @@ -15,20 +17,20 @@ impl radio::Renderer for Renderer { is_selected: 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 radio = Primitive::Quad { bounds, - background: Background::Color( - if is_mouse_over { - [0.90, 0.90, 0.90] - } else { - [0.95, 0.95, 0.95] - } - .into(), - ), + background: style.background, border_radius: (SIZE / 2.0) as u16, - border_width: 1, - border_color: Color::from_rgb(0.6, 0.6, 0.6), + border_width: style.border_width, + border_color: style.border_color, }; ( @@ -41,7 +43,7 @@ impl radio::Renderer for Renderer { width: bounds.width - DOT_SIZE, height: bounds.height - DOT_SIZE, }, - background: Background::Color([0.3, 0.3, 0.3].into()), + background: Background::Color(style.dot_color), border_radius: (DOT_SIZE / 2.0) as u16, border_width: 0, border_color: Color::TRANSPARENT, diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index 3f3dc0b0..991e0644 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,6 +1,7 @@ pub mod button; pub mod container; pub mod progress_bar; +pub mod radio; pub mod scrollable; pub mod slider; pub mod text_input; diff --git a/wgpu/src/widget/radio.rs b/wgpu/src/widget/radio.rs new file mode 100644 index 00000000..6e5cf042 --- /dev/null +++ b/wgpu/src/widget/radio.rs @@ -0,0 +1,10 @@ +//! Create choices using radio buttons. +use crate::Renderer; + +pub use iced_style::radio::{Style, StyleSheet}; + +/// A circular button representing a choice. +/// +/// This is an alias of an `iced_native` radio button with an +/// `iced_wgpu::Renderer`. +pub type Radio = iced_native::Radio; -- cgit From ed30b487d649ffa0967ab8bfd66f4820ee2150fd Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 7 Jan 2020 02:54:54 +0100 Subject: Implement styling for `Checkbox` --- wgpu/src/renderer/widget/checkbox.rs | 31 ++++++++++++++++--------------- wgpu/src/widget.rs | 1 + wgpu/src/widget/checkbox.rs | 9 +++++++++ 3 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 wgpu/src/widget/checkbox.rs (limited to 'wgpu') 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; + 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 = iced_native::Checkbox; -- cgit From 3d26eb79c2b6a4ed4d186552b052c31235bd0b83 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 7 Jan 2020 03:18:39 +0100 Subject: Always show scroller if scrollbar is visible --- wgpu/src/renderer/widget/scrollable.rs | 73 ++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 35 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/scrollable.rs b/wgpu/src/renderer/widget/scrollable.rs index 30d7f337..bfee7411 100644 --- a/wgpu/src/renderer/widget/scrollable.rs +++ b/wgpu/src/renderer/widget/scrollable.rs @@ -66,50 +66,53 @@ impl scrollable::Renderer for Renderer { ( if let Some(scrollbar) = scrollbar { - if is_mouse_over || state.is_scroller_grabbed() { - let style = if state.is_scroller_grabbed() { - style_sheet.dragging() - } else if is_mouse_over_scrollbar { - style_sheet.hovered() - } else { - style_sheet.active() - }; + let style = if state.is_scroller_grabbed() { + style_sheet.dragging() + } else if is_mouse_over_scrollbar { + style_sheet.hovered() + } else { + style_sheet.active() + }; + + let is_scrollbar_visible = + style.background.is_some() || style.border_width > 0; - let scroller = Primitive::Quad { + let scroller = if is_mouse_over + || state.is_scroller_grabbed() + || is_scrollbar_visible + { + Primitive::Quad { bounds: scrollbar.scroller.bounds, background: Background::Color(style.scroller.color), border_radius: style.scroller.border_radius, border_width: style.scroller.border_width, border_color: style.scroller.border_color, - }; - - if style.background.is_some() || style.border_width > 0 { - let scrollbar = Primitive::Quad { - bounds: Rectangle { - x: scrollbar.bounds.x - + f32::from(SCROLLBAR_MARGIN), - width: scrollbar.bounds.width - - f32::from(2 * SCROLLBAR_MARGIN), - ..scrollbar.bounds - }, - background: style.background.unwrap_or( - Background::Color(Color::TRANSPARENT), - ), - border_radius: style.border_radius, - border_width: style.border_width, - border_color: style.border_color, - }; + } + } else { + Primitive::None + }; - Primitive::Group { - primitives: vec![clip, scrollbar, scroller], - } - } else { - Primitive::Group { - primitives: vec![clip, scroller], - } + let scrollbar = if is_scrollbar_visible { + Primitive::Quad { + bounds: Rectangle { + x: scrollbar.bounds.x + f32::from(SCROLLBAR_MARGIN), + width: scrollbar.bounds.width + - f32::from(2 * SCROLLBAR_MARGIN), + ..scrollbar.bounds + }, + background: style + .background + .unwrap_or(Background::Color(Color::TRANSPARENT)), + border_radius: style.border_radius, + border_width: style.border_width, + border_color: style.border_color, } } else { - clip + Primitive::None + }; + + Primitive::Group { + primitives: vec![clip, scrollbar, scroller], } } else { clip -- cgit From cae4463e8379cddefbd8322a40ad8957bce07215 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 8 Jan 2020 03:30:15 +0100 Subject: Allow `Checkbox` style to change based on its state --- wgpu/src/renderer/widget/checkbox.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/checkbox.rs b/wgpu/src/renderer/widget/checkbox.rs index cd90be5e..17121eea 100644 --- a/wgpu/src/renderer/widget/checkbox.rs +++ b/wgpu/src/renderer/widget/checkbox.rs @@ -21,9 +21,9 @@ impl checkbox::Renderer for Renderer { style_sheet: &Self::Style, ) -> Self::Output { let style = if is_mouse_over { - style_sheet.hovered() + style_sheet.hovered(is_checked) } else { - style_sheet.active() + style_sheet.active(is_checked) }; let checkbox = Primitive::Quad { -- cgit From 89b1ac6eac03bec9e2acb9b4d59da86e59d26153 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 8 Jan 2020 03:32:38 +0100 Subject: Fix drawing empty `Quad` on empty `ProgressBar` --- wgpu/src/renderer/widget/progress_bar.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'wgpu') diff --git a/wgpu/src/renderer/widget/progress_bar.rs b/wgpu/src/renderer/widget/progress_bar.rs index 8bb9db03..34e33276 100644 --- a/wgpu/src/renderer/widget/progress_bar.rs +++ b/wgpu/src/renderer/widget/progress_bar.rs @@ -29,20 +29,24 @@ impl progress_bar::Renderer for Renderer { }], }; - let bar = Primitive::Quad { - bounds: Rectangle { - width: active_progress_width, - ..bounds - }, - background: style.bar, - border_radius: style.border_radius, - border_width: 0, - border_color: Color::TRANSPARENT, - }; - ( - Primitive::Group { - primitives: vec![background, bar], + if active_progress_width > 0.0 { + let bar = Primitive::Quad { + bounds: Rectangle { + width: active_progress_width, + ..bounds + }, + background: style.bar, + border_radius: style.border_radius, + border_width: 0, + border_color: Color::TRANSPARENT, + }; + + Primitive::Group { + primitives: vec![background, bar], + } + } else { + background }, MouseCursor::OutOfBounds, ) -- cgit From 7b278755fc7929633b5771824beac4d39b16e82e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 9 Jan 2020 18:31:07 +0100 Subject: Write missing docs and reenable deny statements --- wgpu/src/defaults.rs | 5 +++++ wgpu/src/lib.rs | 2 +- wgpu/src/settings.rs | 6 ++++++ wgpu/src/widget.rs | 26 ++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) (limited to 'wgpu') diff --git a/wgpu/src/defaults.rs b/wgpu/src/defaults.rs index 8de8258b..11718a87 100644 --- a/wgpu/src/defaults.rs +++ b/wgpu/src/defaults.rs @@ -1,7 +1,10 @@ +//! Use default styling attributes to inherit styles. use iced_native::Color; +/// Some default styling attributes. #[derive(Debug, Clone, Copy)] pub struct Defaults { + /// Text styling pub text: Text, } @@ -13,8 +16,10 @@ impl Default for Defaults { } } +/// Some default text styling attributes. #[derive(Debug, Clone, Copy)] pub struct Text { + /// The default color of text pub color: Color, } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index dda4f322..ab14987c 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -19,7 +19,7 @@ //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs //! [WebGPU API]: https://gpuweb.github.io/gpuweb/ //! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph -//#![deny(missing_docs)] +#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![deny(unsafe_code)] diff --git a/wgpu/src/settings.rs b/wgpu/src/settings.rs index c6d8369b..dbe81830 100644 --- a/wgpu/src/settings.rs +++ b/wgpu/src/settings.rs @@ -1,4 +1,10 @@ +/// The settings of a [`Renderer`]. +/// +/// [`Renderer`]: struct.Renderer.html #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct Settings { + /// The bytes of the font that will be used by default. + /// + /// If `None` is provided, a default system font will be chosen. pub default_font: Option<&'static [u8]>, } diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index e0f56594..e3edda0b 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,3 +1,12 @@ +//! Use the widgets supported out-of-the-box. +//! +//! # Re-exports +//! For convenience, the contents of this module are available at the root +//! module. Therefore, you can directly type: +//! +//! ``` +//! use iced_wgpu::{button, Button}; +//! ``` pub mod button; pub mod checkbox; pub mod container; @@ -6,3 +15,20 @@ pub mod radio; pub mod scrollable; pub mod slider; pub mod text_input; + +#[doc(no_inline)] +pub use button::Button; +#[doc(no_inline)] +pub use checkbox::Checkbox; +#[doc(no_inline)] +pub use container::Container; +#[doc(no_inline)] +pub use progress_bar::ProgressBar; +#[doc(no_inline)] +pub use radio::Radio; +#[doc(no_inline)] +pub use scrollable::Scrollable; +#[doc(no_inline)] +pub use slider::Slider; +#[doc(no_inline)] +pub use text_input::TextInput; -- cgit