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