[olympic/studio] Fix several crashes
This commit is contained in:
parent
2167a46266
commit
db961739ad
@ -53,7 +53,7 @@ static ox::Error runApp(
|
||||
turbine::setConstantRefresh(*ctx, false);
|
||||
studio::StudioContext studioCtx;
|
||||
turbine::setApplicationData(*ctx, &studioCtx);
|
||||
StudioUI ui(ctx.get(), projectDataDir);
|
||||
StudioUI ui(*ctx, projectDataDir);
|
||||
studioCtx.ui = &ui;
|
||||
StudioUIDrawer drawer(ui);
|
||||
turbine::gl::addDrawer(*ctx, &drawer);
|
||||
|
@ -15,7 +15,12 @@
|
||||
|
||||
namespace studio {
|
||||
|
||||
ox::Vector<const studio::Module*> modules;
|
||||
static ox::Vector<const studio::Module*> modules;
|
||||
|
||||
void registerModule(studio::Module const*mod) noexcept {
|
||||
modules.emplace_back(mod);
|
||||
}
|
||||
|
||||
|
||||
struct StudioConfig {
|
||||
static constexpr auto TypeName = "net.drinkingtea.studio.StudioConfig";
|
||||
@ -33,23 +38,25 @@ oxModelBegin(StudioConfig)
|
||||
oxModelFieldRename(show_project_explorer, showProjectExplorer)
|
||||
oxModelEnd()
|
||||
|
||||
StudioUI::StudioUI(turbine::Context *ctx, ox::StringView projectDir) noexcept:
|
||||
m_ctx(*ctx),
|
||||
m_projectDir(projectDir),
|
||||
m_projectExplorer(ox::make_unique<ProjectExplorer>(m_ctx)),
|
||||
m_aboutPopup(*ctx) {
|
||||
StudioUI::StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcept:
|
||||
m_ctx(ctx),
|
||||
m_projectDataDir(projectDataDir),
|
||||
m_projectExplorer(ox::make_unique<ProjectExplorer>(m_ctx)),
|
||||
m_aboutPopup(m_ctx) {
|
||||
m_projectExplorer->fileChosen.connect(this, &StudioUI::openFile);
|
||||
ImGui::GetIO().IniFilename = nullptr;
|
||||
loadModules();
|
||||
// open project and files
|
||||
const auto [config, err] = studio::readConfig<StudioConfig>(keelCtx(*ctx));
|
||||
auto const [config, err] = studio::readConfig<StudioConfig>(keelCtx(m_ctx));
|
||||
m_showProjectExplorer = config.showProjectExplorer;
|
||||
if (!err) {
|
||||
oxIgnoreError(openProject(config.projectPath));
|
||||
for (const auto &f : config.openFiles) {
|
||||
auto openFileErr = openFileActiveTab(f, config.activeTabItemName == f);
|
||||
if (openFileErr) {
|
||||
oxErrorf("\nCould not open editor for file:\n\t{}\nReason:\n\t{}\n", f, toStr(openFileErr));
|
||||
auto const openProjErr = openProject(config.projectPath);
|
||||
if (!openProjErr) {
|
||||
for (const auto &f: config.openFiles) {
|
||||
auto openFileErr = openFileActiveTab(f, config.activeTabItemName == f);
|
||||
if (openFileErr) {
|
||||
oxErrorf("\nCould not open editor for file:\n\t{}\nReason:\n\t{}\n", f, toStr(openFileErr));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -83,7 +90,9 @@ void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept {
|
||||
toggleProjectExplorer();
|
||||
break;
|
||||
case turbine::Key::Alpha_C:
|
||||
m_activeEditor->copy();
|
||||
if (m_activeEditor && m_activeEditor->copyEnabled()) {
|
||||
m_activeEditor->copy();
|
||||
}
|
||||
break;
|
||||
case turbine::Key::Alpha_N:
|
||||
m_newMenu.open();
|
||||
@ -98,10 +107,14 @@ void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept {
|
||||
save();
|
||||
break;
|
||||
case turbine::Key::Alpha_V:
|
||||
m_activeEditor->paste();
|
||||
if (m_activeEditor && m_activeEditor->pasteEnabled()) {
|
||||
m_activeEditor->paste();
|
||||
}
|
||||
break;
|
||||
case turbine::Key::Alpha_X:
|
||||
m_activeEditor->cut();
|
||||
if (m_activeEditor && m_activeEditor->cutEnabled()) {
|
||||
m_activeEditor->cut();
|
||||
}
|
||||
break;
|
||||
case turbine::Key::Alpha_Y:
|
||||
redo();
|
||||
@ -169,19 +182,19 @@ void StudioUI::drawMenu() noexcept {
|
||||
if (ImGui::BeginMenu("Edit")) {
|
||||
auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
|
||||
if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack && undoStack->canUndo())) {
|
||||
m_activeEditor->undoStack()->undo();
|
||||
undoStack->undo();
|
||||
}
|
||||
if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack && undoStack->canRedo())) {
|
||||
m_activeEditor->undoStack()->redo();
|
||||
undoStack->redo();
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
|
||||
if (ImGui::MenuItem("Copy", "Ctrl+C", false, m_activeEditor && m_activeEditor->copyEnabled())) {
|
||||
m_activeEditor->copy();
|
||||
}
|
||||
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
|
||||
if (ImGui::MenuItem("Cut", "Ctrl+X", false, m_activeEditor && m_activeEditor->cutEnabled())) {
|
||||
m_activeEditor->cut();
|
||||
}
|
||||
if (ImGui::MenuItem("Paste", "Ctrl+V")) {
|
||||
if (ImGui::MenuItem("Paste", "Ctrl+V", false, m_activeEditor && m_activeEditor->pasteEnabled()) && m_activeEditor) {
|
||||
m_activeEditor->paste();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
@ -240,6 +253,9 @@ void StudioUI::drawTabs() noexcept {
|
||||
}
|
||||
if (!open) {
|
||||
e->close();
|
||||
if (m_activeEditor == (*it).get()) {
|
||||
m_activeEditor = nullptr;
|
||||
}
|
||||
try {
|
||||
oxThrowError(m_editors.erase(it).moveTo(&it));
|
||||
} catch (const ox::Exception &ex) {
|
||||
@ -305,7 +321,7 @@ ox::Error StudioUI::openProject(ox::CRStringView path) noexcept {
|
||||
oxRequireM(fs, keel::loadRomFs(path));
|
||||
oxReturnError(keel::setRomFs(keelCtx(m_ctx), std::move(fs)));
|
||||
turbine::setWindowTitle(m_ctx, ox::sfmt("{} - {}", keelCtx(m_ctx).appName, path));
|
||||
m_project = ox::make_unique<studio::Project>(keelCtx(m_ctx), ox::String(path), m_projectDir);
|
||||
m_project = ox::make_unique<studio::Project>(keelCtx(m_ctx), ox::String(path), m_projectDataDir);
|
||||
auto sctx = applicationData<studio::StudioContext>(m_ctx);
|
||||
sctx->project = m_project.get();
|
||||
m_project->fileAdded.connect(m_projectExplorer.get(), &ProjectExplorer::refreshProjectTreeModel);
|
||||
@ -324,6 +340,9 @@ ox::Error StudioUI::openFile(ox::CRStringView path) noexcept {
|
||||
}
|
||||
|
||||
ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab) noexcept {
|
||||
if (!m_project) {
|
||||
return OxError(1, "No project open to open a file from");
|
||||
}
|
||||
if (m_openFiles.contains(path)) {
|
||||
for (auto &e : m_editors) {
|
||||
if (makeActiveTab && e->itemPath() == path) {
|
||||
@ -332,7 +351,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
oxRequire(ext, studio::fileExt(path).to<ox::String>([](auto const&v) {return ox::String(v);}));
|
||||
// create Editor
|
||||
@ -372,18 +391,14 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
|
||||
|
||||
ox::Error StudioUI::closeFile(ox::CRStringView path) noexcept {
|
||||
if (!m_openFiles.contains(path)) {
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
oxIgnoreError(m_openFiles.erase(std::remove(m_openFiles.begin(), m_openFiles.end(), path)));
|
||||
// save to config
|
||||
studio::editConfig<StudioConfig>(keelCtx(m_ctx), [&](StudioConfig *config) {
|
||||
oxIgnoreError(config->openFiles.erase(std::remove(config->openFiles.begin(), config->openFiles.end(), path)));
|
||||
});
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
void registerModule(const studio::Module *mod) noexcept {
|
||||
modules.emplace_back(mod);
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,27 +24,27 @@ class StudioUI: public ox::SignalHandler {
|
||||
|
||||
private:
|
||||
turbine::Context &m_ctx;
|
||||
ox::String m_projectDir;
|
||||
ox::UniquePtr<studio::Project> m_project;
|
||||
ox::String m_projectDataDir;
|
||||
ox::UPtr<studio::Project> m_project;
|
||||
studio::TaskRunner m_taskRunner;
|
||||
ox::Vector<ox::UniquePtr<studio::BaseEditor>> m_editors;
|
||||
ox::Vector<ox::UniquePtr<studio::Widget>> m_widgets;
|
||||
ox::Vector<ox::UPtr<studio::BaseEditor>> m_editors;
|
||||
ox::Vector<ox::UPtr<studio::Widget>> m_widgets;
|
||||
ox::HashMap<ox::String, studio::EditorMaker::Func> m_editorMakers;
|
||||
ox::UniquePtr<ProjectExplorer> m_projectExplorer;
|
||||
ox::UPtr<ProjectExplorer> m_projectExplorer;
|
||||
ox::Vector<ox::String> m_openFiles;
|
||||
studio::BaseEditor *m_activeEditorOnLastDraw = nullptr;
|
||||
studio::BaseEditor *m_activeEditor = nullptr;
|
||||
studio::BaseEditor *m_activeEditorUpdatePending = nullptr;
|
||||
NewMenu m_newMenu;
|
||||
AboutPopup m_aboutPopup;
|
||||
const ox::Array<studio::Popup*, 2> m_popups = {
|
||||
ox::Array<studio::Popup*, 2> const m_popups = {
|
||||
&m_newMenu,
|
||||
&m_aboutPopup
|
||||
};
|
||||
bool m_showProjectExplorer = true;
|
||||
|
||||
public:
|
||||
explicit StudioUI(turbine::Context *ctx, ox::StringView projectDir) noexcept;
|
||||
explicit StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcept;
|
||||
|
||||
void update() noexcept;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user