From 05ac1ccfc41b13fdbb869292c888becd39e4e3e4 Mon Sep 17 00:00:00 2001
From: IceSentry <c.giguere42@gmail.com>
Date: Fri, 7 Jan 2022 22:33:52 -0500
Subject: [PATCH] TextBox text style improvements

* Use colour style for the text
* Use gray colour for the placeholder text
* Add more color constant
---
 examples/text_box.rs    | 37 ++++++++++++++++++++++++++++---------
 kayak_core/src/color.rs | 32 ++++++++++++++++++++++++++++++++
 src/widgets/text_box.rs | 26 ++++++++++++++++++++++----
 3 files changed, 82 insertions(+), 13 deletions(-)

diff --git a/examples/text_box.rs b/examples/text_box.rs
index 1a1ffe3..49b7a7f 100644
--- a/examples/text_box.rs
+++ b/examples/text_box.rs
@@ -3,6 +3,7 @@ use bevy::{
     window::WindowDescriptor,
     DefaultPlugins,
 };
+use kayak_core::Color;
 use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle};
 use kayak_ui::core::{
     render, rsx,
@@ -16,32 +17,50 @@ fn TextBoxExample(context: &mut KayakContext) {
     let value = context
         .create_state("I started with a value!".to_string())
         .unwrap();
-    let value2 = context.create_state("".to_string()).unwrap();
+    let red_value = context
+        .create_state("This text is red".to_string())
+        .unwrap();
+    let empty_value = context.create_state("".to_string()).unwrap();
 
     let input_styles = Style {
         top: StyleProp::Value(Units::Pixels(10.0)),
         ..Default::default()
     };
 
+    let red_text_styles = Style {
+        color: StyleProp::Value(Color::RED),
+        ..input_styles.clone()
+    };
+
     let cloned_value = value.clone();
     let on_change = OnChange::new(move |event| {
         cloned_value.set(event.value);
     });
 
-    let cloned_value2 = value2.clone();
+    let cloned_value2 = empty_value.clone();
     let on_change2 = OnChange::new(move |event| {
         cloned_value2.set(event.value);
     });
 
+    let cloned_red_value = red_value.clone();
+    let on_change_red = OnChange::new(move |event| {
+        cloned_red_value.set(event.value);
+    });
+
     let current_value = value.get();
-    let current_value2 = value2.get();
+    let current_value2 = empty_value.get();
+    let current_red_value = red_value.get();
     rsx! {
-        <>
-            <Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"TextBox Example".to_string()}>
-                <TextBox styles={Some(input_styles)} value={current_value} on_change={Some(on_change)} />
-                <TextBox styles={Some(input_styles)} value={current_value2} on_change={Some(on_change2)} />
-            </Window>
-        </>
+        <Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"TextBox Example".to_string()}>
+            <TextBox styles={Some(input_styles)} value={current_value} on_change={Some(on_change)} />
+            <TextBox
+                styles={Some(input_styles)}
+                value={current_value2}
+                on_change={Some(on_change2)}
+                placeholder={Some("This is a placeholder".to_string())}
+            />
+            <TextBox styles={Some(red_text_styles)} value={current_red_value} on_change={Some(on_change_red)} />
+        </Window>
     }
 }
 
diff --git a/kayak_core/src/color.rs b/kayak_core/src/color.rs
index b71a107..94b81c1 100644
--- a/kayak_core/src/color.rs
+++ b/kayak_core/src/color.rs
@@ -34,6 +34,38 @@ impl Color {
         a: 1.0,
     };
 
+    /// The white color.
+    pub const GRAY: Color = Color {
+        r: 0.5,
+        g: 0.5,
+        b: 0.5,
+        a: 1.0,
+    };
+
+    /// The red color.
+    pub const RED: Color = Color {
+        r: 1.0,
+        g: 0.0,
+        b: 0.0,
+        a: 1.0,
+    };
+
+    /// The green color.
+    pub const GREEN: Color = Color {
+        r: 0.0,
+        g: 1.0,
+        b: 0.0,
+        a: 1.0,
+    };
+
+    /// The blue color.
+    pub const BLUE: Color = Color {
+        r: 0.0,
+        g: 0.0,
+        b: 1.0,
+        a: 1.0,
+    };
+
     /// A color with no opacity.
     pub const TRANSPARENT: Color = Color {
         r: 0.0,
diff --git a/src/widgets/text_box.rs b/src/widgets/text_box.rs
index ee5ab76..72bb3a4 100644
--- a/src/widgets/text_box.rs
+++ b/src/widgets/text_box.rs
@@ -70,13 +70,14 @@ pub fn TextBox(value: String, on_change: Option<OnChange>, placeholder: Option<S
     let mut current_value = value.clone();
     let cloned_on_change = on_change.clone();
     let cloned_has_focus = has_focus.clone();
+
     self.on_event = Some(OnEvent::new(move |_, event| match event.event_type {
         EventType::CharInput { c } => {
             if !cloned_has_focus.get().0 {
                 return;
             }
             if is_backspace(c) {
-                if current_value.len() > 0 {
+                if !current_value.is_empty() {
                     current_value.truncate(current_value.len() - 1);
                 }
             } else if !c.is_control() {
@@ -95,15 +96,32 @@ pub fn TextBox(value: String, on_change: Option<OnChange>, placeholder: Option<S
         _ => {}
     }));
 
+    let text_styles = if value.is_empty() || (has_focus.get().0 && value.is_empty()) {
+        Style {
+            color: StyleProp::Value(Color::GRAY),
+            ..Style::default()
+        }
+    } else {
+        Style {
+            color: styles.clone().unwrap_or_default().color,
+            ..Style::default()
+        }
+    };
+
     let value = if value.is_empty() {
-        placeholder.clone().unwrap_or(value.clone())
+        placeholder.unwrap_or_else(|| value.clone())
     } else {
-        value.clone()
+        value
     };
+
     rsx! {
         <Background styles={Some(background_styles)}>
             <Clip>
-                <Text content={value} size={14.0} />
+                <Text
+                    content={value}
+                    size={14.0}
+                    styles={Some(text_styles)}
+                />
             </Clip>
         </Background>
     }
-- 
GitLab