add basic core
This commit is contained in:
parent
5c4c23b971
commit
d1f132b07e
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/ResourceManager.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class Asset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool IsExtensionSupported(std::string_view ext) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TResourceManager>
|
||||||
|
class TAsset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool IsExtensionSupported(std::string_view ext) { return m_resourceManager. }
|
||||||
|
protected:
|
||||||
|
TResourceManager m_resourceManager;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARAEDITOR_CORE_CONFIG_HPP
|
||||||
|
#define NAZARAEDITOR_CORE_CONFIG_HPP
|
||||||
|
|
||||||
|
#if !defined(NAZARAEDITOR_STATIC)
|
||||||
|
#ifdef NAZARAEDITOR_CORE_BUILD
|
||||||
|
#define NAZARAEDITOR_CORE_API NAZARA_EXPORT
|
||||||
|
#else
|
||||||
|
#define NAZARAEDITOR_CORE_API NAZARA_IMPORT
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NAZARAEDITOR_CORE_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // NAZARAEDITOR_CORE_CONFIG_HPP
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Config.hpp>
|
||||||
|
|
||||||
|
#include <Nazara/Core/ModuleBase.hpp>
|
||||||
|
#include <NazaraImgui/NazaraImgui.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class NAZARAEDITOR_CORE_API EditorCore : public Nz::ModuleBase<EditorCore>
|
||||||
|
{
|
||||||
|
friend ModuleBase;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Dependencies = TypeList<Imgui>;
|
||||||
|
|
||||||
|
struct Config {};
|
||||||
|
|
||||||
|
EditorCore(Config config);
|
||||||
|
~EditorCore();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static EditorCore* s_instance;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Reflection/Reflection.hpp>
|
||||||
|
#include <NazaraEditor/Core/Reflection/Math.hpp>
|
||||||
|
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Utility.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
class TypeReflect<Color>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, Color& obj)
|
||||||
|
{
|
||||||
|
p.AddProperty(obj.r, "R", "Red (0-255)");
|
||||||
|
p.AddProperty(obj.g, "G", "Green (0-255)");
|
||||||
|
p.AddProperty(obj.b, "B", "Blue (0-255)");
|
||||||
|
p.AddProperty(obj.a, "A", "Alpha (0-255)");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace EditorImgui
|
||||||
|
{
|
||||||
|
inline bool Begin(Color& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
// your IMGUI Code
|
||||||
|
float values[] = { obj.r, obj.g, obj.b, obj.a };
|
||||||
|
if (ImGui::ColorEdit4(name.c_str(), values, ImGuiColorEditFlags_PickerHueWheel))
|
||||||
|
{
|
||||||
|
obj = Color(values[0], values[1], values[2], values[3]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(Color&) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper for array values
|
||||||
|
template <typename T>
|
||||||
|
struct ArrayEntry
|
||||||
|
{
|
||||||
|
T& value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TypeReflect<ArrayEntry<T>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, ArrayEntry<T>& obj)
|
||||||
|
{
|
||||||
|
p.AddProperty(p.value, "", "");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
class TypeReflect<std::array<T, Size>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, std::array<T, Size>& obj)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < Size; ++i)
|
||||||
|
{
|
||||||
|
p.AddProperty(ArrayEntry{ obj[i] }, "", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace EditorImgui
|
||||||
|
{
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
static bool Begin(ArrayEntry<T>& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
static void End(ArrayEntry<T>&) {
|
||||||
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
static bool Begin(std::array<T, Size>& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
return ImGui::TreeNode(name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t Size>
|
||||||
|
static void End(std::array<T, Size>&) {
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class TypeReflect<entt::handle>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, entt::handle& obj)
|
||||||
|
{
|
||||||
|
for (auto&& curr : obj.storage())
|
||||||
|
{
|
||||||
|
if (auto& storage = curr.second; storage.contains(obj))
|
||||||
|
{
|
||||||
|
entt::id_type id = curr.first;
|
||||||
|
if (auto reflect = entt::resolve(id).func(entt::hashed_string("Reflect")); reflect)
|
||||||
|
reflect.invoke({}, p, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace EditorImgui
|
||||||
|
{
|
||||||
|
static bool Begin(entt::handle& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
std::string n = "Entity " + name;
|
||||||
|
return ImGui::TreeNode(n.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void End(entt::handle&) {
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TPropertyEnumerator, typename TComponent>
|
||||||
|
inline void ReflectComponent(TPropertyEnumerator& p, entt::handle& obj)
|
||||||
|
{
|
||||||
|
TComponent* component = obj.try_get<TComponent>();
|
||||||
|
if (component != nullptr)
|
||||||
|
p.AddProperty(*component, "", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <typename TPropertyDetail>
|
||||||
|
struct EditorPropertyInspector
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
void AddProperty(T& prop, const std::string& name, const std::string& tooltip);
|
||||||
|
|
||||||
|
/*template <typename T, typename U, typename V>
|
||||||
|
void AddProperty(T& parent, V(U::* Getter)() const, void(U::*Setter(const V&))(), const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
U val = parent->Getter();
|
||||||
|
AddProperty(val, name, tooltip);
|
||||||
|
parent->Setter(val);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
template <typename TGetter, typename TSetter>
|
||||||
|
void AddProperty(TGetter Getter, TSetter Setter, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
auto val = Getter();
|
||||||
|
AddProperty(val, name, tooltip);
|
||||||
|
Setter(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EditorRenderer
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
static bool Begin(T& prop, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
return EditorImgui::Begin(prop, name, tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void End(T& prop)
|
||||||
|
{
|
||||||
|
EditorImgui::End(prop);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Reflection/Editor.inl>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename TPropertyDetail>
|
||||||
|
template <typename T> void EditorPropertyInspector<TPropertyDetail>::AddProperty(T& prop, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
if (TPropertyDetail::Begin(prop, name, tooltip))
|
||||||
|
{
|
||||||
|
TypeReflect<T>::Reflect(*this, prop);
|
||||||
|
TPropertyDetail::End(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Reflection/Reflection.hpp>
|
||||||
|
|
||||||
|
#include <Nazara/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
class TypeReflect<LightComponent::LightEntry>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, LightComponent::LightEntry& obj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class TypeReflect<LightComponent>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, LightComponent& obj)
|
||||||
|
{
|
||||||
|
p.AddProperty([&obj]() { return obj.IsVisible(); }, [&obj](bool v) { obj.Show(v); }, "Is Visible", "Toggles lights visibility");
|
||||||
|
//p.AddProperty(obj.GetLights(), "Lights", "");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace EditorImgui
|
||||||
|
{
|
||||||
|
inline bool Begin(Nz::LightComponent::LightEntry& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(Nz::LightComponent::LightEntry&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Begin(Nz::LightComponent& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
return ImGui::TreeNode("LightComponent");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(Nz::LightComponent&) {
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Reflection/Reflection.hpp>
|
||||||
|
#include <Nazara/Math.hpp>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
namespace EditorImgui
|
||||||
|
{
|
||||||
|
inline bool Begin(bool& obj, const std::string& name, const std::string& /*tooltip*/)
|
||||||
|
{
|
||||||
|
ImGui::Checkbox(name.c_str(), &obj);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(bool&) {}
|
||||||
|
|
||||||
|
#define IMGUI_BASIC_INTEGER(Type) \
|
||||||
|
inline bool Begin(Type& obj, const std::string& name, const std::string& /*tooltip*/) \
|
||||||
|
{ \
|
||||||
|
int value = static_cast<int>(obj); \
|
||||||
|
if (ImGui::DragInt(name.c_str(), &value, 1.f, std::numeric_limits<Type>::min(), std::numeric_limits<Type>::max())) \
|
||||||
|
obj = static_cast<Type>(value); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
inline void End(Type&) {}
|
||||||
|
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::Int8);
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::Int16)
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::Int32);
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::Int64);
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::UInt8);
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::UInt16);
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::UInt32);
|
||||||
|
IMGUI_BASIC_INTEGER(Nz::UInt64);
|
||||||
|
|
||||||
|
#define IMGUI_BASIC_FLOAT(Type) \
|
||||||
|
inline bool Begin(Type& obj, const std::string& name, const std::string& /*tooltip*/) \
|
||||||
|
{ \
|
||||||
|
float value = (float)obj; \
|
||||||
|
if (ImGui::DragFloat(name.c_str(), &value, 1.f, std::numeric_limits<Type>::min(), std::numeric_limits<Type>::max())) \
|
||||||
|
obj = (Type)value; \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
inline void End(Type&) {}
|
||||||
|
|
||||||
|
IMGUI_BASIC_FLOAT(float);
|
||||||
|
IMGUI_BASIC_FLOAT(double);
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Begin(Nz::Vector3f& obj, const std::string& name, const std::string& /*tooltip*/)
|
||||||
|
{
|
||||||
|
float value[] = { obj.x, obj.y, obj.z };
|
||||||
|
if (ImGui::DragFloat3(name.c_str(), value, 1.f, std::numeric_limits<float>::min(), std::numeric_limits<float>::max()))
|
||||||
|
obj = Nz::Vector3f(value[0], value[1], value[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(Nz::Vector3f&) {}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Begin(Nz::Quaternionf& obj, const std::string& name, const std::string& /*tooltip*/)
|
||||||
|
{
|
||||||
|
auto euler = obj.ToEulerAngles();
|
||||||
|
float value[] = { euler.pitch.ToDegrees(), euler.yaw.ToDegrees(), euler.roll.ToDegrees() };
|
||||||
|
if (ImGui::DragFloat3(name.c_str(), value, 1.f, std::numeric_limits<float>::min(), std::numeric_limits<float>::max()))
|
||||||
|
{
|
||||||
|
obj = EulerAnglesf(value[0], value[1], value[2]).ToQuaternion();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(Nz::Quaternionf&) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
class TypeReflect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TEnumerator>
|
||||||
|
static void Reflect(TEnumerator&, T&) { } // default specialization
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraEditor/Core/Reflection/Reflection.hpp>
|
||||||
|
|
||||||
|
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class TypeReflect<NodeComponent>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename TPropertyEnumerator>
|
||||||
|
static void Reflect(TPropertyEnumerator& p, NodeComponent& obj)
|
||||||
|
{
|
||||||
|
p.AddProperty([&obj]() { return obj.GetPosition(); }, [&obj](const Nz::Vector3f& v) { return obj.SetPosition(v); }, "Position", "Position of the node");
|
||||||
|
p.AddProperty([&obj]() { return obj.GetRotation(); }, [&obj](const Nz::Quaternionf& v) { return obj.SetRotation(v); }, "Rotation", "Rotation of the node");
|
||||||
|
p.AddProperty([&obj]() { return obj.GetScale(); }, [&obj](const Nz::Vector3f& v) { return obj.SetScale(v); }, "Scale", "Scale of the node");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace EditorImgui
|
||||||
|
{
|
||||||
|
inline bool Begin(Nz::NodeComponent& obj, const std::string& name, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
return ImGui::TreeNode("NodeComponent");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void End(Nz::NodeComponent&) {
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <NazaraUtils/Prerequisites.hpp>
|
||||||
|
#include <NazaraEditor/Core/Config.hpp>
|
||||||
|
#include <NazaraImgui/NazaraImgui.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
using ActionCallback = std::function<void(void)>;
|
||||||
|
|
||||||
|
class NAZARAEDITOR_CORE_API EditorWindow
|
||||||
|
: private Nz::ImguiHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorWindow(const std::string& name = "");
|
||||||
|
~EditorWindow();
|
||||||
|
|
||||||
|
EditorWindow(const EditorWindow&) = delete;
|
||||||
|
EditorWindow& operator=(const EditorWindow&) = delete;
|
||||||
|
|
||||||
|
virtual void OnRenderImgui() override;
|
||||||
|
|
||||||
|
void AddMenuAction(const std::string& path, const std::string& shortcut, ActionCallback callback);
|
||||||
|
void AddMenuSeparator(const std::string& path);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnEditorGUI() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawMenus();
|
||||||
|
|
||||||
|
std::string m_windowName;
|
||||||
|
|
||||||
|
struct MenuAction
|
||||||
|
{
|
||||||
|
std::string label;
|
||||||
|
std::string shortcut;
|
||||||
|
ActionCallback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MenuSeparator
|
||||||
|
{};
|
||||||
|
|
||||||
|
struct MenuList
|
||||||
|
{
|
||||||
|
std::string label;
|
||||||
|
std::vector<std::variant<MenuAction, MenuSeparator, MenuList>> entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
MenuList m_root;
|
||||||
|
|
||||||
|
MenuList& GetOrCreateMenuHierarchy(const std::vector<std::string_view>& hierarchy);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <NazaraEditor/Core/Core.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorCore* EditorCore::s_instance = nullptr;
|
||||||
|
|
||||||
|
EditorCore::EditorCore(Config /*config*/)
|
||||||
|
: ModuleBase("EditorCore", this)
|
||||||
|
{
|
||||||
|
ImGui::EnsureContextOnThisThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorCore::~EditorCore() {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
#include <NazaraEditor/Core/UI/Window.hpp>
|
||||||
|
|
||||||
|
#include <Nazara/Core/StringExt.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
EditorWindow::EditorWindow(const std::string& name)
|
||||||
|
: m_windowName(name)
|
||||||
|
{
|
||||||
|
Nz::Imgui::Instance()->AddHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorWindow::~EditorWindow()
|
||||||
|
{
|
||||||
|
Nz::Imgui::Instance()->RemoveHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorWindow::OnRenderImgui()
|
||||||
|
{
|
||||||
|
bool bNeedsMenu = !m_root.entries.empty();
|
||||||
|
ImGuiWindowFlags flags = (bNeedsMenu ? ImGuiWindowFlags_MenuBar : 0);
|
||||||
|
|
||||||
|
if (ImGui::Begin(m_windowName.c_str(), nullptr, flags))
|
||||||
|
{
|
||||||
|
DrawMenus();
|
||||||
|
|
||||||
|
OnEditorGUI();
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorWindow::AddMenuAction(const std::string& path, const std::string& shortcut, ActionCallback callback)
|
||||||
|
{
|
||||||
|
std::vector<std::string_view> v;
|
||||||
|
Nz::SplitString(path, "|", [&](std::string_view str) { v.push_back(str); return true; });
|
||||||
|
|
||||||
|
std::string leaf = std::string(v.back());
|
||||||
|
|
||||||
|
v.pop_back(); // remove action name from hierarchy
|
||||||
|
|
||||||
|
MenuList& parent = GetOrCreateMenuHierarchy(v);
|
||||||
|
|
||||||
|
parent.entries.push_back(MenuAction{ leaf, shortcut, callback});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorWindow::AddMenuSeparator(const std::string& path)
|
||||||
|
{
|
||||||
|
std::vector<std::string_view> v;
|
||||||
|
Nz::SplitString(path, "|", [&](std::string_view str) { v.push_back(str); return true; });
|
||||||
|
MenuList& parent = GetOrCreateMenuHierarchy(v);
|
||||||
|
parent.entries.push_back(MenuSeparator{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorWindow::DrawMenus()
|
||||||
|
{
|
||||||
|
if (m_root.entries.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::function<void(const std::variant<MenuAction, MenuSeparator, MenuList>&)> visitor;
|
||||||
|
|
||||||
|
visitor = [&visitor](auto& menu) {
|
||||||
|
std::visit(Overloaded{
|
||||||
|
[&visitor](const MenuList& arg) {
|
||||||
|
if (ImGui::BeginMenu(arg.label.c_str()))
|
||||||
|
{
|
||||||
|
for (auto& child : arg.entries)
|
||||||
|
visitor(child);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[](const MenuSeparator&) {
|
||||||
|
ImGui::Separator();
|
||||||
|
},
|
||||||
|
[](const MenuAction& arg) {
|
||||||
|
if (ImGui::MenuItem(arg.label.c_str(), arg.shortcut.c_str()))
|
||||||
|
arg.callback();
|
||||||
|
},
|
||||||
|
}, menu);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
for (auto& menu : m_root.entries)
|
||||||
|
visitor(menu);
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorWindow::MenuList& EditorWindow::GetOrCreateMenuHierarchy(const std::vector<std::string_view>& hierarchy)
|
||||||
|
{
|
||||||
|
auto getOrCreate_submenu = [](MenuList* menu, std::string_view v) -> MenuList*
|
||||||
|
{
|
||||||
|
for (auto& e : menu->entries)
|
||||||
|
{
|
||||||
|
MenuList* ptr = nullptr;
|
||||||
|
std::visit(Overloaded{
|
||||||
|
[&ptr, v](MenuList& arg) {
|
||||||
|
if (arg.label == v)
|
||||||
|
ptr = &arg;
|
||||||
|
},
|
||||||
|
[](MenuSeparator&) { },
|
||||||
|
[](MenuAction&) { },
|
||||||
|
}, e);
|
||||||
|
if (nullptr != ptr)
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu->entries.push_back(MenuList{ std::string(v) });
|
||||||
|
return &std::get<MenuList>(menu->entries.back());
|
||||||
|
};
|
||||||
|
|
||||||
|
MenuList* currentMenu = &m_root;
|
||||||
|
for (auto& entry : hierarchy)
|
||||||
|
currentMenu = getOrCreate_submenu(currentMenu, entry);
|
||||||
|
|
||||||
|
return *currentMenu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
set_project("NazaraEditor")
|
||||||
|
|
||||||
|
add_rules("mode.asan", "mode.tsan", "mode.coverage", "mode.debug", "mode.releasedbg", "mode.release")
|
||||||
|
add_rules("plugin.vsxmake.autoupdate")
|
||||||
|
|
||||||
|
includes("xmake/**.lua")
|
||||||
|
|
||||||
|
add_repositories("nazara-engine-repo https://github.com/NazaraEngine/xmake-repo")
|
||||||
|
add_repositories("nazara-imgui-repo https://github.com/SweetId/NazaraImgui-xmake-repo")
|
||||||
|
add_requires("nazaraengine", { alias = "nazara", debug = is_mode("debug") })
|
||||||
|
add_requires("nazaraimgui", { alias = "nzimgui", debug = is_mode("debug") })
|
||||||
|
|
||||||
|
add_includedirs("include", "src")
|
||||||
|
set_languages("c89", "c++17")
|
||||||
|
set_rundir("./bin/$(plat)_$(arch)_$(mode)")
|
||||||
|
set_targetdir("./bin/$(plat)_$(arch)_$(mode)")
|
||||||
|
|
||||||
|
if has_config("erronwarn") then
|
||||||
|
set_warnings("allextra", "error")
|
||||||
|
else
|
||||||
|
set_warnings("allextra")
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_plat("mingw", "linux") then
|
||||||
|
add_cxflags("-Wno-subobject-linkage")
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_plat("windows") then
|
||||||
|
add_defines("_CRT_SECURE_NO_WARNINGS")
|
||||||
|
add_cxxflags("/bigobj", "/permissive-", "/Zc:__cplusplus", "/Zc:externConstexpr", "/Zc:inline", "/Zc:lambda", "/Zc:preprocessor", "/Zc:referenceBinding", "/Zc:strictStrings", "/Zc:throwingNew")
|
||||||
|
add_cxflags("/w44062") -- Enable warning: switch case not handled
|
||||||
|
add_cxflags("/wd4251") -- Disable warning: class needs to have dll-interface to be used by clients of class blah blah blah
|
||||||
|
add_cxflags("/wd4275") -- Disable warning: DLL-interface class 'class_1' used as base for DLL-interface blah
|
||||||
|
elseif is_plat("mingw") then
|
||||||
|
add_cxflags("-Og", "-Wa,-mbig-obj")
|
||||||
|
add_ldflags("-Wa,-mbig-obj")
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_mode("debug") then
|
||||||
|
set_runtimes("MDd")
|
||||||
|
elseif is_mode("asan", "tsan", "ubsan") then
|
||||||
|
set_optimize("none") -- by default xmake will optimize asan builds
|
||||||
|
elseif is_mode("coverage") then
|
||||||
|
if not is_plat("windows") then
|
||||||
|
add_links("gcov")
|
||||||
|
end
|
||||||
|
elseif is_mode("releasedbg") then
|
||||||
|
set_runtimes("MD")
|
||||||
|
set_fpmodels("fast")
|
||||||
|
add_vectorexts("sse", "sse2", "sse3", "ssse3")
|
||||||
|
end
|
||||||
|
|
||||||
|
local modules = {
|
||||||
|
Core = {
|
||||||
|
Packages = { "nazara", "nzimgui" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ModuleTargetConfig(name, module)
|
||||||
|
add_defines("NAZARAEDITOR_" .. name:upper() .. "_BUILD")
|
||||||
|
if is_mode("debug") then
|
||||||
|
add_defines("NAZARAEDITOR_" .. name:upper() .. "_DEBUG")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add header and source files
|
||||||
|
local headerExts = {".h", ".hpp", ".inl", ".natvis"}
|
||||||
|
for _, ext in ipairs(headerExts) do
|
||||||
|
add_headerfiles("include/(NazaraEditor/" .. name .. "/**" .. ext .. ")")
|
||||||
|
add_headerfiles("src/NazaraEditor/" .. name .. "/**" .. ext, { prefixdir = "private", install = false })
|
||||||
|
add_headerfiles("src/NazaraEditor/" .. name .. "/Resources/**.nzsl", { prefixdir = "private", install = false })
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_headerfiles("src/NazaraEditor/" .. name .. "/Resources/**.h")
|
||||||
|
|
||||||
|
add_files("src/NazaraEditor/" .. name .. "/**.cpp")
|
||||||
|
if has_config("embed_resources") then
|
||||||
|
local embedResourceRule = false
|
||||||
|
for _, filepath in pairs(os.files("src/NazaraEditor/" .. name .. "/Resources/**|**.h|**.nzsl|**.nzslb")) do
|
||||||
|
if not embedResourceRule then
|
||||||
|
add_rules("embed.resources")
|
||||||
|
embedResourceRule = true
|
||||||
|
end
|
||||||
|
|
||||||
|
add_files(filepath, {rule = "embed.resources"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if has_config("compile_shaders") then
|
||||||
|
local compileShaderRule = false
|
||||||
|
for _, filepath in pairs(os.files("src/NazaraEditor/" .. name .. "/Resources/**.nzsl")) do
|
||||||
|
if not compileShaderRule then
|
||||||
|
add_rules("nzsl.compile.shaders")
|
||||||
|
compileShaderRule = true
|
||||||
|
end
|
||||||
|
|
||||||
|
add_files(filepath, {rule = "nzsl.compile.shaders"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remove platform-specific files
|
||||||
|
if not is_plat("windows", "mingw") then
|
||||||
|
remove_headerfiles("src/NazaraEditor/" .. name .. "/Win32/**")
|
||||||
|
remove_files("src/NazaraEditor/" .. name .. "/Win32/**")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not is_plat("linux", "android", "cross") then
|
||||||
|
remove_headerfiles("src/NazaraEditor/" .. name .. "/Linux/**")
|
||||||
|
remove_files("src/NazaraEditor/" .. name .. "/Linux/**")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not is_plat("macosx", "iphoneos") then
|
||||||
|
remove_headerfiles("src/NazaraEditor/" .. name .. "/Darwin/**")
|
||||||
|
remove_files("src/NazaraEditor/" .. name .. "/Darwin/**")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not is_plat("linux", "macosx", "iphoneos", "android", "wasm", "cross") then
|
||||||
|
remove_headerfiles("src/NazaraEditor/" .. name .. "/Posix/**")
|
||||||
|
remove_files("src/NazaraEditor/" .. name .. "/Posix/**")
|
||||||
|
end
|
||||||
|
|
||||||
|
if module.Custom then
|
||||||
|
module.Custom()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for name, module in pairs(modules) do
|
||||||
|
if module.Option and not has_config(module.Option) then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
target("NazaraEditor-" .. name, function ()
|
||||||
|
set_group("Modules")
|
||||||
|
|
||||||
|
-- for now only shared compilation is supported (except on platforms like wasm)
|
||||||
|
if not is_plat("wasm") then
|
||||||
|
set_kind("shared")
|
||||||
|
else
|
||||||
|
set_kind("static")
|
||||||
|
add_defines("NAZARAEDITOR_STATIC", { public = true })
|
||||||
|
end
|
||||||
|
|
||||||
|
add_rpathdirs("$ORIGIN")
|
||||||
|
|
||||||
|
if module.Deps then
|
||||||
|
add_deps(table.unpack(module.Deps))
|
||||||
|
end
|
||||||
|
|
||||||
|
if module.Packages then
|
||||||
|
add_packages(table.unpack(module.Packages))
|
||||||
|
end
|
||||||
|
|
||||||
|
if module.PublicPackages then
|
||||||
|
for _, pkg in ipairs(module.PublicPackages) do
|
||||||
|
add_packages(pkg, { public = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if has_config("usepch") then
|
||||||
|
set_pcxxheader("include/NazaraEditor/" .. name .. ".hpp")
|
||||||
|
end
|
||||||
|
|
||||||
|
if has_config("unitybuild") then
|
||||||
|
add_rules("c++.unity_build", {uniqueid = "NAZARA_UNITY_ID", batchsize = 12})
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_plat("windows", "mingw") then
|
||||||
|
add_defines("NAZARA_UTILS_WINDOWS_NT6=1")
|
||||||
|
end
|
||||||
|
|
||||||
|
add_includedirs("src")
|
||||||
|
|
||||||
|
ModuleTargetConfig(name, module)
|
||||||
|
end)
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
||||||
|
target("NazaraEditor")
|
||||||
|
set_group("Applications")
|
||||||
|
add_headerfiles("include/NazaraEditor/Editor/**.h")
|
||||||
|
add_headerfiles("include/NazaraEditor/Editor/**.hpp")
|
||||||
|
add_headerfiles("include/NazaraEditor/Editor/**.inl")
|
||||||
|
add_files("src/NazaraEditor/Editor/**.cpp")
|
||||||
|
|
||||||
|
for name, module in pairs(modules) do
|
||||||
|
add_deps("NazaraEditor-" .. name)
|
||||||
|
end
|
||||||
|
add_packages("nazara", "nzimgui")
|
||||||
|
set_rundir(".")
|
||||||
Loading…
Reference in New Issue