From 9c8a575b762f363b2b41908a1394685f24d93a0c Mon Sep 17 00:00:00 2001 From: Gliniak Date: Tue, 27 Aug 2024 20:48:22 +0200 Subject: [PATCH] [UI] Host Notification: Replace previous notification in case of new one --- src/xenia/ui/imgui_drawer.cc | 36 ++++++++++++++++--------- src/xenia/ui/imgui_host_notification.cc | 9 +++++-- src/xenia/ui/imgui_host_notification.h | 3 +++ src/xenia/ui/imgui_notification.cc | 5 ++-- src/xenia/ui/imgui_notification.h | 30 ++++++++++++++------- 5 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/xenia/ui/imgui_drawer.cc b/src/xenia/ui/imgui_drawer.cc index 735f4ca4f..d9d5f6b9b 100644 --- a/src/xenia/ui/imgui_drawer.cc +++ b/src/xenia/ui/imgui_drawer.cc @@ -467,20 +467,32 @@ void ImGuiDrawer::Draw(UIDrawContext& ui_draw_context) { dialog_loop_next_index_ = SIZE_MAX; if (!notifications_.empty()) { - bool was_guest_notification_drawn = false; - bool was_host_notification_drawn = false; + std::vector guest_notifications = {}; + std::vector host_notifications = {}; - for (const auto& notification : notifications_) { - if (notification->GetNotificationType() == NotificationType::Guest && - !was_guest_notification_drawn) { - was_guest_notification_drawn = true; - notification->Draw(); - } + std::copy_if(notifications_.cbegin(), notifications_.cend(), + std::back_inserter(guest_notifications), + [](ui::ImGuiNotification* notification) { + return notification->GetNotificationType() == + NotificationType::Guest; + }); - if (notification->GetNotificationType() == NotificationType::Host && - !was_host_notification_drawn) { - was_host_notification_drawn = true; - notification->Draw(); + std::copy_if(notifications_.cbegin(), notifications_.cend(), + std::back_inserter(host_notifications), + [](ui::ImGuiNotification* notification) { + return notification->GetNotificationType() == + NotificationType::Host; + }); + + if (guest_notifications.size() > 0) { + guest_notifications.at(0)->Draw(); + } + + if (host_notifications.size() > 0) { + host_notifications.at(0)->Draw(); + + if (host_notifications.size() > 1) { + host_notifications.at(0)->SetDeletionPending(); } } } diff --git a/src/xenia/ui/imgui_host_notification.cc b/src/xenia/ui/imgui_host_notification.cc index af8371a2d..a7ebbea54 100644 --- a/src/xenia/ui/imgui_host_notification.cc +++ b/src/xenia/ui/imgui_host_notification.cc @@ -25,7 +25,7 @@ ImGuiHostNotification::ImGuiHostNotification(ui::ImGuiDrawer* imgui_drawer, uint8_t position_id) : ImGuiNotification(imgui_drawer, NotificationType::Host, title, description, user_index, position_id) { - SetCreationTime(Clock::QueryHostUptimeMillis()); + SetCreationTime(Clock::QueryHostUptimeMillis() + notification_initial_delay); imgui_drawer->AddNotification(this); } @@ -39,11 +39,16 @@ const ImVec2 ImGuiHostNotification::CalculateNotificationSize(ImVec2 text_size, } void HostNotificationWindow::OnDraw(ImGuiIO& io) { - if (IsNotificationClosingTime()) { + if (IsNotificationClosingTime() || IsMarkedForDeletion()) { delete this; return; } + // Adding 200ms of delay in case of notification spam. + if (Clock::QueryHostUptimeMillis() < GetCreationTime()) { + return; + } + const std::string longest_notification_text_line = GetTitle().size() > GetDescription().size() ? GetTitle().c_str() : GetDescription().c_str(); diff --git a/src/xenia/ui/imgui_host_notification.h b/src/xenia/ui/imgui_host_notification.h index 58983826a..b6bbe0478 100644 --- a/src/xenia/ui/imgui_host_notification.h +++ b/src/xenia/ui/imgui_host_notification.h @@ -26,6 +26,9 @@ class ImGuiHostNotification : public ImGuiNotification { ~ImGuiHostNotification(); protected: + const uint64_t notification_initial_delay = + std::chrono::milliseconds(200).count(); + const ImVec2 CalculateNotificationSize(ImVec2 text_size, float scale) override; diff --git a/src/xenia/ui/imgui_notification.cc b/src/xenia/ui/imgui_notification.cc index 410c9766c..cd15ad5b3 100644 --- a/src/xenia/ui/imgui_notification.cc +++ b/src/xenia/ui/imgui_notification.cc @@ -37,7 +37,7 @@ ImGuiNotification::~ImGuiNotification() { void ImGuiNotification::Draw() { OnDraw(imgui_drawer_->GetIO()); } const NotificationAlignment ImGuiNotification::GetNotificationAlignment( - const uint8_t notification_position_id) { + const uint8_t notification_position_id) const { NotificationAlignment alignment = NotificationAlignment::kAlignUnknown; if (notification_position_id >= @@ -60,7 +60,8 @@ const NotificationAlignment ImGuiNotification::GetNotificationAlignment( } const ImVec2 ImGuiNotification::CalculateNotificationScreenPosition( - ImVec2 screen_size, ImVec2 window_size, uint8_t notification_position_id) { + ImVec2 screen_size, ImVec2 window_size, + uint8_t notification_position_id) const { ImVec2 result = {NAN, NAN}; if (window_size.x >= screen_size.x || window_size.y >= screen_size.y) { diff --git a/src/xenia/ui/imgui_notification.h b/src/xenia/ui/imgui_notification.h index 7212235cc..e16a73de2 100644 --- a/src/xenia/ui/imgui_notification.h +++ b/src/xenia/ui/imgui_notification.h @@ -63,14 +63,21 @@ class ImGuiNotification { return notification_type_; } + void SetDeletionPending() { marked_for_deletion_ = true; } + protected: ImGuiDrawer* GetDrawer() { return imgui_drawer_; } - const bool IsNotificationClosingTime() { - return Clock::QueryHostUptimeMillis() - creation_time_ > time_to_close_; + const bool IsNotificationClosingTime() const { + const uint64_t current_time = Clock::QueryHostUptimeMillis(); + // We're before showing notification + if (current_time < creation_time_) { + return false; + } + return current_time - creation_time_ > time_to_close_; } - const std::string GetNotificationText() { + const std::string GetNotificationText() const { std::string text = title_; if (!description_.empty()) { @@ -83,17 +90,20 @@ class ImGuiNotification { creation_time_ = new_creation_time; } - const std::string GetTitle() { return title_; } - const std::string GetDescription() { return description_; } + const bool IsMarkedForDeletion() const { return marked_for_deletion_; } + const std::string GetTitle() const { return title_; } + const std::string GetDescription() const { return description_; } - const uint8_t GetPositionId() { return position_; } - const uint8_t GetUserIndex() { return user_index_; } + const uint8_t GetPositionId() const { return position_; } + const uint8_t GetUserIndex() const { return user_index_; } + const uint64_t GetCreationTime() const { return creation_time_; } const NotificationAlignment GetNotificationAlignment( - const uint8_t notification_position_id); + const uint8_t notification_position_id) const; const ImVec2 CalculateNotificationScreenPosition( - ImVec2 screen_size, ImVec2 window_size, uint8_t notification_position_id); + ImVec2 screen_size, ImVec2 window_size, + uint8_t notification_position_id) const; virtual const ImVec2 CalculateNotificationSize(ImVec2 text_size, float scale) = 0; @@ -114,6 +124,8 @@ class ImGuiNotification { std::string title_; std::string description_; + bool marked_for_deletion_ = false; + ImGuiDrawer* imgui_drawer_ = nullptr; };