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