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(8.f, 8.f);
38 style->FramePadding = ImVec2(6.f, 3.f);
39 style->CellPadding = ImVec2(6.f, 4.f);
40 style->ItemSpacing = ImVec2(6.f, 4.f);
41 style->ItemInnerSpacing = ImVec2(6.f, 4.f);
42 style->TouchExtraPadding = ImVec2(0.f, 0.f);
43 style->IndentSpacing = 20.f;
44 style->ScrollbarSize = 14.f;
45 style->GrabMinSize = 14.f;
46
47 style->WindowBorderSize = 1.f;
48 style->ChildBorderSize = 0.f;
49 style->PopupBorderSize = 1.f;
50 style->FrameBorderSize = 0.f;
51 style->TabBorderSize = 0.f;
52
53 style->WindowRounding = 2.f;
54 style->ChildRounding = 3.f;
55 style->FrameRounding = 4.f;
56 style->PopupRounding = 4.f;
57 style->ScrollbarRounding = 4.f;
58 style->TabRounding = 3.f;
59
60 auto alttpDarkGreen = ImVec4(0.18f, 0.26f, 0.18f, 1.0f);
61 auto alttpMidGreen = ImVec4(0.28f, 0.36f, 0.28f, 1.0f);
62 auto allttpLightGreen = ImVec4(0.36f, 0.45f, 0.36f, 1.0f);
63 auto allttpLightestGreen = ImVec4(0.49f, 0.57f, 0.49f, 1.0f);
64
65 colors[ImGuiCol_MenuBarBg] = alttpDarkGreen;
66 colors[ImGuiCol_TitleBg] = alttpMidGreen;
67
68 colors[ImGuiCol_Header] = alttpDarkGreen;
69 colors[ImGuiCol_HeaderHovered] = allttpLightGreen;
70 colors[ImGuiCol_HeaderActive] = alttpMidGreen;
71
72 colors[ImGuiCol_TitleBgActive] = alttpDarkGreen;
73 colors[ImGuiCol_TitleBgCollapsed] = alttpMidGreen;
74
75 colors[ImGuiCol_Tab] = alttpDarkGreen;
76 colors[ImGuiCol_TabHovered] = alttpMidGreen;
77 colors[ImGuiCol_TabSelected] = ImVec4(0.347f, 0.466f, 0.347f, 1.000f);
78
79 colors[ImGuiCol_Button] = alttpMidGreen;
80 colors[ImGuiCol_ButtonHovered] = allttpLightestGreen;
81 colors[ImGuiCol_ButtonActive] = allttpLightGreen;
82
83 colors[ImGuiCol_ScrollbarBg] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
84 colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.36f, 0.45f, 0.36f, 0.30f);
85 colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.36f, 0.45f, 0.36f, 0.40f);
86 colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
87
88 colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
89 colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
90 colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f);
91 colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
92 colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f);
93 colors[ImGuiCol_Border] = allttpLightGreen;
94 colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
95
96 colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f);
97 colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f);
98 colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f);
99
100 colors[ImGuiCol_CheckMark] =
101 ImVec4(0.26f, 0.59f, 0.98f, 1.00f); // Solid blue checkmark
102 // Checked checkboxes lean toward the hover color, as ImGui's own styles do.
103 colors[ImGuiCol_CheckboxSelectedBg] =
104 ImLerp(colors[ImGuiCol_FrameBg], colors[ImGuiCol_FrameBgHovered], 0.65f);
105 colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
106 colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
107
108 colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
109 colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
110 colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
111 colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
112 colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
113 colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
114
115 colors[ImGuiCol_TabDimmed] =
116 ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
117 colors[ImGuiCol_TabDimmedSelected] =
118 ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
119 colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
120 colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
121 colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
122 colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
123 colors[ImGuiCol_TableHeaderBg] = alttpDarkGreen;
124 colors[ImGuiCol_TableBorderStrong] = alttpMidGreen;
125 colors[ImGuiCol_TableBorderLight] =
126 ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here
127 colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
128 colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f);
129 colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
130 colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
131 colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
132 colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
133 colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
134 colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
135
136 // ImGui slots and style scalars added after this function was written. They
137 // must be set explicitly: this is the only writer for Classic YAZE, so
138 // anything left out keeps the value of whichever .theme preset was applied
139 // before, and the two greens bleed into a purple docking preview or a cyan
140 // caret. Values mirror BuildClassicYazeTheme's declarations.
141 colors[ImGuiCol_DockingPreview] = ImVec4(0.36f, 0.45f, 0.36f, 0.71f);
142 colors[ImGuiCol_DockingEmptyBg] = alttpDarkGreen;
143 colors[ImGuiCol_InputTextCursor] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
144 colors[ImGuiCol_TextLink] = allttpLightestGreen;
145 colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Separator];
146 colors[ImGuiCol_TabSelectedOverline] = allttpLightestGreen;
147 colors[ImGuiCol_TabDimmedSelectedOverline] = allttpLightestGreen;
148 // Transparent, matching every ImGui built-in style: the drop target is drawn
149 // as an outline (ImGuiCol_DragDropTarget above), not a fill.
150 colors[ImGuiCol_DragDropTargetBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
151 colors[ImGuiCol_UnsavedMarker] = colors[ImGuiCol_Text];
152 style->GrabRounding = 5.f;
153}
154
155void DrawBitmapViewer(const std::vector<gfx::Bitmap>& bitmaps, float scale,
156 int& current_bitmap_id) {
157 if (bitmaps.empty()) {
158 ImGui::Text(tr("No bitmaps available."));
159 return;
160 }
161
162 // Display the current bitmap index and total count.
163 ImGui::Text(tr("Viewing Bitmap %d / %zu"), current_bitmap_id + 1,
164 bitmaps.size());
165
166 // Buttons to navigate through bitmaps.
167 if (ImGui::Button(tr("<- Prev"))) {
168 if (current_bitmap_id > 0) {
169 --current_bitmap_id;
170 }
171 }
172 ImGui::SameLine();
173 if (ImGui::Button(tr("Next ->"))) {
174 if (current_bitmap_id < bitmaps.size() - 1) {
175 ++current_bitmap_id;
176 }
177 }
178
179 // Display the current bitmap.
180 const gfx::Bitmap& current_bitmap = bitmaps[current_bitmap_id];
181 // Assuming Bitmap has a function to get its texture ID, and width and
182 // height.
183 ImTextureID tex_id = (ImTextureID)(intptr_t)current_bitmap.texture();
184 ImVec2 size(current_bitmap.width() * scale, current_bitmap.height() * scale);
185 // ImGui::Image(tex_id, size);
186
187 // Scroll if the image is larger than the display area.
188 if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false,
189 ImGuiWindowFlags_HorizontalScrollbar)) {
190 ImGui::Image(tex_id, size);
191 ImGui::EndChild();
192 }
193}
194
195static const char* const kKeywords[] = {
196 "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL",
197 "BRA", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "CPX",
198 "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX", "INY", "JMP", "JSR",
199 "JSL", "LDA", "LDX", "LDY", "LSR", "MVN", "NOP", "ORA", "PEA", "PER",
200 "PHA", "PHB", "PHD", "PHP", "PHX", "PHY", "PLA", "PLB", "PLD", "PLP",
201 "PLX", "PLY", "REP", "ROL", "ROR", "RTI", "RTL", "RTS", "SBC", "SEC",
202 "SEI", "SEP", "STA", "STP", "STX", "STY", "STZ", "TAX", "TAY", "TCD",
203 "TCS", "TDC", "TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY", "TYA",
204 "TYX", "WAI", "WDM", "XBA", "XCE", "ORG", "LOROM", "HIROM"};
205
206static const char* const kIdentifiers[] = {
207 "abort", "abs", "acos", "asin", "atan", "atexit",
208 "atof", "atoi", "atol", "ceil", "clock", "cosh",
209 "ctime", "div", "exit", "fabs", "floor", "fmod",
210 "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph",
211 "ispunct", "isspace", "isupper", "kbhit", "log10", "log2",
212 "log", "memcmp", "modf", "pow", "putchar", "putenv",
213 "puts", "rand", "remove", "rename", "sinh", "sqrt",
214 "srand", "strcat", "strcmp", "strerror", "time", "tolower",
215 "toupper"};
216
218 TextEditor::LanguageDefinition language_65816;
219 for (auto& k : kKeywords)
220 language_65816.mKeywords.emplace(k);
221
222 for (auto& k : kIdentifiers) {
224 id.mDeclaration = "Built-in function";
225 language_65816.mIdentifiers.insert(std::make_pair(std::string(k), id));
226 }
227
228 language_65816.mTokenRegexStrings.push_back(
229 std::make_pair<std::string, TextEditor::PaletteIndex>(
230 "[ \\t]*#[ \\t]*[a-zA-Z_]+", TextEditor::PaletteIndex::Preprocessor));
231 language_65816.mTokenRegexStrings.push_back(
232 std::make_pair<std::string, TextEditor::PaletteIndex>(
233 "L?\\\"(\\\\.|[^\\\"])*\\\"", TextEditor::PaletteIndex::String));
234 language_65816.mTokenRegexStrings.push_back(
235 std::make_pair<std::string, TextEditor::PaletteIndex>(
236 "\\'\\\\?[^\\']\\'", TextEditor::PaletteIndex::CharLiteral));
237 language_65816.mTokenRegexStrings.push_back(
238 std::make_pair<std::string, TextEditor::PaletteIndex>(
239 "[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?",
241 language_65816.mTokenRegexStrings.push_back(
242 std::make_pair<std::string, TextEditor::PaletteIndex>(
243 "[+-]?[0-9]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number));
244 language_65816.mTokenRegexStrings.push_back(
245 std::make_pair<std::string, TextEditor::PaletteIndex>(
246 "0[0-7]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number));
247 language_65816.mTokenRegexStrings.push_back(
248 std::make_pair<std::string, TextEditor::PaletteIndex>(
249 "0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?",
251 language_65816.mTokenRegexStrings.push_back(
252 std::make_pair<std::string, TextEditor::PaletteIndex>(
253 "[a-zA-Z_][a-zA-Z0-9_]*", TextEditor::PaletteIndex::Identifier));
254 language_65816.mTokenRegexStrings.push_back(
255 std::make_pair<std::string, TextEditor::PaletteIndex>(
256 "[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/"
257 "\\;\\,\\.]",
259
260 language_65816.mCommentStart = "/*";
261 language_65816.mCommentEnd = "*/";
262 language_65816.mSingleLineComment = ";";
263
264 language_65816.mCaseSensitive = false;
265 language_65816.mAutoIndentation = true;
266
267 language_65816.mName = "65816";
268
269 return language_65816;
270}
271
272// TODO: Add more display settings to popup windows.
273void BeginWindowWithDisplaySettings(const char* id, bool* active,
274 const ImVec2& size,
275 ImGuiWindowFlags flags) {
276 ImGuiStyle* ref = &ImGui::GetStyle();
277 static float childBgOpacity = 0.75f;
278 auto color = ref->Colors[ImGuiCol_WindowBg];
279
280 ImGui::PushStyleColor(ImGuiCol_WindowBg, color);
281 ImGui::PushStyleColor(ImGuiCol_ChildBg, color);
282 ImGui::PushStyleColor(ImGuiCol_Border, color);
283
284 ImGui::Begin(id, active, flags | ImGuiWindowFlags_MenuBar);
285 ImGui::BeginMenuBar();
286 if (ImGui::BeginMenu(tr("Display Settings"))) {
287 ImGui::SliderFloat(tr("Child Background Opacity"), &childBgOpacity, 0.0f,
288 1.0f);
289 ImGui::EndMenu();
290 }
291 ImGui::EndMenuBar();
292}
293
295 ImGui::End();
296 ImGui::PopStyleColor(3);
297}
298
299void BeginPadding(int i) {
300 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(i, i));
301 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(i, i));
302}
304 EndNoPadding();
305}
306
308 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
309 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
310}
312 ImGui::PopStyleVar(2);
313}
314
315void BeginChildWithScrollbar(const char* str_id) {
316 // Get available region but ensure minimum size for proper scrolling
317 ImVec2 available = ImGui::GetContentRegionAvail();
318 if (available.x < 64.0f)
319 available.x = 64.0f;
320 if (available.y < 64.0f)
321 available.y = 64.0f;
322
323 ImGui::BeginChild(str_id, available, true,
324 ImGuiWindowFlags_AlwaysVerticalScrollbar);
325}
326
327void BeginChildWithScrollbar(const char* str_id, ImVec2 content_size,
328 bool horizontal_scroll) {
329 // Set content size before beginning child to enable proper scrolling.
330 // Allow callers to communicate only one axis when the other should remain
331 // auto-sized by ImGui.
332 if (content_size.x > 0.0f || content_size.y > 0.0f) {
333 ImGui::SetNextWindowContentSize(content_size);
334 }
335
336 // Get available region but ensure minimum size for proper scrolling
337 ImVec2 available = ImGui::GetContentRegionAvail();
338 if (available.x < 64.0f)
339 available.x = 64.0f;
340 if (available.y < 64.0f)
341 available.y = 64.0f;
342
343 ImGui::BeginChild(
344 str_id, available, true,
345 ImGuiWindowFlags_AlwaysVerticalScrollbar |
346 (horizontal_scroll ? ImGuiWindowFlags_AlwaysHorizontalScrollbar : 0));
347}
348
350 ImGuiID child_id = ImGui::GetID((void*)(intptr_t)id);
351 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
352 ImGuiWindowFlags_AlwaysVerticalScrollbar |
353 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
354}
355
356void DrawDisplaySettingsForPopup(ImGuiStyle* ref) {
357 // Style editor for the Display Settings popup. The theme section uses plain
358 // rows instead of a table so it lays out correctly inside the popup.
359 ImGuiStyle& style = ImGui::GetStyle();
360 static ImGuiStyle ref_saved_style;
361
362 // Default to using internal storage as reference
363 static bool init = true;
364 if (init && ref == NULL)
365 ref_saved_style = style;
366 init = false;
367 if (ref == NULL)
368 ref = &ref_saved_style;
369
370 ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
371
372 // Enhanced theme management section (simplified for popup)
373 if (ImGui::CollapsingHeader(tr("Theme Management"),
374 ImGuiTreeNodeFlags_DefaultOpen)) {
375 auto& theme_manager = ThemeManager::Get();
376
377 ImGui::Text(tr("%s Current Theme:"), ICON_MD_PALETTE);
378 ImGui::SameLine();
379
380 std::string current_theme_name = theme_manager.GetCurrentThemeName();
381 bool is_classic_active = (current_theme_name == "Classic YAZE");
382
383 // Current theme display with color preview
384 if (is_classic_active) {
385 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
386 current_theme_name.c_str());
387 } else {
388 ImGui::Text("%s", current_theme_name.c_str());
389 }
390
391 // Theme color preview
392 auto current_theme = theme_manager.GetCurrentTheme();
393 ImGui::SameLine();
394 ImGui::ColorButton("##primary_preview",
395 gui::ConvertColorToImVec4(current_theme.primary),
396 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
397 ImGui::SameLine();
398 ImGui::ColorButton("##secondary_preview",
399 gui::ConvertColorToImVec4(current_theme.secondary),
400 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
401 ImGui::SameLine();
402 ImGui::ColorButton("##accent_preview",
403 gui::ConvertColorToImVec4(current_theme.accent),
404 ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20));
405
406 ImGui::Spacing();
407
408 // Simplified theme selection (no table to avoid popup conflicts)
409 if (is_classic_active) {
410 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f));
411 }
412
413 if (ImGui::Button(tr("Classic YAZE"))) {
414 theme_manager.ApplyClassicYazeTheme();
415 ref_saved_style = style;
416 }
417
418 if (is_classic_active) {
419 ImGui::PopStyleColor();
420 }
421
422 ImGui::SameLine();
423 if (ImGui::Button(tr("Reset ColorsYaze"))) {
425 ref_saved_style = style;
426 }
427
428 // File themes dropdown
429 auto available_themes = theme_manager.GetAvailableThemes();
430 const char* current_file_theme = "";
431
432 // Find current file theme for display
433 for (const auto& theme_name : available_themes) {
434 if (theme_name == current_theme_name) {
435 current_file_theme = theme_name.c_str();
436 break;
437 }
438 }
439
440 ImGui::Text(tr("File Themes:"));
441 ImGui::SetNextItemWidth(-1);
442 if (ImGui::BeginCombo("##FileThemes", current_file_theme)) {
443 for (const auto& theme_name : available_themes) {
444 bool is_selected = (theme_name == current_theme_name);
445 if (ImGui::Selectable(theme_name.c_str(), is_selected)) {
446 theme_manager.LoadTheme(theme_name);
447 ref_saved_style = style;
448 }
449 }
450 ImGui::EndCombo();
451 }
452
453 if (ImGui::Button(tr("Refresh Themes"))) {
454 theme_manager.RefreshAvailableThemes();
455 }
456 ImGui::SameLine();
457 if (ImGui::Button(tr("Open Theme Editor"))) {
458 static bool show_theme_editor = true;
459 theme_manager.ShowSimpleThemeEditor(&show_theme_editor);
460 }
461 }
462
463 ImGui::Separator();
464
465 // Background effects settings
466 auto& bg_renderer = gui::BackgroundRenderer::Get();
467 bg_renderer.DrawSettingsUI();
468
469 ImGui::Separator();
470
471 if (ImGui::ShowStyleSelector("Colors##Selector"))
472 ref_saved_style = style;
473 ImGui::ShowFontSelector("Fonts##Selector");
474
475 // Quick style controls before the tabbed section
476 if (ImGui::SliderFloat(tr("FrameRounding"), &style.FrameRounding, 0.0f, 12.0f,
477 "%.0f"))
478 style.GrabRounding = style.FrameRounding;
479
480 // Border checkboxes (simplified layout)
481 bool window_border = (style.WindowBorderSize > 0.0f);
482 if (ImGui::Checkbox(tr("WindowBorder"), &window_border)) {
483 style.WindowBorderSize = window_border ? 1.0f : 0.0f;
484 }
485 ImGui::SameLine();
486
487 bool frame_border = (style.FrameBorderSize > 0.0f);
488 if (ImGui::Checkbox(tr("FrameBorder"), &frame_border)) {
489 style.FrameBorderSize = frame_border ? 1.0f : 0.0f;
490 }
491 ImGui::SameLine();
492
493 bool popup_border = (style.PopupBorderSize > 0.0f);
494 if (ImGui::Checkbox(tr("PopupBorder"), &popup_border)) {
495 style.PopupBorderSize = popup_border ? 1.0f : 0.0f;
496 }
497
498 // Save/Revert buttons
499 if (ImGui::Button(tr("Save Ref")))
500 *ref = ref_saved_style = style;
501 ImGui::SameLine();
502 if (ImGui::Button(tr("Revert Ref")))
503 style = *ref;
504
505 ImGui::Separator();
506
507 // Tabbed style controls, based on ImGui::ShowStyleEditor() in imgui_demo.cpp.
508 if (ImGui::BeginTabBar("DisplaySettingsTabs", ImGuiTabBarFlags_None)) {
509 if (ImGui::BeginTabItem(tr("Sizes"))) {
510 ImGui::SeparatorText(tr("Main"));
511 ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f,
512 20.0f, "%.0f");
513 ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f,
514 20.0f, "%.0f");
515 ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f,
516 20.0f, "%.0f");
517 ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing,
518 0.0f, 20.0f, "%.0f");
519 ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding,
520 0.0f, 10.0f, "%.0f");
521 ImGui::SliderFloat(tr("IndentSpacing"), &style.IndentSpacing, 0.0f, 30.0f,
522 "%.0f");
523 ImGui::SliderFloat(tr("ScrollbarSize"), &style.ScrollbarSize, 1.0f, 20.0f,
524 "%.0f");
525 ImGui::SliderFloat(tr("GrabMinSize"), &style.GrabMinSize, 1.0f, 20.0f,
526 "%.0f");
527
528 ImGui::SeparatorText(tr("Borders"));
529 ImGui::SliderFloat(tr("WindowBorderSize"), &style.WindowBorderSize, 0.0f,
530 1.0f, "%.0f");
531 ImGui::SliderFloat(tr("ChildBorderSize"), &style.ChildBorderSize, 0.0f,
532 1.0f, "%.0f");
533 ImGui::SliderFloat(tr("PopupBorderSize"), &style.PopupBorderSize, 0.0f,
534 1.0f, "%.0f");
535 ImGui::SliderFloat(tr("FrameBorderSize"), &style.FrameBorderSize, 0.0f,
536 1.0f, "%.0f");
537 ImGui::SliderFloat(tr("TabBorderSize"), &style.TabBorderSize, 0.0f, 1.0f,
538 "%.0f");
539 ImGui::SliderFloat(tr("TabBarBorderSize"), &style.TabBarBorderSize, 0.0f,
540 2.0f, "%.0f");
541
542 ImGui::SeparatorText(tr("Rounding"));
543 ImGui::SliderFloat(tr("WindowRounding"), &style.WindowRounding, 0.0f,
544 12.0f, "%.0f");
545 ImGui::SliderFloat(tr("ChildRounding"), &style.ChildRounding, 0.0f, 12.0f,
546 "%.0f");
547 ImGui::SliderFloat(tr("FrameRounding"), &style.FrameRounding, 0.0f, 12.0f,
548 "%.0f");
549 ImGui::SliderFloat(tr("PopupRounding"), &style.PopupRounding, 0.0f, 12.0f,
550 "%.0f");
551 ImGui::SliderFloat(tr("ScrollbarRounding"), &style.ScrollbarRounding,
552 0.0f, 12.0f, "%.0f");
553 ImGui::SliderFloat(tr("GrabRounding"), &style.GrabRounding, 0.0f, 12.0f,
554 "%.0f");
555 ImGui::SliderFloat(tr("TabRounding"), &style.TabRounding, 0.0f, 12.0f,
556 "%.0f");
557
558 ImGui::SeparatorText(tr("Tables"));
559 ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f,
560 20.0f, "%.0f");
561 ImGui::SliderAngle("TableAngledHeadersAngle",
562 &style.TableAngledHeadersAngle, -50.0f, +50.0f);
563
564 ImGui::SeparatorText(tr("Widgets"));
565 ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign,
566 0.0f, 1.0f, "%.2f");
567 ImGui::Combo(tr("ColorButtonPosition"), (int*)&style.ColorButtonPosition,
568 "Left\0Right\0");
569 ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign,
570 0.0f, 1.0f, "%.2f");
571 ImGui::SameLine();
572
573 ImGui::SliderFloat2("SelectableTextAlign",
574 (float*)&style.SelectableTextAlign, 0.0f, 1.0f,
575 "%.2f");
576 ImGui::SameLine();
577
578 ImGui::SliderFloat(tr("SeparatorTextBorderSize"),
579 &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
580 ImGui::SliderFloat2("SeparatorTextAlign",
581 (float*)&style.SeparatorTextAlign, 0.0f, 1.0f,
582 "%.2f");
583 ImGui::SliderFloat2("SeparatorTextPadding",
584 (float*)&style.SeparatorTextPadding, 0.0f, 40.0f,
585 "%.0f");
586 ImGui::SliderFloat(tr("LogSliderDeadzone"), &style.LogSliderDeadzone,
587 0.0f, 12.0f, "%.0f");
588
589 ImGui::SeparatorText(tr("Tooltips"));
590 for (int n = 0; n < 2; n++)
591 if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse"
592 : "HoverFlagsForTooltipNav")) {
593 ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse
594 : &style.HoverFlagsForTooltipNav;
595 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p,
596 ImGuiHoveredFlags_DelayNone);
597 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p,
598 ImGuiHoveredFlags_DelayShort);
599 ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p,
600 ImGuiHoveredFlags_DelayNormal);
601 ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p,
602 ImGuiHoveredFlags_Stationary);
603 ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p,
604 ImGuiHoveredFlags_NoSharedDelay);
605 ImGui::TreePop();
606 }
607
608 ImGui::SeparatorText(tr("Misc"));
609 ImGui::SliderFloat2("DisplaySafeAreaPadding",
610 (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f,
611 "%.0f");
612 ImGui::SameLine();
613
614 ImGui::EndTabItem();
615 }
616
617 if (ImGui::BeginTabItem(tr("Colors"))) {
618 static int output_dest = 0;
619 static bool output_only_modified = true;
620 if (ImGui::Button(tr("Export"))) {
621 if (output_dest == 0)
622 ImGui::LogToClipboard();
623 else
624 ImGui::LogToTTY();
625 ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
626 for (int i = 0; i < ImGuiCol_COUNT; i++) {
627 const ImVec4& col = style.Colors[i];
628 const char* name = ImGui::GetStyleColorName(i);
629 if (!output_only_modified ||
630 memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
631 ImGui::LogText(
632 "colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, "
633 "%.2ff);" IM_NEWLINE,
634 name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
635 }
636 ImGui::LogFinish();
637 }
638 ImGui::SameLine();
639 ImGui::SetNextItemWidth(120);
640 ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
641 ImGui::SameLine();
642 ImGui::Checkbox(tr("Only Modified Colors"), &output_only_modified);
643
644 static ImGuiTextFilter filter;
645 ImGui::SetNextItemWidth(ImGui::GetFontSize() * 16);
646 filter.DrawWithHint("Filter colors");
647
648 static ImGuiColorEditFlags alpha_flags = 0;
649 // ImGui 1.91.8 made the transparent preview the default and reduced
650 // ImGuiColorEditFlags_AlphaPreview to 0; opaque now needs AlphaOpaque.
651 if (ImGui::RadioButton(tr("Opaque"),
652 alpha_flags == ImGuiColorEditFlags_AlphaOpaque)) {
653 alpha_flags = ImGuiColorEditFlags_AlphaOpaque;
654 }
655 ImGui::SameLine();
656 if (ImGui::RadioButton(tr("Alpha"),
657 alpha_flags == ImGuiColorEditFlags_None)) {
658 alpha_flags = ImGuiColorEditFlags_None;
659 }
660 ImGui::SameLine();
661 if (ImGui::RadioButton(
662 tr("Both"),
663 alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) {
664 alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
665 }
666 ImGui::SameLine();
667
668 ImGui::SetNextWindowSizeConstraints(
669 ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10),
670 ImVec2(FLT_MAX, FLT_MAX));
671 ImGui::BeginChild("##colors", ImVec2(0, 0),
672 ImGuiChildFlags_Borders | ImGuiChildFlags_NavFlattened,
673 ImGuiWindowFlags_AlwaysVerticalScrollbar |
674 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
675 ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
676 for (int i = 0; i < ImGuiCol_COUNT; i++) {
677 const char* name = ImGui::GetStyleColorName(i);
678 if (!filter.PassFilter(name))
679 continue;
680 ImGui::PushID(i);
681 ImGui::ColorEdit4("##color", (float*)&style.Colors[i],
682 ImGuiColorEditFlags_AlphaBar | alpha_flags);
683 if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) {
684 // Tips: in a real user application, you may want to merge and use
685 // an icon font into the main font, so instead of "Save"/"Revert"
686 // you'd use icons! Read the FAQ and docs/FONTS.md about using icon
687 // fonts. It's really easy and super convenient!
688 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
689 if (ImGui::Button(tr("Save"))) {
690 ref->Colors[i] = style.Colors[i];
691 }
692 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
693 if (ImGui::Button(tr("Revert"))) {
694 style.Colors[i] = ref->Colors[i];
695 }
696 }
697 ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
698 ImGui::TextUnformatted(name);
699 ImGui::PopID();
700 }
701 ImGui::PopItemWidth();
702 ImGui::EndChild();
703
704 ImGui::EndTabItem();
705 }
706
707 if (ImGui::BeginTabItem(tr("Fonts"))) {
708 ImGuiIO& io = ImGui::GetIO();
709 ImFontAtlas* atlas = io.Fonts;
710 ImGui::ShowFontAtlas(atlas);
711
712 // Post-baking font scaling. Note that this is NOT the nice way of
713 // scaling fonts, read below. (we enforce hard clamping manually as by
714 // default DragFloat/SliderFloat allows CTRL+Click text to get out of
715 // bounds).
716 const float MIN_SCALE = 0.3f;
717 const float MAX_SCALE = 2.0f;
718
719 static float window_scale = 1.0f;
720 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
721 if (ImGui::DragFloat(
722 tr("window scale"), &window_scale, 0.005f, MIN_SCALE, MAX_SCALE,
723 "%.2f",
724 ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
725 ImGui::SetWindowFontScale(window_scale);
726 // Global scale is handled by the caller (PopupManager or
727 // SettingsPanel) to enable persistence via UserSettings.
728 ImGui::PopItemWidth();
729
730 ImGui::EndTabItem();
731 }
732
733 if (ImGui::BeginTabItem(tr("Rendering"))) {
734 ImGui::Checkbox(tr("Anti-aliased lines"), &style.AntiAliasedLines);
735 ImGui::SameLine();
736
737 // ImGui 1.93 draws anti-aliased line ends only when anti-aliased lines
738 // are also on, so the box does nothing while that one is off.
739 ImGui::BeginDisabled(!style.AntiAliasedLines);
740 ImGui::Checkbox(tr("Anti-aliased line ends"), &style.AntiAliasedLineEnds);
741 ImGui::EndDisabled();
742 ImGui::SameLine();
743
744 ImGui::Checkbox(tr("Anti-aliased fill"), &style.AntiAliasedFill);
745 ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
746 ImGui::DragFloat(tr("Curve Tessellation Max Error"),
747 &style.CurveTessellationMaxError, 0.02f, 0.10f, 10.0f,
748 "%.2f");
749 if (style.CurveTessellationMaxError < 0.10f)
750 style.CurveTessellationMaxError = 0.10f;
751
752 // When editing the "Circle Segment Max Error" value, draw a preview of
753 // its effect on auto-tessellated circles.
754 ImGui::DragFloat(tr("Circle Tessellation Max Error"),
755 &style.CircleTessellationMaxError, 0.005f, 0.10f, 5.0f,
756 "%.2f", ImGuiSliderFlags_AlwaysClamp);
757 const bool show_samples = ImGui::IsItemActive();
758 if (show_samples)
759 ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
760 if (show_samples && ImGui::BeginTooltip()) {
761 ImGui::TextUnformatted(tr("(R = radius, N = number of segments)"));
762 ImGui::Spacing();
763 ImDrawList* draw_list = ImGui::GetWindowDrawList();
764 const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x;
765 for (int n = 0; n < 8; n++) {
766 const float RAD_MIN = 5.0f;
767 const float RAD_MAX = 70.0f;
768 const float rad =
769 RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f);
770
771 ImGui::BeginGroup();
772
773 ImGui::Text(tr("R: %.f\nN: %d"), rad,
774 draw_list->_CalcCircleAutoSegmentCount(rad));
775
776 const float canvas_width = std::max(min_widget_width, rad * 2.0f);
777 const float offset_x = floorf(canvas_width * 0.5f);
778 const float offset_y = floorf(RAD_MAX);
779
780 const ImVec2 p1 = ImGui::GetCursorScreenPos();
781 draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad,
782 ImGui::GetColorU32(ImGuiCol_Text));
783 ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2));
784
785 ImGui::EndGroup();
786 ImGui::SameLine();
787 }
788 ImGui::EndTooltip();
789 }
790 ImGui::SameLine();
791
792 ImGui::DragFloat(tr("Global Alpha"), &style.Alpha, 0.005f, 0.20f, 1.0f,
793 "%.2f"); // Not exposing zero here so user doesn't
794 // "lose" the UI (zero alpha clips all
795 // widgets). But application code could have a
796 // toggle to switch between zero and non-zero.
797 ImGui::DragFloat(tr("Disabled Alpha"), &style.DisabledAlpha, 0.005f, 0.0f,
798 1.0f, "%.2f");
799
800 ImGui::PopItemWidth();
801
802 // These two write ImGuiIO, not ImGuiStyle: Save Ref and Revert Ref do
803 // not touch them and this panel does not save them. They let a
804 // developer compare 1.93 rendering and ID checks in the running app.
805 ImGui::SeparatorText(tr("Debug comparisons"));
806 ImGuiIO& io = ImGui::GetIO();
807 ImGui::Checkbox(tr("Debug: pre-1.93 strokes"),
808 &io.ConfigDebugDrawListDefaultsToStrokeLegacy);
809 ImGui::SetItemTooltip(
810 "%s", tr("Draw every ImDrawList the way ImGui 1.92 did (legacy "
811 "stroke positions, miter joins, no anti-aliased line "
812 "ends) to compare against 1.93 output."));
813 ImGui::Checkbox(tr("Debug: highlight ID conflicts"),
814 &io.ConfigDebugHighlightIdConflicts);
815 ImGui::SetItemTooltip(
816 "%s", tr("Highlight items whose ID is used by another item in the "
817 "same frame and show ImGui's error popup for them."));
818
819 ImGui::EndTabItem();
820 }
821
822 ImGui::EndTabBar();
823 }
824
825 ImGui::PopItemWidth();
826}
827
828void TextWithSeparators(const absl::string_view& text) {
829 ImGui::Separator();
830 ImGui::Text("%s", text.data());
831 ImGui::Separator();
832}
833
835 ImGuiIO& io = ImGui::GetIO();
836 ImFontAtlas* atlas = io.Fonts;
837
838 static ImFont* current_font = atlas->Fonts[0];
839 static int current_font_index = 0;
840 static int font_size = 16;
841 static bool font_selected = false;
842
843 ImGui::Text(tr("Loaded fonts"));
844 for (const auto& loaded_font : font_registry.fonts) {
845 ImGui::Text("%s", loaded_font.font_path);
846 }
847 ImGui::Separator();
848
849 ImGui::Text(tr("Current Font: %s"), current_font->GetDebugName());
850 ImGui::Text(tr("Font Size: %d"), font_size);
851
852 if (ImGui::BeginCombo(tr("Fonts"), current_font->GetDebugName())) {
853 for (int i = 0; i < atlas->Fonts.Size; i++) {
854 bool is_selected = (current_font == atlas->Fonts[i]);
855 if (ImGui::Selectable(atlas->Fonts[i]->GetDebugName(), is_selected)) {
856 current_font = atlas->Fonts[i];
857 current_font_index = i;
858 font_selected = true;
859 }
860 if (is_selected) {
861 ImGui::SetItemDefaultFocus();
862 }
863 }
864 ImGui::EndCombo();
865 }
866
867 ImGui::Separator();
868 if (ImGui::SliderInt(tr("Font Size"), &font_size, 8, 32)) {
869 current_font->Scale = font_size / 16.0f;
870 }
871}
872
873} // namespace gui
874} // namespace yaze
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
TextureHandle texture() const
Definition bitmap.h:410
int height() const
Definition bitmap.h:399
int width() const
Definition bitmap.h:398
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:155
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:140
void DrawFontManager()
Definition style.cc:834
void BeginPadding(int i)
Definition style.cc:299
void BeginChildBothScrollbars(int id)
Definition style.cc:349
void EndNoPadding()
Definition style.cc:311
TextEditor::LanguageDefinition GetAssemblyLanguageDef()
Definition style.cc:217
void EndPadding()
Definition style.cc:303
void BeginNoPadding()
Definition style.cc:307
void EndWindowWithDisplaySettings()
Definition style.cc:294
void DrawDisplaySettingsForPopup(ImGuiStyle *ref)
Definition style.cc:356
void ColorsYaze()
Definition style.cc:33
void BeginWindowWithDisplaySettings(const char *id, bool *active, const ImVec2 &size, ImGuiWindowFlags flags)
Definition style.cc:273
void TextWithSeparators(const absl::string_view &text)
Definition style.cc:828
void BeginChildWithScrollbar(const char *str_id)
Definition style.cc:315
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