mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Split off ScreenManager from Screen.cpp
This commit is contained in:
1 parent
e59aa11987
commit
7219cd2f5a
43 files changed
+691
-627
No files matched your search
@@ -281,6 +281,8 @@ add_library(Common STATIC
|
||||
UI/Root.h
|
||||
UI/Screen.cpp
|
||||
UI/Screen.h
|
||||
UI/ScreenManager.cpp
|
||||
UI/ScreenManager.h
|
||||
UI/UI.cpp
|
||||
UI/UI.h
|
||||
UI/Context.cpp
|
||||
|
||||
@@ -562,6 +562,7 @@
|
||||
<ClInclude Include="UI\PopupScreens.h" />
|
||||
<ClInclude Include="UI\Root.h" />
|
||||
<ClInclude Include="UI\Screen.h" />
|
||||
<ClInclude Include="UI\ScreenManager.h" />
|
||||
<ClInclude Include="UI\ScrollView.h" />
|
||||
<ClInclude Include="UI\TabHolder.h" />
|
||||
<ClInclude Include="UI\Tween.h" />
|
||||
@@ -1022,6 +1023,7 @@
|
||||
<ClCompile Include="UI\PopupScreens.cpp" />
|
||||
<ClCompile Include="UI\Root.cpp" />
|
||||
<ClCompile Include="UI\Screen.cpp" />
|
||||
<ClCompile Include="UI\ScreenManager.cpp" />
|
||||
<ClCompile Include="UI\ScrollView.cpp" />
|
||||
<ClCompile Include="UI\TabHolder.cpp" />
|
||||
<ClCompile Include="UI\Tween.cpp" />
|
||||
|
||||
@@ -798,6 +798,9 @@
|
||||
<ClInclude Include="GPU\OpenGL\OpenGLGraphicsContext.h">
|
||||
<Filter>GPU\OpenGL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UI\ScreenManager.h">
|
||||
<Filter>UI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
@@ -1472,6 +1475,9 @@
|
||||
<ClCompile Include="GPU\OpenGL\OpenGLGraphicsContext.cpp">
|
||||
<Filter>GPU\OpenGL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UI\ScreenManager.cpp">
|
||||
<Filter>UI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Crypto">
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/System/System.h"
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/Input/InputState.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/UI/Screen.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/Data/Collections/TinySet.h"
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
|
||||
void Screen::focusChanged(ScreenFocusChange focusChange) {
|
||||
const char *eventName = "";
|
||||
@@ -50,489 +41,6 @@ Screen::~Screen() {
|
||||
}
|
||||
}
|
||||
|
||||
ScreenManager::~ScreenManager() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void ScreenManager::switchScreen(Screen *screen) {
|
||||
if (!screen) {
|
||||
ERROR_LOG(Log::UI, "Can't switch to empty screen");
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_LOG(Log::UI, "ScreenManager::switchScreen('%s')", screen->tag());
|
||||
|
||||
if (!nextStack_.empty() && screen == nextStack_.front().screen) {
|
||||
ERROR_LOG(Log::UI, "Already switching to this screen");
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that if a dialog is found, this will be a silent background switch that
|
||||
// will only become apparent if the dialog is closed. The previous screen will stick around
|
||||
// until that switch.
|
||||
// TODO: is this still true?
|
||||
if (!nextStack_.empty()) {
|
||||
for (int i = 0; i < nextStack_.size(); i++) {
|
||||
INFO_LOG(Log::UI, "NextStack contents[%d].screen->tag(): '%s'", i, nextStack_[i].screen->tag());
|
||||
}
|
||||
|
||||
ERROR_LOG(Log::UI, "Already had a nextStack_! Asynchronous open while doing something? Deleting the new screen.");
|
||||
delete screen;
|
||||
return;
|
||||
}
|
||||
if (screen == nullptr) {
|
||||
WARN_LOG(Log::UI, "Switching to a zero screen, this can't be good");
|
||||
}
|
||||
if (stack_.empty() || screen != stack_.back().screen) {
|
||||
if (screen) {
|
||||
screen->setScreenManager(this);
|
||||
}
|
||||
nextStack_.push_back({ screen, 0 });
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::cancelScreensAbove(Screen *screen) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < stack_.size(); i++) {
|
||||
if (stack_[i].screen == screen) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
cancelScreensAbove_ = screen;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::update() {
|
||||
if (cancelScreensAbove_) {
|
||||
bool found = false;
|
||||
for (int i = (int)stack_.size() - 1; i >= 0; i--) {
|
||||
if (stack_[i].screen == cancelScreensAbove_) {
|
||||
break;
|
||||
}
|
||||
Layer temp = stack_.back();
|
||||
stack_.pop_back();
|
||||
delete temp.screen;
|
||||
}
|
||||
cancelScreensAbove_ = nullptr;
|
||||
}
|
||||
|
||||
if (!nextStack_.empty()) {
|
||||
switchToNext();
|
||||
}
|
||||
|
||||
if (overlayScreen_) {
|
||||
// NOTE: This is not a full UIScreen update, to avoid double global event processing.
|
||||
overlayScreen_->update();
|
||||
}
|
||||
|
||||
// Process queued events.
|
||||
std::deque<QueuedEvent> events;
|
||||
{
|
||||
std::lock_guard<std::mutex> eventGuard(eventQueueLock_);
|
||||
events = std::move(eventQueue_);
|
||||
eventQueue_.clear();
|
||||
}
|
||||
|
||||
for (const QueuedEvent &ev : events) {
|
||||
switch (ev.type) {
|
||||
case QueuedEventType::TOUCH:
|
||||
{
|
||||
const TouchInput &touch = ev.touch;
|
||||
// Send release all events to every screen layer.
|
||||
if (touch.flags & TouchInputFlags::RELEASE_ALL) {
|
||||
for (auto &layer : stack_) {
|
||||
Screen *screen = layer.screen;
|
||||
layer.screen->touch(screen->transformTouch(touch));
|
||||
}
|
||||
} else if (!stack_.empty()) {
|
||||
// Let the overlay know about touch-downs, to be able to dismiss popups.
|
||||
bool skip = false;
|
||||
if (overlayScreen_ && (touch.flags & TouchInputFlags::DOWN)) {
|
||||
skip = overlayScreen_->touch(overlayScreen_->transformTouch(touch));
|
||||
}
|
||||
if (!skip) {
|
||||
Screen *screen = stack_.back().screen;
|
||||
stack_.back().screen->touch(screen->transformTouch(touch));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QueuedEventType::KEY:
|
||||
{
|
||||
const KeyInput &key = ev.key;
|
||||
// Send key up to every screen layer, to avoid stuck keys.
|
||||
if (key.flags & KeyInputFlags::UP) {
|
||||
for (auto &layer : stack_) {
|
||||
layer.screen->key(key);
|
||||
}
|
||||
} else if (!stack_.empty()) {
|
||||
stack_.back().screen->key(key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QueuedEventType::AXIS:
|
||||
{
|
||||
const AxisInput &axis = ev.axis;
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->axis(axis);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERROR_LOG(Log::UI, "Unknown queued event type: %d", (int)ev.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only the front screen gets update().
|
||||
if (!stack_.empty()) {
|
||||
Screen *backScreen = stack_.back().screen;
|
||||
backScreen->update();
|
||||
passInputToMapper_ = backScreen->PassInputToMapper();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::switchToNext() {
|
||||
if (nextStack_.empty()) {
|
||||
ERROR_LOG(Log::System, "switchToNext: No nextStack_!");
|
||||
}
|
||||
|
||||
Layer temp = {nullptr, 0};
|
||||
if (!stack_.empty()) {
|
||||
temp = stack_.back();
|
||||
temp.screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
stack_.pop_back();
|
||||
}
|
||||
stack_.push_back(nextStack_.front());
|
||||
nextStack_.front().screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP);
|
||||
delete temp.screen;
|
||||
UI::SetFocusedView(nullptr, UI::FocusFlags::CAUSE_SCREEN_CHANGE);
|
||||
|
||||
// When will this ever happen? Should handle focus here too?
|
||||
for (size_t i = 1; i < nextStack_.size(); ++i) {
|
||||
stack_.push_back(nextStack_[i]);
|
||||
}
|
||||
nextStack_.clear();
|
||||
}
|
||||
|
||||
void ScreenManager::touch(const TouchInput &touch) {
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::TOUCH;
|
||||
ev.touch = touch;
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
eventQueue_.push_back(ev);
|
||||
}
|
||||
|
||||
void ScreenManager::key(const KeyInput &key) {
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::KEY;
|
||||
ev.key = key;
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
eventQueue_.push_back(ev);
|
||||
}
|
||||
|
||||
void ScreenManager::axis(const AxisInput *axes, size_t count) {
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::AXIS;
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ev.axis = axes[i];
|
||||
eventQueue_.push_back(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::deviceLost() {
|
||||
for (auto &iter : stack_)
|
||||
iter.screen->deviceLost();
|
||||
}
|
||||
|
||||
void ScreenManager::deviceRestored(Draw::DrawContext *draw) {
|
||||
draw_ = draw;
|
||||
for (auto &iter : stack_)
|
||||
iter.screen->deviceRestored(draw);
|
||||
}
|
||||
|
||||
void ScreenManager::resized() {
|
||||
INFO_LOG(Log::UI, "ScreenManager::resized(g_display.dp_xres/dp_yres: %dx%d)", g_display.dp_xres, g_display.dp_yres);
|
||||
// Have to notify the whole stack, otherwise there will be problems when going back
|
||||
// to non-top screens.
|
||||
for (auto &layer : stack_) {
|
||||
layer.screen->resized();
|
||||
}
|
||||
}
|
||||
|
||||
ScreenRenderFlags ScreenManager::render() {
|
||||
using namespace Draw;
|
||||
|
||||
ScreenRenderFlags flags = ScreenRenderFlags::NONE;
|
||||
|
||||
// First, go through the whole stack and have every screen render any non-backbuffer render passes.
|
||||
// In EmuScreen, this might result in running emulation.
|
||||
for (size_t i = 0; i < stack_.size(); i++) {
|
||||
const auto &layer = stack_[i];
|
||||
ScreenRenderMode mode = ScreenRenderMode::DEFAULT;
|
||||
if (i == stack_.size() - 1) {
|
||||
mode |= ScreenRenderMode::TOP;
|
||||
}
|
||||
flags |= layer.screen->PreRender(mode);
|
||||
}
|
||||
|
||||
// Now, start the final render pass. This is now the ONLY place where binding the null fb is allowed.
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, {RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR}, "BackBuffer");
|
||||
getUIContext()->BeginFrame();
|
||||
|
||||
const Draw::Viewport viewport{0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f};
|
||||
draw_->SetViewport(viewport);
|
||||
draw_->SetScissorRect(0, 0, g_display.pixel_xres, g_display.pixel_yres);
|
||||
draw_->SetTargetSize(g_display.pixel_xres, g_display.pixel_yres);
|
||||
|
||||
if (!stack_.empty()) {
|
||||
// Collect the screens to render
|
||||
TinySet<Screen *, 6> layers;
|
||||
|
||||
// Start at the end, collect screens to form the transparency stack.
|
||||
// Then we'll iterate them in reverse order.
|
||||
// Note that we skip the overlay screen, we handle it separately.
|
||||
// Additionally, we pick up a "background" screen. Normally it will be either
|
||||
// the EmuScreen or the actual global background screen.
|
||||
auto iter = stack_.end();
|
||||
Screen *coveringScreen = nullptr;
|
||||
Screen *foundBackgroundScreen = nullptr;
|
||||
bool first = true;
|
||||
|
||||
do {
|
||||
--iter;
|
||||
ScreenRenderRole role = iter->screen->renderRole(first);
|
||||
if (!foundBackgroundScreen && (role & ScreenRenderRole::CAN_BE_BACKGROUND)) {
|
||||
// There still might be a screen that wants to be background - generally the EmuScreen if present.
|
||||
layers.push_back(iter->screen);
|
||||
foundBackgroundScreen = iter->screen;
|
||||
} else if (!coveringScreen) {
|
||||
layers.push_back(iter->screen);
|
||||
}
|
||||
if (iter->flags != LAYER_TRANSPARENT) {
|
||||
coveringScreen = iter->screen;
|
||||
}
|
||||
first = false;
|
||||
if (role & ScreenRenderRole::MUST_BE_FIRST) {
|
||||
break;
|
||||
}
|
||||
} while (iter != stack_.begin());
|
||||
|
||||
if (backgroundScreen_ && !foundBackgroundScreen) {
|
||||
layers.push_back(backgroundScreen_);
|
||||
foundBackgroundScreen = backgroundScreen_;
|
||||
}
|
||||
|
||||
// OK, now we iterate backwards over our little pile of collected screens.
|
||||
for (int i = (int)layers.size() - 1; i >= 0; i--) {
|
||||
ScreenRenderMode mode = ScreenRenderMode::DEFAULT;
|
||||
if (i == (int)layers.size() - 1) {
|
||||
// Bottom.
|
||||
mode = ScreenRenderMode::FIRST;
|
||||
if (i == 0) {
|
||||
mode |= ScreenRenderMode::TOP;
|
||||
}
|
||||
} else if (i == 0) {
|
||||
mode = ScreenRenderMode::TOP;
|
||||
} else {
|
||||
mode = ScreenRenderMode::BEHIND;
|
||||
}
|
||||
flags |= layers[i]->render(mode);
|
||||
}
|
||||
|
||||
if (overlayScreen_) {
|
||||
// It doesn't care about mode.
|
||||
flags |= overlayScreen_->render(ScreenRenderMode::TOP);
|
||||
}
|
||||
|
||||
getUIContext()->Flush();
|
||||
|
||||
if (postRenderCb_) {
|
||||
// Really can't render anything after this! Will crash the screenshot mechanism if we do.
|
||||
postRenderCb_(getUIContext(), postRenderUserdata_);
|
||||
}
|
||||
} else {
|
||||
ERROR_LOG(Log::UI, "No current screen!");
|
||||
}
|
||||
|
||||
processFinishDialog();
|
||||
return flags;
|
||||
}
|
||||
|
||||
void ScreenManager::getFocusPosition(float &x, float &y, float &z) {
|
||||
UI::ScrollView::GetLastScrollPosition(x, y);
|
||||
|
||||
UI::View *v = UI::GetFocusedView();
|
||||
x += v ? v->GetBounds().x : 0;
|
||||
y += v ? v->GetBounds().y : 0;
|
||||
z = stack_.size();
|
||||
}
|
||||
|
||||
void ScreenManager::sendMessage(UIMessage message, const char *value) {
|
||||
if (message == UIMessage::RECREATE_VIEWS) {
|
||||
RecreateAllViews();
|
||||
} else if (message == UIMessage::LOST_FOCUS) {
|
||||
TouchInput input{};
|
||||
input.x = -50000.0f;
|
||||
input.y = -50000.0f;
|
||||
input.flags = TouchInputFlags::RELEASE_ALL;
|
||||
input.timestamp = time_now_d();
|
||||
input.id = 0;
|
||||
touch(input);
|
||||
}
|
||||
|
||||
if (backgroundScreen_) {
|
||||
backgroundScreen_->sendMessage(message, value);
|
||||
}
|
||||
|
||||
// NOTE: Changed this to send the message to all screens, instead of just the top one,
|
||||
// to allow EmuScreen to receive messages from popup menus. Hope this didn't break anything..
|
||||
// NOTE: We do not use the iterator solution here, because the screen array may change by sendMessage!
|
||||
// Although if it does, that's very bad.
|
||||
// We also pick out the stack size before, so we don't get infinite growth if a screen is pushed from the handler.
|
||||
// We probably should delay pushes, though...
|
||||
const size_t stack_size = stack_.size();
|
||||
for (int i = 0; i < stack_size; i++) {
|
||||
if (stack_[i].screen) {
|
||||
stack_[i].screen->sendMessage(message, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::shutdown() {
|
||||
for (const auto &layer : stack_)
|
||||
delete layer.screen;
|
||||
stack_.clear();
|
||||
for (const auto &layer : nextStack_)
|
||||
delete layer.screen;
|
||||
nextStack_.clear();
|
||||
delete overlayScreen_;
|
||||
overlayScreen_ = nullptr;
|
||||
delete backgroundScreen_;
|
||||
backgroundScreen_ = nullptr;
|
||||
}
|
||||
|
||||
void ScreenManager::push(Screen *screen, int layerFlags) {
|
||||
screen->setScreenManager(this);
|
||||
if (screen->isTransparent()) {
|
||||
layerFlags |= LAYER_TRANSPARENT;
|
||||
}
|
||||
|
||||
// Release touches and unfocus.
|
||||
UI::SetFocusedView(nullptr, UI::FocusFlags::CAUSE_SCREEN_CHANGE);
|
||||
TouchInput input{};
|
||||
input.x = -50000.0f;
|
||||
input.y = -50000.0f;
|
||||
input.flags = TouchInputFlags::RELEASE_ALL;
|
||||
input.timestamp = time_now_d();
|
||||
input.id = 0;
|
||||
touch(input);
|
||||
|
||||
Layer layer = {screen, layerFlags};
|
||||
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
}
|
||||
|
||||
if (nextStack_.empty()) {
|
||||
layer.screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP);
|
||||
stack_.push_back(layer);
|
||||
} else {
|
||||
nextStack_.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::pop() {
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
|
||||
delete stack_.back().screen;
|
||||
stack_.pop_back();
|
||||
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
}
|
||||
} else {
|
||||
ERROR_LOG(Log::UI, "Can't pop when stack empty");
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::RecreateAllViews() {
|
||||
for (auto &layer : stack_) {
|
||||
layer.screen->RecreateViews();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::finishDialog(Screen *dialog, DialogResult result) {
|
||||
if (stack_.empty()) {
|
||||
ERROR_LOG(Log::UI, "Must be in a dialog to finishDialog");
|
||||
return;
|
||||
}
|
||||
if (dialog != stack_.back().screen) {
|
||||
ERROR_LOG(Log::UI, "Wrong dialog being finished!");
|
||||
return;
|
||||
}
|
||||
dialog->onFinish(result);
|
||||
dialogFinished_ = dialog;
|
||||
dialogResult_ = result;
|
||||
}
|
||||
|
||||
Screen *ScreenManager::dialogParent(const Screen *dialog) const {
|
||||
for (size_t i = 1; i < stack_.size(); ++i) {
|
||||
if (stack_[i].screen == dialog) {
|
||||
// The previous screen was the caller (not necessarily the topmost.)
|
||||
return stack_[i - 1].screen;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ScreenManager::processFinishDialog() {
|
||||
if (dialogFinished_) {
|
||||
{
|
||||
// Another dialog may have been pushed before the render, so search for it.
|
||||
Screen *caller = dialogParent(dialogFinished_);
|
||||
bool erased = false;
|
||||
for (size_t i = 0; i < stack_.size(); ++i) {
|
||||
if (stack_[i].screen == dialogFinished_) {
|
||||
stack_[i].screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
stack_.erase(stack_.begin() + i);
|
||||
erased = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (erased && !stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP);
|
||||
}
|
||||
|
||||
if (!caller) {
|
||||
ERROR_LOG(Log::UI, "ERROR: no top screen when finishing dialog");
|
||||
} else if (caller != topScreen()) {
|
||||
// The caller may get confused if we call dialogFinished() now.
|
||||
WARN_LOG(Log::UI, "Skipping non-top dialog when finishing dialog.");
|
||||
} else {
|
||||
caller->dialogFinished(dialogFinished_, dialogResult_);
|
||||
}
|
||||
}
|
||||
delete dialogFinished_;
|
||||
dialogFinished_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::SetBackgroundOverlayScreens(Screen *backgroundScreen, Screen *overlayScreen) {
|
||||
delete backgroundScreen_;
|
||||
backgroundScreen_ = backgroundScreen;
|
||||
backgroundScreen_->setScreenManager(this);
|
||||
|
||||
delete overlayScreen_;
|
||||
overlayScreen_ = overlayScreen;
|
||||
overlayScreen_->setScreenManager(this);
|
||||
}
|
||||
|
||||
const char *DialogResultToString(DialogResult result) {
|
||||
switch (result) {
|
||||
case DR_NONE: return "DR_NONE";
|
||||
|
||||
+20
-132
@@ -14,11 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Input/InputState.h"
|
||||
@@ -28,6 +24,10 @@ namespace UI {
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace Draw {
|
||||
class DrawContext;
|
||||
}
|
||||
|
||||
enum DialogResult {
|
||||
DR_NONE,
|
||||
DR_OK,
|
||||
@@ -41,10 +41,6 @@ const char *DialogResultToString(DialogResult result);
|
||||
class ScreenManager;
|
||||
class UIContext;
|
||||
|
||||
namespace Draw {
|
||||
class DrawContext;
|
||||
}
|
||||
|
||||
enum class ScreenFocusChange {
|
||||
FOCUS_LOST_TOP, // Another screen was pushed on top
|
||||
FOCUS_BECAME_TOP, // Became the top screen again
|
||||
@@ -58,12 +54,6 @@ enum class ScreenRenderMode {
|
||||
};
|
||||
ENUM_CLASS_BITOPS(ScreenRenderMode);
|
||||
|
||||
enum class ScreenRenderFlags {
|
||||
NONE = 0,
|
||||
HANDLED_THROTTLING = 1,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(ScreenRenderFlags);
|
||||
|
||||
enum class ScreenRenderRole {
|
||||
NONE = 0,
|
||||
CAN_BE_BACKGROUND = 1,
|
||||
@@ -77,15 +67,6 @@ enum class ViewLayoutMode {
|
||||
IgnoreBottomInset,
|
||||
};
|
||||
|
||||
enum class InputMode {
|
||||
None = 0,
|
||||
Keyboard = 1,
|
||||
Mouse = 2,
|
||||
Other = 4,
|
||||
ImDebuggerToggle = 8, // ugly hack. debugger and pause goes through.
|
||||
};
|
||||
ENUM_CLASS_BITOPS(InputMode);
|
||||
|
||||
enum class QueuedEventType : u8 {
|
||||
KEY,
|
||||
AXIS,
|
||||
@@ -101,6 +82,21 @@ struct QueuedEvent {
|
||||
};
|
||||
};
|
||||
|
||||
enum class ScreenRenderFlags {
|
||||
NONE = 0,
|
||||
HANDLED_THROTTLING = 1,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(ScreenRenderFlags);
|
||||
|
||||
enum class InputMode {
|
||||
None = 0,
|
||||
Keyboard = 1,
|
||||
Mouse = 2,
|
||||
Other = 4,
|
||||
ImDebuggerToggle = 8, // ugly hack. debugger and pause goes through.
|
||||
};
|
||||
ENUM_CLASS_BITOPS(InputMode);
|
||||
|
||||
class Screen {
|
||||
public:
|
||||
Screen() = default;
|
||||
@@ -126,8 +122,7 @@ public:
|
||||
|
||||
virtual void RecreateViews() {}
|
||||
|
||||
// NOTE: This is polled every frame, not called on every input event. This is
|
||||
// a step towards eventually removing the ScreenManager input mutex.
|
||||
// NOTE: This is polled every frame, not called on every input event.
|
||||
virtual InputMode PassInputToMapper() const { return InputMode::None; }
|
||||
|
||||
ScreenManager *screenManager() { return screenManager_; }
|
||||
@@ -154,110 +149,3 @@ private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Screen);
|
||||
};
|
||||
|
||||
class Transition {
|
||||
public:
|
||||
Transition() = default;
|
||||
};
|
||||
|
||||
enum {
|
||||
LAYER_TRANSPARENT = 2,
|
||||
};
|
||||
|
||||
typedef void (*PostRenderCallback)(UIContext *ui, void *userdata);
|
||||
|
||||
class ScreenManager {
|
||||
public:
|
||||
virtual ~ScreenManager();
|
||||
|
||||
void switchScreen(Screen *screen);
|
||||
void update();
|
||||
|
||||
void setUIContext(UIContext *context) { uiContext_ = context; }
|
||||
UIContext *getUIContext() { return uiContext_; }
|
||||
Draw::DrawContext *getDrawContext() { return draw_; }
|
||||
|
||||
void setPostRenderCallback(PostRenderCallback cb, void *userdata) {
|
||||
postRenderCb_ = cb;
|
||||
postRenderUserdata_ = userdata;
|
||||
}
|
||||
|
||||
ScreenRenderFlags render();
|
||||
void resized();
|
||||
void shutdown();
|
||||
|
||||
void deviceLost();
|
||||
void deviceRestored(Draw::DrawContext *draw);
|
||||
|
||||
// Push a dialog box in front. Currently 1-level only.
|
||||
void push(Screen *screen, int layerFlags = 0);
|
||||
|
||||
// Recreate all views
|
||||
void RecreateAllViews();
|
||||
|
||||
// Pops the dialog away.
|
||||
void finishDialog(Screen *dialog, DialogResult result = DR_OK);
|
||||
Screen *dialogParent(const Screen *dialog) const;
|
||||
|
||||
// Instant touch, separate from the update() mechanism.
|
||||
void touch(const TouchInput &touch);
|
||||
void key(const KeyInput &key);
|
||||
void axis(const AxisInput *axes, size_t count);
|
||||
|
||||
void sendMessage(UIMessage message, const char *value);
|
||||
|
||||
const Screen *topScreen() const {
|
||||
return stack_.empty() ? nullptr : stack_.back().screen;
|
||||
}
|
||||
Screen *topScreen() {
|
||||
return stack_.empty() ? nullptr : stack_.back().screen;
|
||||
}
|
||||
|
||||
void cancelScreensAbove(Screen *screen);
|
||||
|
||||
void getFocusPosition(float &x, float &y, float &z);
|
||||
|
||||
// Will delete any existing overlay screen.
|
||||
void SetBackgroundOverlayScreens(Screen *backgroundScreen, Screen *overlayScreen);
|
||||
|
||||
InputMode PassInputToMapper() const {
|
||||
return passInputToMapper_;
|
||||
}
|
||||
|
||||
private:
|
||||
void pop();
|
||||
void switchToNext();
|
||||
void processFinishDialog();
|
||||
|
||||
UIContext *uiContext_ = nullptr;
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
|
||||
PostRenderCallback postRenderCb_ = nullptr;
|
||||
void *postRenderUserdata_ = nullptr;
|
||||
|
||||
const Screen *dialogFinished_ = nullptr;
|
||||
DialogResult dialogResult_{};
|
||||
|
||||
Screen *backgroundScreen_ = nullptr;
|
||||
Screen *overlayScreen_ = nullptr;
|
||||
|
||||
Screen *cancelScreensAbove_ = nullptr;
|
||||
|
||||
struct Layer {
|
||||
Screen *screen;
|
||||
int flags; // From LAYER_ enum above
|
||||
UI::View *focusedView; // TODO: save focus here. Going for quick solution now to reset focus.
|
||||
};
|
||||
|
||||
// Dialog stack. These are shown "on top" of base screens and the Android back button works as expected.
|
||||
// Used for options, in-game menus and other things you expect to be able to back out from onto something.
|
||||
std::vector<Layer> stack_;
|
||||
std::vector<Layer> nextStack_;
|
||||
|
||||
std::unordered_map<int64_t, int> lastAxis_;
|
||||
|
||||
std::mutex eventQueueLock_;
|
||||
std::deque<QueuedEvent> eventQueue_;
|
||||
|
||||
InputMode passInputToMapper_ = InputMode::None;
|
||||
};
|
||||
@@ -0,0 +1,491 @@
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/Data/Collections/TinySet.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/GPU/thin3d.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
|
||||
ScreenManager::~ScreenManager() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void ScreenManager::switchScreen(Screen *screen) {
|
||||
if (!screen) {
|
||||
ERROR_LOG(Log::UI, "Can't switch to empty screen");
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_LOG(Log::UI, "ScreenManager::switchScreen('%s')", screen->tag());
|
||||
|
||||
if (!nextStack_.empty() && screen == nextStack_.front().screen) {
|
||||
ERROR_LOG(Log::UI, "Already switching to this screen");
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that if a dialog is found, this will be a silent background switch that
|
||||
// will only become apparent if the dialog is closed. The previous screen will stick around
|
||||
// until that switch.
|
||||
// TODO: is this still true?
|
||||
if (!nextStack_.empty()) {
|
||||
for (int i = 0; i < nextStack_.size(); i++) {
|
||||
INFO_LOG(Log::UI, "NextStack contents[%d].screen->tag(): '%s'", i, nextStack_[i].screen->tag());
|
||||
}
|
||||
|
||||
ERROR_LOG(Log::UI, "Already had a nextStack_! Asynchronous open while doing something? Deleting the new screen.");
|
||||
delete screen;
|
||||
return;
|
||||
}
|
||||
if (screen == nullptr) {
|
||||
WARN_LOG(Log::UI, "Switching to a zero screen, this can't be good");
|
||||
}
|
||||
if (stack_.empty() || screen != stack_.back().screen) {
|
||||
if (screen) {
|
||||
screen->setScreenManager(this);
|
||||
}
|
||||
nextStack_.push_back({screen, 0});
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::cancelScreensAbove(Screen *screen) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < stack_.size(); i++) {
|
||||
if (stack_[i].screen == screen) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
cancelScreensAbove_ = screen;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::update() {
|
||||
if (cancelScreensAbove_) {
|
||||
bool found = false;
|
||||
for (int i = (int)stack_.size() - 1; i >= 0; i--) {
|
||||
if (stack_[i].screen == cancelScreensAbove_) {
|
||||
break;
|
||||
}
|
||||
Layer temp = stack_.back();
|
||||
stack_.pop_back();
|
||||
delete temp.screen;
|
||||
}
|
||||
cancelScreensAbove_ = nullptr;
|
||||
}
|
||||
|
||||
if (!nextStack_.empty()) {
|
||||
switchToNext();
|
||||
}
|
||||
|
||||
if (overlayScreen_) {
|
||||
// NOTE: This is not a full UIScreen update, to avoid double global event processing.
|
||||
overlayScreen_->update();
|
||||
}
|
||||
|
||||
// Process queued events.
|
||||
std::deque<QueuedEvent> events;
|
||||
{
|
||||
std::lock_guard<std::mutex> eventGuard(eventQueueLock_);
|
||||
events = std::move(eventQueue_);
|
||||
eventQueue_.clear();
|
||||
}
|
||||
|
||||
for (const QueuedEvent &ev : events) {
|
||||
switch (ev.type) {
|
||||
case QueuedEventType::TOUCH:
|
||||
{
|
||||
const TouchInput &touch = ev.touch;
|
||||
// Send release all events to every screen layer.
|
||||
if (touch.flags & TouchInputFlags::RELEASE_ALL) {
|
||||
for (auto &layer : stack_) {
|
||||
Screen *screen = layer.screen;
|
||||
layer.screen->touch(screen->transformTouch(touch));
|
||||
}
|
||||
} else if (!stack_.empty()) {
|
||||
// Let the overlay know about touch-downs, to be able to dismiss popups.
|
||||
bool skip = false;
|
||||
if (overlayScreen_ && (touch.flags & TouchInputFlags::DOWN)) {
|
||||
skip = overlayScreen_->touch(overlayScreen_->transformTouch(touch));
|
||||
}
|
||||
if (!skip) {
|
||||
Screen *screen = stack_.back().screen;
|
||||
stack_.back().screen->touch(screen->transformTouch(touch));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QueuedEventType::KEY:
|
||||
{
|
||||
const KeyInput &key = ev.key;
|
||||
// Send key up to every screen layer, to avoid stuck keys.
|
||||
if (key.flags & KeyInputFlags::UP) {
|
||||
for (auto &layer : stack_) {
|
||||
layer.screen->key(key);
|
||||
}
|
||||
} else if (!stack_.empty()) {
|
||||
stack_.back().screen->key(key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QueuedEventType::AXIS:
|
||||
{
|
||||
const AxisInput &axis = ev.axis;
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->axis(axis);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERROR_LOG(Log::UI, "Unknown queued event type: %d", (int)ev.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only the front screen gets update().
|
||||
if (!stack_.empty()) {
|
||||
Screen *backScreen = stack_.back().screen;
|
||||
backScreen->update();
|
||||
passInputToMapper_ = backScreen->PassInputToMapper();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::switchToNext() {
|
||||
if (nextStack_.empty()) {
|
||||
ERROR_LOG(Log::System, "switchToNext: No nextStack_!");
|
||||
}
|
||||
|
||||
Layer temp = {nullptr, 0};
|
||||
if (!stack_.empty()) {
|
||||
temp = stack_.back();
|
||||
temp.screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
stack_.pop_back();
|
||||
}
|
||||
stack_.push_back(nextStack_.front());
|
||||
nextStack_.front().screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP);
|
||||
delete temp.screen;
|
||||
UI::SetFocusedView(nullptr, UI::FocusFlags::CAUSE_SCREEN_CHANGE);
|
||||
|
||||
// When will this ever happen? Should handle focus here too?
|
||||
for (size_t i = 1; i < nextStack_.size(); ++i) {
|
||||
stack_.push_back(nextStack_[i]);
|
||||
}
|
||||
nextStack_.clear();
|
||||
}
|
||||
|
||||
void ScreenManager::touch(const TouchInput &touch) {
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::TOUCH;
|
||||
ev.touch = touch;
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
eventQueue_.push_back(ev);
|
||||
}
|
||||
|
||||
void ScreenManager::key(const KeyInput &key) {
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::KEY;
|
||||
ev.key = key;
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
eventQueue_.push_back(ev);
|
||||
}
|
||||
|
||||
void ScreenManager::axis(const AxisInput *axes, size_t count) {
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::AXIS;
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ev.axis = axes[i];
|
||||
eventQueue_.push_back(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::deviceLost() {
|
||||
for (auto &iter : stack_)
|
||||
iter.screen->deviceLost();
|
||||
}
|
||||
|
||||
void ScreenManager::deviceRestored(Draw::DrawContext *draw) {
|
||||
draw_ = draw;
|
||||
for (auto &iter : stack_)
|
||||
iter.screen->deviceRestored(draw);
|
||||
}
|
||||
|
||||
void ScreenManager::resized() {
|
||||
INFO_LOG(Log::UI, "ScreenManager::resized(g_display.dp_xres/dp_yres: %dx%d)", g_display.dp_xres, g_display.dp_yres);
|
||||
// Have to notify the whole stack, otherwise there will be problems when going back
|
||||
// to non-top screens.
|
||||
for (auto &layer : stack_) {
|
||||
layer.screen->resized();
|
||||
}
|
||||
}
|
||||
|
||||
ScreenRenderFlags ScreenManager::render() {
|
||||
using namespace Draw;
|
||||
|
||||
ScreenRenderFlags flags = ScreenRenderFlags::NONE;
|
||||
|
||||
// First, go through the whole stack and have every screen render any non-backbuffer render passes.
|
||||
// In EmuScreen, this might result in running emulation.
|
||||
for (size_t i = 0; i < stack_.size(); i++) {
|
||||
const auto &layer = stack_[i];
|
||||
ScreenRenderMode mode = ScreenRenderMode::DEFAULT;
|
||||
if (i == stack_.size() - 1) {
|
||||
mode |= ScreenRenderMode::TOP;
|
||||
}
|
||||
flags |= layer.screen->PreRender(mode);
|
||||
}
|
||||
|
||||
// Now, start the final render pass. This is now the ONLY place where binding the null fb is allowed.
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, {RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR}, "BackBuffer");
|
||||
getUIContext()->BeginFrame();
|
||||
|
||||
const Draw::Viewport viewport{0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f};
|
||||
draw_->SetViewport(viewport);
|
||||
draw_->SetScissorRect(0, 0, g_display.pixel_xres, g_display.pixel_yres);
|
||||
draw_->SetTargetSize(g_display.pixel_xres, g_display.pixel_yres);
|
||||
|
||||
if (!stack_.empty()) {
|
||||
// Collect the screens to render
|
||||
TinySet<Screen *, 6> layers;
|
||||
|
||||
// Start at the end, collect screens to form the transparency stack.
|
||||
// Then we'll iterate them in reverse order.
|
||||
// Note that we skip the overlay screen, we handle it separately.
|
||||
// Additionally, we pick up a "background" screen. Normally it will be either
|
||||
// the EmuScreen or the actual global background screen.
|
||||
auto iter = stack_.end();
|
||||
Screen *coveringScreen = nullptr;
|
||||
Screen *foundBackgroundScreen = nullptr;
|
||||
bool first = true;
|
||||
|
||||
do {
|
||||
--iter;
|
||||
ScreenRenderRole role = iter->screen->renderRole(first);
|
||||
if (!foundBackgroundScreen && (role & ScreenRenderRole::CAN_BE_BACKGROUND)) {
|
||||
// There still might be a screen that wants to be background - generally the EmuScreen if present.
|
||||
layers.push_back(iter->screen);
|
||||
foundBackgroundScreen = iter->screen;
|
||||
} else if (!coveringScreen) {
|
||||
layers.push_back(iter->screen);
|
||||
}
|
||||
if (iter->flags != LAYER_TRANSPARENT) {
|
||||
coveringScreen = iter->screen;
|
||||
}
|
||||
first = false;
|
||||
if (role & ScreenRenderRole::MUST_BE_FIRST) {
|
||||
break;
|
||||
}
|
||||
} while (iter != stack_.begin());
|
||||
|
||||
if (backgroundScreen_ && !foundBackgroundScreen) {
|
||||
layers.push_back(backgroundScreen_);
|
||||
foundBackgroundScreen = backgroundScreen_;
|
||||
}
|
||||
|
||||
// OK, now we iterate backwards over our little pile of collected screens.
|
||||
for (int i = (int)layers.size() - 1; i >= 0; i--) {
|
||||
ScreenRenderMode mode = ScreenRenderMode::DEFAULT;
|
||||
if (i == (int)layers.size() - 1) {
|
||||
// Bottom.
|
||||
mode = ScreenRenderMode::FIRST;
|
||||
if (i == 0) {
|
||||
mode |= ScreenRenderMode::TOP;
|
||||
}
|
||||
} else if (i == 0) {
|
||||
mode = ScreenRenderMode::TOP;
|
||||
} else {
|
||||
mode = ScreenRenderMode::BEHIND;
|
||||
}
|
||||
flags |= layers[i]->render(mode);
|
||||
}
|
||||
|
||||
if (overlayScreen_) {
|
||||
// It doesn't care about mode.
|
||||
flags |= overlayScreen_->render(ScreenRenderMode::TOP);
|
||||
}
|
||||
|
||||
getUIContext()->Flush();
|
||||
|
||||
if (postRenderCb_) {
|
||||
// Really can't render anything after this! Will crash the screenshot mechanism if we do.
|
||||
postRenderCb_(getUIContext(), postRenderUserdata_);
|
||||
}
|
||||
} else {
|
||||
ERROR_LOG(Log::UI, "No current screen!");
|
||||
}
|
||||
|
||||
processFinishDialog();
|
||||
return flags;
|
||||
}
|
||||
|
||||
void ScreenManager::getFocusPosition(float &x, float &y, float &z) {
|
||||
UI::ScrollView::GetLastScrollPosition(x, y);
|
||||
|
||||
UI::View *v = UI::GetFocusedView();
|
||||
x += v ? v->GetBounds().x : 0;
|
||||
y += v ? v->GetBounds().y : 0;
|
||||
z = stack_.size();
|
||||
}
|
||||
|
||||
void ScreenManager::sendMessage(UIMessage message, const char *value) {
|
||||
if (message == UIMessage::RECREATE_VIEWS) {
|
||||
RecreateAllViews();
|
||||
} else if (message == UIMessage::LOST_FOCUS) {
|
||||
TouchInput input{};
|
||||
input.x = -50000.0f;
|
||||
input.y = -50000.0f;
|
||||
input.flags = TouchInputFlags::RELEASE_ALL;
|
||||
input.timestamp = time_now_d();
|
||||
input.id = 0;
|
||||
touch(input);
|
||||
}
|
||||
|
||||
if (backgroundScreen_) {
|
||||
backgroundScreen_->sendMessage(message, value);
|
||||
}
|
||||
|
||||
// NOTE: Changed this to send the message to all screens, instead of just the top one,
|
||||
// to allow EmuScreen to receive messages from popup menus. Hope this didn't break anything..
|
||||
// NOTE: We do not use the iterator solution here, because the screen array may change by sendMessage!
|
||||
// Although if it does, that's very bad.
|
||||
// We also pick out the stack size before, so we don't get infinite growth if a screen is pushed from the handler.
|
||||
// We probably should delay pushes, though...
|
||||
const size_t stack_size = stack_.size();
|
||||
for (int i = 0; i < stack_size; i++) {
|
||||
if (stack_[i].screen) {
|
||||
stack_[i].screen->sendMessage(message, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::shutdown() {
|
||||
for (const auto &layer : stack_)
|
||||
delete layer.screen;
|
||||
stack_.clear();
|
||||
for (const auto &layer : nextStack_)
|
||||
delete layer.screen;
|
||||
nextStack_.clear();
|
||||
delete overlayScreen_;
|
||||
overlayScreen_ = nullptr;
|
||||
delete backgroundScreen_;
|
||||
backgroundScreen_ = nullptr;
|
||||
}
|
||||
|
||||
void ScreenManager::push(Screen *screen, int layerFlags) {
|
||||
screen->setScreenManager(this);
|
||||
if (screen->isTransparent()) {
|
||||
layerFlags |= LAYER_TRANSPARENT;
|
||||
}
|
||||
|
||||
// Release touches and unfocus.
|
||||
UI::SetFocusedView(nullptr, UI::FocusFlags::CAUSE_SCREEN_CHANGE);
|
||||
TouchInput input{};
|
||||
input.x = -50000.0f;
|
||||
input.y = -50000.0f;
|
||||
input.flags = TouchInputFlags::RELEASE_ALL;
|
||||
input.timestamp = time_now_d();
|
||||
input.id = 0;
|
||||
touch(input);
|
||||
|
||||
Layer layer = {screen, layerFlags};
|
||||
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
}
|
||||
|
||||
if (nextStack_.empty()) {
|
||||
layer.screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP);
|
||||
stack_.push_back(layer);
|
||||
} else {
|
||||
nextStack_.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::pop() {
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
|
||||
delete stack_.back().screen;
|
||||
stack_.pop_back();
|
||||
|
||||
if (!stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
}
|
||||
} else {
|
||||
ERROR_LOG(Log::UI, "Can't pop when stack empty");
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::RecreateAllViews() {
|
||||
for (auto &layer : stack_) {
|
||||
layer.screen->RecreateViews();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::finishDialog(Screen *dialog, DialogResult result) {
|
||||
if (stack_.empty()) {
|
||||
ERROR_LOG(Log::UI, "Must be in a dialog to finishDialog");
|
||||
return;
|
||||
}
|
||||
if (dialog != stack_.back().screen) {
|
||||
ERROR_LOG(Log::UI, "Wrong dialog being finished!");
|
||||
return;
|
||||
}
|
||||
dialog->onFinish(result);
|
||||
dialogFinished_ = dialog;
|
||||
dialogResult_ = result;
|
||||
}
|
||||
|
||||
Screen *ScreenManager::dialogParent(const Screen *dialog) const {
|
||||
for (size_t i = 1; i < stack_.size(); ++i) {
|
||||
if (stack_[i].screen == dialog) {
|
||||
// The previous screen was the caller (not necessarily the topmost.)
|
||||
return stack_[i - 1].screen;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ScreenManager::processFinishDialog() {
|
||||
if (dialogFinished_) {
|
||||
{
|
||||
// Another dialog may have been pushed before the render, so search for it.
|
||||
Screen *caller = dialogParent(dialogFinished_);
|
||||
bool erased = false;
|
||||
for (size_t i = 0; i < stack_.size(); ++i) {
|
||||
if (stack_[i].screen == dialogFinished_) {
|
||||
stack_[i].screen->focusChanged(ScreenFocusChange::FOCUS_LOST_TOP);
|
||||
stack_.erase(stack_.begin() + i);
|
||||
erased = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (erased && !stack_.empty()) {
|
||||
stack_.back().screen->focusChanged(ScreenFocusChange::FOCUS_BECAME_TOP);
|
||||
}
|
||||
|
||||
if (!caller) {
|
||||
ERROR_LOG(Log::UI, "ERROR: no top screen when finishing dialog");
|
||||
} else if (caller != topScreen()) {
|
||||
// The caller may get confused if we call dialogFinished() now.
|
||||
WARN_LOG(Log::UI, "Skipping non-top dialog when finishing dialog.");
|
||||
} else {
|
||||
caller->dialogFinished(dialogFinished_, dialogResult_);
|
||||
}
|
||||
}
|
||||
delete dialogFinished_;
|
||||
dialogFinished_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::SetBackgroundOverlayScreens(Screen *backgroundScreen, Screen *overlayScreen) {
|
||||
delete backgroundScreen_;
|
||||
backgroundScreen_ = backgroundScreen;
|
||||
backgroundScreen_->setScreenManager(this);
|
||||
|
||||
delete overlayScreen_;
|
||||
overlayScreen_ = overlayScreen;
|
||||
overlayScreen_->setScreenManager(this);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Input/InputState.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/UI/Screen.h"
|
||||
|
||||
class Screen;
|
||||
class UIContext;
|
||||
|
||||
|
||||
/*
|
||||
class Transition {
|
||||
public:
|
||||
Transition() = default;
|
||||
};
|
||||
*/
|
||||
|
||||
enum {
|
||||
LAYER_TRANSPARENT = 2,
|
||||
};
|
||||
|
||||
typedef void (*PostRenderCallback)(UIContext *ui, void *userdata);
|
||||
|
||||
class ScreenManager {
|
||||
public:
|
||||
virtual ~ScreenManager();
|
||||
|
||||
void switchScreen(Screen *screen);
|
||||
void update();
|
||||
|
||||
void setUIContext(UIContext *context) { uiContext_ = context; }
|
||||
UIContext *getUIContext() { return uiContext_; }
|
||||
Draw::DrawContext *getDrawContext() { return draw_; }
|
||||
|
||||
void setPostRenderCallback(PostRenderCallback cb, void *userdata) {
|
||||
postRenderCb_ = cb;
|
||||
postRenderUserdata_ = userdata;
|
||||
}
|
||||
|
||||
ScreenRenderFlags render();
|
||||
void resized();
|
||||
void shutdown();
|
||||
|
||||
void deviceLost();
|
||||
void deviceRestored(Draw::DrawContext *draw);
|
||||
|
||||
// Push a dialog box in front. Currently 1-level only.
|
||||
void push(Screen *screen, int layerFlags = 0);
|
||||
|
||||
// Recreate all views
|
||||
void RecreateAllViews();
|
||||
|
||||
// Pops the dialog away.
|
||||
void finishDialog(Screen *dialog, DialogResult result = DR_OK);
|
||||
Screen *dialogParent(const Screen *dialog) const;
|
||||
|
||||
// Instant touch, separate from the update() mechanism.
|
||||
void touch(const TouchInput &touch);
|
||||
void key(const KeyInput &key);
|
||||
void axis(const AxisInput *axes, size_t count);
|
||||
|
||||
void sendMessage(UIMessage message, const char *value);
|
||||
|
||||
const Screen *topScreen() const {
|
||||
return stack_.empty() ? nullptr : stack_.back().screen;
|
||||
}
|
||||
Screen *topScreen() {
|
||||
return stack_.empty() ? nullptr : stack_.back().screen;
|
||||
}
|
||||
|
||||
void cancelScreensAbove(Screen *screen);
|
||||
|
||||
void getFocusPosition(float &x, float &y, float &z);
|
||||
|
||||
// Will delete any existing overlay screen.
|
||||
void SetBackgroundOverlayScreens(Screen *backgroundScreen, Screen *overlayScreen);
|
||||
|
||||
InputMode PassInputToMapper() const {
|
||||
return passInputToMapper_;
|
||||
}
|
||||
|
||||
private:
|
||||
void pop();
|
||||
void switchToNext();
|
||||
void processFinishDialog();
|
||||
|
||||
UIContext *uiContext_ = nullptr;
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
|
||||
PostRenderCallback postRenderCb_ = nullptr;
|
||||
void *postRenderUserdata_ = nullptr;
|
||||
|
||||
const Screen *dialogFinished_ = nullptr;
|
||||
DialogResult dialogResult_{};
|
||||
|
||||
Screen *backgroundScreen_ = nullptr;
|
||||
Screen *overlayScreen_ = nullptr;
|
||||
|
||||
Screen *cancelScreensAbove_ = nullptr;
|
||||
|
||||
struct Layer {
|
||||
Screen *screen;
|
||||
int flags; // From LAYER_ enum above
|
||||
UI::View *focusedView; // TODO: save focus here. Going for quick solution now to reset focus.
|
||||
};
|
||||
|
||||
// Dialog stack. These are shown "on top" of base screens and the Android back button works as expected.
|
||||
// Used for options, in-game menus and other things you expect to be able to back out from onto something.
|
||||
std::vector<Layer> stack_;
|
||||
std::vector<Layer> nextStack_;
|
||||
|
||||
std::unordered_map<int64_t, int> lastAxis_;
|
||||
|
||||
std::mutex eventQueueLock_;
|
||||
std::deque<QueuedEvent> eventQueue_;
|
||||
|
||||
InputMode passInputToMapper_ = InputMode::None;
|
||||
};
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Common/Input/KeyCodes.h"
|
||||
#include "Common/UI/UIScreen.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/Screen.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/Render/DrawBuffer.h"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "Common/Net/Resolve.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Data/Text/Parsers.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/Net/HTTPClient.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/UI/UI.h"
|
||||
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Data/Color/RGBAUtil.h"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/Data/Color/RGBAUtil.h"
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/CwCheat.h"
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/IconCache.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Render/Text/draw_text.h"
|
||||
#include "Common/Profiler/Profiler.h"
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Render/Text/draw_text.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "GPU/Common/TextureReplacer.h"
|
||||
#include "GPU/Common/PostShader.h"
|
||||
#include "Core/MIPS/MIPSTracer.h"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/UIScreen.h"
|
||||
#include "Common/UI/TabHolder.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Math/math_util.h"
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
|
||||
#include "Core/Config.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
@@ -33,6 +33,7 @@ using namespace std::placeholders;
|
||||
#include "Common/UI/Tween.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/AsyncImageFileView.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/GPU/Shader.h"
|
||||
#include "Common/GPU/ShaderWriter.h"
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
|
||||
#include "Common/Math/curves.h"
|
||||
#include "Common/Net/URL.h"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "Common/System/OSD.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Render/ManagedTexture.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
#include "Common/BitSet.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "UI/JitCompareScreen.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Render/DrawBuffer.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/MIPS/MIPSTables.h"
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/System/System.h"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "Common/Data/Color/RGBAUtil.h"
|
||||
#include "Common/Data/Encoding/Utf8.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Render/ManagedTexture.h"
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "Common/GPU/thin3d.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/Screen.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/IconCache.h"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Common/UI/UIScreen.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/GPU/thin3d.h"
|
||||
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "Common/File/PathBrowser.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Data/Format/JSONReader.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/Common.h"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "Common/UI/AsyncImageFileView.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "Core/Config.h"
|
||||
#include "Core/RetroAchievements.h"
|
||||
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "UI/RetroAchievementScreens.h"
|
||||
#include "UI/BackgroundAudio.h"
|
||||
#include "UI/OnScreenDisplay.h"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/AsyncImageFileView.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "UI/SavedataScreen.h"
|
||||
#include "UI/MainScreen.h"
|
||||
#include "UI/GameInfoCache.h"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "UI/SimpleDialogScreen.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "UI/MiscViews.h"
|
||||
|
||||
ViewLayoutMode UISimpleBaseDialogScreen::LayoutMode() const {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/IconCache.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/Render/DrawBuffer.h"
|
||||
|
||||
#include "Common/Log.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/Notice.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Config.h"
|
||||
#include "GPU/GPUState.h" // ugh
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "UI/MiscViews.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "UI/TabbedDialogScreen.h"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/UI/Context.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/UI/TabHolder.h"
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
|
||||
#include "Core/Config.h"
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
<ClInclude Include="..\..\Common\UI\PopupScreens.h" />
|
||||
<ClInclude Include="..\..\Common\UI\Root.h" />
|
||||
<ClInclude Include="..\..\Common\UI\Screen.h" />
|
||||
<ClInclude Include="..\..\Common\UI\ScreenManager.h" />
|
||||
<ClInclude Include="..\..\Common\UI\ScrollView.h" />
|
||||
<ClInclude Include="..\..\Common\UI\TabHolder.h" />
|
||||
<ClInclude Include="..\..\Common\UI\Tween.h" />
|
||||
@@ -406,6 +407,7 @@
|
||||
<ClCompile Include="..\..\Common\UI\PopupScreens.cpp" />
|
||||
<ClCompile Include="..\..\Common\UI\Root.cpp" />
|
||||
<ClCompile Include="..\..\Common\UI\Screen.cpp" />
|
||||
<ClCompile Include="..\..\Common\UI\ScreenManager.cpp" />
|
||||
<ClCompile Include="..\..\Common\UI\ScrollView.cpp" />
|
||||
<ClCompile Include="..\..\Common\UI\TabHolder.cpp" />
|
||||
<ClCompile Include="..\..\Common\UI\Tween.cpp" />
|
||||
@@ -503,4 +505,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -591,6 +591,9 @@
|
||||
<ClCompile Include="..\..\ext\pugixml\pugixml.cpp">
|
||||
<Filter>ext\pugixml</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Common\UI\ScreenManager.cpp">
|
||||
<Filter>UI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="targetver.h" />
|
||||
@@ -1145,6 +1148,9 @@
|
||||
<ClInclude Include="..\..\ext\pugixml\pugixml.hpp">
|
||||
<Filter>ext\pugixml</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Common\UI\ScreenManager.h">
|
||||
<Filter>UI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\ext\libpng17\CMakeLists.txt" />
|
||||
@@ -1187,4 +1193,4 @@
|
||||
<Filter>ext\at3_standalone</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -386,6 +386,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/Common/UI/AsyncImageFileView.cpp \
|
||||
$(SRC)/Common/UI/Root.cpp \
|
||||
$(SRC)/Common/UI/Screen.cpp \
|
||||
$(SRC)/Common/UI/ScreenManager.cpp \
|
||||
$(SRC)/Common/UI/UI.cpp \
|
||||
$(SRC)/Common/UI/Context.cpp \
|
||||
$(SRC)/Common/UI/UIScreen.cpp \
|
||||
|
||||
Reference in new issue
Block a user