Merge pull request #134 from SHADE-DP/SP3-4-Editor
asset browser added asset browser shortcuts for copy/paste and select all fix checkbox bug fix entity parenting bug
This commit is contained in:
commit
18093433fa
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//#define SHEDITOR
|
//#define SHEDITOR
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
//#include "Scenes/SBEditorScene.h"
|
//#include "Scenes/SBEditorScene.h"
|
||||||
#endif // SHEDITOR
|
#endif // SHEDITOR
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
|
//SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
|
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
|
|
@ -8,7 +8,7 @@ project "SHADE_Engine"
|
||||||
pchheader "SHpch.h"
|
pchheader "SHpch.h"
|
||||||
pchsource "%{prj.location}/src/SHpch.cpp"
|
pchsource "%{prj.location}/src/SHpch.cpp"
|
||||||
staticruntime "off"
|
staticruntime "off"
|
||||||
|
buildoptions{"/bigobj"}
|
||||||
files
|
files
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/**.h",
|
"%{prj.location}/src/**.h",
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
//TODO: Convert to RTTR?
|
//TODO: Convert to RTTR?
|
||||||
constexpr auto DRAG_EID = "DragEID";
|
|
||||||
constexpr auto DRAG_RESOURCE = "DragResource";
|
|
||||||
|
|
||||||
|
|
||||||
struct SHDragDrop
|
struct SHDragDrop
|
||||||
{
|
{
|
||||||
|
using DragDropTag = std::string_view;
|
||||||
|
static constexpr DragDropTag DRAG_EID = "DragEID";
|
||||||
|
static constexpr DragDropTag DRAG_RESOURCE = "DragResource";
|
||||||
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
||||||
/**
|
/**
|
||||||
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Editor/IconsFontAwesome6.h"
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAssetBrowser::SHAssetBrowser()
|
SHAssetBrowser::SHAssetBrowser()
|
||||||
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar)
|
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,62 +25,140 @@ namespace SHADE
|
||||||
void SHAssetBrowser::Update()
|
void SHAssetBrowser::Update()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
if(Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
|
RecursivelyDrawTree(rootFolder);
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
auto const& assets = SHAssetManager::GetAllAssets();
|
DrawCurrentFolder();
|
||||||
if(ImGui::BeginTable("AssetBrowserTable", 3))
|
|
||||||
{
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableHeader("Asset ID");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableHeader("Name");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableHeader("Type");
|
|
||||||
for(SHAsset const& asset : assets)
|
|
||||||
{
|
|
||||||
DrawAsset(asset);
|
|
||||||
}
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetBrowser::DrawMenuBar()
|
void SHAssetBrowser::DrawMenuBar()
|
||||||
{
|
{
|
||||||
if(ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetBrowser::DrawAsset(SHAsset const& asset)
|
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
|
||||||
{
|
{
|
||||||
ImGui::PushID(asset.id);
|
auto const& subFolders = folder->subFolders;
|
||||||
ImGui::BeginGroup();
|
auto const& files = folder->files;
|
||||||
|
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
|
||||||
ImGui::TableNextColumn();
|
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
|
||||||
ImGui::Selectable(std::format("{}", asset.id).data(), false, ImGuiSelectableFlags_SpanAllColumns);
|
if (isSelected)
|
||||||
if(SHDragDrop::BeginSource())
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
if (folder == rootFolder)
|
||||||
|
flags |= ImGuiTreeNodeFlags_DefaultOpen;
|
||||||
|
|
||||||
|
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
|
||||||
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
if(ImGui::IsItemClicked())
|
||||||
{
|
{
|
||||||
auto id = asset.id;
|
selectedFolders.clear();
|
||||||
ImGui::Text("Moving Asset: %zu", id);
|
selectedFolders.push_back(folder);
|
||||||
SHDragDrop::SetPayload<AssetID>(DRAG_RESOURCE, &id);
|
}
|
||||||
SHDragDrop::EndSource();
|
if (isOpen)
|
||||||
|
{
|
||||||
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
const float horizontalOffset = 0.0f;
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||||
|
vertLineStart.x += horizontalOffset;
|
||||||
|
ImVec2 vertLineEnd = vertLineStart;
|
||||||
|
for (auto const& subFolder : subFolders)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 8.0f;
|
||||||
|
const ImRect childRect = RecursivelyDrawTree(subFolder);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
for (auto const& file : files)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 25.0f;
|
||||||
|
const ImRect childRect = DrawFile(file);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
return nodeRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetBrowser::DrawCurrentFolder()
|
||||||
|
{
|
||||||
|
//auto const& subFolders = currentFolder->subFolders;
|
||||||
|
//ImVec2 initialCursorPos = ImGui::GetCursorPos();
|
||||||
|
//ImVec2 initialRegionAvail = ImGui::GetContentRegionAvail();
|
||||||
|
//int maxTiles = initialRegionAvail.x / tileWidth;
|
||||||
|
//float maxX = (maxTiles - 1)*tileWidth;
|
||||||
|
//ImVec2 tilePos = initialCursorPos;
|
||||||
|
//for (auto const& subFolder : subFolders)
|
||||||
|
//{
|
||||||
|
// ImGui::SetCursorPos(tilePos);
|
||||||
|
// ImGui::BeginGroup();
|
||||||
|
// ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, {0.0f, 0.0f});
|
||||||
|
// ImGui::Button(ICON_MD_FOLDER, {tileWidth});
|
||||||
|
// ImGui::Text(subFolder->name.data());
|
||||||
|
// ImGui::PopStyleVar();
|
||||||
|
// ImGui::EndGroup();
|
||||||
|
// if(tilePos.x >= maxX)
|
||||||
|
// {
|
||||||
|
// tilePos.x = initialCursorPos.x;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// ImGui::SameLine();
|
||||||
|
// tilePos.x += tileWidth;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImRect SHAssetBrowser::DrawFile(SHFile const& file) noexcept
|
||||||
|
{
|
||||||
|
if (file.assetMeta == nullptr)
|
||||||
|
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
const bool isSelected = std::ranges::find(selectedAssets, file.assetMeta->id) != selectedAssets.end();
|
||||||
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
|
||||||
|
if (isSelected)
|
||||||
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
std::string icon{};
|
||||||
|
|
||||||
|
switch(file.assetMeta->type)
|
||||||
|
{
|
||||||
|
case AssetType::INVALID: break;
|
||||||
|
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
||||||
|
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
||||||
|
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
||||||
|
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
||||||
|
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
||||||
|
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
||||||
|
case AssetType::MATERIAL: break;
|
||||||
|
case AssetType::MAX_COUNT: break;
|
||||||
|
default: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
|
||||||
ImGui::Text("%s", asset.name.c_str());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
if(SHDragDrop::BeginSource())
|
||||||
ImGui::TableNextColumn();
|
{
|
||||||
ImGui::Text("%s", "Type");
|
auto id = file.assetMeta->id;
|
||||||
|
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
|
||||||
ImGui::EndGroup();
|
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
||||||
ImGui::PopID();
|
SHDragDrop::EndSource();
|
||||||
|
}
|
||||||
|
if(ImGui::IsItemClicked())
|
||||||
|
{
|
||||||
|
selectedAssets.clear();
|
||||||
|
selectedAssets.push_back(file.assetMeta->id);
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
return nodeRect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "imgui_internal.h"
|
||||||
#include "Assets/SHAsset.h"
|
#include "Assets/SHAsset.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Filesystem/SHFolder.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -16,9 +18,14 @@ namespace SHADE
|
||||||
void Refresh();
|
void Refresh();
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar();
|
void DrawMenuBar();
|
||||||
void DrawAsset(SHAsset const& asset);
|
ImRect RecursivelyDrawTree(FolderPointer folder);
|
||||||
|
void DrawCurrentFolder();
|
||||||
|
ImRect DrawFile(SHFile const& file) noexcept;
|
||||||
|
|
||||||
float idColumnWidth, nameColumnWidth, typeColumnWidth;
|
FolderPointer rootFolder, prevFolder, currentFolder;
|
||||||
|
std::vector<FolderPointer> selectedFolders;
|
||||||
|
std::vector<AssetID> selectedAssets;
|
||||||
|
static constexpr float tileWidth = 50.0f;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "SHHierarchyPanel.h"
|
#include "SHHierarchyPanel.h"
|
||||||
|
@ -48,7 +48,7 @@ namespace SHADE
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
if(skipFrame)
|
if (skipFrame)
|
||||||
{
|
{
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
skipFrame = false;
|
skipFrame = false;
|
||||||
|
@ -63,9 +63,9 @@ namespace SHADE
|
||||||
|
|
||||||
for (const auto child : children)
|
for (const auto child : children)
|
||||||
{
|
{
|
||||||
if(child)
|
if (child)
|
||||||
RecursivelyDrawEntityNode(child);
|
RecursivelyDrawEntityNode(child);
|
||||||
if(skipFrame)
|
if (skipFrame)
|
||||||
{
|
{
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
|
@ -77,12 +77,36 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Scene Graph root is null! Unable to render hierarchy.")
|
SHLOG_WARNING("Scene Graph root is null! Unable to render hierarchy.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if (ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
|
if (ImGui::IsWindowFocused())
|
||||||
|
{
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_A))
|
||||||
|
{
|
||||||
|
SelectAllEntities();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_C))
|
||||||
|
{
|
||||||
|
CopySelectedEntities();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && !ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
||||||
|
{
|
||||||
|
PasteEntities();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
||||||
|
{
|
||||||
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editor->selectedEntities.size() == 1)
|
||||||
|
{
|
||||||
|
PasteEntities(editor->selectedEntities.back());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -94,7 +118,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::SetScrollTo(EntityID eid)
|
void SHHierarchyPanel::SetScrollTo(EntityID eid)
|
||||||
{
|
{
|
||||||
if(eid == MAX_EID)
|
if (eid == MAX_EID)
|
||||||
return;
|
return;
|
||||||
scrollTo = eid;
|
scrollTo = eid;
|
||||||
}
|
}
|
||||||
|
@ -106,8 +130,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.75f);
|
auto size = ImGui::GetWindowSize();
|
||||||
if(ImGui::SmallButton(ICON_MD_DESELECT))
|
auto g = ImGui::GetCurrentContext();
|
||||||
|
ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f);
|
||||||
|
if (ImGui::SmallButton(ICON_MD_CLEAR_ALL))
|
||||||
{
|
{
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
|
@ -134,7 +160,7 @@ namespace SHADE
|
||||||
|
|
||||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
||||||
{
|
{
|
||||||
if(currentNode == nullptr)
|
if (currentNode == nullptr)
|
||||||
return {};
|
return {};
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
|
@ -142,7 +168,7 @@ namespace SHADE
|
||||||
auto& children = currentNode->GetChildren();
|
auto& children = currentNode->GetChildren();
|
||||||
EntityID eid = currentNode->GetEntityID();
|
EntityID eid = currentNode->GetEntityID();
|
||||||
|
|
||||||
if(scrollTo != MAX_EID && eid == scrollTo)
|
if (scrollTo != MAX_EID && eid == scrollTo)
|
||||||
{
|
{
|
||||||
ImGui::SetScrollHereY();
|
ImGui::SetScrollHereY();
|
||||||
scrollTo = MAX_EID;
|
scrollTo = MAX_EID;
|
||||||
|
@ -169,23 +195,23 @@ namespace SHADE
|
||||||
if (SHDragDrop::BeginSource())
|
if (SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
std::string moveLabel = "Moving EID: ";
|
std::string moveLabel = "Moving EID: ";
|
||||||
if(!isSelected)
|
if (!isSelected)
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
for(int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
|
for (int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
|
||||||
{
|
{
|
||||||
moveLabel.append(std::to_string(editor->selectedEntities[i]));
|
moveLabel.append(std::to_string(editor->selectedEntities[i]));
|
||||||
if(i + 1 < static_cast<int>(editor->selectedEntities.size()))
|
if (i + 1 < static_cast<int>(editor->selectedEntities.size()))
|
||||||
{
|
{
|
||||||
moveLabel.append(", ");
|
moveLabel.append(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::Text(moveLabel.c_str());
|
ImGui::Text(moveLabel.c_str());
|
||||||
SHDragDrop::SetPayload<std::vector<EntityID>>(DRAG_EID, &editor->selectedEntities);
|
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &editor->selectedEntities);
|
||||||
SHDragDrop::EndSource();
|
SHDragDrop::EndSource();
|
||||||
}
|
}
|
||||||
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||||
{
|
{
|
||||||
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(DRAG_EID)) //If payload is valid
|
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid
|
||||||
{
|
{
|
||||||
ParentSelectedEntities(eid);
|
ParentSelectedEntities(eid);
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
|
@ -193,43 +219,43 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
//Context menu
|
//Context menu
|
||||||
if(ImGui::BeginPopupContextItem(std::to_string(eid).c_str()))
|
if (ImGui::BeginPopupContextItem(std::to_string(eid).c_str()))
|
||||||
{
|
{
|
||||||
if(!isSelected)
|
if (!isSelected)
|
||||||
{
|
{
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Copy"))
|
if (ImGui::Selectable("Copy"))
|
||||||
{
|
{
|
||||||
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
|
CopySelectedEntities();
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Paste"))
|
if (ImGui::Selectable("Paste"))
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
|
PasteEntities();
|
||||||
skipFrame = true;
|
skipFrame = true;
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
if(isNodeOpen)
|
if (isNodeOpen)
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
return nodeRect;
|
return nodeRect;
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Paste as Child"))
|
if (ImGui::Selectable("Paste as Child"))
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
|
PasteEntities(eid);
|
||||||
skipFrame = true;
|
skipFrame = true;
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if (ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
SHEntityManager::DestroyEntity(eid);
|
SHEntityManager::DestroyEntity(eid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
||||||
{
|
{
|
||||||
ParentSelectedEntities(MAX_EID);
|
ParentSelectedEntities(MAX_EID);
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle node selection
|
//Handle node selection
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
|
@ -237,11 +263,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!isSelected)
|
if (!isSelected)
|
||||||
{
|
{
|
||||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift))
|
if (ImGui::IsKeyDown(ImGuiKey_LeftShift))
|
||||||
{
|
{
|
||||||
if(editor->selectedEntities.size() >= 1)
|
if (editor->selectedEntities.size() >= 1)
|
||||||
{
|
{
|
||||||
SelectRangeOfEntities(editor->selectedEntities[0], eid);
|
SelectRangeOfEntities(editor->selectedEntities[0], eid);
|
||||||
}
|
}
|
||||||
else editor->selectedEntities.clear();
|
else editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
|
@ -299,12 +325,12 @@ namespace SHADE
|
||||||
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
SHEntityParentCommand::EntityParentData entityParentData;
|
SHEntityParentCommand::EntityParentData entityParentData;
|
||||||
std::vector<EntityID> parentedEIDS;
|
std::vector<EntityID> parentedEIDS;
|
||||||
for(auto const& eid : editor->selectedEntities)
|
for (auto const& eid : editor->selectedEntities)
|
||||||
{
|
{
|
||||||
if(sceneGraph.GetChild(eid, parentEID) == nullptr)
|
if (sceneGraph.GetChild(eid, parentEID) == nullptr)
|
||||||
{
|
{
|
||||||
parentedEIDS.push_back(eid);
|
parentedEIDS.push_back(eid);
|
||||||
if(auto parent = sceneGraph.GetParent(eid))
|
if (auto parent = sceneGraph.GetParent(eid))
|
||||||
entityParentData[eid].oldParentEID = parent->GetEntityID();
|
entityParentData[eid].oldParentEID = parent->GetEntityID();
|
||||||
entityParentData[eid].newParentEID = parentEID;
|
entityParentData[eid].newParentEID = parentEID;
|
||||||
}
|
}
|
||||||
|
@ -319,34 +345,57 @@ namespace SHADE
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
{
|
|
||||||
auto eid = nodePtr->GetEntityID();
|
|
||||||
if(!startSelecting)
|
|
||||||
{
|
{
|
||||||
if(eid == beginEID || eid == endEID)
|
auto eid = nodePtr->GetEntityID();
|
||||||
|
if (!startSelecting)
|
||||||
{
|
{
|
||||||
startSelecting = true;
|
if (eid == beginEID || eid == endEID)
|
||||||
editor->selectedEntities.push_back(eid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!endSelecting)
|
|
||||||
{
|
|
||||||
editor->selectedEntities.push_back(eid);
|
|
||||||
if(eid == endEID || eid == beginEID)
|
|
||||||
{
|
{
|
||||||
endSelecting = true;
|
startSelecting = true;
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
});
|
{
|
||||||
|
if (!endSelecting)
|
||||||
|
{
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
|
if (eid == endEID || eid == beginEID)
|
||||||
|
{
|
||||||
|
endSelecting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::SelectAllEntities()
|
||||||
|
{
|
||||||
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
editor->selectedEntities.clear();
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
{
|
||||||
|
auto eid = nodePtr->GetEntityID();
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::CopySelectedEntities()
|
||||||
|
{
|
||||||
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::PasteEntities(EntityID parentEID)
|
||||||
|
{
|
||||||
|
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCreateEntityCommand::Execute()
|
void SHCreateEntityCommand::Execute()
|
||||||
{
|
{
|
||||||
EntityID newEID = SHEntityManager::CreateEntity(eid);
|
EntityID newEID = SHEntityManager::CreateEntity(eid);
|
||||||
if(eid == MAX_EID)
|
if (eid == MAX_EID)
|
||||||
eid = newEID;
|
eid = newEID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +407,9 @@ namespace SHADE
|
||||||
void SHEntityParentCommand::Execute()
|
void SHEntityParentCommand::Execute()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for(auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if(entityParentData[eid].newParentEID == MAX_EID)
|
if (entityParentData[eid].newParentEID == MAX_EID)
|
||||||
sceneGraph.SetParent(eid, nullptr);
|
sceneGraph.SetParent(eid, nullptr);
|
||||||
else
|
else
|
||||||
sceneGraph.SetParent(eid, entityParentData[eid].newParentEID);
|
sceneGraph.SetParent(eid, entityParentData[eid].newParentEID);
|
||||||
|
@ -370,9 +419,9 @@ namespace SHADE
|
||||||
void SHEntityParentCommand::Undo()
|
void SHEntityParentCommand::Undo()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for(auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if(entityParentData[eid].oldParentEID == MAX_EID)
|
if (entityParentData[eid].oldParentEID == MAX_EID)
|
||||||
sceneGraph.SetParent(eid, nullptr);
|
sceneGraph.SetParent(eid, nullptr);
|
||||||
else
|
else
|
||||||
sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID);
|
sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID);
|
||||||
|
|
|
@ -30,7 +30,9 @@ namespace SHADE
|
||||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
||||||
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||||
|
void SelectAllEntities();
|
||||||
|
void CopySelectedEntities();
|
||||||
|
void PasteEntities(EntityID parentEID = MAX_EID);
|
||||||
bool skipFrame = false;
|
bool skipFrame = false;
|
||||||
std::string filter;
|
std::string filter;
|
||||||
bool isAnyNodeSelected = false;
|
bool isAnyNodeSelected = false;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
||||||
|
static void DrawContextMenu(T* component);
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
||||||
|
static void DrawComponent(T* component);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "SHEditorComponentView.hpp"
|
|
@ -13,25 +13,28 @@
|
||||||
#include "Editor/IconsFontAwesome6.h"
|
#include "Editor/IconsFontAwesome6.h"
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::vector<const char*> GetRTTREnumNames()
|
std::vector<const char*> GetRTTREnumNames()
|
||||||
{
|
{
|
||||||
auto const rttrType = rttr::type::get<T>();
|
auto const rttrType = rttr::type::get<T>();
|
||||||
if(!rttrType.is_enumeration())
|
if (!rttrType.is_enumeration())
|
||||||
return {};
|
return {};
|
||||||
auto const enumAlign = rttrType.get_enumeration();
|
auto const enumAlign = rttrType.get_enumeration();
|
||||||
auto const names = enumAlign.get_names();
|
auto const names = enumAlign.get_names();
|
||||||
std::vector<const char*> result;
|
std::vector<const char*> result;
|
||||||
std::transform(names.begin(), names.end(), std::back_inserter(result), [](rttr::string_view const& name){return name.data();});
|
std::transform(names.begin(), names.end(), std::back_inserter(result), [](rttr::string_view const& name) {return name.data(); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool>>
|
||||||
static void DrawContextMenu(T* component)
|
static void DrawContextMenu(T* component)
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
|
@ -60,13 +63,15 @@ namespace SHADE
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool>>
|
||||||
static void DrawComponent(T* component)
|
static void DrawComponent(T* component)
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get<T>();
|
||||||
|
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
|
ImGui::PopID();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -75,7 +80,8 @@ namespace SHADE
|
||||||
for (auto const& property : properties)
|
for (auto const& property : properties)
|
||||||
{
|
{
|
||||||
auto const& type = property.get_type();
|
auto const& type = property.get_type();
|
||||||
|
auto tooltip = property.get_metadata(META::tooltip);
|
||||||
|
bool const& isAngleInRad = property.get_metadata(META::angleInRad).is_valid() ? property.get_metadata(META::angleInRad).template get_value<bool>() : false;
|
||||||
if (type.is_enumeration())
|
if (type.is_enumeration())
|
||||||
{
|
{
|
||||||
auto enumAlign = type.get_enumeration();
|
auto enumAlign = type.get_enumeration();
|
||||||
|
@ -89,29 +95,25 @@ namespace SHADE
|
||||||
auto values = enumAlign.get_values();
|
auto values = enumAlign.get_values();
|
||||||
auto it = std::next(values.begin(), idx);
|
auto it = std::next(values.begin(), idx);
|
||||||
property.set_value(component, *it);
|
property.set_value(component, *it);
|
||||||
});
|
}, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else if (type.is_arithmetic())
|
else if (type.is_arithmetic())
|
||||||
{
|
{
|
||||||
if (type == rttr::type::get<bool>())
|
if (type == rttr::type::get<bool>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); });
|
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
//else if (type == rttr::type::get<char>())
|
|
||||||
//{
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
else if (type == rttr::type::get<int8_t>() || type == rttr::type::get<int16_t>() || type == rttr::type::get<int32_t>() || type == rttr::type::get<int64_t>())
|
else if (type == rttr::type::get<int8_t>() || type == rttr::type::get<int16_t>() || type == rttr::type::get<int32_t>() || type == rttr::type::get<int64_t>())
|
||||||
{
|
{
|
||||||
auto metaMin = property.get_metadata(META::min);
|
auto metaMin = property.get_metadata(META::min);
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin && metaMax)
|
if (metaMin && metaMax)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMax.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMax.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint8_t>())
|
else if (type == rttr::type::get<uint8_t>())
|
||||||
|
@ -120,11 +122,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint16_t>())
|
else if (type == rttr::type::get<uint16_t>())
|
||||||
|
@ -133,11 +135,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMax.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMax.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint32_t>())
|
else if (type == rttr::type::get<uint32_t>())
|
||||||
|
@ -146,11 +148,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMax.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMax.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint64_t>())
|
else if (type == rttr::type::get<uint64_t>())
|
||||||
|
@ -159,11 +161,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMax.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMax.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<float>())
|
else if (type == rttr::type::get<float>())
|
||||||
|
@ -171,17 +173,17 @@ namespace SHADE
|
||||||
auto metaMin = property.get_metadata(META::min);
|
auto metaMin = property.get_metadata(META::min);
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
float min{}, max{};
|
float min{}, max{};
|
||||||
if(metaMin.is_valid())
|
if (metaMin.is_valid())
|
||||||
min = std::max(metaMin.template get_value<float>(), -FLT_MAX * 0.5f);
|
min = std::max(metaMin.template get_value<float>(), -FLT_MAX * 0.5f);
|
||||||
if(metaMax.is_valid())
|
if (metaMax.is_valid())
|
||||||
max = std::min(metaMax.template get_value<float>(), FLT_MAX * 0.5f);
|
max = std::min(metaMax.template get_value<float>(), FLT_MAX * 0.5f);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderFloat(property.get_name().data(), min, max, [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
|
SHEditorWidgets::SliderFloat(property.get_name().data(), min, max, [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, "Test");
|
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<double>())
|
else if (type == rttr::type::get<double>())
|
||||||
|
@ -190,25 +192,25 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMax.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); });
|
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMax.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f);
|
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f, {}, {}, "%.3f", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec4>())
|
else if (type == rttr::type::get<SHVec4>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); }, isAngleInRad, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec3>())
|
else if (type == rttr::type::get<SHVec3>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); }, isAngleInRad, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec2>())
|
else if (type == rttr::type::get<SHVec2>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); }, isAngleInRad, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -223,10 +225,10 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get transform component for extrapolating relative sizes
|
// Get transform component for extrapolating relative sizes
|
||||||
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(component->GetEID());
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
|
||||||
|
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -234,8 +236,8 @@ namespace SHADE
|
||||||
|
|
||||||
auto& colliders = component->GetColliders();
|
auto& colliders = component->GetColliders();
|
||||||
int const size = static_cast<int>(colliders.size());
|
int const size = static_cast<int>(colliders.size());
|
||||||
ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true);
|
ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
||||||
std::optional<int> colliderToDelete{std::nullopt};
|
std::optional<int> colliderToDelete{ std::nullopt };
|
||||||
for (int i{}; i < size; ++i)
|
for (int i{}; i < size; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
|
@ -244,12 +246,12 @@ namespace SHADE
|
||||||
|
|
||||||
if (collider->GetType() == SHCollider::Type::BOX)
|
if (collider->GetType() == SHCollider::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
"Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); },
|
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); },
|
||||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
||||||
|
@ -258,14 +260,14 @@ namespace SHADE
|
||||||
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
"Radius",
|
"Radius",
|
||||||
[sphere, transformComponent]
|
[sphere, transformComponent]
|
||||||
{
|
{
|
||||||
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
||||||
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
||||||
return sphere->GetRadius() / MAX_SCALE;
|
return sphere->GetRadius() / MAX_SCALE;
|
||||||
},
|
},
|
||||||
[collider](float const& value) { collider->SetBoundingSphere(value);});
|
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
@ -276,14 +278,14 @@ namespace SHADE
|
||||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
}
|
}
|
||||||
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||||
{
|
{
|
||||||
colliderToDelete = i;
|
colliderToDelete = i;
|
||||||
}
|
}
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
if(colliderToDelete.has_value())
|
if (colliderToDelete.has_value())
|
||||||
{
|
{
|
||||||
component->RemoveCollider(colliderToDelete.value());
|
component->RemoveCollider(colliderToDelete.value());
|
||||||
}
|
}
|
||||||
|
@ -291,11 +293,11 @@ namespace SHADE
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Add Collider"))
|
if (ImGui::BeginMenu("Add Collider"))
|
||||||
{
|
{
|
||||||
if(ImGui::Selectable("Box Collider"))
|
if (ImGui::Selectable("Box Collider"))
|
||||||
{
|
{
|
||||||
component->AddBoundingBox();
|
component->AddBoundingBox();
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Sphere Collider"))
|
if (ImGui::Selectable("Sphere Collider"))
|
||||||
{
|
{
|
||||||
component->AddBoundingSphere();
|
component->AddBoundingSphere();
|
||||||
}
|
}
|
||||||
|
@ -308,10 +310,10 @@ namespace SHADE
|
||||||
template<>
|
template<>
|
||||||
static void DrawComponent(SHLightComponent* component)
|
static void DrawComponent(SHLightComponent* component)
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -319,19 +321,48 @@ namespace SHADE
|
||||||
|
|
||||||
static auto const enumAlign = rttr::type::get<SH_LIGHT_TYPE>().get_enumeration();
|
static auto const enumAlign = rttr::type::get<SH_LIGHT_TYPE>().get_enumeration();
|
||||||
static std::vector<const char*> list(GetRTTREnumNames<SH_LIGHT_TYPE>());
|
static std::vector<const char*> list(GetRTTREnumNames<SH_LIGHT_TYPE>());
|
||||||
|
|
||||||
SHEditorWidgets::ComboBox("Type", list, [component] {return static_cast<int>(component->GetType()); }, [component](int const& idx)
|
SHEditorWidgets::ComboBox("Type", list, [component] {return static_cast<int>(component->GetType()); }, [component](int const& idx)
|
||||||
{
|
{
|
||||||
component->SetType(static_cast<SH_LIGHT_TYPE>(idx));
|
component->SetType(static_cast<SH_LIGHT_TYPE>(idx));
|
||||||
});
|
});
|
||||||
SHEditorWidgets::DragVec3("Position", {"X", "Y", "Z"}, [component](){return component->GetPosition();}, [component](SHVec3 const& vec){component->SetPosition(vec);});
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component]() {return component->GetPosition(); }, [component](SHVec3 const& vec) {component->SetPosition(vec); });
|
||||||
SHEditorWidgets::DragVec3("Direction", {"X", "Y", "Z"}, [component](){return component->GetDirection();}, [component](SHVec3 const& vec){component->SetDirection(vec);});
|
SHEditorWidgets::DragVec3("Direction", { "X", "Y", "Z" }, [component]() {return component->GetDirection(); }, [component](SHVec3 const& vec) {component->SetDirection(vec); });
|
||||||
SHEditorWidgets::ColorPicker("Color", [component](){return component->GetColor();}, [component](SHVec4 const& rgba){component->SetColor(rgba);});
|
SHEditorWidgets::ColorPicker("Color", [component]() {return component->GetColor(); }, [component](SHVec4 const& rgba) {component->SetColor(rgba); });
|
||||||
SHEditorWidgets::DragFloat("Strength", [component](){return component->GetStrength();}, [component](float const& value){component->SetStrength(value);});
|
SHEditorWidgets::DragFloat("Strength", [component]() {return component->GetStrength(); }, [component](float const& value) {component->SetStrength(value); });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
template<>
|
||||||
|
static void DrawComponent(SHRenderable* component)
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
return;
|
||||||
|
const auto componentType = rttr::type::get(*component);
|
||||||
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
|
||||||
|
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]()
|
||||||
|
{
|
||||||
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
return SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0);
|
||||||
|
},
|
||||||
|
[component](AssetID const& id)
|
||||||
|
{
|
||||||
|
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
||||||
|
}, SHDragDrop::DRAG_RESOURCE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "SHEditorInspector.h"
|
#include "SHEditorInspector.h"
|
||||||
|
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
@ -10,17 +10,14 @@
|
||||||
|
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "SHEditorComponentView.hpp"
|
|
||||||
#include "ECS_Base/UnitTesting/SHTestComponents.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
|
||||||
#include "AudioSystem/SHAudioSystem.h"
|
|
||||||
#include "Physics/Components/SHRigidBodyComponent.h"
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Camera/SHCameraComponent.h"
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "SHEditorComponentView.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -30,8 +27,17 @@ namespace SHADE
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
if(!SHComponentManager::HasComponent<ComponentType>(eid))
|
if(!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
|
const char* componentName = rttr::type::get<ComponentType>().get_name().data();
|
||||||
|
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
||||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
|
if(ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
||||||
|
ImGui::Text("to this entity", componentName);
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
@ -42,13 +48,26 @@ namespace SHADE
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
|
const char* componentName = rttr::type::get<ComponentType>().get_name().data();
|
||||||
|
|
||||||
|
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
||||||
{
|
{
|
||||||
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
||||||
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
||||||
|
|
||||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
}
|
}
|
||||||
|
if(ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
||||||
|
ImGui::Text("to this entity", componentName);
|
||||||
|
ImGui::Text("Adds"); ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImGuiColors::red, "%s", rttr::type::get<EnforcedComponent>().get_name().data()); ImGui::SameLine();
|
||||||
|
ImGui::Text("if the entity does not already have it");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
@ -117,6 +136,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
DrawAddComponentButton<SHCameraComponent>(eid);
|
DrawAddComponentButton<SHCameraComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHLightComponent>(eid);
|
||||||
|
|
||||||
// Components that require Transforms
|
// Components that require Transforms
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "SHEditorMenuBar.h"
|
#include "SHEditorMenuBar.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/Command/SHCommandManager.h"
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
#include "ImGuizmo.h"
|
#include "ImGuizmo.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
#include <Editor/IconsFontAwesome6.h>
|
#include <Editor/IconsFontAwesome6.h>
|
||||||
|
|
||||||
|
#include "Camera/SHCameraSystem.h"
|
||||||
|
#include "FRC/SHFramerateController.h"
|
||||||
|
|
||||||
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
|
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -30,8 +33,15 @@ namespace SHADE
|
||||||
void SHEditorViewport::Update()
|
void SHEditorViewport::Update()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f,0.0f));
|
if (shouldUpdateCamera)
|
||||||
if(Begin())
|
{
|
||||||
|
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime());
|
||||||
|
shouldUpdateCamera = false;
|
||||||
|
}
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
if (Begin())
|
||||||
{
|
{
|
||||||
ImGuizmo::SetDrawlist();
|
ImGuizmo::SetDrawlist();
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
|
@ -39,21 +49,38 @@ namespace SHADE
|
||||||
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||||
auto mousePos = ImGui::GetMousePos();
|
auto mousePos = ImGui::GetMousePos();
|
||||||
beginCursorPos = ImGui::GetCursorScreenPos();
|
beginCursorPos = ImGui::GetCursorScreenPos();
|
||||||
viewportMousePos = {mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y};
|
viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y };
|
||||||
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
|
gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos);
|
||||||
|
|
||||||
ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y});
|
ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y });
|
||||||
|
|
||||||
if(ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||||
{
|
{
|
||||||
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
|
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
|
||||||
ImGui::SetCursorScreenPos(ImGui::GetMousePos());
|
ImGui::SetCursorScreenPos(ImGui::GetMousePos());
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green);
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green);
|
||||||
ImGui::Text(ICON_FA_EYE);
|
ImGui::Text(ICON_FA_EYE);
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
shouldUpdateCamera = true;
|
||||||
|
}
|
||||||
|
if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||||
|
{
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_Q))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_W))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_E))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||||
transformGizmo.Draw();
|
transformGizmo.Draw();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
@ -72,11 +99,12 @@ namespace SHADE
|
||||||
|
|
||||||
//auto pos = ImGui::GetCursorPos();
|
//auto pos = ImGui::GetCursorPos();
|
||||||
//windowCursorPos = {}
|
//windowCursorPos = {}
|
||||||
if(beginContentRegionAvailable.x == 0 || beginContentRegionAvailable.y == 0)
|
if (beginContentRegionAvailable.x == 0 || beginContentRegionAvailable.y == 0)
|
||||||
{
|
{
|
||||||
beginContentRegionAvailable = windowSize;
|
beginContentRegionAvailable = windowSize;
|
||||||
}
|
}
|
||||||
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(beginContentRegionAvailable.y));
|
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(beginContentRegionAvailable.y));
|
||||||
|
shouldUpdateCamera = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorViewport::OnPosChange()
|
void SHEditorViewport::OnPosChange()
|
||||||
|
@ -86,44 +114,63 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEditorViewport::DrawMenuBar() noexcept
|
void SHEditorViewport::DrawMenuBar() noexcept
|
||||||
{
|
{
|
||||||
if(ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
|
ImGui::BeginDisabled(ImGui::IsWindowFocused() && ImGui::IsMouseDown(ImGuiMouseButton_Right));
|
||||||
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
|
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
|
||||||
ImGui::BeginDisabled(isTranslate);
|
ImGui::BeginDisabled(isTranslate);
|
||||||
if(isTranslate)
|
if (isTranslate)
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
||||||
if(ImGui::Button(ICON_MD_OPEN_WITH))
|
if (ImGui::Button(ICON_MD_OPEN_WITH))
|
||||||
{
|
{
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
if(isTranslate)
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Translate [Q]");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
if (isTranslate)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
bool const isRotate = transformGizmo.operation == SHTransformGizmo::Operation::ROTATE;
|
bool const isRotate = transformGizmo.operation == SHTransformGizmo::Operation::ROTATE;
|
||||||
ImGui::BeginDisabled(isRotate);
|
ImGui::BeginDisabled(isRotate);
|
||||||
if(isRotate)
|
if (isRotate)
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
||||||
if(ImGui::Button(ICON_MD_AUTORENEW))
|
if (ImGui::Button(ICON_MD_AUTORENEW))
|
||||||
{
|
{
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
if(isRotate)
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Rotate [W]");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
if (isRotate)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
bool const isScale = transformGizmo.operation == SHTransformGizmo::Operation::SCALE;
|
bool const isScale = transformGizmo.operation == SHTransformGizmo::Operation::SCALE;
|
||||||
ImGui::BeginDisabled(isScale);
|
ImGui::BeginDisabled(isScale);
|
||||||
if(isScale)
|
if (isScale)
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
||||||
if(ImGui::Button(ICON_MD_EXPAND))
|
if (ImGui::Button(ICON_MD_EXPAND))
|
||||||
{
|
{
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
if(isScale)
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Scale [E]");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
if (isScale)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHEditorViewport final : public SHEditorWindow
|
class SHEditorViewport final : public SHEditorWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SHEditorViewport();
|
SHEditorViewport();
|
||||||
|
@ -28,5 +28,6 @@ namespace SHADE
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() noexcept;
|
void DrawMenuBar() noexcept;
|
||||||
SHVec2 beginCursorPos;
|
SHVec2 beginCursorPos;
|
||||||
|
bool shouldUpdateCamera = false;
|
||||||
};//class SHEditorViewport
|
};//class SHEditorViewport
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <ImGuizmo.h>
|
#include <ImGuizmo.h>
|
||||||
|
@ -63,6 +63,9 @@ namespace SHADE
|
||||||
if (selectedEntityTransformComponent == nullptr)
|
if (selectedEntityTransformComponent == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(!selectedEntityTransformComponent->isActive)
|
||||||
|
return;
|
||||||
|
|
||||||
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
|
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
|
||||||
useSnap = ImGui::IsKeyDown(ImGuiKey_LeftCtrl);
|
useSnap = ImGui::IsKeyDown(ImGuiKey_LeftCtrl);
|
||||||
if(useSnap)
|
if(useSnap)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
#include "SHEditor.hpp"
|
#include "SHEditor.h"
|
||||||
#include "SHEditorWidgets.hpp"
|
#include "SHEditorWidgets.hpp"
|
||||||
|
|
||||||
#include "Math/Transform/SHTransformSystem.h"
|
#include "Math/Transform/SHTransformSystem.h"
|
||||||
|
@ -175,7 +175,7 @@ namespace SHADE
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
||||||
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_MD, 0 };
|
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
@ -293,6 +293,7 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHEditor::InitBackend()
|
void SHEditor::InitBackend()
|
||||||
{
|
{
|
||||||
|
#ifdef SHEDITOR
|
||||||
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
||||||
{
|
{
|
||||||
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
||||||
|
@ -339,6 +340,7 @@ namespace SHADE
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::PollPicking()
|
void SHEditor::PollPicking()
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <misc/cpp/imgui_stdlib.h>
|
#include <misc/cpp/imgui_stdlib.h>
|
||||||
#include <rttr/type.h>
|
#include <rttr/type.h>
|
||||||
|
|
||||||
|
#include "DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SH_API SHEditorWidgets
|
class SH_API SHEditorWidgets
|
||||||
|
@ -41,7 +43,7 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.2f));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
auto frameHeight = ImGui::GetFrameHeight();
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
@ -86,7 +88,7 @@ namespace SHADE
|
||||||
|
|
||||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.2f));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
auto frameHeight = ImGui::GetFrameHeight();
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
@ -127,7 +129,7 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui::GetWindowDrawList()->AddRect(
|
ImGui::GetWindowDrawList()->AddRect(
|
||||||
frameRect.Min, frameRect.Max,
|
frameRect.Min, frameRect.Max,
|
||||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)),
|
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled)),
|
||||||
halfFrame.x);
|
halfFrame.x);
|
||||||
|
|
||||||
ImGui::PopClipRect();
|
ImGui::PopClipRect();
|
||||||
|
@ -174,15 +176,19 @@ namespace SHADE
|
||||||
ImGui::SetColumnWidth(-1, 80.0f);
|
ImGui::SetColumnWidth(-1, 80.0f);
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered |= ImGui::IsItemHovered();
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(static_cast<int>(i));
|
ImGui::PushID(static_cast<int>(i));
|
||||||
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str()));
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered |= ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(80.0f);
|
ImGui::SetNextItemWidth(80.0f);
|
||||||
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered |= ImGui::IsItemHovered();
|
||||||
const ImVec2 min = ImGui::GetItemRectMin();
|
const ImVec2 min = ImGui::GetItemRectMin();
|
||||||
const ImVec2 max = ImGui::GetItemRectMax();
|
const ImVec2 max = ImGui::GetItemRectMax();
|
||||||
const float spacing = g.Style.FrameRounding;
|
const float spacing = g.Style.FrameRounding;
|
||||||
|
@ -203,23 +209,31 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DragVec2(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
static bool DragVec2(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||||
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f,
|
std::function<void(SHVec2)> set, bool const& isAnAngleInRad = false, std::string_view const& tooltip = {}, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0)
|
||||||
{
|
{
|
||||||
SHVec2 values = get();
|
SHVec2 values = get();
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::RadiansToDegrees(values.x), SHMath::RadiansToDegrees(values.y)};
|
||||||
|
}
|
||||||
bool const changed = DragN<float, 2>(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags);
|
bool const changed = DragN<float, 2>(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags);
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::DegreesToRadians(values.x), SHMath::DegreesToRadians(values.y)};
|
||||||
|
}
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), startRecording);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), startRecording);
|
||||||
if (!startRecording)
|
if (!startRecording)
|
||||||
startRecording = true;
|
startRecording = true;
|
||||||
}
|
}
|
||||||
if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
startRecording = false;
|
startRecording = false;
|
||||||
if(!tooltip.empty())
|
if (!tooltip.empty())
|
||||||
{
|
{
|
||||||
if(ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(tooltip.data());
|
ImGui::Text(tooltip.data());
|
||||||
|
@ -230,17 +244,24 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DragVec3(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
static bool DragVec3(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||||
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f,
|
std::function<void(SHVec3)> set, bool const& isAnAngleInRad = false, std::string_view const& tooltip = {}, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0)
|
||||||
{
|
{
|
||||||
SHVec3 values = get();
|
SHVec3 values = get();
|
||||||
bool const changed = DragN<float, 3>(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags);
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::RadiansToDegrees(values.x), SHMath::RadiansToDegrees(values.y), SHMath::RadiansToDegrees(values.z)};
|
||||||
|
}
|
||||||
|
bool isHovered = false;
|
||||||
|
bool const changed = DragN<float, 3>(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags, &isHovered);
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
SHVec3 old = get();
|
SHVec3 old = get();
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::DegreesToRadians(values.x), SHMath::DegreesToRadians(values.y), SHMath::DegreesToRadians(values.z)};
|
||||||
|
}
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(old, values, set)), startRecording);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(old, values, set)), startRecording);
|
||||||
if (!startRecording)
|
if (!startRecording)
|
||||||
startRecording = true;
|
startRecording = true;
|
||||||
|
@ -249,9 +270,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
startRecording = false;
|
startRecording = false;
|
||||||
}
|
}
|
||||||
if(!tooltip.empty())
|
if (!tooltip.empty())
|
||||||
{
|
{
|
||||||
if(ImGui::IsItemHovered())
|
if (isHovered)
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(tooltip.data());
|
ImGui::Text(tooltip.data());
|
||||||
|
@ -262,14 +283,22 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DragVec4(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
static bool DragVec4(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||||
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f,
|
std::function<void(SHVec4)> set, bool const& isAnAngleInRad = false, std::string_view const& tooltip = {}, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0)
|
||||||
{
|
{
|
||||||
SHVec4 values = get();
|
SHVec4 values = get();
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::RadiansToDegrees(values.x), SHMath::RadiansToDegrees(values.y), SHMath::RadiansToDegrees(values.z), SHMath::RadiansToDegrees(values.w)};
|
||||||
|
}
|
||||||
bool const changed = DragN<float, 4>(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags);
|
bool const changed = DragN<float, 4>(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags);
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::DegreesToRadians(values.x), SHMath::DegreesToRadians(values.y), SHMath::DegreesToRadians(values.z), SHMath::DegreesToRadians(values.w)};
|
||||||
|
}
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), startRecording);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), startRecording);
|
||||||
if (!startRecording)
|
if (!startRecording)
|
||||||
startRecording = true;
|
startRecording = true;
|
||||||
|
@ -278,9 +307,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
startRecording = false;
|
startRecording = false;
|
||||||
}
|
}
|
||||||
if(!tooltip.empty())
|
if (!tooltip.empty())
|
||||||
{
|
{
|
||||||
if(ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(tooltip.data());
|
ImGui::Text(tooltip.data());
|
||||||
|
@ -297,7 +326,7 @@ namespace SHADE
|
||||||
static void TextLabel(std::string_view const& text, bool sameLine = true)
|
static void TextLabel(std::string_view const& text, bool sameLine = true)
|
||||||
{
|
{
|
||||||
const ImVec2 textSize = ImGui::CalcTextSize(text.data(), NULL, true);
|
const ImVec2 textSize = ImGui::CalcTextSize(text.data(), NULL, true);
|
||||||
if(textSize.x > 0.0f)
|
if (textSize.x > 0.0f)
|
||||||
{
|
{
|
||||||
ImGui::Text(text.data());
|
ImGui::Text(text.data());
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -310,32 +339,32 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
if (ImGui::Checkbox("##", &value))
|
bool const changed = ImGui::Checkbox("##", &value);
|
||||||
|
if (changed)
|
||||||
{
|
{
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
if(!tooltip.empty())
|
if (!tooltip.empty())
|
||||||
{
|
{
|
||||||
if(ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(tooltip.data());
|
ImGui::Text(tooltip.data());
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool RadioButton(std::vector<std::string> const& label, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set ,std::string_view const& tooltip = {})
|
static bool RadioButton(std::vector<std::string> const& label, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set, std::string_view const& tooltip = {})
|
||||||
{
|
{
|
||||||
T type = get();
|
T type = get();
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
//TextLabel(label);
|
||||||
for (size_t i = 0; i < listTypes.size(); i++)
|
for (size_t i = 0; i < listTypes.size(); i++)
|
||||||
{
|
{
|
||||||
if (ImGui::RadioButton(label[i].c_str(), type == listTypes[i]))
|
if (ImGui::RadioButton(label[i].c_str(), type == listTypes[i]))
|
||||||
|
@ -366,12 +395,11 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
if (ImGui::InputText("##", &text, flag, callback, userData))
|
bool const changed = ImGui::InputText("##", &text, flag, callback, userData);
|
||||||
|
if (changed)
|
||||||
{
|
{
|
||||||
if (ImGui::IsItemDeactivatedAfterEdit())
|
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
@ -384,7 +412,37 @@ namespace SHADE
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool DragDropReadOnlyField(std::string const& label, std::string_view const& fieldVTextValue, std::function<T (void)> const& get, std::function<void(T const&)> const& set, SHDragDrop::DragDropTag const& dragDropTag, std::string_view const& tooltip = {})
|
||||||
|
{
|
||||||
|
std::string text = fieldVTextValue.data();
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::PushID(label.data());
|
||||||
|
TextLabel(label);
|
||||||
|
bool const changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
|
||||||
|
if(SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
if (!tooltip.empty())
|
||||||
|
{
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text(tooltip.data());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -442,9 +500,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
if(!tooltip.empty())
|
if (!tooltip.empty())
|
||||||
{
|
{
|
||||||
if(ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(tooltip.data());
|
ImGui::Text(tooltip.data());
|
||||||
|
|
|
@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Windowing/Surface/SHVkSurface.h"
|
#include "Graphics/Windowing/Surface/SHVkSurface.h"
|
||||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
#include "Camera/SHCameraSystem.h"
|
#include "Camera/SHCameraSystem.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
//#include "SHRenderer.h"
|
//#include "SHRenderer.h"
|
||||||
#include "Graphics/Windowing/SHWindow.h"
|
#include "Graphics/Windowing/SHWindow.h"
|
||||||
|
|
|
@ -54,13 +54,14 @@ namespace SHADE
|
||||||
|
|
||||||
if (wndData.isFullscreen)
|
if (wndData.isFullscreen)
|
||||||
{
|
{
|
||||||
dwExStyle = WS_EX_APPWINDOW | WS_EX_ACCEPTFILES;
|
dwExStyle = WS_EX_APPWINDOW;
|
||||||
dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||||
|
dwExStyle |= WS_EX_ACCEPTFILES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE | WS_EX_ACCEPTFILES;
|
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
|
||||||
|
dwExStyle |= WS_EX_ACCEPTFILES;
|
||||||
if (wndData.frameEnabled)
|
if (wndData.frameEnabled)
|
||||||
{
|
{
|
||||||
dwStyle = WNDSTYLE::SHWS_WINDOWED;
|
dwStyle = WNDSTYLE::SHWS_WINDOWED;
|
||||||
|
@ -87,7 +88,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//DPI_AWARENESS_CONTEXT prevDPIContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
DPI_AWARENESS_CONTEXT prevDPIContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
|
||||||
RECT windowRect;
|
RECT windowRect;
|
||||||
windowRect.left = wndData.x; //or CW_USEDEFAULT ?
|
windowRect.left = wndData.x; //or CW_USEDEFAULT ?
|
||||||
|
@ -97,13 +98,16 @@ namespace SHADE
|
||||||
AdjustWindowRectEx(&windowRect, dwStyle, false, dwExStyle);
|
AdjustWindowRectEx(&windowRect, dwStyle, false, dwExStyle);
|
||||||
|
|
||||||
//Create window
|
//Create window
|
||||||
wndHWND = CreateWindowEx(0, (LPWSTR) wndData.name.c_str(), (LPWSTR)wndData.title.c_str(), dwStyle, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, parent, NULL, hInstance, NULL);
|
wndHWND = CreateWindowEx(dwExStyle, (LPWSTR) wndData.name.c_str(), (LPWSTR)wndData.title.c_str(), dwStyle, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, parent, NULL, hInstance, NULL);
|
||||||
|
|
||||||
if (!wndHWND)
|
if (!wndHWND)
|
||||||
{
|
{
|
||||||
//DWORD err = GetLastError();
|
//DWORD err = GetLastError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
BOOL help = ChangeWindowMessageFilter (WM_DROPFILES, MSGFLT_ADD);
|
||||||
|
help &= ChangeWindowMessageFilter (WM_COPYDATA, MSGFLT_ADD);
|
||||||
|
help &= ChangeWindowMessageFilter (0x0049, MSGFLT_ADD);
|
||||||
|
|
||||||
if (wndData.isVisible)
|
if (wndData.isVisible)
|
||||||
{
|
{
|
||||||
|
@ -318,13 +322,13 @@ namespace SHADE
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
||||||
break;
|
break;
|
||||||
|
case WM_QUIT:
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
OnDestroy();
|
OnDestroy();
|
||||||
return 0;
|
return 0;
|
||||||
case WM_DROPFILES:
|
case WM_DROPFILES:
|
||||||
//OnFileDrop(reinterpret_cast<HDROP>(wparam));
|
OnFileDrop(reinterpret_cast<HDROP>(wparam));
|
||||||
break;
|
break;
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
|
@ -386,12 +390,25 @@ namespace SHADE
|
||||||
void SHWindow::OnDestroy()
|
void SHWindow::OnDestroy()
|
||||||
{
|
{
|
||||||
OnClose();
|
OnClose();
|
||||||
|
DragAcceptFiles(wndHWND, false);
|
||||||
this->Destroy();
|
this->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
//void SHWindow::OnFileDrop(HDROP drop)
|
void SHWindow::OnFileDrop(HDROP drop)
|
||||||
//{
|
{
|
||||||
//}
|
|
||||||
|
int const numFiles = static_cast<int>(DragQueryFile(drop, 0xFFFFFFFF, nullptr, 0));
|
||||||
|
for(int i = 0; i < numFiles; ++i)
|
||||||
|
{
|
||||||
|
//char fileNameBuffer[MAX_PATH];
|
||||||
|
std::wstring fileNameBuffer;
|
||||||
|
fileNameBuffer.reserve(MAX_PATH);
|
||||||
|
DragQueryFile(drop, static_cast<UINT>(i), fileNameBuffer.data(), MAX_PATH);
|
||||||
|
std::string name(fileNameBuffer.begin(), fileNameBuffer.end());
|
||||||
|
SHLOG_INFO("Dropped: {}", name)
|
||||||
|
}
|
||||||
|
DragFinish(drop);
|
||||||
|
}
|
||||||
|
|
||||||
void SHWindow::OnSize([[maybe_unused]] UINT msg,[[maybe_unused]] UINT type, SIZE size)
|
void SHWindow::OnSize([[maybe_unused]] UINT msg,[[maybe_unused]] UINT type, SIZE size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define SH_WINDOW_H
|
#define SH_WINDOW_H
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "SHWindowMap.h"
|
#include "SHWindowMap.h"
|
||||||
|
@ -10,7 +11,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
constexpr uint16_t MAX_BUFFER = 1024;
|
constexpr uint16_t MAX_BUFFER = 1024;
|
||||||
|
|
||||||
enum WNDSTYLE : DWORD
|
enum WNDSTYLE : DWORD
|
||||||
{
|
{
|
||||||
SHWS_WINDOWED = WS_OVERLAPPEDWINDOW,
|
SHWS_WINDOWED = WS_OVERLAPPEDWINDOW,
|
||||||
|
@ -47,7 +48,7 @@ namespace SHADE
|
||||||
|
|
||||||
//bool canFullscreen = true;
|
//bool canFullscreen = true;
|
||||||
|
|
||||||
unsigned bgColor = WHITE_BRUSH;
|
unsigned bgColor = DKGRAY_BRUSH;
|
||||||
|
|
||||||
//bool transparent = false;
|
//bool transparent = false;
|
||||||
|
|
||||||
|
@ -168,7 +169,7 @@ namespace SHADE
|
||||||
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
||||||
void OnClose();
|
void OnClose();
|
||||||
void OnDestroy();
|
void OnDestroy();
|
||||||
//void OnFileDrop(HDROP drop);
|
void OnFileDrop(HDROP drop);
|
||||||
void OnSize(UINT msg, UINT type, SIZE size);
|
void OnSize(UINT msg, UINT type, SIZE size);
|
||||||
void OnPosChange(LPWINDOWPOS pos);
|
void OnPosChange(LPWINDOWPOS pos);
|
||||||
void OnPaint(HDC hdc, LPPAINTSTRUCT paint);
|
void OnPaint(HDC hdc, LPPAINTSTRUCT paint);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "SHTransformComponent.h"
|
#include "SHTransformComponent.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -184,7 +185,7 @@ RTTR_REGISTRATION
|
||||||
using namespace rttr;
|
using namespace rttr;
|
||||||
|
|
||||||
registration::class_<SHTransformComponent>("Transform Component")
|
registration::class_<SHTransformComponent>("Transform Component")
|
||||||
.property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition )
|
.property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate"))
|
||||||
.property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation) )
|
.property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation) ) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true))
|
||||||
.property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale );
|
.property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale"));
|
||||||
}
|
}
|
|
@ -263,6 +263,9 @@ namespace SHADE
|
||||||
auto* node = EVENT_DATA->data->node;
|
auto* node = EVENT_DATA->data->node;
|
||||||
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
|
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
|
||||||
|
|
||||||
|
if(tf == nullptr)
|
||||||
|
return EVENT_DATA->handle;
|
||||||
|
|
||||||
// Recompute local transform and store localToWorld Matrix
|
// Recompute local transform and store localToWorld Matrix
|
||||||
SHMatrix localToWorld = SHMatrix::Identity;
|
SHMatrix localToWorld = SHMatrix::Identity;
|
||||||
SHMatrix worldToLocal = SHMatrix::Identity;
|
SHMatrix worldToLocal = SHMatrix::Identity;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
|
@ -7,5 +7,6 @@ namespace SHADE
|
||||||
constexpr const char* min = "MIN";
|
constexpr const char* min = "MIN";
|
||||||
constexpr const char* max = "MAX";
|
constexpr const char* max = "MAX";
|
||||||
constexpr const char* tooltip = "tooltip";
|
constexpr const char* tooltip = "tooltip";
|
||||||
|
constexpr const char* angleInRad = "angleInRad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHPrefabManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHPrefabManager::PrefabMap SHPrefabManager::prefabMap{};
|
||||||
|
|
||||||
|
void SHPrefabManager::AddPrefab(AssetID const& prefabAssetID) noexcept
|
||||||
|
{
|
||||||
|
prefabMap.insert({ prefabAssetID, {} });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::RemovePrefab(AssetID const& prefabAssetID) noexcept
|
||||||
|
{
|
||||||
|
prefabMap.erase(prefabAssetID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::ClearPrefab(AssetID const& prefabAssetID) noexcept
|
||||||
|
{
|
||||||
|
if (prefabMap.contains(prefabAssetID))
|
||||||
|
{
|
||||||
|
prefabMap[prefabAssetID].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::UpdateAllPrefabEntities(AssetID const& prefabAssetID) noexcept
|
||||||
|
{
|
||||||
|
//Loop through all entities and deserialize new data
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::AddEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept
|
||||||
|
{
|
||||||
|
if (prefabMap.contains(prefabAssetID))
|
||||||
|
{
|
||||||
|
prefabMap[prefabAssetID].insert(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::RemoveEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept
|
||||||
|
{
|
||||||
|
if (prefabMap.contains(prefabAssetID))
|
||||||
|
{
|
||||||
|
prefabMap[prefabAssetID].erase(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPrefabManager::Clear() noexcept
|
||||||
|
{
|
||||||
|
prefabMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPrefabManager::Empty() noexcept
|
||||||
|
{
|
||||||
|
return prefabMap.empty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHPrefabManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using PrefabMap = std::unordered_map<AssetID, std::unordered_set<EntityID>>;
|
||||||
|
|
||||||
|
static void AddPrefab(AssetID const& prefabAssetID) noexcept;
|
||||||
|
static void RemovePrefab(AssetID const& prefabAssetID) noexcept;
|
||||||
|
static void ClearPrefab(AssetID const& prefabAssetID) noexcept;
|
||||||
|
static void UpdateAllPrefabEntities(AssetID const& prefabAssetID) noexcept;
|
||||||
|
static void AddEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept;
|
||||||
|
static void RemoveEntity(AssetID const& prefabAssetID, EntityID const& eid) noexcept;
|
||||||
|
static void Clear() noexcept;
|
||||||
|
static bool Empty() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PrefabMap prefabMap;
|
||||||
|
};
|
||||||
|
}
|
|
@ -239,6 +239,7 @@ namespace YAML
|
||||||
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHWinDialog.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <shobjidl.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHWinDialog::DisplayMessageBox(MessageBoxType const& messageBoxType, std::string const& title, std::string const& text)
|
||||||
|
{
|
||||||
|
if(messageBoxType == MessageBoxType::MB_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UINT flags = MB_APPLMODAL | MB_SETFOREGROUND | MB_OK;
|
||||||
|
flags |= static_cast<UINT>(messageBoxType);
|
||||||
|
|
||||||
|
const std::wstring wTitle(title.begin(), title.end());
|
||||||
|
const std::wstring wText(text.begin(), text.end());
|
||||||
|
|
||||||
|
MessageBox(GetDesktopWindow(), wText.data(), wTitle.data(), flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> SHWinDialog::DisplayOpenDialog(OpenSaveConfig const& openSaveConfig)
|
||||||
|
{
|
||||||
|
const HWND hwnd = GetDesktopWindow();
|
||||||
|
HRESULT hResult = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||||
|
if(SUCCEEDED(hResult))
|
||||||
|
{
|
||||||
|
IFileOpenDialog* pFileOpen;
|
||||||
|
|
||||||
|
//Create Dialog object
|
||||||
|
hResult = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast<LPVOID*>(pFileOpen));
|
||||||
|
|
||||||
|
if(SUCCEEDED(hResult))
|
||||||
|
{
|
||||||
|
//Show the open dialog box
|
||||||
|
hResult = pFileOpen->Show(hwnd);
|
||||||
|
|
||||||
|
//Get file name from the dialoh box
|
||||||
|
if(SUCCEEDED(hResult))
|
||||||
|
{
|
||||||
|
if(openSaveConfig.openMultiple)
|
||||||
|
{
|
||||||
|
IShellItemArray* pItemArray;
|
||||||
|
hResult = pFileOpen->GetResults(&pItemArray);
|
||||||
|
if(SUCCEEDED(hResult))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IShellItem* pItem;
|
||||||
|
hResult = pFileOpen->GetResult(&pItem);
|
||||||
|
if(SUCCEEDED(hResult))
|
||||||
|
{
|
||||||
|
PWSTR pszFilePath;
|
||||||
|
hResult = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> SHWinDialog::DisplaySaveAsDialog(OpenSaveConfig const& openSaveConfig)
|
||||||
|
{
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox
|
||||||
|
enum class MessageBoxType
|
||||||
|
{
|
||||||
|
MB_ERROR = 0x00000010L,
|
||||||
|
MB_QUESTION = 0x00000020L,
|
||||||
|
MB_WARNING = 0x00000030L,
|
||||||
|
MB_INFO = 0x00000040L,
|
||||||
|
MB_MAX = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpenSaveConfig
|
||||||
|
{
|
||||||
|
using Extension = std::string;
|
||||||
|
using Extensions = std::vector<Extension>;
|
||||||
|
using FileTypeDesc = std::pair<std::string, Extensions>;
|
||||||
|
using FilterList = std::vector<FileTypeDesc>;
|
||||||
|
|
||||||
|
std::string title = "Open";
|
||||||
|
bool openFolders = false;
|
||||||
|
bool openMultiple = false;
|
||||||
|
FilterList filterList{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHWinDialog
|
||||||
|
{
|
||||||
|
static void DisplayMessageBox(MessageBoxType const& messageBoxType, std::string const& title, std::string const& text);
|
||||||
|
static std::vector<std::string> DisplayOpenDialog(OpenSaveConfig const& openSaveConfig);
|
||||||
|
static std::vector<std::string> DisplaySaveAsDialog(OpenSaveConfig const& openSaveConfig);
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue