From 2db31928e9965eeb3e3e21592fbc3daa3e043be6 Mon Sep 17 00:00:00 2001 From: Nemirtingas Date: Wed, 4 Sep 2019 19:31:31 +0200 Subject: [PATCH] Notifications --- overlay_experimental/steam_overlay.cpp | 93 +++++++++++++++++++------- overlay_experimental/steam_overlay.h | 23 ++++++- 2 files changed, 90 insertions(+), 26 deletions(-) diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 69d90b6..ef9b4f1 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -170,6 +170,18 @@ void Steam_Overlay::ShowOverlay(bool state) overlay_state_changed = true; } +void Steam_Overlay::NotifyUser(friend_window_state& friend_state, std::string const& message) +{ + if (!(friend_state.window_state & window_state_show)) + { + friend_state.window_state |= window_state_need_attention; +#ifdef __WINDOWS__ + PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY); +#endif + AddNotification(message); + } +} + void Steam_Overlay::SetLobbyInvite(Friend friendId, uint64 lobbyId) { if (!Ready()) @@ -184,12 +196,7 @@ void Steam_Overlay::SetLobbyInvite(Friend friendId, uint64 lobbyId) frd.window_state |= window_state_lobby_invite; // Make sure don't have rich presence invite and a lobby invite (it should not happen but who knows) frd.window_state &= ~window_state_rich_invite; - - if (!(frd.window_state & window_state_show)) - { - frd.window_state |= window_state_need_attention; - // TODO: Push a notification - } + NotifyUser(i->second, i->first.name() + " invited you to join a game"); } } @@ -207,12 +214,7 @@ void Steam_Overlay::SetRichInvite(Friend friendId, const char* connect_str) frd.window_state |= window_state_rich_invite; // Make sure don't have rich presence invite and a lobby invite (it should not happen but who knows) frd.window_state &= ~window_state_lobby_invite; - - if (!(frd.window_state & window_state_show)) - { - frd.window_state |= window_state_need_attention; - // TODO: Push a notification - } + NotifyUser(i->second, i->first.name() + " invited you to join a game"); } } @@ -232,6 +234,14 @@ void Steam_Overlay::FriendDisconnect(Friend _friend) friends.erase(it); } +void Steam_Overlay::AddNotification(std::string const& message) +{ + Notification notif; + notif.message = message; + notif.start_time = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + notifications.emplace_back(notif); +} + bool Steam_Overlay::FriendHasLobby(uint64 friend_id) { Steam_Friends* steamFriends = get_steam_client()->steam_friends; @@ -304,9 +314,6 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st { if (state.window_state & window_state_need_attention && ImGui::IsWindowFocused()) { -#ifdef __WINDOWS__ - PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY); -#endif state.window_state &= ~window_state_need_attention; } @@ -378,15 +385,49 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st ImGui::End(); } -void Steam_Overlay::BuildNotifications() +void Steam_Overlay::BuildNotifications(int width, int height) { - //ImGui::SetNextWindowPos(ImVec2{ (float)width - 300, (float)height - 80 }); - //ImGui::SetNextWindowSize(ImVec2{ 300.0, 80.0 }); - //ImGui::Begin("##notification", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse - // | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing - // | ImGuiWindowFlags_NoDecoration); - // - //ImGui::End(); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + int i = 0; + for (auto it = notifications.begin(); it != notifications.end(); ++it, ++i) + { + auto elapsed_notif = now - it->start_time; + + if ( elapsed_notif < Notification::fade_in) + { + float alpha = Notification::max_alpha * (elapsed_notif.count() / static_cast(Notification::fade_in.count())); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, alpha)); + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(Notification::r, Notification::g, Notification::b, alpha)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 255, alpha*2)); + } + else if ( elapsed_notif > Notification::fade_out_start) + { + float alpha = Notification::max_alpha * ((Notification::show_time - elapsed_notif).count() / static_cast(Notification::fade_out.count())); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, alpha)); + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(Notification::r, Notification::g, Notification::b, alpha)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 255, alpha*2)); + } + else + { + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, Notification::max_alpha)); + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(Notification::r, Notification::g, Notification::b, Notification::max_alpha)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 255, Notification::max_alpha*2)); + } + + ImGui::SetNextWindowPos(ImVec2((float)width - Notification::width, (float)Notification::height * i )); + ImGui::SetNextWindowSize(ImVec2( Notification::width, Notification::height )); + ImGui::Begin(std::to_string(10000+i).c_str(), nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | + ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMouseInputs); + + ImGui::TextWrapped("%s", it->message.c_str()); + + ImGui::End(); + + ImGui::PopStyleColor(3); + } + notifications.erase(std::remove_if(notifications.begin(), notifications.end(), [&now](Notification &item) { + return (now - item.start_time) > Notification::show_time; + }), notifications.end()); } // Try to make this function as short as possible or it might affect game's fps. @@ -397,6 +438,8 @@ void Steam_Overlay::OverlayProc( int width, int height ) if (!Ready()) return; + BuildNotifications(width, height); + if (show_overlay) { int friend_size = friends.size(); @@ -445,8 +488,6 @@ void Steam_Overlay::OverlayProc( int width, int height ) } ImGui::End(); }// if(show_overlay) - - BuildNotifications(); } void Steam_Overlay::Callback(Common_Message *msg) @@ -465,6 +506,8 @@ void Steam_Overlay::Callback(Common_Message *msg) { friend_info->second.window_state |= window_state_need_attention; } + + AddNotification(friend_info->first.name() + " says: " + steam_message.message()); } } } diff --git a/overlay_experimental/steam_overlay.h b/overlay_experimental/steam_overlay.h index 45fd514..fe4aa75 100644 --- a/overlay_experimental/steam_overlay.h +++ b/overlay_experimental/steam_overlay.h @@ -39,6 +39,22 @@ struct Friend_Less } }; +struct Notification +{ + static constexpr float width = 200.0; + static constexpr float height = 60.0; + static constexpr std::chrono::milliseconds fade_in = std::chrono::milliseconds(2000); + static constexpr std::chrono::milliseconds fade_out = std::chrono::milliseconds(2000); + static constexpr std::chrono::milliseconds show_time = std::chrono::milliseconds(6000) + fade_in + fade_out; + static constexpr std::chrono::milliseconds fade_out_start = show_time - fade_out; + static constexpr float r = 0.16; + static constexpr float g = 0.29; + static constexpr float b = 0.48; + static constexpr float max_alpha = 0.5f; + std::chrono::seconds start_time; + std::string message; +}; + #ifndef NO_OVERLAY class Steam_Overlay @@ -60,6 +76,7 @@ class Steam_Overlay // Callback infos std::queue has_friend_action; + std::vector notifications; bool overlay_state_changed; Steam_Overlay(Steam_Overlay const&) = delete; @@ -76,12 +93,14 @@ class Steam_Overlay bool FriendHasLobby(uint64 friend_id); bool IHaveLobby(); + void NotifyUser(friend_window_state& friend_state, std::string const& message); + // Right click on friend void BuildContextMenu(Friend const& frd, friend_window_state &state); // Double click on friend void BuildFriendWindow(Friend const& frd, friend_window_state &state); // Notifications like achievements, chat and invitations - void BuildNotifications(); + void BuildNotifications(int width, int height); public: Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking *network); @@ -111,6 +130,8 @@ public: void FriendConnect(Friend _friend); void FriendDisconnect(Friend _friend); + + void AddNotification(std::string const& message); }; #else