diff --git a/docs/tasks/refactoring.todo b/docs/tasks/refactoring.todo index 74b7e0c..eeb1b72 100644 --- a/docs/tasks/refactoring.todo +++ b/docs/tasks/refactoring.todo @@ -1,4 +1,22 @@ +Editor Action System: + - The main benefits of this are: + - 1: Central location for all actions (all action responsibilty goes to the editor class) + - 2: Actions are descretely organized into objects + - 3: allows for an action history with undo support + + ☐ All actions should go through the main editor (or the asset editor ie. the tile map editor) + - Context menus can remain in the panel classes but the resulting actions should be sent to the appropriate editor + ☐ Actions should be encapsulated, command pattern? + ☐ Actions should be undoable + ☐ Concrete Action classes should have an undo implementation + ☐ Action History Stack in the Editor + ☐ Refactor all panels of the main editor to use the actions system + ☐ World Tree + ☐ Content Browser + ☐ World View + ☐ Properties View + ☐ Create base classes for serializeable objects ✔ JSON serializeable @done(22-08-12 19:19) diff --git a/src/run_modes/editor/panels/world_tree.cpp b/src/run_modes/editor/panels/world_tree.cpp index f32db86..cb50d5a 100644 --- a/src/run_modes/editor/panels/world_tree.cpp +++ b/src/run_modes/editor/panels/world_tree.cpp @@ -82,10 +82,37 @@ namespace lunarium { namespace editor return; } + // Drop onto panel itself? + // TODO: Nope this does not work for dropping onto the panel + // if (ImGui::BeginDragDropTarget()) + // { + // if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("Entity")) + // { + // Entity *pDroppedEnt = *((Entity **)payload->Data); + + // if (pDroppedEnt->HasParent()) + // mpWorld->GetEntity(pDroppedEnt->GetParent())->RemoveChild(pDroppedEnt->GetUUID()); + + // } + // ImGui::EndDragDropTarget(); + // } + ImGui::SetNextItemOpen(true); if (ImGui::TreeNode("World Root")) { + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("Entity")) + { + Entity *pDroppedEnt = *((Entity **)payload->Data); + + if (pDroppedEnt->HasParent()) + mpWorld->GetEntity(pDroppedEnt->GetParent())->RemoveChild(pDroppedEnt->GetUUID()); + } + ImGui::EndDragDropTarget(); + } + // List all world entities int idx = 0; for (auto iter = mpWorld->EntitiesBegin(); !mpWorld->EntitiesIsEnd(iter); iter++, idx++) @@ -113,37 +140,52 @@ namespace lunarium { namespace editor { bool was_clicked = false; bool was_right_clicked = false; - if (ImGui::TreeNode(pEnt->GetName().c_str())) + + bool node_open = ImGui::TreeNode(pEnt->GetName().c_str()); + + // Handle drag and drop even if the node is closed + if (ImGui::BeginDragDropSource()) { - if (ImGui::BeginDragDropSource()) - { - // Need to pass a pointer to the payload data. This means we need to pass a - // pointer to the Entity pointer (Entity**) which &(*pEnt) becomes - ImGui::SetDragDropPayload("Entity", (void *)&(*pEnt), sizeof(Entity *)); - ImGui::Text("%s", pEnt->GetName().c_str()); - ImGui::EndDragDropSource(); - } + // Need to pass a pointer to the payload data. This means we need to pass a + // pointer to the Entity pointer (Entity**) which &pEnt becomes + ImGui::SetDragDropPayload("Entity", (void *)&pEnt, sizeof(Entity *)); + ImGui::Text("%s", pEnt->GetName().c_str()); + ImGui::EndDragDropSource(); + } - - if (ImGui::BeginDragDropTarget()) + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("Entity")) { - if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("Entity")) - { - Entity* pDroppedEnt = *((Entity**) payload->Data); + Entity *pDroppedEnt = *((Entity **)payload->Data); - // Can't drop and entity on itself - if (pDroppedEnt != pEnt) + // Can't drop and entity on itself + if (pDroppedEnt != pEnt) + { + // If the dropped ent is the parent of pEnt then we need to swap the relationship + if (pEnt->HasParent() && pEnt->GetParent() == pDroppedEnt->GetUUID()) { - // If the dropped ent is the parent of pEnt then we need to swap the relationship + // TODO: Finish Entity Drop Logic + } + + // If the dropped ent is already a child of pEnt then we do nothing - // If the dropped ent is already a child of pEnt then we do nothing + // Else add dropped ent as a child of pEnt + else if (!pDroppedEnt->HasParent() || (pDroppedEnt->GetParent() != pEnt->GetUUID())) + { + if (pDroppedEnt->HasParent()) + mpWorld->GetEntity(pDroppedEnt->GetParent())->RemoveChild(pDroppedEnt->GetUUID()); - // Else add dropped ent as a child of pEnt + pEnt->AddChild(pDroppedEnt->GetUUID()); } } - ImGui::EndDragDropTarget(); } + ImGui::EndDragDropTarget(); + } + // Now handle the node if it's open + if (node_open) + { was_clicked = ImGui::IsItemClicked(ImGuiMouseButton_Left); was_right_clicked = ImGui::IsItemClicked(ImGuiMouseButton_Right); diff --git a/src/world/entity.cpp b/src/world/entity.cpp index bbe85b2..051ed37 100644 --- a/src/world/entity.cpp +++ b/src/world/entity.cpp @@ -59,6 +59,20 @@ namespace lunarium mName = name; } + bool Entity::HasParent() + { + return HasComponent(); + } + + LUUID Entity::GetParent() + { + if (HasParent()) + { + return GetComponent().Parent; + } + + return 0; + } bool Entity::HasChildren() { diff --git a/src/world/entity.h b/src/world/entity.h index 4e0d17e..03ce286 100644 --- a/src/world/entity.h +++ b/src/world/entity.h @@ -74,8 +74,8 @@ namespace lunarium // TODO: : public JSONSerializable void RemoveChild(LUUID child); std::vector& GetChildren(); - // bool HasParent() const; - // LUUID GetParent() const; + bool HasParent(); + LUUID GetParent(); // void SetParent(LUUID parent); void ClearParent();