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 \