added more internal control to ui animations
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 16 Sep 2021 03:47:17 +0000 (22:47 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 16 Sep 2021 03:47:17 +0000 (22:47 -0500)
modules/ui/components/button.onyx
modules/ui/components/checkbox.onyx
modules/ui/components/radio.onyx
modules/ui/components/slider.onyx
modules/ui/components/textbox.onyx
modules/ui/ui.onyx

index 170c764383f68f4d3655db67e20e58e796aa92fe..82ac73cc5191a4411e5d858a6415c0bf82df0960 100644 (file)
@@ -19,7 +19,7 @@ button :: (use r: Rectangle, text: str, theme := ^default_button_theme, site :=
     result := false;
 
     hash := get_site_hash(site, increment);
-    animation_state := map.get(^animation_states, hash);
+    animation_state := get_animation(hash);
     mx, my := get_mouse_position();
 
     if is_active_item(hash) {
@@ -73,11 +73,5 @@ button :: (use r: Rectangle, text: str, theme := ^default_button_theme, site :=
 
     move_towards(^animation_state.click_time, 0.0f, theme.click_decay_speed);
 
-    if animation_state.click_time > 0 || animation_state.hover_time > 0 {
-        map.put(^animation_states, hash, animation_state);
-    } else {
-        map.delete(^animation_states, hash);
-    }
-
     return result;
 }
index 2d60b5172d9ca17a784ef2e0c1f68ccbd3d93072..891c80b41c81a6d8c918abeb77470aab4b6eadc3 100644 (file)
@@ -23,7 +23,7 @@ checkbox :: (use r: Rectangle, value: ^bool, text: str, theme := ^default_checkb
     result := false;
 
     hash := get_site_hash(site, increment);
-    animation_state := map.get(^animation_states, hash);
+    animation_state := get_animation(hash);
     mx, my := get_mouse_position();
 
     if is_active_item(hash) {
@@ -94,11 +94,5 @@ checkbox :: (use r: Rectangle, value: ^bool, text: str, theme := ^default_checkb
 
     move_towards(^animation_state.click_time, 0.0f, theme.click_decay_speed);
 
-    if animation_state.click_time > 0 || animation_state.hover_time > 0 {
-        map.put(^animation_states, hash, animation_state);
-    } else {
-        map.delete(^animation_states, hash);
-    }
-
     return result;
-}
\ No newline at end of file
+}
index 53183b35582482291ac529d342728df434702d92..502cbcb566833fead8816a7ddcee16d48be0648e 100644 (file)
@@ -23,7 +23,7 @@ radio :: (use r: Rectangle, selected: ^$T, value: T, text: str, theme := ^defaul
     result := false;
 
     hash := get_site_hash(site, increment);
-    animation_state := map.get(^animation_states, hash);
+    animation_state := get_animation(hash);
 
     mx, my := get_mouse_position();
 
@@ -87,11 +87,5 @@ radio :: (use r: Rectangle, selected: ^$T, value: T, text: str, theme := ^defaul
 
     move_towards(^animation_state.click_time, 0.0f, theme.click_decay_speed);
 
-    if animation_state.click_time > 0 || animation_state.hover_time > 0 {
-        map.put(^animation_states, hash, animation_state);
-    } else {
-        map.delete(^animation_states, hash);
-    }
-
     return result;
-}
\ No newline at end of file
+}
index 403d706a2141e7ec178d51180d23a9a8286a4e38..7272eb886d651d72bc7932bff062d9c8eed5f892 100644 (file)
@@ -21,7 +21,7 @@ slider :: (use r: Rectangle, value: ^$T, min_value: T, max_value: T, theme := ^d
     result := false;
 
     hash := get_site_hash(site, increment);
-    animation_state := map.get(^animation_states, hash);
+    animation_state := get_animation(hash);
     width, height := Rectangle.dimensions(r);
     mx, my := get_mouse_position();
 
@@ -81,11 +81,5 @@ slider :: (use r: Rectangle, value: ^$T, min_value: T, max_value: T, theme := ^d
         .{ box_width, height - box_border_width * 2 },
         bar_color);
 
-    if animation_state.click_time > 0 || animation_state.hover_time > 0 {
-        map.put(^animation_states, hash, animation_state);
-    } else {
-        map.delete(^animation_states, hash);
-    }
-
     return result;
 }
index fc5c8c0f1ec2297703a68563df89206cb0503320..052c475316cc2aac12f4ce95d523717f372c0c6e 100644 (file)
@@ -47,7 +47,7 @@ textbox :: (use r: Rectangle, text_buffer: ^string.String_Buffer, placeholder :=
     result := false;
 
     hash := get_site_hash(site, increment);
-    animation_state := map.get(^animation_states, hash);
+    animation_state := get_animation(hash);
     mx, my := get_mouse_position();
 
     border_width  := theme.border_width;
@@ -179,12 +179,6 @@ textbox :: (use r: Rectangle, text_buffer: ^string.String_Buffer, placeholder :=
 
     move_towards(^animation_state.click_time, 0.0f, theme.click_decay_speed);
 
-    if animation_state.click_time > 0 || animation_state.hover_time > 0 {
-        map.put(^animation_states, hash, animation_state);
-    } else {
-        map.delete(^animation_states, hash);
-    }
-
     return result;
 }
 
@@ -471,4 +465,4 @@ key_map := u8.[
     /* 227 */    #char "\0",   #char "\0",
     /* 228 */    #char "\0",   #char "\0",
     /* 229 */    #char "\0",   #char "\0",
-];
\ No newline at end of file
+];
index 980cc8c75a24b1ebf065ff2748856adac26c7474..e924453d4317319f5df296eccf429e6c0e683719 100644 (file)
@@ -58,6 +58,19 @@ end_frame :: () {
         if *s == .Just_Down do *s = .Down;
         if *s == .Just_Up   do *s = .Up;
     }
+
+    for ^state: animation_states.entries {
+        // If the animation isn't being used anymore, discard it. This makes the has_active_animation function
+        // correct, otherwise, there could be animations that didn't finish, but the element was removed, and is
+        // no longer being updated.
+        if !state.value.accessed_this_frame || (state.value.click_time == 0 && state.value.hover_time == 0) {
+            map.delete(^animation_states, state.key);
+        }
+    }
+
+    for ^state: animation_states.entries {
+        state.value.accessed_this_frame = false;
+    }
 }
 
 set_active_item :: (id: UI_Id) -> bool {
@@ -179,11 +192,26 @@ Animation_Theme :: struct {
 // Animation states are stored globally as there is not much to the state of a button.
 // Forcing the end user to store a structure for each button that is just the animation
 // state of the component feels very wrong.
-#private animation_states : Map(UI_Id, Animation_State);
+#private_file animation_states : Map(UI_Id, Animation_State);
 
 Animation_State :: struct {
     hover_time := 0.0f;
     click_time := 0.0f;
+
+    accessed_this_frame := false;
+}
+
+get_animation :: (id: UI_Id) -> ^Animation_State {
+    retval := map.get_ptr(^animation_states, id);
+
+    if retval == null {
+        map.put(^animation_states, id, .{});
+        retval = map.get_ptr(^animation_states, id);
+    }
+
+    // printf("{*}\n", retval);
+    retval.accessed_this_frame = true;
+    return retval;
 }
 
 has_active_animation :: () -> bool {