Squashed 'deps/nostalgia/' changes from 804d78e1..2a8e3c2d

2a8e3c2d [nostalgia/gfx] Remove unnecessary cast
998066d3 [ox/std] Add comparison functions
fefb876f [nostalgia/gfx] Add checks for GCC version for warning suppression
5979e988 [jsoncpp] Up required CMake version
a17abe46 [nfde] Up required CMake version
d62f9138 [nostalgia/gfx] Suppress some superfluous warnings
12bb7475 [nostalgia/gfx/studio/tilesheet] Adjust pixel line size on Windows
df2c7e2b [nostalgia] Update release notes
713aec88 [buildcore] Change mypy invokation
3089cd7a Change builder type to olympic
00638bc8 [nostalgia/gfx/studio/tilesheet] Mark DrawCommands as obsolete if no changes
e0021098 [studio] Make undo/redo skip over obsolete commands
b4798fd2 [nostalgia/gfx/studio/tilesheet] Make rotate only available for square subsheets or selections
3c804bf6 [studio] Give MakeCopy popup an error message for files that already exist
d39d552b [nostalgia/studio] Update icon to higher resolution
b7202a2b [nostalgia/player] Disable Keel mods on GBA
4e27a4c1 [nostalgia/core/studio/tilesheet] Fix palette path display update
4ef31762 [nostalgia/core/studio/tilesheet] Cleanup
8b22a8f3 [keel] Make buildUuidMap only read the first 40 bytes of each file
d45ff05b [ox/fs] Add new partial file read functions
671dd862 [keel,studio] Add Make Copy option to ProjectExplorer
0abadc18 [studio] Fix QuestionPopup to only emit a response when there is a response
4e068d62 [studio] Fix misrender flash on tab close
4461f99f [studio] Add Ctrl-W shortcut for closing active tab
cd1f4bda [studio] Add confirmation for closing file with unsaved changes
47286995 [studio] Add combobox that will take string views
105a1e55 [nostalgia/core/studio/tilesheet] Rework operation ctrls into a dropbox
1bc18e34 [nostalgia/core/studio/tilesheet] Add ability to rotate a selection
fb8d295f [nostalgia/core/studio/tilesheet] Add rotate functionality

git-subtree-dir: deps/nostalgia
git-subtree-split: 2a8e3c2dc44642fd9fef6bc8b645ad966f0277da
This commit is contained in:
2025-02-19 00:34:26 -06:00
parent c42adc290c
commit a6b9657268
43 changed files with 817 additions and 72 deletions

View File

