<commit_before>#include "ImGuiEntityEditorSystem.hpp"
#include "EntityManager.hpp"

#include "components/ImGuiComponent.hpp"
#include "components/SelectedComponent.hpp"

#include "functions/Basic.hpp"
#include "functions/ImGuiEditor.hpp"

#include "packets/AddImGuiTool.hpp"

#include "imgui.h"

auto ImGuiEntityEditor(kengine::EntityManager & em) {
	return [&](kengine::Entity & e) {
		static bool display = true;
		em.send(kengine::packets::AddImGuiTool{ "Entity editor", display });

		e += kengine::ImGuiComponent([&] {
			if (!display)
				return;

			for (auto &[selected, _] : em.getEntities<kengine::SelectedComponent>()) {
				bool open = true;
				if (ImGui::Begin(putils::string<64>("[%d] Entity editor", selected.id), &open)) {
					static char nameSearch[1024] = "";
					ImGui::InputText("Component", nameSearch, sizeof(nameSearch));

					const auto components = em.getComponentFunctionMaps();
					if (ImGui::CollapsingHeader("Edit"))
						for (const auto comp : components) {
							const auto has = comp->getFunction<kengine::functions::Has>();
							const auto edit = comp->getFunction<kengine::functions::EditImGui>();
							if (has != nullptr && edit != nullptr && strstr(comp->name, nameSearch) && has(selected))
								if (ImGui::TreeNode(comp->name)) {
									edit(selected);
									ImGui::TreePop();
								}
						}

					if (ImGui::CollapsingHeader("Add"))
						for (const auto comp : components) {
							const auto has = comp->getFunction<kengine::functions::Has>();
							const auto add = comp->getFunction<kengine::functions::Attach>();
							if (has != nullptr && add != nullptr && strstr(comp->name, nameSearch) && !has(selected))
								if (ImGui::Button(comp->name))
									add(selected);
						}

					if (ImGui::CollapsingHeader("Remove"))
						for (const auto comp : components) {
							const auto has = comp->getFunction<kengine::functions::Has>();
							const auto remove = comp->getFunction<kengine::functions::Detach>();
							if (has != nullptr && remove != nullptr && strstr(comp->name, nameSearch) && has(selected))
								if (ImGui::Button(putils::string<64>(comp->name) + "##remove"))
									remove(selected);
						}
				}
				ImGui::End();
				if (!open)
					selected.detach<kengine::SelectedComponent>();
			}
		});
	};
}

void kengine::ImGuiEntityEditorSystem::onLoad(const char * directory) noexcept {
	_em += ImGuiEntityEditor(_em);
}<commit_msg>improved entity editor layout<commit_after>#include "ImGuiEntityEditorSystem.hpp"
#include "EntityManager.hpp"

#include "components/ImGuiComponent.hpp"
#include "components/SelectedComponent.hpp"

#include "functions/Basic.hpp"
#include "functions/ImGuiEditor.hpp"

#include "packets/AddImGuiTool.hpp"

#include "imgui.h"

auto ImGuiEntityEditor(kengine::EntityManager & em) {
	return [&](kengine::Entity & e) {
		static bool display = true;
		em.send(kengine::packets::AddImGuiTool{ "Entity editor", display });

		e += kengine::ImGuiComponent([&] {
			if (!display)
				return;

			for (auto &[selected, _] : em.getEntities<kengine::SelectedComponent>()) {
				ImGui::SetNextWindowSize({ 200.f, 200.f}, ImGuiCond_FirstUseEver);

				if (ImGui::Begin(putils::string<64>("[%d] Entity editor", selected.id), nullptr, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) {

					if (ImGui::Button("x"))
						selected.detach<kengine::SelectedComponent>();
					ImGui::SameLine();
					ImGui::Text("Search");
					ImGui::SameLine();
					static char nameSearch[1024] = "";
					ImGui::PushItemWidth(-1.f);
					ImGui::InputText("##Search", nameSearch, sizeof(nameSearch));
					ImGui::PopItemWidth();

					{
						ImGui::BeginChild("##child");
						const auto components = em.getComponentFunctionMaps();
						if (ImGui::CollapsingHeader("Edit"))
							for (const auto comp : components) {
								const auto has = comp->getFunction<kengine::functions::Has>();
								const auto edit = comp->getFunction<kengine::functions::EditImGui>();
								if (has != nullptr && edit != nullptr && strstr(comp->name, nameSearch) && has(selected))
									if (ImGui::TreeNode(putils::string<64>(comp->name) + "##edit")) {
										edit(selected);
										ImGui::TreePop();
									}
							}

						if (ImGui::CollapsingHeader("Add"))
							for (const auto comp : components) {
								const auto has = comp->getFunction<kengine::functions::Has>();
								const auto add = comp->getFunction<kengine::functions::Attach>();
								if (has != nullptr && add != nullptr && strstr(comp->name, nameSearch) && !has(selected))
									if (ImGui::Button(putils::string<64>(comp->name) + "##add"))
										add(selected);
							}

						if (ImGui::CollapsingHeader("Remove"))
							for (const auto comp : components) {
								const auto has = comp->getFunction<kengine::functions::Has>();
								const auto remove = comp->getFunction<kengine::functions::Detach>();
								if (has != nullptr && remove != nullptr && strstr(comp->name, nameSearch) && has(selected))
									if (ImGui::Button(putils::string<64>(comp->name) + "##remove"))
										remove(selected);
							}

						ImGui::EndChild();
					}
				}
				ImGui::End();
			}
		});
	};
}

void kengine::ImGuiEntityEditorSystem::onLoad(const char * directory) noexcept {
	_em += ImGuiEntityEditor(_em);
}
{'fraction_non_alphanumeric': 0.16780045351473924, 'fraction_numerical': 0.00510204081632653, 'mean_word_length': 3.8604224058769514, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4927636', 'n_tokens_mistral': 2095, 'n_tokens_neox': 1601, 'n_words': 313}