--- /dev/null
+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