[UI] Host Notification: Replace previous notification in case of new one

This commit is contained in:
Gliniak 2024-08-27 20:48:22 +02:00
parent ee210db096
commit 9c8a575b76
5 changed files with 58 additions and 25 deletions

View File

@ -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<ui::ImGuiNotification*> guest_notifications = {};
std::vector<ui::ImGuiNotification*> 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;
});
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 (notification->GetNotificationType() == NotificationType::Host &&
!was_host_notification_drawn) {
was_host_notification_drawn = true;
notification->Draw();
if (host_notifications.size() > 0) {
host_notifications.at(0)->Draw();
if (host_notifications.size() > 1) {
host_notifications.at(0)->SetDeletionPending();
}
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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) {

View File

@ -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;
};