#include "HirearchieView.hpp" #include "PropertiesView.hpp" TSE::EDITOR::HirearchieView::HirearchieView(Scene *s) : GuiWindow("Hirearchie", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoCollapse) { SetScene(s); } void TSE::EDITOR::HirearchieView::SetScene(Scene *s) { currentScene = s; } bool selectedFound = false; void TSE::EDITOR::HirearchieView::Define() { if(currentScene == nullptr) return; MenuBar(); bool collapseOpen = ImGui::CollapsingHeader(currentScene->GetName().c_str(), ImGuiTreeNodeFlags_DefaultOpen); if(ImGui::BeginPopupContextItem()) { if(ImGui::MenuItem("Rename")) { strcpy(inputBuffer, currentScene->GetName().c_str()); activatePopUpNamingLayer = true; inputPurpose = RenamingScene; } ImGui::Separator(); AddMenu(nullptr, nullptr); ImGui::EndPopup(); } if(collapseOpen) { int layerCount = currentScene->GetLayerCount(); selectedFound = false; for (int i = 0; i < layerCount; i++) { auto layer = currentScene->GetLayerAt(i); //if(layer->GetName() != ".editor") DisplayLayer(layer); } if(!selectedFound && PropertiesView::GetCurrentInspectableType() == InspectableType::Transformable) { PropertiesView::ForceClearInspectorElement(); } } if(activatePopUpNamingLayer) { activatePopUpNamingLayer = false; openPopUpNamingLayer = true; ImGui::OpenPopup("Enter Text"); } if (openPopUpNamingLayer) { if (ImGui::BeginPopupModal("Enter Text", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("Please enter a Name:"); ImGui::InputText("##input", inputBuffer, IM_ARRAYSIZE(inputBuffer)); bool inputValid = strlen(inputBuffer) > 0; if (!inputValid) { ImGui::TextColored(ImVec4(1,0,0,1), "Not Valid."); } if (ImGui::Button("OK", ImVec2(120, 0))) { if (inputValid) { inputConfirmed = true; openPopUpNamingLayer = false; ImGui::CloseCurrentPopup(); } } ImGui::SameLine(); if (ImGui::Button("Cancel", ImVec2(120, 0))) { openPopUpNamingLayer = false; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } } if (inputConfirmed) { switch (inputPurpose) { case LayerCreation: CreateLayer(); break; case RenamingLayer: currentScene->RenameLayer(tmpHolder2->GetName(), inputBuffer); tmpHolder2 = nullptr; break; case RenamingScene: currentScene->SetName(inputBuffer); break; case RenamingTransformable: tmpHolder1->name = inputBuffer; tmpHolder1 = nullptr; break; } inputConfirmed = false; inputPurpose = Nothing; strcpy(inputBuffer, ""); // Reset } } void TSE::EDITOR::HirearchieView::MenuBar() { if(ImGui::BeginMenuBar()) { if(ImGui::BeginMenu("Add")) { if(ImGui::MenuItem("Empty")) { CreateEmpty(currentScene->GetLayerAt(0)); } ImGui::Separator(); if(ImGui::MenuItem("Layer")) { activatePopUpNamingLayer = true; inputPurpose = LayerCreation; } ImGui::EndMenu(); } } ImGui::EndMenuBar(); } void TSE::EDITOR::HirearchieView::DisplayLayer(Layer *l) { ImGui::Indent(20.0f); bool collapseOpen = ImGui::CollapsingHeader(l->GetName().c_str(), ImGuiTreeNodeFlags_DefaultOpen); if(ImGui::BeginPopupContextItem()) { bool disabled = currentScene->GetLayerCount() <= 1; if (disabled) { ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); } if(ImGui::MenuItem("Move Up") && !disabled) { MoveUpLayer(l); } if(ImGui::MenuItem("Move Down") && !disabled) { MoveDownLayer(l); } if (disabled) { ImGui::PopStyleVar(); } if(ImGui::MenuItem("Rename")) { strcpy(inputBuffer, l->GetName().c_str()); activatePopUpNamingLayer = true; inputPurpose = RenamingLayer; tmpHolder2 = l; } ImGui::Separator(); AddMenu(nullptr, l); ImGui::Separator(); if(ImGui::MenuItem("Delete")) { currentScene->RemoveLayer(l->GetName()); //property display remove if present //exit early: ImGui::EndPopup(); ImGui::Unindent(20.0f); return; } ImGui::EndPopup(); } if(ImGui::BeginDragDropTarget()) { auto payload = ImGui::AcceptDragDropPayload("OBJ_TRANS_PTR"); if(payload != nullptr) { auto t2 = *(Transformable**)payload->Data; HandleDropping(l, t2); } ImGui::EndDragDropTarget(); } if(collapseOpen) { for(int i = 0; i < l->GetAllObjects().size(); i++) { DisplayObj(l->GetAllObjects()[i], l); } } ImGui::Unindent(20.0f); } void TSE::EDITOR::HirearchieView::DisplayObj(Transformable *t, Layer *l) { ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth; if(t->GetChildren().size() == 0) { flags |= ImGuiTreeNodeFlags_Leaf; } if(selected == t->id) { flags |= ImGuiTreeNodeFlags_Selected; selectedFound = true; } string name = t->GetName() + "##" + to_string(t->id); bool open = ImGui::TreeNodeEx((name).c_str(), flags); if(ImGui::BeginPopupContextItem()) { bool disabled = false; if(t->GetParent() != nullptr) disabled = t->GetParent()->GetChildren().size() < 1; else disabled = l->GetAllObjects().size() <= 1; if (disabled) { ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); } if(ImGui::MenuItem("Move Up") && !disabled) { t->MoveUp(l); } if(ImGui::MenuItem("Move Down") && !disabled) { t->MoveDown(l); } if (disabled) { ImGui::PopStyleVar(); } if(ImGui::MenuItem("Rename")) { strcpy(inputBuffer, t->name.c_str()); activatePopUpNamingLayer = true; inputPurpose = RenamingTransformable; tmpHolder1 = t; } ImGui::Separator(); AddMenu(t, nullptr); ImGui::Separator(); if(ImGui::MenuItem("Delete")) { t->SetParent(nullptr); int layerCount = currentScene->GetLayerCount(); for (int i = 0; i < layerCount; i++) { auto layer = currentScene->GetLayerAt(i); if(layer->HasTransformable(t)) { layer->RemoveTransformable(t); break; } } Transformable::HardDelete(t->id); PropertiesView::ForceClearInspectorElement(); //exit early: ImGui::EndPopup(); if(open) { ImGui::TreePop(); } return; } ImGui::EndPopup(); } if(ImGui::BeginDragDropSource()) { auto ptr = &t; ImGui::SetDragDropPayload("OBJ_TRANS_PTR", ptr, sizeof(ptr)); std::string name = t->GetName(); ImGui::Text((std::string("Move \"") + t->GetName() + "\"").c_str()); ImGui::EndDragDropSource(); } if(ImGui::BeginDragDropTarget()) { auto payload = ImGui::AcceptDragDropPayload("OBJ_TRANS_PTR"); if(payload != nullptr) { auto t2 = *(Transformable**)payload->Data; HandleDropping(t, t2); } ImGui::EndDragDropTarget(); } if(ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { selected = t->id; PropertiesView::SetInspectorElement(InspectableType::Transformable, t); selectedFound = true; } if(open) { for(int i = 0; i < t->GetChildren().size(); i++) { DisplayObj(t->GetChildren()[i], nullptr); } ImGui::TreePop(); } } void TSE::EDITOR::HirearchieView::HandleDropping(Layer *target, Transformable *payload) { payload->SetParent(nullptr); int layerCount = currentScene->GetLayerCount(); for (int i = 0; i < layerCount; i++) { auto layer = currentScene->GetLayerAt(i); if(layer == target && layer->HasTransformable(payload)) return; if(layer->HasTransformable(payload)) { layer->RemoveTransformable(payload); break; } } target->AddTransformable(payload); } void TSE::EDITOR::HirearchieView::HandleDropping(Transformable *target, Transformable *payload) { if(target->id == payload->id) return; if(payload->IsMyChild(target)) return; int layerCount = currentScene->GetLayerCount(); for (int i = 0; i < layerCount; i++) { auto layer = currentScene->GetLayerAt(i); if(layer->HasTransformable(payload)) { layer->RemoveTransformable(payload); break; } } payload->SetParent(target); } void TSE::EDITOR::HirearchieView::AddMenu(Transformable *t, Layer *l) { if(t== nullptr && l == nullptr) //Scene { if(ImGui::MenuItem("Add Layer")) { activatePopUpNamingLayer = true; inputPurpose = LayerCreation; } } else //Layer and Transformable { if(ImGui::MenuItem("Add Empty")) { if(t == nullptr) CreateEmpty(l); else CreateEmpty(t); } } } void TSE::EDITOR::HirearchieView::MoveUpLayer(Layer *t) { if(currentScene->GetLayerAt(0) == t) return; currentScene->MoveLayerUp(t); } void TSE::EDITOR::HirearchieView::MoveDownLayer(Layer *t) { int lc = currentScene->GetLayerCount(); if(currentScene->GetLayerAt(lc - 1) == t) return; currentScene->MoveLayerDown(t); } void TSE::EDITOR::HirearchieView::CreateEmpty(Transformable *parent) { Transformable* t = new Transformable("Unnamed Object"); if(parent != nullptr) { t->SetParent(parent); } // else // { // // TODO: need to chose a layer to put it in. I would suggest the first one? // currentScene->GetLayerAt(0)->AddTransformable(t); // } } void TSE::EDITOR::HirearchieView::CreateEmpty(Layer *parent) { Transformable* t = new Transformable("Unnamed Object"); if(parent != nullptr) { parent->AddTransformable(t); } } void TSE::EDITOR::HirearchieView::CreateLayer() { Layer* l = new Layer(inputBuffer); currentScene->AddLayer(l); }