405 lines
11 KiB
C++
405 lines
11 KiB
C++
#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);
|
|
}
|