@@ -225,6 +225,18 @@ PopupResponse PopupControlsOkCancel(
[[nodiscard]]
bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show, ImVec2 const&sz = {285, 0});
/**
*
* @param lbl
* @param list
* @param selectedIdx
* @return true if new value selected, false otherwise
*/
bool ComboBox(
ox::CStringView lbl,
ox::SpanView<ox::CStringView> list,
size_t &selectedIdx) noexcept;
/**
*
* @param lbl
@@ -291,6 +303,34 @@ class FilePicker {
};
class QuestionPopup {
private:
enum class Stage {
Closed,
Opening,
Open,
};
Stage m_stage = Stage::Closed;
bool m_open{};
ox::String m_title;
ox::String m_question;
public:
ox::Signal<ox::Error(ig::PopupResponse)> response;
QuestionPopup(ox::StringParam title, ox::StringParam question) noexcept;
void open() noexcept;
void close() noexcept;
[[nodiscard]]
bool isOpen() const noexcept;
void draw(StudioContext &ctx, ImVec2 const &sz = {}) noexcept;
};
[[nodiscard]]
bool mainWinHasFocus() noexcept;

View File

@@ -92,6 +92,8 @@ class Project: public ox::SignalHandler {
ox::Result<ox::FileStat> stat(ox::StringViewCR path) const noexcept;
ox::Error copyItem(ox::StringViewCR src, ox::StringViewCR dest) noexcept;
ox::Error moveItem(ox::StringViewCR src, ox::StringViewCR dest) noexcept;
ox::Error moveDir(ox::StringViewCR src, ox::StringViewCR dest) noexcept;

View File

@@ -90,6 +90,25 @@ bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show,
return ImGui::BeginPopupModal(popupName.c_str(), &show, modalFlags);
}
bool ComboBox(
ox::CStringView lbl,
ox::SpanView<ox::CStringView> list,
size_t &selectedIdx) noexcept {
bool out{};
auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : "";
if (ImGui::BeginCombo(lbl.c_str(), first, 0)) {
for (auto i = 0u; i < list.size(); ++i) {
const auto selected = (selectedIdx == i);
if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) {
selectedIdx = i;
out = true;
}
}
ImGui::EndCombo();
}
return out;
}
bool ComboBox(
ox::CStringView lbl,
ox::Span<const ox::String> list,
@@ -206,6 +225,60 @@ void FilePicker::show() noexcept {
m_show = true;
}
QuestionPopup::QuestionPopup(ox::StringParam title, ox::StringParam question) noexcept:
m_title{std::move(title)},
m_question{std::move(question)} {
}
void QuestionPopup::open() noexcept {
m_stage = Stage::Opening;
}
void QuestionPopup::close() noexcept {
m_stage = Stage::Closed;
m_open = false;
}
bool QuestionPopup::isOpen() const noexcept {
return m_open;
}
void QuestionPopup::draw(StudioContext &ctx, ImVec2 const &sz) noexcept {
switch (m_stage) {
case Stage::Closed:
break;
case Stage::Opening:
ImGui::OpenPopup(m_title.c_str());
m_stage = Stage::Open;
m_open = true;
[[fallthrough]];
case Stage::Open:
centerNextWindow(ctx.tctx);
ImGui::SetNextWindowSize(static_cast<ImVec2>(sz));
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
if (ImGui::BeginPopupModal(m_title.c_str(), &m_open, modalFlags)) {
ImGui::Text("%s", m_question.c_str());
auto const r = PopupControlsOkCancel(m_open, "Yes", "No");
switch (r) {
case PopupResponse::None:
break;
case PopupResponse::OK:
response.emit(r);
close();
break;
case PopupResponse::Cancel:
response.emit(r);
close();
break;
}
ImGui::EndPopup();
}
break;
}
}
bool s_mainWinHasFocus{};
bool mainWinHasFocus() noexcept {
return s_mainWinHasFocus;

View File

@@ -97,6 +97,14 @@ ox::Result<ox::FileStat> Project::stat(ox::StringViewCR path) const noexcept {
return m_fs.stat(path);
}
ox::Error Project::copyItem(ox::StringViewCR src, ox::StringViewCR dest) noexcept {
OX_REQUIRE_M(buff, loadBuff(src));
OX_REQUIRE(id, keel::regenerateUuidHeader(buff));
OX_RETURN_ERROR(writeBuff(dest, buff));
createUuidMapping(m_kctx, dest, id);
return {};
}
ox::Error Project::moveItem(ox::StringViewCR src, ox::StringViewCR dest) noexcept {
OX_RETURN_ERROR(m_fs.move(src, dest));
OX_RETURN_ERROR(keel::updatePath(m_kctx, src, dest));

View File

@@ -7,9 +7,7 @@
namespace studio {
ox::Error UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept {
for (auto const i = m_stackIdx; i < m_stack.size();) {
std::ignore = m_stack.erase(i);
}
m_stack.resize(m_stackIdx);
OX_RETURN_ERROR(cmd->redo());
redoTriggered.emit(cmd.get());
changeTriggered.emit(cmd.get());
@@ -25,22 +23,29 @@ ox::Error UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept {
}
ox::Error UndoStack::redo() noexcept {
if (m_stackIdx < m_stack.size()) {
auto &c = m_stack[m_stackIdx];
OX_RETURN_ERROR(c->redo());
while (m_stackIdx < m_stack.size()) {
auto const &c = m_stack[m_stackIdx];
++m_stackIdx;
redoTriggered.emit(c.get());
changeTriggered.emit(c.get());
if (!c->isObsolete()) {
OX_RETURN_ERROR(c->redo());
redoTriggered.emit(c.get());
changeTriggered.emit(c.get());
break;
}
}
return {};
}
ox::Error UndoStack::undo() noexcept {
if (m_stackIdx) {
auto &c = m_stack[--m_stackIdx];
OX_RETURN_ERROR(c->undo());
undoTriggered.emit(c.get());
changeTriggered.emit(c.get());
while (m_stackIdx) {
--m_stackIdx;
auto const &c = m_stack[m_stackIdx];
if (!c->isObsolete()) {
OX_RETURN_ERROR(c->undo());
undoTriggered.emit(c.get());
changeTriggered.emit(c.get());
break;
}
}
return {};
}