making the editor actually something
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 31 Jan 2022 02:56:13 +0000 (20:56 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 31 Jan 2022 02:56:13 +0000 (20:56 -0600)
src/entity/editor.onyx
src/main.onyx
src/utils/input.onyx

index 73d1b8e0336988286d05a541e9d1613faca5cec4..ad08f55365557ebecbb0937dc7becca35c9528c1 100644 (file)
@@ -1,26 +1,47 @@
 
+//
+// Editor features to be added:
+//
+// - [ ] Create new entity
+// - [ ] Edit entity properties in UI
+// - [ ] Serialize / Deserialize a scene
+//
+
 use package core
 use package opengles
 use package glfw3
 
-editor_shown := false;
-
 editor_init :: () {
     editor_font = font_lookup(.{"./assets/fonts/calibri.ttf", 18});
     selected_entity_id = Entity_Nothing;
 }
 
+editor_shown :: () => editor_openness != 0.0f || editor_target_openness != 0.0f;
+
 editor_toggle :: () {
-    editor_shown = !editor_shown;
+    editor_target_openness = 1.0f - editor_target_openness;
     selected_entity_id = Entity_Nothing;
     dragging = false;
 }
 
 editor_update :: (dt: f32) {
-    mx, my := mouse_get_position();
-    mouse_pos := Vector2.{ ~~mx, ~~my };
+    move_towards(^editor_openness, editor_target_openness, dt * 6);
+
+    handle_clicking_tab(dt);
+    handle_entity_selction_and_dragging(dt);
+}
 
-    if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) {
+#local handle_clicking_tab :: (dt: f32) {
+    if clicked_tab == .None do return;
+
+    active_tab = clicked_tab;
+    clicked_tab = .None;
+}
+
+#local handle_entity_selction_and_dragging :: (dt: f32) {
+    mouse_pos := mouse_get_position_vector();
+
+    if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && mouse_pos.x < ~~window_width - sidebar_width {
         selected_entity_id = Entity_Nothing;
         for entity_manager.entities {
             get_rect := entity_manager.entity_types[it.type].get_rect;
@@ -36,14 +57,20 @@ editor_update :: (dt: f32) {
     }
 
     if !is_button_down(GLFW_MOUSE_BUTTON_LEFT) {
-        dragging = false;        
+        dragging = false;
     }
 
-    // This will be replaced by a "tool" system
-    if dragging && selected_entity_id != Entity_Nothing {
-        dmx, dmy := mouse_get_delta();
+    if selected_entity_id != Entity_Nothing && active_tab == .Edit {
         selected_entity := entity_manager->get(selected_entity_id);
-        selected_entity.pos += Vector2.{~~dmx, ~~dmy};
+
+        if dragging {
+            selected_entity.pos += mouse_get_delta_vector();
+        } else {
+            if is_key_down(GLFW_KEY_UP)    do selected_entity.pos.y -= 32 * dt;
+            if is_key_down(GLFW_KEY_DOWN)  do selected_entity.pos.y += 32 * dt;
+            if is_key_down(GLFW_KEY_LEFT)  do selected_entity.pos.x -= 32 * dt;
+            if is_key_down(GLFW_KEY_RIGHT) do selected_entity.pos.x += 32 * dt;
+        }
     }
 }
 
@@ -61,38 +88,112 @@ editor_draw :: () {
         immediate_rectangle(r.x, r.y, r.w, r.h);
     }
 
-    immediate_set_color(.{0.5, 0.5, 0.5, 0.7});
+    background_color :: Color.{0.5, 0.5, 0.5, 0.7};
+
+    { // Draw menu bar
+        x := 0.0f;
+        w := cast(f32) window_width;
+        h := 40.0f;
+        y := h * (editor_openness - 1);
+
+        immediate_set_color(background_color);
+        immediate_rectangle(x, y, w, h);
 
-    x0 := cast(f32) window_width * 0.25;
-    x1 := cast(f32) window_width * 0.75;
-    y0 := cast(f32) window_height * 0.25;
-    y1 := cast(f32) window_height * 0.75;
+        x = 2;
+        y += 2;
+        h = 36;
+        w = 100;
 
-    immediate_rectangle(x0, y0, x1 - x0, y1 - y0);
+        for type_info.enum_values(Tabs) {
+            // Don't draw the "None" item;
+            if it.value == 0 do continue;
+
+            contains_mouse := Rect.contains(.{x, y, w, h}, mouse_get_position_vector());
+            if contains_mouse && is_button_down(GLFW_MOUSE_BUTTON_LEFT) {
+                clicked_tab = ~~ it.value;
+            }
 
-    font_set_color(.{1,1,1});
-    y0 += 20;
-    font_print(editor_font, x0, y0, "Registered Entity types:");
-    y0 += 20;
-    for entity_manager.entity_types.entries {
-        defer y0 += 20;
-        info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(it.key);
-        font_print(editor_font, x0, y0, "    {}\n", info.name);
+            if ~~it.value == active_tab {
+                immediate_set_color(.{0.4, 0.4, 0.5, 1});
+            } else {
+                // This would be nice to have some kind of lerping, but that would require
+                // a lot more structure to this, which I don't think will be worth it.
+                if contains_mouse {
+                    immediate_set_color(.{0.3, 0.3, 0.3, 1});
+                } else {
+                    immediate_set_color(.{0.2, 0.2, 0.2, 1});
+                }
+            }
+            immediate_rectangle(x, y, w, h);
+
+            text_width := font_get_width(editor_font, it.name);
+            font_draw(editor_font, x + (w - text_width) / 2, y + h / 2 + 18 / 4, it.name);
+            x += w;
+        }
     }
 
-    if selected_entity_id != Entity_Nothing {
-        selected_entity := entity_manager->get(selected_entity_id);
+    { // Draw sidebar, if necessary
+        sidebar_width = editor_openness * 300.0f;
+        w := sidebar_width; 
+        x := ~~ window_width - w;
+        y := 40.0f;
+        h := ~~ window_height - y;
+        immediate_set_color(background_color);
+        immediate_rectangle(x, y, w, h);
+
+        switch active_tab {
+            case .Create {
+
+            }
+
+            case .Edit {
+                if selected_entity_id != Entity_Nothing {
+                    selected_entity := entity_manager->get(selected_entity_id);
+                    render_entity_fields(selected_entity, x, y, w, h);
+                }
+            }
+        }
+    }
+}
 
-        switch_entity(selected_entity) {
-            entity_case(Player) { font_print(editor_font, x0, y0, "{*}", object); }
-            case #default { font_print(editor_font, x0, y0, "{*}", selected_entity); }
+#local render_entity_fields :: (entity: ^Entity, x, y, w, h: f32) {
+    assert(entity != null, "entity is null");
+    assert(type_info.struct_inherits(entity.type, Entity), "entity is not an entity");
+    info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(entity.type);
+
+    font_print(editor_font, x + 2, y + 20, info.name);
+
+    i := 0;
+    for info.members {
+        defer i += 1;
+        y += 20;
+
+        if i % 2 == 0 {
+           immediate_set_color(.{.3,.3,.3});
+           immediate_rectangle(x, y + 2, w, 22);
         }
+
+        font_print(editor_font, x + 22, y + 20, it.name);
     }
 }
 
 #local {
     editor_font: Font;
 
+    editor_openness := 0.0f;
+    editor_target_openness := 0.0f;
+
     selected_entity_id: Entity_ID;
     dragging := false;
+
+    sidebar_width := 0.0f;
+
+    Tabs :: enum {
+        None;
+        Create;
+        Edit;
+    }
+
+    active_tab  := Tabs.Create;
+    clicked_tab := Tabs.None;
 }
index e4d55db44a5064e897dd1b32980287bd158fd9c5..52f848773d14b172d78146554320bbe6a6119273 100644 (file)
@@ -71,7 +71,6 @@ init :: () {
 
 update :: (dt: f32) {
     input_update();
-    defer input_post_update();
 
     if is_key_down(GLFW_KEY_ESCAPE) {
         glfwSetWindowShouldClose(window, true);
@@ -82,7 +81,7 @@ update :: (dt: f32) {
         editor_toggle();
     }
 
-    if editor_shown {
+    if editor_shown() {
         editor_update(dt);
         return;
     }
@@ -92,10 +91,11 @@ update :: (dt: f32) {
 
 draw :: () {
     immediate_clear(.{0.1, 0.1, 0.1});
+    defer input_post_update();
     defer {
         immediate_flush();
         
-        #if DEBUG {
+        #if DEBUG && false {
             font_set_color(.{1,0,0});
             font_print(debug_font, 0, 16, "FPS: {}", game_fps);
             font_print(debug_font, 0, 32, "HEAP: {b16}", alloc.heap.get_watermark());
@@ -112,7 +112,7 @@ draw :: () {
     update_world_matrix();
     update_model_matrix(.{0,0});
 
-    if editor_shown {
+    if editor_shown() {
         editor_draw();
         return;
     }
index c8d7523c9f3951e424885a8b6f27c660ddd39733..09679958fd0e0bdd853ca2c054cbf88d00006f8b 100644 (file)
@@ -43,10 +43,19 @@ mouse_get_delta :: () -> (f64, f64) {
        return mouse_x - last_mouse_x, mouse_y - last_mouse_y;
 }
 
+mouse_get_delta_vector :: () -> Vector2 {
+       dmx, dmy := mouse_get_delta();
+       return .{ ~~dmx, ~~dmy };
+}
+
 mouse_get_position :: () -> (f64, f64) {
        return mouse_x, mouse_y;
 }
 
+mouse_get_position_vector :: () -> Vector2 {
+       return .{ ~~mouse_x, ~~mouse_y };
+}
+
 
 input_bind_glfw_events :: (window: GLFWwindow_p) {
        glfwSetKeyCallback(window, INPUT_KEY_EVENT);