added checkboxes; starting to make something of the editor
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 8 Feb 2022 12:29:24 +0000 (06:29 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 8 Feb 2022 12:29:24 +0000 (06:29 -0600)
src/entity/editor.onyx
src/gfx/ui.onyx

index e59bab665d4525dbf8d976b43f5c717fd0a33f78..efedda2cfb32fc6a9ae4785dac2f34be0f684a78 100644 (file)
@@ -64,7 +64,7 @@ editor_update :: (dt: f32) {
 #local handle_entity_selction_and_dragging :: (dt: f32) {
     mouse_pos := mouse_get_position_vector();
 
-    if mouse_pos.x < ~~window_width - sidebar_width && mouse_pos.y > menubar_height {
+    if mouse_pos.x < ~~window_width - sidebar_width * 2 && mouse_pos.y > menubar_height {
         if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) || is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) {
             if active_tab == .Edit do active_index = -1;
             selected_entity_id = Entity_Nothing;
@@ -200,6 +200,10 @@ editor_draw :: () {
     }
 
     draw_textbox(.{x, y + 72.0f, w, 36.0f}, ^test);
+
+    #persist dumb := false;
+
+    draw_checkbox(.{x, y + 150, w, 36.0f}, ^dumb, "Testing checkboxes");
 }
 
 #local render_entity_fields :: (entity: ^Entity, x, y, w, h: f32) {
@@ -289,6 +293,37 @@ editor_draw :: () {
         type_is(f32) {
             font_print(editor_font, x, y + 32, "FLOAT: {}\n", value);
         }
+
+        case #default {
+            info := type_info.get_type_info(v.type);
+
+            if info.kind == .Enum {
+                enum_info := cast(^type_info.Type_Info_Enum) info;
+                value: u64;
+                switch enum_info.backing_type {
+                    case i8,  u8  do value = cast(u64) *(cast(^u8) v.data);
+                    case i16, u16 do value = cast(u64) *(cast(^u16) v.data);
+                    case i32, u32 do value = cast(u64) *(cast(^u32) v.data);
+                    case i64, u64 do value = cast(u64) *(cast(^u64) v.data);
+                    case #default do assert(false, "Bad enum backing type");
+                }
+
+                if enum_info.is_flags {
+                    for^ enum_info.members {
+                        y += 20;
+                        checkbox_value := (value & it.value) != 0;
+                        if draw_checkbox(.{x, y, w, 20}, ^checkbox_value, it.name, increment=~~y) {
+                            println(checkbox_value);
+
+                            if !checkbox_value do *cast(^u32) v.data = ~~(value & ~it.value);
+                            else               do *cast(^u32) v.data = ~~(value |  it.value);
+                        }
+                    }
+                } else {
+
+                }
+            }
+        }
     }
 
     type_is :: macro (T: type_expr, body: Code) {
index 0e987cecc4cb8edd4c9e1d7facd8b0cabfcc950a..62871bdff4ecb3a0fb6becd5cbdfc51cb84308a4 100644 (file)
@@ -251,6 +251,95 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
 
 
 
+//
+// Checkboxes
+//
+Checkbox_Theme :: struct {
+    use text_theme := Text_Theme.{};
+    use animation_theme := Animation_Theme.{};
+
+    box_color        := Color.{ 0.2, 0.2, 0.2 };
+    box_border_width := 4.0f;    @InPixels
+    box_size         := 20.0f;   @InPixels
+
+    checked_color       := Color.{ 1, 0, 0 };
+    checked_hover_color := Color.{ 1, 0.6, 0.6 };
+
+    background_color := Color.{ 0.05, 0.05, 0.05 };  // Background of the checkbox button.
+    hover_color      := Color.{ 0.3, 0.3, 0.3 };
+    click_color      := Color.{ 0.5, 0.5, 0.7 };
+}
+
+#local default_checkbox_theme := Checkbox_Theme.{};
+
+draw_checkbox :: (use r: Rect, value: ^bool, text: str, theme := ^default_checkbox_theme, site := #callsite, increment := 0) -> bool {
+    result := false;
+
+    hash := get_site_hash(site, increment);
+    animation_state := get_animation(hash);
+    mx, my := mouse_get_position();
+
+    contains := Rect.contains(r, .{~~mx, ~~my});
+
+    if is_active_item(hash) {
+        if is_button_just_up(GLFW_MOUSE_BUTTON_LEFT) {
+            if is_hot_item(hash) && contains {
+                result = true;
+                *value = !*value;
+                animation_state.click_time = 1.0f;
+            }
+
+            set_active_item(0);
+        }
+    } elseif is_hot_item(hash) {
+        if is_button_down(GLFW_MOUSE_BUTTON_LEFT) {
+            set_active_item(hash);
+        }
+    }
+
+    if contains {
+        set_hot_item(hash);
+    }
+
+    if is_hot_item(hash) {
+        move_towards(^animation_state.hover_time, 1.0f, theme.hover_speed);
+    } else {
+        move_towards(^animation_state.hover_time, 0.0f, theme.hover_speed);
+    }
+
+    box_border_width := theme.box_border_width;
+    box_size         := theme.box_size;
+
+    immediate_set_color(theme.box_color);
+    immediate_rectangle(x + 4, y + (h - box_size) / 2, box_size, box_size);
+
+    surface_color : Color;
+    if *value {
+        surface_color = theme.checked_color;
+        surface_color = color_lerp(animation_state.hover_time, surface_color, theme.checked_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);
+
+    immediate_set_color(surface_color);
+    immediate_rectangle(x + 4 + box_border_width, y + (h - box_size) / 2 + box_border_width, box_size - box_border_width * 2, box_size - box_border_width * 2);
+
+    font := font_lookup(.{theme.font_name, theme.font_size});
+    text_width  := font_get_width(font, text);
+    text_height := font_get_height(font, text);
+
+    font_set_color(theme.text_color);
+    font_draw(font, x + box_size + 4 * 2, y + font.em + (h - text_height) / 2, text);
+
+    move_towards(^animation_state.click_time, 0.0f, theme.click_decay_speed);
+
+    return result;
+}
+
 
 #local {
     hot_item    : UI_Id = 0