9#include "absl/strings/str_format.h"
12#include <emscripten.h>
31#include "imgui/imgui.h"
43 : editor_manager_(editor_manager),
44 rom_manager_(rom_manager),
45 project_manager_(project_manager),
46 editor_registry_(editor_registry),
47 panel_manager_(panel_manager),
48 session_coordinator_(session_coordinator),
49 window_delegate_(window_delegate),
50 toast_manager_(toast_manager),
51 popup_manager_(popup_manager),
52 shortcut_manager_(shortcut_manager) {
63 var romInput = document.getElementById(
'rom-input');
75 absl::StrFormat(
"Failed to load ROM: %s", status.message()),
90 absl::StrFormat(
"Failed to create project: %s", status.message()),
99 welcome_screen_->SetOpenProjectCallback([
this](
const std::string& filepath) {
104 absl::StrFormat(
"Failed to open project: %s", status.message()),
115#ifdef YAZE_BUILD_AGENT_UI
156 if (ImGui::GetCurrentContext()) {
157 ImDrawList* bg_draw_list = ImGui::GetBackgroundDrawList();
158 const ImGuiViewport* viewport = ImGui::GetMainViewport();
161 auto current_theme = theme_manager.GetCurrentTheme();
165 ImVec2 grid_pos = viewport->WorkPos;
166 ImVec2 grid_size = viewport->WorkSize;
167 bg_renderer.RenderDockingBackground(bg_draw_list, grid_pos, grid_size,
168 current_theme.primary);
200 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
201 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
203 ImGui::PushStyleColor(ImGuiCol_ButtonActive,
213 bool clicked = ImGui::SmallButton(icon);
215 ImGui::PopStyleColor(4);
217 if (tooltip && ImGui::IsItemHovered()) {
218 ImGui::SetTooltip(
"%s", tooltip);
226 const float frame_padding = ImGui::GetStyle().FramePadding.x;
229 return icon_width + frame_padding * 2.0f;
241 const std::string full_version =
244 const float item_spacing = 6.0f;
246 const float padding = 8.0f;
249 const ImGuiViewport* viewport = ImGui::GetMainViewport();
250 const float true_viewport_right = viewport->WorkPos.x + viewport->WorkSize.x;
254 int panel_button_count = 0;
257 panel_button_count = 5;
259 panel_button_count = 4;
263 float panel_region_width = 0.0f;
264 if (panel_button_count > 0) {
265 panel_region_width = (button_width * panel_button_count) +
266 (item_spacing * (panel_button_count - 1)) + padding;
269 panel_region_width += button_width + item_spacing;
273 float panel_screen_x = true_viewport_right - panel_region_width;
281 const float window_width = ImGui::GetWindowWidth();
282 const float window_screen_x = ImGui::GetWindowPos().x;
283 const float menu_items_end = ImGui::GetCursorPosX() + 16.0f;
286 float panel_local_x = panel_screen_x - window_screen_x;
287 float region_end = std::min(window_width - padding, panel_local_x - item_spacing);
290 bool has_dirty_rom = current_rom && current_rom->is_loaded() && current_rom->dirty();
293 float version_width = ImGui::CalcTextSize(full_version.c_str()).x;
295 float session_width = button_width;
297 const float available_width = region_end - menu_items_end - padding;
300 float required_width = button_width;
306 bool show_version = (required_width + version_width + item_spacing) <= available_width;
308 required_width += version_width + item_spacing;
312 bool show_session = has_multiple_sessions &&
313 (required_width + session_width + item_spacing) <= available_width;
315 required_width += session_width + item_spacing;
319 bool show_dirty = has_dirty_rom &&
320 (required_width + dirty_width) <= available_width;
322 required_width += dirty_width;
326 float start_pos = std::max(menu_items_end, region_end - required_width);
331 ImGui::SameLine(start_pos);
332 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(item_spacing, 0.0f));
337 ImGui::Text(
"%s", full_version.c_str());
338 ImGui::PopStyleColor();
345 ImGui::PushStyleColor(ImGuiCol_Text,
348 ImGui::PopStyleColor();
349 if (ImGui::IsItemHovered()) {
350 ImGui::SetTooltip(
"Unsaved changes: %s",
351 current_rom->short_name().c_str());
368 if (panel_button_count > 0) {
370 float menu_bar_y = ImGui::GetCursorScreenPos().y;
373 ImGui::SetCursorScreenPos(ImVec2(panel_screen_x, menu_bar_y));
383 "Hide menu bar (Alt to restore)")) {
388 ImGui::PopStyleVar();
398 ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar |
399 ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
400 ImGuiWindowFlags_NoScrollbar |
401 ImGuiWindowFlags_NoCollapse |
402 ImGuiWindowFlags_AlwaysAutoResize |
403 ImGuiWindowFlags_NoBackground |
404 ImGuiWindowFlags_NoSavedSettings;
406 ImGui::SetNextWindowPos(ImVec2(8, 8));
407 ImGui::SetNextWindowBgAlpha(0.7f);
409 if (ImGui::Begin(
"##MenuBarRestore",
nullptr, flags)) {
411 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
413 ImGui::PushStyleColor(ImGuiCol_ButtonActive,
421 ImGui::PopStyleColor(4);
423 if (ImGui::IsItemHovered()) {
424 ImGui::SetTooltip(
"Show menu bar (Alt)");
430 if (ImGui::IsKeyPressed(ImGuiKey_LeftAlt) ||
431 ImGui::IsKeyPressed(ImGuiKey_RightAlt)) {
437 bool show_session,
bool has_multiple_sessions) {
443 bool is_active = right_panel &&
447 if (unread > 0 || is_active) {
449 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
454 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
467 ImGui::PopStyleColor(4);
470 if (ImGui::IsItemHovered()) {
471 ImGui::BeginTooltip();
477 unread, unread == 1 ?
"" :
"s");
478 ImGui::PopStyleColor();
482 ImGui::PopStyleColor();
485 ImGui::TextDisabled(
"Click to open Notifications panel");
488 if (!show_dirty && has_dirty_rom) {
493 current_rom->short_name().c_str());
494 ImGui::PopStyleColor();
497 if (!show_session && has_multiple_sessions) {
498 if (!show_dirty && has_dirty_rom) {
506 ImGui::PopStyleColor();
517 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
518 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
520 ImGui::PushStyleColor(ImGuiCol_ButtonActive,
525 ImVec2 button_min = ImGui::GetCursorScreenPos();
528 ImGui::OpenPopup(
"##SessionSwitcherPopup");
531 ImVec2 button_max = ImGui::GetItemRectMax();
533 ImGui::PopStyleColor(4);
535 if (ImGui::IsItemHovered()) {
536 std::string tooltip = current_rom && current_rom->is_loaded()
537 ? current_rom->short_name()
539 ImGui::SetTooltip(
"%s\n%zu sessions open (Ctrl+Tab)", tooltip.c_str(),
544 const float popup_width = 250.0f;
545 const float screen_width = ImGui::GetIO().DisplaySize.x;
546 const float popup_x = std::min(button_min.x, screen_width - popup_width - 10.0f);
548 ImGui::SetNextWindowPos(ImVec2(popup_x, button_max.y + 2.0f), ImGuiCond_Appearing);
551 if (ImGui::BeginPopup(
"##SessionSwitcherPopup")) {
563 Rom* rom = &session->rom;
564 ImGui::PushID(
static_cast<int>(i));
566 bool is_current = (rom == current_rom);
575 if (ImGui::Selectable(label.c_str(), is_current)) {
580 ImGui::PopStyleColor();
648 "EditorManager is null - cannot check ROM state");
653 LOG_ERROR(
"UICoordinator",
"WelcomeScreen object is null - cannot render");
659 bool rom_is_loaded = current_rom && current_rom->is_loaded();
712 ImGuiWindowFlags_AlwaysAutoResize);
713 static char preset_name[128] =
"";
714 ImGui::InputText(
"Name", preset_name, IM_ARRAYSIZE(preset_name));
716 if (strlen(preset_name) > 0) {
720 preset_name[0] =
'\0';
726 preset_name[0] =
'\0';
733 ImGuiWindowFlags_AlwaysAutoResize);
739 for (
const auto& name : workspace_manager->workspace_presets()) {
740 if (ImGui::Selectable(name.c_str())) {
746 if (workspace_manager->workspace_presets().empty())
747 ImGui::Text(
"No presets found");
785 std::string category =
790 LOG_INFO(
"UICoordinator",
"Hid all panels in category: %s", category.c_str());
820 const std::string& icon,
822 std::function<
void()> callback,
825 ImGui::PushStyleColor(ImGuiCol_Button,
830 std::string button_text =
831 absl::StrFormat(
"%s %s", icon.c_str(), text.c_str());
832 if (ImGui::Button(button_text.c_str())) {
833 if (enabled && callback) {
839 ImGui::PopStyleColor(2);
845 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
846 ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
851 ImGui::SetNextWindowPos(ImVec2(x, y), ImGuiCond_Appearing);
856 ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_FirstUseEver);
864 using namespace ImGui;
867 SetNextWindowPos(GetMainViewport()->GetCenter(), ImGuiCond_Appearing,
869 SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
871 bool show_palette =
true;
872 if (Begin(absl::StrFormat(
"%s Command Palette",
ICON_MD_SEARCH).c_str(),
873 &show_palette, ImGuiWindowFlags_NoCollapse)) {
875 SetNextItemWidth(-100);
876 if (IsWindowAppearing()) {
877 SetKeyboardFocusHere();
881 bool input_changed = InputTextWithHint(
883 absl::StrFormat(
"%s Search commands (fuzzy matching enabled)...",
889 if (Button(absl::StrFormat(
"%s Clear",
ICON_MD_CLEAR).c_str())) {
891 input_changed =
true;
898 std::vector<std::pair<int, std::pair<std::string, std::string>>>
901 std::transform(query_lower.begin(), query_lower.end(), query_lower.begin(),
905 const auto& name = entry.first;
906 const auto& shortcut = entry.second;
908 std::string name_lower = name;
909 std::transform(name_lower.begin(), name_lower.end(), name_lower.begin(),
915 }
else if (name_lower.find(query_lower) == 0) {
917 }
else if (name_lower.find(query_lower) != std::string::npos) {
921 size_t text_idx = 0, query_idx = 0;
922 while (text_idx < name_lower.length() &&
923 query_idx < query_lower.length()) {
924 if (name_lower[text_idx] == query_lower[query_idx]) {
930 if (query_idx != query_lower.length())
935 std::string shortcut_text =
936 shortcut.keys.empty()
938 : absl::StrFormat(
"(%s)",
PrintShortcut(shortcut.keys).c_str());
939 scored_commands.push_back({score, {name, shortcut_text}});
943 std::sort(scored_commands.begin(), scored_commands.end(),
944 [](
const auto& a,
const auto& b) { return a.first > b.first; });
947 if (BeginTabBar(
"CommandCategories")) {
949 absl::StrFormat(
"%s All Commands",
ICON_MD_LIST).c_str())) {
951 "CommandPaletteTable", 3,
952 ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg |
953 ImGuiTableFlags_SizingStretchProp,
955 TableSetupColumn(
"Command", ImGuiTableColumnFlags_WidthStretch, 0.5f);
956 TableSetupColumn(
"Shortcut", ImGuiTableColumnFlags_WidthStretch,
958 TableSetupColumn(
"Score", ImGuiTableColumnFlags_WidthStretch, 0.2f);
961 for (
size_t i = 0; i < scored_commands.size(); ++i) {
962 const auto& [score, cmd_pair] = scored_commands[i];
963 const auto& [command_name, shortcut_text] = cmd_pair;
968 PushID(
static_cast<int>(i));
971 if (Selectable(command_name.c_str(), is_selected,
972 ImGuiSelectableFlags_SpanAllColumns)) {
975 auto it = shortcuts.find(command_name);
976 if (it != shortcuts.end() && it->second.callback) {
977 it->second.callback();
984 PushStyleColor(ImGuiCol_Text,
986 Text(
"%s", shortcut_text.c_str());
991 PushStyleColor(ImGuiCol_Text,
1003 if (BeginTabItem(absl::StrFormat(
"%s Recent",
ICON_MD_HISTORY).c_str())) {
1004 Text(
"Recent commands coming soon...");
1008 if (BeginTabItem(absl::StrFormat(
"%s Frequent",
ICON_MD_STAR).c_str())) {
1009 Text(
"Frequent commands coming soon...");
1018 Text(
"%s %zu commands | Score: fuzzy match",
ICON_MD_INFO,
1019 scored_commands.size());
1021 PushStyleColor(ImGuiCol_Text,
1023 Text(
"| ↑↓=Navigate | Enter=Execute | Esc=Close");
1029 if (!show_palette) {
1038 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
1039 ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
1040 ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
1042 bool show_search =
true;
1045 &show_search, ImGuiWindowFlags_NoCollapse)) {
1047 ImGui::SetNextItemWidth(-100);
1048 if (ImGui::IsWindowAppearing()) {
1049 ImGui::SetKeyboardFocusHere();
1052 bool input_changed = ImGui::InputTextWithHint(
1054 absl::StrFormat(
"%s Search everything...",
ICON_MD_SEARCH).c_str(),
1058 if (ImGui::Button(absl::StrFormat(
"%s Clear",
ICON_MD_CLEAR).c_str())) {
1060 input_changed =
true;
1066 if (ImGui::BeginTabBar(
"SearchResultTabs")) {
1068 if (ImGui::BeginTabItem(
1071 auto recent_files = manager.GetRecentFiles();
1073 if (ImGui::BeginTable(
"RecentFilesTable", 3,
1074 ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg |
1075 ImGuiTableFlags_SizingStretchProp)) {
1076 ImGui::TableSetupColumn(
"File", ImGuiTableColumnFlags_WidthStretch,
1078 ImGui::TableSetupColumn(
"Type", ImGuiTableColumnFlags_WidthFixed,
1080 ImGui::TableSetupColumn(
"Action", ImGuiTableColumnFlags_WidthFixed,
1082 ImGui::TableHeadersRow();
1084 for (
const auto& file : recent_files) {
1089 ImGui::TableNextRow();
1090 ImGui::TableNextColumn();
1093 ImGui::TableNextColumn();
1095 if (ext ==
"sfc" || ext ==
"smc") {
1096 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f),
"%s ROM",
1098 }
else if (ext ==
"yaze") {
1099 ImGui::TextColored(ImVec4(0.2f, 0.6f, 0.8f, 1.0f),
"%s Project",
1105 ImGui::TableNextColumn();
1106 ImGui::PushID(file.c_str());
1107 if (ImGui::Button(
"Open")) {
1111 absl::StrCat(
"Failed to open: ", status.message()),
1121 ImGui::EndTabItem();
1126 if (current_rom && current_rom->resource_label()) {
1127 if (ImGui::BeginTabItem(
1129 auto& labels = current_rom->resource_label()->labels_;
1131 if (ImGui::BeginTable(
"LabelsTable", 3,
1132 ImGuiTableFlags_ScrollY |
1133 ImGuiTableFlags_RowBg |
1134 ImGuiTableFlags_SizingStretchProp)) {
1135 ImGui::TableSetupColumn(
"Type", ImGuiTableColumnFlags_WidthFixed,
1137 ImGui::TableSetupColumn(
"Label", ImGuiTableColumnFlags_WidthStretch,
1139 ImGui::TableSetupColumn(
"Value", ImGuiTableColumnFlags_WidthStretch,
1141 ImGui::TableHeadersRow();
1143 for (
const auto& type_pair : labels) {
1144 for (
const auto& kv : type_pair.second) {
1150 ImGui::TableNextRow();
1151 ImGui::TableNextColumn();
1152 ImGui::Text(
"%s", type_pair.first.c_str());
1154 ImGui::TableNextColumn();
1155 if (ImGui::Selectable(kv.first.c_str(),
false,
1156 ImGuiSelectableFlags_SpanAllColumns)) {
1160 ImGui::TableNextColumn();
1161 ImGui::TextDisabled(
"%s", kv.second.c_str());
1167 ImGui::EndTabItem();
1173 if (ImGui::BeginTabItem(
1174 absl::StrFormat(
"%s Sessions",
ICON_MD_TAB).c_str())) {
1175 ImGui::Text(
"Search and switch between active sessions:");
1179 std::string session_info =
1181 if (session_info ==
"[CLOSED SESSION]")
1191 ImGui::PushStyleColor(ImGuiCol_Text,
1192 ImVec4(0.2f, 0.8f, 0.2f, 1.0f));
1195 if (ImGui::Selectable(absl::StrFormat(
"%s %s %s",
ICON_MD_TAB,
1196 session_info.c_str(),
1197 is_current ?
"(Current)" :
"")
1206 ImGui::PopStyleColor();
1209 ImGui::EndTabItem();
1218 ImGui::Text(
"%s Global search across all YAZE data",
ICON_MD_INFO);
1237 const char* surface_names[] = {
"Welcome",
"Dashboard",
"Editor"};
1238 LOG_INFO(
"UICoordinator",
"Startup surface: %s -> %s",
1239 surface_names[
static_cast<int>(old_surface)],
1240 surface_names[
static_cast<int>(surface)]);
1297 if (!current_rom || !current_rom->is_loaded()) {
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
The EditorManager controls the main editor window and manages the various editor classes.
void SaveWorkspacePreset(const std::string &name)
float GetRightLayoutOffset() const
void SwitchToSession(size_t index)
WorkspaceManager * workspace_manager()
void LoadWorkspacePreset(const std::string &name)
absl::Status CreateNewProject(const std::string &template_name="Basic ROM Hack")
void RefreshWorkspacePresets()
auto GetCurrentEditor() const -> Editor *
absl::Status LoadRom()
Load a ROM file into a new or existing session.
auto GetCurrentRom() const -> Rom *
absl::Status OpenRomOrProject(const std::string &filename)
float GetLeftLayoutOffset() const
RightPanelManager * right_panel_manager()
Manages editor types, categories, and lifecycle.
static std::string GetEditorCategory(EditorType type)
Central registry for all editor cards with session awareness and dependency injection.
void ToggleSidebarVisibility()
bool ShowPanel(size_t session_id, const std::string &base_card_id)
bool IsPanelVisible(size_t session_id, const std::string &base_card_id) const
bool IsSidebarVisible() const
void SetSidebarVisible(bool visible)
bool HidePanel(size_t session_id, const std::string &base_card_id)
void HideAllPanelsInCategory(size_t session_id, const std::string &category)
Handles all project file operations with ROM-first workflow.
float GetPanelWidth() const
Get the width of the panel when expanded.
bool IsPanelExpanded() const
Check if any panel is currently expanded.
bool DrawPanelToggleButtons()
Draw toggle buttons for the status cluster.
bool IsPanelActive(PanelType type) const
Check if a specific panel is active.
Handles all ROM file I/O operations.
High-level orchestrator for multi-session UI.
void * GetSession(size_t index) const
bool IsSessionSwitcherVisible() const
size_t GetActiveSessionIndex() const
size_t GetActiveSessionCount() const
void HideSessionSwitcher()
std::string GetSessionDisplayName(size_t index) const
void ShowSessionSwitcher()
size_t GetTotalSessionCount() const
bool IsSessionClosed(size_t index) const
bool HasMultipleSessions() const
auto GetShortcuts() const
size_t GetUnreadCount() const
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f)
ShortcutManager & shortcut_manager_
void DrawMaterialButton(const std::string &text, const std::string &icon, const ImVec4 &color, std::function< void()> callback, bool enabled=true)
void SetPanelSidebarVisible(bool visible)
bool show_save_workspace_preset_
void SetSessionSwitcherVisible(bool visible)
void SetGlobalSearchVisible(bool visible)
void HidePopup(const std::string &popup_name)
void SetStartupSurface(StartupSurface surface)
SessionCoordinator & session_coordinator_
char global_search_query_[256]
UICoordinator(EditorManager *editor_manager, RomFileManager &rom_manager, ProjectManager &project_manager, EditorRegistry &editor_registry, PanelManager &card_registry, SessionCoordinator &session_coordinator, WindowDelegate &window_delegate, ToastManager &toast_manager, PopupManager &popup_manager, ShortcutManager &shortcut_manager)
bool IsEmulatorVisible() const
void ShowSessionSwitcher()
ToastManager & toast_manager_
void DrawWorkspacePresetDialogs()
void SetEmulatorVisible(bool visible)
char command_palette_query_[256]
bool ShouldShowActivityBar() const
void DrawNotificationBell(bool show_dirty, bool has_dirty_rom, bool show_session, bool has_multiple_sessions)
bool show_command_palette_
bool IsPanelSidebarVisible() const
void HideCurrentEditorPanels()
WindowDelegate & window_delegate_
bool DrawMenuBarIconButton(const char *icon, const char *tooltip, bool is_active=false)
bool ShouldShowDashboard() const
void ShowPopup(const std::string &popup_name)
void TogglePanelSidebar()
StartupVisibility welcome_behavior_override_
bool welcome_screen_manually_closed_
StartupVisibility dashboard_behavior_override_
StartupSurface current_startup_surface_
PopupManager & popup_manager_
void DrawWindowManagementUI()
void PositionWindow(const std::string &window_name, float x, float y)
void SetWindowSize(const std::string &window_name, float width, float height)
void ShowDisplaySettings()
void SetWelcomeScreenBehavior(StartupVisibility mode)
bool show_editor_selection_
bool show_welcome_screen_
PanelManager & panel_manager_
EditorManager * editor_manager_
void SetDashboardBehavior(StartupVisibility mode)
bool IsSessionSwitcherVisible() const
std::unique_ptr< WelcomeScreen > welcome_screen_
static float GetMenuBarIconButtonWidth()
bool show_load_workspace_preset_
void DrawMenuBarRestoreButton()
int command_palette_selected_idx_
bool ShouldShowWelcome() const
void DrawCommandPalette()
EditorRegistry & editor_registry_
void CenterWindow(const std::string &window_name)
Low-level window operations with minimal dependencies.
static BackgroundRenderer & Get()
static void EndTableWithTheming()
static bool BeginTableWithTheming(const char *str_id, int columns, ImGuiTableFlags flags=0, const ImVec2 &outer_size=ImVec2(0, 0), float inner_width=0.0f)
const Theme & GetCurrentTheme() const
static ThemeManager & Get()
static RecentFilesManager & GetInstance()
#define ICON_MD_NOTIFICATIONS
#define ICON_MD_FULLSCREEN_EXIT
#define ICON_MD_EXPAND_LESS
#define ICON_MD_VIDEOGAME_ASSET
#define ICON_MD_MANAGE_SEARCH
#define ICON_MD_DESCRIPTION
#define ICON_MD_FIBER_MANUAL_RECORD
#define LOG_ERROR(category, format,...)
#define LOG_INFO(category, format,...)
StartupSurface
Represents the current startup surface state.
std::string PrintShortcut(const std::vector< ImGuiKey > &keys)
ImVec4 ConvertColorToImVec4(const Color &color)
ImVec4 GetSurfaceContainerHighestVec4()
ImVec4 GetTextDisabledVec4()
ImVec4 GetTextSecondaryVec4()
ImVec4 GetSurfaceContainerHighVec4()
constexpr ImVec2 kDefaultModalSize
ImVec4 GetOnSurfaceVariantVec4()
ImVec4 GetSurfaceContainerVec4()
std::string GetFileName(const std::string &filename)
Gets the filename from a full path.
std::string GetFileExtension(const std::string &filename)
Gets the file extension from a filename.
StartupVisibility
Tri-state toggle used for startup UI visibility controls.
Represents a single session, containing a ROM and its associated editors.