diff --git a/Common/UI/Screen.cpp b/Common/UI/Screen.cpp index 664f3f9275..4e1b736991 100644 --- a/Common/UI/Screen.cpp +++ b/Common/UI/Screen.cpp @@ -53,6 +53,10 @@ void ScreenManager::update() { stack_.back().screen->update(); } + if (overlayScreen_) { + overlayScreen_->update(); + } + g_iconCache.FrameUpdate(); } @@ -174,6 +178,9 @@ void ScreenManager::render() { stack_.back().screen->render(); if (postRenderCb_) postRenderCb_(getUIContext(), postRenderUserdata_); + if (overlayScreen_) { + overlayScreen_->render(); + } backback.screen->postRender(); break; } @@ -183,6 +190,9 @@ void ScreenManager::render() { stack_.back().screen->render(); if (postRenderCb_) postRenderCb_(getUIContext(), postRenderUserdata_); + if (overlayScreen_) { + overlayScreen_->render(); + } stack_.back().screen->postRender(); break; } @@ -233,6 +243,8 @@ void ScreenManager::shutdown() { for (auto layer : nextStack_) delete layer.screen; nextStack_.clear(); + delete overlayScreen_; + overlayScreen_ = nullptr; } void ScreenManager::push(Screen *screen, int layerFlags) { @@ -325,3 +337,11 @@ void ScreenManager::processFinishDialog() { dialogFinished_ = nullptr; } } + +void ScreenManager::SetOverlayScreen(Screen *screen) { + if (overlayScreen_) { + delete overlayScreen_; + } + overlayScreen_ = screen; + overlayScreen_->setScreenManager(this); +} diff --git a/Common/UI/Screen.h b/Common/UI/Screen.h index fca213fdb8..7e9e4f8489 100644 --- a/Common/UI/Screen.h +++ b/Common/UI/Screen.h @@ -144,6 +144,9 @@ public: void getFocusPosition(float &x, float &y, float &z); + // Will delete any existing overlay screen. + void SetOverlayScreen(Screen *screen); + std::recursive_mutex inputLock_; private: @@ -157,8 +160,10 @@ private: PostRenderCallback postRenderCb_ = nullptr; void *postRenderUserdata_ = nullptr; - const Screen *dialogFinished_; - DialogResult dialogResult_; + const Screen *dialogFinished_ = nullptr; + DialogResult dialogResult_{}; + + Screen *overlayScreen_ = nullptr; struct Layer { Screen *screen; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 0d926f9531..600d9c2041 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -936,7 +936,6 @@ void EmuScreen::CreateViews() { saveStatePreview_->SetVisibility(V_GONE); saveStatePreview_->SetCanBeFocused(false); root_->Add(saveStatePreview_); - onScreenMessagesView_ = root_->Add(new OnScreenMessagesView(new AnchorLayoutParams((Size)bounds.w, (Size)bounds.h))); GameInfoBGView *loadingBG = root_->Add(new GameInfoBGView(gamePath_, new AnchorLayoutParams(FILL_PARENT, FILL_PARENT))); TextView *loadingTextView = root_->Add(new TextView(sc->T(PSP_GetLoading()), new AnchorLayoutParams(bounds.centerX(), NONE, NONE, 40, true))); @@ -1042,7 +1041,6 @@ void EmuScreen::update() { using namespace UI; UIScreen::update(); - onScreenMessagesView_->SetVisibility(g_Config.bShowOnScreenMessages ? V_VISIBLE : V_GONE); resumeButton_->SetVisibility(coreState == CoreState::CORE_RUNTIME_ERROR && Memory::MemFault_MayBeResumable() ? V_VISIBLE : V_GONE); resetButton_->SetVisibility(coreState == CoreState::CORE_RUNTIME_ERROR ? V_VISIBLE : V_GONE); diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 7eda3988d4..6bfafe62e7 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -32,7 +32,6 @@ struct AxisInput; class AsyncImageFileView; -class OnScreenMessagesView; class ChatMenu; class EmuScreen : public UIScreen { @@ -113,7 +112,6 @@ private: ChatMenu *chatMenu_ = nullptr; UI::Button *cardboardDisableButton_ = nullptr; - OnScreenMessagesView *onScreenMessagesView_ = nullptr; ControlMapper controlMapper_; }; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 322c9c55d4..8a616ef12f 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -786,6 +786,8 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT)); } + g_screenManager->SetOverlayScreen(new OSDOverlayScreen()); + // Easy testing // screenManager->push(new GPUDriverTestScreen()); @@ -1016,27 +1018,6 @@ void TakeScreenshot() { } void RenderOverlays(UIContext *dc, void *userdata) { - // Thin bar at the top of the screen. - std::vector progress = g_DownloadManager.GetCurrentProgress(); - if (!progress.empty()) { - static const uint32_t colors[4] = { - 0xFFFFFFFF, - 0xFFCCCCCC, - 0xFFAAAAAA, - 0xFF777777, - }; - - dc->Begin(); - int h = 5; - for (size_t i = 0; i < progress.size(); i++) { - float barWidth = 10 + (dc->GetBounds().w - 10) * progress[i]; - Bounds bounds(0, h * i, barWidth, h); - UI::Drawable solid(colors[i & 3]); - dc->FillRect(solid, bounds); - } - dc->Flush(); - } - if (g_TakeScreenshot) { TakeScreenshot(); } diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 06d3d2f9f7..0712b45970 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -10,10 +10,16 @@ #include "Common/UI/Context.h" #include "Common/TimeUtil.h" +#include "Common/Net/HTTPClient.h" +#include "Core/Config.h" OnScreenMessages osm; void OnScreenMessagesView::Draw(UIContext &dc) { + if (!g_Config.bShowOnScreenMessages) { + return; + } + // First, clean out old messages. osm.Lock(); osm.Clean(); @@ -61,6 +67,27 @@ void OnScreenMessagesView::Draw(UIContext &dc) { } osm.Unlock(); + + // Thin bar at the top of the screen. + std::vector progress = g_DownloadManager.GetCurrentProgress(); + if (!progress.empty()) { + static const uint32_t colors[4] = { + 0xFFFFFFFF, + 0xFFCCCCCC, + 0xFFAAAAAA, + 0xFF777777, + }; + + dc.Begin(); + int h = 5; + for (size_t i = 0; i < progress.size(); i++) { + float barWidth = 10 + (dc.GetBounds().w - 10) * progress[i]; + Bounds bounds(0, h * i, barWidth, h); + UI::Drawable solid(colors[i & 3]); + dc.FillRect(solid, bounds); + } + dc.Flush(); + } } std::string OnScreenMessagesView::DescribeText() const { @@ -114,3 +141,8 @@ void OnScreenMessages::Show(const std::string &text, float duration_s, uint32_t void OnScreenMessages::ShowOnOff(const std::string &message, bool b, float duration_s, uint32_t color, int icon) { Show(message + (b ? ": on" : ": off"), duration_s, color, icon); } + +void OSDOverlayScreen::CreateViews() { + root_ = new UI::AnchorLayout(); + root_->Add(new OnScreenMessagesView(new UI::AnchorLayoutParams(0.0f, 0.0f, 0.0f, 0.0f))); +} diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h index 7a56c0b08e..d4e425a8a6 100644 --- a/UI/OnScreenDisplay.h +++ b/UI/OnScreenDisplay.h @@ -6,9 +6,11 @@ #include "Common/Math/geom2d.h" #include "Common/UI/View.h" +#include "Common/UI/UIScreen.h" class DrawBuffer; +// Data holder. This one is currently global. class OnScreenMessages { public: void Show(const std::string &message, float duration_s = 1.0f, uint32_t color = 0xFFFFFF, int icon = -1, bool checkUnique = true, const char *id = nullptr); @@ -39,6 +41,8 @@ private: std::mutex mutex_; }; +// Infrastructure for rendering overlays. + class OnScreenMessagesView : public UI::InertView { public: OnScreenMessagesView(UI::LayoutParams *layoutParams = nullptr) : UI::InertView(layoutParams) {} @@ -46,4 +50,10 @@ public: std::string DescribeText() const override; }; +class OSDOverlayScreen : public UIScreen { +public: + const char *tag() const override { return "OSDOverlayScreen"; } + void CreateViews() override; +}; + extern OnScreenMessages osm;