[nostalgia/core/studio] Add SubSheet editor
This commit is contained in:
parent
921cb97a14
commit
2f7c62f2ef
@ -16,6 +16,7 @@ TileSheetEditorImGui::TileSheetEditorImGui(Context *ctx, const ox::String &path)
|
||||
const auto lastSlash = std::find(m_itemPath.rbegin(), m_itemPath.rend(), '/').offset();
|
||||
m_itemName = m_itemPath.substr(lastSlash + 1);
|
||||
undoStack()->changeTriggered.connect(this, &TileSheetEditorImGui::markUnsavedChanges);
|
||||
m_subsheetEditor.inputSubmitted.connect(model(), &TileSheetEditorModel::updateActiveSubsheet);
|
||||
}
|
||||
|
||||
ox::String TileSheetEditorImGui::itemName() const noexcept {
|
||||
@ -61,7 +62,8 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
|
||||
ImGui::EndChild();
|
||||
ImGui::BeginChild("child2", ImVec2(m_palViewWidth - 24, paneSize.y / 2.07f), true);
|
||||
{
|
||||
const auto btnSize = ImVec2(18, 18);
|
||||
constexpr auto btnHeight = 18;
|
||||
const auto btnSize = ImVec2(18, btnHeight);
|
||||
if (ImGui::Button("+", btnSize)) {
|
||||
auto insertOnIdx = model()->activeSubSheetIdx();
|
||||
const auto &parent = *model()->activeSubSheet();
|
||||
@ -76,6 +78,15 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
|
||||
model()->rmSubsheet(activeSubsheetIdx);
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Edit", ImVec2(36, btnHeight))) {
|
||||
const auto sheet = model()->activeSubSheet();
|
||||
if (sheet->subsheets.size()) {
|
||||
m_subsheetEditor.show(sheet->name, -1, -1);
|
||||
} else {
|
||||
m_subsheetEditor.show(sheet->name, sheet->columns, sheet->rows);
|
||||
}
|
||||
}
|
||||
TileSheet::SubSheetIdx path;
|
||||
constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
if (ImGui::BeginTable("Subsheets", 3, flags)) {
|
||||
@ -90,6 +101,8 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
m_subsheetEditor.draw();
|
||||
ImGui::ShowDemoWindow();
|
||||
}
|
||||
|
||||
void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, TileSheet::SubSheetIdx *path) noexcept {
|
||||
@ -105,6 +118,8 @@ void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, T
|
||||
| (rowSelected ? ImGuiTreeNodeFlags_Selected : 0);
|
||||
ImGui::TableNextColumn();
|
||||
const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags);
|
||||
Str newName = subsheet->name.c_str();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsItemClicked()) {
|
||||
model()->setActiveSubsheet(*path);
|
||||
}
|
||||
@ -223,4 +238,31 @@ ox::Error TileSheetEditorImGui::markUnsavedChanges(int) noexcept {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
void TileSheetEditorImGui::SubSheetEditor::draw() noexcept {
|
||||
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
||||
constexpr auto popupName = "Edit SubSheet";
|
||||
if (m_show) {
|
||||
ImGui::OpenPopup(popupName);
|
||||
ImGui::SetNextWindowSize(ImVec2(235, 125));
|
||||
}
|
||||
if (ImGui::BeginPopupModal(popupName, &m_show, modalFlags)) {
|
||||
ImGui::InputText("Name", m_name.data(), m_name.cap());
|
||||
if (m_cols != -1) {
|
||||
ImGui::InputInt("Columns", &m_cols);
|
||||
ImGui::InputInt("Rows", &m_rows);
|
||||
}
|
||||
if (ImGui::Button("OK")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
m_show = false;
|
||||
inputSubmitted.emit(m_name.c_str(), m_cols, m_rows);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
m_show = false;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,22 @@ namespace nostalgia::core {
|
||||
class TileSheetEditorImGui: public studio::Editor {
|
||||
|
||||
private:
|
||||
class SubSheetEditor {
|
||||
ox::BString<100> m_name;
|
||||
int m_cols = 0;
|
||||
int m_rows = 0;
|
||||
bool m_show;
|
||||
public:
|
||||
ox::Signal<ox::Error(const ox::String &name, int cols, int rows)> inputSubmitted;
|
||||
constexpr void show(const ox::String &name, int cols, int rows) noexcept {
|
||||
m_show = true;
|
||||
m_name = name.c_str();
|
||||
m_cols = cols;
|
||||
m_rows = rows;
|
||||
}
|
||||
void draw() noexcept;
|
||||
};
|
||||
SubSheetEditor m_subsheetEditor;
|
||||
ox::String m_itemPath;
|
||||
ox::String m_itemName;
|
||||
glutils::FrameBuffer m_framebuffer;
|
||||
|
@ -55,6 +55,11 @@ void TileSheetEditorModel::rmSubsheet(const TileSheet::SubSheetIdx &idx) noexcep
|
||||
pushCommand(new RmSubSheetCommand(&m_img, idx));
|
||||
}
|
||||
|
||||
ox::Error TileSheetEditorModel::updateActiveSubsheet(const ox::String &name, int cols, int rows) noexcept {
|
||||
pushCommand(new UpdateSubSheetCommand(&m_img, m_activeSubsSheetIdx, name, cols, rows));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
void TileSheetEditorModel::setActiveSubsheet(const TileSheet::SubSheetIdx &idx) noexcept {
|
||||
m_activeSubsSheetIdx = idx;
|
||||
this->activeSubsheetChanged.emit(m_activeSubsSheetIdx);
|
||||
|
@ -19,6 +19,7 @@ enum class CommandId {
|
||||
Draw = 1,
|
||||
AddSubSheet = 2,
|
||||
RmSubSheet = 3,
|
||||
UpdateSubSheet = 4,
|
||||
};
|
||||
|
||||
constexpr bool operator==(CommandId c, int i) noexcept {
|
||||
@ -180,6 +181,46 @@ struct RmSubSheetCommand: public studio::UndoCommand {
|
||||
|
||||
};
|
||||
|
||||
struct UpdateSubSheetCommand: public studio::UndoCommand {
|
||||
private:
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet::SubSheetIdx m_idx;
|
||||
TileSheet::SubSheet m_sheet;
|
||||
ox::String m_newName;
|
||||
int m_newCols = 0;
|
||||
int m_newRows = 0;
|
||||
|
||||
public:
|
||||
constexpr UpdateSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx,
|
||||
const ox::String &name, int cols, int rows) noexcept {
|
||||
m_img = img;
|
||||
m_idx = idx;
|
||||
m_sheet = img->getSubSheet(idx);
|
||||
m_newName = name;
|
||||
m_newCols = cols;
|
||||
m_newRows = rows;
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
auto &sheet = m_img->getSubSheet(m_idx);
|
||||
sheet.name = m_newName;
|
||||
sheet.columns = m_newCols;
|
||||
sheet.rows = m_newRows;
|
||||
sheet.pixels.resize(static_cast<std::size_t>(m_newCols * m_newRows * PixelsPerTile));
|
||||
}
|
||||
|
||||
void undo() noexcept final {
|
||||
auto &sheet = m_img->getSubSheet(m_idx);
|
||||
sheet = m_sheet;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept final {
|
||||
return static_cast<int>(CommandId::UpdateSubSheet);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct TileSheetClipboard {
|
||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
@ -262,6 +303,8 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
||||
|
||||
void rmSubsheet(const TileSheet::SubSheetIdx &idx) noexcept;
|
||||
|
||||
ox::Error updateActiveSubsheet(const ox::String &name, int cols, int rows) noexcept;
|
||||
|
||||
void setActiveSubsheet(const TileSheet::SubSheetIdx&) noexcept;
|
||||
|
||||
constexpr const TileSheet::SubSheet *activeSubSheet() const noexcept {
|
||||
|
Loading…
Reference in New Issue
Block a user