Editor widget selection and creation
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "../GLM.h"
|
||||
#include <glm/gtx/common.hpp>
|
||||
|
||||
#include "EditorWidgetSystem.h"
|
||||
#include "../Core/EventBroker.h"
|
||||
#include "../Core/World.h"
|
||||
#include "../Core/EntityWrapper.h"
|
||||
@@ -22,6 +23,13 @@ class EditorGUI
|
||||
public:
|
||||
EditorGUI(World* world, EventBroker* eventBroker);
|
||||
|
||||
enum class WidgetMode
|
||||
{
|
||||
Translate,
|
||||
Rotate,
|
||||
Scale
|
||||
};
|
||||
|
||||
void Draw();
|
||||
|
||||
void SelectEntity(EntityWrapper entity);
|
||||
@@ -59,6 +67,9 @@ public:
|
||||
// Called when the user means to delete a component off an entity.
|
||||
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentDelete_t;
|
||||
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:
|
||||
World* m_World;
|
||||
@@ -72,6 +83,7 @@ private:
|
||||
std::unordered_map<EntityWrapper, boost::filesystem::path> m_EntityFiles;
|
||||
EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid;
|
||||
std::string m_LastErrorMessage;
|
||||
WidgetMode m_CurrentWidgetMode = WidgetMode::Translate;
|
||||
|
||||
// Callbacks
|
||||
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
||||
@@ -83,6 +95,7 @@ private:
|
||||
OnEntityChangeName_t m_OnEntityChangeName = nullptr;
|
||||
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
||||
OnComponentDelete_t m_OnComponentDelete = nullptr;
|
||||
OnWidgetMode_t m_OnWidgetMode = nullptr;
|
||||
|
||||
// Utility functions
|
||||
boost::filesystem::path fileOpenDialog();
|
||||
|
||||
@@ -26,14 +26,19 @@ 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;
|
||||
EditorStats* m_EditorStats;
|
||||
|
||||
// State
|
||||
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
|
||||
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
||||
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
||||
|
||||
// Utility functions
|
||||
EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath);
|
||||
void setWidgetMode(EditorGUI::WidgetMode mode);
|
||||
|
||||
// GUI callbacks
|
||||
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" ?>
|
||||
<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"/>
|
||||
</EditorWidget>
|
||||
@@ -7,10 +7,9 @@
|
||||
<xs:complexContent>
|
||||
<xs:extension base="t:enum">
|
||||
<xs:choice>
|
||||
<xs:element name="None" 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="2" minOccurs="0"/>
|
||||
<xs:element name="Scale" type="xs:integer" fixed="3" minOccurs="0"/>
|
||||
<xs:element name="Translate" type="xs:integer" fixed="0" minOccurs="0"/>
|
||||
<xs:element name="Rotate" type="xs:integer" fixed="1" minOccurs="0"/>
|
||||
<xs:element name="Scale" type="xs:integer" fixed="2" minOccurs="0"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
|
||||
@@ -36,13 +36,55 @@ void EditorGUI::drawTools()
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
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::ItemSize(ImVec2(5, 0));
|
||||
@@ -83,7 +125,7 @@ void EditorGUI::drawEntities(World* world)
|
||||
entityImport(world);
|
||||
}
|
||||
ImGui::SameLine(0.f, 5.f);
|
||||
ImGui::Button("Reference", ImVec2(buttonWidth, 0));
|
||||
ImGui::ButtonEx("Reference", ImVec2(buttonWidth, 0), ImGuiButtonFlags_Disabled);
|
||||
|
||||
// Naming
|
||||
char buffer[256];
|
||||
|
||||
@@ -12,9 +12,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
||||
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||
|
||||
m_Widget = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/EditorWidget.xml");
|
||||
|
||||
m_Camera = EntityWrapper(m_EditorWorld, m_EditorWorld->CreateEntity());
|
||||
m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
|
||||
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->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->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
|
||||
|
||||
m_EditorStats = new EditorStats();
|
||||
|
||||
@@ -60,7 +59,8 @@ void EditorSystem::Update(double dt)
|
||||
|
||||
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)
|
||||
@@ -118,4 +118,36 @@ EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem
|
||||
} catch (const std::exception&) {
|
||||
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