Add Renderer::Defaults and style inheritance

This commit is contained in:
Héctor Ramón Jiménez 2019-12-30 12:14:26 +01:00
parent 89a6b8a9a1
commit 8caa66be27
32 changed files with 224 additions and 150 deletions

View File

@ -13,7 +13,7 @@ mod circle {
layout, Background, Color, Element, Hasher, Layout, Length, layout, Background, Color, Element, Hasher, Layout, Length,
MouseCursor, Point, Size, Widget, MouseCursor, Point, Size, Widget,
}; };
use iced_wgpu::{Primitive, Renderer}; use iced_wgpu::{Defaults, Primitive, Renderer};
pub struct Circle { pub struct Circle {
radius: u16, radius: u16,
@ -54,6 +54,7 @@ mod circle {
fn draw( fn draw(
&self, &self,
_renderer: &mut Renderer, _renderer: &mut Renderer,
_defaults: &Defaults,
layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: Point, _cursor_position: Point,
) -> (Primitive, MouseCursor) { ) -> (Primitive, MouseCursor) {

View File

@ -1,6 +1,6 @@
use iced::{ use iced::{
button, image, Align, Application, Button, Color, Column, Command, button, image, Align, Application, Button, Column, Command, Container,
Container, Element, Image, Length, Row, Settings, Text, Element, Image, Length, Row, Settings, Text,
}; };
pub fn main() { pub fn main() {
@ -219,7 +219,7 @@ impl From<surf::Exception> for Error {
} }
fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> { fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> {
Button::new(state, Text::new(text).color(Color::WHITE)) Button::new(state, Text::new(text))
.padding(10) .padding(10)
.style(style::Button::Primary) .style(style::Button::Primary)
} }
@ -239,6 +239,7 @@ mod style {
})), })),
border_radius: 12, border_radius: 12,
shadow_offset: 1.0, shadow_offset: 1.0,
text_color: Color::WHITE,
} }
} }
} }

View File

@ -1,6 +1,6 @@
use iced::{ use iced::{
button, Align, Application, Button, Color, Column, Command, Container, button, Align, Application, Button, Column, Command, Container, Element,
Element, HorizontalAlignment, Length, Row, Settings, Subscription, Text, HorizontalAlignment, Length, Row, Settings, Subscription, Text,
}; };
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -102,7 +102,6 @@ impl Application for Stopwatch {
Button::new( Button::new(
state, state,
Text::new(label) Text::new(label)
.color(Color::WHITE)
.horizontal_alignment(HorizontalAlignment::Center), .horizontal_alignment(HorizontalAlignment::Center),
) )
.min_width(80) .min_width(80)
@ -199,6 +198,7 @@ mod style {
})), })),
border_radius: 12, border_radius: 12,
shadow_offset: 1.0, shadow_offset: 1.0,
text_color: Color::WHITE,
} }
} }
} }

View File

