add basic editor
This commit is contained in:
parent
d1f132b07e
commit
a30e94dee9
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Core.hpp>
|
||||||
|
#include <NazaraEditor/Core/UI/Window.hpp>
|
||||||
|
#include <NazaraEditor/Core/Reflection/Math.hpp>
|
||||||
|
#include <NazaraEditor/Core/Reflection/Core.hpp>
|
||||||
|
#include <NazaraEditor/Core/Reflection/Utility.hpp>
|
||||||
|
#include <NazaraEditor/Core/Reflection/Graphics.hpp>
|
||||||
|
#include <NazaraEditor/Core/Reflection/Editor.hpp>
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Graphics.hpp>
|
||||||
|
#include <Nazara/Platform.hpp>
|
||||||
|
#include <Nazara/Renderer.hpp>
|
||||||
|
#include <Nazara/Utility.hpp>
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core.hpp>
|
||||||
|
#include <NazaraImgui/NazaraImgui.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class EditorApplication
|
||||||
|
: public Nz::Application<Nz::Graphics, Nz::Imgui, Nz::EditorCore>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NazaraSignal(OnWorldChanged, Nz::EnttWorld*);
|
||||||
|
|
||||||
|
// Entity lifetime events
|
||||||
|
NazaraSignal(OnEntityCreated, entt::handle);
|
||||||
|
NazaraSignal(OnEntityDestroyed, entt::handle);
|
||||||
|
NazaraSignal(OnEntityParentChanged, entt::handle);
|
||||||
|
|
||||||
|
// Entity selection events
|
||||||
|
NazaraSignal(OnEntitySelected, entt::handle);
|
||||||
|
NazaraSignal(OnEntityDeselected, entt::handle);
|
||||||
|
|
||||||
|
static EditorApplication& Instance();
|
||||||
|
|
||||||
|
void NewWorld();
|
||||||
|
Nz::EnttWorld* GetCurrentWorld();
|
||||||
|
|
||||||
|
entt::handle CreateEntity();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void RegisterWindow()
|
||||||
|
{
|
||||||
|
static_assert(std::is_base_of<Nz::EditorWindow, T>::value, "Register Window should be called with a subclass of Nz::EditorWindow");
|
||||||
|
m_windows.push_back(std::make_unique<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EditorApplication();
|
||||||
|
|
||||||
|
std::unique_ptr<Nz::WindowSwapchain> m_windowSwapchain;
|
||||||
|
Nz::EnttWorld* m_world;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Nz::EditorWindow>> m_windows;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <NazaraEditor/Core/UI/Window.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class EditorAssetsWindow
|
||||||
|
: public Nz::EditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorAssetsWindow();
|
||||||
|
|
||||||
|
void ImportAsset();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void BuildMenuBar();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <NazaraEditor/Core/UI/Window.hpp>
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class EditorInspectorWindow
|
||||||
|
: public Nz::EditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorInspectorWindow();
|
||||||
|
|
||||||
|
virtual void OnEditorGUI() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnEntitySelected(entt::handle entity);
|
||||||
|
void OnEntityDeselected(entt::handle);
|
||||||
|
|
||||||
|
entt::handle m_currentEntity;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <NazaraEditor/Core/UI/Window.hpp>
|
||||||
|
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Utility.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class EditorLevelWindow
|
||||||
|
: public Nz::EditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorLevelWindow();
|
||||||
|
|
||||||
|
virtual void OnEditorGUI() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RefreshEntities();
|
||||||
|
|
||||||
|
Nz::EnttWorld* m_currentWorld;
|
||||||
|
bool m_dirty;
|
||||||
|
|
||||||
|
std::vector<Nz::Node*> m_rootNodes;
|
||||||
|
std::map<Nz::Node*, entt::handle> m_nodeToEntity;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <NazaraEditor/Core/UI/Window.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class EditorMainWindow
|
||||||
|
: public Nz::EditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorMainWindow();
|
||||||
|
|
||||||
|
bool Quit();
|
||||||
|
|
||||||
|
bool NewLevel();
|
||||||
|
bool OpenLevel();
|
||||||
|
bool SaveLevel();
|
||||||
|
|
||||||
|
bool NewProject();
|
||||||
|
bool OpenProject();
|
||||||
|
bool SaveProject();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void BuildMenuBar();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
#include <NazaraEditor/Editor/Application.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorApplication::EditorApplication()
|
||||||
|
: m_world(nullptr)
|
||||||
|
{
|
||||||
|
auto& windowing = AddComponent<Nz::AppWindowingComponent>();
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::RenderDevice> device = Nz::Graphics::Instance()->GetRenderDevice();
|
||||||
|
|
||||||
|
std::string windowTitle = "Nazara Editor";
|
||||||
|
Nz::Window& window = windowing.CreateWindow(Nz::VideoMode(1280, 720, 32), windowTitle);
|
||||||
|
m_windowSwapchain = std::make_unique<Nz::WindowSwapchain>(device, window);
|
||||||
|
|
||||||
|
// connect basic handler
|
||||||
|
window.GetEventHandler().OnQuit.Connect([&window](const auto* handler) {
|
||||||
|
NazaraUnused(handler);
|
||||||
|
window.Close();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddComponent<Nz::AppEntitySystemComponent>();
|
||||||
|
|
||||||
|
Nz::Imgui::Instance()->Init(window);
|
||||||
|
ImGui::EnsureContextOnThisThread();
|
||||||
|
|
||||||
|
NewWorld();
|
||||||
|
|
||||||
|
AddUpdaterFunc(Interval{ Nz::Time::Milliseconds(16) }, [&](Nz::Time elapsed) {
|
||||||
|
if (!window.IsOpen())
|
||||||
|
return;
|
||||||
|
|
||||||
|
window.ProcessEvents();
|
||||||
|
|
||||||
|
Nz::RenderFrame frame = m_windowSwapchain->AcquireFrame();
|
||||||
|
if (!frame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Nz::Imgui::Instance()->Update(window, elapsed.AsSeconds());
|
||||||
|
|
||||||
|
Nz::Imgui::Instance()->Render(m_windowSwapchain.get(), frame);
|
||||||
|
|
||||||
|
frame.Present();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorApplication& EditorApplication::Instance()
|
||||||
|
{
|
||||||
|
static EditorApplication e;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::EnttWorld* EditorApplication::GetCurrentWorld()
|
||||||
|
{
|
||||||
|
return m_world;
|
||||||
|
}
|
||||||
|
|
||||||
|
entt::handle EditorApplication::CreateEntity()
|
||||||
|
{
|
||||||
|
if (m_world == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
entt::handle entity = m_world->CreateEntity();
|
||||||
|
entity.emplace<Nz::NodeComponent>();
|
||||||
|
|
||||||
|
OnEntityCreated(entity);
|
||||||
|
OnEntitySelected(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorApplication::NewWorld()
|
||||||
|
{
|
||||||
|
auto& ecs = GetComponent<Nz::AppEntitySystemComponent>();
|
||||||
|
m_world = &ecs.AddWorld<Nz::EnttWorld>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <NazaraEditor/Editor/UI/AssetsWindow.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorAssetsWindow::EditorAssetsWindow()
|
||||||
|
: Nz::EditorWindow("Assets Browser")
|
||||||
|
{
|
||||||
|
BuildMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorAssetsWindow::ImportAsset()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorAssetsWindow::BuildMenuBar()
|
||||||
|
{
|
||||||
|
AddMenuAction("Import", "Ctrl+I", [this]() { ImportAsset(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <NazaraEditor/Editor/UI/InspectorWindow.hpp>
|
||||||
|
|
||||||
|
#include <NazaraEditor/Editor/Application.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorInspectorWindow::EditorInspectorWindow()
|
||||||
|
: Nz::EditorWindow("Inspector")
|
||||||
|
{
|
||||||
|
EditorApplication::Instance().OnEntitySelected.Connect(this, &EditorInspectorWindow::OnEntitySelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorInspectorWindow::OnEditorGUI()
|
||||||
|
{
|
||||||
|
if (!m_currentEntity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Nz::EditorPropertyInspector<Nz::EditorRenderer> enumerator;
|
||||||
|
enumerator.AddProperty(m_currentEntity, "", "");
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorInspectorWindow::OnEntitySelected(entt::handle entity)
|
||||||
|
{
|
||||||
|
m_currentEntity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorInspectorWindow::OnEntityDeselected(entt::handle)
|
||||||
|
{
|
||||||
|
m_currentEntity = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include <NazaraEditor/Editor/UI/LevelWindow.hpp>
|
||||||
|
|
||||||
|
#include <NazaraEditor/Editor/Application.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorLevelWindow::EditorLevelWindow()
|
||||||
|
: Nz::EditorWindow("Level")
|
||||||
|
, m_currentWorld(EditorApplication::Instance().GetCurrentWorld())
|
||||||
|
, m_dirty(true)
|
||||||
|
{
|
||||||
|
EditorApplication::Instance().OnWorldChanged.Connect([this](Nz::EnttWorld* world) { m_currentWorld = world; m_dirty = true; });
|
||||||
|
EditorApplication::Instance().OnEntityCreated.Connect([this](entt::handle) { m_dirty = true; });
|
||||||
|
EditorApplication::Instance().OnEntityDestroyed.Connect([this](entt::handle) { m_dirty = true; });
|
||||||
|
EditorApplication::Instance().OnEntityParentChanged.Connect([this](entt::handle) { m_dirty = true; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorLevelWindow::OnEditorGUI()
|
||||||
|
{
|
||||||
|
RefreshEntities();
|
||||||
|
|
||||||
|
std::function<void(Nz::Node*)> drawHierarchy = [&](Nz::Node* c)
|
||||||
|
{
|
||||||
|
entt::handle entity = m_nodeToEntity[c];
|
||||||
|
Nz::EditorImgui::Begin(entity, "", "");
|
||||||
|
for (auto& child : c->GetChilds())
|
||||||
|
drawHierarchy(child);
|
||||||
|
Nz::EditorImgui::End(entity);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& node : m_rootNodes)
|
||||||
|
drawHierarchy(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorLevelWindow::RefreshEntities()
|
||||||
|
{
|
||||||
|
if (!m_dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_dirty = false;
|
||||||
|
m_rootNodes.clear();
|
||||||
|
m_nodeToEntity.clear();
|
||||||
|
|
||||||
|
if (m_currentWorld == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_currentWorld->GetRegistry().each([&](const entt::entity entity) {
|
||||||
|
entt::handle handle(m_currentWorld->GetRegistry(), entity);
|
||||||
|
Nz::NodeComponent* component = handle.try_get<Nz::NodeComponent>();
|
||||||
|
if (component != nullptr)
|
||||||
|
{
|
||||||
|
m_nodeToEntity[component] = handle;
|
||||||
|
if (component->GetParent() == nullptr)
|
||||||
|
m_rootNodes.push_back(component);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include <NazaraEditor/Editor/UI/MainWindow.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorMainWindow::EditorMainWindow()
|
||||||
|
: Nz::EditorWindow("MainWindow")
|
||||||
|
{
|
||||||
|
BuildMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorMainWindow::BuildMenuBar()
|
||||||
|
{
|
||||||
|
AddMenuAction("File|Project|New", "Ctrl+Shift+N", [this]() { NewProject(); });
|
||||||
|
AddMenuAction("File|Project|Open", "Ctrl+Shift+O", [this]() { OpenProject(); });
|
||||||
|
AddMenuAction("File|Project|Save", "Ctrl+Shift+S", [this]() { SaveProject(); });
|
||||||
|
AddMenuAction("File|Level|New", "Ctrl+N", [this]() { NewLevel(); });
|
||||||
|
AddMenuAction("File|Level|Open", "Ctrl+O", [this]() { OpenLevel(); });
|
||||||
|
AddMenuAction("File|Level|Save", "Ctrl+S", [this]() { SaveLevel(); });
|
||||||
|
AddMenuSeparator("File");
|
||||||
|
AddMenuAction("File|Quit", "Ctrl+W", [this]() { Quit(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorMainWindow::OnEditorGUI()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::Quit()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::NewLevel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::OpenLevel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::SaveLevel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::NewProject()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::OpenProject()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorMainWindow::SaveProject()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Graphics.hpp>
|
||||||
|
#include <Nazara/Platform.hpp>
|
||||||
|
#include <Nazara/Renderer.hpp>
|
||||||
|
#include <Nazara/Utility.hpp>
|
||||||
|
|
||||||
|
#include <NazaraImgui/NazaraImgui.hpp>
|
||||||
|
#include <NazaraEditor/Core.hpp>
|
||||||
|
|
||||||
|
#include <NazaraEditor/Editor/Application.hpp>
|
||||||
|
#include <NazaraEditor/Editor/UI/AssetsWindow.hpp>
|
||||||
|
#include <NazaraEditor/Editor/UI/InspectorWindow.hpp>
|
||||||
|
#include <NazaraEditor/Editor/UI/LevelWindow.hpp>
|
||||||
|
#include <NazaraEditor/Editor/UI/MainWindow.hpp>
|
||||||
|
|
||||||
|
NAZARA_REQUEST_DEDICATED_GPU()
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
#else
|
||||||
|
int WinMain(int argc, char* argv[])
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
NazaraUnused(argc);
|
||||||
|
NazaraUnused(argv);
|
||||||
|
|
||||||
|
Nz::EditorApplication& app = Nz::EditorApplication::Instance();
|
||||||
|
app.RegisterWindow<Nz::EditorMainWindow>();
|
||||||
|
app.RegisterWindow<Nz::EditorAssetsWindow>();
|
||||||
|
app.RegisterWindow<Nz::EditorLevelWindow>();
|
||||||
|
app.RegisterWindow<Nz::EditorInspectorWindow>();
|
||||||
|
|
||||||
|
entt::meta<Nz::NodeComponent>()
|
||||||
|
.type(entt::type_hash<Nz::NodeComponent>::value())
|
||||||
|
.func<&Nz::ReflectComponent<Nz::EditorPropertyInspector<Nz::EditorRenderer>, Nz::NodeComponent>>(entt::hashed_string("Reflect"));
|
||||||
|
entt::meta<Nz::LightComponent>()
|
||||||
|
.type(entt::type_hash<Nz::LightComponent>::value())
|
||||||
|
.func<&Nz::ReflectComponent<Nz::EditorPropertyInspector<Nz::EditorRenderer>, Nz::LightComponent>>(entt::hashed_string("Reflect"));
|
||||||
|
|
||||||
|
entt::handle entity = app.CreateEntity();
|
||||||
|
|
||||||
|
return app.Run();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue