diff --git a/src/imgui/window/animations.cpp b/src/imgui/window/animations.cpp index a5f37dd..df67422 100644 --- a/src/imgui/window/animations.cpp +++ b/src/imgui/window/animations.cpp @@ -209,6 +209,7 @@ namespace anm2ed::imgui if (ImGui::BeginChild("##Animations Child", childSize, ImGuiChildFlags_Borders)) { + selection.start(anm2.animations.items.size()); for (auto [i, animation] : std::views::enumerate(anm2.animations.items)) @@ -249,11 +250,17 @@ namespace anm2ed::imgui if (isNewAnimation) { - ImGui::SetScrollHereY(0.5f); + isUpdateScroll = true; newAnimationSelectedIndex = -1; } ImGui::PopFont(); + if (isUpdateScroll && isReferenced) + { + ImGui::SetScrollHereY(0.5f); + isUpdateScroll = false; + } + if (ImGui::BeginItemTooltip()) { ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE); @@ -468,5 +475,19 @@ namespace anm2ed::imgui } } ImGui::End(); + + auto isNextAnimation = shortcut(manager.chords[SHORTCUT_NEXT_ANIMATION], shortcut::GLOBAL); + auto isPreviousAnimation = shortcut(manager.chords[SHORTCUT_PREVIOUS_ANIMATION], shortcut::GLOBAL); + + if ((isPreviousAnimation || isNextAnimation) && !anm2.animations.items.empty()) + { + if (isPreviousAnimation) + reference.animationIndex = glm::clamp(--reference.animationIndex, 0, (int)anm2.animations.items.size() - 1); + if (isNextAnimation) + reference.animationIndex = glm::clamp(++reference.animationIndex, 0, (int)anm2.animations.items.size() - 1); + + selection = {reference.animationIndex}; + isUpdateScroll = true; + } } -} \ No newline at end of file +} diff --git a/src/imgui/window/animations.h b/src/imgui/window/animations.h index 0a08fea..82be436 100644 --- a/src/imgui/window/animations.h +++ b/src/imgui/window/animations.h @@ -14,6 +14,7 @@ namespace anm2ed::imgui int newAnimationSelectedIndex{-1}; int renameQueued{-1}; bool isInContextMenu{}; + bool isUpdateScroll{}; RenameState renameState{RENAME_SELECTABLE}; public: diff --git a/src/imgui/window/timeline.cpp b/src/imgui/window/timeline.cpp index 2adc659..f1c7463 100644 --- a/src/imgui/window/timeline.cpp +++ b/src/imgui/window/timeline.cpp @@ -1866,21 +1866,21 @@ namespace anm2ed::imgui } isExtendChordHeld = isExtendFrame; - if (shortcut(manager.chords[SHORTCUT_PREVIOUS_FRAME], shortcut::GLOBAL)) - { - if (auto item = document.item_get(); !item->frames.empty()) - { - reference.frameIndex = glm::clamp(--reference.frameIndex, 0, (int)item->frames.size() - 1); - frames_selection_set_reference(); - document.frameTime = item->frame_time_from_index_get(reference.frameIndex); - } - } + auto isPreviousFrame = shortcut(manager.chords[SHORTCUT_PREVIOUS_FRAME], shortcut::GLOBAL); + auto isNextFrame = shortcut(manager.chords[SHORTCUT_NEXT_FRAME], shortcut::GLOBAL); - if (shortcut(manager.chords[SHORTCUT_NEXT_FRAME], shortcut::GLOBAL)) + if (isPreviousFrame) + if (auto item = document.item_get(); !item->frames.empty()) + reference.frameIndex = glm::clamp(--reference.frameIndex, 0, (int)item->frames.size() - 1); + + if (isNextFrame) + if (auto item = document.item_get(); !item->frames.empty()) + reference.frameIndex = glm::clamp(++reference.frameIndex, 0, (int)item->frames.size() - 1); + + if (isPreviousFrame || isNextFrame) { if (auto item = document.item_get(); !item->frames.empty()) { - reference.frameIndex = glm::clamp(++reference.frameIndex, 0, (int)item->frames.size() - 1); frames_selection_set_reference(); document.frameTime = item->frame_time_from_index_get(reference.frameIndex); } diff --git a/src/manager.cpp b/src/manager.cpp index 4446ad4..7a537b2 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -115,7 +115,7 @@ namespace anm2ed { std::string errorString{}; auto autosavePath = document.autosave_path_get(); - document.autosave(&errorString); + if (!document.autosave(&errorString)) return; autosaveFiles.erase(std::remove(autosaveFiles.begin(), autosaveFiles.end(), autosavePath), autosaveFiles.end()); autosaveFiles.insert(autosaveFiles.begin(), autosavePath); @@ -392,16 +392,25 @@ namespace anm2ed ensure_parent_directory_exists(autosave_path_get()); autosaveWriteFile.open(autosave_path_get(), std::ofstream::out | std::ofstream::trunc); + if (!autosaveWriteFile.is_open()) + { + logger.warning(std::format("Could not write autosave files to: {}. Skipping...", path::to_utf8(autosave_path_get()))); + return; + } + for (auto& path : autosaveFiles) autosaveWriteFile << path::to_utf8(path) << "\n"; - - autosaveWriteFile.close(); } void Manager::autosave_files_clear() { for (auto& path : autosaveFiles) - std::filesystem::remove(path); + { + std::error_code ec{}; + std::filesystem::remove(path, ec); + if (ec) + logger.warning(std::format("Could not remove autosave file {}: {}", path::to_utf8(path), ec.message())); + } autosaveFiles.clear(); autosave_files_write(); diff --git a/src/resource/strings.h b/src/resource/strings.h index 639a319..c5a731a 100644 --- a/src/resource/strings.h +++ b/src/resource/strings.h @@ -358,6 +358,7 @@ namespace anm2ed X(SHORTCUT_STRING_MERGE, "Merge", "Combinar", "Соединить", "合并", "병합") \ X(SHORTCUT_STRING_MOVE, "Move", "Mover", "Передвинуть", "移动", "이동") \ X(SHORTCUT_STRING_NEW, "New", "Nuevo", "Новый", "新", "새 파일") \ + X(SHORTCUT_STRING_NEXT_ANIMATION, "Next Animation", "Siguiente Animacion", "Следующая анимация", "下一动画", "다음 애니메이션") \ X(SHORTCUT_STRING_NEXT_FRAME, "Next Frame", "Siguiente Frame", "Следующий кадр", "下一帧", "다음 프레임") \ X(SHORTCUT_STRING_ONIONSKIN, "Onionskin", "Papel Cebolla", "Оньонскин", "洋葱皮预览", "전후 비교") \ X(SHORTCUT_STRING_OPEN, "Open", "Abrir", "Открыть", "打开", "열기") \ @@ -366,6 +367,7 @@ namespace anm2ed X(SHORTCUT_STRING_PLAYHEAD_BACK, "Playhead Back", "Cabezal Atras", "Назад воспроизводящей головкой", "播放指针往后", "플레이헤드 뒤로") \ X(SHORTCUT_STRING_PLAYHEAD_FORWARD, "Playhead Forward", "Cabezal Adelante", "Вперед воспроизводящей головкой", "播放指针往前", "플레이헤드 앞으로") \ X(SHORTCUT_STRING_PLAY_PAUSE, "Play/Pause", "Reproducir/Pausar", "Возпроизвести/Пауза", "播放/暂停", "재생/일시정지") \ + X(SHORTCUT_STRING_PREVIOUS_ANIMATION, "Previous Animation", "Animacion Anterior", "Предыдущая анимация", "上一动画", "이전 애니메이션") \ X(SHORTCUT_STRING_PREVIOUS_FRAME, "Previous Frame", "Frame Anterior", "Предыдущий кадр", "前一帧", "이전 프레임") \ X(SHORTCUT_STRING_REDO, "Redo", "Rehacer", "Повторить", "重做", "다시 실행") \ X(SHORTCUT_STRING_RENAME, "Rename", "Renombrar", "Переименовать", "重命名", "이름 변경") \ diff --git a/src/settings.h b/src/settings.h index c2c3396..43e0f24 100644 --- a/src/settings.h +++ b/src/settings.h @@ -227,6 +227,9 @@ namespace anm2ed X(SHORTCUT_INSERT_FRAME, shortcutInsertFrame, SHORTCUT_STRING_INSERT_FRAME, STRING, "F6") \ X(SHORTCUT_PREVIOUS_FRAME, shortcutPreviousFrame, SHORTCUT_STRING_PREVIOUS_FRAME, STRING, "F7") \ X(SHORTCUT_NEXT_FRAME, shortcutNextFrame, SHORTCUT_STRING_NEXT_FRAME, STRING, "F8") \ + /* Animations */ \ + X(SHORTCUT_PREVIOUS_ANIMATION, shortcutPreviousAnimation, SHORTCUT_STRING_PREVIOUS_ANIMATION, STRING, "F9") \ + X(SHORTCUT_NEXT_ANIMATION, shortcutNextAnimation, SHORTCUT_STRING_NEXT_ANIMATION, STRING, "F10") \ /* Toggles */ \ X(SHORTCUT_ONIONSKIN, shortcutOnionskin, SHORTCUT_STRING_ONIONSKIN, STRING, "O") diff --git a/src/util/working_directory.cpp b/src/util/working_directory.cpp index 91ee5ac..42118cf 100644 --- a/src/util/working_directory.cpp +++ b/src/util/working_directory.cpp @@ -1,19 +1,48 @@ #include "working_directory.h" +#include + +#include "log.h" +#include "path_.h" + namespace anm2ed::util { WorkingDirectory::WorkingDirectory(const std::filesystem::path& path, Type type) { - previous = std::filesystem::current_path(); + std::error_code ec{}; + previous = std::filesystem::current_path(ec); + if (ec) + { + logger.warning(std::format("Could not query current directory: {}", ec.message())); + previous.clear(); + ec.clear(); + } + if (type == FILE) { std::filesystem::path filePath = path; std::filesystem::path parentPath = filePath.parent_path(); - std::filesystem::current_path(parentPath); + std::filesystem::current_path(parentPath, ec); + if (ec) + logger.warning( + std::format("Could not set current directory to {}: {}", path::to_utf8(parentPath), ec.message())); } else - std::filesystem::current_path(path); + { + std::filesystem::current_path(path, ec); + if (ec) + logger.warning(std::format("Could not set current directory to {}: {}", path::to_utf8(path), ec.message())); + } } - WorkingDirectory::~WorkingDirectory() { std::filesystem::current_path(previous); } -} \ No newline at end of file + WorkingDirectory::~WorkingDirectory() + { + if (previous.empty()) return; + + std::error_code ec{}; + std::filesystem::current_path(previous, ec); + if (ec) + logger.warning( + std::format("Could not restore current directory to {}: {}", path::to_utf8(previous), ec.message())); + } +}