Add XCUI runtime screen stack helper
This commit is contained in:
@@ -522,6 +522,7 @@ add_library(XCEngine STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/UI/Runtime/UISystem.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UI/Runtime/UIScreenDocumentHost.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UI/Runtime/UIScreenPlayer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UI/Runtime/UIScreenStackController.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UI/Runtime/UISystem.cpp
|
||||
|
||||
# Input
|
||||
@@ -587,6 +588,9 @@ target_link_libraries(XCEngine PUBLIC
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(XCEngine PRIVATE
|
||||
/FS
|
||||
$<$<CONFIG:Debug,RelWithDebInfo>:/Z7>)
|
||||
target_link_libraries(XCEngine PUBLIC delayimp)
|
||||
target_link_options(XCEngine INTERFACE "/DELAYLOAD:assimp-vc143-mt.dll")
|
||||
set_target_properties(XCEngine PROPERTIES
|
||||
|
||||
54
engine/include/XCEngine/UI/Runtime/UIScreenStackController.h
Normal file
54
engine/include/XCEngine/UI/Runtime/UIScreenStackController.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/UI/Runtime/UISystem.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace UI {
|
||||
namespace Runtime {
|
||||
|
||||
struct UIScreenStackEntry {
|
||||
UIScreenLayerId layerId = 0;
|
||||
UIScreenAsset asset = {};
|
||||
UIScreenLayerOptions options = {};
|
||||
};
|
||||
|
||||
class UIScreenStackController {
|
||||
public:
|
||||
explicit UIScreenStackController(UISystem& system);
|
||||
|
||||
UIScreenLayerId PushScreen(
|
||||
const UIScreenAsset& asset,
|
||||
const UIScreenLayerOptions& options = UIScreenLayerOptions());
|
||||
UIScreenLayerId PushMenu(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& debugName = {});
|
||||
UIScreenLayerId PushModal(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& debugName = {});
|
||||
UIScreenLayerId PushHud(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& debugName = {});
|
||||
|
||||
bool ReplaceTop(
|
||||
const UIScreenAsset& asset,
|
||||
const UIScreenLayerOptions& options = UIScreenLayerOptions());
|
||||
bool Pop();
|
||||
bool Remove(UIScreenLayerId layerId);
|
||||
void Clear();
|
||||
|
||||
std::size_t GetEntryCount() const;
|
||||
const UIScreenStackEntry* GetTop() const;
|
||||
const std::vector<UIScreenStackEntry>& GetEntries() const;
|
||||
|
||||
private:
|
||||
UISystem* m_system = nullptr;
|
||||
std::vector<UIScreenStackEntry> m_entries = {};
|
||||
};
|
||||
|
||||
} // namespace Runtime
|
||||
} // namespace UI
|
||||
} // namespace XCEngine
|
||||
148
engine/src/UI/Runtime/UIScreenStackController.cpp
Normal file
148
engine/src/UI/Runtime/UIScreenStackController.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include <XCEngine/UI/Runtime/UIScreenStackController.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace UI {
|
||||
namespace Runtime {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string ResolveDebugName(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& fallbackName,
|
||||
const std::string& explicitName) {
|
||||
if (!explicitName.empty()) {
|
||||
return explicitName;
|
||||
}
|
||||
if (!asset.screenId.empty()) {
|
||||
return asset.screenId;
|
||||
}
|
||||
return fallbackName;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
UIScreenStackController::UIScreenStackController(UISystem& system)
|
||||
: m_system(&system) {
|
||||
}
|
||||
|
||||
UIScreenLayerId UIScreenStackController::PushScreen(
|
||||
const UIScreenAsset& asset,
|
||||
const UIScreenLayerOptions& options) {
|
||||
const UIScreenLayerId layerId = m_system != nullptr
|
||||
? m_system->PushScreen(asset, options)
|
||||
: 0;
|
||||
if (layerId == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UIScreenStackEntry entry = {};
|
||||
entry.layerId = layerId;
|
||||
entry.asset = asset;
|
||||
entry.options = options;
|
||||
m_entries.push_back(std::move(entry));
|
||||
return layerId;
|
||||
}
|
||||
|
||||
UIScreenLayerId UIScreenStackController::PushMenu(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& debugName) {
|
||||
UIScreenLayerOptions options = {};
|
||||
options.debugName = ResolveDebugName(asset, "Menu", debugName);
|
||||
options.acceptsInput = true;
|
||||
options.blocksLayersBelow = true;
|
||||
return PushScreen(asset, options);
|
||||
}
|
||||
|
||||
UIScreenLayerId UIScreenStackController::PushModal(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& debugName) {
|
||||
UIScreenLayerOptions options = {};
|
||||
options.debugName = ResolveDebugName(asset, "Modal", debugName);
|
||||
options.acceptsInput = true;
|
||||
options.blocksLayersBelow = true;
|
||||
return PushScreen(asset, options);
|
||||
}
|
||||
|
||||
UIScreenLayerId UIScreenStackController::PushHud(
|
||||
const UIScreenAsset& asset,
|
||||
const std::string& debugName) {
|
||||
UIScreenLayerOptions options = {};
|
||||
options.debugName = ResolveDebugName(asset, "HUD", debugName);
|
||||
options.acceptsInput = false;
|
||||
options.blocksLayersBelow = false;
|
||||
return PushScreen(asset, options);
|
||||
}
|
||||
|
||||
bool UIScreenStackController::ReplaceTop(
|
||||
const UIScreenAsset& asset,
|
||||
const UIScreenLayerOptions& options) {
|
||||
if (m_entries.empty()) {
|
||||
return PushScreen(asset, options) != 0;
|
||||
}
|
||||
|
||||
if (!Pop()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return PushScreen(asset, options) != 0;
|
||||
}
|
||||
|
||||
bool UIScreenStackController::Pop() {
|
||||
if (m_system == nullptr || m_entries.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const UIScreenLayerId layerId = m_entries.back().layerId;
|
||||
if (!m_system->RemoveLayer(layerId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_entries.pop_back();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UIScreenStackController::Remove(UIScreenLayerId layerId) {
|
||||
if (m_system == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::size_t index = 0; index < m_entries.size(); ++index) {
|
||||
if (m_entries[index].layerId != layerId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_system->RemoveLayer(layerId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_entries.erase(m_entries.begin() + static_cast<std::ptrdiff_t>(index));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UIScreenStackController::Clear() {
|
||||
if (m_system != nullptr) {
|
||||
m_system->DestroyAllPlayers();
|
||||
}
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
std::size_t UIScreenStackController::GetEntryCount() const {
|
||||
return m_entries.size();
|
||||
}
|
||||
|
||||
const UIScreenStackEntry* UIScreenStackController::GetTop() const {
|
||||
return m_entries.empty() ? nullptr : &m_entries.back();
|
||||
}
|
||||
|
||||
const std::vector<UIScreenStackEntry>& UIScreenStackController::GetEntries() const {
|
||||
return m_entries;
|
||||
}
|
||||
|
||||
} // namespace Runtime
|
||||
} // namespace UI
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user