diff --git a/src/modules/stream/ui/building_layout_graph_ui.h b/src/modules/stream/ui/building_layout_graph_ui.h index afff1cd..306b99f 100644 --- a/src/modules/stream/ui/building_layout_graph_ui.h +++ b/src/modules/stream/ui/building_layout_graph_ui.h @@ -34,10 +34,53 @@ public: { dlg->connect("tree_entered", this, "tree_entered"); } - void menu_pressed(int id, Control *button) + void menu_pressed(int id, Control *button, const String &path) { assert(button); print_line(itos(id)); + print_line(path); + flecs::world ecs = BaseData::get_singleton()->get(); + flecs::entity base_e = ecs.lookup(path.ascii().ptr()); + switch (id) { + case 100: + case 101: + case 102: + case 103: { + int count = 0; + String type_name; + switch (id) { + case 100: + type_name = "unit"; + break; + case 101: + case 102: + type_name = "zone"; + break; + } + if (type_name.length() == 0) + return; + base_e.children([type_name, &count](flecs::entity e) { + String name(e.name()); + if (name.begins_with(type_name + "_" + + itos(count))) + count++; + }); + String ename = type_name + "_" + itos(count); + flecs::entity new_e = + ecs.entity(ename.ascii().ptr()).child_of(base_e); + if (id == 100) { + new_e.set({ 0 }); + } else if (id == 101) { + new_e.set({ 0 }); + } else if (id == 102) { + new_e.set({ 1 }); + } + } break; + } + update_graph(); } flecs::entity get_layout_base() { @@ -84,8 +127,11 @@ public: if (e.is_valid()) return; e = ecs.entity(layout_name.ascii().ptr()).child_of(base); - if (e.is_valid()) + if (e.is_valid()) { e.add(); + e.set( + { 0 }); + } } flecs::entity get_current_layout() { @@ -133,8 +179,11 @@ public: selected = i; break; } - if (selected >= 0) + if (selected >= 0) { item_list->select(selected); + select_layout(selected); + update_graph(); + } if (!item_list->is_connected("item_selected", this, "select_layout")) item_list->connect("item_selected", this, @@ -178,22 +227,57 @@ public: void update_buttons(ColorRect *canvas) { assert(current_layout.length() > 0); - flecs::entity e = get_current_layout(); + flecs::entity layout_e = get_current_layout(); List queue; bool layout_empty = true; - queue.push_back(e); - HashMap depth_height; - depth_height[0] = 0; - buttons.clear(); + queue.push_back(layout_e); + layout_e.set< + WorldEditor::components::buildings_layout_graph_node>( + { 0, 0, 0 }); + queue.clear(); + queue.push_back(layout_e); while (!queue.empty()) { + flecs::entity e = queue.front()->get(); + queue.pop_front(); + int size = 1; + bool readd = false; + e.children([&readd, &size, &queue](flecs::entity fe) { + if (!fe.has()) { + fe.set( + { 0, 0, 0 }); + readd = true; + } + size += fe.get() + ->size; + queue.push_back(fe); + }); + if (readd) + queue.push_back(e); + if (e.get() + ->size != size) { + e.get_mut() + ->size = size; + if (e.parent() + .has()) + queue.push_back(e); + } + } + queue.clear(); + queue.push_back(layout_e); + while (!queue.empty()) { + buttons.clear(); layout_empty = false; flecs::entity e = queue.front()->get(); queue.pop_front(); if (!e.has()) { - e.set( - { 0, 0 }); + assert(false); } int depth = e.get() @@ -201,18 +285,109 @@ public: int y = e.get() ->y_pos; + e.get_mut() + ->y_pos = y; /* make button here */ - Vector2 pt(depth * 100 + 40, y * 60 + 40); - buttons.push_back(pt); + Vector2 pt(depth * 120 + 40, y * 110 + 40); { MenuButton *button = memnew(MenuButton); - button->set_text("XXX"); + button->set_text(""); canvas->add_child(button); button->set_size(Vector2(80, 40)); button->set_position(pt); if (e.has()) { - button->set_text("Entry"); + buildings_layout_floor>()) { + button->set_text(button->get_text() + + "Floor\n" + + String(e.name())); + button->get_popup()->add_item( + "Create block unit", 100); + button->get_popup()->add_item( + "Create private zone", 101); + button->get_popup()->add_item( + "Create public zone", 102); + } + if (e.has()) { + button->set_text(button->get_text() + + "Unit\n" + + String(e.name())); + button->get_popup()->add_item( + "Create private zone", 101); + button->get_popup()->add_item( + "Create public zone", 102); + } + if (e.has()) { + int zone_type = + e.get() + ->type; + if (zone_type == 0) { + button->set_text( + button->get_text() + + "Private Zone\n"); + button->get_popup()->add_item( + "Create WC", 200); + button->get_popup()->add_item( + "Create Bathroom", 201); + button->get_popup()->add_item( + "Create Bedroom", 202); + button->get_popup()->add_item( + "Create Holding Cell", + 203); + button->get_popup()->add_item( + "Create Torture Room", + 203); + } else if (zone_type == 1) { + button->set_text( + button->get_text() + + "Public Zone\n"); + button->get_popup()->add_item( + "Create Living Room", + 300); + button->get_popup()->add_item( + "Create Family Room", + 301); + button->get_popup()->add_item( + "Create Kitchen", 302); + button->get_popup()->add_item( + "Create Dinging Room", + 303); + button->get_popup()->add_item( + "Create Enterance", + 304); + button->get_popup()->add_item( + "Create Stair", 305); + button->get_popup()->add_item( + "Create Elevator", 306); + button->get_popup()->add_item( + "Create Storage Room", + 307); + button->get_popup()->add_item( + "Create Cellar", 308); + button->get_popup()->add_item( + "Create Office", 309); + button->get_popup()->add_item( + "Create Server Room", + 310); + button->get_popup()->add_item( + "Create Room", 311); + PopupMenu *mp = + memnew(PopupMenu); + mp->add_child(memnew(LineEdit)); + button->get_popup()->add_child( + mp); + mp->set_name("subedit"); + button->get_popup() + ->add_submenu_item( + "SubEdit Moo", + "subedit", 400); + } + button->set_text(button->get_text() + + String(e.name())); +#if 0 button->get_popup()->add_item( "Create block unit", 100); button->get_popup()->add_item( @@ -221,34 +396,38 @@ public: "Create public zone", 102); button->get_popup()->add_item( "Create hallway", 103); - button->get_popup()->connect( - "id_pressed", this, - "menu_pressed", varray(button)); +#endif } +#if 0 + button->set_text( + button->get_text() + "size: \n" + + itos(e.get() + ->size)); +#endif + button->get_popup()->connect( + "id_pressed", this, "menu_pressed", + varray(button, String(e.path()))); } int count = 0; + int offset = y; e.children([depth, y, &count, &queue, - &depth_height](flecs::entity e) { - e.set( - { depth + 1, y + count }); - queue.push_back(e); - if (!depth_height.has(depth + 1)) - depth_height[depth + 1] = 0; - depth_height[depth + 1] = - MAX(depth_height[depth + 1], - y + count) + - 1; + &offset](flecs::entity fe) { + int size = + fe.get() + ->size; + fe.set( + { depth + 1, offset, size }); + offset += size; + queue.push_back(fe); + count++; }); - if (!depth_height.has(depth)) - depth_height[depth] = y + count + 1; - else { - y = MAX(depth_height[depth], y); - e.set( - { depth, y }); - depth_height[depth] = y + count + 1; - } + + // if (count > 1) + // height += count - 1; + // // height++; } #if 0 if (layout_empty) { @@ -307,11 +486,58 @@ public: } void draw_graph() { + List queue; + if (current_layout.length() == 0) { + canvas_item->draw_rect(Rect2(Vector2(), + canvas_item->get_size()), + Color(0.4, 0.4, 0.65, 1.0)); + // canvas_item->draw_string() + return; + } + flecs::entity layout_e = get_current_layout(); + queue.push_back(layout_e); canvas_item->draw_rect(Rect2(Vector2(), canvas_item->get_size()), Color(0.2, 0.2, 0.25, 1.0)); - canvas_item->draw_circle(Vector2(40, 45) + Vector2(40, 20), - 40.0f, Color(0.4, 0.4, 0.55, 1.0)); + while (!queue.empty()) { + Vector2 p1; + flecs::entity button_e = queue.front()->get(); + if (button_e.has()) { + int depth = + button_e.get() + ->depth; + int y = button_e.get() + ->y_pos; + Vector2 pt(depth * 120 + 40, y * 110 + 40); + canvas_item->draw_circle( + pt + Vector2(40, 20), 40.0f, + Color(0.4, 0.4, 0.55, 1.0)); + p1 = pt + Vector2(40, 20); + } + queue.pop_front(); + button_e.children([&queue, this, p1](flecs::entity e) { + int depth = + e.get() + ->depth; + int y = e.get() + ->y_pos; + Vector2 p2(depth * 120 + 40, y * 110 + 40); + p2 += Vector2(40, 20); + Vector2 p3(p1.x, p2.y); + canvas_item->draw_line(p1, p3, + Color(0.4, 0.4, 0.55), + 4.0f, true); + canvas_item->draw_line(p3, p2, + Color(0.4, 0.4, 0.55), + 4.0f, true); + queue.push_back(e); + }); + } } void setup_layout_tab(Control *tab, const String &header) { @@ -334,7 +560,8 @@ public: } static void _bind_methods() { - ClassDB::bind_method(D_METHOD("menu_pressed", "id", "button"), + ClassDB::bind_method(D_METHOD("menu_pressed", "id", "button", + "path"), &BuildingLayoutGraphUI::menu_pressed); ClassDB::bind_method(D_METHOD("tree_entered"), &BuildingLayoutGraphUI::tree_entered); diff --git a/src/modules/stream/world_editor.h b/src/modules/stream/world_editor.h index f408dbb..b5b30e5 100644 --- a/src/modules/stream/world_editor.h +++ b/src/modules/stream/world_editor.h @@ -71,6 +71,16 @@ public: struct buildings_layout_graph_node { int depth; int y_pos; + int size; + }; + struct buildings_layout_unit { + int flags; + }; + struct buildings_layout_zone { + int type; + }; + struct buildings_layout_floor { + int flags; }; }; };