From bbba74d88a9e622fd574a3f291c25768b26010a0 Mon Sep 17 00:00:00 2001
From: StarArawn <toasterthegamer@gmail.com>
Date: Mon, 20 Dec 2021 09:56:14 -0500
Subject: [PATCH] Use clone internally for every widget prop.

---
 bevy_kayak_ui/src/render/unified/pipeline.rs  |  6 +++++
 examples/full_ui.rs                           |  2 +-
 examples/todo/card.rs                         |  2 --
 kayak_core/src/node.rs                        | 22 +++++++++++++++++--
 kayak_core/src/styles.rs                      |  4 ++++
 kayak_render_macros/src/function_component.rs |  1 +
 kayak_widgets/src/if_element.rs               |  2 +-
 kayak_widgets/src/image.rs                    |  2 +-
 kayak_widgets/src/nine_patch.rs               |  5 +----
 kayak_widgets/src/text.rs                     |  4 ++--
 kayak_widgets/src/text_box.rs                 | 17 ++++++++++----
 kayak_widgets/src/window.rs                   |  2 ++
 12 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/bevy_kayak_ui/src/render/unified/pipeline.rs b/bevy_kayak_ui/src/render/unified/pipeline.rs
index b098884..562a110 100644
--- a/bevy_kayak_ui/src/render/unified/pipeline.rs
+++ b/bevy_kayak_ui/src/render/unified/pipeline.rs
@@ -594,6 +594,12 @@ impl Draw<TransparentUI> for DrawUI {
             if width == 0 || height == 0 {
                 return;
             }
+            if x + width > window_size.0 as u32 {
+                width = window_size.0 as u32 - x;
+            }
+            if y + height > window_size.1 as u32 {
+                height = window_size.1 as u32 - y;
+            }
             pass.set_scissor_rect(x, y, width, height);
             return;
         }
diff --git a/examples/full_ui.rs b/examples/full_ui.rs
index 9295e4e..94bed23 100644
--- a/examples/full_ui.rs
+++ b/examples/full_ui.rs
@@ -52,7 +52,7 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>)
     };
 
     let cloned_current_button_handle = current_button_handle.clone();
