FuncDoodle
Loading...
Searching...
No Matches
ImUtil.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#include "Core/App.h"
18#include <algorithm>
19#include <filesystem>
20#include <fstream>
21
22#include "Anim/Anim.h"
23#include "imgui.h"
24#include <string_view>
25#include <unordered_map>
26
27namespace FuncDoodle {
28 inline std::unordered_map<ImGuiID, double>& GetAnimTimers() {
29 static std::unordered_map<ImGuiID, double> timers;
30 return timers;
31 }
32
33 inline void ClearAnimTimers() {
34 GetAnimTimers().clear();
35 }
36
47 inline bool ImBegin(const char* name, bool* p_open, ImGuiWindowFlags flags,
48 Application* app) {
49
50 if (!app->GetCurProj())
51 return ImGui::Begin(name, p_open, flags);
52
53 ImGuiID id = ImGui::GetID(name);
54 double& t = GetAnimTimers()[id];
55
56 double dt = app->GetDt();
57
58 bool isOpen = (p_open == nullptr) ? true : *p_open;
59 double alpha =
60 std::max(Anim::Animate(isOpen, 2.0, t, dt, Anim::OutCubic), 0.3);
61
62 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, (float)alpha);
63 bool result = ImGui::Begin(name, p_open, flags);
64
65 return result;
66 }
67
72 inline void ImEnd() {
73 ImGui::End();
74 ImGui::PopStyleVar();
75 }
76
77} // namespace FuncDoodle
78
84 // NOLINTBEGIN
85 inline constexpr char s_DefaultLayout[] = {
86#embed "../Conf/imgui.ini"
87 , 0};
88 // NOLINTEND
89
96 inline void SetupDefaultLayout() {
97 ImGuiIO& io = ImGui::GetIO();
98 const char* userIniPath = "imgui.ini";
99
100 io.IniFilename = userIniPath;
101
102 if (!std::filesystem::exists(userIniPath)) {
103 ImGui::LoadIniSettingsFromMemory(s_DefaultLayout);
104
105 std::ofstream outFile(userIniPath);
106 if (outFile) {
107 outFile << s_DefaultLayout;
108 outFile.close();
109 }
110 }
111 }
112
118
124 inline float ButtonWidth(const char* label) {
125 ImVec2 size = ImGui::CalcTextSize(label);
126 return size.x + (ImGui::GetStyle().FramePadding.x * 2.0f);
127 }
128
135 inline void AlignButtonsRight(float totalWidth) {
136 float avail = ImGui::GetContentRegionAvail().x;
137 float startX =
138 ImGui::GetCursorPosX() + std::max(0.0f, avail - totalWidth);
139 ImGui::SetCursorPosX(startX);
140 }
141
148 inline bool EnterPressed() {
149 return ImGui::IsKeyPressed(ImGuiKey_Enter, false) ||
150 ImGui::IsKeyPressed(ImGuiKey_KeypadEnter, false);
151 }
152
159 inline bool EscPressed() {
160 return ImGui::IsKeyPressed(ImGuiKey_Escape, false);
161 }
162
171 inline ButtonRowResult ConfirmButtons(const char* primary,
172 const char* secondary, const char* tertiary = nullptr) {
173 float spacing = ImGui::GetStyle().ItemSpacing.x;
174 float primaryWidth = ButtonWidth(primary);
175 float secondaryWidth = ButtonWidth(secondary);
176 float tertiaryWidth = tertiary ? ButtonWidth(tertiary) : 0.0f;
177 int count = tertiary ? 3 : 2;
178 float totalWidth = primaryWidth + secondaryWidth + tertiaryWidth +
179 (spacing * (count - 1));
180 AlignButtonsRight(totalWidth);
181
183 if (tertiary) {
184 if (ImGui::Button(tertiary))
186 ImGui::SameLine();
187 }
188 if (ImGui::Button(secondary))
190 ImGui::SameLine();
191 if (ImGui::Button(primary))
193 return result;
194 }
195
203 return ConfirmButtons("OK", "Cancel");
204 }
205
213 return ConfirmButtons("Yes", "No");
214 }
215
223 return ConfirmButtons("Yes", "No", "Cancel");
224 }
225
233 return ConfirmButtons("OK", "Close");
234 }
235
243 return ConfirmButtons("Create", "Cancel");
244 }
245
253 return ConfirmButtons("Export", "Close");
254 }
255
260 inline bool SingleButtonRow(const char* label) {
262 return ImGui::Button(label);
263 }
264
271 inline bool OkButton() {
272 return SingleButtonRow("OK");
273 }
274
281 inline bool CloseButton() {
282 return SingleButtonRow("Close");
283 }
284
291 inline ImGuiKey GetAnyReleasedKey() {
292 for (int i = ImGuiKey_NamedKey_BEGIN; i < ImGuiKey_NamedKey_END; i++) {
293 auto key = (ImGuiKey)i;
294 if (key == ImGuiKey_LeftCtrl || key == ImGuiKey_RightCtrl ||
295 key == ImGuiKey_LeftShift || key == ImGuiKey_RightShift ||
296 key == ImGuiKey_LeftAlt || key == ImGuiKey_RightAlt ||
297 key == ImGuiKey_LeftSuper || key == ImGuiKey_RightSuper ||
298 key == ImGuiKey_MouseLeft || key == ImGuiKey_MouseRight)
299 continue;
300 if (ImGui::IsKeyReleased(key))
301 return key;
302 }
303 return ImGuiKey_None;
304 }
305
316 inline const char* GetUsername() {
317 const char* username =
318 std::getenv("USER"); // Common on Linux and macOS
319 if (!username) {
320 username = std::getenv("LOGNAME"); // Fallback for Linux and macOS
321 }
322 if (!username) {
323 username = std::getenv("USERNAME"); // Common on Windows
324 }
325 if (!username) {
326 username = "unknown";
327 }
328
329 return username;
330 }
331
332 template<typename T>
333 concept IntEnum =
334 std::is_enum_v<T> &&
335 std::same_as<std::underlying_type_t<T>, int> &&
336 !std::convertible_to<T, int>;
337
338 template<IntEnum T, size_t N>
339 inline bool Combo(const char* title, T* buf, std::array<std::string_view, N> names) {
340 std::array<const char*, N> ptrs{};
341 for (size_t i = 0; i < N; ++i)
342 ptrs[i] = names[i].data();
343
344 return ImGui::Combo(title, reinterpret_cast<int*>(buf), ptrs.data(), names.size());
345 }
346
347 struct ImVec2iHash {
348 size_t operator()(const ImVec2i& v) const {
349 return std::hash<int>()(v.x) ^ (std::hash<int>()(v.y) << 32);
350 }
351 };
353 bool operator()(const ImVec2i& a, const ImVec2i& b) const {
354 return a.x == b.x && a.y == b.y;
355 }
356 };
357} // namespace FuncDoodle::ImUtil
Core FuncDoodle application class and runtime control interface.
Class holding most of the data required to launch FuncDoodle.
Definition App.h:50
SharedPtr< ProjectFile > GetCurProj()
Returns the currently open project.
Definition App.h:188
double GetDt()
Get deltaTime.
Definition App.h:402
Definition ImUtil.h:333
double Animate(bool forward, double duration, double &from, double dt, double(*ease)(double))
Definition Anim.h:23
double OutCubic(double t)
Definition Anim.h:84
Definition ImUtil.h:83
ButtonRowResult YesNoButtons()
Renders a Yes/No button row.
Definition ImUtil.h:212
ButtonRowResult
Identifies which button was pressed in a button row.
Definition ImUtil.h:117
@ Tertiary
Definition ImUtil.h:117
@ Primary
Definition ImUtil.h:117
@ Secondary
Definition ImUtil.h:117
@ None
Definition ImUtil.h:117
bool EscPressed()
Returns true when Escape is pressed this frame.
Definition ImUtil.h:159
ButtonRowResult CreateCancelButtons()
Renders a Create/Cancel button row.
Definition ImUtil.h:242
ImGuiKey GetAnyReleasedKey()
Returns the first non-modifier key released this frame.
Definition ImUtil.h:291
float ButtonWidth(const char *label)
Returns the width needed to render a button with the given label.
Definition ImUtil.h:124
void AlignButtonsRight(float totalWidth)
Right-aligns the next row of buttons within the current content region.
Definition ImUtil.h:135
const char * GetUsername()
Small util function for fetching the current users' username. Used for filling out the animation auth...
Definition ImUtil.h:316
constexpr char s_DefaultLayout[]
Definition ImUtil.h:85
ButtonRowResult OkCancelButtons()
Renders an OK/Cancel button row.
Definition ImUtil.h:202
ButtonRowResult ConfirmButtons(const char *primary, const char *secondary, const char *tertiary=nullptr)
Renders CONFIRM buttons for popups.
Definition ImUtil.h:171
ButtonRowResult CloseOkButtons()
Renders an OK/Close button row.
Definition ImUtil.h:232
ButtonRowResult ExportCloseButtons()
Renders an Export/Close button row.
Definition ImUtil.h:252
void SetupDefaultLayout()
Sets up the default ImGui layout in-case there's no user-defined one.
Definition ImUtil.h:96
bool CloseButton()
Renders a single Close button.
Definition ImUtil.h:281
bool Combo(const char *title, T *buf, std::array< std::string_view, N > names)
Definition ImUtil.h:339
bool OkButton()
Renders a single OK button.
Definition ImUtil.h:271
bool EnterPressed()
Returns true when Enter or keypad Enter is pressed this frame.
Definition ImUtil.h:148
ButtonRowResult YesNoCancelButtons()
Renders a Yes/No/Cancel button row.
Definition ImUtil.h:222
bool SingleButtonRow(const char *label)
Renders a single right-aligned button.
Definition ImUtil.h:260
The FuncDoodle C++ namespace.
Definition Common.h:12
std::unordered_map< ImGuiID, double > & GetAnimTimers()
Definition ImUtil.h:28
void ImEnd()
Clean wrapper to close the window layout context.
Definition ImUtil.h:72
bool ImBegin(const char *name, bool *p_open, ImGuiWindowFlags flags, Application *app)
Definition ImUtil.h:47
void ClearAnimTimers()
Definition ImUtil.h:33
Definition ImUtil.h:352
bool operator()(const ImVec2i &a, const ImVec2i &b) const
Definition ImUtil.h:353
Definition ImUtil.h:347
size_t operator()(const ImVec2i &v) const
Definition ImUtil.h:348