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
11namespace yaze {
12namespace gui {
13
14// ============================================================================
15// RAII Style Guards
16// ============================================================================
17// Replace manual PushStyleColor/PopStyleColor and PushStyleVar/PopStyleVar
18// patterns with scope-based guards that automatically clean up.
19
28 public:
29 struct Entry {
30 ImGuiCol idx;
31 ImVec4 color;
32 };
33
34 StyleColorGuard(ImGuiCol idx, const ImVec4& color) : count_(1) {
35 ImGui::PushStyleColor(idx, color);
36 }
37
38 StyleColorGuard(ImGuiCol idx, const Color& color) : count_(1) {
39 ImGui::PushStyleColor(idx, static_cast<ImVec4>(color));
40 }
41
42 StyleColorGuard(std::initializer_list<Entry> entries)
43 : count_(static_cast<int>(entries.size())) {
44 for (const auto& e : entries) {
45 ImGui::PushStyleColor(e.idx, e.color);
46 }
47 }
48
50 if (count_ > 0) ImGui::PopStyleColor(count_);
51 }
52
55
56 private:
57 int count_;
58};
59
69 public:
70 struct Entry {
71 ImGuiStyleVar idx;
72 std::variant<float, ImVec2> value;
73 };
74
75 StyleVarGuard(ImGuiStyleVar idx, float val) : count_(1) {
76 ImGui::PushStyleVar(idx, val);
77 }
78
79 StyleVarGuard(ImGuiStyleVar idx, const ImVec2& val) : count_(1) {
80 ImGui::PushStyleVar(idx, val);
81 }
82
83 StyleVarGuard(std::initializer_list<Entry> entries)
84 : count_(static_cast<int>(entries.size())) {
85 for (const auto& e : entries) {
86 if (auto* f = std::get_if<float>(&e.value)) {
87 ImGui::PushStyleVar(e.idx, *f);
88 } else {
89 ImGui::PushStyleVar(e.idx, std::get<ImVec2>(e.value));
90 }
91 }
92 }
93
95 if (count_ > 0) ImGui::PopStyleVar(count_);
96 }
97
98 StyleVarGuard(const StyleVarGuard&) = delete;
100
101 private:
103};
104
105// ============================================================================
106// Compound RAII Helpers
107// ============================================================================
108
116 std::optional<ImVec4> bg;
117 std::optional<ImVec4> border;
118 ImVec2 padding = {-1, -1}; // -1 means "don't push"
119 ImVec2 spacing = {-1, -1}; // -1 means "don't push"
120 float border_size = -1.0f; // -1 means "don't push"
121 float rounding = -1.0f; // -1 means "don't push"
122};
123
136 public:
137 StyledWindow(const char* name, const StyledWindowConfig& config,
138 bool* p_open = nullptr, ImGuiWindowFlags flags = 0)
139 : color_count_(0), var_count_(0) {
140 // Push colors
141 if (config.bg.has_value()) {
142 ImGui::PushStyleColor(ImGuiCol_WindowBg, *config.bg);
143 ++color_count_;
144 }
145 if (config.border.has_value()) {
146 ImGui::PushStyleColor(ImGuiCol_Border, *config.border);
147 ++color_count_;
148 }
149
150 // Push vars
151 if (config.padding.x >= 0.0f) {
152 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, config.padding);
153 ++var_count_;
154 }
155 if (config.spacing.x >= 0.0f) {
156 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, config.spacing);
157 ++var_count_;
158 }
159 if (config.border_size >= 0.0f) {
160 ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, config.border_size);
161 ++var_count_;
162 }
163 if (config.rounding >= 0.0f) {
164 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, config.rounding);
165 ++var_count_;
166 }
167
168 is_open_ = ImGui::Begin(name, p_open, flags);
169 }
170
172 ImGui::End();
173 if (var_count_ > 0) ImGui::PopStyleVar(var_count_);
174 if (color_count_ > 0) ImGui::PopStyleColor(color_count_);
175 }
176
177 explicit operator bool() const { return is_open_; }
178
179 StyledWindow(const StyledWindow&) = delete;
181
182 private:
186};
187
199 public:
200 FixedPanel(const char* name, const ImVec2& pos, const ImVec2& size,
201 const StyledWindowConfig& config,
202 ImGuiWindowFlags extra_flags = 0)
203 : window_(std::nullopt) {
204 ImGui::SetNextWindowPos(pos);
205 ImGui::SetNextWindowSize(size);
206
207 constexpr ImGuiWindowFlags kFixedFlags =
208 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
209 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse |
210 ImGuiWindowFlags_NoDocking;
211
212 window_.emplace(name, config, nullptr, kFixedFlags | extra_flags);
213 }
214
215 explicit operator bool() const {
216 return window_.has_value() && static_cast<bool>(*window_);
217 }
218
219 FixedPanel(const FixedPanel&) = delete;
220 FixedPanel& operator=(const FixedPanel&) = delete;
221
222 private:
223 std::optional<StyledWindow> window_;
224};
225
226// ============================================================================
227// StyledChild — RAII for BeginChild/EndChild with optional styling
228// ============================================================================
229
237 std::optional<ImVec4> bg; // ImGuiCol_ChildBg
238 std::optional<ImVec4> border; // ImGuiCol_Border
239 float rounding = -1.0f; // ImGuiStyleVar_ChildRounding
240 float border_size = -1.0f; // ImGuiStyleVar_ChildBorderSize
241};
242
254 public:
255 StyledChild(const char* id, const ImVec2& size,
256 const StyledChildConfig& config,
257 bool has_border = false, ImGuiWindowFlags flags = 0)
258 : color_count_(0), var_count_(0) {
259 if (config.bg.has_value()) {
260 ImGui::PushStyleColor(ImGuiCol_ChildBg, *config.bg);
261 ++color_count_;
262 }
263 if (config.border.has_value()) {
264 ImGui::PushStyleColor(ImGuiCol_Border, *config.border);
265 ++color_count_;
266 }
267 if (config.rounding >= 0.0f) {
268 ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, config.rounding);
269 ++var_count_;
270 }
271 if (config.border_size >= 0.0f) {
272 ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, config.border_size);
273 ++var_count_;
274 }
275 is_open_ = ImGui::BeginChild(id, size, has_border, flags);
276 }
277
279 ImGui::EndChild();
280 if (var_count_ > 0) ImGui::PopStyleVar(var_count_);
281 if (color_count_ > 0) ImGui::PopStyleColor(color_count_);
282 }
283
284 explicit operator bool() const { return is_open_; }
285
286 StyledChild(const StyledChild&) = delete;
288
289 private:
293};
294
295} // namespace gui
296} // namespace yaze
297
298#endif // YAZE_APP_GUI_CORE_STYLE_GUARD_H_
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 style colors.
Definition style_guard.h:27
StyleColorGuard(ImGuiCol idx, const Color &color)
Definition style_guard.h:38
StyleColorGuard(ImGuiCol idx, const ImVec4 &color)
Definition style_guard.h:34
StyleColorGuard(std::initializer_list< Entry > entries)
Definition style_guard.h:42
StyleColorGuard(const StyleColorGuard &)=delete
StyleColorGuard & operator=(const StyleColorGuard &)=delete
RAII guard for ImGui style vars.
Definition style_guard.h:68
StyleVarGuard(ImGuiStyleVar idx, float val)
Definition style_guard.h:75
StyleVarGuard(ImGuiStyleVar idx, const ImVec2 &val)
Definition style_guard.h:79
StyleVarGuard(const StyleVarGuard &)=delete
StyleVarGuard & operator=(const StyleVarGuard &)=delete
StyleVarGuard(std::initializer_list< Entry > entries)
Definition style_guard.h:83
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:72
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