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 bool horizontal_scroll) {
304 // Set content size before beginning child to enable proper scrolling.
305 // Allow callers to communicate only one axis when the other should remain
306 // auto-sized by ImGui.
307 if (content_size.x > 0.0f || content_size.y > 0.0f) {
308 ImGui::SetNextWindowContentSize(content_size);
309 }
310
311 // Get available region but ensure minimum size for proper scrolling
312 ImVec2 available = ImGui::GetContentRegionAvail();
313 if (available.x < 64.0f)
314 available.x = 64.0f;
315 if (available.y < 64.0f)
316 available.y = 64.0f;
317
318 ImGui::BeginChild(
319 str_id, available, true,
320 ImGuiWindowFlags_AlwaysVerticalScrollbar |
321 (horizontal_scroll ? ImGuiWindowFlags_AlwaysHorizontalScrollbar : 0));
322}
323
325 ImGuiID child_id = ImGui::GetID((void*)(intptr_t)id);
326 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
327 ImGuiWindowFlags_AlwaysVerticalScrollbar |
328 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
329}
330
331// Helper functions for table canvas management
332void BeginTableCanvas(const char* table_id, int columns, ImVec2 canvas_size) {
333 // Use proper sizing for tables containing canvas elements
334 ImGuiTableFlags flags =
335 ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchProp;
336
337 // If canvas size is specified, use it as minimum size
338 ImVec2 outer_size = ImVec2(0, 0);
339 if (canvas_size.x > 0 || canvas_size.y > 0) {
340 outer_size = canvas_size;
341 flags |= ImGuiTableFlags_NoHostExtendY; // Prevent auto-extending past
342 // canvas size
343 }
344
345 ImGui::BeginTable(table_id, columns, flags, outer_size);
346}
347
349 ImGui::EndTable();
350}
351
352void SetupCanvasTableColumn(const char* label, float width_ratio) {
353 if (width_ratio > 0) {
354 ImGui::TableSetupColumn(label, ImGuiTableColumnFlags_WidthStretch,
355 width_ratio);
356 } else {
357 ImGui::TableSetupColumn(label, ImGuiTableColumnFlags_WidthStretch);
358 }
359}
360
361void BeginCanvasTableCell(ImVec2 min_size) {
362 ImGui::TableNextColumn();
363
364 // Ensure minimum size for canvas cells
365 if (min_size.x > 0 || min_size.y > 0) {
366 ImVec2 avail = ImGui::GetContentRegionAvail();
367 ImVec2 actual_size =
368 ImVec2(std::max(avail.x, min_size.x), std::max(avail.y, min_size.y));
369
370 // Reserve space for the canvas
371 ImGui::Dummy(actual_size);
372 // ImGui::SetCursorPos(ImGui::GetCursorPos() - actual_size); // Reset cursor
373 // for drawing
374 }
375}
376
377void DrawDisplaySettings(ImGuiStyle* ref) {
378 // You can pass in a reference ImGuiStyle structure to compare to, revert to
379 // and save to (without a reference style pointer, we will use one compared
380 // locally as a reference)
381 ImGuiStyle& style = ImGui::GetStyle();
382 static ImGuiStyle ref_saved_style;
383
384 // Default to using internal storage as reference
385 static bool init = true;
386 if (init && ref == NULL)
387 ref_saved_style = style;
388 init = false;
389 if (ref == NULL)
390 ref = &ref_saved_style;
391
392 ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
393
394 // Enhanced theme management section
395 if (ImGui::CollapsingHeader("Theme Management",
396 ImGuiTreeNodeFlags_DefaultOpen)) {
397 auto& theme_manager = ThemeManager::Get();
398 static bool show_theme_selector = false;
399 static bool show_theme_editor = false;
400
401 ImGui::Text("%s Current Theme:", ICON_MD_PALETTE);
402 ImGui::SameLine();
403
404 std::string current_theme_name = theme_manager.GetCurrentThemeName();
405 bool is_classic_active = (current_theme_name == "Classic YAZE");
406
407 // Current theme display with color preview
408 if (is_classic_active) {
409 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
410 current_theme_name.c_str());
411 } else {
412 ImGui::Text("%s", current_theme_name.c_str());
413 }
414
415 // Theme color preview
416 auto current_theme = theme_manager.GetCurrentTheme();
417 ImGui::SameLine();
418 ImGui::ColorButton("##primary_preview",
419 gui::ConvertColorToImVec4(current_theme.primary),
420 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
421 ImGui::SameLine();
422 ImGui::ColorButton("##secondary_preview",
423 gui::ConvertColorToImVec4(current_theme.secondary),
424 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
425 ImGui::SameLine();
426 ImGui::ColorButton("##accent_preview",
427 gui::ConvertColorToImVec4(current_theme.accent),
428 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
429
430 ImGui::Spacing();
431
432 // Theme selection table for better organization
433 if (ImGui::BeginTable(
434 "ThemeSelectionTable", 3,
435 ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_NoHostExtendY,
436 ImVec2(0, 80))) {
437 ImGui::TableSetupColumn("Built-in", ImGuiTableColumnFlags_WidthStretch,
438 0.3f);
439 ImGui::TableSetupColumn("File Themes", ImGuiTableColumnFlags_WidthStretch,
440 0.4f);
441 ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthStretch,
442 0.3f);
443 ImGui::TableHeadersRow();
444
445 ImGui::TableNextRow();
446
447 // Built-in themes column
448 ImGui::TableNextColumn();
449 if (is_classic_active) {
450 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f));
451 }
452
453 if (ImGui::Button("Classic YAZE", ImVec2(-1, 30))) {
454 theme_manager.ApplyClassicYazeTheme();
455 ref_saved_style = style;
456 }
457
458 if (is_classic_active) {
459 ImGui::PopStyleColor();
460 }
461
462 if (ImGui::Button("Reset ColorsYaze", ImVec2(-1, 30))) {
464 ref_saved_style = style;
465 }
466
467 // File themes column
468 ImGui::TableNextColumn();
469 auto available_themes = theme_manager.GetAvailableThemes();
470 const char* current_file_theme = "";
471
472 // Find current file theme for display
473 for (const auto& theme_name : available_themes) {
474 if (theme_name == current_theme_name) {
475 current_file_theme = theme_name.c_str();
476 break;
477 }
478 }
479
480 ImGui::SetNextItemWidth(-1);
481 if (ImGui::BeginCombo("##FileThemes", current_file_theme)) {
482 for (const auto& theme_name : available_themes) {
483 bool is_selected = (theme_name == current_theme_name);
484 if (ImGui::Selectable(theme_name.c_str(), is_selected)) {
485 theme_manager.LoadTheme(theme_name);
486 ref_saved_style = style;
487 }
488 }
489 ImGui::EndCombo();
490 }
491
492 if (ImGui::Button("Refresh Themes", ImVec2(-1, 30))) {
493 theme_manager.RefreshAvailableThemes();
494 }
495
496 // Actions column
497 ImGui::TableNextColumn();
498 if (ImGui::Button("Theme Selector", ImVec2(-1, 30))) {
499 show_theme_selector = true;
500 }
501
502 if (ImGui::Button("Theme Editor", ImVec2(-1, 30))) {
503 show_theme_editor = true;
504 }
505
506 ImGui::EndTable();
507 }
508
509 // Show theme dialogs
510 if (show_theme_selector) {
511 theme_manager.ShowThemeSelector(&show_theme_selector);
512 }
513
514 if (show_theme_editor) {
515 theme_manager.ShowSimpleThemeEditor(&show_theme_editor);
516 }
517 }
518
519 ImGui::Separator();
520
521 // Background effects settings
522 auto& bg_renderer = gui::BackgroundRenderer::Get();
523 bg_renderer.DrawSettingsUI();
524
525 ImGui::Separator();
526
527 if (ImGui::ShowStyleSelector("Colors##Selector"))
528 ref_saved_style = style;
529 ImGui::ShowFontSelector("Fonts##Selector");
530
531 // Simplified Settings (expose floating-pointer border sizes as boolean
532 // representing 0.0f or 1.0f)
533 if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
534 "%.0f"))
535 style.GrabRounding = style.FrameRounding; // Make GrabRounding always the
536 // same value as FrameRounding
537 {
538 bool border = (style.WindowBorderSize > 0.0f);
539 if (ImGui::Checkbox("WindowBorder", &border)) {
540 style.WindowBorderSize = border ? 1.0f : 0.0f;
541 }
542 }
543 ImGui::SameLine();
544 {
545 bool border = (style.FrameBorderSize > 0.0f);
546 if (ImGui::Checkbox("FrameBorder", &border)) {
547 style.FrameBorderSize = border ? 1.0f : 0.0f;
548 }
549 }
550 ImGui::SameLine();
551 {
552 bool border = (style.PopupBorderSize > 0.0f);
553 if (ImGui::Checkbox("PopupBorder", &border)) {
554 style.PopupBorderSize = border ? 1.0f : 0.0f;
555 }
556 }
557
558 // Save/Revert button
559 if (ImGui::Button("Save Ref"))
560 *ref = ref_saved_style = style;
561 ImGui::SameLine();
562 if (ImGui::Button("Revert Ref"))
563 style = *ref;
564 ImGui::SameLine();
565
566 ImGui::Separator();
567
568 if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None)) {
569 if (ImGui::BeginTabItem("Sizes")) {
570 ImGui::SeparatorText("Main");
571 ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f,
572 20.0f, "%.0f");
573 ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f,
574 20.0f, "%.0f");
575 ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f,
576 20.0f, "%.0f");
577 ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing,
578 0.0f, 20.0f, "%.0f");
579 ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding,
580 0.0f, 10.0f, "%.0f");
581 ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f,
582 "%.0f");
583 ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f,
584 "%.0f");
585 ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f,
586 "%.0f");
587
588 ImGui::SeparatorText("Borders");
589 ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f,
590 1.0f, "%.0f");
591 ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f,
592 "%.0f");
593 ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f,
594 "%.0f");
595 ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f,
596 "%.0f");
597 ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f,
598 "%.0f");
599 ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f,
600 2.0f, "%.0f");
601
602 ImGui::SeparatorText("Rounding");
603 ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f,
604 "%.0f");
605 ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f,
606 "%.0f");
607 ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
608 "%.0f");
609 ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f,
610 "%.0f");
611 ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f,
612 12.0f, "%.0f");
613 ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f,
614 "%.0f");
615 ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f,
616 "%.0f");
617
618 ImGui::SeparatorText("Tables");
619 ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f,
620 20.0f, "%.0f");
621 ImGui::SliderAngle("TableAngledHeadersAngle",
622 &style.TableAngledHeadersAngle, -50.0f, +50.0f);
623
624 ImGui::SeparatorText("Widgets");
625 ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign,
626 0.0f, 1.0f, "%.2f");
627 ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition,
628 "Left\0Right\0");
629 ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign,
630 0.0f, 1.0f, "%.2f");
631 ImGui::SameLine();
632
633 ImGui::SliderFloat2("SelectableTextAlign",
634 (float*)&style.SelectableTextAlign, 0.0f, 1.0f,
635 "%.2f");
636 ImGui::SameLine();
637
638 ImGui::SliderFloat("SeparatorTextBorderSize",
639 &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
640 ImGui::SliderFloat2("SeparatorTextAlign",
641 (float*)&style.SeparatorTextAlign, 0.0f, 1.0f,
642 "%.2f");
643 ImGui::SliderFloat2("SeparatorTextPadding",
644 (float*)&style.SeparatorTextPadding, 0.0f, 40.0f,
645 "%.0f");
646 ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f,
647 12.0f, "%.0f");
648
649 ImGui::SeparatorText("Tooltips");
650 for (int n = 0; n < 2; n++)
651 if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse"
652 : "HoverFlagsForTooltipNav")) {
653 ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse
654 : &style.HoverFlagsForTooltipNav;
655 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p,
656 ImGuiHoveredFlags_DelayNone);
657 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p,
658 ImGuiHoveredFlags_DelayShort);
659 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p,
660 ImGuiHoveredFlags_DelayNormal);
661 ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p,
662 ImGuiHoveredFlags_Stationary);
663 ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p,
664 ImGuiHoveredFlags_NoSharedDelay);
665 ImGui::TreePop();
666 }
667
668 ImGui::SeparatorText("Misc");
669 ImGui::SliderFloat2("DisplaySafeAreaPadding",
670 (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f,
671 "%.0f");
672 ImGui::SameLine();
673
674 ImGui::EndTabItem();
675 }
676
677 if (ImGui::BeginTabItem("Colors")) {
678 static int output_dest = 0;
679 static bool output_only_modified = true;
680 if (ImGui::Button("Export")) {
681 if (output_dest == 0)
682 ImGui::LogToClipboard();
683 else
684 ImGui::LogToTTY();
685 ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
686 for (int i = 0; i < ImGuiCol_COUNT; i++) {
687 const ImVec4& col = style.Colors[i];
688 const char* name = ImGui::GetStyleColorName(i);
689 if (!output_only_modified ||
690 memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
691 ImGui::LogText(
692 "colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, "
693 "%.2ff);" IM_NEWLINE,
694 name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
695 }
696 ImGui::LogFinish();
697 }
698 ImGui::SameLine();
699 ImGui::SetNextItemWidth(120);
700 ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
701 ImGui::SameLine();
702 ImGui::Checkbox("Only Modified Colors", &output_only_modified);
703
704 static ImGuiTextFilter filter;
705 filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
706
707 static ImGuiColorEditFlags alpha_flags = 0;
708 if (ImGui::RadioButton("Opaque",
709 alpha_flags == ImGuiColorEditFlags_None)) {
710 alpha_flags = ImGuiColorEditFlags_None;
711 }
712 ImGui::SameLine();
713 if (ImGui::RadioButton("Alpha",
714 alpha_flags == ImGuiColorEditFlags_AlphaPreview)) {
715 alpha_flags = ImGuiColorEditFlags_AlphaPreview;
716 }
717 ImGui::SameLine();
718 if (ImGui::RadioButton(
719 "Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) {
720 alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
721 }
722 ImGui::SameLine();
723
724 ImGui::SetNextWindowSizeConstraints(
725 ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10),
726 ImVec2(FLT_MAX, FLT_MAX));
727 ImGui::BeginChild("##colors", ImVec2(0, 0),
728 ImGuiChildFlags_Borders | ImGuiChildFlags_NavFlattened,
729 ImGuiWindowFlags_AlwaysVerticalScrollbar |
730 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
731 ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
732 for (int i = 0; i < ImGuiCol_COUNT; i++) {
733 const char* name = ImGui::GetStyleColorName(i);
734 if (!filter.PassFilter(name))
735 continue;
736 ImGui::PushID(i);
737 ImGui::ColorEdit4("##color", (float*)&style.Colors[i],
738 ImGuiColorEditFlags_AlphaBar | alpha_flags);
739 if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
740 // Tips: in a real user application, you may want to merge and use
741 // an icon font into the main font, so instead of "Save"/"Revert"
742 // you'd use icons! Read the FAQ and docs/FONTS.md about using icon
743 // fonts. It's really easy and super convenient!
744 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
745 if (ImGui::Button("Save")) {
746 ref->Colors[i] = style.Colors[i];
747 }
748 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
749 if (ImGui::Button("Revert")) {
750 style.Colors[i] = ref->Colors[i];
751 }
752 }
753 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
754 ImGui::TextUnformatted(name);
755 ImGui::PopID();
756 }
757 ImGui::PopItemWidth();
758 ImGui::EndChild();
759
760 ImGui::EndTabItem();
761 }
762
763 if (ImGui::BeginTabItem("Fonts")) {
764 ImGuiIO& io = ImGui::GetIO();
765 ImFontAtlas* atlas = io.Fonts;
766 ImGui::ShowFontAtlas(atlas);
767
768 // Post-baking font scaling. Note that this is NOT the nice way of
769 // scaling fonts, read below. (we enforce hard clamping manually as by
770 // default DragFloat/SliderFloat allows CTRL+Click text to get out of
771 // bounds).
772 const float MIN_SCALE = 0.3f;
773 const float MAX_SCALE = 2.0f;
774
775 static float window_scale = 1.0f;
776 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
777 if (ImGui::DragFloat(
778 "window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE,
779 "%.2f",
780 ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
781 ImGui::SetWindowFontScale(window_scale);
782 // Global scale is handled by the caller (PopupManager or
783 // SettingsPanel) to enable persistence via UserSettings.
784 ImGui::PopItemWidth();
785
786 ImGui::EndTabItem();
787 }
788
789 if (ImGui::BeginTabItem("Rendering")) {
790 ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
791 ImGui::SameLine();
792
793 ImGui::Checkbox("Anti-aliased lines use texture",
794 &style.AntiAliasedLinesUseTex);
795 ImGui::SameLine();
796
797 ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
798 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
799 ImGui::DragFloat("Curve Tessellation Tolerance",
800 &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f,
801 "%.2f");
802 if (style.CurveTessellationTol < 0.10f)
803 style.CurveTessellationTol = 0.10f;
804
805 // When editing the "Circle Segment Max Error" value, draw a preview of
806 // its effect on auto-tessellated circles.
807 ImGui::DragFloat("Circle Tessellation Max Error",
808 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
809 "%.2f", ImGuiSliderFlags_AlwaysClamp);
810 const bool show_samples = ImGui::IsItemActive();
811 if (show_samples)
812 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
813 if (show_samples && ImGui::BeginTooltip()) {
814 ImGui::TextUnformatted("(R = radius, N = number of segments)");
815 ImGui::Spacing();
816 ImDrawList* draw_list = ImGui::GetWindowDrawList();
817 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
818 for (int n = 0; n < 8; n++) {
819 const float RAD_MIN = 5.0f;
820 const float RAD_MAX = 70.0f;
821 const float rad =
822 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
823
824 ImGui::BeginGroup();
825
826 ImGui::Text("R: %.f\nN: %d", rad,
827 draw_list->_CalcCircleAutoSegmentCount(rad));
828
829 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
830 const float offset_x = floorf(canvas_width * 0.5f);
831 const float offset_y = floorf(RAD_MAX);
832
833 const ImVec2 p1 = ImGui::GetCursorScreenPos();
834 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
835 ImGui::GetColorU32(ImGuiCol_Text));
836 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
837
838 /*
839 const ImVec2 p2 = ImGui::GetCursorScreenPos();
840 draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y),
841 rad, ImGui::GetColorU32(ImGuiCol_Text));
842 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
843 */
844
845 ImGui::EndGroup();
846 ImGui::SameLine();
847 }
848 ImGui::EndTooltip();
849 }
850 ImGui::SameLine();
851
852 ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f,
853 "%.2f"); // Not exposing zero here so user doesn't
854 // "lose" the UI (zero alpha clips all
855 // widgets). But application code could have a
856 // toggle to switch between zero and non-zero.
857 ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f,
858 1.0f, "%.2f");
859 ImGui::SameLine();
860
861 ImGui::PopItemWidth();
862
863 ImGui::EndTabItem();
864 }
865
866 ImGui::EndTabBar();
867 }
868
869 ImGui::PopItemWidth();
870}
871
872void DrawDisplaySettingsForPopup(ImGuiStyle* ref) {
873 // Popup-safe version of DrawDisplaySettings without problematic tables
874 ImGuiStyle& style = ImGui::GetStyle();
875 static ImGuiStyle ref_saved_style;
876
877 // Default to using internal storage as reference
878 static bool init = true;
879 if (init && ref == NULL)
880 ref_saved_style = style;
881 init = false;
882 if (ref == NULL)
883 ref = &ref_saved_style;
884
885 ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
886
887 // Enhanced theme management section (simplified for popup)
888 if (ImGui::CollapsingHeader("Theme Management",
889 ImGuiTreeNodeFlags_DefaultOpen)) {
890 auto& theme_manager = ThemeManager::Get();
891
892 ImGui::Text("%s Current Theme:", ICON_MD_PALETTE);
893 ImGui::SameLine();
894
895 std::string current_theme_name = theme_manager.GetCurrentThemeName();
896 bool is_classic_active = (current_theme_name == "Classic YAZE");
897
898 // Current theme display with color preview
899 if (is_classic_active) {
900 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
901 current_theme_name.c_str());
902 } else {
903 ImGui::Text("%s", current_theme_name.c_str());
904 }
905
906 // Theme color preview
907 auto current_theme = theme_manager.GetCurrentTheme();
908 ImGui::SameLine();
909 ImGui::ColorButton("##primary_preview",
910 gui::ConvertColorToImVec4(current_theme.primary),
911 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
912 ImGui::SameLine();
913 ImGui::ColorButton("##secondary_preview",
914 gui::ConvertColorToImVec4(current_theme.secondary),
915 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
916 ImGui::SameLine();
917 ImGui::ColorButton("##accent_preview",
918 gui::ConvertColorToImVec4(current_theme.accent),
919 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
920
921 ImGui::Spacing();
922
923 // Simplified theme selection (no table to avoid popup conflicts)
924 if (is_classic_active) {
925 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f));
926 }
927
928 if (ImGui::Button("Classic YAZE")) {
929 theme_manager.ApplyClassicYazeTheme();
930 ref_saved_style = style;
931 }
932
933 if (is_classic_active) {
934 ImGui::PopStyleColor();
935 }
936
937 ImGui::SameLine();
938 if (ImGui::Button("Reset ColorsYaze")) {
940 ref_saved_style = style;
941 }
942
943 // File themes dropdown
944 auto available_themes = theme_manager.GetAvailableThemes();
945 const char* current_file_theme = "";
946
947 // Find current file theme for display
948 for (const auto& theme_name : available_themes) {
949 if (theme_name == current_theme_name) {
950 current_file_theme = theme_name.c_str();
951 break;
952 }
953 }
954
955 ImGui::Text("File Themes:");
956 ImGui::SetNextItemWidth(-1);
957 if (ImGui::BeginCombo("##FileThemes", current_file_theme)) {
958 for (const auto& theme_name : available_themes) {
959 bool is_selected = (theme_name == current_theme_name);
960 if (ImGui::Selectable(theme_name.c_str(), is_selected)) {
961 theme_manager.LoadTheme(theme_name);
962 ref_saved_style = style;
963 }
964 }
965 ImGui::EndCombo();
966 }
967
968 if (ImGui::Button("Refresh Themes")) {
969 theme_manager.RefreshAvailableThemes();
970 }
971 ImGui::SameLine();
972 if (ImGui::Button("Open Theme Editor")) {
973 static bool show_theme_editor = true;
974 theme_manager.ShowSimpleThemeEditor(&show_theme_editor);
975 }
976 }
977
978 ImGui::Separator();
979
980 // Background effects settings
981 auto& bg_renderer = gui::BackgroundRenderer::Get();
982 bg_renderer.DrawSettingsUI();
983
984 ImGui::Separator();
985
986 if (ImGui::ShowStyleSelector("Colors##Selector"))
987 ref_saved_style = style;
988 ImGui::ShowFontSelector("Fonts##Selector");
989
990 // Quick style controls before the tabbed section
991 if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
992 "%.0f"))
993 style.GrabRounding = style.FrameRounding;
994
995 // Border checkboxes (simplified layout)
996 bool window_border = (style.WindowBorderSize > 0.0f);
997 if (ImGui::Checkbox("WindowBorder", &window_border)) {
998 style.WindowBorderSize = window_border ? 1.0f : 0.0f;
999 }
1000 ImGui::SameLine();
1001
1002 bool frame_border = (style.FrameBorderSize > 0.0f);
1003 if (ImGui::Checkbox("FrameBorder", &frame_border)) {
1004 style.FrameBorderSize = frame_border ? 1.0f : 0.0f;
1005 }
1006 ImGui::SameLine();
1007
1008 bool popup_border = (style.PopupBorderSize > 0.0f);
1009 if (ImGui::Checkbox("PopupBorder", &popup_border)) {
1010 style.PopupBorderSize = popup_border ? 1.0f : 0.0f;
1011 }
1012
1013 // Save/Revert buttons
1014 if (ImGui::Button("Save Ref"))
1015 *ref = ref_saved_style = style;
1016 ImGui::SameLine();
1017 if (ImGui::Button("Revert Ref"))
1018 style = *ref;
1019
1020 ImGui::Separator();
1021
1022 // Add the comprehensive tabbed settings from the original DrawDisplaySettings
1023 if (ImGui::BeginTabBar("DisplaySettingsTabs", ImGuiTabBarFlags_None)) {
1024 if (ImGui::BeginTabItem("Sizes")) {
1025 ImGui::SeparatorText("Main");
1026 ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f,
1027 20.0f, "%.0f");
1028 ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f,
1029 20.0f, "%.0f");
1030 ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f,
1031 20.0f, "%.0f");
1032 ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing,
1033 0.0f, 20.0f, "%.0f");
1034 ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding,
1035 0.0f, 10.0f, "%.0f");
1036 ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f,
1037 "%.0f");
1038 ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f,
1039 "%.0f");
1040 ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f,
1041 "%.0f");
1042
1043 ImGui::SeparatorText("Borders");
1044 ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f,
1045 1.0f, "%.0f");
1046 ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f,
1047 "%.0f");
1048 ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f,
1049 "%.0f");
1050 ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f,
1051 "%.0f");
1052 ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f,
1053 "%.0f");
1054 ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f,
1055 2.0f, "%.0f");
1056
1057 ImGui::SeparatorText("Rounding");
1058 ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f,
1059 "%.0f");
1060 ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f,
1061 "%.0f");
1062 ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
1063 "%.0f");
1064 ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f,
1065 "%.0f");
1066 ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f,
1067 12.0f, "%.0f");
1068 ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f,
1069 "%.0f");
1070 ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f,
1071 "%.0f");
1072
1073 ImGui::SeparatorText("Tables");
1074 ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f,
1075 20.0f, "%.0f");
1076 ImGui::SliderAngle("TableAngledHeadersAngle",
1077 &style.TableAngledHeadersAngle, -50.0f, +50.0f);
1078
1079 ImGui::SeparatorText("Widgets");
1080 ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign,
1081 0.0f, 1.0f, "%.2f");
1082 ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition,
1083 "Left\0Right\0");
1084 ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign,
1085 0.0f, 1.0f, "%.2f");
1086 ImGui::SameLine();
1087
1088 ImGui::SliderFloat2("SelectableTextAlign",
1089 (float*)&style.SelectableTextAlign, 0.0f, 1.0f,
1090 "%.2f");
1091 ImGui::SameLine();
1092
1093 ImGui::SliderFloat("SeparatorTextBorderSize",
1094 &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
1095 ImGui::SliderFloat2("SeparatorTextAlign",
1096 (float*)&style.SeparatorTextAlign, 0.0f, 1.0f,
1097 "%.2f");
1098 ImGui::SliderFloat2("SeparatorTextPadding",
1099 (float*)&style.SeparatorTextPadding, 0.0f, 40.0f,
1100 "%.0f");
1101 ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f,
1102 12.0f, "%.0f");
1103
1104 ImGui::SeparatorText("Tooltips");
1105 for (int n = 0; n < 2; n++)
1106 if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse"
1107 : "HoverFlagsForTooltipNav")) {
1108 ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse
1109 : &style.HoverFlagsForTooltipNav;
1110 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p,
1111 ImGuiHoveredFlags_DelayNone);
1112 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p,
1113 ImGuiHoveredFlags_DelayShort);
1114 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p,
1115 ImGuiHoveredFlags_DelayNormal);
1116 ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p,
1117 ImGuiHoveredFlags_Stationary);
1118 ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p,
1119 ImGuiHoveredFlags_NoSharedDelay);
1120 ImGui::TreePop();
1121 }
1122
1123 ImGui::SeparatorText("Misc");
1124 ImGui::SliderFloat2("DisplaySafeAreaPadding",
1125 (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f,
1126 "%.0f");
1127 ImGui::SameLine();
1128
1129 ImGui::EndTabItem();
1130 }
1131
1132 if (ImGui::BeginTabItem("Colors")) {
1133 static int output_dest = 0;
1134 static bool output_only_modified = true;
1135 if (ImGui::Button("Export")) {
1136 if (output_dest == 0)
1137 ImGui::LogToClipboard();
1138 else
1139 ImGui::LogToTTY();
1140 ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
1141 for (int i = 0; i < ImGuiCol_COUNT; i++) {
1142 const ImVec4& col = style.Colors[i];
1143 const char* name = ImGui::GetStyleColorName(i);
1144 if (!output_only_modified ||
1145 memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
1146 ImGui::LogText(
1147 "colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, "
1148 "%.2ff);" IM_NEWLINE,
1149 name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
1150 }
1151 ImGui::LogFinish();
1152 }
1153 ImGui::SameLine();
1154 ImGui::SetNextItemWidth(120);
1155 ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
1156 ImGui::SameLine();
1157 ImGui::Checkbox("Only Modified Colors", &output_only_modified);
1158
1159 static ImGuiTextFilter filter;
1160 filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
1161
1162 static ImGuiColorEditFlags alpha_flags = 0;
1163 if (ImGui::RadioButton("Opaque",
1164 alpha_flags == ImGuiColorEditFlags_None)) {
1165 alpha_flags = ImGuiColorEditFlags_None;
1166 }
1167 ImGui::SameLine();
1168 if (ImGui::RadioButton("Alpha",
1169 alpha_flags == ImGuiColorEditFlags_AlphaPreview)) {
1170 alpha_flags = ImGuiColorEditFlags_AlphaPreview;
1171 }
1172 ImGui::SameLine();
1173 if (ImGui::RadioButton(
1174 "Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) {
1175 alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
1176 }
1177 ImGui::SameLine();
1178
1179 ImGui::SetNextWindowSizeConstraints(
1180 ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10),
1181 ImVec2(FLT_MAX, FLT_MAX));
1182 ImGui::BeginChild("##colors", ImVec2(0, 0),
1183 ImGuiChildFlags_Borders | ImGuiChildFlags_NavFlattened,
1184 ImGuiWindowFlags_AlwaysVerticalScrollbar |
1185 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
1186 ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
1187 for (int i = 0; i < ImGuiCol_COUNT; i++) {
1188 const char* name = ImGui::GetStyleColorName(i);
1189 if (!filter.PassFilter(name))
1190 continue;
1191 ImGui::PushID(i);
1192 ImGui::ColorEdit4("##color", (float*)&style.Colors[i],
1193 ImGuiColorEditFlags_AlphaBar | alpha_flags);
1194 if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
1195 // Tips: in a real user application, you may want to merge and use
1196 // an icon font into the main font, so instead of "Save"/"Revert"
1197 // you'd use icons! Read the FAQ and docs/FONTS.md about using icon
1198 // fonts. It's really easy and super convenient!
1199 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1200 if (ImGui::Button("Save")) {
1201 ref->Colors[i] = style.Colors[i];
1202 }
1203 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1204 if (ImGui::Button("Revert")) {
1205 style.Colors[i] = ref->Colors[i];
1206 }
1207 }
1208 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1209 ImGui::TextUnformatted(name);
1210 ImGui::PopID();
1211 }
1212 ImGui::PopItemWidth();
1213 ImGui::EndChild();
1214
1215 ImGui::EndTabItem();
1216 }
1217
1218 if (ImGui::BeginTabItem("Fonts")) {
1219 ImGuiIO& io = ImGui::GetIO();
1220 ImFontAtlas* atlas = io.Fonts;
1221 ImGui::ShowFontAtlas(atlas);
1222
1223 // Post-baking font scaling. Note that this is NOT the nice way of
1224 // scaling fonts, read below. (we enforce hard clamping manually as by
1225 // default DragFloat/SliderFloat allows CTRL+Click text to get out of
1226 // bounds).
1227 const float MIN_SCALE = 0.3f;
1228 const float MAX_SCALE = 2.0f;
1229
1230 static float window_scale = 1.0f;
1231 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
1232 if (ImGui::DragFloat(
1233 "window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE,
1234 "%.2f",
1235 ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
1236 ImGui::SetWindowFontScale(window_scale);
1237 // Global scale is handled by the caller (PopupManager or
1238 // SettingsPanel) to enable persistence via UserSettings.
1239 ImGui::PopItemWidth();
1240
1241 ImGui::EndTabItem();
1242 }
1243
1244 if (ImGui::BeginTabItem("Rendering")) {
1245 ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
1246 ImGui::SameLine();
1247
1248 ImGui::Checkbox("Anti-aliased lines use texture",
1249 &style.AntiAliasedLinesUseTex);
1250 ImGui::SameLine();
1251
1252 ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
1253 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
1254 ImGui::DragFloat("Curve Tessellation Tolerance",
1255 &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f,
1256 "%.2f");
1257 if (style.CurveTessellationTol < 0.10f)
1258 style.CurveTessellationTol = 0.10f;
1259
1260 // When editing the "Circle Segment Max Error" value, draw a preview of
1261 // its effect on auto-tessellated circles.
1262 ImGui::DragFloat("Circle Tessellation Max Error",
1263 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
1264 "%.2f", ImGuiSliderFlags_AlwaysClamp);
1265 const bool show_samples = ImGui::IsItemActive();
1266 if (show_samples)
1267 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
1268 if (show_samples && ImGui::BeginTooltip()) {
1269 ImGui::TextUnformatted("(R = radius, N = number of segments)");
1270 ImGui::Spacing();
1271 ImDrawList* draw_list = ImGui::GetWindowDrawList();
1272 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
1273 for (int n = 0; n < 8; n++) {
1274 const float RAD_MIN = 5.0f;
1275 const float RAD_MAX = 70.0f;
1276 const float rad =
1277 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
1278
1279 ImGui::BeginGroup();
1280
1281 ImGui::Text("R: %.f\nN: %d", rad,
1282 draw_list->_CalcCircleAutoSegmentCount(rad));
1283
1284 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
1285 const float offset_x = floorf(canvas_width * 0.5f);
1286 const float offset_y = floorf(RAD_MAX);
1287
1288 const ImVec2 p1 = ImGui::GetCursorScreenPos();
1289 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
1290 ImGui::GetColorU32(ImGuiCol_Text));
1291 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
1292
1293 ImGui::EndGroup();
1294 ImGui::SameLine();
1295 }
1296 ImGui::EndTooltip();
1297 }
1298 ImGui::SameLine();
1299
1300 ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f,
1301 "%.2f"); // Not exposing zero here so user doesn't
1302 // "lose" the UI (zero alpha clips all
1303 // widgets). But application code could have a
1304 // toggle to switch between zero and non-zero.
1305 ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f,
1306 1.0f, "%.2f");
1307 ImGui::SameLine();
1308
1309 ImGui::PopItemWidth();
1310
1311 ImGui::EndTabItem();
1312 }
1313
1314 ImGui::EndTabBar();
1315 }
1316
1317 ImGui::PopItemWidth();
1318}
1319
1320void TextWithSeparators(const absl::string_view& text) {
1321 ImGui::Separator();
1322 ImGui::Text("%s", text.data());
1323 ImGui::Separator();
1324}
1325
1327 ImGuiIO& io = ImGui::GetIO();
1328 ImFontAtlas* atlas = io.Fonts;
1329
1330 static ImFont* current_font = atlas->Fonts[0];
1331 static int current_font_index = 0;
1332 static int font_size = 16;
1333 static bool font_selected = false;
1334
1335 ImGui::Text("Loaded fonts");
1336 for (const auto& loaded_font : font_registry.fonts) {
1337 ImGui::Text("%s", loaded_font.font_path);
1338 }
1339 ImGui::Separator();
1340
1341 ImGui::Text("Current Font: %s", current_font->GetDebugName());
1342 ImGui::Text("Font Size: %d", font_size);
1343
1344 if (ImGui::BeginCombo("Fonts", current_font->GetDebugName())) {
1345 for (int i = 0; i < atlas->Fonts.Size; i++) {
1346 bool is_selected = (current_font == atlas->Fonts[i]);
1347 if (ImGui::Selectable(atlas->Fonts[i]->GetDebugName(), is_selected)) {
1348 current_font = atlas->Fonts[i];
1349 current_font_index = i;
1350 font_selected = true;
1351 }
1352 if (is_selected) {
1353 ImGui::SetItemDefaultFocus();
1354 }
1355 }
1356 ImGui::EndCombo();
1357 }
1358
1359 ImGui::Separator();
1360 if (ImGui::SliderInt("Font Size", &font_size, 8, 32)) {
1361 current_font->Scale = font_size / 16.0f;
1362 }
1363}
1364
1365} // namespace gui
1366} // 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:361
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:134
void BeginTableCanvas(const char *table_id, int columns, ImVec2 canvas_size)
Definition style.cc:332
void DrawFontManager()
Definition style.cc:1326
void BeginPadding(int i)
Definition style.cc:274
void BeginChildBothScrollbars(int id)
Definition style.cc:324
void EndNoPadding()
Definition style.cc:286
TextEditor::LanguageDefinition GetAssemblyLanguageDef()
Definition style.cc:193
void DrawDisplaySettings(ImGuiStyle *ref)
Definition style.cc:377
void EndPadding()
Definition style.cc:278
void BeginNoPadding()
Definition style.cc:282
void SetupCanvasTableColumn(const char *label, float width_ratio)
Definition style.cc:352
void EndWindowWithDisplaySettings()
Definition style.cc:269
void DrawDisplaySettingsForPopup(ImGuiStyle *ref)
Definition style.cc:872
void EndTableCanvas()
Definition style.cc:348
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:1320
void BeginChildWithScrollbar(const char *str_id)
Definition style.cc:290
FontState font_registry
Definition font_loader.h:23
TokenRegexStrings mTokenRegexStrings
std::vector< FontConfig > fonts
Definition font_loader.h:20
float green
Definition color.h:18