#include "ElementDrawer.hpp" #include "BehaviourScriptRegistry.hpp" #include "elements/ShaderRegistry.hpp" #include "BehaviourScripts/Camera.hpp" #include namespace TSE::EDITOR { #pragma region helper bool InputText(const char* label, std::string& str, size_t bufferSize = 256) { std::vector buffer(bufferSize); strncpy(buffer.data(), str.c_str(), bufferSize); buffer[bufferSize - 1] = '\0'; bool changed = ImGui::InputText(label, buffer.data(), bufferSize); if (changed) { str = std::string(buffer.data()); } return changed; } void BeginList(std::string listName) { ImGui::BeginChild(listName.c_str(), {0,150}, ImGuiChildFlags_Borders); } bool ListAddBtn(std::string label = "Add") { float available_width = ImGui::GetContentRegionAvail().x; return ImGui::Button(label.c_str(),{available_width, 0}); } void BeginListItem(std::string name, float customHeight = 20) { float available_width = ImGui::GetContentRegionAvail().x; ImGui::BeginChild(name.c_str(),{available_width - 30, customHeight}); } void EndListItem() { ImGui::EndChild(); } bool ListItemXBotton(std::string id) { ImGui::SameLine(); return ImGui::Button(id.c_str(), {20,0}); } void EndList() { ImGui::EndChild(); } #pragma endregion void ElementDrawer::DrawAddDropdown(const std::vector& options, string& selectedOption) { ImGuiStyle& style = ImGui::GetStyle(); float availableWidth = ImGui::GetContentRegionAvail().x; // Add Button if (ImGui::Button("Add", ImVec2(availableWidth, 0))) { addDropdownOpen = !addDropdownOpen; } if (addDropdownOpen) { // Begin Popup ImGui::BeginChild("##AddDropdownChild", ImVec2(availableWidth, 300), true); // Suchfeld mit X Button ImGui::PushItemWidth(-style.FramePadding.x * 4 - 24); // Platz für Clear Button ImGui::InputTextWithHint("##SearchField", "Suchfeld", searchBuffer, IM_ARRAYSIZE(searchBuffer)); ImGui::PopItemWidth(); ImGui::SameLine(); if (ImGui::Button("X")) { searchBuffer[0] = '\0'; } ImGui::Separator(); // Scrollbare Liste mit Filter ImGui::BeginChild("##OptionsList", ImVec2(0, 250), false, ImGuiWindowFlags_AlwaysVerticalScrollbar); int count = 0; for (const auto& option : options) { if (strlen(searchBuffer) == 0 || option.find(searchBuffer) != std::string::npos) { if (ImGui::Selectable(option.c_str())) { selectedOption = option; addDropdownOpen = false; break; } count++; if (count >= 50) break; // Begrenze maximal gezeichnete Elemente zur Performance } } ImGui::EndChild(); ImGui::EndChild(); } } void ElementDrawer::Draw(Transformable* element,const bool& debug) { ImGui::SeparatorText("Transform"); ImGui::Checkbox("##checkbox", &element->_enabled); ImGui::SameLine(); InputText("<-- Name##", element->name); ImGui::DragFloat3("<-- Position", &element->position.x, 0.1f); ImGui::DragFloat3("<--Scale", &element->scale.x, 0.1f); Vector3 euler = element->GetEuler(); ImGui::DragFloat3("<-- Rotation", &(euler.x), 0.1f); element->SetEuler(euler); ImGui::Spacing(); if(debug) { ImGui::BeginDisabled(); ImGui::Text(("ID: " + to_string(element->id)).c_str()); ImGui::Text(("Child Count: " + std::to_string(element->GetChildren().size())).c_str()); ImGui::Text(("Component Count: " + std::to_string(element->GetComponentCount())).c_str()); ImGui::EndDisabled(); ImGui::Spacing(); } if(element->GetComponentCount() > 0) ImGui::SeparatorText("Components"); for (int i = 0; i < element->GetComponentCount(); i++) { Draw(element->GetBehaviourScriptAt(i), debug, i); } ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); std::vector behaviourScripts; for (const auto& [name, _] : BehaviourScriptRegistry::GetRegistry()) { behaviourScripts.push_back(name); } std::string selectedScript = ""; DrawAddDropdown(behaviourScripts, selectedScript); if (!selectedScript.empty()) { // Erzeuge das Script: BehaviourScript* script = BehaviourScriptRegistry::CreateBehaviourScript(selectedScript); if (script) { if(element->HasBehaviourScript(typeid(*script).name())) { delete script; } else element->AddBehaviourScript(script); } selectedScript = ""; // Reset nach Hinzufügen } } void ElementDrawer::Draw(Scene* element,const bool& debug) { ImGui::Text("Scene Name: %s", element->GetName().c_str()); ImGui::Text("Layer Count: %d", element->GetLayerCount()); } void ElementDrawer::Draw(Layer* element,const bool& debug) { ImGui::Text("Layer Name: %s", element->GetName().c_str()); } void ElementDrawer::Draw(BehaviourScript *element, const bool &debug, const int& id) { ImGui::PushID(("Script##" + std::to_string(id)).c_str()); std::string name = element->GetName(); if(ImGui::CollapsingHeader(name.c_str())) { bool enabled = element->IsEnabled(); ImGui::Checkbox("enabled", &enabled); element->SetEnabled(enabled); if(name == "Renderable") { Draw((Renderable*)element, debug); } else if (name == "Mesh Container") { Draw((MeshContainer*)element, debug); } else if (name == "Image") { Draw((Image*)element, debug); } else if (name == "Image Animation") { Draw((ImageAnimation*)element, debug); } else if (name == "Rect Base") { Draw((RectBase*)element, debug); } else if (name == "Camera") { Draw((Camera*)element, debug); } else if (name == "Particle System") { Draw((ParticleSystem*)element, debug); } else { element->CustomDraw(debug); } } ImGui::PopID(); } void ElementDrawer::Draw(Renderable *element, const bool &debug) { ImGui::SeparatorText("Material"); int height = 100; if(element->GetMaterial() == nullptr) { height = 35; } ImVec2 size(0, height); ImGui::BeginChild("MaterialViewer", size, ImGuiChildFlags_Borders); Draw(element->GetMaterial(), debug); ImGui::EndChild(); } void ElementDrawer::Draw(MeshContainer *element, const bool &debug) { int height = ImGui::GetContentRegionAvail().x; if(element->GetMesh() == nullptr) { height = 35; } ImVec2 size(0, height); Draw(element->GetMesh(), debug, "Mesh", true); } void ElementDrawer::Draw(Image *element, const bool &debug) { int height = ImGui::GetContentRegionAvail().x + 50; if(element->GetSpritePtr() == nullptr) { height = 35; } ImVec2 size(0, height); ImGui::SeparatorText("Sprite"); Draw(element->GetSpritePtr(), debug, "Sprite", true); } void ElementDrawer::Draw(ImageAnimation *element, const bool &debug) { int currentSelection = -1; int itemCount = element->GetImageAnimationSetCount(); std::vector items; for (int i = 0; i < itemCount; i++) { if(element->GetImageAnimationAt(i) == nullptr) continue; items.push_back(element->GetImageAnimationAt(i)->Name); if(element->GetImageAnimationAt(i)->Name == element->GetCurrentAnimation()) { currentSelection = i; } } auto getter = [](void* vec, int idx, const char** out_text) { auto& vector = *static_cast*>(vec); if (idx < 0 || idx >= static_cast(vector.size())) return false; *out_text = vector.at(idx).c_str(); return true; }; if(ImGui::Combo("Active animation", ¤tSelection, getter, static_cast(&items), items.size())) { element->StartAnimation(items[currentSelection]); } items.clear(); for (int i = 0; i < itemCount; i++) { if(element->GetImageAnimationAt(i) == nullptr) { items.push_back("NULL"); continue; } items.push_back(element->GetImageAnimationAt(i)->Name); } ImGui::Text(("Frame: " + std::to_string(element->GetCurrentFrame())).c_str()); if(debug) { ImGui::TextDisabled(("DeltaTime: " + std::to_string(element->GetDeltaTime())).c_str()); } ImGui::SeparatorText("Animation Sets"); BeginList("ImageAnimationSetList"); if(ListAddBtn() && (itemCount == 0 || items[itemCount - 1] != "NULL")) { element->SetAnimationSet("NULL", nullptr); itemCount++; items.push_back("NULL"); } for (int i = 0; i < itemCount; i++) { BeginListItem("subcomponent##" + std::to_string(i)); Draw(element->GetImageAnimationAt(i),debug, items[i], true); EndListItem(); if(ListItemXBotton("x##" + std::to_string(i))) { element->RemoveAnimationSet(items[i]); itemCount--; i--; } } EndList(); } void ElementDrawer::Draw(RectBase *element, const bool &debug) { ImGui::DragFloat2("Size", &element->size.x); ImGui::Separator(); if (ImGui::TreeNode("Anchors")) { ImGui::Text("Min"); ImGui::DragFloat("X##anchor_min_x", &element->anchors.p1.x,0.2f); ImGui::DragFloat("Y##anchor_min_y", &element->anchors.p1.y,0.2f); ImGui::Text("Max"); ImGui::DragFloat("X##anchor_max_x", &element->anchors.p2.x,0.2f); ImGui::DragFloat("Y##anchor_max_y", &element->anchors.p2.y,0.2f); ImGui::TreePop(); } ImGui::Text("Pivot"); ImGui::DragFloat("X##pivot_x", &element->pivit.x,0.2f); ImGui::DragFloat("Y##pivot_y", &element->pivit.y,0.2f); } void ElementDrawer::Draw(Material *element, const bool &debug) { if(element == nullptr) { ImGui::TextDisabled("No material"); return; } else { InputText("Name", element->GetName()); int currentSelection = -1; int itemCount = ShaderRegistry::GetShaderCount(); std::vector items; for (int i = 0; i < itemCount; i++) { if(ShaderRegistry::GetShaderAt(i) == nullptr) continue; items.push_back(ShaderRegistry::GetNameAt(i)); if(ShaderRegistry::GetShaderAt(i) == element->GetShader()) { currentSelection = i; } } auto getter = [](void* vec, int idx, const char** out_text) { auto& vector = *static_cast*>(vec); if (idx < 0 || idx >= static_cast(vector.size())) return false; *out_text = vector.at(idx).c_str(); return true; }; if(ImGui::Combo("Shader", ¤tSelection, getter, static_cast(&items), items.size())) { element->SetShader(ShaderRegistry::GetShader(items[currentSelection])); } if(debug) ImGui::TextDisabled(to_string(element->GetID()).c_str()); ImGui::Separator(); int count = element->GetValueCount(); for(int i = 0; i < count; i++) { std::tuple tupel = element->GetValueAt(i); auto[ptr, type, name] = tupel; if (type == typeid(int).name()) { int value = element->GetValue(name); if(ImGui::InputInt(name.c_str(), &value)) { element->SetValue(name, value); } } else if (type == typeid(float).name()) { float value = element->GetValue(name); if(ImGui::InputFloat(name.c_str(), &value)) { element->SetValue(name, value); } } else if (type == typeid(Vector2).name()) { Vector2 value = element->GetValue(name); if(ImGui::InputFloat2(name.c_str(), &value.x)) { element->SetValue(name, value); } } else if (type == typeid(Vector3).name()) { Vector3 value = element->GetValue(name); if(ImGui::InputFloat3(name.c_str(), &value.x)) { element->SetValue(name, value); } } else if (type == typeid(Vector4).name()) { Vector4 value = element->GetValue(name); if(ImGui::InputFloat4(name.c_str(), &value.x)) { element->SetValue(name, value); } } else if (type == typeid(Matrix4x4).name()) { Matrix4x4 value = element->GetValue(name); //TODO: need to implement; } else if (type == typeid(Color).name()) { Color value = element->GetValue(name); if(ImGui::ColorEdit4(name.c_str(), &value.r)) { element->SetValue(name, value); } } else if (type == typeid(std::string).name()) { Vector4 value = element->GetValue(name); if(ImGui::InputFloat4(name.c_str(), &value.x)) { element->SetValue(name, value); } } else if (type == typeid(Texture*).name()) { Texture* value = element->GetValue(name); Draw(value, debug, name , true); } else { ImGui::TextDisabled(("Not Implemented: " + type).c_str()); } } } } void ElementDrawer::Draw(Texture *element, const bool &debug, const std::string& label, const bool small) { if(element == nullptr) { ImGui::Text("No Texture Set"); return; } if(small) DrawTextureCompact(element, debug, label); else DrawTextureNormal(element, debug, label); } void ElementDrawer::Draw(Sprite *element, const bool &debug, const std::string &label, const bool small) { if(element == nullptr) { ImGui::Text("No Sprite Set"); return; } if(small) DrawSpriteCompact(element, debug, label); else DrawSpriteNormal(element, debug, label); } void ElementDrawer::Draw(Mesh *element, const bool &debug, const std::string &label, const bool small) { if(element == nullptr) { ImGui::Text("No Mesh Set"); return; } if(small) DrawMeshCompact(element, debug, label); else DrawMeshNormal(element, debug, label); } void ElementDrawer::Draw(ImageAnimationSet *element, const bool &debug, const std::string &label, const bool small) { if(element == nullptr) { ImGui::Text("No Animation Set Asigned"); return; } if(small) DrawImageAnimationSetCompact(element, debug, label); else DrawImageAnimationSetNormal(element, debug, label); } void ElementDrawer::Draw(Camera *element, const bool &debug) { const bool isMain = (Camera::mainCamera == element); if (!isMain && element->baseObject->name != ".EditorCamera") { if (ImGui::Button("Make Main Camera")) { Camera::mainCamera = element; } } else if(element->baseObject->name != ".EditorCamera") { ImGui::Text("This is the Main Camera"); } else { ImGui::Text("Editor Camera can't be main camera"); } ImGui::Separator(); // Render Scale float renderScale = element->GetRenderScale(); if (ImGui::DragFloat("Render Scale", &renderScale, 0.1f)) element->SetRenderScale(renderScale); ImGui::Separator(); // Projection int projIndex = (element->GetProjection() == ProjectionType::Orthographic) ? 0 : 1; const char* projItems[] = { "Orthographic", "Perspective" }; if (ImGui::Combo("Projection", &projIndex, projItems, IM_ARRAYSIZE(projItems))) element->SetProjection(projIndex == 0 ? ProjectionType::Orthographic : ProjectionType::Perspective); // Clipping Planes float nearCP = element->GetNearClippingPlane(); if (ImGui::DragFloat("Near Clipping Plane", &nearCP, 0.1f)) element->SetNearClippingPlane(nearCP); float farCP = element->GetFarClippingPlane(); if (ImGui::DragFloat("Far Clipping Plane", &farCP, 0.1f)) element->SetFarClippingPlane(farCP); // Field of View (only relevant for Perspective) const bool isPerspective = (element->GetProjection() == ProjectionType::Perspective); if (!isPerspective) ImGui::BeginDisabled(); float fov = element->GetFov(); if (ImGui::DragFloat("Field of View (deg)", &fov, 0.1f)) element->SetFov(fov); if (!isPerspective) ImGui::EndDisabled(); } void ElementDrawer::Draw(ParticleSystem *element, const bool &debug) { float indent = 15.0f; auto OpeningAngleDeg = [](float conePlane) -> float { float cosA = std::clamp(conePlane * 2.0f - 1.0f, -1.0f, 1.0f); return std::acos(cosA) * (180.0f / TSE_PI); }; auto ClampPositive = [](float& v, float minv = 0.0f) { if (v < minv) v = minv; }; // ========================= // MISC // ========================= ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent); if (ImGui::CollapsingHeader("Misc", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(20.0f); int pc = static_cast(element->particleCount); if (ImGui::DragInt("Max Particles", &pc, 1.0f, 0, 100000)) { if (pc < 0) pc = 0; element->particleCount = static_cast(pc); } ImGui::Checkbox("Start with Simulated Particles", &element->startWithSimulatedParicles); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Wenn aktiv, wird beim Start bereits ein gefüllter Partikelpuffer simuliert."); ImGui::Unindent(20.0f); ImGui::Separator(); } // ========================= // START CONDITIONS // ========================= ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent); if (ImGui::CollapsingHeader("Start Conditions", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(20.0f); if (ImGui::TreeNodeEx("Rotation (Start)", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(16.0f); ImGui::Checkbox("Random Rotation Direction", &element->startWithRandomRotationDirection); if (!element->startWithRandomRotationDirection) { int dirIdx = (element->rotationDirection >= 0.0f) ? 1 : 0; const char* dirItems[] = { "-1 (CCW)", "+1 (CW)" }; if (ImGui::Combo("Rotation Direction", &dirIdx, dirItems, IM_ARRAYSIZE(dirItems))) { element->rotationDirection = (dirIdx == 1) ? 1.0f : -1.0f; } } else { ImGui::BeginDisabled(); float dummy = element->rotationDirection; ImGui::InputFloat("Rotation Direction", &dummy); ImGui::EndDisabled(); } ImGui::Checkbox("Random Start Rotation", &element->startWithRandomRotation); if (element->startWithRandomRotation) { ImGui::DragFloat("Min Rotation (rad)", &element->minRotationRad, 0.01f); ImGui::DragFloat("Max Rotation (rad)", &element->maxrotationRad, 0.01f); if (element->maxrotationRad < element->minRotationRad) std::swap(element->minRotationRad, element->maxrotationRad); } else { ImGui::DragFloat("Start Rotation (rad)", &element->maxrotationRad, 0.01f); ImGui::BeginDisabled(); ImGui::DragFloat("Min Rotation (rad)", &element->minRotationRad, 0.01f); ImGui::EndDisabled(); } ImGui::Unindent(16.0f); ImGui::TreePop(); } if (ImGui::TreeNode("Size (Start)")) { ImGui::Indent(16.0f); ImGui::Checkbox("Random Start Size", &element->startWithRandomSize); if (element->startWithRandomSize) { if (ImGui::DragFloat("Min Size", &element->minSize, 0.01f)) { ClampPositive(element->minSize, 0.0f); } if (ImGui::DragFloat("Max Size", &element->maxSize, 0.01f)) { ClampPositive(element->maxSize, 0.0f); } if (element->maxSize < element->minSize) std::swap(element->minSize, element->maxSize); } else { if (ImGui::DragFloat("Start Size", &element->maxSize, 0.01f)) { ClampPositive(element->maxSize, 0.0f); } ImGui::BeginDisabled(); ImGui::DragFloat("Min Size", &element->minSize, 0.01f); ImGui::EndDisabled(); } ImGui::Unindent(16.0f); ImGui::TreePop(); } if (ImGui::TreeNode("Lifetime (Start)")) { ImGui::Indent(16.0f); ImGui::Checkbox("Random Start Lifetime", &element->startWithRandomLifetime); if (element->startWithRandomLifetime) { if (ImGui::DragFloat("Min Lifetime (s)", &element->minLifetime, 0.01f)) { ClampPositive(element->minLifetime, 0.0f); } if (ImGui::DragFloat("Max Lifetime (s)", &element->maxLifetime, 0.01f)) { ClampPositive(element->maxLifetime, 0.0f); } if (element->maxLifetime < element->minLifetime) std::swap(element->minLifetime, element->maxLifetime); } else { if (ImGui::DragFloat("Lifetime (s)", &element->maxLifetime, 0.01f)) { ClampPositive(element->maxLifetime, 0.0f); } ImGui::BeginDisabled(); ImGui::DragFloat("Min Lifetime (s)", &element->minLifetime, 0.01f); ImGui::EndDisabled(); } ImGui::Unindent(16.0f); ImGui::TreePop(); } ImGui::Unindent(20.0f); ImGui::Separator(); } // ========================= // LIFETIME CONDITIONS // ========================= ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent); if (ImGui::CollapsingHeader("Lifetime Conditions", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(20.0f); if (ImGui::TreeNode("Color over Lifetime")) { ImGui::Indent(16.0f); ImGui::Checkbox("Enable Color over Lifetime", &element->changeColorOverLifetime); // Start immer editierbar ImGui::ColorEdit4("Start Color", &element->startColor.r, ImGuiColorEditFlags_Float); // End nur wenn aktiviert if (!element->changeColorOverLifetime) ImGui::BeginDisabled(); ImGui::ColorEdit4("End Color", &element->endColor.r, ImGuiColorEditFlags_Float); if (!element->changeColorOverLifetime) ImGui::EndDisabled(); ImGui::Unindent(16.0f); ImGui::TreePop(); } if (ImGui::TreeNode("Speed over Lifetime")) { ImGui::Indent(16.0f); ImGui::Checkbox("Enable Speed over Lifetime", &element->changeSpeedOverLifetime); // Start immer frei ImGui::DragFloat("Start Speed", &element->startSpeed, 0.01f); // End nur bei aktiv if (!element->changeSpeedOverLifetime) ImGui::BeginDisabled(); ImGui::DragFloat("End Speed", &element->endSpeed, 0.01f); if (!element->changeSpeedOverLifetime) ImGui::EndDisabled(); ImGui::Unindent(16.0f); ImGui::TreePop(); } if (ImGui::TreeNode("Rotation Speed over Lifetime")) { ImGui::Indent(16.0f); ImGui::Checkbox("Enable RotationSpeed over Lifetime", &element->changeRotationspeedOverLifetime); // Start immer frei ImGui::DragFloat("Start RotSpeed", &element->startRotationSpeed, 0.01f); // End nur bei aktiv if (!element->changeRotationspeedOverLifetime) ImGui::BeginDisabled(); ImGui::DragFloat("End RotSpeed", &element->endRotationSpeed, 0.01f); if (!element->changeRotationspeedOverLifetime) ImGui::EndDisabled(); ImGui::Unindent(16.0f); ImGui::TreePop(); } ImGui::Unindent(20.0f); ImGui::Separator(); } // ========================= // SPAWN AREA // ========================= ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent); if (ImGui::CollapsingHeader("Spawn Area", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(20.0f); ImGui::DragFloat3("Offset (world)", &element->offset.x, 0.01f); ImGui::DragFloat3("Forward", &element->forward.x, 0.01f); ImGui::SameLine(); if (ImGui::SmallButton("Normalize##fwd")) { element->forward.NormalizeSafe(Vector3::forward); } if (ImGui::DragFloat("Radius", &element->radius, 0.01f)) { if (element->radius < 0.0f) element->radius = 0.0f; } if (ImGui::SliderFloat("Cone Plane", &element->conePlane, 0.0f, 1.0f, "%.3f")) { element->conePlane = std::clamp(element->conePlane, 0.0f, 1.0f); } float angle = OpeningAngleDeg(element->conePlane); ImGui::Text("Opening Angle: %.2f deg", angle); const char* mode = "Forward Cone"; if (element->conePlane == 1.0f) mode = "Full Sphere"; else if (element->conePlane <= 0.5f) mode = "Forward Cone"; else mode = "Inverse Cone"; ImGui::Text("Mode (derived): %s", mode); if (debug) { ImGui::Separator(); ImGui::TextDisabled("Debug:"); ImGui::BulletText("Forward len^2: %.6f", element->forward.LengthSqr()); } ImGui::Unindent(20.0f); } } void ElementDrawer::DrawImageAnimationSetCompact(ImageAnimationSet *element, const bool &debug, const std::string &label) { float item_spacing = ImGui::GetStyle().ItemSpacing.x; ImVec2 label_size = ImGui::CalcTextSize(label.c_str()); float available_width = ImGui::GetContentRegionAvail().x; float field_width = available_width - label_size.x - item_spacing; ImVec2 field_size = ImVec2(field_width, label_size.y + 4); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_FrameBg)); // gleiche Farbe wie InputText ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetStyle().FrameRounding); ImGui::BeginChild("##FakeInput", field_size, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::SetCursorPos(ImVec2(2, 2)); ImGui::TextUnformatted(element->Name.c_str()); ImGui::EndChild(); ImGui::PopStyleVar(); ImGui::PopStyleColor(); ImGui::SameLine(); ImVec2 cursorCurrent = ImGui::GetCursorPos(); cursorCurrent.y += 2; ImGui::SetCursorPos(cursorCurrent); ImGui::TextUnformatted(label.c_str()); } void ElementDrawer::DrawImageAnimationSetNormal(ImageAnimationSet *element, const bool &debug, const std::string &label) { InputText("Name", element->Name); ImGui::InputFloat("Frame Time", &element->frameTime); ImGui::SeparatorText("Sprites"); BeginList("SpriteList"); if(ListAddBtn()) { element->Sprites.push_back(nullptr); } auto it = element->Sprites.begin(); for (int i = 0; i < element->Sprites.size(); i++) { BeginListItem("subcomponent##" + std::to_string(i),65); Draw(element->Sprites[i],debug, std::to_string(i), true); EndListItem(); if(ListItemXBotton("x##" + std::to_string(i))) { auto it2 = it; it--; element->Sprites.erase(it2); i--; } it++; } EndList(); } void ElementDrawer::DrawMeshCompact(Mesh *element, const bool &debug, const std::string &label) { float item_spacing = ImGui::GetStyle().ItemSpacing.x; ImVec2 label_size = ImGui::CalcTextSize(label.c_str()); float available_width = ImGui::GetContentRegionAvail().x; float field_width = available_width - label_size.x - item_spacing; ImVec2 field_size = ImVec2(field_width, label_size.y + 4); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_FrameBg)); // gleiche Farbe wie InputText ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetStyle().FrameRounding); ImGui::BeginChild("##FakeInput", field_size, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::SetCursorPos(ImVec2(2, 2)); ImGui::TextUnformatted(element->name.c_str()); ImGui::EndChild(); ImGui::PopStyleVar(); ImGui::PopStyleColor(); ImGui::SameLine(); ImVec2 cursorCurrent = ImGui::GetCursorPos(); cursorCurrent.y += 2; ImGui::SetCursorPos(cursorCurrent); ImGui::TextUnformatted(label.c_str()); } void ElementDrawer::DrawMeshNormal(Mesh *element, const bool &debug, const std::string &label) { ImGui::Text(("Name: " + element->name).c_str()); if(debug) { //ImGui::TextDisabled(("ID: " + to_string(element->id)).c_str()); } ImGui::Separator(); ImGui::Text(("Vectex Count: " + std::to_string(element->vertecies.size())).c_str()); ImGui::Text(("Index Count: " + std::to_string(element->indecies.size())).c_str()); ImGui::Text(("UV Count: " + std::to_string(element->uvs.size())).c_str()); ImGui::Indent(20.0f); if(ImGui::CollapsingHeader("Vertecies")) { ImGui::PushID("Verts"); ImGui::BeginDisabled(); for (int i = 0; i < element->vertecies.size(); i++) { ImGui::InputFloat3(std::to_string(i).c_str(), &element->vertecies[i].x); } ImGui::EndDisabled(); ImGui::PopID(); } if(ImGui::CollapsingHeader("Indecies")) { ImGui::PushID("Inds"); ImGui::BeginDisabled(); for (int i = 0; i < element->indecies.size(); i++) { int val = element->indecies[i]; ImGui::InputInt(std::to_string(i).c_str(), &val); } ImGui::EndDisabled(); ImGui::PopID(); } if(ImGui::CollapsingHeader("UVs")) { ImGui::PushID("Uvs"); ImGui::BeginDisabled(); for (int i = 0; i < element->uvs.size(); i++) { ImGui::InputFloat2(std::to_string(i).c_str(), &element->uvs[i].x); } ImGui::EndDisabled(); ImGui::PopID(); } ImGui::Unindent(20.0f); } void ElementDrawer::DrawSpriteCompact(Sprite *element, const bool &debug, const std::string &label) { float item_spacing = ImGui::GetStyle().ItemSpacing.x; ImVec2 label_size = ImGui::CalcTextSize(label.c_str()); float available_width = ImGui::GetContentRegionAvail().x; float field_width = available_width - label_size.x - item_spacing; ImVec2 field_size = ImVec2(field_width, 60); Rect r = element->GetUVRect(); float ymultiplyer = (element->GetTexture()->height() * r.height()) / (element->GetTexture()->width() * r.width()); ImVec2 texSize (field_size.y - 2, (field_size.y - 2) * ymultiplyer); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_FrameBg)); // gleiche Farbe wie InputText ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetStyle().FrameRounding); ImGui::BeginChild("##FakeInput", field_size, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::SetCursorPos(ImVec2(1,(60-texSize.y) / 2)); ImGui::Image(element->GetTexture()->GetTextureId(), texSize, {r.p1.x,r.p2.y}, {r.p2.x,r.p1.y}); ImGui::EndChild(); ImGui::PopStyleVar(); ImGui::PopStyleColor(); ImGui::SameLine(); ImVec2 cursorCurrent = ImGui::GetCursorPos(); cursorCurrent.y += (60-label_size.y) / 2; ImGui::SetCursorPos(cursorCurrent); ImGui::TextUnformatted(label.c_str()); } void ElementDrawer::DrawSpriteNormal(Sprite *element, const bool &debug, const std::string &label) { Rect& r = element->GetUVRect(); ImGui::InputFloat2("UV1", &r.p1.x); ImGui::InputFloat2("UV2", &r.p2.x); if(debug) { Draw(element->GetTexture(), debug, "Texture", true); } ImGui::Separator(); float available_width = ImGui::GetContentRegionAvail().x; float ymultiplyer = (element->GetTexture()->height() * r.height()) / (element->GetTexture()->width() * r.width()); ImVec2 texSize (available_width, (available_width) * ymultiplyer); ImGui::Image(element->GetTexture()->GetTextureId(), texSize, {r.p1.x,r.p2.y}, {r.p2.x,r.p1.y}); } void ElementDrawer::DrawTextureCompact(Texture *element, const bool &debug, const std::string &label) { float item_spacing = ImGui::GetStyle().ItemSpacing.x; ImVec2 label_size = ImGui::CalcTextSize(label.c_str()); float available_width = ImGui::GetContentRegionAvail().x; float field_width = available_width - label_size.x - item_spacing; ImVec2 field_size = ImVec2(field_width, 60); float ymultiplyer = element->height() / element->width(); ImVec2 texSize (field_size.y - 2, (field_size.y - 2) * ymultiplyer); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_FrameBg)); // gleiche Farbe wie InputText ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetStyle().FrameRounding); ImGui::BeginChild("##FakeInput", field_size, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::SetCursorPos(ImVec2(1,(60-texSize.y) / 2)); ImGui::Image(element->GetTextureId(), texSize, {0,1}, {1,0}); ImGui::SameLine(); ImGui::SetCursorPos(ImVec2(field_size.y + 1,(60-label_size.y) / 2)); ImGui::TextUnformatted(element->name.c_str()); ImGui::EndChild(); ImGui::PopStyleVar(); ImGui::PopStyleColor(); ImGui::SameLine(); ImVec2 cursorCurrent = ImGui::GetCursorPos(); cursorCurrent.y += (60-label_size.y) / 2; ImGui::SetCursorPos(cursorCurrent); ImGui::TextUnformatted(label.c_str()); } void ElementDrawer::DrawTextureNormal(Texture *element, const bool &debug, const std::string& label) { ImGui::TextUnformatted(element->name.c_str()); if(debug) { ImGui::Separator(); ImGui::TextDisabled(("Width: " + std::to_string(element->width())).c_str()); ImGui::TextDisabled(("Height: " + std::to_string(element->height())).c_str()); ImGui::TextDisabled(("BPP: " + std::to_string(element->bpp())).c_str()); ImGui::TextDisabled(("Chanels: " + std::to_string(element->Chanels())).c_str()); ImGui::Separator(); ImGui::TextDisabled(("TextureID: " + std::to_string(element->GetTextureId())).c_str()); } ImGui::Separator(); float available_width = ImGui::GetContentRegionAvail().x; float ymultiplyer = element->height() / element->width(); ImVec2 texSize (available_width, (available_width) * ymultiplyer); ImGui::Image(element->GetTextureId(), texSize, {0,1}, {1,0}); } } // namespace TSE::EDITOR