[studio] Add Get Info file dialog
Some checks failed
Build / build (push) Failing after 1m9s

This commit is contained in:
2026-02-05 21:32:36 -06:00
parent 7848cbbbff
commit f8b2700ea7
7 changed files with 176 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ add_library(
font.cpp
popups/about.cpp
popups/deleteconfirmation.cpp
popups/fileinfo.cpp
popups/makecopy.cpp
popups/newdir.cpp
popups/newmenu.cpp

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include "fileinfo.hpp"
namespace studio {
FileInfo::FileInfo(Context &sctx) noexcept:
Popup("File Info"),
m_sctx(sctx) {}
ox::Error FileInfo::open(ox::StringParam filePath) noexcept {
m_filePath = std::move(filePath);
auto &fs = m_sctx.project->romFs();
auto const fileBuff = fs.read(m_filePath).or_value({});
auto hdr = keel::readAssetHeader(fileBuff).or_value({});
m_fileInfo.id = hdr.uuid.toString();
m_fileInfo.typeName = std::move(hdr.clawHdr.typeName);
m_fileInfo.typeVersion = hdr.clawHdr.typeVersion;
m_fileInfo.format = [&hdr] {
switch (hdr.clawHdr.fmt) {
case ox::ClawFormat::Metal:
return ox::StringLiteral{"Metal Claw"};
case ox::ClawFormat::Organic:
return ox::StringLiteral{"Organic Claw"};
default:
return ox::StringLiteral{"Other"};
}
}();
m_fileInfo.dataSize = hdr.clawHdr.dataSize;
Popup::open();
return {};
}
void FileInfo::draw(Context &sctx) noexcept {
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
close();
return;
}
switch (m_stage) {
case Stage::Closed:
break;
case Stage::Opening:
ImGui::OpenPopup(m_title.c_str());
m_stage = Stage::Open;
[[fallthrough]];
case Stage::Open: {
constexpr auto modalFlags =
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
ig::centerNextWindow(sctx.tctx);
auto open = true;
if (ImGui::BeginPopupModal(m_title.c_str(), &open, modalFlags)) {
drawTable();
switch (auto const r = ig::PopupControlsOk(m_open, "Close")) {
case ig::PopupResponse::None:
break;
case ig::PopupResponse::OK:
response.emit(r);
close();
break;
case ig::PopupResponse::Cancel:
break;
}
ImGui::EndPopup();
}
if (!open) {
m_stage = Stage::Closed;
}
break;
}
}
}
void FileInfo::drawTable() const noexcept {
ig::IDStackItem const idStackItem{"FileInfo"};
ImGui::Text("%s", m_filePath.c_str());
if (ImGui::BeginTable(
"Table", 2,
ImGuiTableFlags_Borders |
ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_NoHide);
// id
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("ID:");
ImGui::TableSetColumnIndex(1);
ImGui::Text("%s", m_fileInfo.id.c_str());
// typeName
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("Type Name:");
ImGui::TableSetColumnIndex(1);
ImGui::Text("%s", m_fileInfo.typeName.c_str());
// typeVersion
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("Type Version:");
ImGui::TableSetColumnIndex(1);
ImGui::Text("%d", m_fileInfo.typeVersion);
// format
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("Format:");
ImGui::TableSetColumnIndex(1);
ImGui::Text("%s", m_fileInfo.format.c_str());
// size
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("Data Size:");
ImGui::TableSetColumnIndex(1);
ImGui::Text("%lluB", m_fileInfo.dataSize);
ImGui::EndTable();
}
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/std/string.hpp>
#include <studio/context.hpp>
#include <studio/imguiutil.hpp>
namespace studio {
class FileInfo: public ig::Popup {
private:
Context &m_sctx;
ox::String m_filePath;
struct {
ox::UUIDStr id;
ox::String typeName;
int typeVersion{};
ox::StringLiteral format;
size_t dataSize{};
} m_fileInfo;
public:
explicit FileInfo(Context &sctx) noexcept;
ox::Error open(ox::StringParam filePath) noexcept;
void draw(Context &sctx) noexcept override;
private:
void drawTable() const noexcept;
};
}

View File

@@ -36,6 +36,13 @@ void ProjectExplorer::dirMoved(ox::StringViewCR src, ox::StringViewCR dst) const
void ProjectExplorer::fileContextMenu(ox::StringViewCR path) const noexcept {
if (ImGui::BeginPopupContextItem("FileMenu", ImGuiPopupFlags_MouseButtonRight)) {
if (ImGui::MenuItem("Open")) {
fileChosen.emit(path);
}
if (ImGui::MenuItem("Get Info")) {
getInfo.emit(path);
}
ImGui::Separator();
if (ImGui::MenuItem("Delete")) {
deleteItem.emit(path);
}

View File

@@ -21,6 +21,7 @@ class ProjectExplorer final: public FileExplorer {
ox::Signal<ox::Error(ox::StringViewCR)> deleteItem;
ox::Signal<ox::Error(ox::StringViewCR)> renameItem;
ox::Signal<ox::Error(ox::StringViewCR)> makeCopy;
ox::Signal<ox::Error(ox::StringViewCR)> getInfo;
ox::Signal<ox::Error(ox::StringViewCR src, ox::StringViewCR dst)> moveDir;
ox::Signal<ox::Error(ox::StringViewCR src, ox::StringViewCR dst)> moveItem;

View File

@@ -146,6 +146,7 @@ StudioUI::StudioUI(turbine::Context &tctx, ox::StringParam projectDataDir) noexc
m_projectExplorer.addDir.connect(this, &StudioUI::addDir);
m_projectExplorer.addItem.connect(this, &StudioUI::addFile);
m_projectExplorer.deleteItem.connect(this, &StudioUI::deleteFile);
m_projectExplorer.getInfo.connect(this, &StudioUI::getFileInfo);
m_projectExplorer.renameItem.connect(this, &StudioUI::renameFile);
m_projectExplorer.makeCopy.connect(this, &StudioUI::makeCopyDlg);
m_projectExplorer.moveDir.connect(this, &StudioUI::queueDirMove);
@@ -569,6 +570,10 @@ ox::Error StudioUI::deleteFile(ox::StringViewCR path) noexcept {
return {};
}
ox::Error StudioUI::getFileInfo(ox::StringViewCR path) noexcept {
return m_fileInfo.open(path);
}
ox::Error StudioUI::renameFile(ox::StringViewCR path) noexcept {
return m_renameFile.openPath(path);
}

View File

@@ -21,6 +21,7 @@
#include "popups/newmenu.hpp"
#include "popups/newproject.hpp"
#include "projectexplorer.hpp"
#include "popups/fileinfo.hpp"
#include "popups/renamefile.hpp"
namespace studio {
@@ -48,6 +49,7 @@ class StudioUI final: public ox::SignalHandler {
NewMenu m_newMenu{keelCtx(m_tctx)};
AboutPopup m_aboutPopup{m_tctx};
DeleteConfirmation m_deleteConfirmation;
FileInfo m_fileInfo{m_sctx};
NewDir m_newDirDialog;
ig::QuestionPopup m_closeFileConfirm{"Close File?", "This file has unsaved changes. Close?"};
ig::QuestionPopup m_closeAppConfirm{
@@ -62,10 +64,11 @@ class StudioUI final: public ox::SignalHandler {
ig::QuestionPopup dlg{"Remove From Recents?", "Unable to load project. Remove from recent projects?"};
size_t idx{};
} m_removeRecentProject;
ox::Array<Widget*, 11> const m_widgets {
ox::Array<Widget*, 12> const m_widgets {
&m_closeFileConfirm,
&m_closeAppConfirm,
&m_copyFilePopup,
&m_fileInfo,
&m_newMenu,
&m_newProject,
&m_aboutPopup,
@@ -130,6 +133,8 @@ class StudioUI final: public ox::SignalHandler {
ox::Error deleteFile(ox::StringViewCR path) noexcept;
ox::Error getFileInfo(ox::StringViewCR path) noexcept;
ox::Error renameFile(ox::StringViewCR path) noexcept;
ox::Error handleMoveFile(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const &id) noexcept;