Base work on reimplementing editor GUI

This commit is contained in:
2016-01-17 07:34:20 +01:00
parent 4786986abd
commit 0d50ede6f5
8 changed files with 198 additions and 14 deletions
+65
View File
@@ -0,0 +1,65 @@
#ifndef EditorGUI_h__
#define EditorGUI_h__
#include <imgui/imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui_internal.h>
#include <nativefiledialog/nfd.h>
#include <boost/filesystem.hpp>
#include "../Common.h"
#include "../Core/EventBroker.h"
#include "../Core/World.h"
#include "../Core/EntityWrapper.h"
class EditorGUI
{
public:
EditorGUI(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
void Draw(World* world);
void SelectEntity(EntityWrapper entity);
// Called when an entity is selected in the entity tree
typedef std::function<void(EntityWrapper)> OnEntitySelectedCallback_t;
void SetEntitySelectedCallback(OnEntitySelectedCallback_t f) { m_OnEntitySelected = f; }
// Called when the user means to import an entity file.
// Expects an EntityWrapper of the newly created entity in return.
typedef std::function<EntityWrapper(boost::filesystem::path)> OnEntityImport_t;
void SetEntityImportCallback(OnEntityImport_t f) { m_OnEntityImport = f; }
// Called when the user means to save an entity to file.
// Expects a bool indicating whether the save was successful or not in return.
typedef std::function<bool(EntityWrapper, boost::filesystem::path)> OnEntitySave_t;
void SetEntitySaveCallback(OnEntitySave_t f) { m_OnEntitySave = f; }
// Called when the user means to create a new entity.
// @param EntityWrapper The parent of the entity to be created
// @return EntityWrapper The newly created entity
typedef std::function<EntityWrapper(EntityWrapper)> OnEntityCreate_t;
void SetEntityCreateCallback(OnEntityCreate_t f) { m_OnEntityCreate = f; }
// Called when the user means to delete an entity.
typedef std::function<void(EntityWrapper)> OnEntityDelete_t;
void SetEntityCreateCallback(OnEntityDelete_t f) { m_OnEntityDelete = f; }
private:
EventBroker* m_EventBroker;
// State variables
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
// Callbacks
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
OnEntityImport_t m_OnEntityImport = nullptr;
OnEntitySave_t m_OnEntitySave = nullptr;
OnEntityCreate_t m_OnEntityCreate = nullptr;
OnEntityDelete_t m_OnEntityDelete = nullptr;
void drawMenu();
void drawEntities(World* world);
void drawEntitiesRecursive(World* world, EntityID parent);
bool drawEntityNode(EntityWrapper entity);
};
#endif
+4 -1
View File
@@ -8,6 +8,7 @@
#include "../Core/ResourceManager.h"
#include "../Core/EntityFilePreprocessor.h"
#include "../Core/EntityFileParser.h"
#include "EditorGUI.h"
class EditorSystem : public ImpureSystem
{
@@ -23,8 +24,10 @@ private:
World* m_EditorWorld;
SystemPipeline* m_EditorWorldSystemPipeline;
Camera* m_EditorCamera;
EntityWrapper m_Widget = EntityWrapper::Invalid;
EntityWrapper m_Camera = EntityWrapper::Invalid;
DebugCameraInputController<EditorSystem>* m_DebugCameraInputController;
EditorGUI* m_EditorGUI;
void OnEntitySelected(EntityWrapper entity);
};
-8
View File
@@ -1,8 +0,0 @@
#include <imgui/imgui.h>
#include <nativefiledialog/nfd.h>
class EditorUI
{
public:
EditorUI();
};
+2 -1
View File
@@ -13,7 +13,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="-0"/>
<Position X="0" Y="0" Z="-2"/>
<Scale X="1" Y="1" Z="1"/>
</c:Transform>
<c:Camera>
@@ -23,5 +23,6 @@
</c:Model>
</Components>
</Entity>
<EntityRef file="Schema/Entities/EditorWidget.xml"/>
</Children>
</Entity>
+1 -3
View File
@@ -38,9 +38,7 @@
<xs:element ref="Entity" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="EntityRef" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:attribute name="file" type="xs:string" minOccurs="0"/>
</xs:all>
<xs:attribute name="file" type="xs:string" minOccurs="0"/>
</xs:complexType>
</xs:element>
</xs:sequence>
+114
View File
@@ -0,0 +1,114 @@
#include "Editor/EditorGUI.h"
void EditorGUI::Draw(World* world)
{
drawMenu();
drawEntities(world);
}
void EditorGUI::SelectEntity(EntityWrapper entity)
{
m_CurrentSelection = entity;
if (m_OnEntitySelected != nullptr) {
m_OnEntitySelected(entity);
}
}
void EditorGUI::drawMenu()
{
}
void EditorGUI::drawEntities(World* world)
{
if (!ImGui::Begin("Entities")) {
return;
}
drawEntitiesRecursive(world, EntityID_Invalid);
ImGui::End();
}
void EditorGUI::drawEntitiesRecursive(World* world, EntityID parent)
{
auto entityChildren = world->GetEntityChildren();
auto range = entityChildren.equal_range(parent);
for (auto it = range.first; it != range.second; it++) {
if (EditorGUI::drawEntityNode(EntityWrapper(world, it->second))) {
drawEntitiesRecursive(world, it->second);
ImGui::TreePop();
}
}
}
bool EditorGUI::drawEntityNode(EntityWrapper entity)
{
ImVec2 pos = ImGui::GetCursorScreenPos();
float width = ImGui::GetContentRegionAvailWidth();
ImRect bb(pos + ImVec2(20, 0), pos + ImVec2(width, 13));
auto window = ImGui::GetCurrentWindow();
if (m_CurrentSelection == entity) {
const ImU32 col = window->Color(ImGuiCol_HeaderActive);
window->DrawList->AddRectFilled(bb.Min, bb.Max, col);
}
ImGuiID id = window->GetID((std::string("#SelectButton") + std::to_string(entity)).c_str());
bool hovered = false;
bool held = false;
if (ImGui::ButtonBehavior(bb, id, &hovered, &held)) {
SelectEntity(entity);
}
//if (held) {
// ImVec2 entityDragDelta = ImGui::GetMouseDragDelta(0);
// if (std::abs(entityDragDelta.x) > 0 && std::abs(entityDragDelta.y) > 0) {
// if (m_UIDraggingEntity == EntityID_Invalid) {
// m_UIDraggingEntity = entity;
// LOG_DEBUG("Started drag of entity %i", m_UIDraggingEntity);
// }
// ImGui::SetNextWindowPos(ImGui::GetIO().MousePos + ImVec2(20, 0));
// ImGui::Begin("Change parent", nullptr, ImVec2(0, 0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings);
// ImGui::Text("#%i", m_UIDraggingEntity);
// ImGui::End();
// }
//}
ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once);
std::string nodeTitle;
const std::string& entityName = entity.World->GetName(entity);
if (!entityName.empty()) {
nodeTitle = entityName;
} else {
nodeTitle = std::string("#") + std::to_string(entity.ID);
}
if (ImGui::TreeNode(nodeTitle.c_str())) {
//if (m_UIDraggingEntity != EntityID_Invalid && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) {
// LOG_DEBUG("Changed parent of %i to %i", m_UIDraggingEntity, entity);
// changeParent(m_UIDraggingEntity, entity);
// m_UIDraggingEntity = EntityID_Invalid;
//}
if (ImGui::BeginPopupContextItem("item context menu")) {
if (ImGui::Button("Add")) {
if (m_OnEntityCreate != nullptr) {
EntityWrapper newEntity = m_OnEntityCreate(EntityWrapper(entity.World, EntityID_Invalid));
ImGui::CloseCurrentPopup();
SelectEntity(newEntity);
}
}
ImGui::SameLine();
if (ImGui::Button("Delete")) {
if (m_OnEntityDelete != nullptr) {
m_OnEntityDelete(entity);
ImGui::CloseCurrentPopup();
}
if (!m_CurrentSelection.Valid()) {
SelectEntity(EntityWrapper::Invalid);
}
}
ImGui::EndPopup();
}
return true;
} else {
return false;
}
}
+12 -1
View File
@@ -24,6 +24,9 @@ EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer, Render
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
m_EditorGUI = new EditorGUI(m_EventBroker);
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
Events::SetCamera e;
e.CameraEntity = m_Camera;
m_EventBroker->Publish(e);
@@ -31,6 +34,7 @@ EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer, Render
EditorSystem::~EditorSystem()
{
delete m_EditorGUI;
delete m_DebugCameraInputController;
delete m_EditorWorldSystemPipeline;
delete m_EditorWorld;
@@ -40,7 +44,14 @@ void EditorSystem::Update(World* world, double dt)
{
m_EditorWorldSystemPipeline->Update(m_EditorWorld, dt);
m_EditorGUI->Draw(world);
m_DebugCameraInputController->Update(dt);
m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position();
m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation());
}
}
void EditorSystem::OnEntitySelected(EntityWrapper entity)
{
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(entity.World, entity.ID);
}
View File