yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
style.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
10#include "imgui/imgui.h"
11#include "imgui/imgui_internal.h"
12#include "util/file_util.h"
13#include "util/log.h"
14
15namespace yaze {
16namespace gui {
17
18namespace {
19Color ParseColor(const std::string& color) {
20 Color result;
21 if (color.size() == 7 && color[0] == '#') {
22 result.red = std::stoi(color.substr(1, 2), nullptr, 16) / 255.0f;
23 result.green = std::stoi(color.substr(3, 2), nullptr, 16) / 255.0f;
24 result.blue = std::stoi(color.substr(5, 2), nullptr, 16) / 255.0f;
25 } else {
26 throw std::invalid_argument("Invalid color format: " + color);
27 }
28 return result;
29}
30} // namespace
31
32void ColorsYaze() {
33 ImGuiStyle* style = &ImGui::GetStyle();
34 ImVec4* colors = style->Colors;
35
36 style->WindowPadding = ImVec2(10.f, 10.f);
37 style->FramePadding = ImVec2(10.f, 2.f);
38 style->CellPadding = ImVec2(4.f, 5.f);
39 style->ItemSpacing = ImVec2(10.f, 5.f);
40 style->ItemInnerSpacing = ImVec2(5.f, 5.f);
41 style->TouchExtraPadding = ImVec2(0.f, 0.f);
42 style->IndentSpacing = 20.f;
43 style->ScrollbarSize = 14.f;
44 style->GrabMinSize = 15.f;
45
46 style->WindowBorderSize = 0.f;
47 style->ChildBorderSize = 1.f;
48 style->PopupBorderSize = 1.f;
49 style->FrameBorderSize = 0.f;
50 style->TabBorderSize = 0.f;
51
52 style->WindowRounding = 0.f;
53 style->ChildRounding = 0.f;
54 style->FrameRounding = 5.f;
55 style->PopupRounding = 0.f;
56 style->ScrollbarRounding = 5.f;
57
58 auto alttpDarkGreen = ImVec4(0.18f, 0.26f, 0.18f, 1.0f);
59 auto alttpMidGreen = ImVec4(0.28f, 0.36f, 0.28f, 1.0f);
60 auto allttpLightGreen = ImVec4(0.36f, 0.45f, 0.36f, 1.0f);
61 auto allttpLightestGreen = ImVec4(0.49f, 0.57f, 0.49f, 1.0f);
62
63 colors[ImGuiCol_MenuBarBg] = alttpDarkGreen;
64 colors[ImGuiCol_TitleBg] = alttpMidGreen;
65
66 colors[ImGuiCol_Header] = alttpDarkGreen;
67 colors[ImGuiCol_HeaderHovered] = allttpLightGreen;
68 colors[ImGuiCol_HeaderActive] = alttpMidGreen;
69
70 colors[ImGuiCol_TitleBgActive] = alttpDarkGreen;
71 colors[ImGuiCol_TitleBgCollapsed] = alttpMidGreen;
72
73 colors[ImGuiCol_Tab] = alttpDarkGreen;
74 colors[ImGuiCol_TabHovered] = alttpMidGreen;
75 colors[ImGuiCol_TabActive] = ImVec4(0.347f, 0.466f, 0.347f, 1.000f);
76
77 colors[ImGuiCol_Button] = alttpMidGreen;
78 colors[ImGuiCol_ButtonHovered] = allttpLightestGreen;
79 colors[ImGuiCol_ButtonActive] = allttpLightGreen;
80
81 colors[ImGuiCol_ScrollbarBg] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
82 colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.36f, 0.45f, 0.36f, 0.30f);
83 colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.36f, 0.45f, 0.36f, 0.40f);
84 colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
85
86 colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
87 colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
88 colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f);
89 colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
90 colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f);
91 colors[ImGuiCol_Border] = allttpLightGreen;
92 colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
93
94 colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f);
95 colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f);
96 colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f);
97
98 colors[ImGuiCol_CheckMark] =
99 ImVec4(0.26f, 0.59f, 0.98f, 1.00f); // Solid blue checkmark
100 colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
101 colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
102
103 colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
104 colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
105 colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
106 colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
107 colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
108 colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
109
110 colors[ImGuiCol_TabUnfocused] =
111 ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
112 colors[ImGuiCol_TabUnfocusedActive] =
113 ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
114 colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
115 colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
116 colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
117 colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
118 colors[ImGuiCol_TableHeaderBg] = alttpDarkGreen;
119 colors[ImGuiCol_TableBorderStrong] = alttpMidGreen;
120 colors[ImGuiCol_TableBorderLight] =
121 ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here
122 colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
123 colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f);
124 colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
125 colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
126 colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
127 colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
128 colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
129 colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
130}
131
132void DrawBitmapViewer(const std::vector<gfx::Bitmap>& bitmaps, float scale,
133 int& current_bitmap_id) {
134 if (bitmaps.empty()) {
135 ImGui::Text("No bitmaps available.");
136 return;
137 }
138
139 // Display the current bitmap index and total count.
140 ImGui::Text("Viewing Bitmap %d / %zu", current_bitmap_id + 1, bitmaps.size());
141
142 // Buttons to navigate through bitmaps.
143 if (ImGui::Button("<- Prev")) {
144 if (current_bitmap_id > 0) {
145 --current_bitmap_id;
146 }
147 }
148 ImGui::SameLine();
149 if (ImGui::Button("Next ->")) {
150 if (current_bitmap_id < bitmaps.size() - 1) {
151 ++current_bitmap_id;
152 }
153 }
154
155 // Display the current bitmap.
156 const gfx::Bitmap& current_bitmap = bitmaps[current_bitmap_id];
157 // Assuming Bitmap has a function to get its texture ID, and width and
158 // height.
159 ImTextureID tex_id = (ImTextureID)(intptr_t)current_bitmap.texture();
160 ImVec2 size(current_bitmap.width() * scale, current_bitmap.height() * scale);
161 // ImGui::Image(tex_id, size);
162
163 // Scroll if the image is larger than the display area.
164 if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false,
165 ImGuiWindowFlags_HorizontalScrollbar)) {
166 ImGui::Image(tex_id, size);
167 ImGui::EndChild();
168 }
169}
170
171static const char* const kKeywords[] = {
172 "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL",
173 "BRA", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "CPX",
174 "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX", "INY", "JMP", "JSR",
175 "JSL", "LDA", "LDX", "LDY", "LSR", "MVN", "NOP", "ORA", "PEA", "PER",
176 "PHA", "PHB", "PHD", "PHP", "PHX", "PHY", "PLA", "PLB", "PLD", "PLP",
177 "PLX", "PLY", "REP", "ROL", "ROR", "RTI", "RTL", "RTS", "SBC", "SEC",
178 "SEI", "SEP", "STA", "STP", "STX", "STY", "STZ", "TAX", "TAY", "TCD",
179 "TCS", "TDC", "TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY", "TYA",
180 "TYX", "WAI", "WDM", "XBA", "XCE", "ORG", "LOROM", "HIROM"};
181
182static const char* const kIdentifiers[] = {
183 "abort", "abs", "acos", "asin", "atan", "atexit",
184 "atof", "atoi", "atol", "ceil", "clock", "cosh",
185 "ctime", "div", "exit", "fabs", "floor", "fmod",
186 "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph",
187 "ispunct", "isspace", "isupper", "kbhit", "log10", "log2",
188 "log", "memcmp", "modf", "pow", "putchar", "putenv",
189 "puts", "rand", "remove", "rename", "sinh", "sqrt",
190 "srand", "strcat", "strcmp", "strerror", "time", "tolower",
191 "toupper"};
192
194 TextEditor::LanguageDefinition language_65816;
195 for (auto& k : kKeywords)
196 language_65816.mKeywords.emplace(k);
197
198 for (auto& k : kIdentifiers) {
200 id.mDeclaration = "Built-in function";
201 language_65816.mIdentifiers.insert(std::make_pair(std::string(k), id));
202 }
203
204 language_65816.mTokenRegexStrings.push_back(
205 std::make_pair<std::string, TextEditor::PaletteIndex>(
206 "[ \\t]*#[ \\t]*[a-zA-Z_]+", TextEditor::PaletteIndex::Preprocessor));
207 language_65816.mTokenRegexStrings.push_back(
208 std::make_pair<std::string, TextEditor::PaletteIndex>(
209 "L?\\\"(\\\\.|[^\\\"])*\\\"", TextEditor::PaletteIndex::String));
210 language_65816.mTokenRegexStrings.push_back(
211 std::make_pair<std::string, TextEditor::PaletteIndex>(
212 "\\'\\\\?[^\\']\\'", TextEditor::PaletteIndex::CharLiteral));
213 language_65816.mTokenRegexStrings.push_back(
214 std::make_pair<std::string, TextEditor::PaletteIndex>(
215 "[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?",
217 language_65816.mTokenRegexStrings.push_back(
218 std::make_pair<std::string, TextEditor::PaletteIndex>(
219 "[+-]?[0-9]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number));
220 language_65816.mTokenRegexStrings.push_back(
221 std::make_pair<std::string, TextEditor::PaletteIndex>(
222 "0[0-7]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number));
223 language_65816.mTokenRegexStrings.push_back(
224 std::make_pair<std::string, TextEditor::PaletteIndex>(
225 "0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?",
227 language_65816.mTokenRegexStrings.push_back(
228 std::make_pair<std::string, TextEditor::PaletteIndex>(
229 "[a-zA-Z_][a-zA-Z0-9_]*", TextEditor::PaletteIndex::Identifier));
230 language_65816.mTokenRegexStrings.push_back(
231 std::make_pair<std::string, TextEditor::PaletteIndex>(
232 "[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/"
233 "\\;\\,\\.]",
235
236 language_65816.mCommentStart = "/*";
237 language_65816.mCommentEnd = "*/";
238 language_65816.mSingleLineComment = ";";
239
240 language_65816.mCaseSensitive = false;
241 language_65816.mAutoIndentation = true;
242
243 language_65816.mName = "65816";
244
245 return language_65816;
246}
247
248// TODO: Add more display settings to popup windows.
249void BeginWindowWithDisplaySettings(const char* id, bool* active,
250 const ImVec2& size,
251 ImGuiWindowFlags flags) {
252 ImGuiStyle* ref = &ImGui::GetStyle();
253 static float childBgOpacity = 0.75f;
254 auto color = ref->Colors[ImGuiCol_WindowBg];
255
256 ImGui::PushStyleColor(ImGuiCol_WindowBg, color);
257 ImGui::PushStyleColor(ImGuiCol_ChildBg, color);
258 ImGui::PushStyleColor(ImGuiCol_Border, color);
259
260 ImGui::Begin(id, active, flags | ImGuiWindowFlags_MenuBar);
261 ImGui::BeginMenuBar();
262 if (ImGui::BeginMenu("Display Settings")) {
263 ImGui::SliderFloat("Child Background Opacity", &childBgOpacity, 0.0f, 1.0f);
264 ImGui::EndMenu();
265 }
266 ImGui::EndMenuBar();
267}
268
270 ImGui::End();
271 ImGui::PopStyleColor(3);
272}
273
274void BeginPadding(int i) {
275 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(i, i));
276 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(i, i));
277}
279 EndNoPadding();
280}
281
283 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
284 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
285}
287 ImGui::PopStyleVar(2);
288}
289
290void BeginChildWithScrollbar(const char* str_id) {
291 // Get available region but ensure minimum size for proper scrolling
292 ImVec2 available = ImGui::GetContentRegionAvail();
293 if (available.x < 64.0f)
294 available.x = 64.0f;
295 if (available.y < 64.0f)
296 available.y = 64.0f;
297
298 ImGui::BeginChild(str_id, available, true,
299 ImGuiWindowFlags_AlwaysVerticalScrollbar);
300}
301
302void BeginChildWithScrollbar(const char* str_id, ImVec2 content_size) {
303 // Set content size before beginning child to enable proper scrolling
304 if (content_size.x > 0 && content_size.y > 0) {
305 ImGui::SetNextWindowContentSize(content_size);
306 }
307
308 // Get available region but ensure minimum size for proper scrolling
309 ImVec2 available = ImGui::GetContentRegionAvail();
310 if (available.x < 64.0f)
311 available.x = 64.0f;
312 if (available.y < 64.0f)
313 available.y = 64.0f;
314
315 ImGui::BeginChild(str_id, available, true,
316 ImGuiWindowFlags_AlwaysVerticalScrollbar);
317}
318
320 ImGuiID child_id = ImGui::GetID((void*)(intptr_t)id);
321 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
322 ImGuiWindowFlags_AlwaysVerticalScrollbar |
323 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
324}
325
326// Helper functions for table canvas management
327void BeginTableCanvas(const char* table_id, int columns, ImVec2 canvas_size) {
328 // Use proper sizing for tables containing canvas elements
329 ImGuiTableFlags flags =
330 ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchProp;
331
332 // If canvas size is specified, use it as minimum size
333 ImVec2 outer_size = ImVec2(0, 0);
334 if (canvas_size.x > 0 || canvas_size.y > 0) {
335 outer_size = canvas_size;
336 flags |= ImGuiTableFlags_NoHostExtendY; // Prevent auto-extending past
337 // canvas size
338 }
339
340 ImGui::BeginTable(table_id, columns, flags, outer_size);
341}
342
344 ImGui::EndTable();
345}
346
347void SetupCanvasTableColumn(const char* label, float width_ratio) {
348 if (width_ratio > 0) {
349 ImGui::TableSetupColumn(label, ImGuiTableColumnFlags_WidthStretch,
350 width_ratio);
351 } else {
352 ImGui::TableSetupColumn(label, ImGuiTableColumnFlags_WidthStretch);
353 }
354}
355
356void BeginCanvasTableCell(ImVec2 min_size) {
357 ImGui::TableNextColumn();
358
359 // Ensure minimum size for canvas cells
360 if (min_size.x > 0 || min_size.y > 0) {
361 ImVec2 avail = ImGui::GetContentRegionAvail();
362 ImVec2 actual_size =
363 ImVec2(std::max(avail.x, min_size.x), std::max(avail.y, min_size.y));
364
365 // Reserve space for the canvas
366 ImGui::Dummy(actual_size);
367 // ImGui::SetCursorPos(ImGui::GetCursorPos() - actual_size); // Reset cursor
368 // for drawing
369 }
370}
371
372void DrawDisplaySettings(ImGuiStyle* ref) {
373 // You can pass in a reference ImGuiStyle structure to compare to, revert to
374 // and save to (without a reference style pointer, we will use one compared
375 // locally as a reference)
376 ImGuiStyle& style = ImGui::GetStyle();
377 static ImGuiStyle ref_saved_style;
378
379 // Default to using internal storage as reference
380 static bool init = true;
381 if (init && ref == NULL)
382 ref_saved_style = style;
383 init = false;
384 if (ref == NULL)
385 ref = &ref_saved_style;
386
387 ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
388
389 // Enhanced theme management section
390 if (ImGui::CollapsingHeader("Theme Management",
391 ImGuiTreeNodeFlags_DefaultOpen)) {
392 auto& theme_manager = ThemeManager::Get();
393 static bool show_theme_selector = false;
394 static bool show_theme_editor = false;
395
396 ImGui::Text("%s Current Theme:", ICON_MD_PALETTE);
397 ImGui::SameLine();
398
399 std::string current_theme_name = theme_manager.GetCurrentThemeName();
400 bool is_classic_active = (current_theme_name == "Classic YAZE");
401
402 // Current theme display with color preview
403 if (is_classic_active) {
404 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
405 current_theme_name.c_str());
406 } else {
407 ImGui::Text("%s", current_theme_name.c_str());
408 }
409
410 // Theme color preview
411 auto current_theme = theme_manager.GetCurrentTheme();
412 ImGui::SameLine();
413 ImGui::ColorButton("##primary_preview",
414 gui::ConvertColorToImVec4(current_theme.primary),
415 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
416 ImGui::SameLine();
417 ImGui::ColorButton("##secondary_preview",
418 gui::ConvertColorToImVec4(current_theme.secondary),
419 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
420 ImGui::SameLine();
421 ImGui::ColorButton("##accent_preview",
422 gui::ConvertColorToImVec4(current_theme.accent),
423 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
424
425 ImGui::Spacing();
426
427 // Theme selection table for better organization
428 if (ImGui::BeginTable(
429 "ThemeSelectionTable", 3,
430 ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_NoHostExtendY,
431 ImVec2(0, 80))) {
432 ImGui::TableSetupColumn("Built-in", ImGuiTableColumnFlags_WidthStretch,
433 0.3f);
434 ImGui::TableSetupColumn("File Themes", ImGuiTableColumnFlags_WidthStretch,
435 0.4f);
436 ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthStretch,
437 0.3f);
438 ImGui::TableHeadersRow();
439
440 ImGui::TableNextRow();
441
442 // Built-in themes column
443 ImGui::TableNextColumn();
444 if (is_classic_active) {
445 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f));
446 }
447
448 if (ImGui::Button("Classic YAZE", ImVec2(-1, 30))) {
449 theme_manager.ApplyClassicYazeTheme();
450 ref_saved_style = style;
451 }
452
453 if (is_classic_active) {
454 ImGui::PopStyleColor();
455 }
456
457 if (ImGui::Button("Reset ColorsYaze", ImVec2(-1, 30))) {
459 ref_saved_style = style;
460 }
461
462 // File themes column
463 ImGui::TableNextColumn();
464 auto available_themes = theme_manager.GetAvailableThemes();
465 const char* current_file_theme = "";
466
467 // Find current file theme for display
468 for (const auto& theme_name : available_themes) {
469 if (theme_name == current_theme_name) {
470 current_file_theme = theme_name.c_str();
471 break;
472 }
473 }
474
475 ImGui::SetNextItemWidth(-1);
476 if (ImGui::BeginCombo("##FileThemes", current_file_theme)) {
477 for (const auto& theme_name : available_themes) {
478 bool is_selected = (theme_name == current_theme_name);
479 if (ImGui::Selectable(theme_name.c_str(), is_selected)) {
480 theme_manager.LoadTheme(theme_name);
481 ref_saved_style = style;
482 }
483 }
484 ImGui::EndCombo();
485 }
486
487 if (ImGui::Button("Refresh Themes", ImVec2(-1, 30))) {
488 theme_manager.RefreshAvailableThemes();
489 }
490
491 // Actions column
492 ImGui::TableNextColumn();
493 if (ImGui::Button("Theme Selector", ImVec2(-1, 30))) {
494 show_theme_selector = true;
495 }
496
497 if (ImGui::Button("Theme Editor", ImVec2(-1, 30))) {
498 show_theme_editor = true;
499 }
500
501 ImGui::EndTable();
502 }
503
504 // Show theme dialogs
505 if (show_theme_selector) {
506 theme_manager.ShowThemeSelector(&show_theme_selector);
507 }
508
509 if (show_theme_editor) {
510 theme_manager.ShowSimpleThemeEditor(&show_theme_editor);
511 }
512 }
513
514 ImGui::Separator();
515
516 // Background effects settings
517 auto& bg_renderer = gui::BackgroundRenderer::Get();
518 bg_renderer.DrawSettingsUI();
519
520 ImGui::Separator();
521
522 if (ImGui::ShowStyleSelector("Colors##Selector"))
523 ref_saved_style = style;
524 ImGui::ShowFontSelector("Fonts##Selector");
525
526 // Simplified Settings (expose floating-pointer border sizes as boolean
527 // representing 0.0f or 1.0f)
528 if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
529 "%.0f"))
530 style.GrabRounding = style.FrameRounding; // Make GrabRounding always the
531 // same value as FrameRounding
532 {
533 bool border = (style.WindowBorderSize > 0.0f);
534 if (ImGui::Checkbox("WindowBorder", &border)) {
535 style.WindowBorderSize = border ? 1.0f : 0.0f;
536 }
537 }
538 ImGui::SameLine();
539 {
540 bool border = (style.FrameBorderSize > 0.0f);
541 if (ImGui::Checkbox("FrameBorder", &border)) {
542 style.FrameBorderSize = border ? 1.0f : 0.0f;
543 }
544 }
545 ImGui::SameLine();
546 {
547 bool border = (style.PopupBorderSize > 0.0f);
548 if (ImGui::Checkbox("PopupBorder", &border)) {
549 style.PopupBorderSize = border ? 1.0f : 0.0f;
550 }
551 }
552
553 // Save/Revert button
554 if (ImGui::Button("Save Ref"))
555 *ref = ref_saved_style = style;
556 ImGui::SameLine();
557 if (ImGui::Button("Revert Ref"))
558 style = *ref;
559 ImGui::SameLine();
560
561 ImGui::Separator();
562
563 if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None)) {
564 if (ImGui::BeginTabItem("Sizes")) {
565 ImGui::SeparatorText("Main");
566 ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f,
567 20.0f, "%.0f");
568 ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f,
569 20.0f, "%.0f");
570 ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f,
571 20.0f, "%.0f");
572 ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing,
573 0.0f, 20.0f, "%.0f");
574 ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding,
575 0.0f, 10.0f, "%.0f");
576 ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f,
577 "%.0f");
578 ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f,
579 "%.0f");
580 ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f,
581 "%.0f");
582
583 ImGui::SeparatorText("Borders");
584 ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f,
585 1.0f, "%.0f");
586 ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f,
587 "%.0f");
588 ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f,
589 "%.0f");
590 ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f,
591 "%.0f");
592 ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f,
593 "%.0f");
594 ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f,
595 2.0f, "%.0f");
596
597 ImGui::SeparatorText("Rounding");
598 ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f,
599 "%.0f");
600 ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f,
601 "%.0f");
602 ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
603 "%.0f");
604 ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f,
605 "%.0f");
606 ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f,
607 12.0f, "%.0f");
608 ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f,
609 "%.0f");
610 ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f,
611 "%.0f");
612
613 ImGui::SeparatorText("Tables");
614 ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f,
615 20.0f, "%.0f");
616 ImGui::SliderAngle("TableAngledHeadersAngle",
617 &style.TableAngledHeadersAngle, -50.0f, +50.0f);
618
619 ImGui::SeparatorText("Widgets");
620 ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign,
621 0.0f, 1.0f, "%.2f");
622 ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition,
623 "Left\0Right\0");
624 ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign,
625 0.0f, 1.0f, "%.2f");
626 ImGui::SameLine();
627
628 ImGui::SliderFloat2("SelectableTextAlign",
629 (float*)&style.SelectableTextAlign, 0.0f, 1.0f,
630 "%.2f");
631 ImGui::SameLine();
632
633 ImGui::SliderFloat("SeparatorTextBorderSize",
634 &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
635 ImGui::SliderFloat2("SeparatorTextAlign",
636 (float*)&style.SeparatorTextAlign, 0.0f, 1.0f,
637 "%.2f");
638 ImGui::SliderFloat2("SeparatorTextPadding",
639 (float*)&style.SeparatorTextPadding, 0.0f, 40.0f,
640 "%.0f");
641 ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f,
642 12.0f, "%.0f");
643
644 ImGui::SeparatorText("Tooltips");
645 for (int n = 0; n < 2; n++)
646 if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse"
647 : "HoverFlagsForTooltipNav")) {
648 ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse
649 : &style.HoverFlagsForTooltipNav;
650 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p,
651 ImGuiHoveredFlags_DelayNone);
652 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p,
653 ImGuiHoveredFlags_DelayShort);
654 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p,
655 ImGuiHoveredFlags_DelayNormal);
656 ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p,
657 ImGuiHoveredFlags_Stationary);
658 ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p,
659 ImGuiHoveredFlags_NoSharedDelay);
660 ImGui::TreePop();
661 }
662
663 ImGui::SeparatorText("Misc");
664 ImGui::SliderFloat2("DisplaySafeAreaPadding",
665 (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f,
666 "%.0f");
667 ImGui::SameLine();
668
669 ImGui::EndTabItem();
670 }
671
672 if (ImGui::BeginTabItem("Colors")) {
673 static int output_dest = 0;
674 static bool output_only_modified = true;
675 if (ImGui::Button("Export")) {
676 if (output_dest == 0)
677 ImGui::LogToClipboard();
678 else
679 ImGui::LogToTTY();
680 ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
681 for (int i = 0; i < ImGuiCol_COUNT; i++) {
682 const ImVec4& col = style.Colors[i];
683 const char* name = ImGui::GetStyleColorName(i);
684 if (!output_only_modified ||
685 memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
686 ImGui::LogText(
687 "colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, "
688 "%.2ff);" IM_NEWLINE,
689 name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
690 }
691 ImGui::LogFinish();
692 }
693 ImGui::SameLine();
694 ImGui::SetNextItemWidth(120);
695 ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
696 ImGui::SameLine();
697 ImGui::Checkbox("Only Modified Colors", &output_only_modified);
698
699 static ImGuiTextFilter filter;
700 filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
701
702 static ImGuiColorEditFlags alpha_flags = 0;
703 if (ImGui::RadioButton("Opaque",
704 alpha_flags == ImGuiColorEditFlags_None)) {
705 alpha_flags = ImGuiColorEditFlags_None;
706 }
707 ImGui::SameLine();
708 if (ImGui::RadioButton("Alpha",
709 alpha_flags == ImGuiColorEditFlags_AlphaPreview)) {
710 alpha_flags = ImGuiColorEditFlags_AlphaPreview;
711 }
712 ImGui::SameLine();
713 if (ImGui::RadioButton(
714 "Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) {
715 alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
716 }
717 ImGui::SameLine();
718
719 ImGui::SetNextWindowSizeConstraints(
720 ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10),
721 ImVec2(FLT_MAX, FLT_MAX));
722 ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border,
723 ImGuiWindowFlags_AlwaysVerticalScrollbar |
724 ImGuiWindowFlags_AlwaysHorizontalScrollbar |
725 ImGuiWindowFlags_NavFlattened);
726 ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
727 for (int i = 0; i < ImGuiCol_COUNT; i++) {
728 const char* name = ImGui::GetStyleColorName(i);
729 if (!filter.PassFilter(name))
730 continue;
731 ImGui::PushID(i);
732 ImGui::ColorEdit4("##color", (float*)&style.Colors[i],
733 ImGuiColorEditFlags_AlphaBar | alpha_flags);
734 if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
735 // Tips: in a real user application, you may want to merge and use
736 // an icon font into the main font, so instead of "Save"/"Revert"
737 // you'd use icons! Read the FAQ and docs/FONTS.md about using icon
738 // fonts. It's really easy and super convenient!
739 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
740 if (ImGui::Button("Save")) {
741 ref->Colors[i] = style.Colors[i];
742 }
743 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
744 if (ImGui::Button("Revert")) {
745 style.Colors[i] = ref->Colors[i];
746 }
747 }
748 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
749 ImGui::TextUnformatted(name);
750 ImGui::PopID();
751 }
752 ImGui::PopItemWidth();
753 ImGui::EndChild();
754
755 ImGui::EndTabItem();
756 }
757
758 if (ImGui::BeginTabItem("Fonts")) {
759 ImGuiIO& io = ImGui::GetIO();
760 ImFontAtlas* atlas = io.Fonts;
761 ImGui::ShowFontAtlas(atlas);
762
763 // Post-baking font scaling. Note that this is NOT the nice way of
764 // scaling fonts, read below. (we enforce hard clamping manually as by
765 // default DragFloat/SliderFloat allows CTRL+Click text to get out of
766 // bounds).
767 const float MIN_SCALE = 0.3f;
768 const float MAX_SCALE = 2.0f;
769
770 static float window_scale = 1.0f;
771 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
772 if (ImGui::DragFloat(
773 "window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE,
774 "%.2f",
775 ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
776 ImGui::SetWindowFontScale(window_scale);
777 ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE,
778 MAX_SCALE, "%.2f",
779 ImGuiSliderFlags_AlwaysClamp); // Scale everything
780 ImGui::PopItemWidth();
781
782 ImGui::EndTabItem();
783 }
784
785 if (ImGui::BeginTabItem("Rendering")) {
786 ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
787 ImGui::SameLine();
788
789 ImGui::Checkbox("Anti-aliased lines use texture",
790 &style.AntiAliasedLinesUseTex);
791 ImGui::SameLine();
792
793 ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
794 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
795 ImGui::DragFloat("Curve Tessellation Tolerance",
796 &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f,
797 "%.2f");
798 if (style.CurveTessellationTol < 0.10f)
799 style.CurveTessellationTol = 0.10f;
800
801 // When editing the "Circle Segment Max Error" value, draw a preview of
802 // its effect on auto-tessellated circles.
803 ImGui::DragFloat("Circle Tessellation Max Error",
804 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
805 "%.2f", ImGuiSliderFlags_AlwaysClamp);
806 const bool show_samples = ImGui::IsItemActive();
807 if (show_samples)
808 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
809 if (show_samples && ImGui::BeginTooltip()) {
810 ImGui::TextUnformatted("(R = radius, N = number of segments)");
811 ImGui::Spacing();
812 ImDrawList* draw_list = ImGui::GetWindowDrawList();
813 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
814 for (int n = 0; n < 8; n++) {
815 const float RAD_MIN = 5.0f;
816 const float RAD_MAX = 70.0f;
817 const float rad =
818 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
819
820 ImGui::BeginGroup();
821
822 ImGui::Text("R: %.f\nN: %d", rad,
823 draw_list->_CalcCircleAutoSegmentCount(rad));
824
825 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
826 const float offset_x = floorf(canvas_width * 0.5f);
827 const float offset_y = floorf(RAD_MAX);
828
829 const ImVec2 p1 = ImGui::GetCursorScreenPos();
830 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
831 ImGui::GetColorU32(ImGuiCol_Text));
832 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
833
834 /*
835 const ImVec2 p2 = ImGui::GetCursorScreenPos();
836 draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y),
837 rad, ImGui::GetColorU32(ImGuiCol_Text));
838 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
839 */
840
841 ImGui::EndGroup();
842 ImGui::SameLine();
843 }
844 ImGui::EndTooltip();
845 }
846 ImGui::SameLine();
847
848 ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f,
849 "%.2f"); // Not exposing zero here so user doesn't
850 // "lose" the UI (zero alpha clips all
851 // widgets). But application code could have a
852 // toggle to switch between zero and non-zero.
853 ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f,
854 1.0f, "%.2f");
855 ImGui::SameLine();
856
857 ImGui::PopItemWidth();
858
859 ImGui::EndTabItem();
860 }
861
862 ImGui::EndTabBar();
863 }
864
865 ImGui::PopItemWidth();
866}
867
868void DrawDisplaySettingsForPopup(ImGuiStyle* ref) {
869 // Popup-safe version of DrawDisplaySettings without problematic tables
870 ImGuiStyle& style = ImGui::GetStyle();
871 static ImGuiStyle ref_saved_style;
872
873 // Default to using internal storage as reference
874 static bool init = true;
875 if (init && ref == NULL)
876 ref_saved_style = style;
877 init = false;
878 if (ref == NULL)
879 ref = &ref_saved_style;
880
881 ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
882
883 // Enhanced theme management section (simplified for popup)
884 if (ImGui::CollapsingHeader("Theme Management",
885 ImGuiTreeNodeFlags_DefaultOpen)) {
886 auto& theme_manager = ThemeManager::Get();
887
888 ImGui::Text("%s Current Theme:", ICON_MD_PALETTE);
889 ImGui::SameLine();
890
891 std::string current_theme_name = theme_manager.GetCurrentThemeName();
892 bool is_classic_active = (current_theme_name == "Classic YAZE");
893
894 // Current theme display with color preview
895 if (is_classic_active) {
896 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
897 current_theme_name.c_str());
898 } else {
899 ImGui::Text("%s", current_theme_name.c_str());
900 }
901
902 // Theme color preview
903 auto current_theme = theme_manager.GetCurrentTheme();
904 ImGui::SameLine();
905 ImGui::ColorButton("##primary_preview",
906 gui::ConvertColorToImVec4(current_theme.primary),
907 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
908 ImGui::SameLine();
909 ImGui::ColorButton("##secondary_preview",
910 gui::ConvertColorToImVec4(current_theme.secondary),
911 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
912 ImGui::SameLine();
913 ImGui::ColorButton("##accent_preview",
914 gui::ConvertColorToImVec4(current_theme.accent),
915 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
916
917 ImGui::Spacing();
918
919 // Simplified theme selection (no table to avoid popup conflicts)
920 if (is_classic_active) {
921 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f));
922 }
923
924 if (ImGui::Button("Classic YAZE")) {
925 theme_manager.ApplyClassicYazeTheme();
926 ref_saved_style = style;
927 }
928
929 if (is_classic_active) {
930 ImGui::PopStyleColor();
931 }
932
933 ImGui::SameLine();
934 if (ImGui::Button("Reset ColorsYaze")) {
936 ref_saved_style = style;
937 }
938
939 // File themes dropdown
940 auto available_themes = theme_manager.GetAvailableThemes();
941 const char* current_file_theme = "";
942
943 // Find current file theme for display
944 for (const auto& theme_name : available_themes) {
945 if (theme_name == current_theme_name) {
946 current_file_theme = theme_name.c_str();
947 break;
948 }
949 }
950
951 ImGui::Text("File Themes:");
952 ImGui::SetNextItemWidth(-1);
953 if (ImGui::BeginCombo("##FileThemes", current_file_theme)) {
954 for (const auto& theme_name : available_themes) {
955 bool is_selected = (theme_name == current_theme_name);
956 if (ImGui::Selectable(theme_name.c_str(), is_selected)) {
957 theme_manager.LoadTheme(theme_name);
958 ref_saved_style = style;
959 }
960 }
961 ImGui::EndCombo();
962 }
963
964 if (ImGui::Button("Refresh Themes")) {
965 theme_manager.RefreshAvailableThemes();
966 }
967 ImGui::SameLine();
968 if (ImGui::Button("Open Theme Editor")) {
969 static bool show_theme_editor = true;
970 theme_manager.ShowSimpleThemeEditor(&show_theme_editor);
971 }
972 }
973
974 ImGui::Separator();
975
976 // Background effects settings
977 auto& bg_renderer = gui::BackgroundRenderer::Get();
978 bg_renderer.DrawSettingsUI();
979
980 ImGui::Separator();
981
982 if (ImGui::ShowStyleSelector("Colors##Selector"))
983 ref_saved_style = style;
984 ImGui::ShowFontSelector("Fonts##Selector");
985
986 // Quick style controls before the tabbed section
987 if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
988 "%.0f"))
989 style.GrabRounding = style.FrameRounding;
990
991 // Border checkboxes (simplified layout)
992 bool window_border = (style.WindowBorderSize > 0.0f);
993 if (ImGui::Checkbox("WindowBorder", &window_border)) {
994 style.WindowBorderSize = window_border ? 1.0f : 0.0f;
995 }
996 ImGui::SameLine();
997
998 bool frame_border = (style.FrameBorderSize > 0.0f);
999 if (ImGui::Checkbox("FrameBorder", &frame_border)) {
1000 style.FrameBorderSize = frame_border ? 1.0f : 0.0f;
1001 }
1002 ImGui::SameLine();
1003
1004 bool popup_border = (style.PopupBorderSize > 0.0f);
1005 if (ImGui::Checkbox("PopupBorder", &popup_border)) {
1006 style.PopupBorderSize = popup_border ? 1.0f : 0.0f;
1007 }
1008
1009 // Save/Revert buttons
1010 if (ImGui::Button("Save Ref"))
1011 *ref = ref_saved_style = style;
1012 ImGui::SameLine();
1013 if (ImGui::Button("Revert Ref"))
1014 style = *ref;
1015
1016 ImGui::Separator();
1017
1018 // Add the comprehensive tabbed settings from the original DrawDisplaySettings
1019 if (ImGui::BeginTabBar("DisplaySettingsTabs", ImGuiTabBarFlags_None)) {
1020 if (ImGui::BeginTabItem("Sizes")) {
1021 ImGui::SeparatorText("Main");
1022 ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f,
1023 20.0f, "%.0f");
1024 ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f,
1025 20.0f, "%.0f");
1026 ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f,
1027 20.0f, "%.0f");
1028 ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing,
1029 0.0f, 20.0f, "%.0f");
1030 ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding,
1031 0.0f, 10.0f, "%.0f");
1032 ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f,
1033 "%.0f");
1034 ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f,
1035 "%.0f");
1036 ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f,
1037 "%.0f");
1038
1039 ImGui::SeparatorText("Borders");
1040 ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f,
1041 1.0f, "%.0f");
1042 ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f,
1043 "%.0f");
1044 ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f,
1045 "%.0f");
1046 ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f,
1047 "%.0f");
1048 ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f,
1049 "%.0f");
1050 ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f,
1051 2.0f, "%.0f");
1052
1053 ImGui::SeparatorText("Rounding");
1054 ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f,
1055 "%.0f");
1056 ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f,
1057 "%.0f");
1058 ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
1059 "%.0f");
1060 ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f,
1061 "%.0f");
1062 ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f,
1063 12.0f, "%.0f");
1064 ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f,
1065 "%.0f");
1066 ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f,
1067 "%.0f");
1068
1069 ImGui::SeparatorText("Tables");
1070 ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f,
1071 20.0f, "%.0f");
1072 ImGui::SliderAngle("TableAngledHeadersAngle",
1073 &style.TableAngledHeadersAngle, -50.0f, +50.0f);
1074
1075 ImGui::SeparatorText("Widgets");
1076 ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign,
1077 0.0f, 1.0f, "%.2f");
1078 ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition,
1079 "Left\0Right\0");
1080 ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign,
1081 0.0f, 1.0f, "%.2f");
1082 ImGui::SameLine();
1083
1084 ImGui::SliderFloat2("SelectableTextAlign",
1085 (float*)&style.SelectableTextAlign, 0.0f, 1.0f,
1086 "%.2f");
1087 ImGui::SameLine();
1088
1089 ImGui::SliderFloat("SeparatorTextBorderSize",
1090 &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
1091 ImGui::SliderFloat2("SeparatorTextAlign",
1092 (float*)&style.SeparatorTextAlign, 0.0f, 1.0f,
1093 "%.2f");
1094 ImGui::SliderFloat2("SeparatorTextPadding",
1095 (float*)&style.SeparatorTextPadding, 0.0f, 40.0f,
1096 "%.0f");
1097 ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f,
1098 12.0f, "%.0f");
1099
1100 ImGui::SeparatorText("Tooltips");
1101 for (int n = 0; n < 2; n++)
1102 if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse"
1103 : "HoverFlagsForTooltipNav")) {
1104 ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse
1105 : &style.HoverFlagsForTooltipNav;
1106 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p,
1107 ImGuiHoveredFlags_DelayNone);
1108 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p,
1109 ImGuiHoveredFlags_DelayShort);
1110 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p,
1111 ImGuiHoveredFlags_DelayNormal);
1112 ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p,
1113 ImGuiHoveredFlags_Stationary);
1114 ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p,
1115 ImGuiHoveredFlags_NoSharedDelay);
1116 ImGui::TreePop();
1117 }
1118
1119 ImGui::SeparatorText("Misc");
1120 ImGui::SliderFloat2("DisplaySafeAreaPadding",
1121 (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f,
1122 "%.0f");
1123 ImGui::SameLine();
1124
1125 ImGui::EndTabItem();
1126 }
1127
1128 if (ImGui::BeginTabItem("Colors")) {
1129 static int output_dest = 0;
1130 static bool output_only_modified = true;
1131 if (ImGui::Button("Export")) {
1132 if (output_dest == 0)
1133 ImGui::LogToClipboard();
1134 else
1135 ImGui::LogToTTY();
1136 ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
1137 for (int i = 0; i < ImGuiCol_COUNT; i++) {
1138 const ImVec4& col = style.Colors[i];
1139 const char* name = ImGui::GetStyleColorName(i);
1140 if (!output_only_modified ||
1141 memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
1142 ImGui::LogText(
1143 "colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, "
1144 "%.2ff);" IM_NEWLINE,
1145 name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
1146 }
1147 ImGui::LogFinish();
1148 }
1149 ImGui::SameLine();
1150 ImGui::SetNextItemWidth(120);
1151 ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
1152 ImGui::SameLine();
1153 ImGui::Checkbox("Only Modified Colors", &output_only_modified);
1154
1155 static ImGuiTextFilter filter;
1156 filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
1157
1158 static ImGuiColorEditFlags alpha_flags = 0;
1159 if (ImGui::RadioButton("Opaque",
1160 alpha_flags == ImGuiColorEditFlags_None)) {
1161 alpha_flags = ImGuiColorEditFlags_None;
1162 }
1163 ImGui::SameLine();
1164 if (ImGui::RadioButton("Alpha",
1165 alpha_flags == ImGuiColorEditFlags_AlphaPreview)) {
1166 alpha_flags = ImGuiColorEditFlags_AlphaPreview;
1167 }
1168 ImGui::SameLine();
1169 if (ImGui::RadioButton(
1170 "Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) {
1171 alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
1172 }
1173 ImGui::SameLine();
1174
1175 ImGui::SetNextWindowSizeConstraints(
1176 ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10),
1177 ImVec2(FLT_MAX, FLT_MAX));
1178 ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border,
1179 ImGuiWindowFlags_AlwaysVerticalScrollbar |
1180 ImGuiWindowFlags_AlwaysHorizontalScrollbar |
1181 ImGuiWindowFlags_NavFlattened);
1182 ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
1183 for (int i = 0; i < ImGuiCol_COUNT; i++) {
1184 const char* name = ImGui::GetStyleColorName(i);
1185 if (!filter.PassFilter(name))
1186 continue;
1187 ImGui::PushID(i);
1188 ImGui::ColorEdit4("##color", (float*)&style.Colors[i],
1189 ImGuiColorEditFlags_AlphaBar | alpha_flags);
1190 if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
1191 // Tips: in a real user application, you may want to merge and use
1192 // an icon font into the main font, so instead of "Save"/"Revert"
1193 // you'd use icons! Read the FAQ and docs/FONTS.md about using icon
1194 // fonts. It's really easy and super convenient!
1195 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1196 if (ImGui::Button("Save")) {
1197 ref->Colors[i] = style.Colors[i];
1198 }
1199 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1200 if (ImGui::Button("Revert")) {
1201 style.Colors[i] = ref->Colors[i];
1202 }
1203 }
1204 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1205 ImGui::TextUnformatted(name);
1206 ImGui::PopID();
1207 }
1208 ImGui::PopItemWidth();
1209 ImGui::EndChild();
1210
1211 ImGui::EndTabItem();
1212 }
1213
1214 if (ImGui::BeginTabItem("Fonts")) {
1215 ImGuiIO& io = ImGui::GetIO();
1216 ImFontAtlas* atlas = io.Fonts;
1217 ImGui::ShowFontAtlas(atlas);
1218
1219 // Post-baking font scaling. Note that this is NOT the nice way of
1220 // scaling fonts, read below. (we enforce hard clamping manually as by
1221 // default DragFloat/SliderFloat allows CTRL+Click text to get out of
1222 // bounds).
1223 const float MIN_SCALE = 0.3f;
1224 const float MAX_SCALE = 2.0f;
1225
1226 static float window_scale = 1.0f;
1227 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
1228 if (ImGui::DragFloat(
1229 "window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE,
1230 "%.2f",
1231 ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
1232 ImGui::SetWindowFontScale(window_scale);
1233 ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE,
1234 MAX_SCALE, "%.2f",
1235 ImGuiSliderFlags_AlwaysClamp); // Scale everything
1236 ImGui::PopItemWidth();
1237
1238 ImGui::EndTabItem();
1239 }
1240
1241 if (ImGui::BeginTabItem("Rendering")) {
1242 ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
1243 ImGui::SameLine();
1244
1245 ImGui::Checkbox("Anti-aliased lines use texture",
1246 &style.AntiAliasedLinesUseTex);
1247 ImGui::SameLine();
1248
1249 ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
1250 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
1251 ImGui::DragFloat("Curve Tessellation Tolerance",
1252 &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f,
1253 "%.2f");
1254 if (style.CurveTessellationTol < 0.10f)
1255 style.CurveTessellationTol = 0.10f;
1256
1257 // When editing the "Circle Segment Max Error" value, draw a preview of
1258 // its effect on auto-tessellated circles.
1259 ImGui::DragFloat("Circle Tessellation Max Error",
1260 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
1261 "%.2f", ImGuiSliderFlags_AlwaysClamp);
1262 const bool show_samples = ImGui::IsItemActive();
1263 if (show_samples)
1264 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
1265 if (show_samples && ImGui::BeginTooltip()) {
1266 ImGui::TextUnformatted("(R = radius, N = number of segments)");
1267 ImGui::Spacing();
1268 ImDrawList* draw_list = ImGui::GetWindowDrawList();
1269 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
1270 for (int n = 0; n < 8; n++) {
1271 const float RAD_MIN = 5.0f;
1272 const float RAD_MAX = 70.0f;
1273 const float rad =
1274 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
1275
1276 ImGui::BeginGroup();
1277
1278 ImGui::Text("R: %.f\nN: %d", rad,
1279 draw_list->_CalcCircleAutoSegmentCount(rad));
1280
1281 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
1282 const float offset_x = floorf(canvas_width * 0.5f);
1283 const float offset_y = floorf(RAD_MAX);
1284
1285 const ImVec2 p1 = ImGui::GetCursorScreenPos();
1286 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
1287 ImGui::GetColorU32(ImGuiCol_Text));
1288 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
1289
1290 ImGui::EndGroup();
1291 ImGui::SameLine();
1292 }
1293 ImGui::EndTooltip();
1294 }
1295 ImGui::SameLine();
1296
1297 ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f,
1298 "%.2f"); // Not exposing zero here so user doesn't
1299 // "lose" the UI (zero alpha clips all
1300 // widgets). But application code could have a
1301 // toggle to switch between zero and non-zero.
1302 ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f,
1303 1.0f, "%.2f");
1304 ImGui::SameLine();
1305
1306 ImGui::PopItemWidth();
1307
1308 ImGui::EndTabItem();
1309 }
1310
1311 ImGui::EndTabBar();
1312 }
1313
1314 ImGui::PopItemWidth();
1315}
1316
1317void TextWithSeparators(const absl::string_view& text) {
1318 ImGui::Separator();
1319 ImGui::Text("%s", text.data());
1320 ImGui::Separator();
1321}
1322
1324 ImGuiIO& io = ImGui::GetIO();
1325 ImFontAtlas* atlas = io.Fonts;
1326
1327 static ImFont* current_font = atlas->Fonts[0];
1328 static int current_font_index = 0;
1329 static int font_size = 16;
1330 static bool font_selected = false;
1331
1332 ImGui::Text("Loaded fonts");
1333 for (const auto& loaded_font : font_registry.fonts) {
1334 ImGui::Text("%s", loaded_font.font_path);
1335 }
1336 ImGui::Separator();
1337
1338 ImGui::Text("Current Font: %s", current_font->GetDebugName());
1339 ImGui::Text("Font Size: %d", font_size);
1340
1341 if (ImGui::BeginCombo("Fonts", current_font->GetDebugName())) {
1342 for (int i = 0; i < atlas->Fonts.Size; i++) {
1343 bool is_selected = (current_font == atlas->Fonts[i]);
1344 if (ImGui::Selectable(atlas->Fonts[i]->GetDebugName(), is_selected)) {
1345 current_font = atlas->Fonts[i];
1346 current_font_index = i;
1347 font_selected = true;
1348 }
1349 if (is_selected) {
1350 ImGui::SetItemDefaultFocus();
1351 }
1352 }
1353 ImGui::EndCombo();
1354 }
1355
1356 ImGui::Separator();
1357 if (ImGui::SliderInt("Font Size", &font_size, 8, 32)) {
1358 current_font->Scale = font_size / 16.0f;
1359 }
1360}
1361
1362} // namespace gui
1363} // namespace yaze
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
TextureHandle texture() const
Definition bitmap.h:380
int height() const
Definition bitmap.h:374
int width() const
Definition bitmap.h:373
static BackgroundRenderer & Get()
static ThemeManager & Get()
#define ICON_MD_PALETTE
Definition icons.h:1370
Color ParseColor(const std::string &color)
Definition style.cc:19
void DrawBitmapViewer(const std::vector< gfx::Bitmap > &bitmaps, float scale, int &current_bitmap_id)
Definition style.cc:132
void BeginCanvasTableCell(ImVec2 min_size)
Definition style.cc:356
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:23
void BeginTableCanvas(const char *table_id, int columns, ImVec2 canvas_size)
Definition style.cc:327
void DrawFontManager()
Definition style.cc:1323
void BeginPadding(int i)
Definition style.cc:274
void BeginChildBothScrollbars(int id)
Definition style.cc:319
void EndNoPadding()
Definition style.cc:286
TextEditor::LanguageDefinition GetAssemblyLanguageDef()
Definition style.cc:193
void DrawDisplaySettings(ImGuiStyle *ref)
Definition style.cc:372
void EndPadding()
Definition style.cc:278
void BeginNoPadding()
Definition style.cc:282
void SetupCanvasTableColumn(const char *label, float width_ratio)
Definition style.cc:347
void EndWindowWithDisplaySettings()
Definition style.cc:269
void DrawDisplaySettingsForPopup(ImGuiStyle *ref)
Definition style.cc:868
void EndTableCanvas()
Definition style.cc:343
void ColorsYaze()
Definition style.cc:32
void BeginWindowWithDisplaySettings(const char *id, bool *active, const ImVec2 &size, ImGuiWindowFlags flags)
Definition style.cc:249
void TextWithSeparators(const absl::string_view &text)
Definition style.cc:1317
void BeginChildWithScrollbar(const char *str_id)
Definition style.cc:290
TokenRegexStrings mTokenRegexStrings
float green
Definition color.h:16