1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include "notification.h"
#include "macros.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
|