From: Brendan Hansen Date: Mon, 31 Jan 2022 02:56:13 +0000 (-0600) Subject: making the editor actually something X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8207abafbe07651a8ed5cd1dfbb66fe40a38eef5;p=bar-game.git making the editor actually something --- diff --git a/src/entity/editor.onyx b/src/entity/editor.onyx index 73d1b8e..ad08f55 100644 --- a/src/entity/editor.onyx +++ b/src/entity/editor.onyx @@ -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; } diff --git a/src/main.onyx b/src/main.onyx index e4d55db..52f8487 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -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; } diff --git a/src/utils/input.onyx b/src/utils/input.onyx index c8d7523..0967995 100644 --- a/src/utils/input.onyx +++ b/src/utils/input.onyx @@ -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);