added radio buttons to ui library
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 12 Jun 2021 13:27:57 +0000 (08:27 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 12 Jun 2021 13:27:57 +0000 (08:27 -0500)
modules/ui/components/radio.onyx [new file with mode: 0644]
modules/ui/module.onyx

diff --git a/modules/ui/components/radio.onyx b/modules/ui/components/radio.onyx
new file mode 100644 (file)
index 0000000..7f9feed
--- /dev/null
@@ -0,0 +1,95 @@
+package ui
+use package core
+
+Radio_Theme :: struct {
+    use text_theme := Text_Theme.{};
+
+    radio_color         := gfx.Color4.{ 0.2, 0.2, 0.2 };
+    radio_border_radius := 4.0f;   @InPixels
+    radio_radius        := 12.0f;  @InPixels
+
+    selected_color       := gfx.Color4.{ 1, 0, 0 };
+    selected_hover_color := gfx.Color4.{ 1, 0.6, 0.6 };
+
+    background_color := gfx.Color4.{ 0.05, 0.05, 0.05 };
+    hover_color      := gfx.Color4.{ 0.3, 0.3, 0.3 };
+    click_color      := gfx.Color4.{ 0.5, 0.5, 0.7 };
+}
+
+default_radio_theme := Radio_Theme.{};
+
+@Themeing
+radio :: (use r: Rectangle, selected: ^$T, value: T, text: str, theme := ^default_radio_theme, site := #callsite, increment := 0) -> bool {
+    result := false;
+
+    hash := get_site_hash(site, increment);
+    animation_state := map.get(^animation_states, hash);
+
+    if is_active_item(hash) {
+        if mouse_state.left_button_just_up {
+            if is_hot_item(hash) && Rectangle.contains(r, mouse_state.x, mouse_state.y) {
+                result = true;
+                *selected = value;
+                animation_state.click_time = 1.0f;
+            }
+
+            set_active_item(0);
+        }
+
+    } elseif is_hot_item(hash) {
+        if mouse_state.left_button_down {
+            set_active_item(hash);
+        }
+    }
+
+    if Rectangle.contains(r, mouse_state.x, mouse_state.y) {
+        set_hot_item(hash);
+    }
+
+    if is_hot_item(hash) {
+        move_towards(^animation_state.hover_time, 1.0f, 0.1f);  @ThemeConfiguration
+    } else {
+        move_towards(^animation_state.hover_time, 0.0f, 0.1f);  @ThemeConfiguration
+    }
+
+    radius           := theme.radio_radius;
+    width, height    := Rectangle.dimensions(r);
+
+    cx, cy := x0 + radius, y0 + height / 2;
+
+    gfx.set_texture();
+    gfx.circle(.{ cx, cy }, radius, color=theme.radio_color);
+
+    surface_color : gfx.Color4;
+    if *selected == value {
+        surface_color = theme.selected_color;
+        surface_color = color_lerp(animation_state.hover_time, surface_color, theme.selected_hover_color);
+
+    } else {
+        surface_color = theme.background_color;
+        surface_color = color_lerp(animation_state.hover_time, surface_color, theme.hover_color);
+    }
+
+    surface_color = color_lerp(animation_state.click_time, surface_color, theme.click_color);
+
+    gfx.circle(.{ cx, cy }, radius - theme.radio_border_radius, color=surface_color);
+
+    text_width  := bmfont.get_width(^font, text, theme.font_size);
+    text_height := bmfont.get_height(^font, text, theme.font_size);
+
+    draw_text_raw(
+        text,
+        x0 + 2 * radius + 4, @ThemeConfiguration
+        y0 + ~~ font.common.baseline * theme.font_size + (height - text_height) / 2,
+        theme.font_size, theme.text_color);
+
+    move_towards(^animation_state.click_time, 0.0f, 0.08f);   @ThemeConfiguration
+
+    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 d4063502f74a79994696a6f4f5336062cc0fe8b5..3b28f922133d5d90709b9a77961205e9fa0ea3b2 100644 (file)
@@ -38,6 +38,7 @@ package ui
 #load "./components/button"
 #load "./components/checkbox"
 #load "./components/slider"
+#load "./components/radio"
 
 
 // Package inclusions that are part of all files in the "ui" package.