[nostalgia/studio] Start on ImGui version of Studio

This commit is contained in:
2021-07-26 01:39:56 -05:00
parent 6160335af3
commit ddd63bc45f
46 changed files with 1005 additions and 2269 deletions
+144
View File
@@ -0,0 +1,144 @@
/*
* Copyright 2016 - 2021 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <imgui.h>
#include <nostalgia/core/core.hpp>
#include "lib/configio.hpp"
#include "filedialogmanager.hpp"
#include "studioapp.hpp"
namespace nostalgia {
struct StudioConfig {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.studio.StudioConfig";
static constexpr auto TypeVersion = 1;
ox::String projectPath;
};
template<typename T>
constexpr ox::Error model(T *h, StudioConfig *config) noexcept {
oxReturnError(h->field("project_path", &config->projectPath));
return OxError(0);
}
StudioUI::StudioUI() noexcept {
m_widgets.push_back(&m_projectExplorer);
if (const auto [config, err] = studio::readConfig<StudioConfig>(); !err) {
oxIgnoreError(openProject(config.projectPath));
} else {
oxErrf("Could not open studio config file: {}\n", err.msg);
}
}
static ox::Result<ox::UniquePtr<ProjectTreeModel>>
buildProjectTreeModel(const ox::String &name, const ox::String &path, ox::FileSystem *fs) noexcept {
ox::Vector<ox::UniquePtr<ProjectTreeModel>> outChildren;
oxRequire(stat, fs->stat(path.c_str()));
if (stat.fileType == ox::FileType::Directory) {
oxRequireM(children, fs->ls(path));
//std::sort(children.begin(), children.end());
for (const auto &childName : children) {
if (childName[0] != '.') {
const auto childPath = ox::sfmt("{}/{}", path, childName);
oxRequireM(child, buildProjectTreeModel(childName, childPath, fs));
outChildren.emplace_back(std::move(child));
}
}
}
return ox::make_unique<ProjectTreeModel>(name, std::move(outChildren));
}
void StudioUI::update(core::Context *ctx) noexcept {
m_taskRunner.update(ctx);
}
void StudioUI::draw(core::Context *ctx) noexcept {
drawMenu(ctx);
drawToolbar(ctx);
for (auto &w : m_widgets) {
w->draw(ctx);
}
if (m_aboutEnabled &&
ImGui::Begin("About", &m_aboutEnabled, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize)) {
ImGui::End();
}
}
void StudioUI::drawMenu(core::Context *ctx) noexcept {
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("New...", "Ctrl+N")) {
}
if (ImGui::MenuItem("Open Project...", "Ctrl+O")) {
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
}
if (ImGui::MenuItem("Save", "Ctrl+S", false, m_saveEnabled)) {
}
if (ImGui::MenuItem("Quit", "Ctrl+Q")) {
core::shutdown(ctx);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Module", false)) {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help")) {
if (ImGui::MenuItem("About")) {
m_aboutEnabled = true;
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
}
void StudioUI::drawToolbar(core::Context*) noexcept {
constexpr auto BtnWidth = 96;
constexpr auto BtnHeight = 32;
const auto viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + 20));
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, 48));
const auto flags = ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoSavedSettings;
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
ImGui::Begin("MainToolbar", nullptr, flags);
ImGui::PopStyleVar();
{
ImGui::Button("New##MainToolbar", ImVec2(BtnWidth, BtnHeight));
ImGui::SameLine();
if (ImGui::Button("Open Project##MainToolbar", ImVec2(BtnWidth, BtnHeight))) {
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
}
ImGui::SameLine();
ImGui::Button("Save##MainToolbar", ImVec2(BtnWidth, BtnHeight));
}
ImGui::End();
}
ox::Error StudioUI::openProject(const ox::String &path) noexcept {
m_project = ox::make_unique<studio::Project>(path);
m_project->fileAdded.connect(this, &StudioUI::refreshProjectTreeModel);
m_project->fileDeleted.connect(this, &StudioUI::refreshProjectTreeModel);
oxReturnError(studio::editConfig<StudioConfig>([path](StudioConfig *config) {
config->projectPath = path;
}));
return refreshProjectTreeModel();
}
ox::Error StudioUI::refreshProjectTreeModel(const ox::String&) noexcept {
oxRequireM(model, buildProjectTreeModel("Project", "/", m_project->romFs()));
m_projectExplorer.setModel(std::move(model));
return OxError(0);
}
}