1
0
mirror of synced 2024-11-30 18:34:29 +01:00

feat: Display pattern descriptions in file chooser and pattern popup

This commit is contained in:
WerWolv 2024-08-03 22:00:47 +02:00
parent e9f7908afb
commit 5dfd8c89a3
3 changed files with 60 additions and 23 deletions

View File

@ -18,8 +18,6 @@ namespace hex::plugin::builtin {
struct Workspace { struct Workspace {
Workspace() = default; Workspace() = default;
std::unique_ptr<ImNodesContext, void(*)(ImNodesContext*)> context = { []{ std::unique_ptr<ImNodesContext, void(*)(ImNodesContext*)> context = { []{
ImNodesContext *ctx = ImNodes::CreateContext(); ImNodesContext *ctx = ImNodes::CreateContext();
ctx->Style = ImNodes::GetStyle(); ctx->Style = ImNodes::GetStyle();

View File

@ -261,6 +261,8 @@ namespace hex::plugin::builtin {
bool m_parentHighlightingEnabled = true; bool m_parentHighlightingEnabled = true;
bool m_replaceMode = false; bool m_replaceMode = false;
std::map<std::fs::path, std::string> m_patternNames;
static inline std::array<std::string,256> m_findHistory; static inline std::array<std::string,256> m_findHistory;
static inline u32 m_findHistorySize = 0; static inline u32 m_findHistorySize = 0;
@ -281,7 +283,7 @@ namespace hex::plugin::builtin {
void drawFindReplaceDialog(std::string &findWord, bool &requestFocus, u64 &position, u64 &count, bool &updateCount); void drawFindReplaceDialog(std::string &findWord, bool &requestFocus, u64 &position, u64 &count, bool &updateCount);
void historyInsert(std::array<std::string,256> &history,u32 &size, u32 &index, const std::string &value); void historyInsert(std::array<std::string, 256> &history, u32 &size, u32 &index, const std::string &value);
void loadPatternFile(const std::fs::path &path, prv::Provider *provider); void loadPatternFile(const std::fs::path &path, prv::Provider *provider);
@ -306,12 +308,34 @@ namespace hex::plugin::builtin {
paths.push_back(entry.path()); paths.push_back(entry.path());
} }
} }
ui::PopupFileChooser::open(
basePaths, paths, std::vector<hex::fs::ItemFilter>{ { "Pattern File", "hexpat" } }, false, ui::PopupNamedFileChooser::open(
[this, provider](const std::fs::path &path) { basePaths, paths, std::vector<hex::fs::ItemFilter>{ { "Pattern File", "hexpat" } }, false,
this->loadPatternFile(path, provider); [this, provider](const std::fs::path &path, const std::fs::path &adjustedPath) mutable -> std::string {
AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.load_existing.name"); auto it = m_patternNames.find(path);
if (it != m_patternNames.end()) {
return it->second;
} }
const auto fileName = wolv::util::toUTF8String(adjustedPath.filename());
m_patternNames[path] = fileName;
pl::PatternLanguage runtime;
ContentRegistry::PatternLanguage::configureRuntime(runtime, provider);
runtime.addPragma("description", [&](pl::PatternLanguage &, const std::string &value) -> bool {
m_patternNames[path] = hex::format("{} ({})", value, fileName);
return true;
});
wolv::io::File file(path, wolv::io::File::Mode::Read);
hex::unused(runtime.preprocessString(file.readString(), pl::api::Source::DefaultSource));
return m_patternNames[path];
},
[this, provider](const std::fs::path &path) {
this->loadPatternFile(path, provider);
AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.load_existing.name");
}
); );
}; };

View File

@ -17,10 +17,10 @@ namespace hex::ui {
template<typename T> template<typename T>
class PopupNamedFileChooserBase : public Popup<T> { class PopupNamedFileChooserBase : public Popup<T> {
public: public:
PopupNamedFileChooserBase(const std::vector<std::fs::path> &basePaths, const std::vector<std::fs::path> &files, const std::vector<hex::fs::ItemFilter> &validExtensions, bool multiple, const std::function<std::string(const std::fs::path &)> &nameCallback, const std::function<void(std::fs::path)> &callback) PopupNamedFileChooserBase(const std::vector<std::fs::path> &basePaths, const std::vector<std::fs::path> &files, const std::vector<hex::fs::ItemFilter> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback)
: hex::Popup<T>("hex.ui.common.choose_file"), : hex::Popup<T>("hex.ui.common.choose_file"),
m_files(files),
m_selectedFiles({ }), m_selectedFiles({ }),
m_nameCallback(nameCallback),
m_openCallback(callback), m_openCallback(callback),
m_validExtensions(validExtensions), m_validExtensions(validExtensions),
m_multiple(multiple) { m_multiple(multiple) {
@ -37,11 +37,11 @@ namespace hex::ui {
if (adjustedPath.empty()) if (adjustedPath.empty())
adjustedPath = path.filename(); adjustedPath = path.filename();
m_files.push_back({ path, adjustedPath }); m_adjustedPaths[path] = adjustedPath;
} }
std::sort(m_files.begin(), m_files.end(), [](const auto &a, const auto &b) { std::sort(m_files.begin(), m_files.end(), [](const auto &a, const auto &b) {
return a.first < b.first; return a < b;
}); });
} }
@ -59,9 +59,9 @@ namespace hex::ui {
if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) { if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) {
for (auto fileIt = m_files.begin(); fileIt != m_files.end(); ++fileIt) { for (auto fileIt = m_files.begin(); fileIt != m_files.end(); ++fileIt) {
const auto &[path, pathName] = *fileIt; const auto &path = *fileIt;
const auto &pathNameString = m_nameCallback(pathName); const auto &pathNameString = getEntryName(path);
if (!m_filter.empty() && !pathNameString.contains(m_filter)) if (!m_filter.empty() && !pathNameString.contains(m_filter))
continue; continue;
@ -94,7 +94,7 @@ namespace hex::ui {
if (ImGui::Button("hex.ui.common.open"_lang) || doubleClicked) { if (ImGui::Button("hex.ui.common.open"_lang) || doubleClicked) {
for (const auto &it : m_selectedFiles) for (const auto &it : m_selectedFiles)
m_openCallback(it->first); m_openCallback(*it);
Popup<T>::close(); Popup<T>::close();
} }
@ -115,6 +115,14 @@ namespace hex::ui {
return ImGuiWindowFlags_AlwaysAutoResize; return ImGuiWindowFlags_AlwaysAutoResize;
} }
protected:
const std::fs::path& getAdjustedPath(const std::fs::path &path) const {
return m_adjustedPaths.at(path);
}
virtual std::string getEntryName(const std::fs::path &path) = 0;
private: private:
static bool isSubpath(const std::fs::path &basePath, const std::fs::path &path) { static bool isSubpath(const std::fs::path &basePath, const std::fs::path &path) {
auto relativePath = std::fs::relative(path, basePath); auto relativePath = std::fs::relative(path, basePath);
@ -124,9 +132,9 @@ namespace hex::ui {
private: private:
std::string m_filter; std::string m_filter;
std::vector<std::pair<std::fs::path, std::fs::path>> m_files; std::vector<std::fs::path> m_files;
std::set<std::vector<std::pair<std::fs::path, std::fs::path>>::const_iterator> m_selectedFiles; std::map<std::fs::path, std::fs::path> m_adjustedPaths;
std::function<std::string(const std::fs::path &)> m_nameCallback; std::set<std::vector<std::fs::path>::const_iterator> m_selectedFiles;
std::function<void(std::fs::path)> m_openCallback; std::function<void(std::fs::path)> m_openCallback;
std::vector<hex::fs::ItemFilter> m_validExtensions; std::vector<hex::fs::ItemFilter> m_validExtensions;
bool m_multiple = false; bool m_multiple = false;
@ -135,17 +143,24 @@ namespace hex::ui {
class PopupNamedFileChooser : public PopupNamedFileChooserBase<PopupNamedFileChooser> { class PopupNamedFileChooser : public PopupNamedFileChooserBase<PopupNamedFileChooser> {
public: public:
PopupNamedFileChooser(const std::vector<std::fs::path> &basePaths, const std::vector<std::fs::path> &files, const std::vector<hex::fs::ItemFilter> &validExtensions, bool multiple, const std::function<std::string(const std::fs::path &)> &nameCallback, const std::function<void(std::fs::path)> &callback) PopupNamedFileChooser(const std::vector<std::fs::path> &basePaths, const std::vector<std::fs::path> &files, const std::vector<hex::fs::ItemFilter> &validExtensions, bool multiple, const std::function<std::string(std::fs::path, std::fs::path)> &nameCallback, const std::function<void(std::fs::path)> &callback)
: PopupNamedFileChooserBase(basePaths, files, validExtensions, multiple, nameCallback, callback) { } : PopupNamedFileChooserBase(basePaths, files, validExtensions, multiple, callback), m_nameCallback(nameCallback) { }
std::string getEntryName(const std::fs::path &path) override {
return m_nameCallback(path, getAdjustedPath(path));
}
private:
std::function<std::string(std::fs::path, std::fs::path)> m_nameCallback;
}; };
class PopupFileChooser : public PopupNamedFileChooserBase<PopupFileChooser> { class PopupFileChooser : public PopupNamedFileChooserBase<PopupFileChooser> {
public: public:
PopupFileChooser(const std::vector<std::fs::path> &basePaths, const std::vector<std::fs::path> &files, const std::vector<hex::fs::ItemFilter> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback) PopupFileChooser(const std::vector<std::fs::path> &basePaths, const std::vector<std::fs::path> &files, const std::vector<hex::fs::ItemFilter> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback)
: PopupNamedFileChooserBase(basePaths, files, validExtensions, multiple, nameCallback, callback) { } : PopupNamedFileChooserBase(basePaths, files, validExtensions, multiple, callback) { }
static std::string nameCallback(const std::fs::path &path) { std::string getEntryName(const std::fs::path &path) override {
return wolv::util::toUTF8String(path); return wolv::util::toUTF8String(getAdjustedPath(path));
} }
}; };