[nostalgia] Add NewMenu for creating new files

This commit is contained in:
2022-07-29 21:38:18 -05:00
parent b14e41d057
commit 275e9dbff1
31 changed files with 630 additions and 120 deletions

View File

@@ -2,8 +2,10 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(
nostalgia-studio MACOSX_BUNDLE
aboutpopup.cpp
filedialogmanager.cpp
main.cpp
newmenu.cpp
projectexplorer.cpp
projecttreemodel.cpp
studioapp.cpp

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <imgui.h>
#include "lib/imguiuitl.hpp"
#include "aboutpopup.hpp"
namespace nostalgia {
void AboutPopup::open() noexcept {
m_stage = Stage::Opening;
}
void AboutPopup::close() noexcept {
m_stage = Stage::Closed;
}
bool AboutPopup::isOpen() const noexcept {
return m_stage == Stage::Open;
}
void AboutPopup::draw(core::Context *ctx) noexcept {
switch (m_stage) {
case Stage::Closed:
break;
case Stage::Opening:
ImGui::OpenPopup("About");
m_stage = Stage::Open;
[[fallthrough]];
case Stage::Open: {
constexpr auto modalFlags =
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
ImGui::SetNextWindowSize(ImVec2(215, 90));
studio::ig::centerNextWindow(ctx);
auto open = true;
if (ImGui::BeginPopupModal("About", &open, modalFlags)) {
ImGui::Text("Nostalgia Studio - dev build");
ImGui::NewLine();
ImGui::Dummy(ImVec2(148.0f, 0.0f));
ImGui::SameLine();
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
open = false;
}
ImGui::EndPopup();
}
if (!open) {
m_stage = Stage::Closed;
}
break;
}
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/event/signal.hpp>
#include <ox/std/string.hpp>
#include <nostalgia/core/context.hpp>
#include "lib/popup.hpp"
namespace nostalgia {
class AboutPopup: public studio::Popup {
public:
enum class Stage {
Closed,
Opening,
Open,
};
private:
Stage m_stage = Stage::Closed;
public:
void open() noexcept override;
void close() noexcept override;
[[nodiscard]]
bool isOpen() const noexcept override;
void draw(core::Context *ctx) noexcept override;
};
}

View File

@@ -2,7 +2,9 @@ add_library(
NostalgiaStudio
configio.cpp
editor.cpp
imguiutil.cpp
module.cpp
popup.cpp
project.cpp
task.cpp
undostack.cpp
@@ -43,7 +45,9 @@ install(
context.hpp
editor.hpp
filedialog.hpp
itemmaker.hpp
module.hpp
popup.hpp
project.hpp
task.hpp
undostack.hpp

View File

@@ -36,7 +36,11 @@ void BaseEditor::save() noexcept {
if (!err) {
setUnsavedChanges(false);
} else {
oxErrorf("Could not save file {}: {}", itemName(), toStr(err));
if constexpr(ox::defines::Debug) {
oxErrorf("Could not save file {}: {} ({}:{})", itemName(), toStr(err), err.file, err.line);
} else {
oxErrorf("Could not save file {}: {}", itemName(), toStr(err));
}
}
}

View File

@@ -0,0 +1,13 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <imgui.h>
#include <nostalgia/core/core.hpp>
namespace nostalgia::studio::ig {
void centerNextWindow(core::Context *ctx) noexcept;
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <imgui.h>
#include <nostalgia/core/core.hpp>
namespace nostalgia::studio::ig {
void centerNextWindow(core::Context *ctx) noexcept {
const auto sz = core::getScreenSize(ctx);
const auto screenW = static_cast<float>(sz.width);
const auto screenH = static_cast<float>(sz.height);
const auto mod = ImGui::GetWindowDpiScale() * 2;
ImGui::SetNextWindowPos(ImVec2(screenW / mod, screenH / mod), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/claw/claw.hpp>
#include <nostalgia/core/context.hpp>
namespace nostalgia::studio {
class ItemMaker {
public:
const ox::String name;
const ox::String parentDir;
const ox::String fileExt;
constexpr explicit ItemMaker(ox::String pName, ox::String pParentDir, ox::String pFileExt) noexcept:
name(std::move(pName)),
parentDir(std::move(pParentDir)),
fileExt(std::move(pFileExt)) {
}
virtual ~ItemMaker() noexcept = default;
virtual ox::Error write(core::Context *ctx, const char *pName) const noexcept = 0;
};
template<typename T>
class ItemMakerT: public ItemMaker {
private:
const T item;
const ox::ClawFormat fmt;
public:
constexpr explicit ItemMakerT(ox::String pDisplayName, ox::String pParentDir, ox::String fileExt, ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept:
ItemMaker(std::move(pDisplayName), std::move(pParentDir), std::move(fileExt)),
fmt(pFmt) {
}
constexpr ItemMakerT(ox::String pDisplayName, ox::String pParentDir, ox::String fileExt, const T &pItem, ox::ClawFormat pFmt) noexcept:
ItemMaker(std::move(pDisplayName), std::move(pParentDir), std::move(fileExt)),
item(pItem),
fmt(pFmt) {
}
constexpr ItemMakerT(ox::String pDisplayName, ox::String pParentDir, T &&pItem, ox::ClawFormat pFmt) noexcept:
ItemMaker(std::move(pDisplayName), std::move(pParentDir), std::move(fileExt)),
item(std::forward(pItem)),
fmt(pFmt) {
}
ox::Error write(core::Context *ctx, const char *pName) const noexcept override {
const auto path = ox::sfmt("{}/{}.{}", parentDir, pName, fileExt);
auto sctx = core::applicationData<studio::StudioContext>(ctx);
return sctx->project->writeObj(path, &item, fmt);
}
};
}

View File

@@ -10,4 +10,8 @@ ox::Vector<EditorMaker> Module::editors(core::Context*) {
return {};
}
ox::Vector<ox::UniquePtr<ItemMaker>> Module::itemMakers(core::Context*) {
return {};
}
}

View File

@@ -9,10 +9,13 @@
#include <ox/std/string.hpp>
#include <ox/std/vector.hpp>
#include <nostalgia/studio/studio.hpp>
#include <nostalgia/core/context.hpp>
namespace nostalgia::studio {
class ItemMaker;
struct EditorMaker {
using Func = std::function<ox::Result<class BaseEditor*>(const ox::String&)>;
ox::Vector<ox::String> fileTypes;
@@ -25,6 +28,8 @@ class Module {
virtual ox::Vector<EditorMaker> editors(core::Context *ctx);
virtual ox::Vector<ox::UniquePtr<ItemMaker>> itemMakers(core::Context*);
};
}

View File

@@ -0,0 +1,9 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include "popup.hpp"
namespace nostalgia::studio {
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/event/signal.hpp>
#include <ox/std/string.hpp>
#include <nostalgia/geo/vec.hpp>
#include <nostalgia/core/context.hpp>
#include "imguiuitl.hpp"
namespace nostalgia::studio {
class Popup {
private:
geo::Vec2 m_size;
ox::String m_title;
public:
// emits path parameter
ox::Signal<ox::Error(const ox::String&)> finished;
virtual ~Popup() noexcept = default;
virtual void open() noexcept = 0;
virtual void close() noexcept = 0;
[[nodiscard]]
virtual bool isOpen() const noexcept = 0;
virtual void draw(core::Context *ctx) noexcept = 0;
protected:
constexpr void setSize(geo::Size sz) noexcept {
m_size = {static_cast<float>(sz.width), static_cast<float>(sz.height)};
}
constexpr void setTitle(ox::String title) noexcept {
m_title = std::move(title);
}
constexpr const ox::String &title() const noexcept {
return m_title;
}
void drawWindow(core::Context *ctx, bool *open, auto drawContents) {
studio::ig::centerNextWindow(ctx);
ImGui::SetNextWindowSize(static_cast<ImVec2>(m_size));
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
if (ImGui::BeginPopupModal(m_title.c_str(), open, modalFlags)) {
drawContents();
}
}
};
}

View File

@@ -11,16 +11,8 @@
namespace nostalgia::studio {
ox::String filePathToName(const ox::String &path, const ox::String &prefix, const ox::String &suffix) noexcept {
const auto begin = prefix.len();
const auto end = path.len() - (suffix.len() + prefix.len());
return path.substr(begin, end);
}
Project::Project(ox::FileSystem *fs, const ox::String &path) noexcept: m_typeStore(fs), m_fs(fs) {
oxTracef("nostalgia::studio", "Project: {}", path);
m_path = path;
Project::Project(ox::FileSystem *fs, ox::String path) noexcept: m_path(std::move(path)), m_typeStore(fs), m_fs(fs) {
oxTracef("nostalgia::studio", "Project: {}", m_path);
buildFileIndex();
}
@@ -71,8 +63,13 @@ void Project::buildFileIndex() noexcept {
}
ox::Error Project::writeBuff(const ox::String &path, const ox::Buffer &buff) const noexcept {
const auto newFile = m_fs->stat(path.c_str()).error != 0;
oxReturnError(m_fs->write(path.c_str(), buff.data(), buff.size()));
fileUpdated.emit(path);
if (newFile) {
fileAdded.emit(path);
} else {
fileUpdated.emit(path);
}
return OxError(0);
}

View File

@@ -37,9 +37,6 @@ constexpr ox::Result<ox::String> fileExt(const ox::String &path) noexcept {
return path.substr(extStart + 1);
}
[[nodiscard]]
ox::String filePathToName(const ox::String &path, const ox::String &prefix, const ox::String &suffix) noexcept;
class NOSTALGIASTUDIO_EXPORT Project {
private:
ox::String m_path;
@@ -48,7 +45,7 @@ class NOSTALGIASTUDIO_EXPORT Project {
ox::HashMap<ox::String, ox::Vector<ox::String>> m_fileExtFileMap;
public:
explicit Project(ox::FileSystem *fs, const ox::String &path) noexcept;
explicit Project(ox::FileSystem *fs, ox::String path) noexcept;
ox::Error create() noexcept;
@@ -60,7 +57,7 @@ class NOSTALGIASTUDIO_EXPORT Project {
/**
* Writes a MetalClaw object to the project at the given path.
*/
ox::Error writeObj(const ox::String &path, auto *obj) const noexcept;
ox::Error writeObj(const ox::String &path, auto *obj, ox::ClawFormat fmt = ox::ClawFormat::Metal) const noexcept;
template<typename T>
ox::Result<ox::UniquePtr<T>> loadObj(const ox::String &path) const noexcept;
@@ -100,9 +97,9 @@ class NOSTALGIASTUDIO_EXPORT Project {
};
ox::Error Project::writeObj(const ox::String &path, auto *obj) const noexcept {
ox::Error Project::writeObj(const ox::String &path, auto *obj, ox::ClawFormat fmt) const noexcept {
// write MetalClaw
oxRequireM(buff, ox::writeClaw(obj, ox::ClawFormat::Metal));
oxRequireM(buff, ox::writeClaw(obj, fmt));
// write to FS
oxReturnError(writeBuff(path, buff));
// write type descriptor
@@ -110,15 +107,12 @@ ox::Error Project::writeObj(const ox::String &path, auto *obj) const noexcept {
// write out type store
static constexpr auto descPath = "/.nostalgia/type_descriptors";
oxReturnError(mkdir(descPath));
for (const auto t : m_typeStore.typeList()) {
if (t->typeName.beginsWith("B:")) {
continue;
}
for (const auto &t : m_typeStore.typeList()) {
oxRequireM(typeOut, ox::writeClaw(t, ox::ClawFormat::Organic));
// replace garbage last character with new line
typeOut.back().value = '\n';
// write to FS
const auto typePath = ox::sfmt("{}/{}", descPath, t->typeName);
const auto typePath = ox::sfmt("{}/{};{}", descPath, t->typeName, t->typeVersion);
oxReturnError(writeBuff(typePath, typeOut));
}
fileUpdated.emit(path);

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <imgui.h>
#include "lib/context.hpp"
#include "lib/imguiuitl.hpp"
#include "newmenu.hpp"
namespace nostalgia {
NewMenu::NewMenu() noexcept {
setTitle("New Item");
setSize({225, 110});
}
void NewMenu::open() noexcept {
m_stage = Stage::Opening;
m_selectedType = 0;
}
void NewMenu::close() noexcept {
m_stage = Stage::Closed;
m_open = false;
}
bool NewMenu::isOpen() const noexcept {
return m_open;
}
void NewMenu::draw(core::Context *ctx) noexcept {
switch (m_stage) {
case Stage::Opening:
ImGui::OpenPopup(title().c_str());
m_stage = Stage::NewItemType;
m_open = true;
[[fallthrough]];
case Stage::NewItemType:
drawNewItemType(ctx);
break;
case Stage::NewItemName:
drawNewItemName(ctx);
break;
case Stage::Closed:
m_open = false;
break;
}
}
void NewMenu::addItemMaker(ox::UniquePtr<studio::ItemMaker> im) noexcept {
m_types.emplace_back(std::move(im));
}
void NewMenu::drawNewItemType(core::Context *ctx) noexcept {
drawWindow(ctx, &m_open, [this] {
auto items = ox_malloca(m_types.size() * sizeof(const char*), const char*, nullptr);
for (auto i = 0u; const auto &im : m_types) {
items[i] = im->name.c_str();
++i;
}
ImGui::ListBox("Item Type", &m_selectedType, items.get(), m_types.size());
drawFirstPageButtons();
ImGui::EndPopup();
});
}
void NewMenu::drawNewItemName(core::Context *ctx) noexcept {
drawWindow(ctx, &m_open, [this, ctx] {
const auto typeIdx = static_cast<std::size_t>(m_selectedType);
if (typeIdx < m_types.size()) {
ImGui::InputText("Name", m_itemName.data(), m_itemName.cap());
}
drawLastPageButtons(ctx);
ImGui::EndPopup();
});
}
void NewMenu::drawFirstPageButtons() noexcept {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 80);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
if (ImGui::Button("Next")) {
m_stage = Stage::NewItemName;
}
ImGui::SameLine();
if (ImGui::Button("Quit")) {
ImGui::CloseCurrentPopup();
m_stage = Stage::Closed;
}
}
void NewMenu::drawLastPageButtons(core::Context *ctx) noexcept {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 138);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
if (ImGui::Button("Back")) {
m_stage = Stage::NewItemType;
}
ImGui::SameLine();
if (ImGui::Button("Finish")) {
finish(ctx);
}
ImGui::SameLine();
if (ImGui::Button("Quit")) {
ImGui::CloseCurrentPopup();
m_stage = Stage::Closed;
}
}
void NewMenu::finish(core::Context *ctx) noexcept {
const auto err = m_types[static_cast<std::size_t>(m_selectedType)]->write(ctx, m_itemName.c_str());
if (err) {
oxDebugf("NewMenu::finish() error: {}", toStr(err));
oxLogError(err);
return;
}
finished.emit("");
m_stage = Stage::Closed;
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/claw/claw.hpp>
#include <ox/event/signal.hpp>
#include <ox/std/string.hpp>
#include <nostalgia/core/context.hpp>
#include "lib/itemmaker.hpp"
#include "lib/popup.hpp"
namespace nostalgia {
class NewMenu: public studio::Popup {
public:
enum class Stage {
Closed,
Opening,
NewItemType,
NewItemName,
};
// emits path parameter
ox::Signal<ox::Error(const ox::String&)> finished;
private:
Stage m_stage = Stage::Closed;
ox::String m_typeName;
ox::BString<255> m_itemName;
ox::Vector<ox::UniquePtr<studio::ItemMaker>> m_types;
int m_selectedType = 0;
bool m_open = false;
public:
NewMenu() noexcept;
void open() noexcept override;
void close() noexcept override;
[[nodiscard]]
bool isOpen() const noexcept override;
void draw(core::Context *ctx) noexcept override;
template<typename T>
void addItemType(ox::String name, ox::String parentDir, ox::String fileExt, T itemTempl, ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept;
template<typename T>
void addItemType(ox::String name, ox::String parentDir, ox::String fileExt, ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept;
void addItemMaker(ox::UniquePtr<studio::ItemMaker> im) noexcept;
private:
void drawNewItemType(core::Context *ctx) noexcept;
void drawNewItemName(core::Context *ctx) noexcept;
void drawFirstPageButtons() noexcept;
void drawLastPageButtons(core::Context *ctx) noexcept;
void finish(core::Context *ctx) noexcept;
};
template<typename T>
void NewMenu::addItemType(ox::String displayName, ox::String parentDir, ox::String fileExt, T itemTempl, ox::ClawFormat pFmt) noexcept {
m_types.emplace_back(new studio::ItemMakerT<T>(std::move(displayName), std::move(parentDir), std::move(fileExt), std::move(itemTempl), pFmt));
}
template<typename T>
void NewMenu::addItemType(ox::String displayName, ox::String parentDir, ox::String fileExt, ox::ClawFormat pFmt) noexcept {
m_types.emplace_back(new studio::ItemMakerT<T>(std::move(displayName), std::move(parentDir), std::move(fileExt), pFmt));
}
}

View File

@@ -25,6 +25,7 @@ class ProjectExplorer: public studio::Widget {
ox::Error refreshProjectTreeModel(const ox::String& = {}) noexcept;
[[nodiscard]]
constexpr ox::FileSystem *romFs() noexcept {
return m_ctx->rom.get();
}

View File

@@ -7,7 +7,10 @@
#include "lib/context.hpp"
#include "lib/editor.hpp"
#include "lib/filedialog.hpp"
#include "lib/imguiuitl.hpp"
#include "lib/module.hpp"
#include "lib/itemmaker.hpp"
#include "lib/popup.hpp"
#include "lib/project.hpp"
#include "lib/task.hpp"
#include "lib/undostack.hpp"

View File

@@ -46,10 +46,10 @@ StudioUI::StudioUI(core::Context *ctx) noexcept {
}
}
} else {
if (toStr(err)) {
oxErrf("Could not open studio config file: {}\n", toStr(err));
if constexpr(!ox::defines::Debug) {
oxErrf("Could not open studio config file: {}: {}\n", err.errCode, toStr(err));
} else {
oxErrf("Could not open studio config file: {} ({}:{})\n", err.errCode, err.file, err.line);
oxErrf("Could not open studio config file: {}: {} ({}:{})\n", err.errCode, toStr(err), err.file, err.line);
}
}
}
@@ -60,6 +60,14 @@ void StudioUI::update() noexcept {
void StudioUI::handleKeyEvent(core::Key key, bool down) noexcept {
const auto ctrlDown = core::buttonDown(m_ctx, core::Key::Mod_Ctrl);
for (auto p : m_popups) {
if (p->isOpen()) {
if (key == core::Key::Escape) {
p->close();
}
return;
}
}
if (down && ctrlDown) {
switch (key) {
case core::Key::Num_1:
@@ -68,6 +76,9 @@ void StudioUI::handleKeyEvent(core::Key key, bool down) noexcept {
case core::Key::Alpha_C:
m_activeEditor->copy();
break;
case core::Key::Alpha_N:
m_newMenu.open();
break;
case core::Key::Alpha_O:
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
break;
@@ -109,16 +120,16 @@ void StudioUI::draw() noexcept {
for (auto &w : m_widgets) {
w->draw(m_ctx);
}
if (m_aboutEnabled) {
ImGui::OpenPopup("About");
for (auto p : m_popups) {
p->draw(m_ctx);
}
drawAboutPopup();
}
void StudioUI::drawMenu() noexcept {
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("New...", "Ctrl+N")) {
m_newMenu.open();
}
if (ImGui::MenuItem("Open Project...", "Ctrl+O")) {
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
@@ -159,7 +170,7 @@ void StudioUI::drawMenu() noexcept {
}
if (ImGui::BeginMenu("Help")) {
if (ImGui::MenuItem("About")) {
m_aboutEnabled = true;
m_aboutPopup.open();
}
ImGui::EndMenu();
}
@@ -221,19 +232,6 @@ void StudioUI::drawTabs() noexcept {
}
}
void StudioUI::drawAboutPopup() noexcept {
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
if (ImGui::BeginPopupModal("About", &m_aboutEnabled, modalFlags)) {
ImGui::Text("Nostalgia Studio - dev build");
ImGui::SetNextWindowPos(ImVec2(0.5f, 0.5f), ImGuiCond_Always, ImVec2(0.5f,0.5f));
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
m_aboutEnabled = false;
}
ImGui::EndPopup();
}
}
void StudioUI::loadEditorMaker(const studio::EditorMaker &editorMaker) noexcept {
for (const auto &ext : editorMaker.fileTypes) {
m_editorMakers[ext] = editorMaker.make;
@@ -244,6 +242,9 @@ void StudioUI::loadModule(studio::Module *module) noexcept {
for (auto &editorMaker : module->editors(m_ctx)) {
loadEditorMaker(editorMaker);
}
for (auto &im : module->itemMakers(m_ctx)) {
m_newMenu.addItemMaker(std::move(im));
}
}
void StudioUI::loadModules() noexcept {
@@ -320,7 +321,11 @@ ox::Error StudioUI::openFileActiveTab(const ox::String &path, bool makeActiveTab
}
auto [editor, err] = m_editorMakers[ext](path);
if (err) {
oxErrorf("Could not open Editor: {} ({}:{})", err.msg, err.file, err.line);
if constexpr(!ox::defines::Debug) {
oxErrf("Could not open Editor: {}\n", toStr(err));
} else {
oxErrf("Could not open Editor: {} ({}:{})\n", err.errCode, err.file, err.line);
}
return err;
}
editor->closed.connect(this, &StudioUI::closeFile);

View File

@@ -12,6 +12,8 @@
#include "lib/module.hpp"
#include "lib/project.hpp"
#include "lib/task.hpp"
#include "aboutpopup.hpp"
#include "newmenu.hpp"
#include "projectexplorer.hpp"
#include "projecttreemodel.hpp"
@@ -31,8 +33,12 @@ class StudioUI: public ox::SignalHandler {
ox::Vector<ox::String> m_openFiles;
studio::BaseEditor *m_activeEditor = nullptr;
studio::BaseEditor *m_activeEditorUpdatePending = nullptr;
bool m_saveEnabled = false;
bool m_aboutEnabled = false;
NewMenu m_newMenu;
AboutPopup m_aboutPopup;
const ox::Array<studio::Popup*, 2> m_popups = {
&m_newMenu,
&m_aboutPopup
};
bool m_showProjectExplorer = true;
public:
@@ -57,8 +63,6 @@ class StudioUI: public ox::SignalHandler {
void drawTabs() noexcept;
void drawAboutPopup() noexcept;
void loadEditorMaker(const studio::EditorMaker &editorMaker) noexcept;
void loadModule(studio::Module *module) noexcept;