@@ -22,6 +22,8 @@ void Overlay::PostInitialize()
2222 }
2323
2424 m_initialized = true ;
25+
26+ m_startTime = std::chrono::steady_clock::now ();
2527 }
2628}
2729
@@ -195,12 +197,40 @@ void Overlay::Update()
195197 }
196198 }
197199
200+ // Display binding in bottom right corner for 5 seconds
201+ if (!Bindings::IsFirstTimeSetup () && !m_bindHintShown)
202+ {
203+ const auto currentTime = std::chrono::steady_clock::now ();
204+ if ((currentTime - m_startTime) < std::chrono::seconds (5 ))
205+ {
206+ if (m_notificationString.empty ())
207+ {
208+ auto overlayBindCode = CET::Get ().GetBindings ().GetBindCodeForModBind (Bindings::GetOverlayToggleModBind ());
209+
210+ m_notificationString = " CET Overlay Bind: " ;
211+ m_notificationString += VKBindings::GetBindString (overlayBindCode);
212+ }
213+
214+ m_drawNotification = true ;
215+ }
216+ else
217+ {
218+ m_bindHintShown = true ;
219+ m_drawNotification = false ;
220+ m_notificationString.clear ();
221+ }
222+ }
223+
224+ if (m_drawNotification)
225+ DrawNotification ();
226+
198227 if (!m_enabled)
199228 return ;
200229
201230 const auto [width, height] = CET::Get ().GetD3D12 ().GetResolution ();
202231 const auto heightLimit = 2 * ImGui::GetFrameHeight () + 2 * ImGui::GetStyle ().WindowPadding .y ;
203- ImGui::SetNextWindowPos ({width * 0 .25f , height * 0 .05f }, ImGuiCond_FirstUseEver);
232+ ImGui::SetNextWindowBgAlpha (1.0 );
233+ ImGui::SetNextWindowPos ({width * 0 .25f , height * 0 .05f });
204234 ImGui::SetNextWindowSizeConstraints ({width * 0 .5f , heightLimit}, {FLT_MAX, heightLimit});
205235 if (ImGui::Begin (" Cyber Engine Tweaks" ))
206236 DrawToolbar ();
@@ -346,3 +376,34 @@ void Overlay::DrawToolbar()
346376 if (ImGui::Button (" Reload all mods" , ImVec2 (itemWidth, 0 )))
347377 m_vm.ReloadAllMods ();
348378}
379+
380+ // TODO: Multiple notifications?
381+ void Overlay::DrawNotification ()
382+ {
383+ // ID must be unique for different messages, so why not use the FNV1a hash?
384+ const auto imGuiID = RED4ext::FNV1a32 (m_notificationString.c_str ());
385+ const auto [width, height] = CET::Get ().GetD3D12 ().GetResolution ();
386+
387+ const auto notificationWidth = ImGui::CalcTextSize (m_notificationString.c_str ()).x + 2 * ImGui::GetStyle ().WindowPadding .x ;
388+ const auto notificationHeight = ImGui::CalcTextSize (m_notificationString.c_str ()).y + 2 * ImGui::GetStyle ().WindowPadding .y ;
389+
390+ ImGui::SetNextWindowBgAlpha (0.5 );
391+ ImGui::SetNextWindowPos ({ImGui::GetStyle ().WindowPadding .x , height - (notificationHeight + ImGui::GetStyle ().WindowPadding .y )});
392+ ImGui::SetNextWindowSize ({notificationWidth, notificationHeight});
393+ if (ImGui::Begin (std::format (" ##{}" , imGuiID).c_str (), nullptr , ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings))
394+ {
395+ ImGui::TextUnformatted (m_notificationString.c_str ());
396+ }
397+ ImGui::End ();
398+ }
399+
400+ void Overlay::ShowNotification (const std::string& notification)
401+ {
402+ m_notificationString = notification;
403+ m_drawNotification = true ;
404+ }
405+
406+ void Overlay::HideNotification ()
407+ {
408+ m_drawNotification = false ;
409+ }
0 commit comments