managed autosave deletion
This commit is contained in:
@@ -271,6 +271,8 @@ namespace anm2ed::imgui
|
||||
bool isValid = spritesheet->is_valid();
|
||||
auto& texture = isValid ? spritesheet->texture : resources.icons[icon::NONE];
|
||||
auto tintColor = !isValid ? ImVec4(1.0f, 0.25f, 0.25f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
static std::vector<int> dragDropSelection{};
|
||||
bool isRegionDragDropSourceSubmitted = false;
|
||||
|
||||
for (int i = 0; i < (int)spritesheet->regionOrder.size(); i++)
|
||||
{
|
||||
@@ -324,17 +326,19 @@ namespace anm2ed::imgui
|
||||
auto tooltipPadding = style.WindowPadding.x * 4.0f;
|
||||
auto minWidth = previewSize.x + style.ItemSpacing.x + textWidth + tooltipPadding;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(minWidth, 0), ImGuiCond_Appearing);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
{
|
||||
ImGui::SetNextWindowSize(ImVec2(minWidth, 0), ImGuiCond_Appearing);
|
||||
if (ImGui::BeginItemTooltip())
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2());
|
||||
auto childFlags = ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY;
|
||||
auto noScrollFlags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
|
||||
if (ImGui::BeginChild("##Region Tooltip Image Child", to_imvec2(previewSize), childFlags, noScrollFlags))
|
||||
if (ImGui::BeginChild("##Region Tooltip Image Child", to_imvec2(previewSize), childFlags,
|
||||
noScrollFlags))
|
||||
ImGui::ImageWithBg(texture.id, to_imvec2(previewSize), to_imvec2(uvMin), to_imvec2(uvMax), ImVec4(),
|
||||
tintColor);
|
||||
ImGui::EndChild();
|
||||
@@ -365,7 +369,8 @@ namespace anm2ed::imgui
|
||||
else
|
||||
{
|
||||
StringType originString = LABEL_REGION_ORIGIN_CENTER;
|
||||
if (region.origin == anm2::Spritesheet::Region::TOP_LEFT) originString = LABEL_REGION_ORIGIN_TOP_LEFT;
|
||||
if (region.origin == anm2::Spritesheet::Region::TOP_LEFT)
|
||||
originString = LABEL_REGION_ORIGIN_TOP_LEFT;
|
||||
auto originLabel = localize.get(originString);
|
||||
ImGui::TextUnformatted(
|
||||
std::vformat(localize.get(FORMAT_ORIGIN), std::make_format_args(originLabel)).c_str());
|
||||
@@ -374,28 +379,22 @@ namespace anm2ed::imgui
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
||||
if (ImGui::BeginDragDropSource())
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip))
|
||||
{
|
||||
static std::vector<int> dragDropSelection{};
|
||||
isRegionDragDropSourceSubmitted = true;
|
||||
if (selection.contains(id))
|
||||
dragDropSelection.assign(selection.begin(), selection.end());
|
||||
else
|
||||
dragDropSelection = {id};
|
||||
|
||||
ImGui::SetDragDropPayload("Region Drag Drop", dragDropSelection.data(),
|
||||
dragDropSelection.size() * sizeof(int));
|
||||
|
||||
for (auto regionId : dragDropSelection)
|
||||
{
|
||||
auto dragIt = spritesheet->regions.find(regionId);
|
||||
if (dragIt == spritesheet->regions.end()) continue;
|
||||
ImGui::TextUnformatted(dragIt->second.name.c_str());
|
||||
}
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (auto payload = ImGui::AcceptDragDropPayload("Region Drag Drop"))
|
||||
@@ -450,6 +449,36 @@ namespace anm2ed::imgui
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
auto regionDragPayload = ImGui::GetDragDropPayload();
|
||||
bool isRegionDragActive = regionDragPayload && regionDragPayload->IsDataType("Region Drag Drop");
|
||||
if (isRegionDragActive && !isRegionDragDropSourceSubmitted && !dragDropSelection.empty() &&
|
||||
ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceExtern | ImGuiDragDropFlags_SourceNoPreviewTooltip))
|
||||
{
|
||||
ImGui::SetDragDropPayload("Region Drag Drop", dragDropSelection.data(),
|
||||
dragDropSelection.size() * sizeof(int));
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
|
||||
if (isRegionDragActive && !dragDropSelection.empty())
|
||||
{
|
||||
auto mousePos = ImGui::GetIO().MousePos;
|
||||
auto tooltipOffset = ImVec2(16.0f, 16.0f);
|
||||
ImGui::SetNextWindowPos(ImVec2(mousePos.x + tooltipOffset.x, mousePos.y + tooltipOffset.y));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
for (auto regionId : dragDropSelection)
|
||||
{
|
||||
auto dragIt = spritesheet->regions.find(regionId);
|
||||
if (dragIt == spritesheet->regions.end()) continue;
|
||||
ImGui::TextUnformatted(dragIt->second.name.c_str());
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
selection.finish();
|
||||
|
||||
|
||||
@@ -1174,6 +1174,10 @@ namespace anm2ed::imgui
|
||||
}
|
||||
};
|
||||
|
||||
float playheadLineCenterX{};
|
||||
float playheadLineTopY{};
|
||||
bool isPlayheadLineSet{};
|
||||
|
||||
auto frame_child = [&](anm2::Type type, int id, int& index, float width)
|
||||
{
|
||||
auto item = animation ? animation->item_get(type, id) : nullptr;
|
||||
@@ -1307,6 +1311,11 @@ namespace anm2ed::imgui
|
||||
{
|
||||
ImGui::SetCursorPos(ImVec2(cursorPos.x + frameSize.x * floorf(playback.time), cursorPos.y));
|
||||
ImGui::Image(resources.icons[icon::PLAYHEAD].id, frameSize);
|
||||
auto playheadMin = ImGui::GetItemRectMin();
|
||||
auto playheadMax = ImGui::GetItemRectMax();
|
||||
playheadLineCenterX = (playheadMin.x + playheadMax.x) * 0.5f;
|
||||
playheadLineTopY = playheadMax.y;
|
||||
isPlayheadLineSet = true;
|
||||
overlay_icon(resources.icons[icon::PLAYHEAD].id, playheadIconTint, true);
|
||||
}
|
||||
}
|
||||
@@ -1686,7 +1695,9 @@ namespace anm2ed::imgui
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2());
|
||||
if (ImGui::BeginChild("##Frames List Child", viewListChildSize, true, ImGuiWindowFlags_HorizontalScrollbar))
|
||||
{
|
||||
auto cursorScreenPos = ImGui::GetCursorScreenPos();
|
||||
playheadLineCenterX = 0.0f;
|
||||
playheadLineTopY = 0.0f;
|
||||
isPlayheadLineSet = false;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2());
|
||||
if (ImGui::BeginTable("##Frames List Table", 1,
|
||||
@@ -1757,20 +1768,17 @@ namespace anm2ed::imgui
|
||||
|
||||
ImDrawList* windowDrawList = ImGui::GetWindowDrawList();
|
||||
|
||||
auto frameSize = ImVec2(ImGui::GetTextLineHeight(),
|
||||
ImGui::GetTextLineHeightWithSpacing() + (ImGui::GetStyle().WindowPadding.y * 2));
|
||||
auto playheadIndex = std::floor(playback.time);
|
||||
auto lineCenterX = cursorScreenPos.x + frameSize.x * (playheadIndex + 0.6f) - scroll.x;
|
||||
auto linePos =
|
||||
ImVec2(lineCenterX - (PLAYHEAD_LINE_THICKNESS * 0.5f), cursorScreenPos.y + (frameSize.y * 2.0f));
|
||||
auto lineSize = ImVec2((PLAYHEAD_LINE_THICKNESS / 2.0f),
|
||||
viewListChildSize.y - frameSize.y -
|
||||
(isHorizontalScroll ? ImGui::GetStyle().ScrollbarSize * 2.0f : 0.0f));
|
||||
auto lineBottomY = ImGui::GetWindowPos().y + ImGui::GetWindowSize().y;
|
||||
if (isHorizontalScroll) lineBottomY -= ImGui::GetStyle().ScrollbarSize;
|
||||
|
||||
auto rectMin = windowDrawList->GetClipRectMin();
|
||||
auto rectMax = windowDrawList->GetClipRectMax();
|
||||
if (pickerLineDrawList)
|
||||
if (pickerLineDrawList && isPlayheadLineSet && lineBottomY > playheadLineTopY)
|
||||
{
|
||||
auto linePos =
|
||||
ImVec2(playheadLineCenterX - (PLAYHEAD_LINE_THICKNESS * 0.5f), playheadLineTopY);
|
||||
auto lineSize =
|
||||
ImVec2((PLAYHEAD_LINE_THICKNESS / 2.0f), std::max(0.0f, lineBottomY - playheadLineTopY));
|
||||
pickerLineDrawList->PushClipRect(rectMin, rectMax);
|
||||
pickerLineDrawList->AddRectFilled(linePos, ImVec2(linePos.x + lineSize.x, linePos.y + lineSize.y),
|
||||
ImGui::GetColorU32(playheadLineColor));
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace anm2ed::imgui::wizard
|
||||
|
||||
ImGui::BeginDisabled(!isRaw);
|
||||
{
|
||||
input_float_range(localize.get(BASIC_SCALE), scale, 0.1f, 100.0f, 0.1f, STEP_FAST, "%.1fx");
|
||||
input_float_range(localize.get(BASIC_SCALE), scale, 0.1f, 100.0f, 1.0f, STEP_FAST, "%.1fx");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SCALE_OUTPUT));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
+36
-19
@@ -30,6 +30,15 @@ namespace anm2ed
|
||||
std::filesystem::create_directories(parent, ec);
|
||||
if (ec) logger.warning(std::format("Could not create directory for {}: {}", path::to_utf8(path), ec.message()));
|
||||
}
|
||||
|
||||
void autosave_file_remove(const std::filesystem::path& path)
|
||||
{
|
||||
if (path.empty()) return;
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::selection_history_push(int index)
|
||||
@@ -107,10 +116,22 @@ namespace anm2ed
|
||||
{
|
||||
std::string errorString{};
|
||||
ensure_parent_directory_exists(path);
|
||||
const auto previousAutosavePath = document->autosave_path_get();
|
||||
document->path = !path.empty() ? path : document->path;
|
||||
document->path.replace_extension(".anm2");
|
||||
document->save(document->path, &errorString, compatibility, isBakeSpecialInterpolatedFramesOnSave, isRoundScale,
|
||||
isRoundRotation);
|
||||
const auto autosavePath = document->autosave_path_get();
|
||||
if (document->save(document->path, &errorString, compatibility, isBakeSpecialInterpolatedFramesOnSave,
|
||||
isRoundScale, isRoundRotation))
|
||||
{
|
||||
autosaveFiles.erase(std::remove(autosaveFiles.begin(), autosaveFiles.end(), previousAutosavePath),
|
||||
autosaveFiles.end());
|
||||
if (autosavePath != previousAutosavePath)
|
||||
autosaveFiles.erase(std::remove(autosaveFiles.begin(), autosaveFiles.end(), autosavePath),
|
||||
autosaveFiles.end());
|
||||
autosave_file_remove(previousAutosavePath);
|
||||
autosave_file_remove(autosavePath);
|
||||
autosave_files_write();
|
||||
}
|
||||
recent_file_add(document->path);
|
||||
}
|
||||
}
|
||||
@@ -142,15 +163,6 @@ namespace anm2ed
|
||||
|
||||
const auto autosavePath = documents[index].autosave_path_get();
|
||||
autosaveFiles.erase(std::remove(autosaveFiles.begin(), autosaveFiles.end(), autosavePath), autosaveFiles.end());
|
||||
|
||||
if (!autosavePath.empty())
|
||||
{
|
||||
std::error_code ec{};
|
||||
std::filesystem::remove(autosavePath, ec);
|
||||
if (ec)
|
||||
logger.warning(std::format("Could not remove autosave file {}: {}", path::to_utf8(autosavePath), ec.message()));
|
||||
}
|
||||
|
||||
autosave_files_write();
|
||||
|
||||
documents.erase(documents.begin() + index);
|
||||
@@ -351,6 +363,8 @@ namespace anm2ed
|
||||
|
||||
void Manager::autosave_files_open()
|
||||
{
|
||||
std::vector<std::filesystem::path> restoredFiles{};
|
||||
|
||||
for (auto& path : autosaveFiles)
|
||||
{
|
||||
if (auto document = open(path, false, false))
|
||||
@@ -358,10 +372,16 @@ namespace anm2ed
|
||||
document->isForceDirty = true;
|
||||
document->path = document->path_from_autosave_get(path);
|
||||
document->change(Document::ALL);
|
||||
restoredFiles.emplace_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
autosave_files_clear();
|
||||
for (auto& path : restoredFiles)
|
||||
{
|
||||
autosaveFiles.erase(std::remove(autosaveFiles.begin(), autosaveFiles.end(), path), autosaveFiles.end());
|
||||
autosave_file_remove(path);
|
||||
}
|
||||
autosave_files_write();
|
||||
}
|
||||
|
||||
void Manager::autosave_files_load()
|
||||
@@ -401,14 +421,11 @@ namespace anm2ed
|
||||
std::format("Could not write autosave files to: {}. Skipping...", path::to_utf8(autosave_path_get())));
|
||||
}
|
||||
|
||||
void Manager::autosave_files_clear()
|
||||
void Manager::autosave_files_clear(bool removeFiles)
|
||||
{
|
||||
if (removeFiles)
|
||||
for (auto& path : autosaveFiles)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
autosave_file_remove(path);
|
||||
|
||||
autosaveFiles.clear();
|
||||
autosave_files_write();
|
||||
@@ -420,5 +437,5 @@ namespace anm2ed
|
||||
chords[i] = imgui::string_to_chord(settings.*SHORTCUT_MEMBERS[i]);
|
||||
}
|
||||
|
||||
Manager::~Manager() { autosave_files_clear(); }
|
||||
Manager::~Manager() = default;
|
||||
}
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ namespace anm2ed
|
||||
void autosave_files_load();
|
||||
void autosave_files_open();
|
||||
void autosave_files_write();
|
||||
void autosave_files_clear();
|
||||
void autosave_files_clear(bool removeFiles = false);
|
||||
|
||||
void chords_set(Settings&);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user