10#include <glm/gtc/type_ptr.hpp>
19void Elevate::Editor::AnalyserPanel::OnImGuiRender()
21 ImGui::Begin(
"Analyse");
23 std::weak_ptr<GameObject> selected = EditorLayer::Get().GetSelectedObject();
26 std::shared_ptr<GameObject> obj = selected.lock();
32 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
33 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.r + 0.3f, color.g + 0.3f, color.b + 0.3f, 1.0f));
34 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(color.r, color.g, color.b, 1.0f));
35 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(color.r + 0.1f, color.g + 0.1f, color.b + 0.1f, 1.0f));
36 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(color.r + 0.2f, color.g + 0.2f, color.b + 0.2f, 1.0f));
38 RenderComponentLayout(obj->GetTransform().GetLayout());
43 m_alredyAddedComponents.clear();
45 std::map<EECategory, std::vector<Component*>> m_sortedComponents;
46 for (Component* comp : obj->GetComponents())
48 m_sortedComponents[comp->GetCategory()].push_back(comp);
49 m_alredyAddedComponents.push_back(comp->GetTypeIndex());
52 for (std::pair<
EECategory, std::vector<Component*>> entry : m_sortedComponents)
54 const std::string& categoryName = entry.first.GetName();
56 glm::vec4 color = entry.first.GetCategoryColor();
57 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
58 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.r + 0.3f, color.g + 0.3f, color.b + 0.3f, 1.0f));
59 ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(color.r, color.g, color.b, 1.0f));
60 ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.r + 0.1f, color.g + 0.1f, color.b + 0.1f, 1.0f));
61 ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(color.r + 0.2f, color.g + 0.2f, color.b + 0.2f, 1.0f));
62 if (ImGui::CollapsingHeader(categoryName.c_str(), ImGuiTreeNodeFlags_DefaultOpen))
64 ImGui::PopStyleColor(4);
67 for (Component* comp : entry.second)
71 RenderComponent(comp);
77 ImGui::PopStyleColor(4);
82 if (ImGui::Button(
"Add Component", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
84 ImGui::OpenPopup(
"AddComponentPopup");
87 if (ImGui::BeginPopup(
"AddComponentPopup"))
89 ImGui::Text(
"Add component :");
93 for (
auto& pair : ComponentRegistry::GetEntries())
95 InsertCategory(root, pair.second);
97 std::weak_ptr<GameObject> obj = EditorLayer::Get().GetSelectedObject();
98 for (
auto& cat : root.childs)
100 DrawCategoryMenu(cat, obj);
102 DrawCategoryChildren(root, obj);
111void Elevate::Editor::AnalyserPanel::RenderComponent(Component* comp)
113 const ComponentLayout layout = comp->GetLayout();
119 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.r + 0.3f, color.g + 0.3f, color.b + 0.3f, 1.0f));
120 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(color.r, color.g, color.b, 1.0f));
121 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(color.r + 0.1f, color.g + 0.1f, color.b + 0.1f, 1.0f));
122 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(color.r + 0.2f, color.g + 0.2f, color.b + 0.2f, 1.0f));
124 RenderComponentLayout(layout, comp);
127void Elevate::Editor::AnalyserPanel::RenderComponentLayout(
const ComponentLayout& layout, Component* component)
129 const void* texHandle =
nullptr;
132 if (!m_textureCache.count(component))
134 m_textureCache.insert({ component, component->GetEditorIconHandle() });
136 texHandle = m_textureCache.at(component);
139 if (UI::EECollapsingHeader((layout.GetName()).c_str(),
140 layout.GetFieldCount() > 0,
142 [&layout, &component]()
144 float menu_width = 0;
148 ImGuiStyle& style = ImGui::GetStyle();
150 float customButtonWidth = 25.0f;
151 float customButtonHeight = ImGui::GetFontSize() + style.FramePadding.y * 2.0f;
152 menu_width = customButtonWidth + style.FramePadding.x;
154 ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - customButtonWidth, ImGui::GetCursorPosY()));
155 ImGui::PushID(layout.GetName().c_str());
156 if (ImGui::Button(
"...", ImVec2(customButtonWidth, customButtonHeight)))
157 ImGui::OpenPopup(
"HeaderMenu");
159 if (ImGui::BeginPopup(
"HeaderMenu"))
161 if (ImGui::MenuItem(
"Remove Component"))
163 EditorLayer::Get().PushCommand(std::make_unique<RemoveComponentCommand>(component));
173 ImGui::PopStyleColor(4);
175 for (
const ComponentField& field : layout)
182 ImGui::PopStyleColor(4);
186void Elevate::Editor::AnalyserPanel::RenderField(
const ComponentField& field)
const
188 ImGui::BeginDisabled(field.readOnly);
192 case ComponentDataType::Float:
193 ImGui::InputFloat(field.GetDisplayName().c_str(), (
float*)(field.data));
196 case ComponentDataType::Float2:
197 ImGui::InputFloat2(field.GetDisplayName().c_str(), (
float*)(field.data));
200 case ComponentDataType::Float3:
202 ImGui::ColorEdit3(field.GetDisplayName().c_str(), (
float*)(field.data));
204 ImGui::InputFloat3(field.GetDisplayName().c_str(), (
float*)(field.data));
207 case ComponentDataType::Float4:
209 ImGui::ColorEdit4(field.GetDisplayName().c_str(), (
float*)(field.data));
211 ImGui::InputFloat4(field.GetDisplayName().c_str(), (
float*)(field.data));
214 case ComponentDataType::Bool:
215 ImGui::Checkbox(field.GetDisplayName().c_str(), (
bool*)(field.data));
218 case ComponentDataType::Custom:
221 if (ImGui::TreeNodeEx(field.GetDisplayName().c_str(), ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_FramePadding))
223 for (
const auto& child : field.children)
230 for (
const auto& child : field.children)
236 ImGui::TextColored(ImVec4(1, 0, 0, 1),
"Unsupported data type: %s", field.name.c_str());
240 ImGui::EndDisabled();
242 if (!field.tooltip.empty())
244 ImGui::SetItemTooltip(
"%s", field.tooltip.c_str());
248void Elevate::Editor::AnalyserPanel::InsertCategory(CategoryMenu& root,
const ComponentRegistry::Entry& entry)
255 std::string path = entry.category.GetPath();
258 root.items.push_back(entry);
262 CategoryMenu* current = &root;
267 size_t pos = path.find(
'/', start);
268 std::string part = (pos == std::string::npos)
270 : path.substr(start, pos - start);
272 std::string accumulated = path.substr(0, (pos == std::string::npos ? path.size() : pos));
274 auto it = std::find_if(current->childs.begin(), current->childs.end(),
275 [&](
const CategoryMenu& child) {
276 return child.category.GetPath() == accumulated;
279 if (it == current->childs.end())
283 current->childs.push_back(std::move(child));
284 it = std::prev(current->childs.end());
289 if (pos == std::string::npos)
291 current->items.push_back(entry);
299void Elevate::Editor::AnalyserPanel::DrawCategoryChildren(
const CategoryMenu& category, std::weak_ptr<GameObject> obj)
302 for (
auto& entry : category.items)
304 bool alreadyAdded =
false;
305 for (
auto& type : m_alredyAddedComponents)
307 if (type == entry.type)
314 ImGui::BeginDisabled(alreadyAdded);
315 if (ImGui::Selectable(entry.name.c_str()))
317 if (
auto go = obj.lock())
319 EditorLayer::Get().PushCommand(std::make_unique<AddComponentCommand>(go, entry.factory, entry.destructor));
322 ImGui::EndDisabled();
326void Elevate::Editor::AnalyserPanel::DrawCategoryMenu(
const CategoryMenu& menu, std::weak_ptr<GameObject> obj)
328 if (!menu.category.GetName().empty())
330 if (ImGui::BeginMenu(menu.category.GetName().c_str()))
332 for (
auto& child : menu.childs)
334 DrawCategoryMenu(child, obj);
337 DrawCategoryChildren(menu, obj);
344 for (
auto& child : menu.childs)
346 DrawCategoryMenu(child, obj);
glm::vec4 GetCategoryColor()
void InputField(const char *label, std::string &data)