yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
editor_selection_dialog.cc
Go to the documentation of this file.
2#include "util/i18n/tr.h"
3
4#include <algorithm>
5#include <cfloat>
6#include <fstream>
7#include <sstream>
8
9#include "absl/strings/str_cat.h"
10#include "absl/strings/str_format.h"
11#include "app/gui/core/color.h"
12#include "app/gui/core/icons.h"
14#include "app/gui/core/style.h"
17#include "imgui/imgui.h"
18#include "util/file_util.h"
19
20namespace yaze {
21namespace editor {
22
23namespace {
24
25constexpr float kEditorSelectBaseFontSize = 16.0f;
26constexpr float kEditorSelectCardBaseWidth = 180.0f;
27constexpr float kEditorSelectCardBaseHeight = 120.0f;
28constexpr float kEditorSelectCardWidthMaxFactor = 1.35f;
29constexpr float kEditorSelectCardHeightMaxFactor = 1.35f;
30constexpr float kEditorSelectRecentBaseWidth = 150.0f;
31constexpr float kEditorSelectRecentBaseHeight = 35.0f;
32constexpr float kEditorSelectRecentWidthMaxFactor = 1.3f;
33
34struct GridLayout {
35 int columns = 1;
36 float item_width = 0.0f;
37 float item_height = 0.0f;
38 float spacing = 0.0f;
39 float row_start_x = 0.0f;
40};
41
43 const float font_size = ImGui::GetFontSize();
44 if (font_size <= 0.0f) {
45 return 1.0f;
46 }
47 return font_size / kEditorSelectBaseFontSize;
48}
49
50GridLayout ComputeGridLayout(float avail_width, float min_width,
51 float max_width, float min_height,
52 float max_height, float preferred_width,
53 float aspect_ratio, float spacing) {
54 GridLayout layout;
55 layout.spacing = spacing;
56 const auto width_for_columns = [avail_width, spacing](int columns) {
57 return (avail_width - spacing * static_cast<float>(columns - 1)) /
58 static_cast<float>(columns);
59 };
60
61 layout.columns = std::max(1, static_cast<int>((avail_width + spacing) /
62 (preferred_width + spacing)));
63
64 layout.item_width = width_for_columns(layout.columns);
65 while (layout.columns > 1 && layout.item_width < min_width) {
66 layout.columns -= 1;
67 layout.item_width = width_for_columns(layout.columns);
68 }
69
70 layout.item_width = std::min(layout.item_width, max_width);
71 layout.item_width = std::min(layout.item_width, avail_width);
72 layout.item_height =
73 std::clamp(layout.item_width * aspect_ratio, min_height, max_height);
74
75 const float row_width =
76 layout.item_width * static_cast<float>(layout.columns) +
77 spacing * static_cast<float>(layout.columns - 1);
78 layout.row_start_x = ImGui::GetCursorPosX();
79 if (row_width < avail_width) {
80 layout.row_start_x += (avail_width - row_width) * 0.5f;
81 }
82
83 return layout;
84}
85
86ImVec4 ScaleColor(const ImVec4& color, float scale, float alpha) {
87 return ImVec4(color.x * scale, color.y * scale, color.z * scale, alpha);
88}
89
90ImVec4 ScaleColor(const ImVec4& color, float scale) {
91 return ScaleColor(color, scale, color.w);
92}
93
94ImVec4 WithAlpha(ImVec4 color, float alpha) {
95 color.w = alpha;
96 return color;
97}
98
99ImVec4 GetEditorAccentColor(EditorType type, const gui::Theme& theme) {
100 switch (type) {
108 return gui::ConvertColorToImVec4(theme.info);
112 return gui::ConvertColorToImVec4(theme.accent);
114 return gui::ConvertColorToImVec4(theme.error);
116 return gui::ConvertColorToImVec4(theme.info);
119 case EditorType::kHex:
122 return gui::ConvertColorToImVec4(theme.info);
124 return gui::ConvertColorToImVec4(theme.accent);
129 default:
131 }
132}
133
134} // namespace
135
137 // Use platform-aware shortcut strings (Cmd on macOS, Ctrl elsewhere)
138 const char* ctrl = gui::GetCtrlDisplayName();
139 editors_ = {
140 {EditorType::kOverworld, "Overworld", ICON_MD_MAP,
141 "Edit overworld maps, entrances, and properties",
142 absl::StrFormat("%s+1", ctrl), false, true},
143
145 "Design dungeon rooms, layouts, and mechanics",
146 absl::StrFormat("%s+2", ctrl), false, true},
147
149 "Modify tiles, palettes, and graphics sets",
150 absl::StrFormat("%s+3", ctrl), false, true},
151
153 "Edit sprite graphics and properties", absl::StrFormat("%s+4", ctrl),
154 false, true},
155
157 "Edit dialogue, signs, and text", absl::StrFormat("%s+5", ctrl), false,
158 true},
159
161 "Configure music and sound effects", absl::StrFormat("%s+6", ctrl),
162 false, true},
163
165 "Edit color palettes and animations", absl::StrFormat("%s+7", ctrl),
166 false, true},
167
168 {EditorType::kScreen, "Screens", ICON_MD_TV,
169 "Edit title screen and ending screens", absl::StrFormat("%s+8", ctrl),
170 false, true},
171
173 "Write and edit assembly code", absl::StrFormat("%s+9", ctrl), false,
174 false},
175
176 {EditorType::kHex, "Hex Editor", ICON_MD_DATA_ARRAY,
177 "Direct ROM memory editing and comparison",
178 absl::StrFormat("%s+0", ctrl), false, true},
179
181 "Test and debug your ROM in real-time with live debugging",
182 absl::StrFormat("%s+Shift+E", ctrl), false, true},
183
185 "Configure AI agent, collaboration, and automation",
186 absl::StrFormat("%s+Shift+A", ctrl), false, false},
187
189 "Plan goals, milestones, the play route and open decisions", "", false,
190 false},
191 };
192
194}
195
196bool EditorSelectionDialog::Show(bool* p_open) {
197 // Sync internal state with external flag
198 if (p_open && *p_open && !is_open_) {
199 is_open_ = true;
200 }
201
202 if (!is_open_) {
203 if (p_open)
204 *p_open = false;
205 return false;
206 }
207
208 bool editor_selected = false;
209 bool* window_open = p_open ? p_open : &is_open_;
210
211 // Set window properties immediately before Begin to prevent them from
212 // affecting tooltips
213 ImGuiViewport* viewport = ImGui::GetMainViewport();
214 ImVec2 center = viewport->GetCenter();
215 ImVec2 view_size = viewport->WorkSize;
216 float target_width = std::clamp(view_size.x * 0.9f, 520.0f, 980.0f);
217 float target_height = std::clamp(view_size.y * 0.88f, 420.0f, 760.0f);
218 ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
219 ImGui::SetNextWindowSize(ImVec2(target_width, target_height),
220 ImGuiCond_Appearing);
221 ImGui::SetNextWindowSizeConstraints(
222 ImVec2(420.0f, 360.0f), ImVec2(view_size.x * 0.98f, view_size.y * 0.95f));
223
224 if (ImGui::Begin("Editor Selection", window_open,
225 ImGuiWindowFlags_NoCollapse)) {
227
228 ImGui::Separator();
229 ImGui::Spacing();
230
231 // Quick access buttons for recently used
232 if (!recent_editors_.empty()) {
234 ImGui::Separator();
235 ImGui::Spacing();
236 }
237
238 // Main editor grid
239 ImGui::Text(ICON_MD_APPS " All Editors");
240 ImGui::Spacing();
241
242 const float scale = GetEditorSelectScale();
243 const float compact_scale =
244 ImGui::GetContentRegionAvail().x < 620.0f ? 0.85f : 1.0f;
245 const float min_width = kEditorSelectCardBaseWidth * scale * compact_scale;
246 const float max_width = kEditorSelectCardBaseWidth *
247 kEditorSelectCardWidthMaxFactor * scale *
248 compact_scale;
249 const float min_height =
250 kEditorSelectCardBaseHeight * scale * compact_scale;
251 const float max_height = kEditorSelectCardBaseHeight *
252 kEditorSelectCardHeightMaxFactor * scale *
253 compact_scale;
254 const float spacing = ImGui::GetStyle().ItemSpacing.x;
255 const float aspect_ratio = min_height / std::max(min_width, 1.0f);
256 GridLayout layout = ComputeGridLayout(
257 ImGui::GetContentRegionAvail().x, min_width, max_width, min_height,
258 max_height, min_width, aspect_ratio, spacing);
259
260 int column = 0;
261 for (size_t i = 0; i < editors_.size(); ++i) {
262 if (column == 0) {
263 ImGui::SetCursorPosX(layout.row_start_x);
264 }
265
266 EditorType prev_selection = selected_editor_;
267 DrawEditorPanel(editors_[i], static_cast<int>(i),
268 ImVec2(layout.item_width, layout.item_height));
269
270 // Check if an editor was just selected
271 if (selected_editor_ != prev_selection) {
272 editor_selected = true;
276 }
277 // Auto-dismiss after selection
278 is_open_ = false;
279 if (p_open) {
280 *p_open = false;
281 }
282 }
283
284 column += 1;
285 if (column < layout.columns) {
286 ImGui::SameLine(0.0f, layout.spacing);
287 } else {
288 column = 0;
289 ImGui::Spacing();
290 }
291 }
292
293 if (column != 0) {
294 ImGui::NewLine();
295 }
296 }
297 ImGui::End();
298
299 // Sync state back
300 if (p_open && !(*p_open)) {
301 is_open_ = false;
302 }
303
304 // DO NOT auto-dismiss here. Let the callback/EditorManager handle it.
305 // This allows the dialog to be used as a persistent switcher if desired.
306
307 return editor_selected;
308}
309
311 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
312 const ImVec4 accent = gui::ConvertColorToImVec4(theme.accent);
313 const ImVec4 text_secondary = gui::ConvertColorToImVec4(theme.text_secondary);
314
315 ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[2]); // Large font
316
317 ImGui::TextColored(accent, ICON_MD_EDIT " Select an Editor");
318
319 ImGui::PopFont();
320
321 ImGui::TextColored(text_secondary,
322 tr("Choose an editor to begin working on your ROM. "
323 "You can open multiple editors simultaneously."));
324}
325
327 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
328 const ImVec4 accent = gui::ConvertColorToImVec4(theme.accent);
329 ImGui::TextColored(accent, ICON_MD_HISTORY " Recently Used");
330 ImGui::Spacing();
331
332 const float scale = GetEditorSelectScale();
333 const float min_width = kEditorSelectRecentBaseWidth * scale;
334 const float max_width =
335 kEditorSelectRecentBaseWidth * kEditorSelectRecentWidthMaxFactor * scale;
336 const float height = kEditorSelectRecentBaseHeight * scale;
337 const float spacing = ImGui::GetStyle().ItemSpacing.x;
338 const float avail_width = ImGui::GetContentRegionAvail().x;
339 const bool stack_items = avail_width < min_width * 1.6f;
340 GridLayout layout{};
341 if (stack_items) {
342 layout.columns = 1;
343 layout.item_width = avail_width;
344 layout.item_height = height;
345 layout.spacing = spacing;
346 } else {
347 layout = ComputeGridLayout(avail_width, min_width, max_width, height,
348 height, min_width,
349 height / std::max(min_width, 1.0f), spacing);
350 }
351
352 int column = 0;
353 for (EditorType type : recent_editors_) {
354 // Find editor info
355 auto it = std::find_if(
356 editors_.begin(), editors_.end(),
357 [type](const EditorInfo& info) { return info.type == type; });
358
359 if (it != editors_.end()) {
360 if (column == 0) {
361 ImGui::SetCursorPosX(layout.row_start_x);
362 }
363
364 const ImVec4 base_color = GetEditorAccentColor(it->type, theme);
365 gui::StyleColorGuard btn_guard(
366 {{ImGuiCol_Button, ScaleColor(base_color, 0.5f, 0.7f)},
367 {ImGuiCol_ButtonHovered, ScaleColor(base_color, 0.7f, 0.9f)},
368 {ImGuiCol_ButtonActive, WithAlpha(base_color, 1.0f)}});
369
370 if (ImGui::Button(absl::StrCat(it->icon, " ", it->name).c_str(),
371 ImVec2(layout.item_width, layout.item_height))) {
372 selected_editor_ = type;
373 }
374
375 if (ImGui::IsItemHovered()) {
376 ImGui::SetTooltip("%s", it->description);
377 }
378
379 column += 1;
380 if (column < layout.columns) {
381 ImGui::SameLine(0.0f, layout.spacing);
382 } else {
383 column = 0;
384 ImGui::Spacing();
385 }
386 }
387 }
388
389 if (column != 0) {
390 ImGui::NewLine();
391 }
392}
393
395 const ImVec2& card_size) {
396 ImGui::PushID(index);
397
398 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
399 const ImVec4 base_color = GetEditorAccentColor(info.type, theme);
400 const ImVec4 text_primary = gui::ConvertColorToImVec4(theme.text_primary);
401 const ImVec4 text_secondary = gui::ConvertColorToImVec4(theme.text_secondary);
402 const ImVec4 accent = gui::ConvertColorToImVec4(theme.accent);
403 ImFont* text_font = ImGui::GetFont();
404 const float text_font_size = ImGui::GetFontSize();
405
406 const ImGuiStyle& style = ImGui::GetStyle();
407 const float line_height = ImGui::GetTextLineHeight();
408 const float padding_x = std::max(style.FramePadding.x, card_size.x * 0.06f);
409 const float padding_y = std::max(style.FramePadding.y, card_size.y * 0.08f);
410
411 const float footer_height = info.shortcut.empty() ? 0.0f : line_height;
412 const float footer_spacing =
413 info.shortcut.empty() ? 0.0f : style.ItemSpacing.y;
414 const float available_icon_height = card_size.y - padding_y * 2.0f -
415 line_height - footer_height -
416 footer_spacing;
417 const float min_icon_radius = line_height * 0.9f;
418 float max_icon_radius = card_size.y * 0.24f;
419 max_icon_radius = std::max(max_icon_radius, min_icon_radius);
420 const float icon_radius = std::clamp(available_icon_height * 0.5f,
421 min_icon_radius, max_icon_radius);
422
423 const ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
424 ImDrawList* draw_list = ImGui::GetWindowDrawList();
425 const ImVec2 icon_center(cursor_pos.x + card_size.x * 0.5f,
426 cursor_pos.y + padding_y + icon_radius);
427 float title_y = icon_center.y + icon_radius + style.ItemSpacing.y;
428 const float footer_y = cursor_pos.y + card_size.y - padding_y - footer_height;
429 if (title_y + line_height > footer_y - style.ItemSpacing.y) {
430 title_y = footer_y - line_height - style.ItemSpacing.y;
431 }
432
433 // Panel styling with gradients
434 bool is_recent = std::find(recent_editors_.begin(), recent_editors_.end(),
435 info.type) != recent_editors_.end();
436
437 // Create gradient background
438 ImU32 color_top = ImGui::GetColorU32(ScaleColor(base_color, 0.4f, 0.85f));
439 ImU32 color_bottom = ImGui::GetColorU32(ScaleColor(base_color, 0.2f, 0.9f));
440
441 // Draw gradient card background
442 draw_list->AddRectFilledMultiColor(
443 cursor_pos,
444 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y), color_top,
445 color_top, color_bottom, color_bottom);
446
447 // Colored border
448 ImU32 border_color =
449 is_recent ? ImGui::GetColorU32(WithAlpha(base_color, 1.0f))
450 : ImGui::GetColorU32(ScaleColor(base_color, 0.6f, 0.7f));
451 const float rounding = std::max(style.FrameRounding, card_size.y * 0.05f);
452 const float border_thickness =
453 is_recent ? std::max(2.0f, style.FrameBorderSize + 1.0f)
454 : std::max(1.0f, style.FrameBorderSize);
455 draw_list->AddRect(
456 cursor_pos,
457 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
458 border_color, rounding, 0, border_thickness);
459
460 // Recent indicator badge
461 if (is_recent) {
462 const float badge_radius =
463 std::clamp(line_height * 0.6f, line_height * 0.4f, line_height);
464 ImVec2 badge_pos(cursor_pos.x + card_size.x - padding_x - badge_radius,
465 cursor_pos.y + padding_y + badge_radius);
466 draw_list->AddCircleFilled(badge_pos, badge_radius,
467 ImGui::GetColorU32(base_color), 16);
468 const ImU32 star_color = ImGui::GetColorU32(text_primary);
469 const ImVec2 star_size =
470 text_font->CalcTextSizeA(text_font_size, FLT_MAX, 0.0f, ICON_MD_STAR);
471 const ImVec2 star_pos(badge_pos.x - star_size.x * 0.5f,
472 badge_pos.y - star_size.y * 0.5f);
473 draw_list->AddText(text_font, text_font_size, star_pos, star_color,
475 }
476
477 // Make button transparent (we draw our own background)
478 ImVec4 button_bg = ImGui::GetStyleColorVec4(ImGuiCol_Button);
479 button_bg.w = 0.0f;
480 gui::StyleColorGuard card_btn_guard(
481 {{ImGuiCol_Button, button_bg},
482 {ImGuiCol_ButtonHovered, ScaleColor(base_color, 0.3f, 0.5f)},
483 {ImGuiCol_ButtonActive, ScaleColor(base_color, 0.5f, 0.7f)}});
484
485 bool clicked =
486 ImGui::Button(absl::StrCat("##", info.name).c_str(), card_size);
487 bool is_hovered = ImGui::IsItemHovered();
488
489 // Draw icon with colored background circle
490 ImU32 icon_bg = ImGui::GetColorU32(base_color);
491 draw_list->AddCircleFilled(icon_center, icon_radius, icon_bg, 32);
492
493 // Draw icon
494 ImFont* icon_font = ImGui::GetFont();
495 if (ImGui::GetIO().Fonts->Fonts.size() > 2) {
496 icon_font = ImGui::GetIO().Fonts->Fonts[2];
497 } else if (ImGui::GetIO().Fonts->Fonts.size() > 1) {
498 icon_font = ImGui::GetIO().Fonts->Fonts[1];
499 }
500 ImGui::PushFont(icon_font);
501 const float icon_font_size = ImGui::GetFontSize();
502 const ImVec2 icon_size =
503 icon_font->CalcTextSizeA(icon_font_size, FLT_MAX, 0.0f, info.icon);
504 ImGui::PopFont();
505 const ImVec2 icon_text_pos(icon_center.x - icon_size.x * 0.5f,
506 icon_center.y - icon_size.y * 0.5f);
507 draw_list->AddText(icon_font, icon_font_size, icon_text_pos,
508 ImGui::GetColorU32(text_primary), info.icon);
509
510 // Draw name
511 const ImVec2 name_size =
512 text_font->CalcTextSizeA(text_font_size, FLT_MAX, 0.0f, info.name);
513 float name_x = cursor_pos.x + (card_size.x - name_size.x) * 0.5f;
514 const float name_min_x = cursor_pos.x + padding_x;
515 const float name_max_x = cursor_pos.x + card_size.x - padding_x;
516 name_x = std::clamp(name_x, name_min_x, name_max_x);
517 const ImVec2 name_pos(name_x, title_y);
518 const ImVec4 name_clip(name_min_x, cursor_pos.y + padding_y, name_max_x,
519 footer_y);
520 draw_list->AddText(text_font, text_font_size, name_pos,
521 ImGui::GetColorU32(base_color), info.name, nullptr, 0.0f,
522 &name_clip);
523
524 // Draw shortcut hint if available
525 if (!info.shortcut.empty()) {
526 const ImVec2 shortcut_pos(cursor_pos.x + padding_x, footer_y);
527 const ImVec4 shortcut_clip(cursor_pos.x + padding_x, footer_y,
528 cursor_pos.x + card_size.x - padding_x,
529 cursor_pos.y + card_size.y - padding_y);
530 draw_list->AddText(text_font, text_font_size, shortcut_pos,
531 ImGui::GetColorU32(text_secondary),
532 info.shortcut.c_str(), nullptr, 0.0f, &shortcut_clip);
533 }
534
535 // Hover glow effect
536 if (is_hovered) {
537 ImU32 glow_color = ImGui::GetColorU32(ScaleColor(base_color, 1.0f, 0.18f));
538 draw_list->AddRectFilled(
539 cursor_pos,
540 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
541 glow_color, rounding);
542 }
543
544 // Enhanced tooltip with fixed sizing
545 if (is_hovered) {
546 const float tooltip_width = std::clamp(card_size.x * 1.4f, 240.0f, 340.0f);
547 ImGui::SetNextWindowSize(ImVec2(tooltip_width, 0), ImGuiCond_Always);
548 ImGui::BeginTooltip();
549 ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); // Medium font
550 ImGui::TextColored(base_color, "%s %s", info.icon, info.name);
551 ImGui::PopFont();
552 ImGui::Separator();
553 ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + tooltip_width - 20.0f);
554 ImGui::TextWrapped("%s", info.description);
555 ImGui::PopTextWrapPos();
556 if (!info.shortcut.empty()) {
557 ImGui::Spacing();
558 ImGui::TextColored(base_color, ICON_MD_KEYBOARD " %s",
559 info.shortcut.c_str());
560 }
561 if (is_recent) {
562 ImGui::Spacing();
563 ImGui::TextColored(accent, ICON_MD_STAR " Recently used");
564 }
565 ImGui::EndTooltip();
566 }
567
568 if (clicked) {
569 selected_editor_ = info.type;
570 }
571
572 ImGui::PopID();
573}
574
576 // Remove if already in list
577 auto it = std::find(recent_editors_.begin(), recent_editors_.end(), type);
578 if (it != recent_editors_.end()) {
579 recent_editors_.erase(it);
580 }
581
582 // Add to front
583 recent_editors_.insert(recent_editors_.begin(), type);
584
585 // Limit size
586 if (recent_editors_.size() > kMaxRecentEditors) {
588 }
589
591}
592
594 try {
595 auto data = util::LoadFileFromConfigDir("recent_editors.txt");
596 if (!data.empty()) {
597 std::istringstream ss(data);
598 std::string line;
599 while (std::getline(ss, line) &&
601 int type_int = std::stoi(line);
602 if (type_int >= 0 && type_int <= static_cast<int>(kLastEditorType) &&
603 type_int != static_cast<int>(EditorType::kSettings)) {
604 recent_editors_.push_back(static_cast<EditorType>(type_int));
605 }
606 }
607 }
608 } catch (...) {
609 // Ignore errors, just start with empty recent list
610 }
611}
612
614 try {
615 std::ostringstream ss;
616 for (EditorType type : recent_editors_) {
617 ss << static_cast<int>(type) << "\n";
618 }
619 util::SaveFile("recent_editors.txt", ss.str());
620 } catch (...) {
621 // Ignore save errors
622 }
623}
624
625} // namespace editor
626} // namespace yaze
void DrawEditorPanel(const EditorInfo &info, int index, const ImVec2 &card_size)
void SaveRecentEditors()
Save recently used editors to settings.
void LoadRecentEditors()
Load recently used editors from settings.
std::function< void(EditorType)> selection_callback_
void MarkRecentlyUsed(EditorType type)
Mark an editor as recently used.
bool Show(bool *p_open=nullptr)
Show the dialog.
RAII guard for ImGui style colors.
Definition style_guard.h:27
const Theme & GetCurrentTheme() const
static ThemeManager & Get()
#define ICON_MD_APPS
Definition icons.h:168
#define ICON_MD_EMOJI_EMOTIONS
Definition icons.h:672
#define ICON_MD_DATA_ARRAY
Definition icons.h:519
#define ICON_MD_STAR
Definition icons.h:1848
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_CODE
Definition icons.h:434
#define ICON_MD_VIDEOGAME_ASSET
Definition icons.h:2076
#define ICON_MD_CHAT_BUBBLE
Definition icons.h:395
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_CASTLE
Definition icons.h:380
#define ICON_MD_MUSIC_NOTE
Definition icons.h:1264
#define ICON_MD_ROUTE
Definition icons.h:1627
#define ICON_MD_KEYBOARD
Definition icons.h:1028
#define ICON_MD_PALETTE
Definition icons.h:1370
#define ICON_MD_TV
Definition icons.h:2032
#define ICON_MD_COLOR_LENS
Definition icons.h:440
#define ICON_MD_SMART_TOY
Definition icons.h:1781
#define ICON_MD_HISTORY
Definition icons.h:946
ImVec4 ScaleColor(const ImVec4 &color, float scale, float alpha)
GridLayout ComputeGridLayout(float avail_width, float min_width, float max_width, float min_height, float max_height, float preferred_width, float aspect_ratio, float spacing)
ImVec4 GetEditorAccentColor(EditorType type, const gui::Theme &theme)
constexpr EditorType kLastEditorType
Definition editor.h:235
const char * GetCtrlDisplayName()
Get the display name for the primary modifier key.
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:140
void SaveFile(const std::string &filename, const std::string &contents)
Definition file_util.cc:56
std::string LoadFileFromConfigDir(const std::string &filename)
Loads a file from the user's config directory.
Definition file_util.cc:38
Metadata about an available editor.
Comprehensive theme structure for YAZE.