diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f32808898..5c27978ca0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -893,6 +893,8 @@ add_library(Common STATIC
Common/UI/IconCache.h
Common/UI/UIScreen.cpp
Common/UI/UIScreen.h
+ Common/UI/Notice.cpp
+ Common/UI/Notice.h
Common/UI/Tween.cpp
Common/UI/Tween.h
Common/UI/View.cpp
diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index 85d534469d..1e193e172a 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -541,6 +541,7 @@
+
@@ -992,6 +993,7 @@
+
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
index a8911742a6..1dd44daa52 100644
--- a/Common/Common.vcxproj.filters
+++ b/Common/Common.vcxproj.filters
@@ -722,6 +722,9 @@
ext\aemu_postoffice
+
+ UI
+
@@ -1344,6 +1347,9 @@
ext\aemu_postoffice
+
+ UI
+
diff --git a/Common/UI/Notice.cpp b/Common/UI/Notice.cpp
new file mode 100644
index 0000000000..e7b3c7084d
--- /dev/null
+++ b/Common/UI/Notice.cpp
@@ -0,0 +1,160 @@
+#include "Common/UI/UI.h"
+#include "Common/UI/Notice.h"
+#include "Common/UI/IconCache.h"
+#include "Common/UI/Context.h"
+#include "Common/StringUtils.h"
+#include "Common/System/OSD.h"
+
+static const float extraTextScale = 0.7f;
+
+uint32_t GetNoticeBackgroundColor(NoticeLevel type) {
+ // Colors from Infima
+ switch (type) {
+ case NoticeLevel::ERROR: return 0x3530d5; // danger-darker
+ case NoticeLevel::WARN: return 0x009ed9; // warning-darker
+ case NoticeLevel::INFO: return 0x706760; // gray-700
+ case NoticeLevel::SUCCESS: return 0x008b00; // nice green
+ default: return 0x606770;
+ }
+}
+
+ImageID GetOSDIcon(NoticeLevel level) {
+ switch (level) {
+ case NoticeLevel::INFO: return ImageID("I_INFO");
+ case NoticeLevel::ERROR: return ImageID("I_CROSS");
+ case NoticeLevel::WARN: return ImageID("I_WARNING");
+ case NoticeLevel::SUCCESS: return ImageID("I_CHECKMARK");
+ default: return ImageID::invalid();
+ }
+}
+
+NoticeLevel GetNoticeLevel(OSDType type) {
+ switch (type) {
+ case OSDType::MESSAGE_INFO:
+ return NoticeLevel::INFO;
+ case OSDType::MESSAGE_ERROR:
+ case OSDType::MESSAGE_ERROR_DUMP:
+ case OSDType::MESSAGE_CENTERED_ERROR:
+ return NoticeLevel::ERROR;
+ case OSDType::MESSAGE_WARNING:
+ case OSDType::MESSAGE_CENTERED_WARNING:
+ return NoticeLevel::WARN;
+ case OSDType::MESSAGE_SUCCESS:
+ return NoticeLevel::SUCCESS;
+ default:
+ return NoticeLevel::SUCCESS;
+ }
+}
+
+// Align only matters here for the ASCII-only flag.
+void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float maxWidth, float *width, float *height, float *height1) {
+ float iconW = 0.0f;
+ float iconH = 0.0f;
+ if (!iconName.empty() && !startsWith(iconName, "I_")) { // Check for atlas image. Bit hacky, but we choose prefixes for icon IDs anyway in a way that this is safe.
+ // Normal entry but with a cached icon.
+ int iconWidth, iconHeight;
+ if (g_iconCache.GetDimensions(iconName, &iconWidth, &iconHeight)) {
+ *width += 5.0f + iconWidth;
+ iconW = iconWidth;
+ iconH = iconHeight;
+ }
+ } else {
+ ImageID iconID = iconName.empty() ? GetOSDIcon(level) : ImageID(iconName.c_str());
+ if (iconID.isValid()) {
+ dc.Draw()->GetAtlas()->measureImage(iconID, &iconW, &iconH);
+ }
+ }
+
+ float chromeWidth = iconW + 5.0f + 12.0f;
+ float availableWidth = maxWidth - chromeWidth;
+
+ // OK, now that we have figured out how much space we have for the text, we can measure it (with wrapping if needed).
+ // We currently don't wrap the title.
+
+ float titleWidth, titleHeight;
+ dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text, &titleWidth, &titleHeight, align);
+
+ *width = std::min(titleWidth, availableWidth);
+ *height1 = titleHeight;
+
+ float width2 = 0.0f, height2 = 0.0f;
+ if (!details.empty()) {
+ dc.MeasureTextRect(dc.GetTheme().uiFont, extraTextScale, extraTextScale, details, availableWidth, &width2, &height2, align | FLAG_WRAP_TEXT);
+ *width = std::max(*width, width2);
+ }
+
+ *width += chromeWidth;
+ if (height2 == 0.0f && iconH < 2.0f * *height1) {
+ // Center vertically using the icon.
+ *height1 = std::max(*height1, iconH + 2.0f);
+ }
+ *height = std::max(*height1 + height2 + 8.0f, iconH + 5.0f);
+}
+
+void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float alpha, OSDMessageFlags flags, float timeVal) {
+ UI::Drawable background = UI::Drawable(colorAlpha(GetNoticeBackgroundColor(level), alpha));
+
+ dc.SetFontStyle(dc.GetTheme().uiFont);
+
+ uint32_t foreGround = whiteAlpha(alpha);
+
+ if (!(flags & OSDMessageFlags::Transparent)) {
+ dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha);
+ dc.FillRect(background, bounds);
+ }
+
+ float iconW = 0.0f;
+ float iconH = 0.0f;
+ if (!iconName.empty() && !startsWith(iconName, "I_")) {
+ dc.Flush();
+ // Normal entry but with a cached icon.
+ Draw::Texture *texture = g_iconCache.BindIconTexture(&dc, iconName);
+ if (texture) {
+ iconW = texture->Width();
+ iconH = texture->Height();
+ dc.Draw()->DrawTexRect(Bounds(bounds.x + 2.5f, bounds.y + 2.5f, iconW, iconH), 0.0f, 0.0f, 1.0f, 1.0f, foreGround);
+ dc.Flush();
+ dc.RebindTexture();
+ }
+ dc.Begin();
+ } else {
+ ImageID iconID = iconName.empty() ? GetOSDIcon(level) : ImageID(iconName.c_str());
+ if (iconID.isValid()) {
+ // Atlas icon.
+ dc.Draw()->GetAtlas()->measureImage(iconID, &iconW, &iconH);
+ if (!iconName.empty()) {
+ Bounds iconBounds = Bounds(bounds.x + 2.5f, bounds.y + 2.5f, iconW, iconH);
+ // If it's not a preset OSD icon, give it some background to blend in. The RA icon for example
+ // easily melts into the orange of warnings otherwise.
+ dc.FillRect(UI::Drawable(0x50000000), iconBounds.Expand(2.0f));
+ }
+
+ if (flags & (OSDMessageFlags::SpinLeft | OSDMessageFlags::SpinRight)) {
+ const float direction = (flags & OSDMessageFlags::SpinLeft) ? -1.5f : 1.5f;
+ dc.DrawImageRotated(iconID, bounds.x + 2.5f + iconW * 0.5f, bounds.y + 2.5f + iconW * 0.5f, 1.0f, direction * timeVal, foreGround, false);
+ } else {
+ dc.DrawImageVGradient(iconID, foreGround, foreGround, Bounds(bounds.x + 2.5f, bounds.y + 2.5f, iconW, iconH));
+ }
+ }
+ }
+
+ // Make room
+ bounds.x += iconW + 5.0f;
+ bounds.w -= iconW + 5.0f;
+
+ Bounds primaryBounds = bounds;
+ primaryBounds.h = height1;
+
+ dc.DrawTextShadowRect(text, primaryBounds.Inset(2.0f, 0.0f, 1.0f, 0.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_VCENTER | FLAG_ELLIPSIZE_TEXT);
+
+ if (!details.empty()) {
+ Bounds bottomTextBounds = bounds.Inset(3.0f, height1 + 5.0f, 3.0f, 3.0f);
+ if (!(flags & OSDMessageFlags::Transparent)) {
+ UI::Drawable backgroundDark = UI::Drawable(colorAlpha(darkenColor(GetNoticeBackgroundColor(level)), alpha));
+ dc.FillRect(backgroundDark, bottomTextBounds);
+ }
+ dc.SetFontScale(extraTextScale, extraTextScale);
+ dc.DrawTextRect(details, bottomTextBounds.Inset(1.0f, 1.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_LEFT | FLAG_WRAP_TEXT);
+ }
+ dc.SetFontScale(1.0f, 1.0f);
+}
diff --git a/Common/UI/Notice.h b/Common/UI/Notice.h
new file mode 100644
index 0000000000..be01160b55
--- /dev/null
+++ b/Common/UI/Notice.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include "Common/UI/View.h"
+#include "Common/System/OSD.h"
+
+#undef ERROR
+
+enum class NoticeLevel {
+ SUCCESS,
+ INFO,
+ WARN,
+ ERROR,
+};
+
+class NoticeView : public UI::InertView {
+public:
+ NoticeView(NoticeLevel level, std::string_view text, std::string_view detailsText, UI::LayoutParams *layoutParams = 0)
+ : InertView(layoutParams), level_(level), text_(text), detailsText_(detailsText) {}
+
+ void SetIconName(std::string_view name) {
+ iconName_ = name;
+ }
+ void SetText(std::string_view text) {
+ text_ = text;
+ }
+ void SetLevel(NoticeLevel level) {
+ level_ = level;
+ }
+ void SetSquishy(bool squishy) {
+ squishy_ = squishy;
+ }
+
+ void GetContentDimensionsBySpec(const UIContext &dc, UI::MeasureSpec horiz, UI::MeasureSpec vert, float &w, float &h) const override;
+ void Draw(UIContext &dc) override;
+
+private:
+ std::string text_;
+ std::string detailsText_;
+ std::string iconName_;
+ NoticeLevel level_;
+ mutable float height1_ = 0.0f;
+ bool squishy_ = false;
+};
+
+ImageID GetOSDIcon(NoticeLevel level);
+NoticeLevel GetNoticeLevel(OSDType type);
+uint32_t GetNoticeBackgroundColor(NoticeLevel type);
+void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float maxWidth, float *width, float *height, float *height1);
+void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float alpha, OSDMessageFlags flags, float timeVal);
diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp
index 83a5a5789e..94b4cf815c 100644
--- a/UI/ControlMappingScreen.cpp
+++ b/UI/ControlMappingScreen.cpp
@@ -22,32 +22,26 @@
#include
#include "Common/Render/TextureAtlas.h"
-#include "Common/UI/Root.h"
-#include "Common/UI/UI.h"
#include "Common/UI/Context.h"
#include "Common/UI/View.h"
#include "Common/UI/ViewGroup.h"
+#include "Common/UI/Notice.h"
#include "Common/VR/PPSSPPVR.h"
-
#include "Common/Log.h"
#include "Common/Data/Color/RGBAUtil.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Input/KeyCodes.h"
#include "Common/Input/InputState.h"
#include "Common/StringUtils.h"
-#include "Common/System/Display.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/TimeUtil.h"
#include "Core/KeyMap.h"
#include "Core/HLE/sceCtrl.h"
-#include "Core/System.h"
#include "Core/Config.h"
#include "UI/ControlMappingScreen.h"
#include "UI/PopupScreens.h"
-#include "UI/GameSettingsScreen.h"
#include "UI/JoystickHistoryView.h"
-#include "UI/OnScreenDisplay.h"
#if PPSSPP_PLATFORM(ANDROID)
#include "android/jni/app-android.h"
@@ -57,7 +51,10 @@ using KeyMap::MultiInputMapping;
class SingleControlMapper : public UI::LinearLayout {
public:
- SingleControlMapper(int pspKey, std::string keyName, bool portrait, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = nullptr);
+ SingleControlMapper(int pspKey, std::string_view keyName, bool portrait, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = nullptr)
+ : UI::LinearLayout(ORIENT_VERTICAL, layoutParams), pspKey_(pspKey), keyName_(keyName), scrm_(scrm), portrait_(portrait) {
+ Refresh();
+ }
~SingleControlMapper() {
g_IsMappingMouseInput = false;
}
@@ -82,11 +79,6 @@ private:
bool portrait_;
};
-SingleControlMapper::SingleControlMapper(int pspKey, std::string keyName, bool portrait, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams)
- : UI::LinearLayout(ORIENT_VERTICAL, layoutParams), pspKey_(pspKey), keyName_(keyName), scrm_(scrm), portrait_(portrait) {
- Refresh();
-}
-
void SingleControlMapper::Refresh() {
Clear();
auto mc = GetI18NCategory(I18NCat::MAPPABLECONTROLS);
diff --git a/UI/DriverManagerScreen.cpp b/UI/DriverManagerScreen.cpp
index fd1209b876..7c6c392fa1 100644
--- a/UI/DriverManagerScreen.cpp
+++ b/UI/DriverManagerScreen.cpp
@@ -6,6 +6,7 @@
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Common/UI/PopupScreens.h"
+#include "Common/UI/Notice.h"
#include "Core/Config.h"
#include "Core/System.h"
diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp
index 65c54ecd2e..71848f59f8 100644
--- a/UI/GameScreen.cpp
+++ b/UI/GameScreen.cpp
@@ -24,6 +24,7 @@
#include "Common/UI/View.h"
#include "Common/UI/ViewGroup.h"
#include "Common/UI/PopupScreens.h"
+#include "Common/UI/Notice.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Data/Text/Parsers.h"
#include "Common/Data/Encoding/Utf8.h"
diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp
index 34881d23dc..ab5b83e71a 100644
--- a/UI/GameSettingsScreen.cpp
+++ b/UI/GameSettingsScreen.cpp
@@ -29,6 +29,7 @@
#include "Common/UI/View.h"
#include "Common/UI/ViewGroup.h"
#include "Common/UI/Context.h"
+#include "Common/UI/Notice.h"
#include "Common/Render/ManagedTexture.h"
#include "Common/VR/PPSSPPVR.h"
#include "Common/BitSet.h"
@@ -37,7 +38,6 @@
#include "Common/System/OSD.h"
#include "Common/System/NativeApp.h"
#include "Common/Data/Color/RGBAUtil.h"
-#include "Common/Math/curves.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/UI/PopupScreens.h"
@@ -66,8 +66,6 @@
#include "Common/File/FileUtil.h"
#include "Common/File/AndroidContentURI.h"
-#include "Common/OSVersion.h"
-#include "Common/TimeUtil.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
@@ -79,11 +77,7 @@
#include "Core/HLE/sceUsbCam.h"
#include "Core/HLE/sceUsbMic.h"
#include "Core/HLE/sceUtility.h"
-#include "GPU/Common/TextureReplacer.h"
#include "GPU/Common/PostShader.h"
-#include "GPU/Common/FramebufferManagerCommon.h"
-
-#include "Core/Core.h" // for Core_IsStepping
#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
#include "UI/DarwinFileSystemServices.h"
diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp
index 1330eec76c..89e8b3d7bf 100644
--- a/UI/InstallZipScreen.cpp
+++ b/UI/InstallZipScreen.cpp
@@ -18,6 +18,7 @@
#include "Common/UI/UI.h"
#include "Common/UI/View.h"
#include "Common/UI/ViewGroup.h"
+#include "Common/UI/Notice.h"
#include "Common/StringUtils.h"
#include "Common/File/FileUtil.h"
diff --git a/UI/MemStickScreen.cpp b/UI/MemStickScreen.cpp
index 9e1086b057..69b9d3d68e 100644
--- a/UI/MemStickScreen.cpp
+++ b/UI/MemStickScreen.cpp
@@ -40,6 +40,7 @@
#include "Common/Thread/ThreadManager.h"
#include "Common/UI/ScrollView.h"
+#include "Common/UI/Notice.h"
#include "Core/Config.h"
#include "Core/Reporting.h"
diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp
index 137765a09c..9799d5c9c3 100644
--- a/UI/OnScreenDisplay.cpp
+++ b/UI/OnScreenDisplay.cpp
@@ -14,6 +14,7 @@
#include "UI/DebugOverlay.h"
#include "Common/UI/Context.h"
+#include "Common/UI/Notice.h"
#include "Common/System/OSD.h"
#include "Common/TimeUtil.h"
@@ -26,91 +27,6 @@ static inline const char *DeNull(const char *ptr) {
extern bool g_TakeScreenshot;
static const float g_atlasIconSize = 36.0f;
-static const float extraTextScale = 0.7f;
-
-static uint32_t GetNoticeBackgroundColor(NoticeLevel type) {
- // Colors from Infima
- switch (type) {
- case NoticeLevel::ERROR: return 0x3530d5; // danger-darker
- case NoticeLevel::WARN: return 0x009ed9; // warning-darker
- case NoticeLevel::INFO: return 0x706760; // gray-700
- case NoticeLevel::SUCCESS: return 0x008b00; // nice green
- default: return 0x606770;
- }
-}
-
-static ImageID GetOSDIcon(NoticeLevel level) {
- switch (level) {
- case NoticeLevel::INFO: return ImageID("I_INFO");
- case NoticeLevel::ERROR: return ImageID("I_CROSS");
- case NoticeLevel::WARN: return ImageID("I_WARNING");
- case NoticeLevel::SUCCESS: return ImageID("I_CHECKMARK");
- default: return ImageID::invalid();
- }
-}
-
-static NoticeLevel GetNoticeLevel(OSDType type) {
- switch (type) {
- case OSDType::MESSAGE_INFO:
- return NoticeLevel::INFO;
- case OSDType::MESSAGE_ERROR:
- case OSDType::MESSAGE_ERROR_DUMP:
- case OSDType::MESSAGE_CENTERED_ERROR:
- return NoticeLevel::ERROR;
- case OSDType::MESSAGE_WARNING:
- case OSDType::MESSAGE_CENTERED_WARNING:
- return NoticeLevel::WARN;
- case OSDType::MESSAGE_SUCCESS:
- return NoticeLevel::SUCCESS;
- default:
- return NoticeLevel::SUCCESS;
- }
-}
-
-// Align only matters here for the ASCII-only flag.
-static void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float maxWidth, float *width, float *height, float *height1) {
- float iconW = 0.0f;
- float iconH = 0.0f;
- if (!iconName.empty() && !startsWith(iconName, "I_")) { // Check for atlas image. Bit hacky, but we choose prefixes for icon IDs anyway in a way that this is safe.
- // Normal entry but with a cached icon.
- int iconWidth, iconHeight;
- if (g_iconCache.GetDimensions(iconName, &iconWidth, &iconHeight)) {
- *width += 5.0f + iconWidth;
- iconW = iconWidth;
- iconH = iconHeight;
- }
- } else {
- ImageID iconID = iconName.empty() ? GetOSDIcon(level) : ImageID(iconName.c_str());
- if (iconID.isValid()) {
- dc.Draw()->GetAtlas()->measureImage(iconID, &iconW, &iconH);
- }
- }
-
- float chromeWidth = iconW + 5.0f + 12.0f;
- float availableWidth = maxWidth - chromeWidth;
-
- // OK, now that we have figured out how much space we have for the text, we can measure it (with wrapping if needed).
- // We currently don't wrap the title.
-
- float titleWidth, titleHeight;
- dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text, &titleWidth, &titleHeight, align);
-
- *width = std::min(titleWidth, availableWidth);
- *height1 = titleHeight;
-
- float width2 = 0.0f, height2 = 0.0f;
- if (!details.empty()) {
- dc.MeasureTextRect(dc.GetTheme().uiFont, extraTextScale, extraTextScale, details, availableWidth, &width2, &height2, align | FLAG_WRAP_TEXT);
- *width = std::max(*width, width2);
- }
-
- *width += chromeWidth;
- if (height2 == 0.0f && iconH < 2.0f * *height1) {
- // Center vertically using the icon.
- *height1 = std::max(*height1, iconH + 2.0f);
- }
- *height = std::max(*height1 + height2 + 8.0f, iconH + 5.0f);
-}
// Align only matters here for the ASCII-only flag.
static void MeasureOSDEntry(const UIContext &dc, const OnScreenDisplay::Entry &entry, int align, float maxWidth, float *width, float *height, float *height1) {
@@ -124,74 +40,6 @@ static void MeasureOSDEntry(const UIContext &dc, const OnScreenDisplay::Entry &e
}
}
-static void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float alpha, OSDMessageFlags flags, float timeVal) {
- UI::Drawable background = UI::Drawable(colorAlpha(GetNoticeBackgroundColor(level), alpha));
-
- dc.SetFontStyle(dc.GetTheme().uiFont);
-
- uint32_t foreGround = whiteAlpha(alpha);
-
- if (!(flags & OSDMessageFlags::Transparent)) {
- dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha);
- dc.FillRect(background, bounds);
- }
-
- float iconW = 0.0f;
- float iconH = 0.0f;
- if (!iconName.empty() && !startsWith(iconName, "I_")) {
- dc.Flush();
- // Normal entry but with a cached icon.
- Draw::Texture *texture = g_iconCache.BindIconTexture(&dc, iconName);
- if (texture) {
- iconW = texture->Width();
- iconH = texture->Height();
- dc.Draw()->DrawTexRect(Bounds(bounds.x + 2.5f, bounds.y + 2.5f, iconW, iconH), 0.0f, 0.0f, 1.0f, 1.0f, foreGround);
- dc.Flush();
- dc.RebindTexture();
- }
- dc.Begin();
- } else {
- ImageID iconID = iconName.empty() ? GetOSDIcon(level) : ImageID(iconName.c_str());
- if (iconID.isValid()) {
- // Atlas icon.
- dc.Draw()->GetAtlas()->measureImage(iconID, &iconW, &iconH);
- if (!iconName.empty()) {
- Bounds iconBounds = Bounds(bounds.x + 2.5f, bounds.y + 2.5f, iconW, iconH);
- // If it's not a preset OSD icon, give it some background to blend in. The RA icon for example
- // easily melts into the orange of warnings otherwise.
- dc.FillRect(UI::Drawable(0x50000000), iconBounds.Expand(2.0f));
- }
-
- if (flags & (OSDMessageFlags::SpinLeft | OSDMessageFlags::SpinRight)) {
- const float direction = (flags & OSDMessageFlags::SpinLeft) ? -1.5f : 1.5f;
- dc.DrawImageRotated(iconID, bounds.x + 2.5f + iconW * 0.5f, bounds.y + 2.5f + iconW * 0.5f, 1.0f, direction * timeVal, foreGround, false);
- } else {
- dc.DrawImageVGradient(iconID, foreGround, foreGround, Bounds(bounds.x + 2.5f, bounds.y + 2.5f, iconW, iconH));
- }
- }
- }
-
- // Make room
- bounds.x += iconW + 5.0f;
- bounds.w -= iconW + 5.0f;
-
- Bounds primaryBounds = bounds;
- primaryBounds.h = height1;
-
- dc.DrawTextShadowRect(text, primaryBounds.Inset(2.0f, 0.0f, 1.0f, 0.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_VCENTER | FLAG_ELLIPSIZE_TEXT);
-
- if (!details.empty()) {
- Bounds bottomTextBounds = bounds.Inset(3.0f, height1 + 5.0f, 3.0f, 3.0f);
- if (!(flags & OSDMessageFlags::Transparent)) {
- UI::Drawable backgroundDark = UI::Drawable(colorAlpha(darkenColor(GetNoticeBackgroundColor(level)), alpha));
- dc.FillRect(backgroundDark, bottomTextBounds);
- }
- dc.SetFontScale(extraTextScale, extraTextScale);
- dc.DrawTextRect(details, bottomTextBounds.Inset(1.0f, 1.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_LEFT | FLAG_WRAP_TEXT);
- }
- dc.SetFontScale(1.0f, 1.0f);
-}
-
static void RenderOSDEntry(UIContext &dc, const OnScreenDisplay::Entry &entry, Bounds bounds, float height1, int align, float alpha, float now) {
if (entry.type == OSDType::ACHIEVEMENT_UNLOCKED) {
const rc_client_achievement_t * achievement = rc_client_get_achievement_info(Achievements::GetClient(), entry.numericID);
diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h
index a26d812b44..63991ddb84 100644
--- a/UI/OnScreenDisplay.h
+++ b/UI/OnScreenDisplay.h
@@ -51,39 +51,3 @@ private:
OnScreenMessagesView *osmView_ = nullptr;
};
-enum class NoticeLevel {
- SUCCESS,
- INFO,
- WARN,
- ERROR,
-};
-
-class NoticeView : public UI::InertView {
-public:
- NoticeView(NoticeLevel level, std::string_view text, std::string_view detailsText, UI::LayoutParams *layoutParams = 0)
- : InertView(layoutParams), level_(level), text_(text), detailsText_(detailsText), iconName_("") {}
-
- void SetIconName(std::string_view name) {
- iconName_ = name;
- }
- void SetText(std::string_view text) {
- text_ = text;
- }
- void SetLevel(NoticeLevel level) {
- level_ = level;
- }
- void SetSquishy(bool squishy) {
- squishy_ = squishy;
- }
-
- void GetContentDimensionsBySpec(const UIContext &dc, UI::MeasureSpec horiz, UI::MeasureSpec vert, float &w, float &h) const override;
- void Draw(UIContext &dc) override;
-
-private:
- std::string text_;
- std::string detailsText_;
- std::string iconName_;
- NoticeLevel level_;
- mutable float height1_ = 0.0f;
- bool squishy_ = false;
-};
diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp
index e3a6531f4c..bff60a66c2 100644
--- a/UI/PauseScreen.cpp
+++ b/UI/PauseScreen.cpp
@@ -24,6 +24,7 @@
#include "Common/UI/Context.h"
#include "Common/UI/UIScreen.h"
#include "Common/UI/PopupScreens.h"
+#include "Common/UI/Notice.h"
#include "Common/GPU/thin3d.h"
#include "Common/Data/Text/I18n.h"
diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp
index ba6fa19608..264e1a5dfc 100644
--- a/UI/RemoteISOScreen.cpp
+++ b/UI/RemoteISOScreen.cpp
@@ -36,6 +36,7 @@
#include "Common/File/PathBrowser.h"
#include "Common/UI/PopupScreens.h"
+#include "Common/UI/Notice.h"
#include "Common/Data/Format/JSONReader.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Common.h"
diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp
index 6fee17a5ad..d75357e6b8 100644
--- a/UI/RetroAchievementScreens.cpp
+++ b/UI/RetroAchievementScreens.cpp
@@ -7,6 +7,7 @@
#include "Common/UI/Context.h"
#include "Common/UI/IconCache.h"
#include "Common/UI/PopupScreens.h"
+#include "Common/UI/Notice.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
diff --git a/UI/SystemInfoScreen.cpp b/UI/SystemInfoScreen.cpp
index 49f17ac6c5..42a47ccb8e 100644
--- a/UI/SystemInfoScreen.cpp
+++ b/UI/SystemInfoScreen.cpp
@@ -18,6 +18,7 @@
#include "Common/Render/Text/draw_text.h"
#include "Common/System/Request.h"
#include "Common/UI/Context.h"
+#include "Common/UI/Notice.h"
#include "Core/System.h"
#include "Core/Config.h"
#include "GPU/GPUState.h" // ugh
diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj
index b4ab61a01d..3ac226ebae 100644
--- a/UWP/CommonUWP/CommonUWP.vcxproj
+++ b/UWP/CommonUWP/CommonUWP.vcxproj
@@ -217,6 +217,7 @@
+
@@ -385,6 +386,7 @@
+
diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters
index 454bbdc19b..865a3c9a95 100644
--- a/UWP/CommonUWP/CommonUWP.vcxproj.filters
+++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters
@@ -544,6 +544,9 @@
ext\aemu_postoffice
+
+ UI
+
@@ -1041,6 +1044,9 @@
ext\aemu_postoffice
+
+ UI
+
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index e5292feaa5..ee34b38834 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -361,6 +361,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Common/UI/Context.cpp \
$(SRC)/Common/UI/UIScreen.cpp \
$(SRC)/Common/UI/Tween.cpp \
+ $(SRC)/Common/UI/Notice.cpp \
$(SRC)/Common/UI/IconCache.cpp \
$(SRC)/Common/UI/View.cpp \
$(SRC)/Common/UI/ViewGroup.cpp \
diff --git a/libretro/Makefile.common b/libretro/Makefile.common
index bd189bace2..0f1cbb24a4 100644
--- a/libretro/Makefile.common
+++ b/libretro/Makefile.common
@@ -525,6 +525,7 @@ SOURCES_CXX += \
$(COMMONDIR)/UI/UI.cpp \
$(COMMONDIR)/UI/Context.cpp \
$(COMMONDIR)/UI/UIScreen.cpp \
+ $(COMMONDIR)/UI/Notice.cpp \
$(COMMONDIR)/UI/Tween.cpp \
$(COMMONDIR)/UI/IconCache.cpp \
$(COMMONDIR)/UI/View.cpp \