impr: Added icons to providers, improved the quick settings

This commit is contained in:
WerWolv
2025-08-06 21:37:41 +02:00
parent 5be6297bac
commit 064b21a264
30 changed files with 106 additions and 31 deletions

View File

@@ -1014,12 +1014,17 @@ EXPORT_MODULE namespace hex {
namespace impl {
void addProviderName(const UnlocalizedString &unlocalizedName);
void addProviderName(const UnlocalizedString &unlocalizedName, const char *icon);
using ProviderCreationFunction = std::function<std::unique_ptr<prv::Provider>()>;
void add(const std::string &typeName, ProviderCreationFunction creationFunction);
const std::vector<std::string>& getEntries();
struct Entry {
UnlocalizedString unlocalizedName;
const char *icon;
};
const std::vector<Entry>& getEntries();
}
@@ -1030,14 +1035,15 @@ EXPORT_MODULE namespace hex {
*/
template<std::derived_from<prv::Provider> T>
void add(bool addToList = true) {
auto typeName = T().getTypeName();
const T provider;
auto typeName = provider.getTypeName();
impl::add(typeName, []() -> std::unique_ptr<prv::Provider> {
return std::make_unique<T>();
});
if (addToList)
impl::addProviderName(typeName);
impl::addProviderName(typeName, provider.getIcon());
}
}

View File

@@ -39,6 +39,10 @@ namespace hex::prv {
[[nodiscard]] std::string getName() const override { return m_name; }
[[nodiscard]] UnlocalizedString getTypeName() const override { return "MemoryProvider"; }
[[nodiscard]] const char* getIcon() const override {
return "";
}
private:
void renameFile();

View File

@@ -199,13 +199,19 @@ namespace hex::prv {
[[nodiscard]] virtual UnlocalizedString getTypeName() const = 0;
/**
* @brief Gets a human readable representation of the current provider
* @brief Gets a human-readable representation of the current provider
* @note This is mainly used to display the provider in the UI. For example, the file provider
* will return the file name here
* @return The name of the current provider
*/
[[nodiscard]] virtual std::string getName() const = 0;
/**
* @brief Gets the icon of this provider
* @return The icon string
*/
[[nodiscard]] virtual const char* getIcon() const = 0;
bool resize(u64 newSize);
void insert(u64 offset, u64 size);
void remove(u64 offset, u64 size);

View File

@@ -27,6 +27,10 @@ namespace hex::test {
return "";
}
[[nodiscard]] const char* getIcon() const override {
return "";
}
void readRaw(u64 offset, void *buffer, size_t size) override {
if (offset + size > m_data->size()) return;

View File

@@ -173,7 +173,7 @@ namespace hex {
*/
class View::Floating : public View::Window {
public:
explicit Floating(UnlocalizedString unlocalizedName) : Window(std::move(unlocalizedName), "") {}
explicit Floating(UnlocalizedString unlocalizedName, const char *icon) : Window(std::move(unlocalizedName), icon) {}
[[nodiscard]] ImGuiWindowFlags getWindowFlags() const override { return ImGuiWindowFlags_NoDocking; }
[[nodiscard]] bool shouldStoreWindowState() const override { return false; }
@@ -184,7 +184,7 @@ namespace hex {
*/
class View::Modal : public View {
public:
explicit Modal(UnlocalizedString unlocalizedName) : View(std::move(unlocalizedName), "") {}
explicit Modal(UnlocalizedString unlocalizedName, const char *icon) : View(std::move(unlocalizedName), icon) {}
void draw() final {
if (this->shouldDraw()) {
@@ -193,7 +193,8 @@ namespace hex {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
if (ImGui::BeginPopupModal(View::toWindowName(this->getUnlocalizedName()).c_str(), this->hasCloseButton() ? &this->getWindowOpenState() : nullptr, ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
const auto title = fmt::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName()));
if (ImGui::BeginPopupModal(title.c_str(), this->hasCloseButton() ? &this->getWindowOpenState() : nullptr, ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
this->drawContent();
ImGui::EndPopup();

View File

@@ -1080,15 +1080,15 @@ namespace hex {
});
}
static AutoReset<std::vector<std::string>> s_providerNames;
const std::vector<std::string>& getEntries() {
static AutoReset<std::vector<Entry>> s_providerNames;
const std::vector<Entry>& getEntries() {
return *s_providerNames;
}
void addProviderName(const UnlocalizedString &unlocalizedName) {
void addProviderName(const UnlocalizedString &unlocalizedName, const char *icon) {
log::debug("Registered new provider: {}", unlocalizedName.get());
s_providerNames->push_back(unlocalizedName);
s_providerNames->emplace_back(unlocalizedName, icon);
}
}

View File

@@ -77,6 +77,10 @@ namespace hex {
return "";
}
[[nodiscard]] const char* getIcon() const override {
return "";
}
[[nodiscard]] UnlocalizedString getTypeName() const override { return ""; }
const std::map<u64, u8>& getPatches() const {

View File

@@ -6,6 +6,7 @@
#include <set>
#include <string>
#include <vector>
#include <fonts/vscode_icons.hpp>
#include <wolv/io/handle.hpp>
namespace hex::plugin::builtin {
@@ -44,6 +45,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.disk";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_SAVE;
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
std::variant<std::string, i128> queryInformation(const std::string &category, const std::string &argument) override;

View File

@@ -6,6 +6,7 @@
#include <set>
#include <string_view>
#include <fonts/vscode_icons.hpp>
namespace hex::plugin::builtin {
@@ -52,6 +53,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.file";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_FILE_BINARY;
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
void convertToMemoryFile();
@@ -80,4 +85,4 @@ namespace hex::plugin::builtin {
static std::set<FileProvider*> s_openedFiles;
};
}
}

View File

@@ -8,6 +8,7 @@
#include <mutex>
#include <string_view>
#include <thread>
#include <fonts/vscode_icons.hpp>
#include <hex/providers/cached_provider.hpp>
namespace hex::plugin::builtin {
@@ -48,6 +49,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.gdb";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_CHIP;
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
std::variant<std::string, i128> queryInformation(const std::string &category, const std::string &argument) override;

View File

@@ -1,5 +1,6 @@
#pragma once
#include <fonts/vscode_icons.hpp>
#include <hex/providers/provider.hpp>
#include <wolv/container/interval_tree.hpp>
@@ -38,6 +39,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.intel_hex";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_TABLE;
}
[[nodiscard]] bool handleFilePicker() override;
std::pair<Region, bool> getRegionValidity(u64 address) const override;

View File

@@ -1,5 +1,6 @@
#pragma once
#include <fonts/vscode_icons.hpp>
#include <hex/providers/provider.hpp>
namespace hex::plugin::builtin {
@@ -36,6 +37,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.mem_file";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_FILE_BINARY;
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
void loadSettings(const nlohmann::json &settings) override;

View File

@@ -44,6 +44,10 @@ namespace hex::plugin::builtin {
[[nodiscard]] std::string getName() const override { return "ImHex"; }
[[nodiscard]] const char* getIcon() const override {
return "";
}
void loadSettings(const nlohmann::json &settings) override { std::ignore = settings; }
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override { return settings; }

View File

@@ -11,6 +11,7 @@
#include <set>
#include <thread>
#include <fonts/vscode_icons.hpp>
#include <hex/helpers/auto_reset.hpp>
#include <nlohmann/json.hpp>
@@ -71,6 +72,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.process_memory";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_SERVER_PROCESS;
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64) const override;
std::variant<std::string, i128> queryInformation(const std::string &category, const std::string &argument) override;

View File

@@ -5,6 +5,7 @@
#include <hex/helpers/udp_server.hpp>
#include <nlohmann/json.hpp>
#include <mutex>
#include <fonts/vscode_icons.hpp>
namespace hex::plugin::builtin {
@@ -39,6 +40,10 @@ namespace hex::plugin::builtin {
return "hex.builtin.provider.udp";
}
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_RSS;
}
std::string getName() const override { return fmt::format("hex.builtin.provider.udp.name"_lang, m_port); }
protected:

View File

@@ -1,5 +1,6 @@
#pragma once
#include <fonts/vscode_icons.hpp>
#include <hex/providers/provider.hpp>
namespace hex::plugin::builtin {
@@ -36,6 +37,10 @@ namespace hex::plugin::builtin {
[[nodiscard]] std::vector<Description> getDataDescription() const override;
[[nodiscard]] UnlocalizedString getTypeName() const override;
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_OPEN_PREVIEW;
}
void loadSettings(const nlohmann::json &settings) override;
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override;

View File

@@ -383,8 +383,8 @@ namespace hex::plugin::builtin {
/* Open Other */
ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.open_other"}, ICON_VS_TELESCOPE, 1150, [] {
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::impl::getEntries()) {
if (menu::menuItem(Lang(unlocalizedProviderName)))
for (const auto &[unlocalizedProviderName, icon] : ContentRegistry::Provider::impl::getEntries()) {
if (menu::menuItemEx(Lang(unlocalizedProviderName), icon))
ImHexApi::Provider::createProvider(unlocalizedProviderName);
}
}, noRunningTasks);

View File

@@ -517,7 +517,7 @@ namespace hex::plugin::builtin {
static size_t lastSelectedProvider = 0;
bool isSelected = false;
if (ImGui::BeginTabItem(tabProvider->getName().c_str(), &open, flags)) {
if (ImGui::BeginTabItem(fmt::format("{} {}", tabProvider->getIcon(), tabProvider->getName()).c_str(), &open, flags)) {
isSelected = true;
ImGui::EndTabItem();
}

View File

@@ -78,7 +78,7 @@ namespace hex::plugin::builtin {
}
};
ViewAbout::ViewAbout() : View::Modal("hex.builtin.view.help.about.name") {
ViewAbout::ViewAbout() : View::Modal("hex.builtin.view.help.about.name", ICON_VS_HEART) {
// Add "About" menu item to the help menu
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.help", "hex.builtin.view.help.about.name" }, ICON_VS_INFO, 1000, Shortcut::None, [this] {
this->getWindowOpenState() = true;

View File

@@ -11,7 +11,7 @@
namespace hex::plugin::builtin {
ViewAchievements::ViewAchievements() : View::Floating("hex.builtin.view.achievements.name") {
ViewAchievements::ViewAchievements() : View::Floating("hex.builtin.view.achievements.name", ICON_VS_SPARKLE) {
// Add achievements menu item to Extas menu
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.achievements.name" }, ICON_VS_SPARKLE, 2600, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;

View File

@@ -112,7 +112,7 @@ namespace hex::plugin::builtin {
}
ViewHighlightRules::ViewHighlightRules() : View::Floating("hex.builtin.view.highlight_rules.name") {
ViewHighlightRules::ViewHighlightRules() : View::Floating("hex.builtin.view.highlight_rules.name", ICON_VS_TAG) {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.highlight_rules.menu.edit.rules" }, ICON_VS_TAG, 1950, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;
}, ImHexApi::Provider::isValid,

View File

@@ -7,7 +7,7 @@
namespace hex::plugin::builtin {
ViewLogs::ViewLogs() : View::Floating("hex.builtin.view.logs.name") {
ViewLogs::ViewLogs() : View::Floating("hex.builtin.view.logs.name", ICON_VS_DEBUG_LINE_BY_LINE) {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.logs.name" }, ICON_VS_BRACKET_ERROR, 2500, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;
});

View File

@@ -8,7 +8,7 @@
namespace hex::plugin::builtin {
ViewProviderSettings::ViewProviderSettings() : View::Modal("hex.builtin.view.provider_settings.name") {
ViewProviderSettings::ViewProviderSettings() : View::Modal("hex.builtin.view.provider_settings.name", ICON_VS_SETTINGS) {
EventProviderCreated::subscribe(this, [this](const hex::prv::Provider *provider) {
if (dynamic_cast<const prv::IProviderLoadInterface*>(provider) != nullptr && !provider->shouldSkipLoadInterface())
this->getWindowOpenState() = true;

View File

@@ -12,7 +12,7 @@
namespace hex::plugin::builtin {
ViewSettings::ViewSettings() : View::Modal("hex.builtin.view.settings.name") {
ViewSettings::ViewSettings() : View::Modal("hex.builtin.view.settings.name", ICON_VS_SETTINGS_GEAR) {
// Handle window open requests
RequestOpenWindow::subscribe(this, [this](const std::string &name) {
if (name == "Settings") {

View File

@@ -29,8 +29,8 @@ namespace hex::plugin::builtin {
using namespace std::literals::string_literals;
using namespace std::literals::chrono_literals;
ViewStore::ViewStore() : View::Floating("hex.builtin.view.store.name") {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.store.name" }, ICON_VS_GLOBE, 1000, Shortcut::None, [&, this] {
ViewStore::ViewStore() : View::Floating("hex.builtin.view.store.name", ICON_VS_EXTENSIONS) {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.store.name" }, ICON_VS_EXTENSIONS, 1000, Shortcut::None, [&, this] {
if (m_requestStatus == RequestStatus::NotAttempted)
this->refresh();

View File

@@ -9,7 +9,7 @@
namespace hex::plugin::builtin {
ViewThemeManager::ViewThemeManager() : View::Floating("hex.builtin.view.theme_manager.name") {
ViewThemeManager::ViewThemeManager() : View::Floating("hex.builtin.view.theme_manager.name", ICON_VS_SYMBOL_COLOR) {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.theme_manager.name" }, ICON_VS_SYMBOL_COLOR, 2000, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;
});

View File

@@ -11,7 +11,7 @@
namespace hex::plugin::builtin {
ViewTutorials::ViewTutorials() : View::Floating("hex.builtin.view.tutorials.name") {
ViewTutorials::ViewTutorials() : View::Floating("hex.builtin.view.tutorials.name", ICON_VS_BOOK) {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.help", "hex.builtin.view.tutorials.name" }, ICON_VS_COMPASS, 4000, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;
});

View File

@@ -351,8 +351,8 @@ namespace hex::plugin::builtin {
ImGui::SameLine(0, 2_scaled);
if (ImGuiExt::BeginSubWindow("hex.builtin.welcome.start.open_other"_lang, nullptr, ImVec2(200_scaled, ImGui::GetTextLineHeightWithSpacing() * 5.8), ImGuiChildFlags_AutoResizeX)) {
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::impl::getEntries()) {
if (ImGuiExt::Hyperlink(Lang(unlocalizedProviderName))) {
for (const auto &[unlocalizedProviderName, icon] : ContentRegistry::Provider::impl::getEntries()) {
if (ImGuiExt::Hyperlink(fmt::format("{} {}", icon, Lang(unlocalizedProviderName)).c_str())) {
ImHexApi::Provider::createProvider(unlocalizedProviderName);
otherProvidersVisible = false;
}
@@ -519,11 +519,11 @@ namespace hex::plugin::builtin {
ImGui::SetCursorScreenPos(ImGui::GetWindowPos() + ImGui::GetWindowSize() - windowSize - ImGui::GetStyle().WindowPadding);
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
if (ImGuiExt::BeginSubWindow("hex.builtin.welcome.header.quick_settings"_lang, nullptr, windowSize, ImGuiChildFlags_AutoResizeY)) {
if (ImGuiExt::ToggleSwitch("hex.builtin.welcome.quick_settings.simplified"_lang, &s_simplifiedWelcomeScreen)) {
if (ImGuiExt::DimmedIconToggle(ICON_VS_COMPASS_ACTIVE, ICON_VS_COMPASS, &s_simplifiedWelcomeScreen)) {
ContentRegistry::Settings::write<bool>("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", s_simplifiedWelcomeScreen);
WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default");
}
ImGui::SetItemTooltip("hex.builtin.welcome.quick_settings.simplified"_lang);
}
ImGuiExt::EndSubWindow();

View File

@@ -1,6 +1,7 @@
#pragma once
#include <content/helpers/sftp_client.hpp>
#include <fonts/vscode_icons.hpp>
#include <hex/providers/cached_provider.hpp>
namespace hex::plugin::remote {
@@ -25,6 +26,10 @@ namespace hex::plugin::remote {
UnlocalizedString getTypeName() const override { return "hex.plugin.remote.ssh_provider"; }
std::string getName() const override;
[[nodiscard]] const char* getIcon() const override {
return ICON_VS_REMOTE;
}
bool drawLoadInterface() override;
void loadSettings(const nlohmann::json &settings) override;

View File

@@ -89,6 +89,7 @@ public:
void setName(std::string name) { m_name = std::move(name);}
[[nodiscard]] hex::UnlocalizedString getTypeName() const override { return m_typeName; }
[[nodiscard]] std::string getName() const override { return m_name; }
const char* getIcon() const override { return ""; }
private:
ReadFunction m_readFunction = nullptr;
@@ -109,5 +110,5 @@ SCRIPT_API(void registerProvider, const char *typeName, const char *name, Script
provider->setFunctions(readFunc, writeFunc, getSizeFunc);
return provider;
});
hex::ContentRegistry::Provider::impl::addProviderName(typeNameString);
hex::ContentRegistry::Provider::impl::addProviderName(typeNameString, "");
}