From 8caa66be2708b1c83e20d905d69902c2567c4692 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector0193@gmail.com>
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<Message>(
         &mut self,
+        defaults: &Defaults,
         widget: &dyn Widget<Message, Self>,
         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<dyn StyleSheet>;
 
-    fn draw(
+    fn draw<Message>(
         &mut self,
+        defaults: &Defaults,
         bounds: Rectangle,
         cursor_position: Point,
+        is_disabled: bool,
         is_pressed: bool,
         style: &Box<dyn StyleSheet>,
-        (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<Message>(
         &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<Message>(
         &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<Background>,
     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