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);
127 default:
129 }
130}
131
132} // namespace
133
135 // Use platform-aware shortcut strings (Cmd on macOS, Ctrl elsewhere)
136 const char* ctrl = gui::GetCtrlDisplayName();
137 editors_ = {
138 {EditorType::kOverworld, "Overworld", ICON_MD_MAP,
139 "Edit overworld maps, entrances, and properties",
140 absl::StrFormat("%s+1", ctrl), false, true},
141
143 "Design dungeon rooms, layouts, and mechanics",
144 absl::StrFormat("%s+2", ctrl), false, true},
145
147 "Modify tiles, palettes, and graphics sets",
148 absl::StrFormat("%s+3", ctrl), false, true},
149
151 "Edit sprite graphics and properties", absl::StrFormat("%s+4", ctrl),
152 false, true},
153
155 "Edit dialogue, signs, and text", absl::StrFormat("%s+5", ctrl), false,
156 true},
157
159 "Configure music and sound effects", absl::StrFormat("%s+6", ctrl),
160 false, true},
161
163 "Edit color palettes and animations", absl::StrFormat("%s+7", ctrl),
164 false, true},
165
166 {EditorType::kScreen, "Screens", ICON_MD_TV,
167 "Edit title screen and ending screens", absl::StrFormat("%s+8", ctrl),
168 false, true},
169
171 "Write and edit assembly code", absl::StrFormat("%s+9", ctrl), false,
172 false},
173
174 {EditorType::kHex, "Hex Editor", ICON_MD_DATA_ARRAY,
175 "Direct ROM memory editing and comparison",
176 absl::StrFormat("%s+0", ctrl), false, true},
177
179 "Test and debug your ROM in real-time with live debugging",
180 absl::StrFormat("%s+Shift+E", ctrl), false, true},
181
183 "Configure AI agent, collaboration, and automation",
184 absl::StrFormat("%s+Shift+A", ctrl), false, false},
185 };
186
188}
189
190bool EditorSelectionDialog::Show(bool* p_open) {
191 // Sync internal state with external flag
192 if (p_open && *p_open && !is_open_) {
193 is_open_ = true;
194 }
195
196 if (!is_open_) {
197 if (p_open)
198 *p_open = false;
199 return false;
200 }
201
202 bool editor_selected = false;
203 bool* window_open = p_open ? p_open : &is_open_;
204
205 // Set window properties immediately before Begin to prevent them from
206 // affecting tooltips
207 ImGuiViewport* viewport = ImGui::GetMainViewport();
208 ImVec2 center = viewport->GetCenter();
209 ImVec2 view_size = viewport->WorkSize;
210 float target_width = std::clamp(view_size.x * 0.9f, 520.0f, 980.0f);
211 float target_height = std::clamp(view_size.y * 0.88f, 420.0f, 760.0f);
212 ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
213 ImGui::SetNextWindowSize(ImVec2(target_width, target_height),
214 ImGuiCond_Appearing);
215 ImGui::SetNextWindowSizeConstraints(
216 ImVec2(420.0f, 360.0f), ImVec2(view_size.x * 0.98f, view_size.y * 0.95f));
217
218 if (ImGui::Begin("Editor Selection", window_open,
219 ImGuiWindowFlags_NoCollapse)) {
221
222 ImGui::Separator();
223 ImGui::Spacing();
224
225 // Quick access buttons for recently used
226 if (!recent_editors_.empty()) {
228 ImGui::Separator();
229 ImGui::Spacing();
230 }
231
232 // Main editor grid
233 ImGui::Text(ICON_MD_APPS " All Editors");
234 ImGui::Spacing();
235
236 const float scale = GetEditorSelectScale();
237 const float compact_scale =
238 ImGui::GetContentRegionAvail().x < 620.0f ? 0.85f : 1.0f;
239 const float min_width = kEditorSelectCardBaseWidth * scale * compact_scale;
240 const float max_width = kEditorSelectCardBaseWidth *
241 kEditorSelectCardWidthMaxFactor * scale *
242 compact_scale;
243 const float min_height =
244 kEditorSelectCardBaseHeight * scale * compact_scale;
245 const float max_height = kEditorSelectCardBaseHeight *
246 kEditorSelectCardHeightMaxFactor * scale *
247 compact_scale;
248 const float spacing = ImGui::GetStyle().ItemSpacing.x;
249 const float aspect_ratio = min_height / std::max(min_width, 1.0f);
250 GridLayout layout = ComputeGridLayout(
251 ImGui::GetContentRegionAvail().x, min_width, max_width, min_height,
252 max_height, min_width, aspect_ratio, spacing);
253
254 int column = 0;
255 for (size_t i = 0; i < editors_.size(); ++i) {
256 if (column == 0) {
257 ImGui::SetCursorPosX(layout.row_start_x);
258 }
259
260 EditorType prev_selection = selected_editor_;
261 DrawEditorPanel(editors_[i], static_cast<int>(i),
262 ImVec2(layout.item_width, layout.item_height));
263
264 // Check if an editor was just selected
265 if (selected_editor_ != prev_selection) {
266 editor_selected = true;
270 }
271 // Auto-dismiss after selection
272 is_open_ = false;
273 if (p_open) {
274 *p_open = false;
275 }
276 }
277
278 column += 1;
279 if (column < layout.columns) {
280 ImGui::SameLine(0.0f, layout.spacing);
281 } else {
282 column = 0;
283 ImGui::Spacing();
284 }
285 }
286
287 if (column != 0) {
288 ImGui::NewLine();
289 }
290 }
291 ImGui::End();
292
293 // Sync state back
294 if (p_open && !(*p_open)) {
295 is_open_ = false;
296 }
297
298 // DO NOT auto-dismiss here. Let the callback/EditorManager handle it.
299 // This allows the dialog to be used as a persistent switcher if desired.
300
301 return editor_selected;
302}
303
305 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
306 const ImVec4 accent = gui::ConvertColorToImVec4(theme.accent);
307 const ImVec4 text_secondary = gui::ConvertColorToImVec4(theme.text_secondary);
308
309 ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[2]); // Large font
310
311 ImGui::TextColored(accent, ICON_MD_EDIT " Select an Editor");
312
313 ImGui::PopFont();
314
315 ImGui::TextColored(text_secondary,
316 tr("Choose an editor to begin working on your ROM. "
317 "You can open multiple editors simultaneously."));
318}
319
321 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
322 const ImVec4 accent = gui::ConvertColorToImVec4(theme.accent);
323 ImGui::TextColored(accent, ICON_MD_HISTORY " Recently Used");
324 ImGui::Spacing();
325
326 const float scale = GetEditorSelectScale();
327 const float min_width = kEditorSelectRecentBaseWidth * scale;
328 const float max_width =
329 kEditorSelectRecentBaseWidth * kEditorSelectRecentWidthMaxFactor * scale;
330 const float height = kEditorSelectRecentBaseHeight * scale;
331 const float spacing = ImGui::GetStyle().ItemSpacing.x;
332 const float avail_width = ImGui::GetContentRegionAvail().x;
333 const bool stack_items = avail_width < min_width * 1.6f;
334 GridLayout layout{};
335 if (stack_items) {
336 layout.columns = 1;
337 layout.item_width = avail_width;
338 layout.item_height = height;
339 layout.spacing = spacing;
340 } else {
341 layout = ComputeGridLayout(avail_width, min_width, max_width, height,
342 height, min_width,
343 height / std::max(min_width, 1.0f), spacing);
344 }
345
346 int column = 0;
347 for (EditorType type : recent_editors_) {
348 // Find editor info
349 auto it = std::find_if(
350 editors_.begin(), editors_.end(),
351 [type](const EditorInfo& info) { return info.type == type; });
352
353 if (it != editors_.end()) {
354 if (column == 0) {
355 ImGui::SetCursorPosX(layout.row_start_x);
356 }
357
358 const ImVec4 base_color = GetEditorAccentColor(it->type, theme);
359 gui::StyleColorGuard btn_guard(
360 {{ImGuiCol_Button, ScaleColor(base_color, 0.5f, 0.7f)},
361 {ImGuiCol_ButtonHovered, ScaleColor(base_color, 0.7f, 0.9f)},
362 {ImGuiCol_ButtonActive, WithAlpha(base_color, 1.0f)}});
363
364 if (ImGui::Button(absl::StrCat(it->icon, " ", it->name).c_str(),
365 ImVec2(layout.item_width, layout.item_height))) {
366 selected_editor_ = type;
367 }
368
369 if (ImGui::IsItemHovered()) {
370 ImGui::SetTooltip("%s", it->description);
371 }
372
373 column += 1;
374 if (column < layout.columns) {
375 ImGui::SameLine(0.0f, layout.spacing);
376 } else {
377 column = 0;
378 ImGui::Spacing();
379 }
380 }
381 }
382
383 if (column != 0) {
384 ImGui::NewLine();
385 }
386}
387
389 const ImVec2& card_size) {
390 ImGui::PushID(index);
391
392 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
393 const ImVec4 base_color = GetEditorAccentColor(info.type, theme);
394 const ImVec4 text_primary = gui::ConvertColorToImVec4(theme.text_primary);
395 const ImVec4 text_secondary = gui::ConvertColorToImVec4(theme.text_secondary);
396 const ImVec4 accent = gui::ConvertColorToImVec4(theme.accent);
397 ImFont* text_font = ImGui::GetFont();
398 const float text_font_size = ImGui::GetFontSize();
399
400 const ImGuiStyle& style = ImGui::GetStyle();
401 const float line_height = ImGui::GetTextLineHeight();
402 const float padding_x = std::max(style.FramePadding.x, card_size.x * 0.06f);
403 const float padding_y = std::max(style.FramePadding.y, card_size.y * 0.08f);
404
405 const float footer_height = info.shortcut.empty() ? 0.0f : line_height;
406 const float footer_spacing =
407 info.shortcut.empty() ? 0.0f : style.ItemSpacing.y;
408 const float available_icon_height = card_size.y - padding_y * 2.0f -
409 line_height - footer_height -
410 footer_spacing;
411 const float min_icon_radius = line_height * 0.9f;
412 float max_icon_radius = card_size.y * 0.24f;
413 max_icon_radius = std::max(max_icon_radius, min_icon_radius);
414 const float icon_radius = std::clamp(available_icon_height * 0.5f,
415 min_icon_radius, max_icon_radius);
416
417 const ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
418 ImDrawList* draw_list = ImGui::GetWindowDrawList();
419 const ImVec2 icon_center(cursor_pos.x + card_size.x * 0.5f,
420 cursor_pos.y + padding_y + icon_radius);
421 float title_y = icon_center.y + icon_radius + style.ItemSpacing.y;
422 const float footer_y = cursor_pos.y + card_size.y - padding_y - footer_height;
423 if (title_y + line_height > footer_y - style.ItemSpacing.y) {
424 title_y = footer_y - line_height - style.ItemSpacing.y;
425 }
426
427 // Panel styling with gradients
428 bool is_recent = std::find(recent_editors_.begin(), recent_editors_.end(),
429 info.type) != recent_editors_.end();
430
431 // Create gradient background
432 ImU32 color_top = ImGui::GetColorU32(ScaleColor(base_color, 0.4f, 0.85f));
433 ImU32 color_bottom = ImGui::GetColorU32(ScaleColor(base_color, 0.2f, 0.9f));
434
435 // Draw gradient card background
436 draw_list->AddRectFilledMultiColor(
437 cursor_pos,
438 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y), color_top,
439 color_top, color_bottom, color_bottom);
440
441 // Colored border
442 ImU32 border_color =
443 is_recent ? ImGui::GetColorU32(WithAlpha(base_color, 1.0f))
444 : ImGui::GetColorU32(ScaleColor(base_color, 0.6f, 0.7f));
445 const float rounding = std::max(style.FrameRounding, card_size.y * 0.05f);
446 const float border_thickness =
447 is_recent ? std::max(2.0f, style.FrameBorderSize + 1.0f)
448 : std::max(1.0f, style.FrameBorderSize);
449 draw_list->AddRect(
450 cursor_pos,
451 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
452 border_color, rounding, 0, border_thickness);
453
454 // Recent indicator badge
455 if (is_recent) {
456 const float badge_radius =
457 std::clamp(line_height * 0.6f, line_height * 0.4f, line_height);
458 ImVec2 badge_pos(cursor_pos.x + card_size.x - padding_x - badge_radius,
459 cursor_pos.y + padding_y + badge_radius);
460 draw_list->AddCircleFilled(badge_pos, badge_radius,
461 ImGui::GetColorU32(base_color), 16);
462 const ImU32 star_color = ImGui::GetColorU32(text_primary);
463 const ImVec2 star_size =
464 text_font->CalcTextSizeA(text_font_size, FLT_MAX, 0.0f, ICON_MD_STAR);
465 const ImVec2 star_pos(badge_pos.x - star_size.x * 0.5f,
466 badge_pos.y - star_size.y * 0.5f);
467 draw_list->AddText(text_font, text_font_size, star_pos, star_color,
469 }
470
471 // Make button transparent (we draw our own background)
472 ImVec4 button_bg = ImGui::GetStyleColorVec4(ImGuiCol_Button);
473 button_bg.w = 0.0f;
474 gui::StyleColorGuard card_btn_guard(
475 {{ImGuiCol_Button, button_bg},
476 {ImGuiCol_ButtonHovered, ScaleColor(base_color, 0.3f, 0.5f)},
477 {ImGuiCol_ButtonActive, ScaleColor(base_color, 0.5f, 0.7f)}});
478
479 bool clicked =
480 ImGui::Button(absl::StrCat("##", info.name).c_str(), card_size);
481 bool is_hovered = ImGui::IsItemHovered();
482
483 // Draw icon with colored background circle
484 ImU32 icon_bg = ImGui::GetColorU32(base_color);
485 draw_list->AddCircleFilled(icon_center, icon_radius, icon_bg, 32);
486
487 // Draw icon
488 ImFont* icon_font = ImGui::GetFont();
489 if (ImGui::GetIO().Fonts->Fonts.size() > 2) {
490 icon_font = ImGui::GetIO().Fonts->Fonts[2];
491 } else if (ImGui::GetIO().Fonts->Fonts.size() > 1) {
492 icon_font = ImGui::GetIO().Fonts->Fonts[1];
493 }
494 ImGui::PushFont(icon_font);
495 const float icon_font_size = ImGui::GetFontSize();
496 const ImVec2 icon_size =
497 icon_font->CalcTextSizeA(icon_font_size, FLT_MAX, 0.0f, info.icon);
498 ImGui::PopFont();
499 const ImVec2 icon_text_pos(icon_center.x - icon_size.x * 0.5f,
500 icon_center.y - icon_size.y * 0.5f);
501 draw_list->AddText(icon_font, icon_font_size, icon_text_pos,
502 ImGui::GetColorU32(text_primary), info.icon);
503
504 // Draw name
505 const ImVec2 name_size =
506 text_font->CalcTextSizeA(text_font_size, FLT_MAX, 0.0f, info.name);
507 float name_x = cursor_pos.x + (card_size.x - name_size.x) * 0.5f;
508 const float name_min_x = cursor_pos.x + padding_x;
509 const float name_max_x = cursor_pos.x + card_size.x - padding_x;
510 name_x = std::clamp(name_x, name_min_x, name_max_x);
511 const ImVec2 name_pos(name_x, title_y);
512 const ImVec4 name_clip(name_min_x, cursor_pos.y + padding_y, name_max_x,
513 footer_y);
514 draw_list->AddText(text_font, text_font_size, name_pos,
515 ImGui::GetColorU32(base_color), info.name, nullptr, 0.0f,
516 &name_clip);
517
518 // Draw shortcut hint if available
519 if (!info.shortcut.empty()) {
520 const ImVec2 shortcut_pos(cursor_pos.x + padding_x, footer_y);
521 const ImVec4 shortcut_clip(cursor_pos.x + padding_x, footer_y,
522 cursor_pos.x + card_size.x - padding_x,
523 cursor_pos.y + card_size.y - padding_y);
524 draw_list->AddText(text_font, text_font_size, shortcut_pos,
525 ImGui::GetColorU32(text_secondary),
526 info.shortcut.c_str(), nullptr, 0.0f, &shortcut_clip);
527 }
528
529 // Hover glow effect
530 if (is_hovered) {
531 ImU32 glow_color = ImGui::GetColorU32(ScaleColor(base_color, 1.0f, 0.18f));
532 draw_list->AddRectFilled(
533 cursor_pos,
534 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
535 glow_color, rounding);
536 }
537
538 // Enhanced tooltip with fixed sizing
539 if (is_hovered) {
540 const float tooltip_width = std::clamp(card_size.x * 1.4f, 240.0f, 340.0f);
541 ImGui::SetNextWindowSize(ImVec2(tooltip_width, 0), ImGuiCond_Always);
542 ImGui::BeginTooltip();
543 ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); // Medium font
544 ImGui::TextColored(base_color, "%s %s", info.icon, info.name);
545 ImGui::PopFont();
546 ImGui::Separator();
547 ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + tooltip_width - 20.0f);
548 ImGui::TextWrapped("%s", info.description);
549 ImGui::PopTextWrapPos();
550 if (!info.shortcut.empty()) {
551 ImGui::Spacing();
552 ImGui::TextColored(base_color, ICON_MD_KEYBOARD " %s",
553 info.shortcut.c_str());
554 }
555 if (is_recent) {
556 ImGui::Spacing();
557 ImGui::TextColored(accent, ICON_MD_STAR " Recently used");
558 }
559 ImGui::EndTooltip();
560 }
561
562 if (clicked) {
563 selected_editor_ = info.type;
564 }
565
566 ImGui::PopID();
567}
568
570 // Remove if already in list
571 auto it = std::find(recent_editors_.begin(), recent_editors_.end(), type);
572 if (it != recent_editors_.end()) {
573 recent_editors_.erase(it);
574 }
575
576 // Add to front
577 recent_editors_.insert(recent_editors_.begin(), type);
578
579 // Limit size
580 if (recent_editors_.size() > kMaxRecentEditors) {
582 }
583
585}
586
588 try {
589 auto data = util::LoadFileFromConfigDir("recent_editors.txt");
590 if (!data.empty()) {
591 std::istringstream ss(data);
592 std::string line;
593 while (std::getline(ss, line) &&
595 int type_int = std::stoi(line);
596 if (type_int >= 0 &&
597 type_int < static_cast<int>(EditorType::kSettings)) {
598 recent_editors_.push_back(static_cast<EditorType>(type_int));
599 }
600 }
601 }
602 } catch (...) {
603 // Ignore errors, just start with empty recent list
604 }
605}
606
608 try {
609 std::ostringstream ss;
610 for (EditorType type : recent_editors_) {
611 ss << static_cast<int>(type) << "\n";
612 }
613 util::SaveFile("recent_editors.txt", ss.str());
614 } catch (...) {
615 // Ignore save errors
616 }
617}
618
619} // namespace editor
620} // 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_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)
ImVec4 GetEditorAccentColor(EditorType type, const gui::Theme &theme)
const char * GetCtrlDisplayName()
Get the display name for the primary modifier key.
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:134
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.