Merge pull request #192 from SHADE-DP/SP3-4-Editor
Editor Tweaks Play/Pause/Stop bound to F5/F6/F7 Gizmo does not render on play now Command Manager uses separate stack for undo/redo when editor state is in play
This commit is contained in:
commit
f0d7ee655d
|
@ -10,63 +10,102 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
||||
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
||||
|
||||
SHCommandManager::CommandStack SHCommandManager::undoStack(defaultStackSize);
|
||||
SHCommandManager::CommandStack SHCommandManager::redoStack(defaultStackSize);
|
||||
SHCommandManager::CommandStack SHCommandManager::secondaryUndoStack(defaultStackSize);
|
||||
SHCommandManager::CommandStack SHCommandManager::secondaryRedoStack(defaultStackSize);
|
||||
|
||||
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
|
||||
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
|
||||
|
||||
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
||||
{
|
||||
redoStack = CommandStack();
|
||||
*pCurrRedoStack = CommandStack(defaultStackSize);
|
||||
commandPtr->Execute();
|
||||
if (overrideValue && !undoStack.empty())
|
||||
if (overrideValue && !pCurrUndoStack->Empty())
|
||||
{
|
||||
undoStack.top()->Merge(commandPtr);
|
||||
pCurrUndoStack->Top()->Merge(commandPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
undoStack.push(commandPtr);
|
||||
pCurrUndoStack->Push(commandPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
|
||||
{
|
||||
undoStack.push(commandPtr);
|
||||
pCurrUndoStack->Push(commandPtr);
|
||||
}
|
||||
|
||||
void SHCommandManager::UndoCommand()
|
||||
{
|
||||
if (undoStack.empty())
|
||||
if (pCurrUndoStack->Empty())
|
||||
return;
|
||||
undoStack.top()->Undo();
|
||||
redoStack.push(undoStack.top());
|
||||
undoStack.pop();
|
||||
pCurrUndoStack->Top()->Undo();
|
||||
pCurrRedoStack->Push(pCurrUndoStack->Top());
|
||||
pCurrUndoStack->Pop();
|
||||
}
|
||||
|
||||
void SHCommandManager::RedoCommand()
|
||||
{
|
||||
if (redoStack.empty())
|
||||
if (pCurrRedoStack->Empty())
|
||||
return;
|
||||
redoStack.top()->Execute();
|
||||
undoStack.push(redoStack.top());
|
||||
redoStack.pop();
|
||||
pCurrRedoStack->Top()->Execute();
|
||||
pCurrUndoStack->Push(pCurrRedoStack->Top());
|
||||
pCurrRedoStack->Pop();
|
||||
}
|
||||
|
||||
std::size_t SHCommandManager::GetUndoStackSize()
|
||||
{
|
||||
return undoStack.size();
|
||||
return pCurrUndoStack->Size();
|
||||
}
|
||||
|
||||
std::size_t SHCommandManager::GetRedoStackSize()
|
||||
{
|
||||
return redoStack.size();
|
||||
return pCurrRedoStack->Size();
|
||||
}
|
||||
|
||||
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||
{
|
||||
redoStack.pop();
|
||||
pCurrRedoStack->Pop();
|
||||
}
|
||||
|
||||
void SHCommandManager::PopLatestCommandFromUndoStack()
|
||||
{
|
||||
undoStack.pop();
|
||||
pCurrUndoStack->Pop();
|
||||
}
|
||||
|
||||
void SHCommandManager::SwapStacks()
|
||||
{
|
||||
if (pCurrUndoStack == &undoStack)
|
||||
{
|
||||
pCurrUndoStack = &secondaryUndoStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
secondaryUndoStack.Clear();
|
||||
pCurrUndoStack = &undoStack;
|
||||
}
|
||||
|
||||
if (pCurrRedoStack == &redoStack)
|
||||
{
|
||||
pCurrRedoStack = &secondaryRedoStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
secondaryRedoStack.Clear();
|
||||
pCurrRedoStack = &redoStack;
|
||||
}
|
||||
}
|
||||
|
||||
void SHCommandManager::ClearAll()
|
||||
{
|
||||
undoStack.Clear();
|
||||
redoStack.Clear();
|
||||
|
||||
secondaryUndoStack.Clear();
|
||||
secondaryRedoStack.Clear();
|
||||
}
|
||||
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//#==============================================================#
|
||||
#include "SHCommand.hpp"
|
||||
#include "SH_API.h"
|
||||
#include "Tools/SHDeque.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -22,7 +23,8 @@ namespace SHADE
|
|||
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||
template<typename T>
|
||||
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
|
||||
using CommandStack = std::stack<BaseCommandPtr>;
|
||||
using CommandStack = SHDeque<BaseCommandPtr>;
|
||||
using CommandStackPtr = CommandStack*;
|
||||
|
||||
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
|
||||
static void RegisterCommand(BaseCommandPtr commandPtr);
|
||||
|
@ -34,8 +36,17 @@ namespace SHADE
|
|||
static void PopLatestCommandFromRedoStack();
|
||||
static void PopLatestCommandFromUndoStack();
|
||||
|
||||
static void SwapStacks();
|
||||
static void ClearAll();
|
||||
|
||||
static constexpr CommandStack::SizeType defaultStackSize = 100;
|
||||
private:
|
||||
static CommandStackPtr pCurrUndoStack;
|
||||
static CommandStackPtr pCurrRedoStack;
|
||||
|
||||
static CommandStack undoStack;
|
||||
static CommandStack secondaryUndoStack;
|
||||
static CommandStack redoStack;
|
||||
static CommandStack secondaryRedoStack;
|
||||
};
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
namespace SHADE
|
||||
{
|
||||
SHAssetBrowser::SHAssetBrowser()
|
||||
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt)
|
||||
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -34,23 +34,48 @@ namespace SHADE
|
|||
RecursivelyDrawTree(rootFolder);
|
||||
DrawMenuBar();
|
||||
DrawCurrentFolder();
|
||||
DrawAssetBeingCreated();
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
if(refreshQueued)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SHAssetBrowser::QueueRefresh() noexcept
|
||||
{
|
||||
refreshQueued = true;
|
||||
}
|
||||
|
||||
void SHAssetBrowser::Refresh() noexcept
|
||||
{
|
||||
SHAssetManager::RefreshDirectory();
|
||||
rootFolder = SHAssetManager::GetRootFolder();
|
||||
refreshQueued = false;
|
||||
}
|
||||
|
||||
void SHAssetBrowser::DrawMenuBar()
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
|
||||
if(ImGui::SmallButton(ICON_MD_SYNC))
|
||||
{
|
||||
QueueRefresh();
|
||||
}
|
||||
if(ImGui::SmallButton(ICON_FA_CIRCLE_PLUS))
|
||||
{
|
||||
isAssetBeingCreated = true;
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
}
|
||||
|
||||
//if !compiled, set genMeta to true
|
||||
|
||||
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
|
||||
{
|
||||
auto const& subFolders = folder->subFolders;
|
||||
auto const& files = folder->files;
|
||||
auto files = folder->files;
|
||||
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
|
||||
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
|
||||
if (isSelected)
|
||||
|
@ -62,21 +87,10 @@ namespace SHADE
|
|||
ImGuiID folderID = ImGui::GetItemID();
|
||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if (ImGui::BeginMenu("Create Asset"))
|
||||
{
|
||||
//TODO: Change to rttr type enum align
|
||||
if (ImGui::Selectable("Material"))
|
||||
{
|
||||
assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" };
|
||||
ImGui::TreeNodeSetOpen(folderID, true);
|
||||
isOpen = true;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
//if (ImGui::BeginPopupContextItem())
|
||||
//{
|
||||
// ImGui::EndPopup();
|
||||
//}
|
||||
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
|
@ -100,19 +114,15 @@ namespace SHADE
|
|||
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||
vertLineEnd.y = midPoint;
|
||||
}
|
||||
for (auto const& file : files)
|
||||
for (auto& file : files)
|
||||
{
|
||||
if(file.assetMeta == nullptr)
|
||||
continue;
|
||||
const float horizontalLineSize = 25.0f;
|
||||
const ImRect childRect = DrawFile(file.assetMeta);
|
||||
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);
|
||||
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
|
||||
DrawAssetBeingCreated();
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
@ -148,7 +158,33 @@ namespace SHADE
|
|||
//}
|
||||
}
|
||||
|
||||
ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept
|
||||
ImRect SHAssetBrowser::DrawFile(SHFile& file) noexcept
|
||||
{
|
||||
if(file.compilable)
|
||||
{
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
|
||||
static constexpr std::string_view icon = ICON_MD_FILE_PRESENT;
|
||||
ImGui::PushID(file.name.data());
|
||||
bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data());
|
||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
if(ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if(ImGui::Selectable("Compile"))
|
||||
{
|
||||
SHAssetManager::CompileAsset(file.path, !file.compiled);
|
||||
QueueRefresh();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
ImGui::PopID();
|
||||
return nodeRect;
|
||||
}
|
||||
if(file.assetMeta)
|
||||
DrawAsset(file.assetMeta, file.ext);
|
||||
}
|
||||
|
||||
ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept
|
||||
{
|
||||
if (asset == nullptr)
|
||||
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
|
@ -173,7 +209,7 @@ namespace SHADE
|
|||
default:;
|
||||
}
|
||||
|
||||
bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data());
|
||||
bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s%s", icon.data(), asset->name.data(), ext.data());
|
||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
if (SHDragDrop::BeginSource())
|
||||
{
|
||||
|
@ -212,7 +248,6 @@ namespace SHADE
|
|||
case AssetType::MAX_COUNT: break;
|
||||
default:;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
||||
|
@ -227,7 +262,7 @@ namespace SHADE
|
|||
for(auto const& subAsset : asset->subAssets)
|
||||
{
|
||||
const float horizontalLineSize = 25.0f;
|
||||
const ImRect childRect = DrawFile(subAsset);
|
||||
const ImRect childRect = DrawAsset(subAsset);
|
||||
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;
|
||||
|
@ -240,19 +275,52 @@ namespace SHADE
|
|||
|
||||
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
|
||||
{
|
||||
if (!assetBeingCreated.has_value())
|
||||
return;
|
||||
auto& path = std::get<0>(assetBeingCreated.value());
|
||||
auto& type = std::get<1>(assetBeingCreated.value());
|
||||
auto& assetName = std::get<2>(assetBeingCreated.value());
|
||||
if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
if(isAssetBeingCreated)
|
||||
ImGui::OpenPopup(newAssetPopup.data());
|
||||
|
||||
if(ImGui::BeginPopupModal(newAssetPopup.data(), &isAssetBeingCreated))
|
||||
{
|
||||
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
|
||||
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||
ImGui::RadioButton("Material", true);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputText("##newAssetName", &nameOfAssetBeingCreated, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
|
||||
{
|
||||
matInspector->OpenMaterial(assetId, true);
|
||||
AssetID assetId = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, nameOfAssetBeingCreated);
|
||||
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||
{
|
||||
matInspector->OpenMaterial(assetId, true);
|
||||
}
|
||||
nameOfAssetBeingCreated.clear();
|
||||
QueueRefresh();
|
||||
isAssetBeingCreated = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
assetBeingCreated.reset();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
//if (ImGui::BeginMenu("Create Asset"))
|
||||
//{
|
||||
// //TODO: Change to rttr type enum align
|
||||
// if (ImGui::Selectable("Material"))
|
||||
// {
|
||||
// assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" };
|
||||
// ImGui::TreeNodeSetOpen(folderID, true);
|
||||
// isOpen = true;
|
||||
// }
|
||||
// ImGui::EndMenu();
|
||||
//}
|
||||
//if (!assetBeingCreated.has_value())
|
||||
// return;
|
||||
//auto& path = std::get<0>(assetBeingCreated.value());
|
||||
//auto& type = std::get<1>(assetBeingCreated.value());
|
||||
//auto& assetName = std::get<2>(assetBeingCreated.value());
|
||||
//if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
|
||||
//{
|
||||
// AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
|
||||
// if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||
// {
|
||||
// matInspector->OpenMaterial(assetId, true);
|
||||
// }
|
||||
// assetBeingCreated.reset();
|
||||
// QueueRefresh();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,24 +10,29 @@ namespace SHADE
|
|||
class SHAssetBrowser final : public SHEditorWindow
|
||||
{
|
||||
public:
|
||||
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
|
||||
SHAssetBrowser();
|
||||
|
||||
void Init();
|
||||
void Update();
|
||||
|
||||
void Refresh();
|
||||
void QueueRefresh() noexcept;
|
||||
private:
|
||||
void DrawMenuBar();
|
||||
ImRect RecursivelyDrawTree(FolderPointer folder);
|
||||
void DrawCurrentFolder();
|
||||
ImRect DrawFile(SHAsset const* const asset) noexcept;
|
||||
ImRect DrawFile(SHFile& file) noexcept;
|
||||
ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept;
|
||||
void DrawAssetBeingCreated() noexcept;
|
||||
|
||||
void Refresh() noexcept;
|
||||
|
||||
FolderPointer rootFolder, prevFolder, currentFolder;
|
||||
std::optional<AssetEntry> assetBeingCreated;
|
||||
std::vector<FolderPointer> selectedFolders;
|
||||
std::vector<AssetID> selectedAssets;
|
||||
static constexpr float tileWidth = 50.0f;
|
||||
bool refreshQueued = false;
|
||||
bool isAssetBeingCreated = false;
|
||||
static constexpr std::string_view newAssetPopup = "Create New Asset";
|
||||
std::string nameOfAssetBeingCreated;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -93,13 +93,14 @@ namespace SHADE
|
|||
{
|
||||
EntityID const& eid = editor->selectedEntities[0];
|
||||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||
if(!entity)
|
||||
SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid);
|
||||
if(!entity || !entityNode)
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||
SHEditorWidgets::CheckBox("##IsActive", [entityNode]()->bool {return entityNode->IsActive(); }, [entityNode](bool const& active) {entityNode->SetActive(active); });
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::InputText("##EntityName", &entity->name);
|
||||
|
|
|
@ -223,39 +223,20 @@ namespace SHADE
|
|||
{
|
||||
if(editor->SaveScene())
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::PLAY;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||
editor->Play();
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
||||
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::PAUSE;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
|
||||
editor->Pause();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
|
||||
if(ImGui::SmallButton(ICON_MD_STOP))
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::STOP;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||
editor->Stop();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndMenuBar();
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace SHADE
|
|||
shouldUpdateCamera = false;
|
||||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
|
||||
|
||||
if (Begin())
|
||||
{
|
||||
|
@ -51,7 +52,6 @@ namespace SHADE
|
|||
beginCursorPos = ImGui::GetCursorScreenPos();
|
||||
viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y };
|
||||
gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos);
|
||||
|
||||
ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y });
|
||||
|
||||
if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||
|
@ -64,24 +64,25 @@ namespace SHADE
|
|||
|
||||
shouldUpdateCamera = true;
|
||||
}
|
||||
if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||
if (editor->editorState != SHEditor::State::PLAY && ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||
{
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_Q))
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_W))
|
||||
{
|
||||
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||
}
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_W))
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_E))
|
||||
{
|
||||
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||
}
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_E))
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_R))
|
||||
{
|
||||
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||
transformGizmo.Draw();
|
||||
if(editor->editorState != SHEditor::State::PLAY)
|
||||
transformGizmo.Draw();
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
|
|
@ -168,7 +168,19 @@ namespace SHADE
|
|||
{
|
||||
SHCommandManager::UndoCommand();
|
||||
}
|
||||
|
||||
if(ImGui::IsKeyReleased(ImGuiKey_F5))
|
||||
{
|
||||
Play();
|
||||
}
|
||||
else if (ImGui::IsKeyReleased(ImGuiKey_F6))
|
||||
{
|
||||
Pause();
|
||||
}
|
||||
else if (ImGui::IsKeyReleased(ImGuiKey_F7))
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
|
@ -597,6 +609,48 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHEditor::Play()
|
||||
{
|
||||
if(editorState == State::PLAY)
|
||||
return;
|
||||
if (SaveScene())
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editorState
|
||||
};
|
||||
editorState = State::PLAY;
|
||||
SHCommandManager::SwapStacks();
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void SHEditor::Pause()
|
||||
{
|
||||
if (editorState == State::PAUSE)
|
||||
return;
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editorState
|
||||
};
|
||||
editorState = State::PAUSE;
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
|
||||
}
|
||||
|
||||
void SHEditor::Stop()
|
||||
{
|
||||
if (editorState == State::STOP)
|
||||
return;
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editorState
|
||||
};
|
||||
editorState = SHEditor::State::STOP;
|
||||
SHCommandManager::SwapStacks();
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||
}
|
||||
|
||||
void SHEditor::NewFrame()
|
||||
{
|
||||
SDL_Event event;
|
||||
|
|
|
@ -184,6 +184,10 @@ namespace SHADE
|
|||
|
||||
void LoadScene(AssetID const& assetID) noexcept;
|
||||
|
||||
void Play();
|
||||
void Pause();
|
||||
void Stop();
|
||||
|
||||
// List of selected entities
|
||||
std::vector<EntityID> selectedEntities;
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace SHADE
|
|||
|
||||
for (auto* child : children)
|
||||
{
|
||||
SetActive(newActiveState);
|
||||
child->SetActive(newActiveState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "SH_API.h"
|
||||
#include <deque>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
template<typename T>
|
||||
class SH_API SHDeque
|
||||
{
|
||||
public:
|
||||
using ValueType = T;
|
||||
using Pointer = T*;
|
||||
using ValueRef = T&;
|
||||
using ValueConstRef = T const&;
|
||||
using SizeType = uint32_t;
|
||||
using ContainerType = std::deque<ValueType>;
|
||||
using ContainerTypeConstRef = std::deque<ValueType>;
|
||||
|
||||
SHDeque(SizeType n) : max_size(n) {}
|
||||
|
||||
ContainerTypeConstRef const& GetDeque() const
|
||||
{
|
||||
return deque;
|
||||
}
|
||||
|
||||
void Push(ValueConstRef obj)
|
||||
{
|
||||
if (deque.size() < max_size)
|
||||
deque.push_front(std::move(obj));
|
||||
else
|
||||
{
|
||||
deque.pop_back();
|
||||
deque.push_front(std::move(obj));
|
||||
}
|
||||
}
|
||||
|
||||
bool Empty()
|
||||
{
|
||||
return deque.empty();
|
||||
}
|
||||
|
||||
void Pop()
|
||||
{
|
||||
deque.pop_front();
|
||||
}
|
||||
|
||||
ValueConstRef Top()
|
||||
{
|
||||
return deque.front();
|
||||
}
|
||||
|
||||
SizeType Size() const noexcept
|
||||
{
|
||||
return deque.size();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
deque.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
int max_size;
|
||||
ContainerType deque{};
|
||||
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue