From c3d30ca92c55b1b7677c547b71d0aebeea5f9188 Mon Sep 17 00:00:00 2001
From: Ygg01 <y.laughing.man.y@gmail.com>
Date: Sat, 11 Jun 2022 15:46:19 +0200
Subject: [PATCH] Revert "Tried generic spinbox"

This reverts commit 99431431ecd0844925b0b5d9a3b2f666b839f242.
---
 examples/text_box.rs    |   6 +-
 src/widgets/spin_box.rs | 289 +++++++++++++++++-----------------------
 2 files changed, 123 insertions(+), 172 deletions(-)

diff --git a/examples/text_box.rs b/examples/text_box.rs
index 26e1366..5a51d02 100644
--- a/examples/text_box.rs
+++ b/examples/text_box.rs
@@ -18,7 +18,7 @@ fn TextBoxExample() {
     let (value, set_value, _) = use_state!("I started with a value!".to_string());
     let (empty_value, set_empty_value, _) = use_state!("".to_string());
     let (red_value, set_red_value, _) = use_state!("This text is red".to_string());
-    let (spin_value, set_spin_value, _) = use_state!(3.0f32);
+    let (spin_value, set_spin_value, _) = use_state!("3".to_string());
 
     let input_styles = Style {
         top: StyleProp::Value(Units::Pixels(10.0)),
@@ -43,7 +43,7 @@ fn TextBoxExample() {
     });
 
     let on_change_spin = OnChange::new(move |event| {
-        set_spin_value(32.0);
+        set_spin_value(event.value);
     });
 
     rsx! {
@@ -56,7 +56,7 @@ fn TextBoxExample() {
                 placeholder={Some("This is a placeholder".to_string())}
             />
             <TextBox styles={Some(red_text_styles)} value={red_value} on_change={Some(on_change_red)} />
-            <SpinBox<f32> styles={Some(input_styles)} value={spin_value} on_change={Some(on_change_spin)} />
+            <SpinBox styles={Some(input_styles)} value={spin_value} on_change={Some(on_change_spin)} />
         </Window>
     }
 }
diff --git a/src/widgets/spin_box.rs b/src/widgets/spin_box.rs
index b43aa4d..fa160c1 100644
--- a/src/widgets/spin_box.rs
+++ b/src/widgets/spin_box.rs
@@ -1,5 +1,3 @@
-use std::str::FromStr;
-
 use crate::{
     core::{
         render_command::RenderCommand,
@@ -11,19 +9,13 @@ use crate::{
 };
 use kayak_core::{
     styles::{LayoutType, StyleProp},
-    CursorIcon, Index, OnLayout, Widget,
+    CursorIcon, OnLayout,
 };
 
 use crate::widgets::{Background, Clip, OnChange, Text};
 
-#[derive(Debug, PartialEq, Clone, Default)]
-pub struct SpinBox<T> {
-    pub id: Index,
-    pub props: SpinBoxProps<T>,
-}
-
 #[derive(Debug, PartialEq, Clone)]
-pub struct SpinBoxProps<T> {
+pub struct SpinBoxProps {
     /// If true, prevents the widget from being focused (and consequently edited)
     pub disabled: bool,
     /// A callback for when the text value was changed
@@ -34,7 +26,7 @@ pub struct SpinBoxProps<T> {
     ///
     /// This is a controlled state. You _must_ set this to the value to you wish to be displayed.
     /// You can use the [`on_change`] callback to update this prop as the user types.
-    pub value: Option<T>,
+    pub value: String,
     pub styles: Option<Style>,
     /// Text on increment button defaults to `>`
     pub incr_str: String,
@@ -46,13 +38,14 @@ pub struct SpinBoxProps<T> {
     pub focusable: Option<bool>,
 }
 
-impl<T> Default for SpinBoxProps<T> {
-    fn default() -> SpinBoxProps<T> {
-        Self {
+
+impl Default for SpinBoxProps {
+    fn default() -> SpinBoxProps {
+        SpinBoxProps { 
             incr_str: ">".into(),
             decr_str: "<".into(),
             disabled: Default::default(),
-            on_change: Default::default(),
+            on_change:  Default::default(),
             placeholder: Default::default(),
             value: Default::default(),
             styles: Default::default(),
@@ -64,10 +57,7 @@ impl<T> Default for SpinBoxProps<T> {
     }
 }
 
-impl<T> WidgetProps for SpinBoxProps<T>
-where
-    T: Widget,
-{
+impl WidgetProps for SpinBoxProps {
     fn get_children(&self) -> Option<Children> {
         self.children.clone()
     }
@@ -96,6 +86,7 @@ where
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct FocusSpinbox(pub bool);
 
+#[widget]
 /// A widget that displays a spinnable text field
 ///
 /// # Props
@@ -110,161 +101,121 @@ pub struct FocusSpinbox(pub bool);
 /// | `on_layout` | ✅        |
 /// | `focusable` | ✅        |
 ///
-impl<T> Widget for SpinBox<T>
-where
-    T: Widget + ToString + FromStr + Default,
-{
-    type Props = SpinBoxProps<T>;
-
-    fn constructor(props: Self::Props) -> Self
-    where
-        Self: Sized,
-    {
-        Self {
-            id: Index::default(),
-            props,
-        }
-    }
-
-    fn get_id(&self) -> Index {
-        self.id
-    }
-
-    fn set_id(&mut self, id: Index) {
-        self.id = id;
-    }
-
-    fn get_props(&self) -> &Self::Props {
-        &self.props
-    }
-
-    fn get_props_mut(&mut self) -> &mut Self::Props {
-        &mut self.props
-    }
-
-    fn render(&mut self, context: &mut kayak_core::KayakContextRef) {
-        let children = self.props.get_children();
-        let mut props = self.props.clone();
-        let SpinBoxProps {
-            on_change,
-            placeholder,
-            value,
-            ..
-        } = props.clone();
-
-        props.styles = Some(
-            Style::default()
-                // Required styles
-                .with_style(Style {
-                    render_command: RenderCommand::Layout.into(),
-                    ..Default::default()
-                })
-                // Apply any prop-given styles
-                .with_style(&props.styles)
-                // If not set by props, apply these styles
-                .with_style(Style {
-                    top: Units::Pixels(0.0).into(),
-                    bottom: Units::Pixels(0.0).into(),
-                    height: Units::Pixels(26.0).into(),
-                    cursor: CursorIcon::Text.into(),
-                    ..Default::default()
-                }),
-        );
-
-        let background_styles = Style {
-            background_color: Color::new(0.176, 0.196, 0.215, 1.0).into(),
-            border_radius: Corner::all(5.0).into(),
-            height: Units::Pixels(26.0).into(),
-            padding_left: Units::Pixels(5.0).into(),
-            padding_right: Units::Pixels(5.0).into(),
-            ..Default::default()
-        };
-
-        let has_focus = context.create_state(FocusSpinbox(false)).unwrap();
-        let mut current_value = value.clone().map_or(String::new(), |f| { f.to_string()});
-        let cloned_on_change = on_change.clone();
-        let cloned_has_focus = has_focus.clone();
-
-        props.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.is_empty() {
-                        current_value.truncate(current_value.len() - 1);
-                    }
-                } else if !c.is_control() {
-                    current_value.push(c);
-                }
-                if let Some(on_change) = cloned_on_change.as_ref() {
-                    if let Ok(mut on_change) = on_change.0.write() {
-                        on_change(ChangeEvent {
-                            value: current_value.clone(),
-                        });
-                    }
-                }
+pub fn SpinBox(props: SpinBoxProps) {
+    let SpinBoxProps {
+        on_change,
+        placeholder,
+        value,
+        ..
+    } = props.clone();
+
+    props.styles = Some(
+        Style::default()
+            // Required styles
+            .with_style(Style {
+                render_command: RenderCommand::Layout.into(),
+                ..Default::default()
+            })
+            // Apply any prop-given styles
+            .with_style(&props.styles)
+            // If not set by props, apply these styles
+            .with_style(Style {
+                top: Units::Pixels(0.0).into(),
+                bottom: Units::Pixels(0.0).into(),
+                height: Units::Pixels(26.0).into(),
+                cursor: CursorIcon::Text.into(),
+                ..Default::default()
+            }),
+    );
+
+    let background_styles = Style {
+        background_color: Color::new(0.176, 0.196, 0.215, 1.0).into(),
+        border_radius: Corner::all(5.0).into(),
+        height: Units::Pixels(26.0).into(),
+        padding_left: Units::Pixels(5.0).into(),
+        padding_right: Units::Pixels(5.0).into(),
+        ..Default::default()
+    };
+
+    let has_focus = context.create_state(FocusSpinbox(false)).unwrap();
+
+    let mut current_value = value.clone();
+    let cloned_on_change = on_change.clone();
+    let cloned_has_focus = has_focus.clone();
+
+    props.on_event = Some(OnEvent::new(move |_, event| match event.event_type {
+        EventType::CharInput { c } => {
+            if !cloned_has_focus.get().0 {
+                return;
             }
-            EventType::Focus => cloned_has_focus.set(FocusSpinbox(true)),
-            EventType::Blur => cloned_has_focus.set(FocusSpinbox(false)),
-            _ => {}
-        }));
-
-        let text_styles = if value.is_none() || (has_focus.get().0 && value.is_none()) {
-            Style {
-                color: Color::new(0.5, 0.5, 0.5, 1.0).into(),
-                ..Style::default()
+            if is_backspace(c) {
+                if !current_value.is_empty() {
+                    current_value.truncate(current_value.len() - 1);
+                }
+            } else if !c.is_control() {
+                current_value.push(c);
             }
-        } else {
-            Style {
-                width: Units::Stretch(100.0).into(),
-                ..Style::default()
+            if let Some(on_change) = cloned_on_change.as_ref() {
+                if let Ok(mut on_change) = on_change.0.write() {
+                    on_change(ChangeEvent {
+                        value: current_value.clone(),
+                    });
+                }
             }
-        };
-
-        let button_style = Some(Style {
-            height: Units::Pixels(24.0).into(),
-            width: Units::Pixels(24.0).into(),
-            ..Default::default()
-        });
-
-        // if current_value.is_empty() {
-        //     current_value = placeholder.unwrap_or(current_value);
-        // };
-
-        // let value = if current_value.is_empty() {
-        //     None
-        // } else {
-        //     T::from_str(&current_value).ok()
-        // };
-
-        let inline_style = Style {
-            layout_type: StyleProp::Value(LayoutType::Row),
+        }
+        EventType::Focus => cloned_has_focus.set(FocusSpinbox(true)),
+        EventType::Blur => cloned_has_focus.set(FocusSpinbox(false)),
+        _ => {}
+    }));
+
+    let text_styles = if value.is_empty() || (has_focus.get().0 && value.is_empty()) {
+        Style {
+            color: Color::new(0.5, 0.5, 0.5, 1.0).into(),
+            ..Style::default()
+        }
+    } else {
+        Style {
+            width: Units::Stretch(100.0).into(),
             ..Style::default()
-        };
-
-        let incr_str = props.clone().incr_str;
-        let decr_str = props.clone().decr_str;
-        let content = value.clone().map_or(String::new(), |f| { f.to_string()});
-
-
-        rsx! {
-            <Background styles={Some(background_styles)}>
-                <Clip styles={Some(inline_style)}>
-                    <Button styles={button_style}>
-                        <Text content={decr_str} />
-                    </Button>
-                    <Text
-                        content={content}
-                        size={14.0}
-                        styles={Some(text_styles)}
-                    />
-                    <Button styles={button_style}>
-                        <Text content={incr_str} />
-                    </Button>
-                </Clip>
-            </Background>
         }
+    };
+
+    let button_style = Some(Style {
+        height: Units::Pixels(24.0).into(),
+        width: Units::Pixels(24.0).into(),
+        ..Default::default()
+    });
+
+    let value = if value.is_empty() {
+        placeholder.unwrap_or_else(|| value.clone())
+    } else {
+        value
+    };
+
+    let inline_style = Style {
+        layout_type: StyleProp::Value(LayoutType::Row),
+        ..Style::default()
+    };
+
+    let incr_str = props.clone().incr_str;
+    let decr_str = props.clone().decr_str;
+
+    rsx! {
+        <Background styles={Some(background_styles)}>
+            <Clip styles={Some(inline_style)}>
+                <Button styles={button_style}>
+                    <Text content={decr_str} />
+                </Button>
+                <Text
+                    content={value}
+                    size={14.0}
+                    styles={Some(text_styles)}
+                />
+                <Button styles={button_style}>
+                    <Text content={incr_str} />
+                </Button>
+            </Clip>
+        </Background>
     }
 }
 
-- 
GitLab