Editor widget selection and creation
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
#include <glm/gtx/common.hpp>
|
#include <glm/gtx/common.hpp>
|
||||||
|
|
||||||
|
#include "EditorWidgetSystem.h"
|
||||||
#include "../Core/EventBroker.h"
|
#include "../Core/EventBroker.h"
|
||||||
#include "../Core/World.h"
|
#include "../Core/World.h"
|
||||||
#include "../Core/EntityWrapper.h"
|
#include "../Core/EntityWrapper.h"
|
||||||
@@ -22,6 +23,13 @@ class EditorGUI
|
|||||||
public:
|
public:
|
||||||
EditorGUI(World* world, EventBroker* eventBroker);
|
EditorGUI(World* world, EventBroker* eventBroker);
|
||||||
|
|
||||||
|
enum class WidgetMode
|
||||||
|
{
|
||||||
|
Translate,
|
||||||
|
Rotate,
|
||||||
|
Scale
|
||||||
|
};
|
||||||
|
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
void SelectEntity(EntityWrapper entity);
|
void SelectEntity(EntityWrapper entity);
|
||||||
@@ -59,6 +67,9 @@ public:
|
|||||||
// Called when the user means to delete a component off an entity.
|
// Called when the user means to delete a component off an entity.
|
||||||
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentDelete_t;
|
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentDelete_t;
|
||||||
void SetComponentDeleteCallback(OnComponentDelete_t f) { m_OnComponentDelete = f; }
|
void SetComponentDeleteCallback(OnComponentDelete_t f) { m_OnComponentDelete = f; }
|
||||||
|
// Called when the user selects a widget mode.
|
||||||
|
typedef std::function<void(WidgetMode)> OnWidgetMode_t;
|
||||||
|
void SetWidgetModeCallback(OnWidgetMode_t f) { m_OnWidgetMode = f; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
World* m_World;
|
World* m_World;
|
||||||
@@ -72,6 +83,7 @@ private:
|
|||||||
std::unordered_map<EntityWrapper, boost::filesystem::path> m_EntityFiles;
|
std::unordered_map<EntityWrapper, boost::filesystem::path> m_EntityFiles;
|
||||||
EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid;
|
||||||
std::string m_LastErrorMessage;
|
std::string m_LastErrorMessage;
|
||||||
|
WidgetMode m_CurrentWidgetMode = WidgetMode::Translate;
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
||||||
@@ -83,6 +95,7 @@ private:
|
|||||||
OnEntityChangeName_t m_OnEntityChangeName = nullptr;
|
OnEntityChangeName_t m_OnEntityChangeName = nullptr;
|
||||||
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
||||||
OnComponentDelete_t m_OnComponentDelete = nullptr;
|
OnComponentDelete_t m_OnComponentDelete = nullptr;
|
||||||
|
OnWidgetMode_t m_OnWidgetMode = nullptr;
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
boost::filesystem::path fileOpenDialog();
|
boost::filesystem::path fileOpenDialog();
|
||||||
|
|||||||
@@ -26,14 +26,19 @@ private:
|
|||||||
World* m_EditorWorld;
|
World* m_EditorWorld;
|
||||||
SystemPipeline* m_EditorWorldSystemPipeline;
|
SystemPipeline* m_EditorWorldSystemPipeline;
|
||||||
Camera* m_EditorCamera;
|
Camera* m_EditorCamera;
|
||||||
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
|
||||||
EntityWrapper m_Camera = EntityWrapper::Invalid;
|
EntityWrapper m_Camera = EntityWrapper::Invalid;
|
||||||
DebugCameraInputController<EditorSystem>* m_DebugCameraInputController;
|
DebugCameraInputController<EditorSystem>* m_DebugCameraInputController;
|
||||||
EditorGUI* m_EditorGUI;
|
EditorGUI* m_EditorGUI;
|
||||||
EditorStats* m_EditorStats;
|
EditorStats* m_EditorStats;
|
||||||
|
|
||||||
|
// State
|
||||||
|
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
|
||||||
|
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
||||||
|
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
|
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
|
||||||
|
void setWidgetMode(EditorGUI::WidgetMode mode);
|
||||||
|
|
||||||
// GUI callbacks
|
// GUI callbacks
|
||||||
void OnEntitySelected(EntityWrapper entity);
|
void OnEntitySelected(EntityWrapper entity);
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef EditorWidgetSystem_h__
|
||||||
|
#define EditorWidgetSystem_h__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<EditorWidget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="EditorWidget.xsd">
|
<EditorWidget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="EditorWidget.xsd">
|
||||||
<Type><None/></Type>
|
<Type><Translate/></Type>
|
||||||
<Axis X="0" Y="0" Z="0"/>
|
<Axis X="0" Y="0" Z="0"/>
|
||||||
</EditorWidget>
|
</EditorWidget>
|
||||||
@@ -7,10 +7,9 @@
|
|||||||
<xs:complexContent>
|
<xs:complexContent>
|
||||||
<xs:extension base="t:enum">
|
<xs:extension base="t:enum">
|
||||||
<xs:choice>
|
<xs:choice>
|
||||||
<xs:element name="None" type="xs:integer" fixed="0" minOccurs="0"/>
|
<xs:element name="Translate" type="xs:integer" fixed="0" minOccurs="0"/>
|
||||||
<xs:element name="Translate" type="xs:integer" fixed="1" minOccurs="0"/>
|
<xs:element name="Rotate" type="xs:integer" fixed="1" minOccurs="0"/>
|
||||||
<xs:element name="Rotate" type="xs:integer" fixed="2" minOccurs="0"/>
|
<xs:element name="Scale" type="xs:integer" fixed="2" minOccurs="0"/>
|
||||||
<xs:element name="Scale" type="xs:integer" fixed="3" minOccurs="0"/>
|
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
</xs:extension>
|
</xs:extension>
|
||||||
</xs:complexContent>
|
</xs:complexContent>
|
||||||
|
|||||||
@@ -36,13 +36,55 @@ void EditorGUI::drawTools()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate widget button
|
// Translate widget button
|
||||||
ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Translate.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0));
|
if (ImGui::ImageButton(
|
||||||
|
(void*)tryLoadTexture("Textures/Icons/Translate.png"),
|
||||||
|
ImVec2(24, 24),
|
||||||
|
ImVec2(0, 1),
|
||||||
|
ImVec2(1, 0),
|
||||||
|
-1,
|
||||||
|
ImVec4(0, 0, 0, 0),
|
||||||
|
(m_CurrentWidgetMode == WidgetMode::Translate) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
m_CurrentWidgetMode = WidgetMode::Translate;
|
||||||
|
if (m_OnWidgetMode != nullptr) {
|
||||||
|
m_OnWidgetMode(m_CurrentWidgetMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Rotate widget button
|
// Rotate widget button
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Rotate.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0));
|
if (ImGui::ImageButton(
|
||||||
|
(void*)tryLoadTexture("Textures/Icons/Rotate.png"),
|
||||||
|
ImVec2(24, 24),
|
||||||
|
ImVec2(0, 1),
|
||||||
|
ImVec2(1, 0),
|
||||||
|
-1,
|
||||||
|
ImVec4(0, 0, 0, 0),
|
||||||
|
(m_CurrentWidgetMode == WidgetMode::Rotate) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
m_CurrentWidgetMode = WidgetMode::Rotate;
|
||||||
|
if (m_OnWidgetMode != nullptr) {
|
||||||
|
m_OnWidgetMode(m_CurrentWidgetMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Scale widget button
|
// Scale widget button
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Scale.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0));
|
if (ImGui::ImageButton(
|
||||||
|
(void*)tryLoadTexture("Textures/Icons/Scale.png"),
|
||||||
|
ImVec2(24, 24),
|
||||||
|
ImVec2(0, 1),
|
||||||
|
ImVec2(1, 0),
|
||||||
|
-1,
|
||||||
|
ImVec4(0, 0, 0, 0),
|
||||||
|
(m_CurrentWidgetMode == WidgetMode::Scale) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
m_CurrentWidgetMode = WidgetMode::Scale;
|
||||||
|
if (m_OnWidgetMode != nullptr) {
|
||||||
|
m_OnWidgetMode(m_CurrentWidgetMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::ItemSize(ImVec2(5, 0));
|
ImGui::ItemSize(ImVec2(5, 0));
|
||||||
@@ -83,7 +125,7 @@ void EditorGUI::drawEntities(World* world)
|
|||||||
entityImport(world);
|
entityImport(world);
|
||||||
}
|
}
|
||||||
ImGui::SameLine(0.f, 5.f);
|
ImGui::SameLine(0.f, 5.f);
|
||||||
ImGui::Button("Reference", ImVec2(buttonWidth, 0));
|
ImGui::ButtonEx("Reference", ImVec2(buttonWidth, 0), ImGuiButtonFlags_Disabled);
|
||||||
|
|
||||||
// Naming
|
// Naming
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
|||||||
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
||||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||||
|
|
||||||
m_Widget = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/EditorWidget.xml");
|
m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
||||||
|
|
||||||
m_Camera = EntityWrapper(m_EditorWorld, m_EditorWorld->CreateEntity());
|
|
||||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
||||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
|
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
|
||||||
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
|
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
|
||||||
@@ -29,6 +27,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
|||||||
m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2));
|
m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
|
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
|
||||||
|
|
||||||
m_EditorStats = new EditorStats();
|
m_EditorStats = new EditorStats();
|
||||||
|
|
||||||
@@ -60,7 +59,8 @@ void EditorSystem::Update(double dt)
|
|||||||
|
|
||||||
void EditorSystem::OnEntitySelected(EntityWrapper entity)
|
void EditorSystem::OnEntitySelected(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(entity.World, entity.ID);
|
m_CurrentSelection = entity;
|
||||||
|
setWidgetMode(m_WidgetMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath)
|
void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath)
|
||||||
@@ -118,4 +118,36 @@ EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem
|
|||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
return EntityWrapper::Invalid;
|
return EntityWrapper::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorSystem::setWidgetMode(EditorGUI::WidgetMode mode)
|
||||||
|
{
|
||||||
|
if (mode == m_WidgetMode && m_Widget.Valid() && m_CurrentSelection.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Widget.Valid()) {
|
||||||
|
m_Widget.World->DeleteEntity(m_Widget.ID);
|
||||||
|
m_Widget = EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_CurrentSelection.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case EditorGUI::WidgetMode::Translate:
|
||||||
|
m_Widget = importEntity(EntityWrapper(m_World, EntityID_Invalid), "Schema/Entities/EditorWidgetTranslate.xml");
|
||||||
|
break;
|
||||||
|
case EditorGUI::WidgetMode::Rotate:
|
||||||
|
m_Widget = importEntity(EntityWrapper(m_World, EntityID_Invalid), "Schema/Entities/EditorWidgetRotate.xml");
|
||||||
|
break;
|
||||||
|
case EditorGUI::WidgetMode::Scale:
|
||||||
|
m_Widget = importEntity(EntityWrapper(m_World, EntityID_Invalid), "Schema/Entities/EditorWidgetScale.xml");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
||||||
|
|
||||||
|
m_WidgetMode = mode;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user