#include #include #include #include #include #include #include #include #include #include #include "GameData.h" #include "Components.h" #include "LuaData.h" #include "AppModule.h" #include "GUIModule.h" namespace ECS { struct GUIListener; struct EditorGUIListener; struct GUIData { Ogre::ImGuiOverlay *mGuiOverlay; std::vector glb_names; GUIListener *mGUIListener; }; struct EditorGUIData { Ogre::ImGuiOverlay *mGuiOverlay; std::vector glb_names; EditorGUIListener *mGUIListener; }; struct GUIListener : public Ogre::RenderTargetListener { float panel_width; bool enableEditor; bool enableMapEditor; ImFont *smallFont, *midFont, *bigFont; Ogre::FontPtr _smallFont, _midFont, _bigFont; GUIListener() : Ogre::RenderTargetListener() { _midFont = createFont("midFont", "General", "Jupiteroid-Regular.ttf", 18.0f); _smallFont = createFont("smallFont", "General", "Jupiteroid-Regular.ttf", 13.0f); _bigFont = createFont("bigFont", "General", "Kenney Bold.ttf", 32.0f); smallFont = ECS::get().mGuiOverlay->addFont( "smallFont", "General"); OgreAssert(smallFont, "Could not load font"); midFont = ECS::get().mGuiOverlay->addFont("midFont", "General"); OgreAssert(midFont, "Could not load font"); bigFont = ECS::get().mGuiOverlay->addFont("bigFont", "General"); OgreAssert(bigFont, "Could not load font"); #if 0 Ogre::FontPtr _midFont = createFont("midFont", "General", "Kenney Bold.ttf", 28.0f); #endif #if 0 ImGui::GetIO().Fonts->Build(); #endif } Ogre::FontPtr createFont(const Ogre::String &name, const Ogre::String &group, const Ogre::String &ttfname, float fontSize) { Ogre::FontPtr ret = Ogre::FontManager::getSingleton().create(name, group); ret->setType(Ogre::FontType::FT_TRUETYPE); ret->setSource(ttfname); ret->setTrueTypeSize(fontSize); ret->setTrueTypeResolution(75); ret->addCodePointRange(Ogre::Font::CodePointRange(30, 128)); ret->load(); return ret; } void preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override { preview(evt); } void buttons_panel() { ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5f - 20; ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.5f + 20), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); ImGui::Begin("Control"); // if (ECS::get().get().enabled) // ECS::get().get().app->setWindowGrab(true); if (ImGui::Button("Quit")) Ogre::Root::getSingleton().queueEndRendering(); if (ImGui::Button("Return")) ECS::get().get().finish(); if (ImGui::Button("Enable/Disable item editor")) { enableEditor ^= true; if (enableEditor) enableMapEditor = false; } if (ImGui::Button("Enable/Disable map editor")) { enableMapEditor ^= true; if (enableMapEditor) enableEditor = false; } ImGui::Text("Text message..."); ImGui::End(); } void create_entity_node(const Ogre::String &name, int key) { Ogre::Entity *ent = ECS::get().get().mScnMgr->createEntity( name); Ogre::SceneNode *pnode = ECS::get() .get() .mScnMgr->getRootSceneNode() ->createChildSceneNode( "ent:" + name + Ogre::StringConverter::toString( key), ECS::get() .get() .mCameraPivot->getPosition(), ECS::get() .get() .mCameraPivot->getOrientation()); pnode->attachObject(ent); Ogre::Quaternion q = pnode->getOrientation(); Ogre::Radian yaw = q.getYaw(); Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0)); pnode->setOrientation(nq); ECS::get().get().finish(); } void buildings_editor() { int i; ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5 - 20; ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); ImGui::Begin("Droppings..."); for (i = 0; i < ECS::get().get().glb_names.size(); i++) { Ogre::String id_button = "Create entity: " + ECS::get().get().glb_names[i] + "##ent:" + ECS::get().get().glb_names[i]; if (ImGui::Button(id_button.c_str())) { create_entity_node( ECS::get().get().glb_names[i], i); } } ImGui::End(); } void position_editor(Ogre::SceneNode *node) { Ogre::Vector3 position = node->getPosition(); float v[3] = { position.x, position.y, position.z }; ImGui::InputFloat3("position", v); position.x = v[0]; position.y = v[1]; position.z = v[2]; node->setPosition(position); } void orientation_editor(Ogre::SceneNode *node) { Ogre::Quaternion q = node->getOrientation(); float yaw = Ogre::Radian(q.getYaw()).valueDegrees(); float pitch = Ogre::Radian(q.getPitch()).valueDegrees(); float roll = Ogre::Radian(q.getRoll()).valueDegrees(); bool m1 = ImGui::InputFloat("yaw", &yaw); bool m2 = ImGui::InputFloat("pitch", &pitch); bool m3 = ImGui::InputFloat("roll", &roll); if (m1 || m2 || m3) { Ogre::Quaternion q1(Ogre::Radian(Ogre::Degree(yaw)), Ogre::Vector3::UNIT_Y); Ogre::Quaternion q2(Ogre::Degree(pitch), Ogre::Vector3::UNIT_X); Ogre::Quaternion q3(Ogre::Degree(roll), Ogre::Vector3::UNIT_Z); node->setOrientation(q1 * q2 * q3); } } void attachments_editor(Ogre::SceneNode *node) { const Ogre::SceneNode::ObjectMap &pmap = node->getAttachedObjects(); int i; for (i = 0; i < pmap.size(); i++) { const Ogre::MovableObject *mobj = pmap[i]; const Ogre::String &pname = mobj->getName(); ImGui::Text("Name: %s", pname.c_str()); } } void map_editor() { } void preview(const Ogre::RenderTargetViewportEvent &evt) { int i; Ogre::ImGuiOverlay::NewFrame(); if (ECS::get().get().startupDelay > 0.0f) { ImVec2 size = ImGui::GetMainViewport()->Size; ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(size.x, size.y), ImGuiCond_Always); ImGui::Begin( "StartupScreen", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs); // if (ECS::get().get().enabled) // ECS::get().get().app->setWindowGrab(true); ImGui::PushFont(bigFont); ImGui::TextWrapped( "%s", "This game does not autosave. Please use save function to keep your state"); ImGui::PopFont(); ImGui::End(); } else if (ECS::get().get().enabled) { if (ECS::get().get().narrationBox) { ImVec2 size = ImGui::GetMainViewport()->Size; ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.75f), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(size.x, size.y * 0.25f), ImGuiCond_Always); ImGui::Begin("Narration...", NULL, ImGuiWindowFlags_NoTitleBar); ImGui::PushFont(midFont); ImVec2 p = ImGui::GetCursorScreenPos(); ImGui::TextWrapped( "%s", ECS::get() .get() .narrationText.c_str()); if (ECS::get().get().choices.size() == 0) { ImGui::SetCursorScreenPos(p); if (ImGui::InvisibleButton( "Background", ImGui::GetWindowSize())) ECS::get().mLua->call_handler( "narration_progress"); } else { int i; for (i = 0; i < ECS::get() .get() .choices.size(); i++) { if (ImGui::Button( ECS::get() .get() .choices[i] .c_str())) { ECS::get() .get_mut() .narration_answer = i + 1; std::cout << "answer: " << i + 1 << std::endl; ECS::modified(); ECS::get() .mLua ->call_handler( "narration_answered"); } } } ImGui::Spacing(); ImGui::PopFont(); ImGui::End(); } else if (ECS::get().get().mainMenu) { ImVec2 size = ImGui::GetMainViewport()->Size; ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(size.x, size.y), ImGuiCond_Always); ImGui::Begin( "MainMenu", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing | 0); // if (ECS::get().get().enabled) // ECS::get().get().app->setWindowGrab(true); ImGui::PushFont(bigFont); ImGui::TextWrapped("%s", "Booo!!!!"); bool pressed = false; bool new_game = false, cont = false, load_game = false, opts = false, quit = false; ImGui::SetCursorPosY(size.y / 2.0f - 300.0f); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); new_game = ImGui::Button("New Game"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); cont = ImGui::Button("Continue"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); load_game = ImGui::Button("Load Game"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); opts = ImGui::Button("Options"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); quit = ImGui::Button("Quit###quit"); pressed = new_game || cont || load_game || opts || quit; ImGui::PopFont(); ImGui::Spacing(); ImGui::End(); if (quit) Ogre::Root::getSingleton() .queueEndRendering(); if (pressed) ECS::get().get().finish(); if (new_game) { ECS::get().mLua->call_handler( "new_game"); } } else { buttons_panel(); if (enableEditor) buildings_editor(); if (enableMapEditor) map_editor(); ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5f - 20; ImGui::SetNextWindowPos( ImVec2(size.x - window_width, size.y * 0.5f + 20), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); // ImGui::Begin("Dumb and Stupid", &mKbd.gui_active); ImGui::Begin("Panel..."); std::deque tree_input_queue, tree_output_queue; std::vector tree_list; tree_input_queue.push_back( ECS::get() .get() .mScnMgr->getRootSceneNode()); tree_input_queue.push_back(nullptr); std::set visited; while (true) { int new_nodes_count = 0; while (!tree_input_queue.empty()) { int child; Ogre::SceneNode *item = tree_input_queue.front(); tree_input_queue.pop_front(); if (item && visited.find(item) == visited.end()) { // new node new_nodes_count++; tree_output_queue .push_back( item); visited.insert(item); const Ogre::Node::ChildNodeMap &children = item->getChildren(); for (child = 0; child < children.size(); child++) { tree_output_queue .push_back(static_cast< Ogre::SceneNode *>( children[child])); tree_output_queue .push_back( nullptr); } } else tree_output_queue .push_back( item); } if (new_nodes_count == 0) break; tree_input_queue = tree_output_queue; tree_output_queue.clear(); } tree_list.insert(tree_list.begin(), tree_output_queue.begin(), tree_output_queue.end()); int count = 0; int depth = 0; std::vector check_depth; int max_depth = 0; check_depth.push_back(0); for (count = 0; count < tree_list.size(); count++) { int t; Ogre::SceneNode *node = tree_list[count]; if (node && max_depth >= depth) { Ogre::String name = node->getName(); if (name.length() == 0) { name = "Node #" + Ogre::StringConverter:: toString( count); } if (ImGui::TreeNode( name.c_str())) { check_depth.push_back( max_depth); max_depth++; ImGui::Text( "%s", (name + "##caption") .c_str()); position_editor(node); ImGui::Separator(); orientation_editor( node); ImGui::Separator(); ImGui::Text( "Attachments"); attachments_editor( node); } } else if (!node && max_depth >= depth) { max_depth = check_depth.back(); check_depth.pop_back(); ImGui::TreePop(); } if (tree_list[count]) depth++; else depth--; } ImGui::Spacing(); ImGui::End(); } } } }; struct EditorGUIListener : public Ogre::RenderTargetListener { float panel_width; bool enableEditor; bool enableMapEditor; ImFont *smallFont, *midFont, *bigFont; Ogre::FontPtr _smallFont, _midFont, _bigFont; EditorGUIListener(Ogre::ImGuiOverlay *overlay) : Ogre::RenderTargetListener() { std::cout << "WAAAAAAA!!!!!" << std::endl; _midFont = createFont("midFont", "General", "Jupiteroid-Regular.ttf", 18.0f); _smallFont = createFont("smallFont", "General", "Jupiteroid-Regular.ttf", 13.0f); _bigFont = createFont("bigFont", "General", "Kenney Bold.ttf", 32.0f); smallFont = overlay->addFont("smallFont", "General"); OgreAssert(smallFont, "Could not load font"); midFont = overlay->addFont("midFont", "General"); OgreAssert(midFont, "Could not load font"); bigFont = overlay->addFont("bigFont", "General"); OgreAssert(bigFont, "Could not load font"); #if 0 Ogre::FontPtr _midFont = createFont("midFont", "General", "Kenney Bold.ttf", 28.0f); #endif #if 0 ImGui::GetIO().Fonts->Build(); #endif } Ogre::FontPtr createFont(const Ogre::String &name, const Ogre::String &group, const Ogre::String &ttfname, float fontSize) { Ogre::FontPtr ret = Ogre::FontManager::getSingleton().create(name, group); ret->setType(Ogre::FontType::FT_TRUETYPE); ret->setSource(ttfname); ret->setTrueTypeSize(fontSize); ret->setTrueTypeResolution(75); ret->addCodePointRange(Ogre::Font::CodePointRange(30, 128)); ret->load(); return ret; } void preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override { preview(evt); } void buttons_panel() { ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5f - 20; ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.5f + 20), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); ImGui::Begin("Control"); // if (ECS::get().get().enabled) // ECS::get().get().app->setWindowGrab(true); if (ImGui::Button("Quit")) Ogre::Root::getSingleton().queueEndRendering(); if (ImGui::Button("Return")) ECS::get().get().finish(); if (ImGui::Button("Enable/Disable item editor")) { enableEditor ^= true; if (enableEditor) enableMapEditor = false; } if (ImGui::Button("Enable/Disable map editor")) { enableMapEditor ^= true; if (enableMapEditor) enableEditor = false; } ImGui::Text("Text message..."); ImGui::End(); } void create_entity_node(const Ogre::String &name, int key) { Ogre::Entity *ent = ECS::get().get().mScnMgr->createEntity( name); Ogre::SceneNode *pnode = ECS::get() .get() .mScnMgr->getRootSceneNode() ->createChildSceneNode( "ent:" + name + Ogre::StringConverter::toString( key), ECS::get() .get() .mCameraPivot->getPosition(), ECS::get() .get() .mCameraPivot->getOrientation()); pnode->attachObject(ent); Ogre::Quaternion q = pnode->getOrientation(); Ogre::Radian yaw = q.getYaw(); Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0)); pnode->setOrientation(nq); ECS::get().get().finish(); } void buildings_editor() { int i; ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5 - 20; ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); ImGui::Begin("Droppings..."); for (i = 0; i < ECS::get().get().glb_names.size(); i++) { Ogre::String id_button = "Create entity: " + ECS::get().get().glb_names[i] + "##ent:" + ECS::get().get().glb_names[i]; if (ImGui::Button(id_button.c_str())) { create_entity_node(ECS::get() .get() .glb_names[i], i); } } ImGui::End(); } void position_editor(Ogre::SceneNode *node) { Ogre::Vector3 position = node->getPosition(); float v[3] = { position.x, position.y, position.z }; ImGui::InputFloat3("position", v); position.x = v[0]; position.y = v[1]; position.z = v[2]; node->setPosition(position); } void orientation_editor(Ogre::SceneNode *node) { Ogre::Quaternion q = node->getOrientation(); float yaw = Ogre::Radian(q.getYaw()).valueDegrees(); float pitch = Ogre::Radian(q.getPitch()).valueDegrees(); float roll = Ogre::Radian(q.getRoll()).valueDegrees(); bool m1 = ImGui::InputFloat("yaw", &yaw); bool m2 = ImGui::InputFloat("pitch", &pitch); bool m3 = ImGui::InputFloat("roll", &roll); if (m1 || m2 || m3) { Ogre::Quaternion q1(Ogre::Radian(Ogre::Degree(yaw)), Ogre::Vector3::UNIT_Y); Ogre::Quaternion q2(Ogre::Degree(pitch), Ogre::Vector3::UNIT_X); Ogre::Quaternion q3(Ogre::Degree(roll), Ogre::Vector3::UNIT_Z); node->setOrientation(q1 * q2 * q3); } } void attachments_editor(Ogre::SceneNode *node) { const Ogre::SceneNode::ObjectMap &pmap = node->getAttachedObjects(); int i; for (i = 0; i < pmap.size(); i++) { const Ogre::MovableObject *mobj = pmap[i]; const Ogre::String &pname = mobj->getName(); ImGui::Text("Name: %s", pname.c_str()); } } void map_editor() { } void preview(const Ogre::RenderTargetViewportEvent &evt) { int i; Ogre::ImGuiOverlay::NewFrame(); std::cout << "GUI enabled: " << ECS::get().get().enabled << std::endl; if (ECS::get().get().enabled) { buttons_panel(); buildings_editor(); map_editor(); ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5f - 20; ImGui::SetNextWindowPos(ImVec2(size.x - window_width, size.y * 0.5f + 20), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); // ImGui::Begin("Dumb and Stupid", &mKbd.gui_active); ImGui::Begin("Panel..."); std::deque tree_input_queue, tree_output_queue; std::vector tree_list; tree_input_queue.push_back( ECS::get() .get() .mScnMgr->getRootSceneNode()); tree_input_queue.push_back(nullptr); std::set visited; while (true) { int new_nodes_count = 0; while (!tree_input_queue.empty()) { int child; Ogre::SceneNode *item = tree_input_queue.front(); tree_input_queue.pop_front(); if (item && visited.find(item) == visited.end()) { // new node new_nodes_count++; tree_output_queue.push_back( item); visited.insert(item); const Ogre::Node::ChildNodeMap &children = item->getChildren(); for (child = 0; child < children.size(); child++) { tree_output_queue.push_back( static_cast< Ogre::SceneNode *>( children[child])); tree_output_queue .push_back( nullptr); } } else tree_output_queue.push_back( item); } if (new_nodes_count == 0) break; tree_input_queue = tree_output_queue; tree_output_queue.clear(); } tree_list.insert(tree_list.begin(), tree_output_queue.begin(), tree_output_queue.end()); int count = 0; int depth = 0; std::vector check_depth; int max_depth = 0; check_depth.push_back(0); for (count = 0; count < tree_list.size(); count++) { int t; Ogre::SceneNode *node = tree_list[count]; if (node && max_depth >= depth) { Ogre::String name = node->getName(); if (name.length() == 0) { name = "Node #" + Ogre::StringConverter:: toString(count); } if (ImGui::TreeNode(name.c_str())) { check_depth.push_back( max_depth); max_depth++; ImGui::Text("%s", (name + "##caption") .c_str()); position_editor(node); ImGui::Separator(); orientation_editor(node); ImGui::Separator(); ImGui::Text("Attachments"); attachments_editor(node); } } else if (!node && max_depth >= depth) { max_depth = check_depth.back(); check_depth.pop_back(); ImGui::TreePop(); } if (tree_list[count]) depth++; else depth--; } ImGui::Spacing(); ImGui::End(); #if 0 if (ECS::get().get().narrationBox) { ImVec2 size = ImGui::GetMainViewport()->Size; ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.75f), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(size.x, size.y * 0.25f), ImGuiCond_Always); ImGui::Begin("Narration...", NULL, ImGuiWindowFlags_NoTitleBar); ImGui::PushFont(midFont); ImVec2 p = ImGui::GetCursorScreenPos(); ImGui::TextWrapped( "%s", ECS::get() .get() .narrationText.c_str()); if (ECS::get().get().choices.size() == 0) { ImGui::SetCursorScreenPos(p); if (ImGui::InvisibleButton( "Background", ImGui::GetWindowSize())) ECS::get().mLua->call_handler( "narration_progress"); } else { int i; for (i = 0; i < ECS::get() .get() .choices.size(); i++) { if (ImGui::Button( ECS::get() .get() .choices[i] .c_str())) { ECS::get() .get_mut() .narration_answer = i + 1; std::cout << "answer: " << i + 1 << std::endl; ECS::modified(); ECS::get() .mLua ->call_handler( "narration_answered"); } } } ImGui::Spacing(); ImGui::PopFont(); ImGui::End(); } else if (ECS::get().get().mainMenu) { ImVec2 size = ImGui::GetMainViewport()->Size; ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(size.x, size.y), ImGuiCond_Always); ImGui::Begin( "MainMenu", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing | 0); // if (ECS::get().get().enabled) // ECS::get().get().app->setWindowGrab(true); ImGui::PushFont(bigFont); ImGui::TextWrapped("%s", "Booo!!!!"); bool pressed = false; bool new_game = false, cont = false, load_game = false, opts = false, quit = false; ImGui::SetCursorPosY(size.y / 2.0f - 300.0f); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); new_game = ImGui::Button("New Game"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); cont = ImGui::Button("Continue"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); load_game = ImGui::Button("Load Game"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); opts = ImGui::Button("Options"); ImGui::SetCursorPosX(size.x / 2.0f - 300.0f); quit = ImGui::Button("Quit###quit"); pressed = new_game || cont || load_game || opts || quit; ImGui::PopFont(); ImGui::Spacing(); ImGui::End(); if (quit) Ogre::Root::getSingleton() .queueEndRendering(); if (pressed) ECS::get().get().finish(); if (new_game) { ECS::get().mLua->call_handler( "new_game"); } } else { buttons_panel(); if (enableEditor) buildings_editor(); if (enableMapEditor) map_editor(); ImVec2 size = ImGui::GetMainViewport()->Size; float window_width = size.x * 0.2f; if (window_width > panel_width) window_width = panel_width; float window_height = size.y * 0.5f - 20; ImGui::SetNextWindowPos( ImVec2(size.x - window_width, size.y * 0.5f + 20), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(window_width, window_height), ImGuiCond_Always); // ImGui::Begin("Dumb and Stupid", &mKbd.gui_active); ImGui::Begin("Panel..."); std::deque tree_input_queue, tree_output_queue; std::vector tree_list; tree_input_queue.push_back( ECS::get() .get() .mScnMgr->getRootSceneNode()); tree_input_queue.push_back(nullptr); std::set visited; while (true) { int new_nodes_count = 0; while (!tree_input_queue.empty()) { int child; Ogre::SceneNode *item = tree_input_queue.front(); tree_input_queue.pop_front(); if (item && visited.find(item) == visited.end()) { // new node new_nodes_count++; tree_output_queue .push_back( item); visited.insert(item); const Ogre::Node::ChildNodeMap &children = item->getChildren(); for (child = 0; child < children.size(); child++) { tree_output_queue .push_back(static_cast< Ogre::SceneNode *>( children[child])); tree_output_queue .push_back( nullptr); } } else tree_output_queue .push_back( item); } if (new_nodes_count == 0) break; tree_input_queue = tree_output_queue; tree_output_queue.clear(); } tree_list.insert(tree_list.begin(), tree_output_queue.begin(), tree_output_queue.end()); int count = 0; int depth = 0; std::vector check_depth; int max_depth = 0; check_depth.push_back(0); for (count = 0; count < tree_list.size(); count++) { int t; Ogre::SceneNode *node = tree_list[count]; if (node && max_depth >= depth) { Ogre::String name = node->getName(); if (name.length() == 0) { name = "Node #" + Ogre::StringConverter:: toString( count); } if (ImGui::TreeNode( name.c_str())) { check_depth.push_back( max_depth); max_depth++; ImGui::Text( "%s", (name + "##caption") .c_str()); position_editor(node); ImGui::Separator(); orientation_editor( node); ImGui::Separator(); ImGui::Text( "Attachments"); attachments_editor( node); } } else if (!node && max_depth >= depth) { max_depth = check_depth.back(); check_depth.pop_back(); ImGui::TreePop(); } if (tree_list[count]) depth++; else depth--; } ImGui::Spacing(); ImGui::End(); } #endif } } }; GUIModule::GUIModule(flecs::world &ecs) { ecs.module(); ecs.import (); ecs.component() .on_add([](GUI &gui) { gui.enabled = false; gui.grab = false; gui.grabChanged = false; }) .add(flecs::Singleton); ecs.component() .on_add([](GUIData &priv) { priv.glb_names.clear(); priv.mGUIListener = nullptr; priv.mGuiOverlay = nullptr; }) .add(flecs::Singleton); ecs.set({ false, true, false, false, false, "", {}, -1 }); ecs.set({ nullptr, {}, nullptr }); ui_wait = ecs.system("SetupGUI") .kind(flecs::OnUpdate) .each([this](const RenderWindow &window, App &app, GUIData &gui) { if (!gui.mGuiOverlay) { float vpScale = window.dpi / 96 * window.window->getWidth() / 1600.0f; Ogre::OverlayManager::getSingleton() .setPixelRatio(vpScale); std::cout << "GUI configure\n"; OgreAssert(app.mGuiOverlay, "No ImGUI overlay"); gui.mGuiOverlay = app.mGuiOverlay; gui.mGUIListener = new GUIListener(); gui.mGuiOverlay->setZOrder(300); gui.mGuiOverlay->show(); gui.mGUIListener->panel_width = 300.0f; gui.mGUIListener->enableEditor = false; window.window->addListener( gui.mGUIListener); int i; const std::vector &groups = Ogre::ResourceGroupManager:: getSingleton() .getResourceGroups(); for (i = 0; i < groups.size(); i++) { std::vector names = *Ogre::ResourceGroupManager::getSingleton() .findResourceNames( groups[i], "*.glb"); gui.glb_names.insert( gui.glb_names.end(), names.begin(), names.end()); } ECS::modified(); std::cout << "GUI configure finished\n"; } }); } EditorGUIModule::EditorGUIModule(flecs::world &ecs) { ecs.module(); ecs.import (); ecs.component() .on_add([](GUI &gui) { gui.enabled = true; gui.grab = false; gui.grabChanged = false; }) .add(flecs::Singleton); ecs.component() .on_add([](EditorGUIData &priv) { priv.glb_names.clear(); priv.mGUIListener = nullptr; priv.mGuiOverlay = nullptr; }) .add(flecs::Singleton); ecs.observer("SupportEditorGUI") .event(flecs::OnSet) .without() .each([](const RenderWindow &window, const App &app, GUI &gui) { float vpScale = window.dpi / 96 * window.window->getWidth() / 1600.0f; Ogre::OverlayManager::getSingleton().setPixelRatio( vpScale); std::cout << "Editor GUI configure\n"; OgreAssert(app.mGuiOverlay, "No ImGUI overlay"); Ogre::ImGuiOverlay *guiOverlay = app.mGuiOverlay; EditorGUIListener *guiListener = new EditorGUIListener(guiOverlay); guiOverlay->setZOrder(300); guiOverlay->show(); guiListener->panel_width = 300.0f; guiListener->enableEditor = false; window.window->addListener(guiListener); ECS::get().set( { app.mGuiOverlay, {}, guiListener }); std::cout << "Editor GUI configure finished\n"; }); } }