-    let on_event = OnEvent::new(move |_context, event| match event.event_type {
+    let on_event = OnEvent::new(move |_, event| match event.event_type {
         EventType::MouseIn => {
             cloned_current_button_handle.set(blue_button_hover_handle);
         }
diff --git a/examples/todo/card.rs b/examples/todo/card.rs
index 7bb615c..8134e55 100644
--- a/examples/todo/card.rs
+++ b/examples/todo/card.rs
@@ -9,7 +9,6 @@ use super::delete_button::DeleteButton;
 
 #[widget]
 pub fn Card(card_id: usize, name: String, on_delete: Handler<usize>) {
-    let name = name.clone();
     let background_styles = Style {
         layout_type: StyleProp::Value(LayoutType::Row),
         background_color: StyleProp::Value(Color::new(0.176, 0.196, 0.215, 1.0)),
@@ -23,7 +22,6 @@ pub fn Card(card_id: usize, name: String, on_delete: Handler<usize>) {
     };
 
     let on_delete = on_delete.clone();
-    let card_id = *card_id;
     let on_event = OnEvent::new(move |_, event| match event.event_type {
         EventType::Click => {
             on_delete.call(card_id);
diff --git a/kayak_core/src/node.rs b/kayak_core/src/node.rs
index 91023eb..d07d534 100644
--- a/kayak_core/src/node.rs
+++ b/kayak_core/src/node.rs
@@ -142,11 +142,29 @@ impl<'a> morphorm::Node<'a> for Index {
         Some(morphorm::Units::Auto)
     }
 
-    fn max_width(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+    fn max_width(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(*self) {
+            if let Some(node) = node {
+                return match node.styles.max_width {
+                    StyleProp::Default => Some(morphorm::Units::Auto),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => Some(morphorm::Units::Auto),
+                };
+            }
+        }
         Some(morphorm::Units::Auto)
     }
 
-    fn max_height(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+    fn max_height(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(*self) {
+            if let Some(node) = node {
+                return match node.styles.max_height {
+                    StyleProp::Default => Some(morphorm::Units::Auto),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => Some(morphorm::Units::Auto),
+                };
+            }
+        }
         Some(morphorm::Units::Auto)
     }
 
diff --git a/kayak_core/src/styles.rs b/kayak_core/src/styles.rs
index 850f17b..51767b5 100644
--- a/kayak_core/src/styles.rs
+++ b/kayak_core/src/styles.rs
@@ -55,6 +55,8 @@ pub struct Style {
     pub margin_bottom: StyleProp<Units>,
     pub min_width: StyleProp<Units>,
     pub min_height: StyleProp<Units>,
+    pub max_width: StyleProp<Units>,
+    pub max_height: StyleProp<Units>,
 }
 
 impl Default for Style {
@@ -82,6 +84,8 @@ impl Default for Style {
             margin_bottom: StyleProp::Default,
             min_width: StyleProp::Default,
             min_height: StyleProp::Default,
+            max_width: StyleProp::Default,
+            max_height: StyleProp::Default,
         }
     }
 }
diff --git a/kayak_render_macros/src/function_component.rs b/kayak_render_macros/src/function_component.rs
index 9e96bec..58c4e29 100644
--- a/kayak_render_macros/src/function_component.rs
+++ b/kayak_render_macros/src/function_component.rs
@@ -141,6 +141,7 @@ pub fn create_function_widget(f: syn::ItemFn, widget_arguments: WidgetArguments)
     } else {
         quote!(
             let #struct_name { #(#input_names),*, styles, .. } = self;
+            #(let #input_names = #input_names.clone();)*
         )
     };
 
diff --git a/kayak_widgets/src/if_element.rs b/kayak_widgets/src/if_element.rs
index bcf9b94..c2e2917 100644
--- a/kayak_widgets/src/if_element.rs
+++ b/kayak_widgets/src/if_element.rs
@@ -2,7 +2,7 @@ use kayak_ui::core::{rsx, widget, Children};
 
 #[widget]
 pub fn If(children: Children, condition: bool) {
-    if *condition {
+    if condition {
         rsx! {
             <>
                 {children}
diff --git a/kayak_widgets/src/image.rs b/kayak_widgets/src/image.rs
index 8e2d2f5..c44cb60 100644
--- a/kayak_widgets/src/image.rs
+++ b/kayak_widgets/src/image.rs
@@ -8,7 +8,7 @@ use kayak_ui::core::{
 #[widget]
 pub fn Image(handle: u16, children: Children) {
     *styles = Some(Style {
-        render_command: StyleProp::Value(RenderCommand::Image { handle: *handle }),
+        render_command: StyleProp::Value(RenderCommand::Image { handle }),
         ..styles.clone().unwrap_or_default()
     });
 
diff --git a/kayak_widgets/src/nine_patch.rs b/kayak_widgets/src/nine_patch.rs
index c31f774..f491da9 100644
--- a/kayak_widgets/src/nine_patch.rs
+++ b/kayak_widgets/src/nine_patch.rs
@@ -9,10 +9,7 @@ use kayak_ui::core::{
 #[widget]
 pub fn NinePatch(handle: u16, border: Space, children: Children) {
     *styles = Some(Style {
-        render_command: StyleProp::Value(RenderCommand::NinePatch {
-            handle: *handle,
-            border: *border,
-        }),
+        render_command: StyleProp::Value(RenderCommand::NinePatch { handle, border }),
         ..styles.clone().unwrap_or_default()
     });
 
diff --git a/kayak_widgets/src/text.rs b/kayak_widgets/src/text.rs
index 9357357..dbaf349 100644
--- a/kayak_widgets/src/text.rs
+++ b/kayak_widgets/src/text.rs
@@ -7,8 +7,8 @@ use kayak_ui::core::{
 #[widget]
 pub fn Text(size: f32, content: String, styles: Option<Style>) {
     let render_command = RenderCommand::Text {
-        content: content.clone(),
-        size: *size,
+        content,
+        size,
         font: 0, // TODO: Support font passing here. Perhaps move to style?
     };
     *styles = Some(Style {
diff --git a/kayak_widgets/src/text_box.rs b/kayak_widgets/src/text_box.rs
index 75e43c7..2a7f612 100644
--- a/kayak_widgets/src/text_box.rs
+++ b/kayak_widgets/src/text_box.rs
@@ -39,12 +39,21 @@ pub struct Focus(pub bool);
 
 #[widget(focusable)]
 pub fn TextBox(value: String, on_change: Option<OnChange>, placeholder: Option<String>) {
+    let current_styles = styles.clone().unwrap_or_default();
     *styles = Some(Style {
         render_command: StyleProp::Value(RenderCommand::Layout),
         height: StyleProp::Value(Units::Pixels(26.0)),
-        top: StyleProp::Value(Units::Pixels(0.0)),
-        bottom: StyleProp::Value(Units::Pixels(0.0)),
-        ..styles.clone().unwrap_or_default()
+        top: if matches!(current_styles.top, StyleProp::Value { .. }) {
+            current_styles.top.clone()
+        } else {
+            StyleProp::Value(Units::Pixels(0.0))
+        },
+        bottom: if matches!(current_styles.bottom, StyleProp::Value { .. }) {
+            current_styles.top.clone()
+        } else {
+            StyleProp::Value(Units::Pixels(0.0))
+        },
+        ..current_styles
     });
 
     let background_styles = Style {
@@ -105,4 +114,4 @@ pub fn TextBox(value: String, on_change: Option<OnChange>, placeholder: Option<S
 /// Context: [Wikipedia](https://en.wikipedia.org/wiki/Backspace#Common_use)
 fn is_backspace(c: char) -> bool {
     c == '\u{8}' || c == '\u{7f}'
-}
\ No newline at end of file
+}
diff --git a/kayak_widgets/src/window.rs b/kayak_widgets/src/window.rs
index c2cdee3..0b9abc5 100644
--- a/kayak_widgets/src/window.rs
+++ b/kayak_widgets/src/window.rs
@@ -25,6 +25,8 @@ pub fn Window(
         top: StyleProp::Value(Units::Pixels(position.1)),
         width: StyleProp::Value(Units::Pixels(size.0)),
         height: StyleProp::Value(Units::Pixels(size.1)),
+        max_width: StyleProp::Value(Units::Pixels(size.0)),
+        max_height: StyleProp::Value(Units::Pixels(size.1)),
         ..styles.clone().unwrap_or_default()
     });
 
-- 
GitLab