165 lines
4.1 KiB
C++
165 lines
4.1 KiB
C++
#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 (m_system == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
const UIScreenStackEntry previousTop = m_entries.back();
|
|
const UIScreenLayerId replacementLayerId = m_system->PushScreen(asset, options);
|
|
if (replacementLayerId == 0) {
|
|
return false;
|
|
}
|
|
|
|
if (!m_system->RemoveLayer(previousTop.layerId)) {
|
|
m_system->RemoveLayer(replacementLayerId);
|
|
return false;
|
|
}
|
|
|
|
UIScreenStackEntry replacementEntry = {};
|
|
replacementEntry.layerId = replacementLayerId;
|
|
replacementEntry.asset = asset;
|
|
replacementEntry.options = options;
|
|
m_entries.back() = std::move(replacementEntry);
|
|
return true;
|
|
}
|
|
|
|
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
|