[nostalgia/studio] Get save working
This commit is contained in:
parent
5b7dacd51f
commit
56ec063658
@ -45,19 +45,22 @@ else()
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(
|
set(
|
||||||
NostalgiaCore
|
NOSTALGIA_CORE_GENERAL_SRC
|
||||||
gfx.cpp
|
gfx.cpp
|
||||||
media.cpp
|
media.cpp
|
||||||
typeconv.cpp
|
typeconv.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
NostalgiaCore
|
||||||
|
${NOSTALGIA_CORE_GENERAL_SRC}
|
||||||
${NOSTALGIA_CORE_IMPL_SRC}
|
${NOSTALGIA_CORE_IMPL_SRC}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(
|
add_library(
|
||||||
NostalgiaCore-Headless
|
NostalgiaCore-Headless
|
||||||
gfx.cpp
|
${NOSTALGIA_CORE_GENERAL_SRC}
|
||||||
media.cpp
|
|
||||||
typeconv.cpp
|
|
||||||
headless/core.cpp
|
headless/core.cpp
|
||||||
headless/gfx.cpp
|
headless/gfx.cpp
|
||||||
headless/media.cpp
|
headless/media.cpp
|
||||||
@ -75,7 +78,7 @@ target_link_libraries(
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaCore-Headless PUBLIC
|
NostalgiaCore-Headless PUBLIC
|
||||||
OxClaw
|
OxClaw
|
||||||
OxFS
|
OxFS
|
||||||
)
|
)
|
||||||
|
@ -61,6 +61,12 @@ studio::UndoStack *TileSheetEditorImGui::undoStack() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorImGui::saveItem() {
|
void TileSheetEditorImGui::saveItem() {
|
||||||
|
const auto err = m_tileSheetEditor.model()->saveFile();
|
||||||
|
if (!err) {
|
||||||
|
this->setUnsavedChanges(false);
|
||||||
|
} else {
|
||||||
|
oxErrorf("Could not save file {}: {}", m_itemPath, toStr(err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorImGui::drawTileSheet(const geo::Vec2 &fbSize) noexcept {
|
void TileSheetEditorImGui::drawTileSheet(const geo::Vec2 &fbSize) noexcept {
|
||||||
|
@ -76,6 +76,16 @@ class TileSheetEditor {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr const Palette &pal() const noexcept;
|
constexpr const Palette &pal() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto *model() noexcept {
|
||||||
|
return &m_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto *model() const noexcept {
|
||||||
|
return &m_model;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr auto setPalIdx(auto palIdx) noexcept {
|
constexpr auto setPalIdx(auto palIdx) noexcept {
|
||||||
m_palIdx = palIdx;
|
m_palIdx = palIdx;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ox/claw/write.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/media.hpp>
|
#include <nostalgia/core/media.hpp>
|
||||||
|
|
||||||
#include "tilesheeteditormodel.hpp"
|
#include "tilesheeteditormodel.hpp"
|
||||||
@ -9,6 +11,8 @@
|
|||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
TileSheetEditorModel::TileSheetEditorModel(Context *ctx, const ox::String &path) {
|
TileSheetEditorModel::TileSheetEditorModel(Context *ctx, const ox::String &path) {
|
||||||
|
m_ctx = ctx;
|
||||||
|
m_path = path;
|
||||||
oxRequireT(img, readObj<TileSheet>(ctx, path.c_str()));
|
oxRequireT(img, readObj<TileSheet>(ctx, path.c_str()));
|
||||||
m_img = *img;
|
m_img = *img;
|
||||||
oxThrowError(readObj<Palette>(ctx, m_img.defaultPalette).moveTo(&m_pal));
|
oxThrowError(readObj<Palette>(ctx, m_img.defaultPalette).moveTo(&m_pal));
|
||||||
@ -46,6 +50,12 @@ void TileSheetEditorModel::ackUpdate() noexcept {
|
|||||||
m_updated = false;
|
m_updated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error TileSheetEditorModel::saveFile() noexcept {
|
||||||
|
oxRequire(buff, ox::writeClaw(&m_img));
|
||||||
|
oxReturnError(m_ctx->rom->write(m_path.c_str(), buff.data(), buff.size()));
|
||||||
|
return m_ctx->assetManager.setAsset(m_path, m_img).error;
|
||||||
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::getFillPixels(bool *pixels, const geo::Point &pt, int oldColor) const noexcept {
|
void TileSheetEditorModel::getFillPixels(bool *pixels, const geo::Point &pt, int oldColor) const noexcept {
|
||||||
const auto tileIdx = [this](const geo::Point &pt) noexcept {
|
const auto tileIdx = [this](const geo::Point &pt) noexcept {
|
||||||
return ptToIdx(pt, img().columns()) / PixelsPerTile;
|
return ptToIdx(pt, img().columns()) / PixelsPerTile;
|
||||||
|
@ -119,6 +119,8 @@ class TileSheetEditorModel {
|
|||||||
studio::UndoStack m_undoStack;
|
studio::UndoStack m_undoStack;
|
||||||
DrawCommand *m_ongoingDrawCommand = nullptr;
|
DrawCommand *m_ongoingDrawCommand = nullptr;
|
||||||
bool m_updated = false;
|
bool m_updated = false;
|
||||||
|
Context *m_ctx = nullptr;
|
||||||
|
ox::String m_path;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TileSheetEditorModel(Context *ctx, const ox::String &path);
|
TileSheetEditorModel(Context *ctx, const ox::String &path);
|
||||||
@ -149,6 +151,8 @@ class TileSheetEditorModel {
|
|||||||
|
|
||||||
void ackUpdate() noexcept;
|
void ackUpdate() noexcept;
|
||||||
|
|
||||||
|
ox::Error saveFile() noexcept;
|
||||||
|
|
||||||
constexpr studio::UndoStack *undoStack() noexcept {
|
constexpr studio::UndoStack *undoStack() noexcept {
|
||||||
return &m_undoStack;
|
return &m_undoStack;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ox/std/defines.hpp>
|
|
||||||
|
|
||||||
#include <ox/claw/read.hpp>
|
#include <ox/claw/read.hpp>
|
||||||
|
|
||||||
#include "typeconv.hpp"
|
#include "typeconv.hpp"
|
||||||
@ -40,6 +38,7 @@ struct TileSheetToCompactTileSheetConverter: public Converter<TileSheet, Compact
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifndef OX_BARE_METAL
|
#ifndef OX_BARE_METAL
|
||||||
|
|
||||||
static const auto converters = [] {
|
static const auto converters = [] {
|
||||||
ox::Vector<ox::UniquePtr<BaseConverter>, 3> converters;
|
ox::Vector<ox::UniquePtr<BaseConverter>, 3> converters;
|
||||||
converters.emplace_back(new NostalgiaGraphicToTileSheetConverter());
|
converters.emplace_back(new NostalgiaGraphicToTileSheetConverter());
|
||||||
@ -59,10 +58,12 @@ static auto findConverter(const ox::String &srcTypeName, int srcTypeVersion, con
|
|||||||
|
|
||||||
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, ox::ClawFormat fmt) noexcept {
|
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, ox::ClawFormat fmt) noexcept {
|
||||||
oxRequire(hdr, ox::readClawHeader(srcBuffer));
|
oxRequire(hdr, ox::readClawHeader(srcBuffer));
|
||||||
|
// look for direct converter
|
||||||
auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion);
|
auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion);
|
||||||
if (!err) { // try to chain multiple converters
|
if (!err) {
|
||||||
return c->convertBuffToBuff(srcBuffer);
|
return c->convertBuffToBuff(srcBuffer);
|
||||||
}
|
}
|
||||||
|
// try to chain multiple converters
|
||||||
for (const auto &subConverter : converters) {
|
for (const auto &subConverter : converters) {
|
||||||
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
|
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -12,11 +12,8 @@ add_executable(
|
|||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
nostalgia-studio
|
nostalgia-studio
|
||||||
OxClArgs
|
OxClArgs
|
||||||
OxFS
|
|
||||||
NostalgiaCore-Studio
|
NostalgiaCore-Studio
|
||||||
NostalgiaCore
|
|
||||||
NostalgiaStudio
|
NostalgiaStudio
|
||||||
NostalgiaPack
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
@ -43,8 +43,6 @@ target_link_libraries(
|
|||||||
imgui::imgui
|
imgui::imgui
|
||||||
${GTK3_LIBRARIES}
|
${GTK3_LIBRARIES}
|
||||||
OxEvent
|
OxEvent
|
||||||
OxFS
|
|
||||||
OxClaw
|
|
||||||
NostalgiaCore
|
NostalgiaCore
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,6 +28,16 @@ class UndoStack {
|
|||||||
void redo() noexcept;
|
void redo() noexcept;
|
||||||
|
|
||||||
void undo() noexcept;
|
void undo() noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool canRedo() noexcept {
|
||||||
|
return m_stackIdx < m_stack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool canUndo() noexcept {
|
||||||
|
return m_stackIdx;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -39,14 +39,14 @@ StudioUI::StudioUI(core::Context *ctx) noexcept {
|
|||||||
if (!err) {
|
if (!err) {
|
||||||
oxIgnoreError(openProject(config.projectPath));
|
oxIgnoreError(openProject(config.projectPath));
|
||||||
for (const auto &f : config.openFiles) {
|
for (const auto &f : config.openFiles) {
|
||||||
auto err = openFile(f);
|
auto openFileErr = openFile(f);
|
||||||
if (err) {
|
if (openFileErr) {
|
||||||
oxErrorf("Could not open editor: {}\n", err.msg);
|
oxErrorf("Could not open editor: {}\n", toStr(openFileErr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (err.msg) {
|
if (toStr(err)) {
|
||||||
oxErrf("Could not open studio config file: {}\n", err.msg);
|
oxErrf("Could not open studio config file: {}\n", toStr(err));
|
||||||
} else {
|
} 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, err.file, err.line);
|
||||||
}
|
}
|
||||||
@ -83,7 +83,8 @@ void StudioUI::drawMenu() noexcept {
|
|||||||
if (ImGui::MenuItem("Open Project...", "Ctrl+O")) {
|
if (ImGui::MenuItem("Open Project...", "Ctrl+O")) {
|
||||||
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
|
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Save", "Ctrl+S", false, m_saveEnabled)) {
|
if (ImGui::MenuItem("Save", "Ctrl+S", false, m_acitveEditor && m_acitveEditor->unsavedChanges())) {
|
||||||
|
m_acitveEditor->save();
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Quit", "Ctrl+Q")) {
|
if (ImGui::MenuItem("Quit", "Ctrl+Q")) {
|
||||||
oxIgnoreError(core::shutdown(m_ctx));
|
oxIgnoreError(core::shutdown(m_ctx));
|
||||||
@ -92,14 +93,14 @@ void StudioUI::drawMenu() noexcept {
|
|||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("Edit")) {
|
if (ImGui::BeginMenu("Edit")) {
|
||||||
auto undoStack = m_acitveEditor ? m_acitveEditor->undoStack() : nullptr;
|
auto undoStack = m_acitveEditor ? m_acitveEditor->undoStack() : nullptr;
|
||||||
if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack)) {
|
if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack && undoStack->canUndo())) {
|
||||||
m_acitveEditor->undoStack()->undo();
|
m_acitveEditor->undoStack()->undo();
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack)) {
|
if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack && undoStack->canRedo())) {
|
||||||
m_acitveEditor->undoStack()->redo();
|
m_acitveEditor->undoStack()->redo();
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("Copy", "Ctrl+N")) {
|
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
|
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
|
||||||
}
|
}
|
||||||
@ -139,7 +140,11 @@ void StudioUI::drawToolbar() noexcept {
|
|||||||
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
|
m_taskRunner.add(new FileDialogManager(this, &StudioUI::openProject));
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Button("Save##MainToolbar##MainWindow", ImVec2(BtnWidth, BtnHeight));
|
if (ImGui::Button("Save##MainToolbar##MainWindow", ImVec2(BtnWidth, BtnHeight))) {
|
||||||
|
if (m_acitveEditor) {
|
||||||
|
m_acitveEditor->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@ target_link_libraries(
|
|||||||
NostalgiaPack
|
NostalgiaPack
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
# enable LTO
|
||||||
|
set_property(TARGET nost-pack PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS
|
TARGETS
|
||||||
nost-pack
|
nost-pack
|
||||||
|
@ -6,10 +6,7 @@ add_library(
|
|||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaPack PUBLIC
|
NostalgiaPack PUBLIC
|
||||||
OxClaw
|
|
||||||
OxFS
|
|
||||||
NostalgiaCore-Headless
|
NostalgiaCore-Headless
|
||||||
NostalgiaGeo
|
|
||||||
)
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user