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