Gary Talent ac743834d3
All checks were successful
Build / build (push) Successful in 3m52s
[applib] Fix build
2025-01-19 14:32:08 -06:00

183 lines
4.6 KiB
C++

/*
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <algorithm>
#include <imgui.h>
#include <studio/imguiutil.hpp>
#include "newmenu.hpp"
namespace studio {
NewMenu::NewMenu() noexcept {
setTitle("New Item");
setSize({280, 180});
}
void NewMenu::open() noexcept {
m_stage = Stage::Opening;
m_selectedType = 0;
m_itemName = "";
m_typeName = "";
m_path = "";
}
void NewMenu::openPath(ox::StringParam path) noexcept {
open();
m_path = std::move(path);
}
void NewMenu::close() noexcept {
m_stage = Stage::Closed;
m_open = false;
}
bool NewMenu::isOpen() const noexcept {
return m_open;
}
void NewMenu::draw(StudioContext &sctx) noexcept {
switch (m_stage) {
case Stage::Opening:
ImGui::OpenPopup(title().c_str());
m_stage = Stage::NewItemType;
m_open = true;
[[fallthrough]];
case Stage::NewItemType:
drawNewItemType(sctx);
break;
case Stage::NewItemName:
drawNewItemName(sctx);
break;
case Stage::NewItemTemplate:
drawNewItemTemplate(sctx);
break;
case Stage::Closed:
m_open = false;
break;
}
}
void NewMenu::addItemMaker(ox::UPtr<ItemMaker> &&im) noexcept {
m_types.emplace_back(std::move(im));
std::sort(
m_types.begin(), m_types.end(),
[](ox::UPtr<ItemMaker> const&im1, ox::UPtr<ItemMaker> const&im2) {
return im1->typeDisplayName() < im2->typeDisplayName();
});
}
void NewMenu::installItemTemplate(ox::UPtr<ItemTemplate> &tmplt) noexcept {
for (auto const&im : m_types) {
if (im->installTemplate(tmplt)) {
break;
}
}
}
void NewMenu::drawNewItemType(StudioContext const&sctx) noexcept {
drawWindow(sctx.tctx, m_open, [this] {
ig::ListBox("Item Type", [&](size_t const i) -> ox::CStringView {
return m_types[i]->typeDisplayName();
}, m_types.size(), m_selectedType, {200, 100});
auto const&im = *m_types[m_selectedType];
drawFirstPageButtons(im.itemTemplates().size() == 1 ?
Stage::NewItemName : Stage::NewItemTemplate);
});
}
void NewMenu::drawNewItemTemplate(StudioContext &sctx) noexcept {
drawWindow(sctx.tctx, m_open, [this] {
auto const&templates =
m_types[m_selectedType]->itemTemplates();
ig::ListBox("Template", [&](size_t const i) -> ox::CStringView {
return templates[i]->name();
}, templates.size(), m_selectedTemplate, {200, 100});
drawButtons(Stage::NewItemType, Stage::NewItemName);
});
}
void NewMenu::drawNewItemName(StudioContext &sctx) noexcept {
drawWindow(sctx.tctx, m_open, [this, &sctx] {
if (m_selectedType < m_types.size()) {
ig::InputText("Name", m_itemName);
}
drawLastPageButtons(sctx);
});
}
void NewMenu::drawButtons(Stage const prev, Stage const next) noexcept {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 198);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
constexpr ImVec2 btnSz{60, 20};
if (ImGui::Button("Back", btnSz)) {
m_stage = prev;
}
ImGui::SameLine();
if (ImGui::Button("Next", btnSz)) {
m_stage = next;
}
ImGui::SameLine();
if (ImGui::Button("Cancel", btnSz)) {
ImGui::CloseCurrentPopup();
m_stage = Stage::Closed;
}
}
void NewMenu::drawFirstPageButtons(Stage const next) noexcept {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 130);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
constexpr ImVec2 btnSz{60, 20};
if (ImGui::Button("Next", btnSz)) {
m_stage = next;
}
ImGui::SameLine();
if (ImGui::Button("Cancel", btnSz)) {
ImGui::CloseCurrentPopup();
m_stage = Stage::Closed;
}
}
void NewMenu::drawLastPageButtons(StudioContext &sctx) noexcept {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 198);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
constexpr ImVec2 btnSz{60, 20};
if (ImGui::Button("Back", btnSz)) {
m_stage = Stage::NewItemType;
}
ImGui::SameLine();
if (ImGui::Button("Finish", btnSz)) {
finish(sctx);
}
ImGui::SameLine();
if (ImGui::Button("Quit", btnSz)) {
ImGui::CloseCurrentPopup();
m_stage = Stage::Closed;
}
}
void NewMenu::finish(StudioContext &sctx) noexcept {
if (m_itemName.len() == 0) {
oxLogError(ox::Error{1, "New file error: no file name"});
return;
}
auto const&im = *m_types[m_selectedType];
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"});
return;
}
if (auto const err = im.write(sctx, path, m_selectedTemplate)) {
oxLogError(err);
return;
}
finished.emit(path);
m_stage = Stage::Closed;
}
}