Enhance EditorManager UI with detailed ROM and session information

- Updated the ROM status display to include a clickable button that opens a detailed popup with metadata.
- Improved tooltips for ROM information, providing enhanced visibility on hover.
- Redesigned the session switcher and manager to include session metadata and improved styling for better user experience.
- Added animated background effects and enhanced button styles on the welcome screen for a more engaging interface.
This commit is contained in:
scawful
2025-09-26 17:47:51 -04:00
parent 9e3a5778aa
commit d21df011ae

View File

@@ -935,7 +935,7 @@ void EditorManager::DrawMenuBar() {
SameLine();
}
// ROM status with natural integration
// Enhanced ROM status with metadata popup
if (current_rom_ && current_rom_->is_loaded()) {
std::string rom_display = current_rom_->title();
if (rom_display.length() > 16) {
@@ -946,18 +946,92 @@ void EditorManager::DrawMenuBar() {
ImVec4(1.0f, 0.5f, 0.0f, 1.0f) : // Orange for modified
ImVec4(0.0f, 0.8f, 0.0f, 1.0f); // Green for clean
TextColored(status_color, "%s %s%s",
ICON_MD_STORAGE,
rom_display.c_str(),
current_rom_->dirty() ? "*" : "");
if (IsItemHovered()) {
SetTooltip("ROM: %s\nFile: %s\nSize: %zu bytes\nStatus: %s",
current_rom_->title().c_str(),
current_rom_->filename().c_str(),
current_rom_->size(),
current_rom_->dirty() ? "Modified" : "Clean");
// Make ROM status clickable for detailed popup
if (SmallButton(absl::StrFormat("%s %s%s",
ICON_MD_STORAGE,
rom_display.c_str(),
current_rom_->dirty() ? "*" : "").c_str())) {
ImGui::OpenPopup("ROM Details");
}
// Enhanced tooltip on hover
if (IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("%s ROM Information", ICON_MD_INFO);
ImGui::Separator();
ImGui::Text("%s Title: %s", ICON_MD_TITLE, current_rom_->title().c_str());
ImGui::Text("%s File: %s", ICON_MD_FOLDER_OPEN, current_rom_->filename().c_str());
ImGui::Text("%s Size: %.1f MB (%zu bytes)", ICON_MD_STORAGE,
current_rom_->size() / 1048576.0f, current_rom_->size());
ImGui::Text("%s Status: %s", current_rom_->dirty() ? ICON_MD_EDIT : ICON_MD_CHECK_CIRCLE,
current_rom_->dirty() ? "Modified" : "Clean");
ImGui::Text("%s Click for detailed view", ICON_MD_LAUNCH);
ImGui::EndTooltip();
}
// Detailed ROM popup
if (ImGui::BeginPopup("ROM Details")) {
ImGui::Text("%s ROM Detailed Information", ICON_MD_INFO);
ImGui::Separator();
ImGui::Spacing();
// Basic info with icons
if (ImGui::BeginTable("ROMDetailsTable", 2, ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("Property", ImGuiTableColumnFlags_WidthFixed, 120);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Title", ICON_MD_TITLE);
ImGui::TableNextColumn();
ImGui::Text("%s", current_rom_->title().c_str());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s File", ICON_MD_FOLDER_OPEN);
ImGui::TableNextColumn();
ImGui::Text("%s", current_rom_->filename().c_str());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Size", ICON_MD_STORAGE);
ImGui::TableNextColumn();
ImGui::Text("%.1f MB (%zu bytes)", current_rom_->size() / 1048576.0f, current_rom_->size());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Status", current_rom_->dirty() ? ICON_MD_EDIT : ICON_MD_CHECK_CIRCLE);
ImGui::TableNextColumn();
ImGui::TextColored(status_color, "%s", current_rom_->dirty() ? "Modified" : "Clean");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Session", ICON_MD_TAB);
ImGui::TableNextColumn();
size_t current_session_idx = GetCurrentSessionIndex();
ImGui::Text("Session %zu of %zu", current_session_idx + 1, sessions_.size());
ImGui::EndTable();
}
ImGui::Spacing();
ImGui::Separator();
// Quick actions
ImGui::Text("%s Quick Actions", ICON_MD_FLASH_ON);
if (ImGui::Button(absl::StrFormat("%s Save ROM", ICON_MD_SAVE).c_str(), ImVec2(120, 0))) {
status_ = SaveRom();
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button(absl::StrFormat("%s Switch Session", ICON_MD_SWITCH_ACCOUNT).c_str(), ImVec2(120, 0))) {
show_session_switcher_ = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
SameLine();
} else {
TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "%s No ROM", ICON_MD_HELP_OUTLINE);
@@ -1600,51 +1674,123 @@ void EditorManager::DrawSessionSwitcher() {
if (!show_session_switcher_) return;
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_Appearing);
ImGui::SetNextWindowSize(ImVec2(500, 350), ImGuiCond_Appearing);
if (ImGui::Begin(absl::StrCat(ICON_MD_SWITCH_ACCOUNT, " Session Switcher").c_str(),
if (ImGui::Begin(absl::StrFormat("%s Session Switcher", ICON_MD_SWITCH_ACCOUNT).c_str(),
&show_session_switcher_, ImGuiWindowFlags_NoCollapse)) {
// Header with enhanced info
ImGui::Text("%s %zu Sessions Available", ICON_MD_TAB, sessions_.size());
ImGui::SameLine(ImGui::GetWindowWidth() - 120);
if (ImGui::Button(absl::StrFormat("%s New", ICON_MD_ADD).c_str(), ImVec2(50, 0))) {
CreateNewSession();
}
ImGui::SameLine();
if (ImGui::Button(absl::StrFormat("%s Manager", ICON_MD_SETTINGS).c_str(), ImVec2(60, 0))) {
show_session_manager_ = true;
}
ImGui::Separator();
// Enhanced session list with metadata
for (size_t i = 0; i < sessions_.size(); ++i) {
auto& session = sessions_[i];
bool is_current = (&session.rom == current_rom_);
ImGui::PushID(static_cast<int>(i));
// Session card with background
ImVec2 button_size = ImVec2(-1, 70);
if (is_current) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.7f, 0.3f, 0.3f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.2f, 0.7f, 0.3f, 0.4f));
} else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.1f, 0.1f, 0.2f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.3f, 0.3f, 0.3f));
}
std::string session_name = session.GetDisplayName();
if (ImGui::Button(absl::StrFormat("%s %s %s",
ICON_MD_STORAGE,
session_name.c_str(),
is_current ? "(Current)" : "").c_str(),
ImVec2(-1, 0))) {
if (ImGui::Button("##session_card", button_size)) {
if (!is_current) {
SwitchToSession(i);
show_session_switcher_ = false;
}
}
ImGui::PopStyleColor(2);
if (is_current) {
ImGui::PopStyleColor();
// Session content overlay
ImVec2 button_min = ImGui::GetItemRectMin();
ImVec2 button_max = ImGui::GetItemRectMax();
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Session icon and name
ImVec2 text_pos = ImVec2(button_min.x + 10, button_min.y + 8);
std::string session_display = session.GetDisplayName();
if (session_display.length() > 25) {
session_display = session_display.substr(0, 22) + "...";
}
// Show ROM info on hover
if (ImGui::IsItemHovered() && session.rom.is_loaded()) {
ImGui::BeginTooltip();
ImGui::Text("File: %s", session.rom.filename().c_str());
ImGui::Text("Size: %zu bytes", session.rom.size());
ImGui::Text("Modified: %s", session.rom.dirty() ? "Yes" : "No");
ImGui::EndTooltip();
ImU32 text_color = is_current ? IM_COL32(255, 255, 255, 255) : IM_COL32(220, 220, 220, 255);
draw_list->AddText(text_pos, text_color,
absl::StrFormat("%s %s %s",
ICON_MD_STORAGE,
session_display.c_str(),
is_current ? "(Current)" : "").c_str());
// ROM metadata
if (session.rom.is_loaded()) {
ImVec2 metadata_pos = ImVec2(button_min.x + 10, button_min.y + 28);
std::string rom_info = absl::StrFormat("%s %s | %.1f MB | %s",
ICON_MD_VIDEOGAME_ASSET,
session.rom.title().c_str(),
session.rom.size() / 1048576.0f,
session.rom.dirty() ? "Modified" : "Clean");
if (rom_info.length() > 40) {
rom_info = rom_info.substr(0, 37) + "...";
}
draw_list->AddText(metadata_pos, IM_COL32(180, 180, 180, 255), rom_info.c_str());
} else {
ImVec2 metadata_pos = ImVec2(button_min.x + 10, button_min.y + 28);
draw_list->AddText(metadata_pos, IM_COL32(150, 150, 150, 255),
absl::StrFormat("%s No ROM loaded", ICON_MD_WARNING).c_str());
}
// Action buttons on the right
ImVec2 rename_pos = ImVec2(button_max.x - 90, button_min.y + 5);
ImVec2 close_pos = ImVec2(button_max.x - 45, button_min.y + 5);
ImGui::SetCursorScreenPos(rename_pos);
if (ImGui::SmallButton(absl::StrFormat("%s##rename_%zu", ICON_MD_EDIT, i).c_str())) {
session_to_rename_ = i;
strncpy(session_rename_buffer_, session.GetDisplayName().c_str(), sizeof(session_rename_buffer_) - 1);
show_session_rename_dialog_ = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Rename Session");
}
ImGui::SetCursorScreenPos(close_pos);
if (sessions_.size() > 1) {
if (ImGui::SmallButton(absl::StrFormat("%s##close_%zu", ICON_MD_CLOSE, i).c_str())) {
if (is_current) {
CloseCurrentSession();
} else {
// Switch to this session first, then close it
SwitchToSession(i);
CloseCurrentSession();
}
break; // Exit the loop since session structure changed
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Close Session");
}
}
ImGui::PopID();
ImGui::Spacing();
}
ImGui::Separator();
if (ImGui::Button(absl::StrCat(ICON_MD_CLOSE, " Close").c_str(), ImVec2(-1, 0))) {
if (ImGui::Button(absl::StrFormat("%s Close Switcher", ICON_MD_CLOSE).c_str(), ImVec2(-1, 0))) {
show_session_switcher_ = false;
}
}
@@ -1670,12 +1816,13 @@ void EditorManager::DrawSessionManager() {
ImGui::Separator();
ImGui::Text("%s Active Sessions (%zu)", ICON_MD_TAB, sessions_.size());
// Session list with controls
if (ImGui::BeginTable("SessionTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Session", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("ROM", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed, 80);
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 120);
// Session list with controls (improved sizing)
if (ImGui::BeginTable("SessionTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupColumn("Session", ImGuiTableColumnFlags_WidthStretch, 120.0f);
ImGui::TableSetupColumn("ROM", ImGuiTableColumnFlags_WidthStretch, 200.0f);
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed, 90.0f);
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 200.0f);
ImGui::TableHeadersRow();
for (size_t i = 0; i < sessions_.size(); ++i) {
@@ -1881,15 +2028,72 @@ void EditorManager::DrawSessionRenameDialog() {
void EditorManager::DrawWelcomeScreen() {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(680, 500), ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(750, 550), ImGuiCond_Always);
// Create a subtle animated background effect
static float animation_time = 0.0f;
animation_time += ImGui::GetIO().DeltaTime;
ImGuiWindowFlags flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar;
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoBackground;
if (ImGui::Begin("Welcome to Yaze", nullptr, flags)) {
// Header (reuse homepage style)
TextWrapped("Welcome to the Yet Another Zelda3 Editor (yaze)!");
TextWrapped("The Legend of Zelda: A Link to the Past.");
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 window_pos = ImGui::GetWindowPos();
ImVec2 window_size = ImGui::GetWindowSize();
// Draw animated gradient background
ImU32 bg_color_top = IM_COL32(25, 35, 50, 240);
ImU32 bg_color_bottom = IM_COL32(15, 25, 40, 240);
draw_list->AddRectFilledMultiColor(
window_pos,
ImVec2(window_pos.x + window_size.x, window_pos.y + window_size.y),
bg_color_top, bg_color_top, bg_color_bottom, bg_color_bottom);
// Animated border with gradient effect
float border_thickness = 3.0f;
float pulse = 0.8f + 0.2f * sinf(animation_time * 2.0f);
ImU32 border_color = IM_COL32(70, 130, 200, (int)(255 * pulse));
draw_list->AddRect(window_pos,
ImVec2(window_pos.x + window_size.x, window_pos.y + window_size.y),
border_color, 12.0f, 0, border_thickness);
// Subtle floating particles effect
for (int i = 0; i < 8; ++i) {
float offset_x = sinf(animation_time * 0.5f + i * 0.8f) * 20.0f;
float offset_y = cosf(animation_time * 0.3f + i * 1.2f) * 15.0f;
ImVec2 particle_pos = ImVec2(
window_pos.x + 50 + (i * 80) + offset_x,
window_pos.y + 100 + offset_y);
float alpha = 0.3f + 0.2f * sinf(animation_time * 1.5f + i);
ImU32 particle_color = IM_COL32(100, 150, 255, (int)(alpha * 100));
draw_list->AddCircleFilled(particle_pos, 2.0f + sinf(animation_time + i) * 0.5f, particle_color);
}
// Header with enhanced styling
ImGui::Spacing();
ImGui::SetCursorPosX((window_size.x - ImGui::CalcTextSize("Welcome to Yet Another Zelda3 Editor").x) * 0.5f);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.9f, 0.95f, 1.0f, 1.0f));
ImGui::Text("Welcome to Yet Another Zelda3 Editor");
ImGui::PopStyleColor();
ImGui::SetCursorPosX((window_size.x - ImGui::CalcTextSize("The Legend of Zelda: A Link to the Past").x) * 0.5f);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 0.8f, 0.9f, 0.9f));
ImGui::Text("The Legend of Zelda: A Link to the Past");
ImGui::PopStyleColor();
ImGui::Spacing();
// Decorative line with glow effect
ImVec2 line_start = ImVec2(window_pos.x + 50, window_pos.y + 120);
ImVec2 line_end = ImVec2(window_pos.x + window_size.x - 50, window_pos.y + 120);
float glow_alpha = 0.5f + 0.3f * sinf(animation_time * 1.5f);
draw_list->AddLine(line_start, line_end, IM_COL32(100, 150, 255, (int)(glow_alpha * 255)), 2.0f);
ImGui::Spacing();
ImGui::Spacing();
// Show different messages based on state
if (!sessions_.empty() && !current_rom_) {
@@ -1906,18 +2110,23 @@ void EditorManager::DrawWelcomeScreen() {
ImGui::Spacing();
// Primary actions with material design icons
// Enhanced primary actions with glowing buttons
ImGui::Text("Get Started:");
ImGui::Spacing();
if (ImGui::Button(ICON_MD_FILE_OPEN " Open ROM File", ImVec2(180, 35))) {
// Stylish primary buttons with hover effects
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.5f, 0.9f, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.6f, 1.0f, 0.9f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.1f, 0.4f, 0.8f, 1.0f));
if (ImGui::Button(ICON_MD_FILE_OPEN " Open ROM File", ImVec2(200, 40))) {
status_ = LoadRom();
if (!status_.ok()) {
toast_manager_.Show(std::string(status_.message()), editor::ToastType::kError);
}
}
ImGui::SameLine();
if (ImGui::Button(ICON_MD_FOLDER_OPEN " Open Project", ImVec2(180, 35))) {
if (ImGui::Button(ICON_MD_FOLDER_OPEN " Open Project", ImVec2(200, 40))) {
auto file_name = core::FileDialogWrapper::ShowOpenFileDialog();
if (!file_name.empty()) {
status_ = OpenRomOrProject(file_name);
@@ -1927,6 +2136,8 @@ void EditorManager::DrawWelcomeScreen() {
}
}
ImGui::PopStyleColor(3);
ImGui::Spacing();
// Feature flags section (per-session)