Compare commits
2 Commits
4e5c749918
...
6924147686
Author | SHA1 | Date | |
---|---|---|---|
6924147686 | |||
6e2b4fa7b4 |
9
Makefile
9
Makefile
@ -5,9 +5,11 @@ BUILDCORE_PATH=deps/buildcore
|
|||||||
include ${BUILDCORE_PATH}/base.mk
|
include ${BUILDCORE_PATH}/base.mk
|
||||||
|
|
||||||
ifeq ($(BC_VAR_OS),darwin)
|
ifeq ($(BC_VAR_OS),darwin)
|
||||||
|
PROJECT_PLAYER=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME}.app/Contents/MacOS/${BC_VAR_PROJECT_NAME}
|
||||||
NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio
|
NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio
|
||||||
MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA
|
MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA
|
||||||
else
|
else
|
||||||
|
PROJECT_PLAYER=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME}
|
||||||
NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio
|
NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio
|
||||||
MGBA=mgba-qt
|
MGBA=mgba-qt
|
||||||
endif
|
endif
|
||||||
@ -16,9 +18,12 @@ endif
|
|||||||
pkg-gba: build
|
pkg-gba: build
|
||||||
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME}
|
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME}
|
||||||
|
|
||||||
|
.PHONY: build-player
|
||||||
|
build-player:
|
||||||
|
${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} ${BC_VAR_PROJECT_NAME}
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: build
|
run: build-player
|
||||||
./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
|
${PROJECT_PLAYER} sample_project
|
||||||
.PHONY: run-studio
|
.PHONY: run-studio
|
||||||
run-studio: build
|
run-studio: build
|
||||||
${NOSTALGIA_STUDIO}
|
${NOSTALGIA_STUDIO}
|
||||||
|
@ -22,6 +22,12 @@ void NewMenu::open() noexcept {
|
|||||||
m_selectedType = 0;
|
m_selectedType = 0;
|
||||||
m_itemName = "";
|
m_itemName = "";
|
||||||
m_typeName = "";
|
m_typeName = "";
|
||||||
|
m_path = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewMenu::openPath(ox::StringParam path) noexcept {
|
||||||
|
open();
|
||||||
|
m_path = std::move(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewMenu::close() noexcept {
|
void NewMenu::close() noexcept {
|
||||||
@ -158,14 +164,14 @@ void NewMenu::finish(StudioContext &sctx) noexcept {
|
|||||||
oxLogError(ox::Error{1, "New file error: no file name"});
|
oxLogError(ox::Error{1, "New file error: no file name"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto const&im = *m_types[static_cast<std::size_t>(m_selectedType)];
|
auto const&im = *m_types[m_selectedType];
|
||||||
if (sctx.project->exists(im.itemPath(m_itemName))) {
|
auto const path = m_path.len() ?
|
||||||
|
im.itemPath(m_itemName, m_path) : im.itemPath(m_itemName);
|
||||||
|
if (sctx.project->exists(path)) {
|
||||||
oxLogError(ox::Error{1, "New file error: file already exists"});
|
oxLogError(ox::Error{1, "New file error: file already exists"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto const [path, err] =
|
if (auto const err = im.write(sctx, path, m_selectedTemplate)) {
|
||||||
im.write(sctx, m_itemName, m_selectedTemplate);
|
|
||||||
if (err) {
|
|
||||||
oxLogError(err);
|
oxLogError(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ class NewMenu final: public Popup {
|
|||||||
Stage m_stage = Stage::Closed;
|
Stage m_stage = Stage::Closed;
|
||||||
ox::String m_typeName;
|
ox::String m_typeName;
|
||||||
ox::IString<255> m_itemName;
|
ox::IString<255> m_itemName;
|
||||||
|
ox::String m_path;
|
||||||
ox::Vector<ox::UPtr<studio::ItemMaker>> m_types;
|
ox::Vector<ox::UPtr<studio::ItemMaker>> m_types;
|
||||||
size_t m_selectedType = 0;
|
size_t m_selectedType = 0;
|
||||||
size_t m_selectedTemplate = 0;
|
size_t m_selectedTemplate = 0;
|
||||||
@ -38,6 +39,8 @@ class NewMenu final: public Popup {
|
|||||||
public:
|
public:
|
||||||
NewMenu() noexcept;
|
NewMenu() noexcept;
|
||||||
|
|
||||||
|
void openPath(ox::StringParam path) noexcept;
|
||||||
|
|
||||||
void open() noexcept override;
|
void open() noexcept override;
|
||||||
|
|
||||||
void close() noexcept override;
|
void close() noexcept override;
|
||||||
|
@ -19,7 +19,8 @@ class ProjectExplorer: public Widget {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// slots
|
// slots
|
||||||
ox::Signal<ox::Error(ox::StringView const&)> fileChosen;
|
ox::Signal<ox::Error(ox::StringViewCR)> fileChosen;
|
||||||
|
ox::Signal<ox::Error(ox::StringViewCR)> addItem;
|
||||||
|
|
||||||
explicit ProjectExplorer(turbine::Context &ctx) noexcept;
|
explicit ProjectExplorer(turbine::Context &ctx) noexcept;
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include <studio/imguiutil.hpp>
|
||||||
|
|
||||||
#include "projectexplorer.hpp"
|
#include "projectexplorer.hpp"
|
||||||
#include "projecttreemodel.hpp"
|
#include "projecttreemodel.hpp"
|
||||||
|
|
||||||
@ -30,10 +32,14 @@ bool ProjectTreeModel::draw(turbine::Context &ctx) const noexcept {
|
|||||||
constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||||
if (!m_children.empty()) {
|
if (!m_children.empty()) {
|
||||||
if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) {
|
if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) {
|
||||||
|
drawDirContextMenu();
|
||||||
for (auto const&child : m_children) {
|
for (auto const&child : m_children) {
|
||||||
updated = child->draw(ctx) || updated;
|
updated = child->draw(ctx) || updated;
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
|
} else {
|
||||||
|
ig::IDStackItem const idStackItem{m_name};
|
||||||
|
drawDirContextMenu();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto const path = fullPath();
|
auto const path = fullPath();
|
||||||
@ -58,6 +64,15 @@ void ProjectTreeModel::setChildren(ox::Vector<ox::UPtr<ProjectTreeModel>> childr
|
|||||||
m_children = std::move(children);
|
m_children = std::move(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectTreeModel::drawDirContextMenu() const noexcept {
|
||||||
|
if (ImGui::BeginPopupContextItem("DirMenu", ImGuiPopupFlags_MouseButtonRight)) {
|
||||||
|
if (ImGui::MenuItem("Add Item")) {
|
||||||
|
m_explorer.addItem.emit(fullPath());
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ox::BasicString<255> ProjectTreeModel::fullPath() const noexcept {
|
ox::BasicString<255> ProjectTreeModel::fullPath() const noexcept {
|
||||||
if (m_parent) {
|
if (m_parent) {
|
||||||
return m_parent->fullPath() + "/" + ox::StringView(m_name);
|
return m_parent->fullPath() + "/" + ox::StringView(m_name);
|
||||||
|
@ -31,6 +31,8 @@ class ProjectTreeModel {
|
|||||||
void setChildren(ox::Vector<ox::UPtr<ProjectTreeModel>> children) noexcept;
|
void setChildren(ox::Vector<ox::UPtr<ProjectTreeModel>> children) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void drawDirContextMenu() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::BasicString<255> fullPath() const noexcept;
|
ox::BasicString<255> fullPath() const noexcept;
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ StudioUI::StudioUI(turbine::Context &ctx, ox::StringParam projectDataDir) noexce
|
|||||||
m_aboutPopup(m_tctx) {
|
m_aboutPopup(m_tctx) {
|
||||||
turbine::setApplicationData(m_tctx, &m_sctx);
|
turbine::setApplicationData(m_tctx, &m_sctx);
|
||||||
m_projectExplorer.fileChosen.connect(this, &StudioUI::openFile);
|
m_projectExplorer.fileChosen.connect(this, &StudioUI::openFile);
|
||||||
|
m_projectExplorer.addItem.connect(this, &StudioUI::addFile);
|
||||||
m_newProject.finished.connect(this, &StudioUI::createOpenProject);
|
m_newProject.finished.connect(this, &StudioUI::createOpenProject);
|
||||||
m_newMenu.finished.connect(this, &StudioUI::openFile);
|
m_newMenu.finished.connect(this, &StudioUI::openFile);
|
||||||
ImGui::GetIO().IniFilename = nullptr;
|
ImGui::GetIO().IniFilename = nullptr;
|
||||||
@ -342,6 +343,11 @@ void StudioUI::handleKeyInput() noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error StudioUI::addFile(ox::StringViewCR path) noexcept {
|
||||||
|
m_newMenu.openPath(path);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ox::Error StudioUI::createOpenProject(ox::StringViewCR path) noexcept {
|
ox::Error StudioUI::createOpenProject(ox::StringViewCR path) noexcept {
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
std::filesystem::create_directories(toStdStringView(path), ec);
|
std::filesystem::create_directories(toStdStringView(path), ec);
|
||||||
|
@ -83,6 +83,8 @@ class StudioUI: public ox::SignalHandler {
|
|||||||
|
|
||||||
void handleKeyInput() noexcept;
|
void handleKeyInput() noexcept;
|
||||||
|
|
||||||
|
ox::Error addFile(ox::StringViewCR path) noexcept;
|
||||||
|
|
||||||
ox::Error createOpenProject(ox::StringViewCR path) noexcept;
|
ox::Error createOpenProject(ox::StringViewCR path) noexcept;
|
||||||
|
|
||||||
ox::Error openProjectPath(ox::StringParam path) noexcept;
|
ox::Error openProjectPath(ox::StringParam path) noexcept;
|
||||||
|
@ -128,6 +128,16 @@ class ItemMaker {
|
|||||||
return m_templates;
|
return m_templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::String const&defaultPath() const noexcept {
|
||||||
|
return m_parentDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::String itemPath(ox::StringViewCR pName, ox::StringViewCR pPath) const noexcept {
|
||||||
|
return ox::sfmt("/{}/{}.{}", pPath, pName, m_fileExt);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::String itemPath(ox::StringViewCR pName) const noexcept {
|
ox::String itemPath(ox::StringViewCR pName) const noexcept {
|
||||||
return ox::sfmt("/{}/{}.{}", m_parentDir, pName, m_fileExt);
|
return ox::sfmt("/{}/{}.{}", m_parentDir, pName, m_fileExt);
|
||||||
@ -142,12 +152,40 @@ class ItemMaker {
|
|||||||
/**
|
/**
|
||||||
* Returns path of the file created.
|
* Returns path of the file created.
|
||||||
* @param ctx
|
* @param ctx
|
||||||
|
* @param pPath
|
||||||
|
* @param pTemplateIdx
|
||||||
|
* @return path of file or error in Result
|
||||||
|
*/
|
||||||
|
ox::Error write(
|
||||||
|
StudioContext &ctx,
|
||||||
|
ox::StringViewCR pPath,
|
||||||
|
size_t pTemplateIdx) const noexcept {
|
||||||
|
return writeItem(ctx, pPath, pTemplateIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns path of the file created.
|
||||||
|
* @param ctx
|
||||||
|
* @param pPath
|
||||||
* @param pName
|
* @param pName
|
||||||
* @param pTemplateIdx
|
* @param pTemplateIdx
|
||||||
* @return path of file or error in Result
|
* @return path of file or error in Result
|
||||||
*/
|
*/
|
||||||
virtual ox::Result<ox::String> write(
|
ox::Error write(
|
||||||
StudioContext &ctx, ox::StringViewCR pName, size_t pTemplateIdx) const noexcept = 0;
|
StudioContext &ctx,
|
||||||
|
ox::StringViewCR pPath,
|
||||||
|
ox::StringViewCR pName,
|
||||||
|
size_t pTemplateIdx) const noexcept {
|
||||||
|
auto const path = itemPath(pName, pPath);
|
||||||
|
return writeItem(ctx, path, pTemplateIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ox::Error writeItem(
|
||||||
|
StudioContext &ctx,
|
||||||
|
ox::StringViewCR pPath,
|
||||||
|
size_t pTemplateIdx) const noexcept = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -205,20 +243,19 @@ class ItemMakerT final: public ItemMaker {
|
|||||||
return ox::ModelTypeVersion_v<T>;
|
return ox::ModelTypeVersion_v<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Result<ox::String> write(
|
ox::Error writeItem(
|
||||||
StudioContext &sctx,
|
StudioContext &ctx,
|
||||||
ox::StringViewCR pName,
|
ox::StringViewCR pPath,
|
||||||
size_t const pTemplateIdx) const noexcept override {
|
size_t const pTemplateIdx) const noexcept override {
|
||||||
auto const path = itemPath(pName);
|
createUuidMapping(keelCtx(ctx.tctx), pPath, ox::UUID::generate().unwrap());
|
||||||
createUuidMapping(keelCtx(sctx.tctx), path, ox::UUID::generate().unwrap());
|
|
||||||
auto const&templates = itemTemplates();
|
auto const&templates = itemTemplates();
|
||||||
auto const tmplIdx = pTemplateIdx < templates.size() ? pTemplateIdx : 0;
|
auto const tmplIdx = pTemplateIdx < templates.size() ? pTemplateIdx : 0;
|
||||||
OX_REQUIRE_M(tmpl, templates[tmplIdx]->getItem(
|
OX_REQUIRE_M(tmpl, templates[tmplIdx]->getItem(
|
||||||
keelCtx(sctx), typeName(), typeVersion()));
|
keelCtx(ctx), typeName(), typeVersion()));
|
||||||
auto item = tmpl.template get<T>();
|
auto item = tmpl.template get<T>();
|
||||||
OX_RETURN_ERROR(sctx.project->writeObj(path, *item, m_fmt));
|
OX_RETURN_ERROR(ctx.project->writeObj(pPath, *item, m_fmt));
|
||||||
tmpl.free();
|
tmpl.free();
|
||||||
return path;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user