mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-14 01:59:34 +01:00
Merge pull request #18065 from hrydgard/dismiss-notifications
Add ability to dismiss notifications
This commit is contained in:
12 files changed
+105
-11
No files matched your search
@@ -39,6 +39,13 @@ float OnScreenDisplay::SidebarAlpha() const {
|
||||
return saturatef(1.0f - ((float)timeSinceNudge - 0.1f) * 4.0f);
|
||||
}
|
||||
|
||||
void OnScreenDisplay::DismissEntry(size_t index, double now) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
if (index < entries_.size() && entries_[index].type != OSDType::ACHIEVEMENT_CHALLENGE_INDICATOR) {
|
||||
entries_[index].endTime = std::min(now + FadeoutTime(), entries_[index].endTime);
|
||||
}
|
||||
}
|
||||
|
||||
void OnScreenDisplay::Show(OSDType type, const std::string &text, const std::string &text2, const std::string &icon, float duration_s, const char *id) {
|
||||
// Automatic duration based on type.
|
||||
if (duration_s <= 0.0f) {
|
||||
|
||||
@@ -87,6 +87,9 @@ public:
|
||||
|
||||
std::vector<Entry> Entries();
|
||||
|
||||
// TODO: Use something more stable than the index.
|
||||
void DismissEntry(size_t index, double now);
|
||||
|
||||
static float FadeinTime() { return 0.1f; }
|
||||
static float FadeoutTime() { return 0.25f; }
|
||||
|
||||
|
||||
+12
-2
@@ -48,6 +48,9 @@ void ScreenManager::update() {
|
||||
switchToNext();
|
||||
}
|
||||
|
||||
if (overlayScreen_) {
|
||||
overlayScreen_->update();
|
||||
}
|
||||
if (stack_.size()) {
|
||||
stack_.back().screen->update();
|
||||
}
|
||||
@@ -90,8 +93,15 @@ void ScreenManager::touch(const TouchInput &touch) {
|
||||
layer.screen->UnsyncTouch(screen->transformTouch(touch));
|
||||
}
|
||||
} else if (!stack_.empty()) {
|
||||
Screen *screen = stack_.back().screen;
|
||||
stack_.back().screen->UnsyncTouch(screen->transformTouch(touch));
|
||||
// Let the overlay know about touch-downs, to be able to dismiss popups.
|
||||
bool skip = false;
|
||||
if (overlayScreen_ && (touch.flags & TOUCH_DOWN)) {
|
||||
skip = overlayScreen_->UnsyncTouch(overlayScreen_->transformTouch(touch));
|
||||
}
|
||||
if (!skip) {
|
||||
Screen *screen = stack_.back().screen;
|
||||
stack_.back().screen->UnsyncTouch(screen->transformTouch(touch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -59,7 +59,9 @@ public:
|
||||
virtual void deviceLost() {}
|
||||
virtual void deviceRestored() {}
|
||||
|
||||
virtual void UnsyncTouch(const TouchInput &touch) = 0;
|
||||
// Return value of UnsyncTouch is only used to let the overlay screen block touches.
|
||||
virtual bool UnsyncTouch(const TouchInput &touch) = 0;
|
||||
// Return value of UnsyncKey is used to not block certain system keys like volume when unhandled, on Android.
|
||||
virtual bool UnsyncKey(const KeyInput &touch) = 0;
|
||||
virtual void UnsyncAxis(const AxisInput &touch) = 0;
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ bool UIScreen::key(const KeyInput &key) {
|
||||
}
|
||||
}
|
||||
|
||||
void UIScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
bool UIScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
if (ClickDebug && root_ && (touch.flags & TOUCH_DOWN)) {
|
||||
INFO_LOG(SYSTEM, "Touch down!");
|
||||
std::vector<UI::View *> views;
|
||||
@@ -96,6 +96,7 @@ void UIScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
ev.type = QueuedEventType::TOUCH;
|
||||
ev.touch = touch;
|
||||
eventQueue_.push_back(ev);
|
||||
return false;
|
||||
}
|
||||
|
||||
void UIScreen::UnsyncAxis(const AxisInput &axis) {
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
virtual bool key(const KeyInput &key);
|
||||
virtual void axis(const AxisInput &axis);
|
||||
|
||||
void UnsyncTouch(const TouchInput &touch) override;
|
||||
bool UnsyncTouch(const TouchInput &touch) override;
|
||||
bool UnsyncKey(const KeyInput &key) override;
|
||||
void UnsyncAxis(const AxisInput &axis) override;
|
||||
|
||||
|
||||
+12
-1
@@ -858,7 +858,19 @@ void SystemInfoScreen::CreateTabs() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
LinearLayout *internals = AddTab("DevSystemInfoInternals", si->T("Internals"));
|
||||
CreateInternalsTab(internals);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemInfoScreen::CreateInternalsTab(UI::ViewGroup *internals) {
|
||||
using namespace UI;
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto si = GetI18NCategory(I18NCat::SYSINFO);
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||
|
||||
internals->Add(new ItemHeader(si->T("Icon cache")));
|
||||
IconCacheStats iconStats = g_iconCache.GetStats();
|
||||
@@ -929,7 +941,6 @@ void SystemInfoScreen::CreateTabs() {
|
||||
});
|
||||
|
||||
static const char *positions[] = { "Bottom Left", "Bottom Center", "Bottom Right", "Top Left", "Top Center", "Top Right", "Center Left", "Center Right", "None" };
|
||||
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||
|
||||
internals->Add(new ItemHeader(ac->T("Notifications")));
|
||||
internals->Add(new PopupMultiChoice(&g_Config.iAchievementsLeaderboardTrackerPos, ac->T("Leaderboard tracker"), positions, 0, ARRAY_SIZE(positions), I18NCat::DIALOG, screenManager()))->SetEnabledPtr(&g_Config.bAchievementsEnable);
|
||||
|
||||
+1
-1
@@ -110,11 +110,11 @@ public:
|
||||
const char *tag() const override { return "SystemInfo"; }
|
||||
|
||||
void CreateTabs() override;
|
||||
|
||||
void update() override;
|
||||
|
||||
protected:
|
||||
bool ShowSearchControls() const override { return false; }
|
||||
void CreateInternalsTab(UI::ViewGroup *internals);
|
||||
};
|
||||
|
||||
class AddressPromptScreen : public PopupScreen {
|
||||
|
||||
+3
-2
@@ -563,14 +563,14 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
|
||||
}
|
||||
}
|
||||
|
||||
void EmuScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
bool EmuScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
System_Notify(SystemNotification::ACTIVITY);
|
||||
|
||||
if (chatMenu_ && chatMenu_->GetVisibility() == UI::V_VISIBLE) {
|
||||
// Avoid pressing touch button behind the chat
|
||||
if (chatMenu_->Contains(touch.x, touch.y)) {
|
||||
chatMenu_->Touch(touch);
|
||||
return;
|
||||
return true;
|
||||
} else if ((touch.flags & TOUCH_DOWN) != 0) {
|
||||
chatMenu_->Close();
|
||||
if (chatButton_)
|
||||
@@ -582,6 +582,7 @@ void EmuScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
if (root_) {
|
||||
root_->Touch(touch);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmuScreen::onVKey(int virtualKeyCode, bool down) {
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
// Note: Unlike your average boring UIScreen, here we override the Unsync* functions
|
||||
// to get minimal latency and full control. We forward to UIScreen when needed.
|
||||
void UnsyncTouch(const TouchInput &touch) override;
|
||||
bool UnsyncTouch(const TouchInput &touch) override;
|
||||
bool UnsyncKey(const KeyInput &key) override;
|
||||
void UnsyncAxis(const AxisInput &axis) override;
|
||||
|
||||
|
||||
+44
-1
@@ -367,6 +367,8 @@ void OnScreenMessagesView::Draw(UIContext &dc) {
|
||||
edges[(size_t)pos].maxWidth = std::max(edges[(size_t)pos].maxWidth, measuredEntry.w);
|
||||
}
|
||||
|
||||
std::vector<ClickZone> dismissZones;
|
||||
|
||||
// Now, perform layout for all 8 edges.
|
||||
for (size_t i = 0; i < (size_t)ScreenEdgePosition::VALUE_COUNT; i++) {
|
||||
if (edges[i].height == 0.0f) {
|
||||
@@ -444,13 +446,30 @@ void OnScreenMessagesView::Draw(UIContext &dc) {
|
||||
|
||||
float alpha = Clamp((float)(entry.endTime - now) * 4.0f, 0.0f, 1.0f);
|
||||
RenderOSDEntry(dc, entry, b, measuredEntry.h1, measuredEntry.align, alpha);
|
||||
|
||||
switch (entry.type) {
|
||||
case OSDType::MESSAGE_INFO:
|
||||
case OSDType::MESSAGE_SUCCESS:
|
||||
case OSDType::MESSAGE_WARNING:
|
||||
case OSDType::MESSAGE_ERROR:
|
||||
case OSDType::MESSAGE_ERROR_DUMP:
|
||||
case OSDType::MESSAGE_FILE_LINK:
|
||||
case OSDType::ACHIEVEMENT_UNLOCKED:
|
||||
// Save the location of the popup, for easy dismissal.
|
||||
dismissZones.push_back(ClickZone{ (int)j, b });
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
y += (measuredEntry.h + 4.0f) * measuredEntry.alpha;
|
||||
}
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(clickMutex_);
|
||||
clickZones_ = dismissZones;
|
||||
}
|
||||
|
||||
std::string OnScreenMessagesView::DescribeText() const {
|
||||
@@ -465,10 +484,34 @@ std::string OnScreenMessagesView::DescribeText() const {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Asynchronous!
|
||||
bool OnScreenMessagesView::Dismiss(float x, float y) {
|
||||
bool dismissed = false;
|
||||
std::lock_guard<std::mutex> lock(clickMutex_);
|
||||
double now = time_now_d();
|
||||
for (auto &zone : clickZones_) {
|
||||
if (zone.bounds.Contains(x, y)) {
|
||||
g_OSD.DismissEntry(zone.index, now);
|
||||
dismissed = true;
|
||||
}
|
||||
}
|
||||
return dismissed;
|
||||
}
|
||||
|
||||
bool OSDOverlayScreen::UnsyncTouch(const TouchInput &touch) {
|
||||
// Don't really need to forward.
|
||||
// UIScreen::UnsyncTouch(touch);
|
||||
if ((touch.flags & TOUCH_DOWN) && osmView_) {
|
||||
return osmView_->Dismiss(touch.x, touch.y);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void OSDOverlayScreen::CreateViews() {
|
||||
root_ = new UI::AnchorLayout();
|
||||
root_->SetTag("OSDOverlayScreen");
|
||||
root_->Add(new OnScreenMessagesView(new UI::AnchorLayoutParams(0.0f, 0.0f, 0.0f, 0.0f)));
|
||||
osmView_ = root_->Add(new OnScreenMessagesView(new UI::AnchorLayoutParams(0.0f, 0.0f, 0.0f, 0.0f)));
|
||||
}
|
||||
|
||||
void OSDOverlayScreen::render() {
|
||||
|
||||
@@ -21,14 +21,30 @@ class OnScreenMessagesView : public UI::InertView {
|
||||
public:
|
||||
OnScreenMessagesView(UI::LayoutParams *layoutParams = nullptr) : UI::InertView(layoutParams) {}
|
||||
void Draw(UIContext &dc) override;
|
||||
bool Dismiss(float x, float y); // Not reusing Touch since it's asynchronous.
|
||||
std::string DescribeText() const override;
|
||||
private:
|
||||
struct ClickZone {
|
||||
int index;
|
||||
Bounds bounds;
|
||||
};
|
||||
|
||||
// Argh, would really like to avoid this.
|
||||
std::mutex clickMutex_;
|
||||
std::vector<ClickZone> clickZones_;
|
||||
};
|
||||
|
||||
class OSDOverlayScreen : public UIScreen {
|
||||
public:
|
||||
const char *tag() const override { return "OSDOverlayScreen"; }
|
||||
|
||||
bool UnsyncTouch(const TouchInput &touch) override;
|
||||
|
||||
void CreateViews() override;
|
||||
void render() override;
|
||||
|
||||
private:
|
||||
OnScreenMessagesView *osmView_ = nullptr;
|
||||
};
|
||||
|
||||
enum class NoticeLevel {
|
||||
|
||||
Reference in new issue
Block a user