@ -1,7 +1,7 @@
use iced::{ use iced::{
button, scrollable, text_input, Align, Application, Button, Checkbox, button, scrollable, text_input, Align, Application, Button, Checkbox,
Color, Column, Command, Container, Element, Font, HorizontalAlignment, Column, Command, Container, Element, Font, HorizontalAlignment, Length,
Length, Row, Scrollable, Settings, Text, TextInput, Row, Scrollable, Settings, Text, TextInput,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -291,13 +291,10 @@ impl Task {
.align_items(Align::Center) .align_items(Align::Center)
.push(checkbox) .push(checkbox)
.push( .push(
Button::new( Button::new(edit_button, edit_icon())
edit_button, .on_press(TaskMessage::Edit)
edit_icon().color([0.5, 0.5, 0.5]), .padding(10)
) .style(style::Button::Icon),
.on_press(TaskMessage::Edit)
.padding(10)
.style(style::Button::NoBackground),
) )
.into() .into()
} }
@ -321,14 +318,9 @@ impl Task {
.push( .push(
Button::new( Button::new(
delete_button, delete_button,
Row::new() Row::new().spacing(10).push(delete_icon()).push(
.spacing(10) Text::new("Delete").width(Length::Shrink),
.push(delete_icon().color(Color::WHITE)) ),
.push(
Text::new("Delete")
.width(Length::Shrink)
.color(Color::WHITE),
),
) )
.on_press(TaskMessage::Delete) .on_press(TaskMessage::Delete)
.padding(10) .padding(10)
@ -359,12 +351,10 @@ impl Controls {
let filter_button = |state, label, filter, current_filter| { let filter_button = |state, label, filter, current_filter| {
let label = Text::new(label).size(16).width(Length::Shrink); let label = Text::new(label).size(16).width(Length::Shrink);
let button = if filter == current_filter { let button =
Button::new(state, label.color(Color::WHITE)) Button::new(state, label).style(style::Button::Filter {
.style(style::Button::FilterSelected) selected: filter == current_filter,
} else { });
Button::new(state, label).style(style::Button::NoBackground)
};
button.on_press(Message::FilterChanged(filter)).padding(8) button.on_press(Message::FilterChanged(filter)).padding(8)
}; };
@ -564,25 +554,38 @@ mod style {
use iced::{button, Background, Color}; use iced::{button, Background, Color};
pub enum Button { pub enum Button {
FilterSelected, Filter { selected: bool },
NoBackground, Icon,
Destructive, Destructive,
} }
impl button::StyleSheet for Button { impl button::StyleSheet for Button {
fn active(&self) -> button::Style { fn active(&self) -> button::Style {
match self { match self {
Button::FilterSelected => button::Style { Button::Filter { selected } => {
background: Some(Background::Color(Color::from_rgb( if *selected {
0.2, 0.2, 0.7, button::Style {
))), background: Some(Background::Color(
border_radius: 10, Color::from_rgb(0.2, 0.2, 0.7),
shadow_offset: 0.0, )),
}, border_radius: 10,
Button::NoBackground => button::Style { shadow_offset: 0.0,
text_color: Color::WHITE,
}
} else {
button::Style {
background: None,
border_radius: 0,
shadow_offset: 0.0,
text_color: Color::BLACK,
}
}
}
Button::Icon => button::Style {
background: None, background: None,
border_radius: 0, border_radius: 0,
shadow_offset: 0.0, shadow_offset: 0.0,
text_color: Color::from_rgb(0.5, 0.5, 0.5),
}, },
Button::Destructive => button::Style { Button::Destructive => button::Style {
background: Some(Background::Color(Color::from_rgb( background: Some(Background::Color(Color::from_rgb(
@ -590,8 +593,25 @@ mod style {
))), ))),
border_radius: 5, border_radius: 5,
shadow_offset: 1.0, shadow_offset: 1.0,
text_color: Color::WHITE,
}, },
} }
} }
fn hovered(&self) -> button::Style {
let active = self.active();
button::Style {
text_color: match self {
Button::Icon => Color::from_rgb(0.2, 0.2, 0.7),
Button::Filter { selected } if !selected => {
Color::from_rgb(0.2, 0.2, 0.7)
}
_ => active.text_color,
},
shadow_offset: active.shadow_offset + 1.0,
..active
}
}
} }
} }

View File

@ -694,9 +694,7 @@ fn button<'a, Message>(
) -> Button<'a, Message> { ) -> Button<'a, Message> {
Button::new( Button::new(
state, state,
Text::new(label) Text::new(label).horizontal_alignment(HorizontalAlignment::Center),
.color(Color::WHITE)
.horizontal_alignment(HorizontalAlignment::Center),
) )
.padding(12) .padding(12)
.min_width(100) .min_width(100)
@ -761,6 +759,15 @@ mod style {
})), })),
border_radius: 12, border_radius: 12,
shadow_offset: 1.0, shadow_offset: 1.0,
text_color: Color::from_rgb8(0xEE, 0xEE, 0xEE),
}
}
fn hovered(&self) -> button::Style {
button::Style {
text_color: Color::WHITE,
shadow_offset: 2.0,
..self.active()
} }
} }
} }

