yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
style_guard.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GUI_CORE_STYLE_GUARD_H_
2#define YAZE_APP_GUI_CORE_STYLE_GUARD_H_
3
4#include <initializer_list>
5#include <optional>
6#include <variant>
7
9#include "imgui/imgui.h"
10// ImGuiItemFlags_ReadOnly (used by ReadOnlyScope) is declared only here.
11#include "imgui/imgui_internal.h"
12
13namespace yaze {
14namespace gui {
15
16// ============================================================================
17// RAII Style Guards
18// ============================================================================
19// Replace manual PushStyleColor/PopStyleColor and PushStyleVar/PopStyleVar
20// patterns with scope-based guards that automatically clean up.
21
30 public:
31 struct Entry {
32 ImGuiCol idx;
33 ImVec4 color;
34 };
35
36 StyleColorGuard(ImGuiCol idx, const ImVec4& color) : count_(1) {
37 ImGui::PushStyleColor(idx, color);
38 }
39
40 StyleColorGuard(ImGuiCol idx, const Color& color) : count_(1) {
41 ImGui::PushStyleColor(idx, static_cast<ImVec4>(color));
42 }
43
44 StyleColorGuard(std::initializer_list<Entry> entries)
45 : count_(static_cast<int>(entries.size())) {
46 for (const auto& e : entries) {
47 ImGui::PushStyleColor(e.idx, e.color);
48 }
49 }
50
52 if (count_ > 0)
53 ImGui::PopStyleColor(count_);
54 }
55
58
59 private:
60 int count_;
61};
62
72 public:
73 struct Entry {
74 ImGuiStyleVar idx;
75 std::variant<float, ImVec2> value;
76 };
77
78 StyleVarGuard(ImGuiStyleVar idx, float val) : count_(1) {
79 ImGui::PushStyleVar(idx, val);
80 }
81
82 StyleVarGuard(ImGuiStyleVar idx, const ImVec2& val) : count_(1) {
83 ImGui::PushStyleVar(idx, val);
84 }
85
86 StyleVarGuard(std::initializer_list<Entry> entries)
87 : count_(static_cast<int>(entries.size())) {
88 for (const auto& e : entries) {
89 if (auto* f = std::get_if<float>(&e.value)) {
90 ImGui::PushStyleVar(e.idx, *f);
91 } else {
92 ImGui::PushStyleVar(e.idx, std::get<ImVec2>(e.value));
93 }
94 }
95 }
96
98 if (count_ > 0)
99 ImGui::PopStyleVar(count_);
100 }
101
102 StyleVarGuard(const StyleVarGuard&) = delete;
104
105 private:
107};
108
109// ============================================================================
110// RAII Scope Guards: ID, Disabled, and Item Flag Stacks
111// ============================================================================
112// Each guard pushes in its constructor and pops in its destructor, so an early
113// return, break, or continue inside the scope cannot leave an ImGui stack
114// unbalanced.
115
125class IdScope {
126 public:
127 explicit IdScope(const char* str_id) { ImGui::PushID(str_id); }
128 explicit IdScope(int int_id) { ImGui::PushID(int_id); }
129 explicit IdScope(const void* ptr_id) { ImGui::PushID(ptr_id); }
130
131 ~IdScope() { ImGui::PopID(); }
132
133 IdScope(const IdScope&) = delete;
134 IdScope& operator=(const IdScope&) = delete;
135};
136
150 public:
151 explicit DisabledScope(bool disabled = true) {
152 ImGui::BeginDisabled(disabled);
153 }
154
155 ~DisabledScope() { ImGui::EndDisabled(); }
156
157 DisabledScope(const DisabledScope&) = delete;
159};
160
169 public:
170 ItemFlagScope(ImGuiItemFlags option, bool enabled) {
171 ImGui::PushItemFlag(option, enabled);
172 }
173
174 ~ItemFlagScope() { ImGui::PopItemFlag(); }
175
176 ItemFlagScope(const ItemFlagScope&) = delete;
178};
179
194 public:
195 explicit ReadOnlyScope(bool read_only = true) {
196 ImGui::PushItemFlag(ImGuiItemFlags_ReadOnly, read_only);
197 }
198
199 ~ReadOnlyScope() { ImGui::PopItemFlag(); }
200
201 ReadOnlyScope(const ReadOnlyScope&) = delete;
203};
204
205// ============================================================================
206// Compound RAII Helpers
207// ============================================================================
208
216 std::optional<ImVec4> bg;
217 std::optional<ImVec4> border;
218 ImVec2 padding = {-1, -1}; // -1 means "don't push"
219 ImVec2 spacing = {-1, -1}; // -1 means "don't push"
220 float border_size = -1.0f; // -1 means "don't push"
221 float rounding = -1.0f; // -1 means "don't push"
222};
223
236 public:
237 StyledWindow(const char* name, const StyledWindowConfig& config,
238 bool* p_open = nullptr, ImGuiWindowFlags flags = 0)
239 : color_count_(0), var_count_(0) {
240 // Push colors
241 if (config.bg.has_value()) {
242 ImGui::PushStyleColor(ImGuiCol_WindowBg, *config.bg);
243 ++color_count_;
244 }
245 if (config.border.has_value()) {
246 ImGui::PushStyleColor(ImGuiCol_Border, *config.border);
247 ++color_count_;
248 }
249
250 // Push vars
251 if (config.padding.x >= 0.0f) {
252 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, config.padding);
253 ++var_count_;
254 }
255 if (config.spacing.x >= 0.0f) {
256 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, config.spacing);
257 ++var_count_;
258 }
259 if (config.border_size >= 0.0f) {
260 ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, config.border_size);
261 ++var_count_;
262 }
263 if (config.rounding >= 0.0f) {
264 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, config.rounding);
265 ++var_count_;
266 }
267
268 is_open_ = ImGui::Begin(name, p_open, flags);
269 }
270
272 ImGui::End();
273 if (var_count_ > 0)
274 ImGui::PopStyleVar(var_count_);
275 if (color_count_ > 0)
276 ImGui::PopStyleColor(color_count_);
277 }
278
279 explicit operator bool() const { return is_open_; }
280
281 StyledWindow(const StyledWindow&) = delete;
283
284 private:
288};
289
301 public:
302 FixedPanel(const char* name, const ImVec2& pos, const ImVec2& size,
303 const StyledWindowConfig& config, ImGuiWindowFlags extra_flags = 0)
304 : window_(std::nullopt) {
305 ImGui::SetNextWindowPos(pos);
306 ImGui::SetNextWindowSize(size);
307
308 constexpr ImGuiWindowFlags kFixedFlags =
309 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
310 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse |
311 ImGuiWindowFlags_NoDocking;
312
313 window_.emplace(name, config, nullptr, kFixedFlags | extra_flags);
314 }
315
316 explicit operator bool() const {
317 return window_.has_value() && static_cast<bool>(*window_);
318 }
319
320 FixedPanel(const FixedPanel&) = delete;
321 FixedPanel& operator=(const FixedPanel&) = delete;
322
323 private:
324 std::optional<StyledWindow> window_;
325};
326
327// ============================================================================
328// StyledChild — RAII for BeginChild/EndChild with optional styling
329// ============================================================================
330
338 std::optional<ImVec4> bg; // ImGuiCol_ChildBg
339 std::optional<ImVec4> border; // ImGuiCol_Border
340 float rounding = -1.0f; // ImGuiStyleVar_ChildRounding
341 float border_size = -1.0f; // ImGuiStyleVar_ChildBorderSize
342};
343
355 public:
356 StyledChild(const char* id, const ImVec2& size,
357 const StyledChildConfig& config, bool has_border = false,
358 ImGuiWindowFlags flags = 0)
359 : color_count_(0), var_count_(0) {
360 if (config.bg.has_value()) {
361 ImGui::PushStyleColor(ImGuiCol_ChildBg, *config.bg);
362 ++color_count_;
363 }
364 if (config.border.has_value()) {
365 ImGui::PushStyleColor(ImGuiCol_Border, *config.border);
366 ++color_count_;
367 }
368 if (config.rounding >= 0.0f) {
369 ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, config.rounding);
370 ++var_count_;
371 }
372 if (config.border_size >= 0.0f) {
373 ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, config.border_size);
374 ++var_count_;
375 }
376 is_open_ = ImGui::BeginChild(id, size, has_border, flags);
377 }
378
380 ImGui::EndChild();
381 if (var_count_ > 0)
382 ImGui::PopStyleVar(var_count_);
383 if (color_count_ > 0)
384 ImGui::PopStyleColor(color_count_);
385 }
386
387 explicit operator bool() const { return is_open_; }
388
389 StyledChild(const StyledChild&) = delete;
391
392 private:
396};
397
398} // namespace gui
399} // namespace yaze
400
401#endif // YAZE_APP_GUI_CORE_STYLE_GUARD_H_
RAII guard for ImGui::BeginDisabled / ImGui::EndDisabled.
DisabledScope & operator=(const DisabledScope &)=delete
DisabledScope(const DisabledScope &)=delete
DisabledScope(bool disabled=true)
RAII for fixed-position panels (activity bar, side panel, status bar).
FixedPanel(const FixedPanel &)=delete
FixedPanel(const char *name, const ImVec2 &pos, const ImVec2 &size, const StyledWindowConfig &config, ImGuiWindowFlags extra_flags=0)
FixedPanel & operator=(const FixedPanel &)=delete
std::optional< StyledWindow > window_
RAII guard for ImGui::PushID / ImGui::PopID.
IdScope(const char *str_id)
IdScope(int int_id)
IdScope & operator=(const IdScope &)=delete
IdScope(const IdScope &)=delete
IdScope(const void *ptr_id)
RAII guard for ImGui::PushItemFlag / ImGui::PopItemFlag.
ItemFlagScope & operator=(const ItemFlagScope &)=delete
ItemFlagScope(const ItemFlagScope &)=delete
ItemFlagScope(ImGuiItemFlags option, bool enabled)
RAII guard that pushes ImGuiItemFlags_ReadOnly.
ReadOnlyScope(const ReadOnlyScope &)=delete
ReadOnlyScope & operator=(const ReadOnlyScope &)=delete
ReadOnlyScope(bool read_only=true)
RAII guard for ImGui style colors.
Definition style_guard.h:29
StyleColorGuard(ImGuiCol idx, const Color &color)
Definition style_guard.h:40
StyleColorGuard(ImGuiCol idx, const ImVec4 &color)
Definition style_guard.h:36
StyleColorGuard(std::initializer_list< Entry > entries)
Definition style_guard.h:44
StyleColorGuard(const StyleColorGuard &)=delete
StyleColorGuard & operator=(const StyleColorGuard &)=delete
RAII guard for ImGui style vars.
Definition style_guard.h:71
StyleVarGuard(ImGuiStyleVar idx, float val)
Definition style_guard.h:78
StyleVarGuard(ImGuiStyleVar idx, const ImVec2 &val)
Definition style_guard.h:82
StyleVarGuard(const StyleVarGuard &)=delete
StyleVarGuard & operator=(const StyleVarGuard &)=delete
StyleVarGuard(std::initializer_list< Entry > entries)
Definition style_guard.h:86
RAII guard for ImGui child windows with optional styling.
StyledChild & operator=(const StyledChild &)=delete
StyledChild(const StyledChild &)=delete
StyledChild(const char *id, const ImVec2 &size, const StyledChildConfig &config, bool has_border=false, ImGuiWindowFlags flags=0)
RAII compound guard for window-level style setup.
StyledWindow & operator=(const StyledWindow &)=delete
StyledWindow(const char *name, const StyledWindowConfig &config, bool *p_open=nullptr, ImGuiWindowFlags flags=0)
StyledWindow(const StyledWindow &)=delete
std::variant< float, ImVec2 > value
Definition style_guard.h:75
Configuration for styled child windows.
std::optional< ImVec4 > border
std::optional< ImVec4 > bg
Configuration for styled windows and panels.
std::optional< ImVec4 > border
std::optional< ImVec4 > bg