summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiritoDv <kiritodev01@gmail.com>2024-12-21 22:13:40 -0600
committerKiritoDv <kiritodev01@gmail.com>2024-12-21 22:13:40 -0600
commit08dc266cfbe055b93806401f0574a02aab5140d5 (patch)
tree161ab265d0ddecbcda904d4900ee2e201c970d5d
parentf4bf6666a971636beb2af8b3006ded5a70ad56dc (diff)
Added notification system from soh
-rw-r--r--src/port/notification/notification.cpp132
-rw-r--r--src/port/notification/notification.h35
-rw-r--r--src/port/ui/ImguiUI.cpp9
3 files changed, 176 insertions, 0 deletions
diff --git a/src/port/notification/notification.cpp b/src/port/notification/notification.cpp
new file mode 100644
index 00000000..94f8ea59
--- /dev/null
+++ b/src/port/notification/notification.cpp
@@ -0,0 +1,132 @@
+
+#include "notification.h"
+#include <libultraship/libultraship.h>
+
+namespace Notification {
+
+static uint32_t nextId = 0;
+static std::vector<Options> notifications = {};
+
+void Window::Draw() {
+ auto vp = ImGui::GetMainViewport();
+
+ const float margin = 30.0f;
+ const float padding = 10.0f;
+
+ int position = CVarGetInteger("gNotifications.Position", 0);
+
+ // Top Left
+ ImVec2 basePosition;
+ switch (position) {
+ case 0: // Top Left
+ basePosition = ImVec2(vp->Pos.x + margin, vp->Pos.y + margin);
+ break;
+ case 1: // Top Right
+ basePosition = ImVec2(vp->Pos.x + vp->Size.x - margin, vp->Pos.y + margin);
+ break;
+ case 2: // Bottom Left
+ basePosition = ImVec2(vp->Pos.x + margin, vp->Pos.y + vp->Size.y - margin);
+ break;
+ case 3: // Bottom Right
+ basePosition = ImVec2(vp->Pos.x + vp->Size.x - margin, vp->Pos.y + vp->Size.y - margin);
+ break;
+ case 4: // Hidden
+ return;
+ }
+
+ ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, CVarGetFloat("gNotifications.BgOpacity", 0.5f)));
+ ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f);
+
+ for (int index = 0; index < notifications.size(); ++index) {
+ auto& notification = notifications[index];
+ int inverseIndex = -ABS(index - (notifications.size() - 1));
+
+ ImGui::SetNextWindowViewport(vp->ID);
+ if (notification.remainingTime < 4.0f) {
+ ImGui::PushStyleVar(ImGuiStyleVar_Alpha, (notification.remainingTime - 1) / 3.0f);
+ } else {
+ ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.0f);
+ }
+
+ ImGui::Begin(("notification#" + std::to_string(notification.id)).c_str(), nullptr,
+ ImGuiWindowFlags_AlwaysAutoResize |
+ ImGuiWindowFlags_NoNav |
+ ImGuiWindowFlags_NoFocusOnAppearing |
+ ImGuiWindowFlags_NoResize |
+ ImGuiWindowFlags_NoDocking |
+ ImGuiWindowFlags_NoTitleBar |
+ ImGuiWindowFlags_NoScrollWithMouse |
+ ImGuiWindowFlags_NoInputs |
+ ImGuiWindowFlags_NoMove |
+ ImGuiWindowFlags_NoScrollbar
+ );
+
+ ImGui::SetWindowFontScale(CVarGetFloat("gNotifications.Size", 1.8f)); // Make this adjustable
+
+ ImVec2 notificationPos;
+ switch (position) {
+ case 0: // Top Left
+ notificationPos = ImVec2(basePosition.x, basePosition.y + ((ImGui::GetWindowSize().y + padding) * inverseIndex));
+ break;
+ case 1: // Top Right
+ notificationPos = ImVec2(basePosition.x - ImGui::GetWindowSize().x, basePosition.y + ((ImGui::GetWindowSize().y + padding) * inverseIndex));
+ break;
+ case 2: // Bottom Left
+ notificationPos = ImVec2(basePosition.x, basePosition.y - ((ImGui::GetWindowSize().y + padding) * (inverseIndex + 1)));
+ break;
+ case 3: // Bottom Right
+ notificationPos = ImVec2(basePosition.x - ImGui::GetWindowSize().x, basePosition.y - ((ImGui::GetWindowSize().y + padding) * (inverseIndex + 1)));
+ break;
+ }
+
+ ImGui::SetWindowPos(notificationPos);
+
+ if (notification.itemIcon != nullptr) {
+ ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(notification.itemIcon), ImVec2(24, 24));
+ ImGui::SameLine();
+ }
+ if (!notification.prefix.empty()) {
+ ImGui::TextColored(notification.prefixColor, "%s", notification.prefix.c_str());
+ ImGui::SameLine();
+ }
+ ImGui::TextColored(notification.messageColor, "%s", notification.message.c_str());
+ if (!notification.suffix.empty()) {
+ ImGui::SameLine();
+ ImGui::TextColored(notification.suffixColor, "%s", notification.suffix.c_str());
+ }
+
+ ImGui::End();
+ ImGui::PopStyleVar();
+ }
+
+ ImGui::PopStyleVar();
+ ImGui::PopStyleColor(2);
+}
+
+
+void Window::UpdateElement() {
+ for (int index = 0; index < notifications.size(); ++index) {
+ auto& notification = notifications[index];
+
+ // decrement remainingTime
+ notification.remainingTime -= ImGui::GetIO().DeltaTime;
+
+ // remove notification if it has expired
+ if (notification.remainingTime <= 0) {
+ notifications.erase(notifications.begin() + index);
+ --index;
+ }
+ }
+}
+
+void Emit(Options notification) {
+ notification.id = nextId++;
+ if (notification.remainingTime == 0.0f) {
+ notification.remainingTime = CVarGetFloat("gNotifications.Duration", 10.0f);
+ }
+ notifications.push_back(notification);
+ // Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
+}
+
+} // namespace Notification
diff --git a/src/port/notification/notification.h b/src/port/notification/notification.h
new file mode 100644
index 00000000..dbcece01
--- /dev/null
+++ b/src/port/notification/notification.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#ifdef __cplusplus
+
+#include <string>
+#include <libultraship/libultraship.h>
+
+namespace Notification {
+
+struct Options {
+ uint32_t id = 0;
+ const char* itemIcon = nullptr;
+ std::string prefix = "";
+ ImVec4 prefixColor = ImVec4(0.5f, 0.5f, 1.0f, 1.0f);
+ std::string message = "";
+ ImVec4 messageColor = ImVec4(0.7f, 0.7f, 0.7f, 1.0f);
+ std::string suffix = "";
+ ImVec4 suffixColor = ImVec4(1.0f, 0.5f, 0.5f, 1.0f);
+ float remainingTime = 0.0f; // Seconds
+};
+
+class Window : public Ship::GuiWindow {
+ public:
+ using GuiWindow::GuiWindow;
+
+ void InitElement() override {};
+ void DrawElement() override {};
+ void Draw() override;
+ void UpdateElement() override;
+};
+
+void Emit(Options notification);
+
+} // namespace Notification
+#endif // __cplusplus
diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp
index eb9a62c8..5c77bf14 100644
--- a/src/port/ui/ImguiUI.cpp
+++ b/src/port/ui/ImguiUI.cpp
@@ -11,6 +11,7 @@
#include <libultraship/libultraship.h>
#include <Fast3D/gfx_pc.h>
#include "port/Engine.h"
+#include "port/notification/notification.h"
extern "C" {
#include "sys.h"
@@ -24,6 +25,7 @@ std::shared_ptr<Ship::GuiWindow> mConsoleWindow;
std::shared_ptr<Ship::GuiWindow> mStatsWindow;
std::shared_ptr<Ship::GuiWindow> mInputEditorWindow;
std::shared_ptr<Ship::GuiWindow> mGfxDebuggerWindow;
+std::shared_ptr<Notification::Window> mNotificationWindow;
std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mAdvancedResolutionSettingsWindow;
void SetupGuiElements() {
@@ -59,13 +61,20 @@ void SetupGuiElements() {
mAdvancedResolutionSettingsWindow = std::make_shared<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow>("gAdvancedResolutionEditorEnabled", "Advanced Resolution Settings");
gui->AddGuiWindow(mAdvancedResolutionSettingsWindow);
+ mNotificationWindow = std::make_shared<Notification::Window>("gNotifications", "Notifications Window");
+ gui->AddGuiWindow(mNotificationWindow);
+ mNotificationWindow->Show();
}
void Destroy() {
+ auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
+ gui->RemoveAllGuiWindows();
+
mAdvancedResolutionSettingsWindow = nullptr;
mConsoleWindow = nullptr;
mStatsWindow = nullptr;
mInputEditorWindow = nullptr;
+ mNotificationWindow = nullptr;
}
std::string GetWindowButtonText(const char* text, bool menuOpen) {