View File

@ -235,10 +235,12 @@ where
pub fn draw( pub fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
self.widget.draw(renderer, layout, cursor_position) self.widget
.draw(renderer, defaults, layout, cursor_position)
} }
pub(crate) fn hash_layout(&self, state: &mut Hasher) { pub(crate) fn hash_layout(&self, state: &mut Hasher) {
@ -316,10 +318,12 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
self.widget.draw(renderer, layout, cursor_position) self.widget
.draw(renderer, defaults, layout, cursor_position)
} }
fn hash_layout(&self, state: &mut Hasher) { fn hash_layout(&self, state: &mut Hasher) {
@ -384,10 +388,12 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
renderer.explain( renderer.explain(
defaults,
self.element.widget.as_ref(), self.element.widget.as_ref(),
layout, layout,
cursor_position, cursor_position,

View File

@ -44,6 +44,8 @@ pub trait Renderer: Sized {
/// [`Renderer`]: trait.Renderer.html /// [`Renderer`]: trait.Renderer.html
type Output; type Output;
type Defaults: Default;
/// Lays out the elements of a user interface. /// Lays out the elements of a user interface.
/// ///
/// You should override this if you need to perform any operations before or /// You should override this if you need to perform any operations before or

View File

@ -17,6 +17,7 @@ pub trait Debugger: super::Renderer {
/// [`Element::explain`]: struct.Element.html#method.explain /// [`Element::explain`]: struct.Element.html#method.explain
fn explain<Message>( fn explain<Message>(
&mut self, &mut self,
defaults: &Self::Defaults,
widget: &dyn Widget<Message, Self>, widget: &dyn Widget<Message, Self>,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,

View File

@ -5,16 +5,26 @@ use crate::{
}; };
/// A renderer that does nothing. /// A renderer that does nothing.
///
/// It can be useful if you are writing tests!
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Null; pub struct Null;
impl Null {
pub fn new() -> Null {
Null
}
}
impl Renderer for Null { impl Renderer for Null {
type Output = (); type Output = ();
type Defaults = ();
} }
impl column::Renderer for Null { impl column::Renderer for Null {
fn draw<Message>( fn draw<Message>(
&mut self, &mut self,
_defaults: &Self::Defaults,
_content: &[Element<'_, Message, Self>], _content: &[Element<'_, Message, Self>],
_layout: Layout<'_>, _layout: Layout<'_>,
_cursor_position: Point, _cursor_position: Point,
@ -25,6 +35,7 @@ impl column::Renderer for Null {
impl row::Renderer for Null { impl row::Renderer for Null {
fn draw<Message>( fn draw<Message>(
&mut self, &mut self,
_defaults: &Self::Defaults,
_content: &[Element<'_, Message, Self>], _content: &[Element<'_, Message, Self>],
_layout: Layout<'_>, _layout: Layout<'_>,
_cursor_position: Point, _cursor_position: Point,
@ -49,6 +60,7 @@ impl text::Renderer for Null {
fn draw( fn draw(
&mut self, &mut self,
_defaults: &Self::Defaults,
_bounds: Rectangle, _bounds: Rectangle,
_content: &str, _content: &str,
_size: u16, _size: u16,
@ -119,13 +131,16 @@ impl text_input::Renderer for Null {
impl button::Renderer for Null { impl button::Renderer for Null {
type Style = (); type Style = ();
fn draw( fn draw<Message>(
&mut self, &mut self,
_defaults: &Self::Defaults,
_bounds: Rectangle, _bounds: Rectangle,
_cursor_position: Point, _cursor_position: Point,
_is_disabled: bool,
_is_pressed: bool, _is_pressed: bool,
_style: &Self::Style, _style: &Self::Style,
_content: Self::Output, _content: &Element<'_, Message, Self>,
_content_layout: Layout<'_>,
) -> Self::Output { ) -> Self::Output {
} }
} }

View File

@ -43,24 +43,7 @@ where
/// use iced_wgpu::Renderer; /// use iced_wgpu::Renderer;
/// ///
/// # mod iced_wgpu { /// # mod iced_wgpu {
/// # pub struct Renderer; /// # pub use iced_native::renderer::Null as Renderer;
/// #
/// # impl Renderer {
/// # pub fn new() -> Self { Renderer }
/// # }
/// #
/// # impl iced_native::Renderer for Renderer { type Output = (); }
/// #
/// # impl iced_native::column::Renderer for Renderer {
/// # fn draw<Message>(
/// # &mut self,
/// # _children: &[iced_native::Element<'_, Message, Self>],
/// # _layout: iced_native::Layout<'_>,
/// # _cursor_position: iced_native::Point,
/// # ) -> Self::Output {
/// # ()
/// # }
/// # }
/// # } /// # }
/// # /// #
/// # use iced_native::Column; /// # use iced_native::Column;
@ -139,24 +122,7 @@ where
/// use iced_wgpu::Renderer; /// use iced_wgpu::Renderer;
/// ///
/// # mod iced_wgpu { /// # mod iced_wgpu {
/// # pub struct Renderer; /// # pub use iced_native::renderer::Null as Renderer;
/// #
/// # impl Renderer {
/// # pub fn new() -> Self { Renderer }
/// # }
/// #
/// # impl iced_native::Renderer for Renderer { type Output = (); }
/// #
/// # impl iced_native::column::Renderer for Renderer {
/// # fn draw<Message>(
/// # &mut self,
/// # _children: &[iced_native::Element<'_, Message, Self>],
/// # _layout: iced_native::Layout<'_>,
/// # _cursor_position: iced_native::Point,
/// # ) -> Self::Output {
/// # ()
/// # }
/// # }
/// # } /// # }
/// # /// #
/// # use iced_native::Column; /// # use iced_native::Column;
@ -241,24 +207,7 @@ where
/// use iced_wgpu::Renderer; /// use iced_wgpu::Renderer;
/// ///
/// # mod iced_wgpu { /// # mod iced_wgpu {
/// # pub struct Renderer; /// # pub use iced_native::renderer::Null as Renderer;
/// #
/// # impl Renderer {
/// # pub fn new() -> Self { Renderer }
/// # }
/// #
/// # impl iced_native::Renderer for Renderer { type Output = (); }
/// #
/// # impl iced_native::column::Renderer for Renderer {
/// # fn draw<Message>(
/// # &mut self,
/// # _children: &[iced_native::Element<'_, Message, Self>],
/// # _layout: iced_native::Layout<'_>,
/// # _cursor_position: iced_native::Point,
/// # ) -> Self::Output {
/// # ()
/// # }
/// # }
/// # } /// # }
/// # /// #
/// # use iced_native::Column; /// # use iced_native::Column;
@ -304,6 +253,7 @@ where
pub fn draw(&self, renderer: &mut Renderer) -> Renderer::Output { pub fn draw(&self, renderer: &mut Renderer) -> Renderer::Output {
self.root.widget.draw( self.root.widget.draw(
renderer, renderer,
&Renderer::Defaults::default(),
Layout::new(&self.layout), Layout::new(&self.layout),
self.cursor_position, self.cursor_position,
) )

View File

@ -101,6 +101,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output; ) -> Renderer::Output;

View File

@ -216,21 +216,19 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
let content = self.content.draw(
renderer,
layout.children().next().unwrap(),
cursor_position,
);
renderer.draw( renderer.draw(
defaults,
layout.bounds(), layout.bounds(),
cursor_position, cursor_position,
self.on_press.is_none(),
self.state.is_pressed, self.state.is_pressed,
&self.style, &self.style,
content, &self.content,
layout.children().next().unwrap(),
) )
} }
@ -253,13 +251,16 @@ pub trait Renderer: crate::Renderer + Sized {
/// Draws a [`Button`]. /// Draws a [`Button`].
/// ///
/// [`Button`]: struct.Button.html /// [`Button`]: struct.Button.html
fn draw( fn draw<Message>(
&mut self, &mut self,
defaults: &Self::Defaults,
bounds: Rectangle, bounds: Rectangle,
cursor_position: Point, cursor_position: Point,
is_disabled: bool,
is_pressed: bool, is_pressed: bool,
style: &Self::Style, style: &Self::Style,
content: Self::Output, content: &Element<'_, Message, Self>,
content_layout: Layout<'_>,
) -> Self::Output; ) -> Self::Output;
} }

View File

@ -134,6 +134,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
@ -146,6 +147,7 @@ where
let label = text::Renderer::draw( let label = text::Renderer::draw(
renderer, renderer,
defaults,
label_layout.bounds(), label_layout.bounds(),
&self.label, &self.label,
text::Renderer::default_size(renderer), text::Renderer::default_size(renderer),

View File

@ -173,10 +173,11 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
renderer.draw(&self.children, layout, cursor_position) renderer.draw(defaults, &self.children, layout, cursor_position)
} }
fn hash_layout(&self, state: &mut Hasher) { fn hash_layout(&self, state: &mut Hasher) {
@ -213,6 +214,7 @@ pub trait Renderer: crate::Renderer + Sized {
/// [`Layout`]: ../layout/struct.Layout.html /// [`Layout`]: ../layout/struct.Layout.html
fn draw<Message>( fn draw<Message>(
&mut self, &mut self,
defaults: &Self::Defaults,
content: &[Element<'_, Message, Self>], content: &[Element<'_, Message, Self>],
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,

View File

@ -147,11 +147,13 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
self.content.draw( self.content.draw(
renderer, renderer,
defaults,
layout.children().next().unwrap(), layout.children().next().unwrap(),
cursor_position, cursor_position,
) )

View File

@ -95,6 +95,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
_defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: Point, _cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {

View File

@ -131,6 +131,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
@ -143,6 +144,7 @@ where
let label = text::Renderer::draw( let label = text::Renderer::draw(
renderer, renderer,
defaults,
label_layout.bounds(), label_layout.bounds(),
&self.label, &self.label,
text::Renderer::default_size(renderer), text::Renderer::default_size(renderer),

View File

@ -174,10 +174,11 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
renderer.draw(&self.children, layout, cursor_position) renderer.draw(defaults, &self.children, layout, cursor_position)
} }
fn hash_layout(&self, state: &mut Hasher) { fn hash_layout(&self, state: &mut Hasher) {
@ -215,6 +216,7 @@ pub trait Renderer: crate::Renderer + Sized {
/// [`Layout`]: ../layout/struct.Layout.html /// [`Layout`]: ../layout/struct.Layout.html
fn draw<Message>( fn draw<Message>(
&mut self, &mut self,
defaults: &Self::Defaults,
children: &[Element<'_, Message, Self>], children: &[Element<'_, Message, Self>],
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,

View File

@ -255,6 +255,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
@ -277,7 +278,12 @@ where
Point::new(cursor_position.x, -1.0) Point::new(cursor_position.x, -1.0)
}; };
self.content.draw(renderer, content_layout, cursor_position) self.content.draw(
renderer,
defaults,
content_layout,
cursor_position,
)
}; };
self::Renderer::draw( self::Renderer::draw(

View File

@ -178,6 +178,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
_defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {

View File

@ -91,6 +91,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
_defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: Point, _cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {

View File

@ -146,10 +146,12 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: Point, _cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {
renderer.draw( renderer.draw(
defaults,
layout.bounds(), layout.bounds(),
&self.content, &self.content,
self.size.unwrap_or(renderer.default_size()), self.size.unwrap_or(renderer.default_size()),
@ -209,6 +211,7 @@ pub trait Renderer: crate::Renderer {
/// [`VerticalAlignment`]: enum.VerticalAlignment.html /// [`VerticalAlignment`]: enum.VerticalAlignment.html
fn draw( fn draw(
&mut self, &mut self,
defaults: &Self::Defaults,
bounds: Rectangle, bounds: Rectangle,
content: &str, content: &str,
size: u16, size: u16,

View File

@ -343,6 +343,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
_defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) -> Renderer::Output { ) -> Renderer::Output {

27
wgpu/src/defaults.rs Normal file
View File

@ -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,
}
}
}

View File

@ -24,6 +24,7 @@
#![deny(unused_results)] #![deny(unused_results)]
#![deny(unsafe_code)] #![deny(unsafe_code)]
#![deny(rust_2018_idioms)] #![deny(rust_2018_idioms)]
pub mod defaults;
pub mod widget; pub mod widget;
mod image; mod image;
@ -33,6 +34,7 @@ mod renderer;
mod text; mod text;
mod transformation; mod transformation;
pub use defaults::Defaults;
pub use primitive::Primitive; pub use primitive::Primitive;
pub use renderer::{Renderer, Target}; pub use renderer::{Renderer, Target};
#[doc(no_inline)] #[doc(no_inline)]

View File

@ -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::{ use iced_native::{
renderer::{Debugger, Windowed}, renderer::{Debugger, Windowed},
Background, Color, Layout, MouseCursor, Point, Rectangle, Vector, Widget, Background, Color, Layout, MouseCursor, Point, Rectangle, Vector, Widget,
@ -411,6 +413,7 @@ impl Renderer {
impl iced_native::Renderer for Renderer { impl iced_native::Renderer for Renderer {
type Output = (Primitive, MouseCursor); type Output = (Primitive, MouseCursor);
type Defaults = Defaults;
fn layout<'a, Message>( fn layout<'a, Message>(
&mut self, &mut self,
@ -445,13 +448,15 @@ impl Windowed for Renderer {
impl Debugger for Renderer { impl Debugger for Renderer {
fn explain<Message>( fn explain<Message>(
&mut self, &mut self,
defaults: &Defaults,
widget: &dyn Widget<Message, Self>, widget: &dyn Widget<Message, Self>,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
color: Color, color: Color,
) -> Self::Output { ) -> Self::Output {
let mut primitives = Vec::new(); 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); explain_layout(layout, color, &mut primitives);
primitives.push(primitive); primitives.push(primitive);

View File

@ -1,21 +1,26 @@
use crate::{button::StyleSheet, Primitive, Renderer}; use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer};
use iced_native::{Background, MouseCursor, Point, Rectangle}; use iced_native::{Background, Element, Layout, MouseCursor, Point, Rectangle};
impl iced_native::button::Renderer for Renderer { impl iced_native::button::Renderer for Renderer {
type Style = Box<dyn StyleSheet>; type Style = Box<dyn StyleSheet>;
fn draw( fn draw<Message>(
&mut self, &mut self,
defaults: &Defaults,
bounds: Rectangle, bounds: Rectangle,
cursor_position: Point, cursor_position: Point,
is_disabled: bool,
is_pressed: bool, is_pressed: bool,
style: &Box<dyn StyleSheet>, style: &Box<dyn StyleSheet>,
(content, _): Self::Output, content: &Element<'_, Message, Self>,
content_layout: Layout<'_>,
) -> Self::Output { ) -> Self::Output {
let is_mouse_over = bounds.contains(cursor_position); let is_mouse_over = bounds.contains(cursor_position);
// TODO: Render proper shadows // 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 { if is_pressed {
style.pressed() style.pressed()
} else { } else {
@ -25,6 +30,18 @@ impl iced_native::button::Renderer for Renderer {
style.active() style.active()
}; };
let (content, _) = content.draw(
self,
&Defaults {
text: defaults::Text {
color: styling.text_color,
},
..*defaults
},
content_layout,
cursor_position,
);
( (
match styling.background { match styling.background {
None => content, None => content,

View File

@ -1 +0,0 @@

View File

@ -4,6 +4,7 @@ use iced_native::{column, Element, Layout, MouseCursor, Point};
impl column::Renderer for Renderer { impl column::Renderer for Renderer {
fn draw<Message>( fn draw<Message>(
&mut self, &mut self,
defaults: &Self::Defaults,
content: &[Element<'_, Message, Self>], content: &[Element<'_, Message, Self>],
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
@ -17,7 +18,7 @@ impl column::Renderer for Renderer {
.zip(layout.children()) .zip(layout.children())
.map(|(child, layout)| { .map(|(child, layout)| {
let (primitive, new_mouse_cursor) = let (primitive, new_mouse_cursor) =
child.draw(self, layout, cursor_position); child.draw(self, defaults, layout, cursor_position);
if new_mouse_cursor > mouse_cursor { if new_mouse_cursor > mouse_cursor {
mouse_cursor = new_mouse_cursor; mouse_cursor = new_mouse_cursor;

View File

@ -4,6 +4,7 @@ use iced_native::{row, Element, Layout, MouseCursor, Point};
impl row::Renderer for Renderer { impl row::Renderer for Renderer {
fn draw<Message>( fn draw<Message>(
&mut self, &mut self,
defaults: &Self::Defaults,
children: &[Element<'_, Message, Self>], children: &[Element<'_, Message, Self>],
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
@ -17,7 +18,7 @@ impl row::Renderer for Renderer {
.zip(layout.children()) .zip(layout.children())
.map(|(child, layout)| { .map(|(child, layout)| {
let (primitive, new_mouse_cursor) = let (primitive, new_mouse_cursor) =
child.draw(self, layout, cursor_position); child.draw(self, defaults, layout, cursor_position);
if new_mouse_cursor > mouse_cursor { if new_mouse_cursor > mouse_cursor {
mouse_cursor = new_mouse_cursor; mouse_cursor = new_mouse_cursor;

View File

@ -27,6 +27,7 @@ impl text::Renderer for Renderer {
fn draw( fn draw(
&mut self, &mut self,
defaults: &Self::Defaults,
bounds: Rectangle, bounds: Rectangle,
content: &str, content: &str,
size: u16, size: u16,
@ -40,7 +41,7 @@ impl text::Renderer for Renderer {
content: content.to_string(), content: content.to_string(),
size: f32::from(size), size: f32::from(size),
bounds, bounds,
color: color.unwrap_or(Color::BLACK), color: color.unwrap_or(defaults.text.color),
font, font,
horizontal_alignment, horizontal_alignment,
vertical_alignment, vertical_alignment,

View File

@ -5,7 +5,7 @@
//! [`Button`]: type.Button.html //! [`Button`]: type.Button.html
//! [`State`]: struct.State.html //! [`State`]: struct.State.html
use crate::Renderer; use crate::Renderer;
use iced_native::Background; use iced_native::{Background, Color};
pub use iced_native::button::State; pub use iced_native::button::State;
@ -19,6 +19,7 @@ pub struct Style {
pub shadow_offset: f32, pub shadow_offset: f32,
pub background: Option<Background>, pub background: Option<Background>,
pub border_radius: u16, pub border_radius: u16,
pub text_color: Color,
} }
pub trait StyleSheet { pub trait StyleSheet {
@ -41,7 +42,22 @@ pub trait StyleSheet {
} }
fn disabled(&self) -> Style { 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, shadow_offset: 1.0,
background: Some(Background::Color([0.5, 0.5, 0.5].into())), background: Some(Background::Color([0.5, 0.5, 0.5].into())),
border_radius: 5, border_radius: 5,
} text_color: Color::BLACK,
}
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,
} }
} }
} }