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 // Global scale is handled by the caller (PopupManager or
778 // SettingsPanel) to enable persistence via UserSettings.
779 ImGui::PopItemWidth();
780
781 ImGui::EndTabItem();
782 }
783
784 if (ImGui::BeginTabItem("Rendering")) {
785 ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
786 ImGui::SameLine();
787
788 ImGui::Checkbox("Anti-aliased lines use texture",
789 &style.AntiAliasedLinesUseTex);
790 ImGui::SameLine();
791
792 ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
793 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
794 ImGui::DragFloat("Curve Tessellation Tolerance",
795 &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f,
796 "%.2f");
797 if (style.CurveTessellationTol < 0.10f)
798 style.CurveTessellationTol = 0.10f;
799
800 // When editing the "Circle Segment Max Error" value, draw a preview of
801 // its effect on auto-tessellated circles.
802 ImGui::DragFloat("Circle Tessellation Max Error",
803 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
804 "%.2f", ImGuiSliderFlags_AlwaysClamp);
805 const bool show_samples = ImGui::IsItemActive();
806 if (show_samples)
807 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
808 if (show_samples && ImGui::BeginTooltip()) {
809 ImGui::TextUnformatted("(R = radius, N = number of segments)");
810 ImGui::Spacing();
811 ImDrawList* draw_list = ImGui::GetWindowDrawList();
812 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
813 for (int n = 0; n < 8; n++) {
814 const float RAD_MIN = 5.0f;
815 const float RAD_MAX = 70.0f;
816 const float rad =
817 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
818
819 ImGui::BeginGroup();
820
821 ImGui::Text("R: %.f\nN: %d", rad,
822 draw_list->_CalcCircleAutoSegmentCount(rad));
823
824 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
825 const float offset_x = floorf(canvas_width * 0.5f);
826 const float offset_y = floorf(RAD_MAX);
827
828 const ImVec2 p1 = ImGui::GetCursorScreenPos();
829 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
830 ImGui::GetColorU32(ImGuiCol_Text));
831 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
832
833 /*
834 const ImVec2 p2 = ImGui::GetCursorScreenPos();
835 draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y),
836 rad, ImGui::GetColorU32(ImGuiCol_Text));
837 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
838 */
839
840 ImGui::EndGroup();
841 ImGui::SameLine();
842 }
843 ImGui::EndTooltip();
844 }
845 ImGui::SameLine();
846
847 ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f,
848 "%.2f"); // Not exposing zero here so user doesn't
849 // "lose" the UI (zero alpha clips all
850 // widgets). But application code could have a
851 // toggle to switch between zero and non-zero.
852 ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f,
853 1.0f, "%.2f");
854 ImGui::SameLine();
855
856 ImGui::PopItemWidth();
857
858 ImGui::EndTabItem();
859 }
860
861 ImGui::EndTabBar();
862 }
863
864 ImGui::PopItemWidth();
865}
866
867void DrawDisplaySettingsForPopup(ImGuiStyle* ref) {
868 // Popup-safe version of DrawDisplaySettings without problematic tables
869 ImGuiStyle& style = ImGui::GetStyle();
870 static ImGuiStyle ref_saved_style;
871
872 // Default to using internal storage as reference
873 static bool init = true;
874 if (init && ref == NULL)
875 ref_saved_style = style;
876 init = false;
877 if (ref == NULL)
878 ref = &ref_saved_style;
879
880 ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
881
882 // Enhanced theme management section (simplified for popup)
883 if (ImGui::CollapsingHeader("Theme Management",
884 ImGuiTreeNodeFlags_DefaultOpen)) {
885 auto& theme_manager = ThemeManager::Get();
886
887 ImGui::Text("%s Current Theme:", ICON_MD_PALETTE);
888 ImGui::SameLine();
889
890 std::string current_theme_name = theme_manager.GetCurrentThemeName();
891 bool is_classic_active = (current_theme_name == "Classic YAZE");
892
893 // Current theme display with color preview
894 if (is_classic_active) {
895 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
896 current_theme_name.c_str());
897 } else {
898 ImGui::Text("%s", current_theme_name.c_str());
899 }
900
901 // Theme color preview
902 auto current_theme = theme_manager.GetCurrentTheme();
903 ImGui::SameLine();
904 ImGui::ColorButton("##primary_preview",
905 gui::ConvertColorToImVec4(current_theme.primary),
906 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
907 ImGui::SameLine();
908 ImGui::ColorButton("##secondary_preview",
909 gui::ConvertColorToImVec4(current_theme.secondary),
910 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
911 ImGui::SameLine();
912 ImGui::ColorButton("##accent_preview",
913 gui::ConvertColorToImVec4(current_theme.accent),
914 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
915
916 ImGui::Spacing();
917
918 // Simplified theme selection (no table to avoid popup conflicts)
919 if (is_classic_active) {
920 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f));
921 }
922
923 if (ImGui::Button("Classic YAZE")) {
924 theme_manager.ApplyClassicYazeTheme();
925 ref_saved_style = style;
926 }
927
928 if (is_classic_active) {
929 ImGui::PopStyleColor();
930 }
931
932 ImGui::SameLine();
933 if (ImGui::Button("Reset ColorsYaze")) {
935 ref_saved_style = style;
936 }
937
938 // File themes dropdown
939 auto available_themes = theme_manager.GetAvailableThemes();
940 const char* current_file_theme = "";
941
942 // Find current file theme for display
943 for (const auto& theme_name : available_themes) {
944 if (theme_name == current_theme_name) {
945 current_file_theme = theme_name.c_str();
946 break;
947 }
948 }
949
950 ImGui::Text("File Themes:");
951 ImGui::SetNextItemWidth(-1);
952 if (ImGui::BeginCombo("##FileThemes", current_file_theme)) {
953 for (const auto& theme_name : available_themes) {
954 bool is_selected = (theme_name == current_theme_name);
955 if (ImGui::Selectable(theme_name.c_str(), is_selected)) {
956 theme_manager.LoadTheme(theme_name);
957 ref_saved_style = style;
958 }
959 }
960 ImGui::EndCombo();
961 }
962
963 if (ImGui::Button("Refresh Themes")) {
964 theme_manager.RefreshAvailableThemes();
965 }
966 ImGui::SameLine();
967 if (ImGui::Button("Open Theme Editor")) {
968 static bool show_theme_editor = true;
969 theme_manager.ShowSimpleThemeEditor(&show_theme_editor);
970 }
971 }
972
973 ImGui::Separator();
974
975 // Background effects settings
976 auto& bg_renderer = gui::BackgroundRenderer::Get();
977 bg_renderer.DrawSettingsUI();
978
979 ImGui::Separator();
980
981 if (ImGui::ShowStyleSelector("Colors##Selector"))
982 ref_saved_style = style;
983 ImGui::ShowFontSelector("Fonts##Selector");
984
985 // Quick style controls before the tabbed section
986 if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
987 "%.0f"))
988 style.GrabRounding = style.FrameRounding;
989
990 // Border checkboxes (simplified layout)
991 bool window_border = (style.WindowBorderSize > 0.0f);
992 if (ImGui::Checkbox("WindowBorder", &window_border)) {
993 style.WindowBorderSize = window_border ? 1.0f : 0.0f;
994 }
995 ImGui::SameLine();
996
997 bool frame_border = (style.FrameBorderSize > 0.0f);
998 if (ImGui::Checkbox("FrameBorder", &frame_border)) {
999 style.FrameBorderSize = frame_border ? 1.0f : 0.0f;
1000 }
1001 ImGui::SameLine();
1002
1003 bool popup_border = (style.PopupBorderSize > 0.0f);
1004 if (ImGui::Checkbox("PopupBorder", &popup_border)) {
1005 style.PopupBorderSize = popup_border ? 1.0f : 0.0f;
1006 }
1007
1008 // Save/Revert buttons
1009 if (ImGui::Button("Save Ref"))
1010 *ref = ref_saved_style = style;
1011 ImGui::SameLine();
1012 if (ImGui::Button("Revert Ref"))
1013 style = *ref;
1014
1015 ImGui::Separator();
1016
1017 // Add the comprehensive tabbed settings from the original DrawDisplaySettings
1018 if (ImGui::BeginTabBar("DisplaySettingsTabs", ImGuiTabBarFlags_None)) {
1019 if (ImGui::BeginTabItem("Sizes")) {
1020 ImGui::SeparatorText("Main");
1021 ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f,
1022 20.0f, "%.0f");
1023 ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f,
1024 20.0f, "%.0f");
1025 ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f,
1026 20.0f, "%.0f");
1027 ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing,
1028 0.0f, 20.0f, "%.0f");
1029 ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding,
1030 0.0f, 10.0f, "%.0f");
1031 ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f,
1032 "%.0f");
1033 ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f,
1034 "%.0f");
1035 ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f,
1036 "%.0f");
1037
1038 ImGui::SeparatorText("Borders");
1039 ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f,
1040 1.0f, "%.0f");
1041 ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f,
1042 "%.0f");
1043 ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f,
1044 "%.0f");
1045 ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f,
1046 "%.0f");
1047 ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f,
1048 "%.0f");
1049 ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f,
1050 2.0f, "%.0f");
1051
1052 ImGui::SeparatorText("Rounding");
1053 ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f,
1054 "%.0f");
1055 ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f,
1056 "%.0f");
1057 ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f,
1058 "%.0f");
1059 ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f,
1060 "%.0f");
1061 ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f,
1062 12.0f, "%.0f");
1063 ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f,
1064 "%.0f");
1065 ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f,
1066 "%.0f");
1067
1068 ImGui::SeparatorText("Tables");
1069 ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f,
1070 20.0f, "%.0f");
1071 ImGui::SliderAngle("TableAngledHeadersAngle",
1072 &style.TableAngledHeadersAngle, -50.0f, +50.0f);
1073
1074 ImGui::SeparatorText("Widgets");
1075 ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign,
1076 0.0f, 1.0f, "%.2f");
1077 ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition,
1078 "Left\0Right\0");
1079 ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign,
1080 0.0f, 1.0f, "%.2f");
1081 ImGui::SameLine();
1082
1083 ImGui::SliderFloat2("SelectableTextAlign",
1084 (float*)&style.SelectableTextAlign, 0.0f, 1.0f,
1085 "%.2f");
1086 ImGui::SameLine();
1087
1088 ImGui::SliderFloat("SeparatorTextBorderSize",
1089 &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
1090 ImGui::SliderFloat2("SeparatorTextAlign",
1091 (float*)&style.SeparatorTextAlign, 0.0f, 1.0f,
1092 "%.2f");
1093 ImGui::SliderFloat2("SeparatorTextPadding",
1094 (float*)&style.SeparatorTextPadding, 0.0f, 40.0f,
1095 "%.0f");
1096 ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f,
1097 12.0f, "%.0f");
1098
1099 ImGui::SeparatorText("Tooltips");
1100 for (int n = 0; n < 2; n++)
1101 if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse"
1102 : "HoverFlagsForTooltipNav")) {
1103 ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse
1104 : &style.HoverFlagsForTooltipNav;
1105 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p,
1106 ImGuiHoveredFlags_DelayNone);
1107 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p,
1108 ImGuiHoveredFlags_DelayShort);
1109 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p,
1110 ImGuiHoveredFlags_DelayNormal);
1111 ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p,
1112 ImGuiHoveredFlags_Stationary);
1113 ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p,
1114 ImGuiHoveredFlags_NoSharedDelay);
1115 ImGui::TreePop();
1116 }
1117
1118 ImGui::SeparatorText("Misc");
1119 ImGui::SliderFloat2("DisplaySafeAreaPadding",
1120 (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f,
1121 "%.0f");
1122 ImGui::SameLine();
1123
1124 ImGui::EndTabItem();
1125 }
1126
1127 if (ImGui::BeginTabItem("Colors")) {
1128 static int output_dest = 0;
1129 static bool output_only_modified = true;
1130 if (ImGui::Button("Export")) {
1131 if (output_dest == 0)
1132 ImGui::LogToClipboard();
1133 else
1134 ImGui::LogToTTY();
1135 ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
1136 for (int i = 0; i < ImGuiCol_COUNT; i++) {
1137 const ImVec4& col = style.Colors[i];
1138 const char* name = ImGui::GetStyleColorName(i);
1139 if (!output_only_modified ||
1140 memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
1141 ImGui::LogText(
1142 "colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, "
1143 "%.2ff);" IM_NEWLINE,
1144 name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
1145 }
1146 ImGui::LogFinish();
1147 }
1148 ImGui::SameLine();
1149 ImGui::SetNextItemWidth(120);
1150 ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
1151 ImGui::SameLine();
1152 ImGui::Checkbox("Only Modified Colors", &output_only_modified);
1153
1154 static ImGuiTextFilter filter;
1155 filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
1156
1157 static ImGuiColorEditFlags alpha_flags = 0;
1158 if (ImGui::RadioButton("Opaque",
1159 alpha_flags == ImGuiColorEditFlags_None)) {
1160 alpha_flags = ImGuiColorEditFlags_None;
1161 }
1162 ImGui::SameLine();
1163 if (ImGui::RadioButton("Alpha",
1164 alpha_flags == ImGuiColorEditFlags_AlphaPreview)) {
1165 alpha_flags = ImGuiColorEditFlags_AlphaPreview;
1166 }
1167 ImGui::SameLine();
1168 if (ImGui::RadioButton(
1169 "Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) {
1170 alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
1171 }
1172 ImGui::SameLine();
1173
1174 ImGui::SetNextWindowSizeConstraints(
1175 ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10),
1176 ImVec2(FLT_MAX, FLT_MAX));
1177 ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border,
1178 ImGuiWindowFlags_AlwaysVerticalScrollbar |
1179 ImGuiWindowFlags_AlwaysHorizontalScrollbar |
1180 ImGuiWindowFlags_NavFlattened);
1181 ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
1182 for (int i = 0; i < ImGuiCol_COUNT; i++) {
1183 const char* name = ImGui::GetStyleColorName(i);
1184 if (!filter.PassFilter(name))
1185 continue;
1186 ImGui::PushID(i);
1187 ImGui::ColorEdit4("##color", (float*)&style.Colors[i],
1188 ImGuiColorEditFlags_AlphaBar | alpha_flags);
1189 if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
1190 // Tips: in a real user application, you may want to merge and use
1191 // an icon font into the main font, so instead of "Save"/"Revert"
1192 // you'd use icons! Read the FAQ and docs/FONTS.md about using icon
1193 // fonts. It's really easy and super convenient!
1194 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1195 if (ImGui::Button("Save")) {
1196 ref->Colors[i] = style.Colors[i];
1197 }
1198 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1199 if (ImGui::Button("Revert")) {
1200 style.Colors[i] = ref->Colors[i];
1201 }
1202 }
1203 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
1204 ImGui::TextUnformatted(name);
1205 ImGui::PopID();
1206 }
1207 ImGui::PopItemWidth();
1208 ImGui::EndChild();
1209
1210 ImGui::EndTabItem();
1211 }
1212
1213 if (ImGui::BeginTabItem("Fonts")) {
1214 ImGuiIO& io = ImGui::GetIO();
1215 ImFontAtlas* atlas = io.Fonts;
1216 ImGui::ShowFontAtlas(atlas);
1217
1218 // Post-baking font scaling. Note that this is NOT the nice way of
1219 // scaling fonts, read below. (we enforce hard clamping manually as by
1220 // default DragFloat/SliderFloat allows CTRL+Click text to get out of
1221 // bounds).
1222 const float MIN_SCALE = 0.3f;
1223 const float MAX_SCALE = 2.0f;
1224
1225 static float window_scale = 1.0f;
1226 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
1227 if (ImGui::DragFloat(
1228 "window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE,
1229 "%.2f",
1230 ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
1231 ImGui::SetWindowFontScale(window_scale);
1232 // Global scale is handled by the caller (PopupManager or
1233 // SettingsPanel) to enable persistence via UserSettings.
1234 ImGui::PopItemWidth();
1235
1236 ImGui::EndTabItem();
1237 }
1238
1239 if (ImGui::BeginTabItem("Rendering")) {
1240 ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
1241 ImGui::SameLine();
1242
1243 ImGui::Checkbox("Anti-aliased lines use texture",
1244 &style.AntiAliasedLinesUseTex);
1245 ImGui::SameLine();
1246
1247 ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
1248 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
1249 ImGui::DragFloat("Curve Tessellation Tolerance",
1250 &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f,
1251 "%.2f");
1252 if (style.CurveTessellationTol < 0.10f)
1253 style.CurveTessellationTol = 0.10f;
1254
1255 // When editing the "Circle Segment Max Error" value, draw a preview of
1256 // its effect on auto-tessellated circles.
1257 ImGui::DragFloat("Circle Tessellation Max Error",
1258 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
1259 "%.2f", ImGuiSliderFlags_AlwaysClamp);
1260 const bool show_samples = ImGui::IsItemActive();
1261 if (show_samples)
1262 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
1263 if (show_samples && ImGui::BeginTooltip()) {
1264 ImGui::TextUnformatted("(R = radius, N = number of segments)");
1265 ImGui::Spacing();
1266 ImDrawList* draw_list = ImGui::GetWindowDrawList();
1267 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
1268 for (int n = 0; n < 8; n++) {
1269 const float RAD_MIN = 5.0f;
1270 const float RAD_MAX = 70.0f;
1271 const float rad =
1272 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
1273
1274 ImGui::BeginGroup();
1275
1276 ImGui::Text("R: %.f\nN: %d", rad,
1277 draw_list->_CalcCircleAutoSegmentCount(rad));
1278
1279 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
1280 const float offset_x = floorf(canvas_width * 0.5f);
1281 const float offset_y = floorf(RAD_MAX);
1282
1283 const ImVec2 p1 = ImGui::GetCursorScreenPos();
1284 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
1285 ImGui::GetColorU32(ImGuiCol_Text));
1286 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
1287
1288 ImGui::EndGroup();
1289 ImGui::SameLine();
1290 }
1291 ImGui::EndTooltip();
1292 }
1293 ImGui::SameLine();
1294
1295 ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f,
1296 "%.2f"); // Not exposing zero here so user doesn't
1297 // "lose" the UI (zero alpha clips all
1298 // widgets). But application code could have a
1299 // toggle to switch between zero and non-zero.
1300 ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f,
1301 1.0f, "%.2f");
1302 ImGui::SameLine();
1303
1304 ImGui::PopItemWidth();
1305
1306 ImGui::EndTabItem();
1307 }
1308
1309 ImGui::EndTabBar();
1310 }
1311
1312 ImGui::PopItemWidth();
1313}
1314
1315void TextWithSeparators(const absl::string_view& text) {
1316 ImGui::Separator();
1317 ImGui::Text("%s", text.data());
1318 ImGui::Separator();
1319}
1320
1322 ImGuiIO& io = ImGui::GetIO();
1323 ImFontAtlas* atlas = io.Fonts;
1324
1325 static ImFont* current_font = atlas->Fonts[0];
1326 static int current_font_index = 0;
1327 static int font_size = 16;
1328 static bool font_selected = false;
1329
1330 ImGui::Text("Loaded fonts");
1331 for (const auto& loaded_font : font_registry.fonts) {
1332 ImGui::Text("%s", loaded_font.font_path);
1333 }
1334 ImGui::Separator();
1335
1336 ImGui::Text("Current Font: %s", current_font->GetDebugName());
1337 ImGui::Text("Font Size: %d", font_size);
1338
1339 if (ImGui::BeginCombo("Fonts", current_font->GetDebugName())) {
1340 for (int i = 0; i < atlas->Fonts.Size; i++) {
1341 bool is_selected = (current_font == atlas->Fonts[i]);
1342 if (ImGui::Selectable(atlas->Fonts[i]->GetDebugName(), is_selected)) {
1343 current_font = atlas->Fonts[i];
1344 current_font_index = i;
1345 font_selected = true;
1346 }
1347 if (is_selected) {
1348 ImGui::SetItemDefaultFocus();
1349 }
1350 }
1351 ImGui::EndCombo();
1352 }
1353
1354 ImGui::Separator();
1355 if (ImGui::SliderInt("Font Size", &font_size, 8, 32)) {
1356 current_font->Scale = font_size / 16.0f;
1357 }
1358}
1359
1360} // namespace gui
1361} // 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:134
void BeginTableCanvas(const char *table_id, int columns, ImVec2 canvas_size)
Definition style.cc:327
void DrawFontManager()
Definition style.cc:1321
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:867
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:1315
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