Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.49 KB | None | 0 0
  1. //
  2. // Created by enoc on 20/07/18.
  3. //
  4.  
  5. #include <EddieECS/Components/Transform.hpp>
  6. #include <cstdlib>
  7. #include <EddieEddieUI/Helpers/Keyboard.hpp>
  8. #include <UI/EntityList.hpp>
  9. #include <EddieECS/Components/Visible.hpp>
  10. #include <EddieECS/Components/Sprite.hpp>
  11. #include <EddieECS/Components/Video.hpp>
  12. #include <EddieECS/Components/FSM.hpp>
  13. #include <EddieECS/Components/TamChangeError.hpp>
  14. #include <EddieECS/Components/IgnoreOnEditor.hpp>
  15. #include <EddieGraphics/ImGui/CustomWidgets.hpp>
  16. #include <EddieEddieUI/Events/EcsUiEvents.hpp>
  17. #include <EddieEngine/GameContext/ContextOperations.hpp>
  18. #include "UI/EntityList.hpp"
  19. #include <EddieEddieUI/Events/EcsUiEvents.hpp>
  20. #include <EddieEddieUI/CustomColors.hpp>
  21. #include <EddieECS/Components/NativeReel.hpp>
  22. #include <EddieECS/EcsBaseUtils.hpp>
  23. #include <EddieECS/Components/SoundComponent.hpp>
  24. #include <EddieEddieUI/UIContext.hpp>
  25. #include <EddieECS/Components/RelativeRotationPreservation.hpp>
  26.  
  27. namespace {
  28.     const auto REMOVE_FSM_WINDOW_ID = "Remove FSM##RemoveFsmWindowId";
  29. }
  30.  
  31. // TODO: Quitar las inicializaciones...
  32. EddieUI::EntityList::EntityList() { }
  33.  
  34. void EddieUI::EntityList::AdditionalKeyHandlers() {
  35.     if (gContext) {
  36.         if (ImGui::IsKeyPressed(Key::ESC, false)) {
  37.             Game::ContextDropSelection(*gContext);
  38.         }
  39.         if (ImGui::IsKeyPressed(Key::SUPR, false) || ImGui::IsKeyPressed(Key::DEL, false)) {
  40.             if (ImGui::IsKeyDown(Key::LEFT_CTRL)) {
  41.                 Game::ContextDeleteSelection(*gContext, true);
  42.             } else {
  43.                 Game::ContextDeleteSelection(*gContext, false);
  44.             }
  45.         }
  46.     }
  47. }
  48.  
  49. void EddieUI::EntityList::Prepare() noexcept {
  50.     if (gContext == nullptr) {
  51.         FATAL_ERROR("GameContext Need to be linked before prepare!");
  52.     }
  53.     this->mSGSystem = gContext->GetEcsSystem<ECS::SceneGraphSystem>();
  54.     this->mSelectorSystem = gContext->GetEcsSystem<ECS::EditorSelector>();
  55.     this->mRegisterSystem = gContext->GetEcsSystem<ECS::EntityRegister>();
  56.  
  57.     componentTag.SetEditorSelector(this->mSelectorSystem);
  58. }
  59.  
  60.  
  61. void EddieUI::EntityList::RenderFrameUI(UIContext &context) {
  62.  
  63. /*    constexpr ImGuiTreeNodeFlags node_flags =
  64.             ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_Leaf |
  65.             ImGuiTreeNodeFlags_NoTreePushOnOpen ;*/
  66.  
  67.     std::set<uint64_t> allFsm;
  68.  
  69.     auto gameContext = context.__gameContextPtr;
  70.     if (ImGui::TreeNode("World")) {
  71.         ImGui::Columns(3);
  72.         ImGui::Text("Name");
  73.         ImGui::NextColumn();
  74.         //ImGui::Text("Z-Layer"); ImGui::NextColumn();
  75.         //  ImGui::Text("R-Order"); ImGui::NextColumn();
  76.         ImGui::Text("Object Type");
  77.         ImGui::SameLine();
  78.  
  79.         ImGui::NextColumn();
  80.         ImGui::Text("Visible");
  81.         ImGui::NextColumn();
  82.         ImGui::Separator();
  83.  
  84.         auto selected = mSelectorSystem->GetSelectedSet();
  85.         int counter = 0;
  86.         int firstSelected = 999999999;
  87.         int lastSelected = 999999999;
  88.         int endSelection = -1;
  89.  
  90.         ECS::Signature filter;
  91.  
  92.         bool selectPrevious = false;
  93.         bool selectNext = false;
  94.  
  95.         auto ShowData = [this, &selected, &counter, &allFsm, &firstSelected, &endSelection, &lastSelected, /*&EntityListContextualMenu,*/ gameContext, &selectPrevious, &selectNext](
  96.                 ECS::Entity &ent, const std::string &name) {
  97.             ImGui::PushID(counter);
  98.             const bool isItemSelected = selected.find(ent.Index()) != selected.end();
  99.  
  100.             bool errorState = ent.HasComponent<ECS::Comp::TamChangeCorruption>();
  101.  
  102.             if (isItemSelected) {
  103.                 firstSelected = std::min(firstSelected, counter);
  104.                 lastSelected = counter;
  105.             }
  106.  
  107.             // TODO: Esto serΓ‘ igual para las dos listas...
  108.             if(ImGui::IsWindowFocused()) {
  109.                 if(ImGui::IsKeyPressed(Keyboard::TOP_ARROW, true)) {
  110.                     selectPrevious = true;
  111.                 }
  112.                 if(ImGui::IsKeyPressed(Keyboard::BOTTOM_ARROW, true)) {
  113.                     selectNext = true;
  114.                 }
  115.             }
  116.  
  117.             if (ImGui::Selectable(name.c_str(), isItemSelected, ImGuiSelectableFlags_SpanAllColumns)) {
  118.                 if (ImGui::IsKeyDown(Key::LEFT_SHIFT)) {
  119.                     endSelection = counter;
  120.                 } else if (ImGui::IsKeyDown(Key::LEFT_CTRL)) {
  121.                     if (isItemSelected) {
  122.                         mSelectorSystem->RemoveSelected(ent);
  123.                     } else {
  124.                         mSelectorSystem->AddSelected(ent);
  125.                     }
  126.                 } else {
  127.                     mSelectorSystem->AddSelected(ent, true);
  128.                 }
  129.             }
  130.  
  131.             struct EntityBatchDragAndDrop {
  132.                 ECS::Entity entities[1024];
  133.                 uint32_t entitiesCount = 0;
  134.             };
  135.  
  136.             ImGui::SetItemAllowOverlap();
  137.             if (ImGui::BeginDragDropTarget()) {
  138.                 if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload(ENTITY_BATCH_PAYLOAD)) {
  139.                     EntityBatchDragAndDrop acceptedPayload = *(EntityBatchDragAndDrop *) (payload->Data);
  140.                     if (acceptedPayload.entitiesCount > 0) {
  141.  
  142.                         const auto destinationIndex = ent.Index();
  143.  
  144.                         bool isMovementValid = true;
  145.                         for (auto idx = 0u; idx < acceptedPayload.entitiesCount; idx++) {
  146.                             auto &e = acceptedPayload.entities[idx];
  147.                             if (destinationIndex == e.Index()) {
  148.                                 isMovementValid = false;
  149.                             }
  150.                         }
  151.                         if (isMovementValid) {
  152.                             if (ImGui::IsKeyDown(Key::LEFT_CTRL)) {
  153.                                 for (auto idx = 0u; idx < acceptedPayload.entitiesCount; idx++) {
  154.                                     auto &e = acceptedPayload.entities[idx];
  155.                                     mSGSystem->MoveOver(::ECS::Index(e.Index()), destinationIndex);
  156.                                 }
  157.                             } else {
  158.                                 for (auto idx = acceptedPayload.entitiesCount; idx > 0; idx--) {
  159.                                     auto &e = acceptedPayload.entities[idx - 1];
  160.                                     mSGSystem->MoveUnder(::ECS::Index(e.Index()), destinationIndex);
  161.                                 }
  162.                             }
  163.                             ent.GetComponentHandler<ECS::Comp::Transform>().ForceReplace();
  164.                         }
  165.                     }
  166.                 }
  167.                 ImGui::EndDragDropTarget();
  168.             }
  169.             ImGui::SetItemAllowOverlap();
  170.             if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
  171.  
  172.                 EntityBatchDragAndDrop ebdd;
  173.                 mSelectorSystem->ForEachSelected([&](size_t idx, ECS::Entity e) {
  174.                     if (ebdd.entitiesCount < 1002) {
  175.                         ebdd.entities[ebdd.entitiesCount++] = e;
  176.                     } else {
  177.                         std::cerr << "[ERR] more than 1000 items moving at same time!!" << std::endl;
  178.                     }
  179.                 });
  180.  
  181.                 ImGui::SetDragDropPayload(ENTITY_BATCH_PAYLOAD, &ebdd, sizeof(ebdd), ImGuiCond_Always);
  182.                 if (ebdd.entitiesCount == 1) {
  183.                     ImGui::Text("Moving node....%s", name.c_str());
  184.                 } else {
  185.                     std::stringstream ss;
  186.                     ImGui::Text("Moving %d entities.", ebdd.entitiesCount);
  187.                 }
  188.                 ImGui::EndDragDropSource();
  189.             }
  190.             ImGui::SetItemAllowOverlap();
  191.             if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(Mouse::CLICK)) {
  192.  
  193.             }
  194.  
  195.             if (ImGui::BeginPopupContextWindow()) {
  196. //                EntityListContextualMenu(counter);
  197.                 componentTag.ShowContextualMenu(selected, selectedForRemove);
  198.                 ImGui::EndPopup();
  199.             }
  200.  
  201.             ImGui::NextColumn();
  202.  
  203.  
  204.             //ImGui::Text("%d", c.z); ImGui::NextColumn();
  205.             //ImGui::Text("%d", c.cheatOrder); ImGui::NextColumn();
  206.             bool keep_line = false;
  207.  
  208.             const auto pre = ImGui::GetCursorPos();
  209.             const auto CHAR_SIZE = ImGui::CalcTextSize("A");
  210.  
  211.             auto item_signature = ent.GetSignature();
  212.  
  213. //            const auto add_component_tag = [&](const ECS::Signature &signature, ImColor color, std::string_view text) {
  214. //                if (ECS::Match(item_signature, signature)) {
  215. //                    if (keep_line) {
  216. //                        ImGui::SameLine();
  217. //                    }
  218. //                    ImGui::TextColored(color, "+%s", text.data());
  219. //                    keep_line = true;
  220. //                }
  221. //            };
  222.  
  223.             componentTag.RotTag(ent);
  224.             componentTag.RotRefTag(ent);
  225.             componentTag.RotBaseTag(ent);
  226.             componentTag.SpriteTag(ent);
  227.             componentTag.AnimationTag(ent);
  228.             componentTag.AnimationPlayingTag(ent);
  229.             componentTag.FontTag(ent);
  230.             componentTag.NativeReelTag(ent);
  231.             componentTag.SoundTag(ent);
  232.             componentTag.LayeredFontTag(ent);
  233.  
  234.             if (ent.HasComponent<ECS::Comp::Video>()) {
  235.                 if (keep_line) {
  236.                     ImGui::SameLine();
  237.                 }
  238.                 const std::string VIDEO_TAG = "Video"; // TODO: Ver como ponemos esto....
  239.                 ImGui::TextColored(EddieColors().COLOR_VIDEO, "+%s", VIDEO_TAG.c_str());
  240.                 keep_line = true;
  241.             }
  242.  
  243.             auto add_fsm = componentTag.FsmTag(ent);
  244.  
  245.  
  246.             if (add_fsm) {
  247.                 ImGui::SameLine();
  248.                 const auto post = ImGui::GetCursorPos();
  249.                 const auto spacing = ImVec2(post.x - pre.x, CHAR_SIZE.y);
  250.                 ImGui::SetCursorPos(pre);
  251.                 ImGui::Dummy(spacing);
  252.                 auto fsm_obj = ent.GetComponentHandler<ECS::Comp::Fsm>();
  253.                 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(Mouse::CLICK)) {
  254.                     gContext->EmitEvent<ECS::DirectSelectFsm>(fsm_obj->fsmCode);
  255.                 }
  256.  
  257.                 if (isItemSelected) {
  258.                     allFsm.emplace(fsm_obj->fsmCode);
  259.                 }
  260.             }
  261.             ImGui::NextColumn();
  262.  
  263.             if (!errorState) {
  264.                 const auto cursor = ImGui::GetCursorPos();
  265.                 ImVec2 size;
  266.  
  267.                 if (ent.HasComponent<ECS::Comp::OnScene>()) {
  268.                     size = ImGui::CalcTextSize("- Visible");
  269.                     ImGui::TextColored(EddieColors().COLOR_VISIBLE, "- Visible");
  270.                 } else {
  271.                     size = ImGui::CalcTextSize("- Invisible");
  272.                     ImGui::TextColored(EddieColors().COLOR_INVISIBLE, "- Invisible");
  273.                 }
  274.                 ImGui::SetCursorPos(cursor);
  275.                 ImGui::Dummy(size);
  276.                 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
  277.                     if (ent.HasComponent<ECS::Comp::OnScene>()) {
  278.                         ent.Remove<ECS::Comp::OnScene>();
  279.                     } else {
  280.                         ent.AddComponent<ECS::Comp::OnScene>();
  281.                     }
  282.                 }
  283.                 ImGui::SameLine();
  284.                 componentTag.HideOnEditorTag(ent);
  285.             } else {
  286.                 ImGui::TextColored(EddieColors().COLOR_MISSING_DATA, "MISSING TAM DATA ");
  287.                 ImGui::SameLine();
  288.             }
  289.             ImGui::NextColumn();
  290.             ImGui::PopID();
  291.             counter++;
  292.         };
  293.  
  294.         auto rate = ImGui::GetIO().KeyRepeatRate;
  295.         ImGui::GetIO().KeyRepeatRate = 0.04;
  296.         mSGSystem->ForEachNamedTransform(filter, ShowData);
  297.  
  298.         ImGui::GetIO().KeyRepeatRate = rate;
  299.  
  300.         if(selectPrevious) {
  301.             if(mSelectorSystem->CountRetainedEntities() > 0) {
  302.                 auto selected = mSelectorSystem->GetSelected();
  303.                 if(selected.size() == 1) {
  304.                     auto curr = selected.back();
  305.                     ECS::Entity prev;
  306.                     bool notFirstPrev = false;
  307.                     bool hasPrev = false;
  308.                     mSGSystem->ForEachNamedTransform(filter, [&]( ECS::Entity &ent, const std::string &name) {
  309.                         if(ent.Index() == curr.Index()) {
  310.                             hasPrev = true;
  311.                         }
  312.                         if(!hasPrev) {
  313.                             notFirstPrev = true;
  314.                             prev = ent;
  315.                         }
  316.                     });
  317.                     if(notFirstPrev) {
  318.                         mSelectorSystem->AddSelected(prev, true);
  319.                     }
  320.                 }
  321.             }
  322.         }
  323.  
  324.         if(selectNext) {
  325.             if(mSelectorSystem->CountRetainedEntities() > 0) {
  326.                 auto selected = mSelectorSystem->GetSelected();
  327.                 if(selected.size() == 1) {
  328.                     auto curr = selected.back();
  329.                     ECS::Entity next;
  330.                     bool notLast = false;
  331.                     bool isThis = false;
  332.                     mSGSystem->ForEachNamedTransform(filter, [&]( ECS::Entity &ent, const std::string &name) {
  333.                         if(isThis) {
  334.                             notLast = true;
  335.                             next = ent;
  336.                             isThis = false;
  337.                         }
  338.                         if(ent.Index() == curr.Index()) {
  339.                             isThis = true;
  340.                         }
  341.                     });
  342.                     if(notLast) {
  343.                         mSelectorSystem->AddSelected(next, true);
  344.                     }
  345.                 }
  346.             }
  347.         }
  348.  
  349.         ImGui::Columns(1);
  350.         ImGui::TreePop();
  351.  
  352.         if (endSelection > -1) {
  353.  
  354.  
  355.             uint32_t first = 0;
  356.             uint32_t second = 0;
  357.  
  358.  
  359.             if (firstSelected < endSelection) {
  360.                 first = firstSelected;
  361.                 second = endSelection;
  362.             } else if (endSelection < lastSelected) {
  363.                 first = endSelection;
  364.                 second = lastSelected;
  365.             } else {
  366.                 first = endSelection;
  367.                 second = firstSelected;
  368.             }
  369.  
  370.             auto data = mSGSystem->GetRetainedList(first, second - first + 1);
  371.             bool is_p = true;
  372.             for (auto &ent: data) {
  373.                 mSelectorSystem->AddSelected(ent, is_p);
  374.                 is_p = false;
  375.             }
  376.         }
  377.     }
  378.  
  379.  
  380.     if (ImGui::TreeNode("Out of world")) {
  381.         ImGui::Text("Name");
  382.         ImGui::NextColumn();
  383.         ImGui::Separator();
  384.         auto selected = mSelectorSystem->GetSelectedSet();
  385.         const auto Iterator = [=](const std::string &name, ECS::Entity entity) {
  386.             const bool isItemSelected = selected.find(entity.Index()) != selected.end();
  387.             if (ImGui::Selectable(name.c_str(), isItemSelected, ImGuiSelectableFlags_SpanAllColumns)) {
  388.                 mSelectorSystem->DropSelecteds();
  389.                 // if(isItemSelected) {
  390.                 //    mSelectorSystem->RemoveSelected(entity);
  391.                 // } else {
  392.                 mSelectorSystem->AddSelected(entity);
  393.                 //  }
  394.             }
  395.             ImGui::NextColumn();
  396.         };
  397.         mRegisterSystem->IterateOverAllEntitiesNotMatching(Iterator, gContext->MakeSignature<ECS::Comp::Transform>());
  398.         ImGui::TreePop();
  399.     }
  400.  
  401.     if (ImGui::TreeNode("FSM")) {
  402.         ImGui::Columns(5);
  403.         ImGui::Text("ID");
  404.         ImGui::NextColumn();
  405.         ImGui::Text("States");
  406.         ImGui::NextColumn();
  407.         ImGui::Text("Enabled");
  408.         ImGui::NextColumn();
  409.         ImGui::Text("Finished");
  410.         ImGui::NextColumn();
  411.         ImGui::Text("CurrentState");
  412.         ImGui::NextColumn();
  413.         ImGui::Separator();
  414.         Game::ContextIterateOverFsm(*gContext, [&](EddieFSM::FsmId id, EddieFSM::Fsm &fsm) {
  415.             // ImGui::Text("%d", id); ImGui::NextColumn();
  416.             if (ImGui::Selectable(std::to_string(id).data(), allFsm.find(id) != allFsm.end(),
  417.                                   ImGuiSelectableFlags_SpanAllColumns)) {
  418.  
  419.             }
  420.             if (ImGui::IsItemHovered()) {
  421.                 if (ImGui::IsMouseDoubleClicked(0)) {
  422.                     auto id = fsm.GetFsmIdentity();
  423.  
  424.                     gContext->EmitEvent<ECS::DropSelection>();
  425.                     gContext->EmitEvent<ECS::DirectSelectFsm>(id);
  426.                     std::cout << "Selecting " << id << std::endl;
  427.                     allFsm.clear();
  428.                     allFsm.insert(id);
  429.                 }
  430.                 if (ImGui::IsKeyDown(Key::ALT)) {
  431.                     ImGui::BeginTooltip();
  432.                     ImGui::Text("%s", fsm.GetDescriptiveName().data());
  433.                     ImGui::EndTooltip();
  434.                 }
  435.             }
  436.  
  437.             ImGui::NextColumn();
  438.  
  439.             ImGui::Text("%lu", fsm.States().size());
  440.             ImGui::NextColumn();
  441.             ImGui::Text("%s", fsm.IsEnabled() ? "True" : "False");
  442.             ImGui::NextColumn();
  443.             ImGui::Text("%s", fsm.IsFinished() ? "True" : "False");
  444.             ImGui::NextColumn();
  445.             if (fsm.GetCurrentState()) {
  446.                 ImGui::Text("%s", fsm.GetCurrentState()->GetStateName().data());
  447.             } else {
  448.                 ImGui::Text("NO STATE");
  449.             }
  450.             ImGui::NextColumn();
  451.         });
  452.         ImGui::Columns(1);
  453.         ImGui::TreePop();
  454.     }
  455.     //ImGui::TreePop();
  456.     if(selectedForRemove) {
  457.         ImGui::OpenPopup(REMOVE_FSM_WINDOW_ID);
  458.     }
  459.     RemoveFSMPopup();
  460.  
  461. }
  462.  
  463. void EddieUI::EntityList::RemoveFSMPopup() {
  464.  
  465.     if (ImGui::BeginPopupModal(REMOVE_FSM_WINDOW_ID, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
  466.         ImGui::Text("Are you sure you want to delete the FSM?\n\n");
  467.         ImGui::Separator();
  468.  
  469.         if (ImGui::Button("NO", ImVec2(120, 0))) {
  470.             selectedForRemove = false;
  471.             ImGui::CloseCurrentPopup();
  472.         }
  473.  
  474.         ImGui::SetItemDefaultFocus();
  475.         ImGui::SameLine(0, 40);
  476.  
  477.         if (ImGui::Button("YES", ImVec2(120, 0))) {
  478.             this->mSelectorSystem->ForEachSelected([](size_t idx, ECS::Entity &e) {
  479.                 e.Remove<ECS::Comp::Fsm>();
  480.             });
  481.             selectedForRemove = false;
  482.  
  483.             ImGui::CloseCurrentPopup();
  484.         }
  485.  
  486.         ImGui::EndPopup();
  487.     }
  488. }
  489.  
  490. void EddieUI::EntityList::HandleEvent(const ECS::ResourceProvider<ECS::SpriteProvider> &event) {
  491. //    this->spriteProvider = event.helper;
  492.     componentTag.SetSpriteProvider(event.helper);
  493. }
  494.  
  495. //EddieFSM::Fsm *EddieUI::EntityList::GetFsm(EddieFSM::FsmId id) {
  496. //    if (this->gContext) {
  497. //        return Game::ContextFindFsm(*gContext, id);
  498. //    }
  499. //    return nullptr;
  500. //}
  501.  
  502. void EddieUI::EntityList::HandleEvent(const ECS::ResourceProvider<ECS::VideoProvider> &event) {
  503. //    this->videoProvider = event.helper;
  504.     componentTag.SetVideoProvider(event.helper);
  505. }
  506.  
  507. void EddieUI::EntityList::SetGameContext(Game::Context &context) {
  508.     this->gContext = &context;
  509.     componentTag.SetGameContext(context);
  510. }
  511.  
  512. void EddieUI::EntityList::ConfigureListeners(Game::Context &context) {
  513.     context.Subscribe<ECS::ResourceProvider<ECS::SpriteProvider>>(this);
  514.     context.Subscribe<ECS::ResourceProvider<ECS::VideoProvider> >(this);
  515. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement