.........................................................
This commit is contained in:
@@ -7,6 +7,10 @@
|
|||||||
#include "anm2_type.h"
|
#include "anm2_type.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#if defined(TRANSPARENT)
|
||||||
|
#undef TRANSPARENT
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace anm2ed::anm2
|
namespace anm2ed::anm2
|
||||||
{
|
{
|
||||||
constexpr auto FRAME_DURATION_MIN = 1;
|
constexpr auto FRAME_DURATION_MIN = 1;
|
||||||
@@ -53,4 +57,4 @@ namespace anm2ed::anm2
|
|||||||
};
|
};
|
||||||
|
|
||||||
#undef MEMBERS
|
#undef MEMBERS
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ using namespace tinyxml2;
|
|||||||
|
|
||||||
namespace anm2ed::anm2
|
namespace anm2ed::anm2
|
||||||
{
|
{
|
||||||
Sound::Sound(const Sound& other) : path(other.path) { audio = path.empty() ? Audio() : Audio(path.c_str()); }
|
Sound::Sound(const Sound& other) : path(other.path) { audio = path.empty() ? Audio() : Audio(path); }
|
||||||
|
|
||||||
Sound& Sound::operator=(const Sound& other)
|
Sound& Sound::operator=(const Sound& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
path = other.path;
|
path = other.path;
|
||||||
audio = path.empty() ? Audio() : Audio(path.c_str());
|
audio = path.empty() ? Audio() : Audio(path);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ namespace anm2ed::anm2
|
|||||||
filesystem::WorkingDirectory workingDirectory(directory);
|
filesystem::WorkingDirectory workingDirectory(directory);
|
||||||
this->path = !path.empty() ? std::filesystem::relative(path) : this->path;
|
this->path = !path.empty() ? std::filesystem::relative(path) : this->path;
|
||||||
this->path = filesystem::path_lower_case_backslash_handle(this->path);
|
this->path = filesystem::path_lower_case_backslash_handle(this->path);
|
||||||
audio = Audio(this->path.c_str());
|
audio = Audio(this->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound::Sound(const std::filesystem::path& directory, const std::filesystem::path& path)
|
Sound::Sound(const std::filesystem::path& directory, const std::filesystem::path& path)
|
||||||
@@ -40,14 +40,15 @@ namespace anm2ed::anm2
|
|||||||
element->QueryIntAttribute("Id", &id);
|
element->QueryIntAttribute("Id", &id);
|
||||||
xml::query_path_attribute(element, "Path", &path);
|
xml::query_path_attribute(element, "Path", &path);
|
||||||
path = filesystem::path_lower_case_backslash_handle(path);
|
path = filesystem::path_lower_case_backslash_handle(path);
|
||||||
audio = Audio(path.c_str());
|
audio = Audio(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLElement* Sound::to_element(XMLDocument& document, int id)
|
XMLElement* Sound::to_element(XMLDocument& document, int id)
|
||||||
{
|
{
|
||||||
auto element = document.NewElement("Sound");
|
auto element = document.NewElement("Sound");
|
||||||
element->SetAttribute("Id", id);
|
element->SetAttribute("Id", id);
|
||||||
element->SetAttribute("Path", path.c_str());
|
auto pathString = path.generic_string();
|
||||||
|
element->SetAttribute("Path", pathString.c_str());
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ namespace anm2ed::anm2
|
|||||||
return xml::document_to_string(document);
|
return xml::document_to_string(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::reload(const std::string& directory) { *this = Sound(directory, this->path); }
|
void Sound::reload(const std::filesystem::path& directory) { *this = Sound(directory, this->path); }
|
||||||
|
|
||||||
bool Sound::is_valid() { return audio.is_valid(); }
|
bool Sound::is_valid() { return audio.is_valid(); }
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace anm2ed::anm2
|
|||||||
tinyxml2::XMLElement* to_element(tinyxml2::XMLDocument&, int);
|
tinyxml2::XMLElement* to_element(tinyxml2::XMLDocument&, int);
|
||||||
std::string to_string(int);
|
std::string to_string(int);
|
||||||
void serialize(tinyxml2::XMLDocument&, tinyxml2::XMLElement*, int);
|
void serialize(tinyxml2::XMLDocument&, tinyxml2::XMLElement*, int);
|
||||||
void reload(const std::string&);
|
void reload(const std::filesystem::path&);
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
void play();
|
void play();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ namespace anm2ed::anm2
|
|||||||
{
|
{
|
||||||
auto element = document.NewElement("Spritesheet");
|
auto element = document.NewElement("Spritesheet");
|
||||||
element->SetAttribute("Id", id);
|
element->SetAttribute("Id", id);
|
||||||
element->SetAttribute("Path", path.c_str());
|
auto pathString = path.generic_string();
|
||||||
|
element->SetAttribute("Path", pathString.c_str());
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,11 +58,11 @@ namespace anm2ed::anm2
|
|||||||
bool Spritesheet::save(const std::string& directory, const std::string& path)
|
bool Spritesheet::save(const std::string& directory, const std::string& path)
|
||||||
{
|
{
|
||||||
filesystem::WorkingDirectory workingDirectory(directory);
|
filesystem::WorkingDirectory workingDirectory(directory);
|
||||||
this->path = !path.empty() ? std::filesystem::relative(path).string() : this->path.string();
|
this->path = !path.empty() ? std::filesystem::relative(path) : this->path;
|
||||||
return texture.write_png(this->path);
|
return texture.write_png(this->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spritesheet::reload(const std::string& directory) { *this = Spritesheet(directory, this->path); }
|
void Spritesheet::reload(const std::filesystem::path& directory) { *this = Spritesheet(directory, this->path); }
|
||||||
|
|
||||||
bool Spritesheet::is_valid() { return texture.is_valid(); }
|
bool Spritesheet::is_valid() { return texture.is_valid(); }
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace anm2ed::anm2
|
|||||||
std::string to_string(int id);
|
std::string to_string(int id);
|
||||||
bool save(const std::string&, const std::string& = {});
|
bool save(const std::string&, const std::string& = {});
|
||||||
void serialize(tinyxml2::XMLDocument&, tinyxml2::XMLElement*, int);
|
void serialize(tinyxml2::XMLDocument&, tinyxml2::XMLElement*, int);
|
||||||
void reload(const std::string&);
|
void reload(const std::filesystem::path&);
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,14 @@ namespace anm2ed::imgui
|
|||||||
{
|
{
|
||||||
auto isSelected = selection.contains(id);
|
auto isSelected = selection.contains(id);
|
||||||
auto isReferenced = reference == id;
|
auto isReferenced = reference == id;
|
||||||
|
const std::string pathString =
|
||||||
|
sound.path.empty() ? std::string{anm2::NO_PATH} : sound.path.string();
|
||||||
|
const char* pathLabel = pathString.c_str();
|
||||||
|
|
||||||
ImGui::PushID(id);
|
ImGui::PushID(id);
|
||||||
ImGui::SetNextItemSelectionUserData(id);
|
ImGui::SetNextItemSelectionUserData(id);
|
||||||
if (isReferenced) ImGui::PushFont(resources.fonts[font::ITALICS].get(), font::SIZE);
|
if (isReferenced) ImGui::PushFont(resources.fonts[font::ITALICS].get(), font::SIZE);
|
||||||
if (ImGui::Selectable(sound.path.c_str(), isSelected)) sound.play();
|
if (ImGui::Selectable(pathLabel, isSelected)) sound.play();
|
||||||
if (ImGui::IsItemHovered()) hovered = id;
|
if (ImGui::IsItemHovered()) hovered = id;
|
||||||
|
|
||||||
if (isReferenced) ImGui::PopFont();
|
if (isReferenced) ImGui::PopFont();
|
||||||
@@ -45,7 +48,7 @@ namespace anm2ed::imgui
|
|||||||
if (ImGui::BeginItemTooltip())
|
if (ImGui::BeginItemTooltip())
|
||||||
{
|
{
|
||||||
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
||||||
ImGui::TextUnformatted(sound.path.c_str());
|
ImGui::TextUnformatted(pathLabel);
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
ImGui::Text("ID: %d", id);
|
ImGui::Text("ID: %d", id);
|
||||||
ImGui::Text("Click to play.");
|
ImGui::Text("Click to play.");
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ namespace anm2ed::imgui
|
|||||||
auto isReferenced = id == reference;
|
auto isReferenced = id == reference;
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
auto& texture = spritesheet.texture.is_valid() ? spritesheet.texture : resources.icons[icon::NONE];
|
auto& texture = spritesheet.texture.is_valid() ? spritesheet.texture : resources.icons[icon::NONE];
|
||||||
auto path = spritesheet.path.empty() ? anm2::NO_PATH : spritesheet.path.c_str();
|
const std::string pathString =
|
||||||
|
spritesheet.path.empty() ? std::string{anm2::NO_PATH} : spritesheet.path.string();
|
||||||
|
const char* pathCStr = pathString.c_str();
|
||||||
|
|
||||||
ImGui::SetNextItemSelectionUserData(id);
|
ImGui::SetNextItemSelectionUserData(id);
|
||||||
ImGui::SetNextItemStorageID(id);
|
ImGui::SetNextItemStorageID(id);
|
||||||
@@ -117,7 +119,7 @@ namespace anm2ed::imgui
|
|||||||
else
|
else
|
||||||
textureSize.y = textureSize.x / aspectRatio;
|
textureSize.y = textureSize.x / aspectRatio;
|
||||||
|
|
||||||
auto textWidth = ImGui::CalcTextSize(path).x;
|
auto textWidth = ImGui::CalcTextSize(pathCStr).x;
|
||||||
auto tooltipPadding = style.WindowPadding.x * 4.0f;
|
auto tooltipPadding = style.WindowPadding.x * 4.0f;
|
||||||
auto minWidth = textureSize.x + style.ItemSpacing.x + textWidth + tooltipPadding;
|
auto minWidth = textureSize.x + style.ItemSpacing.x + textWidth + tooltipPadding;
|
||||||
ImGui::SetNextWindowSize(ImVec2(minWidth, 0), ImGuiCond_Appearing);
|
ImGui::SetNextWindowSize(ImVec2(minWidth, 0), ImGuiCond_Appearing);
|
||||||
@@ -140,7 +142,7 @@ namespace anm2ed::imgui
|
|||||||
if (ImGui::BeginChild("##Spritesheet Info Tooltip Child"))
|
if (ImGui::BeginChild("##Spritesheet Info Tooltip Child"))
|
||||||
{
|
{
|
||||||
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
||||||
ImGui::TextUnformatted(path);
|
ImGui::TextUnformatted(pathCStr);
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
ImGui::Text("ID: %d", id);
|
ImGui::Text("ID: %d", id);
|
||||||
ImGui::Text("Size: %d x %d", texture.size.x, texture.size.y);
|
ImGui::Text("Size: %d x %d", texture.size.x, texture.size.y);
|
||||||
@@ -167,7 +169,7 @@ namespace anm2ed::imgui
|
|||||||
spritesheetChildSize.y - spritesheetChildSize.y / 2 - ImGui::GetTextLineHeight() / 2));
|
spritesheetChildSize.y - spritesheetChildSize.y / 2 - ImGui::GetTextLineHeight() / 2));
|
||||||
|
|
||||||
if (isReferenced) ImGui::PushFont(resources.fonts[font::ITALICS].get(), font::SIZE);
|
if (isReferenced) ImGui::PushFont(resources.fonts[font::ITALICS].get(), font::SIZE);
|
||||||
ImGui::Text(anm2::SPRITESHEET_FORMAT_C, id, path);
|
ImGui::Text(anm2::SPRITESHEET_FORMAT_C, id, pathCStr);
|
||||||
if (isReferenced) ImGui::PopFont();
|
if (isReferenced) ImGui::PopFont();
|
||||||
|
|
||||||
context_menu();
|
context_menu();
|
||||||
@@ -208,7 +210,7 @@ namespace anm2ed::imgui
|
|||||||
for (auto& id : selection)
|
for (auto& id : selection)
|
||||||
{
|
{
|
||||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||||
spritesheet.reload(document.directory_get().string());
|
spritesheet.reload(document.directory_get());
|
||||||
toasts.info(std::format("Reloaded spritesheet #{}: {}", id, spritesheet.path.string()));
|
toasts.info(std::format("Reloaded spritesheet #{}: {}", id, spritesheet.path.string()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
15
src/log.h
15
src/log.h
@@ -2,9 +2,24 @@
|
|||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace anm2ed
|
namespace anm2ed
|
||||||
{
|
{
|
||||||
|
#if defined(INFO)
|
||||||
|
#undef INFO
|
||||||
|
#endif
|
||||||
|
#if defined(WARNING)
|
||||||
|
#undef WARNING
|
||||||
|
#endif
|
||||||
|
#if defined(ERROR)
|
||||||
|
#undef ERROR
|
||||||
|
#endif
|
||||||
|
#if defined(FATAL)
|
||||||
|
#undef FATAL
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LEVELS \
|
#define LEVELS \
|
||||||
X(INFO, "[INFO]") \
|
X(INFO, "[INFO]") \
|
||||||
X(WARNING, "[WARNING]") \
|
X(WARNING, "[WARNING]") \
|
||||||
|
|||||||
@@ -26,16 +26,17 @@ namespace anm2ed
|
|||||||
|
|
||||||
Document* Manager::get(int index) { return vector::find(documents, index > -1 ? index : selected); }
|
Document* Manager::get(int index) { return vector::find(documents, index > -1 ? index : selected); }
|
||||||
|
|
||||||
void Manager::open(const std::string& path, bool isNew, bool isRecent)
|
void Manager::open(const std::filesystem::path& path, bool isNew, bool isRecent)
|
||||||
{
|
{
|
||||||
|
const auto pathString = path.string();
|
||||||
std::string errorString{};
|
std::string errorString{};
|
||||||
documents.emplace_back(path, isNew, &errorString);
|
documents.emplace_back(pathString, isNew, &errorString);
|
||||||
|
|
||||||
auto& document = documents.back();
|
auto& document = documents.back();
|
||||||
if (!document.is_valid())
|
if (!document.is_valid())
|
||||||
{
|
{
|
||||||
documents.pop_back();
|
documents.pop_back();
|
||||||
toasts.error(std::format("Failed to open document: {} ({})", path, errorString));
|
toasts.error(std::format("Failed to open document: {} ({})", pathString, errorString));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,23 +44,23 @@ namespace anm2ed
|
|||||||
|
|
||||||
selected = (int)documents.size() - 1;
|
selected = (int)documents.size() - 1;
|
||||||
pendingSelected = selected;
|
pendingSelected = selected;
|
||||||
toasts.info(std::format("Opened document: {}", path));
|
toasts.info(std::format("Opened document: {}", pathString));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::new_(const std::string& path) { open(path, true); }
|
void Manager::new_(const std::filesystem::path& path) { open(path, true); }
|
||||||
|
|
||||||
void Manager::save(int index, const std::string& path)
|
void Manager::save(int index, const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
if (auto document = get(index); document)
|
if (auto document = get(index); document)
|
||||||
{
|
{
|
||||||
std::string errorString{};
|
std::string errorString{};
|
||||||
document->path = !path.empty() ? path : document->path.string();
|
document->path = !path.empty() ? path : document->path;
|
||||||
document->save(document->path.string(), &errorString);
|
document->save(document->path.string(), &errorString);
|
||||||
recent_file_add(document->path.string());
|
recent_file_add(document->path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::save(const std::string& path) { save(selected, path); }
|
void Manager::save(const std::filesystem::path& path) { save(selected, path); }
|
||||||
|
|
||||||
void Manager::autosave(Document& document)
|
void Manager::autosave(Document& document)
|
||||||
{
|
{
|
||||||
@@ -163,13 +164,14 @@ namespace anm2ed
|
|||||||
nullPropertiesPopup.close();
|
nullPropertiesPopup.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::recent_file_add(const std::string& path)
|
void Manager::recent_file_add(const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
if (path.empty()) return;
|
if (path.empty()) return;
|
||||||
|
const auto pathString = path.string();
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
if (!std::filesystem::exists(path, ec))
|
if (!std::filesystem::exists(path, ec))
|
||||||
{
|
{
|
||||||
logger.warning(std::format("Skipping missing recent file: {}", path));
|
logger.warning(std::format("Skipping missing recent file: {}", pathString));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,14 +199,15 @@ namespace anm2ed
|
|||||||
while (std::getline(file, line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
if (line.empty()) continue;
|
if (line.empty()) continue;
|
||||||
if (std::find(recentFiles.begin(), recentFiles.end(), line) != recentFiles.end()) continue;
|
std::filesystem::path entry = line;
|
||||||
|
if (std::find(recentFiles.begin(), recentFiles.end(), entry) != recentFiles.end()) continue;
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
if (!std::filesystem::exists(line, ec))
|
if (!std::filesystem::exists(entry, ec))
|
||||||
{
|
{
|
||||||
logger.warning(std::format("Skipping missing recent file: {}", line));
|
logger.warning(std::format("Skipping missing recent file: {}", line));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
recentFiles.emplace_back(line);
|
recentFiles.emplace_back(std::move(entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,8 +224,8 @@ namespace anm2ed
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& path : recentFiles)
|
for (auto& entry : recentFiles)
|
||||||
file << path.string() << '\n';
|
file << entry.string() << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::recent_files_clear()
|
void Manager::recent_files_clear()
|
||||||
@@ -240,7 +243,7 @@ namespace anm2ed
|
|||||||
|
|
||||||
auto restorePath = path.parent_path() / fileName;
|
auto restorePath = path.parent_path() / fileName;
|
||||||
restorePath.replace_extension("");
|
restorePath.replace_extension("");
|
||||||
open(path.string(), false, false);
|
open(path, false, false);
|
||||||
|
|
||||||
if (auto document = get())
|
if (auto document = get())
|
||||||
{
|
{
|
||||||
@@ -271,8 +274,9 @@ namespace anm2ed
|
|||||||
while (std::getline(file, line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
if (line.empty()) continue;
|
if (line.empty()) continue;
|
||||||
if (std::find(autosaveFiles.begin(), autosaveFiles.end(), line) != autosaveFiles.end()) continue;
|
std::filesystem::path entry = line;
|
||||||
autosaveFiles.emplace_back(line);
|
if (std::find(autosaveFiles.begin(), autosaveFiles.end(), entry) != autosaveFiles.end()) continue;
|
||||||
|
autosaveFiles.emplace_back(std::move(entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
@@ -42,10 +43,10 @@ namespace anm2ed
|
|||||||
~Manager();
|
~Manager();
|
||||||
|
|
||||||
Document* get(int = -1);
|
Document* get(int = -1);
|
||||||
void open(const std::string&, bool = false, bool = true);
|
void open(const std::filesystem::path&, bool = false, bool = true);
|
||||||
void new_(const std::string&);
|
void new_(const std::filesystem::path&);
|
||||||
void save(int, const std::string& = {});
|
void save(int, const std::filesystem::path& = {});
|
||||||
void save(const std::string& = {});
|
void save(const std::filesystem::path& = {});
|
||||||
void autosave(Document&);
|
void autosave(Document&);
|
||||||
void set(int);
|
void set(int);
|
||||||
void close(int);
|
void close(int);
|
||||||
@@ -61,7 +62,7 @@ namespace anm2ed
|
|||||||
void recent_files_load();
|
void recent_files_load();
|
||||||
void recent_files_write();
|
void recent_files_write();
|
||||||
void recent_files_clear();
|
void recent_files_clear();
|
||||||
void recent_file_add(const std::string&);
|
void recent_file_add(const std::filesystem::path&);
|
||||||
|
|
||||||
void autosave_files_load();
|
void autosave_files_load();
|
||||||
void autosave_files_open();
|
void autosave_files_open();
|
||||||
|
|||||||
Reference in New Issue
Block a user