From c901f40fd6c5aa39f4dc056b2b59bc7133b287e6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 14 Apr 2020 12:11:10 +0200 Subject: Introduce `Widget::overlay` :tada: --- graphics/src/renderer.rs | 2 +- graphics/src/widget/canvas.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics/src') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index c9360f3a..44bacd4e 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -62,7 +62,7 @@ where fn explain( &mut self, defaults: &Defaults, - widget: &dyn Widget, + widget: &dyn Widget<'_, Message, Self>, layout: Layout<'_>, cursor_position: Point, color: Color, diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index b8466239..0257f819 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -134,7 +134,7 @@ impl> Canvas { } } -impl Widget> for Canvas +impl<'a, Message, P, B> Widget<'a, Message, Renderer> for Canvas where P: Program, B: Backend, -- cgit From f064f0482b653a1fbee4afbddcecf91e3a399004 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 16 Apr 2020 13:22:00 +0200 Subject: Introduce `Layer` trait --- graphics/src/renderer.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'graphics/src') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 44bacd4e..771f436c 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,7 +1,9 @@ use crate::{Backend, Defaults, Primitive}; use iced_native::layout::{self, Layout}; use iced_native::mouse; -use iced_native::{Background, Color, Element, Point, Widget}; +use iced_native::{ + Background, Color, Element, Point, Rectangle, Vector, Widget, +}; /// A backend-agnostic renderer that supports all the built-in widgets. #[derive(Debug)] @@ -53,6 +55,31 @@ where layout } + + fn overlay( + &mut self, + (base_primitive, base_cursor): (Primitive, mouse::Interaction), + (overlay_primitives, overlay_cursor): (Primitive, mouse::Interaction), + overlay_bounds: Rectangle, + ) -> (Primitive, mouse::Interaction) { + ( + Primitive::Group { + primitives: vec![ + base_primitive, + Primitive::Clip { + bounds: overlay_bounds, + offset: Vector::new(0, 0), + content: Box::new(overlay_primitives), + }, + ], + }, + if base_cursor > overlay_cursor { + base_cursor + } else { + overlay_cursor + }, + ) + } } impl layout::Debugger for Renderer -- cgit From afd9274de26ccf65285df02007b4ddb697bea9a3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 18 Apr 2020 14:42:48 +0200 Subject: Draft `ComboBox` and `Menu` layer --- graphics/src/layer.rs | 2 + graphics/src/layer/menu.rs | 102 +++++++++++++++++++++++++++++++++++++++ graphics/src/lib.rs | 2 +- graphics/src/widget.rs | 1 + graphics/src/widget/combo_box.rs | 67 +++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 graphics/src/layer/menu.rs create mode 100644 graphics/src/widget/combo_box.rs (limited to 'graphics/src') diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index 6aca738e..ddf835a4 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -1,4 +1,6 @@ //! Organize rendering primitives into a flattened list of layers. +mod menu; + use crate::image; use crate::svg; use crate::triangle; diff --git a/graphics/src/layer/menu.rs b/graphics/src/layer/menu.rs new file mode 100644 index 00000000..e94ef964 --- /dev/null +++ b/graphics/src/layer/menu.rs @@ -0,0 +1,102 @@ +use crate::backend::Backend; +use crate::{Primitive, Renderer}; +use iced_native::{ + layer, mouse, Background, Color, Font, HorizontalAlignment, Point, + Rectangle, VerticalAlignment, +}; + +impl layer::menu::Renderer for Renderer +where + B: Backend, +{ + fn decorate( + &mut self, + bounds: Rectangle, + _cursor_position: Point, + (primitives, mouse_cursor): Self::Output, + ) -> Self::Output { + ( + Primitive::Group { + primitives: vec![ + Primitive::Quad { + bounds, + background: Background::Color( + [0.87, 0.87, 0.87].into(), + ), + border_color: [0.7, 0.7, 0.7].into(), + border_width: 1, + border_radius: 0, + }, + primitives, + ], + }, + mouse_cursor, + ) + } + + fn draw( + &mut self, + bounds: Rectangle, + cursor_position: Point, + options: &[T], + hovered_option: Option, + text_size: u16, + padding: u16, + ) -> Self::Output { + use std::f32; + + let is_mouse_over = bounds.contains(cursor_position); + + let mut primitives = Vec::new(); + + for (i, option) in options.iter().enumerate() { + let is_selected = hovered_option == Some(i); + + let bounds = Rectangle { + x: bounds.x, + y: bounds.y + + ((text_size as usize + padding as usize * 2) * i) as f32, + width: bounds.width, + height: f32::from(text_size + padding * 2), + }; + + if is_selected { + primitives.push(Primitive::Quad { + bounds, + background: Background::Color([0.4, 0.4, 1.0].into()), + border_color: Color::TRANSPARENT, + border_width: 0, + border_radius: 0, + }); + } + + primitives.push(Primitive::Text { + content: option.to_string(), + bounds: Rectangle { + x: bounds.x + f32::from(padding), + y: bounds.center_y(), + width: f32::INFINITY, + ..bounds + }, + size: f32::from(text_size), + font: Font::Default, + color: if is_selected { + Color::WHITE + } else { + Color::BLACK + }, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Center, + }); + } + + ( + Primitive::Group { primitives }, + if is_mouse_over { + mouse::Interaction::Pointer + } else { + mouse::Interaction::default() + }, + ) + } +} diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 38d8dffa..bad35ccf 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -2,7 +2,7 @@ //! for [`iced`]. //! //! [`iced`]: https://github.com/hecrj/iced -#![deny(missing_docs)] +//#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![deny(unsafe_code)] diff --git a/graphics/src/widget.rs b/graphics/src/widget.rs index 1f6d6559..a0d06999 100644 --- a/graphics/src/widget.rs +++ b/graphics/src/widget.rs @@ -9,6 +9,7 @@ //! ``` pub mod button; pub mod checkbox; +pub mod combo_box; pub mod container; pub mod image; pub mod pane_grid; diff --git a/graphics/src/widget/combo_box.rs b/graphics/src/widget/combo_box.rs new file mode 100644 index 00000000..27ea762a --- /dev/null +++ b/graphics/src/widget/combo_box.rs @@ -0,0 +1,67 @@ +use crate::backend::{self, Backend}; +use crate::{Primitive, Renderer}; +use iced_native::{ + mouse, Background, Color, Font, HorizontalAlignment, Point, Rectangle, + VerticalAlignment, +}; + +pub use iced_native::ComboBox; + +impl iced_native::combo_box::Renderer for Renderer +where + B: Backend + backend::Text, +{ + const DEFAULT_PADDING: u16 = 5; + + fn draw( + &mut self, + bounds: Rectangle, + cursor_position: Point, + selected: Option, + text_size: u16, + padding: u16, + ) -> Self::Output { + let is_mouse_over = bounds.contains(cursor_position); + + let background = Primitive::Quad { + bounds, + background: Background::Color([0.87, 0.87, 0.87].into()), + border_color: if is_mouse_over { + Color::BLACK + } else { + [0.7, 0.7, 0.7].into() + }, + border_width: 1, + border_radius: 0, + }; + + ( + if let Some(label) = selected { + let label = Primitive::Text { + content: label, + size: f32::from(text_size), + font: Font::Default, + color: Color::BLACK, + bounds: Rectangle { + x: bounds.x + f32::from(padding), + y: bounds.center_y(), + ..bounds + }, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Center, + }; + + Primitive::Group { + primitives: vec![background, label], + } + } else { + background + }, + if is_mouse_over { + mouse::Interaction::Pointer + } else { + mouse::Interaction::default() + }, + ) + } +} -- cgit From e29feef8ba4f95f286039fcc1ca2e53bfe5019c5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 18 Apr 2020 19:53:27 +0200 Subject: Render arrow icon in `ComboBox` --- graphics/src/backend.rs | 7 +++++- graphics/src/font.rs | 6 +++++ graphics/src/widget/combo_box.rs | 52 +++++++++++++++++++++++++--------------- 3 files changed, 45 insertions(+), 20 deletions(-) (limited to 'graphics/src') diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index b73c636e..dd7dbbc2 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -22,9 +22,14 @@ pub trait Text { /// The `char` representing a ✔ icon in the [`ICON_FONT`]. /// - /// [`ICON_FONT`]: #associatedconst.ICON_FONt + /// [`ICON_FONT`]: #associatedconst.ICON_FONT const CHECKMARK_ICON: char; + /// The `char` representing a ▼ icon in the built-in [`ICONS`] font. + /// + /// [`ICON_FONT`]: #associatedconst.ICON_FONT + const ARROW_DOWN_ICON: char; + /// Returns the default size of text. fn default_size(&self) -> u16; diff --git a/graphics/src/font.rs b/graphics/src/font.rs index bcc28857..5c62681c 100644 --- a/graphics/src/font.rs +++ b/graphics/src/font.rs @@ -31,3 +31,9 @@ pub const ICONS: iced_native::Font = iced_native::Font::External { #[cfg(feature = "font-icons")] #[cfg_attr(docsrs, doc(cfg(feature = "font-icons")))] pub const CHECKMARK_ICON: char = '\u{F00C}'; + +/// The `char` representing a ▼ icon in the built-in [`ICONS`] font. +/// +/// [`ICONS`]: const.ICONS.html +#[cfg(feature = "font-icons")] +pub const ARROW_DOWN_ICON: char = '\u{E800}'; diff --git a/graphics/src/widget/combo_box.rs b/graphics/src/widget/combo_box.rs index 27ea762a..92024c6c 100644 --- a/graphics/src/widget/combo_box.rs +++ b/graphics/src/widget/combo_box.rs @@ -35,27 +35,41 @@ where border_radius: 0, }; + let arrow_down = Primitive::Text { + content: B::ARROW_DOWN_ICON.to_string(), + font: B::ICON_FONT, + size: bounds.height * 0.7, + bounds: Rectangle { + x: bounds.x + bounds.width - f32::from(padding) * 2.0, + y: bounds.center_y(), + ..bounds + }, + color: Color::BLACK, + horizontal_alignment: HorizontalAlignment::Right, + vertical_alignment: VerticalAlignment::Center, + }; + ( - if let Some(label) = selected { - let label = Primitive::Text { - content: label, - size: f32::from(text_size), - font: Font::Default, - color: Color::BLACK, - bounds: Rectangle { - x: bounds.x + f32::from(padding), - y: bounds.center_y(), - ..bounds - }, - horizontal_alignment: HorizontalAlignment::Left, - vertical_alignment: VerticalAlignment::Center, - }; + Primitive::Group { + primitives: if let Some(label) = selected { + let label = Primitive::Text { + content: label, + size: f32::from(text_size), + font: Font::Default, + color: Color::BLACK, + bounds: Rectangle { + x: bounds.x + f32::from(padding), + y: bounds.center_y(), + ..bounds + }, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Center, + }; - Primitive::Group { - primitives: vec![background, label], - } - } else { - background + vec![background, label, arrow_down] + } else { + vec![background, arrow_down] + }, }, if is_mouse_over { mouse::Interaction::Pointer -- cgit From 0ff5a02550e5d5de8fb5fd0643ea424d9e508888 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 23 May 2020 01:07:59 +0200 Subject: Rename `Layer` to `overlay::Content` --- graphics/src/layer.rs | 2 - graphics/src/layer/menu.rs | 102 ------------------------------------------- graphics/src/lib.rs | 1 + graphics/src/overlay.rs | 1 + graphics/src/overlay/menu.rs | 102 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 104 deletions(-) delete mode 100644 graphics/src/layer/menu.rs create mode 100644 graphics/src/overlay.rs create mode 100644 graphics/src/overlay/menu.rs (limited to 'graphics/src') diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index ddf835a4..6aca738e 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -1,6 +1,4 @@ //! Organize rendering primitives into a flattened list of layers. -mod menu; - use crate::image; use crate::svg; use crate::triangle; diff --git a/graphics/src/layer/menu.rs b/graphics/src/layer/menu.rs deleted file mode 100644 index e94ef964..00000000 --- a/graphics/src/layer/menu.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::backend::Backend; -use crate::{Primitive, Renderer}; -use iced_native::{ - layer, mouse, Background, Color, Font, HorizontalAlignment, Point, - Rectangle, VerticalAlignment, -}; - -impl layer::menu::Renderer for Renderer -where - B: Backend, -{ - fn decorate( - &mut self, - bounds: Rectangle, - _cursor_position: Point, - (primitives, mouse_cursor): Self::Output, - ) -> Self::Output { - ( - Primitive::Group { - primitives: vec![ - Primitive::Quad { - bounds, - background: Background::Color( - [0.87, 0.87, 0.87].into(), - ), - border_color: [0.7, 0.7, 0.7].into(), - border_width: 1, - border_radius: 0, - }, - primitives, - ], - }, - mouse_cursor, - ) - } - - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - options: &[T], - hovered_option: Option, - text_size: u16, - padding: u16, - ) -> Self::Output { - use std::f32; - - let is_mouse_over = bounds.contains(cursor_position); - - let mut primitives = Vec::new(); - - for (i, option) in options.iter().enumerate() { - let is_selected = hovered_option == Some(i); - - let bounds = Rectangle { - x: bounds.x, - y: bounds.y - + ((text_size as usize + padding as usize * 2) * i) as f32, - width: bounds.width, - height: f32::from(text_size + padding * 2), - }; - - if is_selected { - primitives.push(Primitive::Quad { - bounds, - background: Background::Color([0.4, 0.4, 1.0].into()), - border_color: Color::TRANSPARENT, - border_width: 0, - border_radius: 0, - }); - } - - primitives.push(Primitive::Text { - content: option.to_string(), - bounds: Rectangle { - x: bounds.x + f32::from(padding), - y: bounds.center_y(), - width: f32::INFINITY, - ..bounds - }, - size: f32::from(text_size), - font: Font::Default, - color: if is_selected { - Color::WHITE - } else { - Color::BLACK - }, - horizontal_alignment: HorizontalAlignment::Left, - vertical_alignment: VerticalAlignment::Center, - }); - } - - ( - Primitive::Group { primitives }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } -} diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index bad35ccf..92e8432e 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -9,6 +9,7 @@ #![forbid(rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_cfg))] mod antialiasing; +mod overlay; mod primitive; mod renderer; mod transformation; diff --git a/graphics/src/overlay.rs b/graphics/src/overlay.rs new file mode 100644 index 00000000..c57668d4 --- /dev/null +++ b/graphics/src/overlay.rs @@ -0,0 +1 @@ +mod menu; diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs new file mode 100644 index 00000000..f4204f25 --- /dev/null +++ b/graphics/src/overlay/menu.rs @@ -0,0 +1,102 @@ +use crate::backend::Backend; +use crate::{Primitive, Renderer}; +use iced_native::{ + mouse, overlay, Background, Color, Font, HorizontalAlignment, Point, + Rectangle, VerticalAlignment, +}; + +impl overlay::menu::Renderer for Renderer +where + B: Backend, +{ + fn decorate( + &mut self, + bounds: Rectangle, + _cursor_position: Point, + (primitives, mouse_cursor): Self::Output, + ) -> Self::Output { + ( + Primitive::Group { + primitives: vec![ + Primitive::Quad { + bounds, + background: Background::Color( + [0.87, 0.87, 0.87].into(), + ), + border_color: [0.7, 0.7, 0.7].into(), + border_width: 1, + border_radius: 0, + }, + primitives, + ], + }, + mouse_cursor, + ) + } + + fn draw( + &mut self, + bounds: Rectangle, + cursor_position: Point, + options: &[T], + hovered_option: Option, + text_size: u16, + padding: u16, + ) -> Self::Output { + use std::f32; + + let is_mouse_over = bounds.contains(cursor_position); + + let mut primitives = Vec::new(); + + for (i, option) in options.iter().enumerate() { + let is_selected = hovered_option == Some(i); + + let bounds = Rectangle { + x: bounds.x, + y: bounds.y + + ((text_size as usize + padding as usize * 2) * i) as f32, + width: bounds.width, + height: f32::from(text_size + padding * 2), + }; + + if is_selected { + primitives.push(Primitive::Quad { + bounds, + background: Background::Color([0.4, 0.4, 1.0].into()), + border_color: Color::TRANSPARENT, + border_width: 0, + border_radius: 0, + }); + } + + primitives.push(Primitive::Text { + content: option.to_string(), + bounds: Rectangle { + x: bounds.x + f32::from(padding), + y: bounds.center_y(), + width: f32::INFINITY, + ..bounds + }, + size: f32::from(text_size), + font: Font::Default, + color: if is_selected { + Color::WHITE + } else { + Color::BLACK + }, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Center, + }); + } + + ( + Primitive::Group { primitives }, + if is_mouse_over { + mouse::Interaction::Pointer + } else { + mouse::Interaction::default() + }, + ) + } +} -- cgit From 61f22b1db23f3495145a9a4f7255311fe8381998 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 11 Jun 2020 20:41:11 +0200 Subject: Add styling support for `ComboBox` and `Menu` --- graphics/src/lib.rs | 4 ++-- graphics/src/overlay.rs | 2 +- graphics/src/overlay/menu.rs | 24 +++++++++++++---------- graphics/src/widget/combo_box.rs | 42 ++++++++++++++++++++++++++-------------- 4 files changed, 45 insertions(+), 27 deletions(-) (limited to 'graphics/src') diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 92e8432e..0c427634 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -9,18 +9,18 @@ #![forbid(rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_cfg))] mod antialiasing; -mod overlay; mod primitive; mod renderer; mod transformation; mod viewport; -mod widget; pub mod backend; pub mod defaults; pub mod font; pub mod layer; +pub mod overlay; pub mod triangle; +pub mod widget; pub mod window; #[doc(no_inline)] diff --git a/graphics/src/overlay.rs b/graphics/src/overlay.rs index c57668d4..b9a0e3e0 100644 --- a/graphics/src/overlay.rs +++ b/graphics/src/overlay.rs @@ -1 +1 @@ -mod menu; +pub mod menu; diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index f4204f25..13065645 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -1,18 +1,23 @@ use crate::backend::Backend; use crate::{Primitive, Renderer}; use iced_native::{ - mouse, overlay, Background, Color, Font, HorizontalAlignment, Point, - Rectangle, VerticalAlignment, + mouse, overlay, Color, Font, HorizontalAlignment, Point, Rectangle, + VerticalAlignment, }; +pub use iced_style::menu::Style; + impl overlay::menu::Renderer for Renderer where B: Backend, { + type Style = Style; + fn decorate( &mut self, bounds: Rectangle, _cursor_position: Point, + style: &Style, (primitives, mouse_cursor): Self::Output, ) -> Self::Output { ( @@ -20,11 +25,9 @@ where primitives: vec![ Primitive::Quad { bounds, - background: Background::Color( - [0.87, 0.87, 0.87].into(), - ), - border_color: [0.7, 0.7, 0.7].into(), - border_width: 1, + background: style.background, + border_color: style.border_color, + border_width: style.border_width, border_radius: 0, }, primitives, @@ -42,6 +45,7 @@ where hovered_option: Option, text_size: u16, padding: u16, + style: &Style, ) -> Self::Output { use std::f32; @@ -63,7 +67,7 @@ where if is_selected { primitives.push(Primitive::Quad { bounds, - background: Background::Color([0.4, 0.4, 1.0].into()), + background: style.selected_background, border_color: Color::TRANSPARENT, border_width: 0, border_radius: 0, @@ -81,9 +85,9 @@ where size: f32::from(text_size), font: Font::Default, color: if is_selected { - Color::WHITE + style.selected_text_color } else { - Color::BLACK + style.text_color }, horizontal_alignment: HorizontalAlignment::Left, vertical_alignment: VerticalAlignment::Center, diff --git a/graphics/src/widget/combo_box.rs b/graphics/src/widget/combo_box.rs index 92024c6c..078b5def 100644 --- a/graphics/src/widget/combo_box.rs +++ b/graphics/src/widget/combo_box.rs @@ -1,18 +1,29 @@ use crate::backend::{self, Backend}; use crate::{Primitive, Renderer}; use iced_native::{ - mouse, Background, Color, Font, HorizontalAlignment, Point, Rectangle, - VerticalAlignment, + mouse, Font, HorizontalAlignment, Point, Rectangle, VerticalAlignment, }; +use iced_style::menu; -pub use iced_native::ComboBox; +pub use iced_native::combo_box::State; +pub use iced_style::combo_box::{Style, StyleSheet}; + +/// A widget allowing the selection of a single value from a list of options. +pub type ComboBox<'a, T, Message, Backend> = + iced_native::ComboBox<'a, T, Message, Renderer>; impl iced_native::combo_box::Renderer for Renderer where B: Backend + backend::Text, { + type Style = Box; + const DEFAULT_PADDING: u16 = 5; + fn menu_style(style: &Box) -> menu::Style { + style.menu() + } + fn draw( &mut self, bounds: Rectangle, @@ -20,31 +31,34 @@ where selected: Option, text_size: u16, padding: u16, + style: &Box, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); + let style = if is_mouse_over { + style.hovered() + } else { + style.active() + }; + let background = Primitive::Quad { bounds, - background: Background::Color([0.87, 0.87, 0.87].into()), - border_color: if is_mouse_over { - Color::BLACK - } else { - [0.7, 0.7, 0.7].into() - }, - border_width: 1, - border_radius: 0, + background: style.background, + border_color: style.border_color, + border_width: style.border_width, + border_radius: style.border_radius, }; let arrow_down = Primitive::Text { content: B::ARROW_DOWN_ICON.to_string(), font: B::ICON_FONT, - size: bounds.height * 0.7, + size: bounds.height * style.icon_size, bounds: Rectangle { x: bounds.x + bounds.width - f32::from(padding) * 2.0, y: bounds.center_y(), ..bounds }, - color: Color::BLACK, + color: style.text_color, horizontal_alignment: HorizontalAlignment::Right, vertical_alignment: VerticalAlignment::Center, }; @@ -56,7 +70,7 @@ where content: label, size: f32::from(text_size), font: Font::Default, - color: Color::BLACK, + color: style.text_color, bounds: Rectangle { x: bounds.x + f32::from(padding), y: bounds.center_y(), -- cgit From 625979b6652a8a14a0eaf6bd62f1e9a8da0ae421 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 5 Jul 2020 05:44:10 +0200 Subject: Draft `Widget::overlay` idempotency --- graphics/src/overlay/menu.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics/src') diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index 13065645..914baa6a 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -1,4 +1,4 @@ -use crate::backend::Backend; +use crate::backend::{self, Backend}; use crate::{Primitive, Renderer}; use iced_native::{ mouse, overlay, Color, Font, HorizontalAlignment, Point, Rectangle, @@ -9,7 +9,7 @@ pub use iced_style::menu::Style; impl overlay::menu::Renderer for Renderer where - B: Backend, + B: Backend + backend::Text, { type Style = Style; -- cgit From 69ac47f463fd5c392f1f8e788fcf89b1a76abcae Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 8 Jul 2020 07:04:20 +0200 Subject: Implement `font` method for `ComboBox` --- graphics/src/overlay/menu.rs | 5 +++-- graphics/src/widget/combo_box.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'graphics/src') diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index 914baa6a..89a9cd03 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -43,8 +43,9 @@ where cursor_position: Point, options: &[T], hovered_option: Option, - text_size: u16, padding: u16, + text_size: u16, + font: Font, style: &Style, ) -> Self::Output { use std::f32; @@ -83,7 +84,7 @@ where ..bounds }, size: f32::from(text_size), - font: Font::Default, + font, color: if is_selected { style.selected_text_color } else { diff --git a/graphics/src/widget/combo_box.rs b/graphics/src/widget/combo_box.rs index 078b5def..e7ed4e04 100644 --- a/graphics/src/widget/combo_box.rs +++ b/graphics/src/widget/combo_box.rs @@ -29,8 +29,9 @@ where bounds: Rectangle, cursor_position: Point, selected: Option, - text_size: u16, padding: u16, + text_size: u16, + font: Font, style: &Box, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); @@ -69,7 +70,7 @@ where let label = Primitive::Text { content: label, size: f32::from(text_size), - font: Font::Default, + font, color: style.text_color, bounds: Rectangle { x: bounds.x + f32::from(padding), -- cgit From 33e6682882cd09dd210da123eb3b893e33bd977d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 8 Jul 2020 11:40:07 +0200 Subject: Avoid clipping antialiasing in `Renderer::overlay` --- graphics/src/renderer.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'graphics/src') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 771f436c..5ca6c057 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -67,7 +67,11 @@ where primitives: vec![ base_primitive, Primitive::Clip { - bounds: overlay_bounds, + bounds: Rectangle { + width: overlay_bounds.width + 0.5, + height: overlay_bounds.height + 0.5, + ..overlay_bounds + }, offset: Vector::new(0, 0), content: Box::new(overlay_primitives), }, -- cgit From dc0e423142f053c59c326d92920e7829b6852cca Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 10 Jul 2020 02:01:30 +0200 Subject: Remove unnecessary lifetime in `Widget` trait --- graphics/src/renderer.rs | 2 +- graphics/src/widget/canvas.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'graphics/src') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 5ca6c057..5d51e6d4 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -93,7 +93,7 @@ where fn explain( &mut self, defaults: &Defaults, - widget: &dyn Widget<'_, Message, Self>, + widget: &dyn Widget, layout: Layout<'_>, cursor_position: Point, color: Color, diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index 0257f819..b8466239 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -134,7 +134,7 @@ impl> Canvas { } } -impl<'a, Message, P, B> Widget<'a, Message, Renderer> for Canvas +impl Widget> for Canvas where P: Program, B: Backend, -- cgit From 2118a726f8b6134820e1ca5b7b802fa1344e453a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 10 Jul 2020 02:39:12 +0200 Subject: Write documentation for the new `overlay` API --- graphics/src/lib.rs | 2 +- graphics/src/overlay.rs | 1 + graphics/src/overlay/menu.rs | 1 + graphics/src/widget/combo_box.rs | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) (limited to 'graphics/src') diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 0c427634..d03f3b48 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -2,7 +2,7 @@ //! for [`iced`]. //! //! [`iced`]: https://github.com/hecrj/iced -//#![deny(missing_docs)] +#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![deny(unsafe_code)] diff --git a/graphics/src/overlay.rs b/graphics/src/overlay.rs index b9a0e3e0..bc0ed744 100644 --- a/graphics/src/overlay.rs +++ b/graphics/src/overlay.rs @@ -1 +1,2 @@ +//! Display interactive elements on top of other widgets. pub mod menu; diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index 89a9cd03..a952f065 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -1,3 +1,4 @@ +//! Build and show dropdown menus. use crate::backend::{self, Backend}; use crate::{Primitive, Renderer}; use iced_native::{ diff --git a/graphics/src/widget/combo_box.rs b/graphics/src/widget/combo_box.rs index e7ed4e04..f200c2b7 100644 --- a/graphics/src/widget/combo_box.rs +++ b/graphics/src/widget/combo_box.rs @@ -1,3 +1,4 @@ +//! Display a dropdown list of selectable values. use crate::backend::{self, Backend}; use crate::{Primitive, Renderer}; use iced_native::{ -- cgit From 73b8ae8e5e7f57c608c775272a2980995ab22bb3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 10 Jul 2020 02:50:47 +0200 Subject: Rename `ComboBox` to `PickList` --- graphics/src/widget.rs | 4 +- graphics/src/widget/combo_box.rs | 97 ---------------------------------------- graphics/src/widget/pick_list.rs | 97 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 98 deletions(-) delete mode 100644 graphics/src/widget/combo_box.rs create mode 100644 graphics/src/widget/pick_list.rs (limited to 'graphics/src') diff --git a/graphics/src/widget.rs b/graphics/src/widget.rs index a0d06999..94a65011 100644 --- a/graphics/src/widget.rs +++ b/graphics/src/widget.rs @@ -9,10 +9,10 @@ //! ``` pub mod button; pub mod checkbox; -pub mod combo_box; pub mod container; pub mod image; pub mod pane_grid; +pub mod pick_list; pub mod progress_bar; pub mod radio; pub mod scrollable; @@ -34,6 +34,8 @@ pub use container::Container; #[doc(no_inline)] pub use pane_grid::PaneGrid; #[doc(no_inline)] +pub use pick_list::PickList; +#[doc(no_inline)] pub use progress_bar::ProgressBar; #[doc(no_inline)] pub use radio::Radio; diff --git a/graphics/src/widget/combo_box.rs b/graphics/src/widget/combo_box.rs deleted file mode 100644 index f200c2b7..00000000 --- a/graphics/src/widget/combo_box.rs +++ /dev/null @@ -1,97 +0,0 @@ -//! Display a dropdown list of selectable values. -use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; -use iced_native::{ - mouse, Font, HorizontalAlignment, Point, Rectangle, VerticalAlignment, -}; -use iced_style::menu; - -pub use iced_native::combo_box::State; -pub use iced_style::combo_box::{Style, StyleSheet}; - -/// A widget allowing the selection of a single value from a list of options. -pub type ComboBox<'a, T, Message, Backend> = - iced_native::ComboBox<'a, T, Message, Renderer>; - -impl iced_native::combo_box::Renderer for Renderer -where - B: Backend + backend::Text, -{ - type Style = Box; - - const DEFAULT_PADDING: u16 = 5; - - fn menu_style(style: &Box) -> menu::Style { - style.menu() - } - - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - selected: Option, - padding: u16, - text_size: u16, - font: Font, - style: &Box, - ) -> Self::Output { - let is_mouse_over = bounds.contains(cursor_position); - - let style = if is_mouse_over { - style.hovered() - } else { - style.active() - }; - - let background = Primitive::Quad { - bounds, - background: style.background, - border_color: style.border_color, - border_width: style.border_width, - border_radius: style.border_radius, - }; - - let arrow_down = Primitive::Text { - content: B::ARROW_DOWN_ICON.to_string(), - font: B::ICON_FONT, - size: bounds.height * style.icon_size, - bounds: Rectangle { - x: bounds.x + bounds.width - f32::from(padding) * 2.0, - y: bounds.center_y(), - ..bounds - }, - color: style.text_color, - horizontal_alignment: HorizontalAlignment::Right, - vertical_alignment: VerticalAlignment::Center, - }; - - ( - Primitive::Group { - primitives: if let Some(label) = selected { - let label = Primitive::Text { - content: label, - size: f32::from(text_size), - font, - color: style.text_color, - bounds: Rectangle { - x: bounds.x + f32::from(padding), - y: bounds.center_y(), - ..bounds - }, - horizontal_alignment: HorizontalAlignment::Left, - vertical_alignment: VerticalAlignment::Center, - }; - - vec![background, label, arrow_down] - } else { - vec![background, arrow_down] - }, - }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } -} diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs new file mode 100644 index 00000000..f42a8707 --- /dev/null +++ b/graphics/src/widget/pick_list.rs @@ -0,0 +1,97 @@ +//! Display a dropdown list of selectable values. +use crate::backend::{self, Backend}; +use crate::{Primitive, Renderer}; +use iced_native::{ + mouse, Font, HorizontalAlignment, Point, Rectangle, VerticalAlignment, +}; +use iced_style::menu; + +pub use iced_native::pick_list::State; +pub use iced_style::pick_list::{Style, StyleSheet}; + +/// A widget allowing the selection of a single value from a list of options. +pub type PickList<'a, T, Message, Backend> = + iced_native::PickList<'a, T, Message, Renderer>; + +impl iced_native::pick_list::Renderer for Renderer +where + B: Backend + backend::Text, +{ + type Style = Box; + + const DEFAULT_PADDING: u16 = 5; + + fn menu_style(style: &Box) -> menu::Style { + style.menu() + } + + fn draw( + &mut self, + bounds: Rectangle, + cursor_position: Point, + selected: Option, + padding: u16, + text_size: u16, + font: Font, + style: &Box, + ) -> Self::Output { + let is_mouse_over = bounds.contains(cursor_position); + + let style = if is_mouse_over { + style.hovered() + } else { + style.active() + }; + + let background = Primitive::Quad { + bounds, + background: style.background, + border_color: style.border_color, + border_width: style.border_width, + border_radius: style.border_radius, + }; + + let arrow_down = Primitive::Text { + content: B::ARROW_DOWN_ICON.to_string(), + font: B::ICON_FONT, + size: bounds.height * style.icon_size, + bounds: Rectangle { + x: bounds.x + bounds.width - f32::from(padding) * 2.0, + y: bounds.center_y(), + ..bounds + }, + color: style.text_color, + horizontal_alignment: HorizontalAlignment::Right, + vertical_alignment: VerticalAlignment::Center, + }; + + ( + Primitive::Group { + primitives: if let Some(label) = selected { + let label = Primitive::Text { + content: label, + size: f32::from(text_size), + font, + color: style.text_color, + bounds: Rectangle { + x: bounds.x + f32::from(padding), + y: bounds.center_y(), + ..bounds + }, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Center, + }; + + vec![background, label, arrow_down] + } else { + vec![background, arrow_down] + }, + }, + if is_mouse_over { + mouse::Interaction::Pointer + } else { + mouse::Interaction::default() + }, + ) + } +} -- cgit