+//
+// 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;
}
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;
+ }
}
}
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;
}