impr: Split up optional provider features into multiple abstract interfaces

This commit is contained in:
WerWolv
2025-07-14 00:37:12 +02:00
parent b94519362c
commit 18e02fbf5c
22 changed files with 155 additions and 124 deletions

View File

@@ -40,13 +40,15 @@ namespace hex::plugin::builtin {
ImGui::TableNextRow();
for (auto &[name, value] : m_provider->getDataDescription()) {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", name);
ImGui::TableNextColumn();
ImGui::PushID(name.c_str());
ImGuiExt::TextFormattedWrappedSelectable("{}", value);
ImGui::PopID();
if (auto *dataDescriptionProvider = dynamic_cast<prv::IProviderDataDescription*>(m_provider); dataDescriptionProvider != nullptr) {
for (auto &[name, value] : dataDescriptionProvider->getDataDescription()) {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", name);
ImGui::TableNextColumn();
ImGui::PushID(name.c_str());
ImGuiExt::TextFormattedWrappedSelectable("{}", value);
ImGui::PopID();
}
}
ImGui::TableNextColumn();

View File

@@ -198,8 +198,8 @@ namespace hex::plugin::builtin {
if (provider->shouldSkipLoadInterface())
return;
if (provider->hasFilePicker()) {
if (!provider->handleFilePicker()) {
if (auto *filePickerProvider = dynamic_cast<prv::IProviderFilePicker*>(provider); filePickerProvider != nullptr) {
if (!filePickerProvider->handleFilePicker()) {
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
@@ -213,7 +213,7 @@ namespace hex::plugin::builtin {
}
});
}
else if (!provider->hasLoadInterface()) {
else if (dynamic_cast<prv::IProviderLoadInterface*>(provider) == nullptr) {
TaskManager::createBlockingTask("hex.builtin.provider.opening", TaskManager::NoProgress, [provider]() {
if (!provider->open() || !provider->isAvailable()) {
ui::ToastError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));

View File

@@ -178,7 +178,7 @@ namespace hex::plugin::builtin {
}
std::vector<FileProvider::MenuEntry> FileProvider::getMenuEntries() {
FileProvider::MenuEntry loadMenuItem;
MenuEntry loadMenuItem;
if (m_loadedIntoMemory)
loadMenuItem = { "hex.builtin.provider.file.menu.direct_access"_lang, ICON_VS_ARROW_SWAP, [this] { this->convertToDirectAccess(); } };

View File

@@ -282,7 +282,7 @@ namespace hex::plugin::builtin {
return m_selectedProcess != nullptr;
}
void ProcessMemoryProvider::drawInterface() {
void ProcessMemoryProvider::drawSidebarInterface() {
ImGuiExt::Header("hex.builtin.provider.process_memory.memory_regions"_lang, true);
auto availableX = ImGui::GetContentRegionAvail().x;

View File

@@ -68,7 +68,7 @@ namespace hex::plugin::builtin {
/* Not supported */
}
void UDPProvider::drawInterface() {
void UDPProvider::drawSidebarInterface() {
std::scoped_lock lock(m_mutex);
if (ImGui::BeginTable("##Messages", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImGui::GetContentRegionAvail())) {

View File

@@ -124,11 +124,16 @@ namespace hex::plugin::builtin {
else
return hex::format("{} View", m_provider->getName());
}
[[nodiscard]] std::vector<ViewProvider::Description> ViewProvider::getDataDescription() const {
if (m_provider == nullptr)
return { };
return m_provider->getDataDescription();
if (auto *dataDescriptionProvider = dynamic_cast<const IProviderDataDescription*>(m_provider); dataDescriptionProvider != nullptr) {
return dataDescriptionProvider->getDataDescription();
}
return {};
}
void ViewProvider::loadSettings(const nlohmann::json &settings) {
@@ -181,7 +186,7 @@ namespace hex::plugin::builtin {
return { Region::Invalid(), false };
}
std::vector<prv::Provider::MenuEntry> ViewProvider::getMenuEntries() {
std::vector<prv::IProviderMenuItems::MenuEntry> ViewProvider::getMenuEntries() {
return {
MenuEntry { Lang("hex.builtin.provider.rename"), ICON_VS_TAG, [this] { this->renameFile(); } }
};

View File

@@ -15,12 +15,18 @@ namespace hex::plugin::builtin {
ContentRegistry::Reports::addReportProvider([](const prv::Provider *provider) -> std::string {
std::string result;
result += "## Data description\n\n";
result += "| Type | Value |\n";
result += "| ---- | ----- |\n";
if (auto *dataDescriptionProvider = dynamic_cast<const prv::IProviderDataDescription*>(provider); dataDescriptionProvider != nullptr) {
auto descriptions = dataDescriptionProvider->getDataDescription();
if (!descriptions.empty()) {
result += "## Data description\n\n";
result += "| Type | Value |\n";
result += "| ---- | ----- |\n";
for (const auto &[type, value] : dataDescriptionProvider->getDataDescription())
result += hex::format("| {} | {} |\n", type, value);
}
}
for (const auto &[type, value] : provider->getDataDescription())
result += hex::format("| {} | {} |\n", type, value);
return result;
});

View File

@@ -353,9 +353,11 @@ namespace hex::plugin::builtin {
}
static void drawProviderContextMenu(prv::Provider *provider) {
for (const auto &menuEntry : provider->getMenuEntries()) {
if (ImGui::MenuItemEx(menuEntry.name.c_str(), menuEntry.icon)) {
menuEntry.callback();
if (auto *menuItemProvider = dynamic_cast<prv::IProviderMenuItems*>(provider); menuItemProvider != nullptr) {
for (const auto &menuEntry : menuItemProvider->getMenuEntries()) {
if (ImGui::MenuItemEx(menuEntry.name.c_str(), menuEntry.icon)) {
menuEntry.callback();
}
}
}
}
@@ -366,28 +368,30 @@ namespace hex::plugin::builtin {
ImGuiExt::TextFormatted("{}", provider->getName().c_str());
const auto &description = provider->getDataDescription();
if (!description.empty()) {
ImGui::Separator();
if (ImGui::GetIO().KeyShift && !description.empty()) {
if (auto *dataDescriptionProvider = dynamic_cast<const prv::IProviderDataDescription*>(provider); dataDescriptionProvider != nullptr) {
const auto &description = dataDescriptionProvider->getDataDescription();
if (!description.empty()) {
ImGui::Separator();
if (ImGui::GetIO().KeyShift && !description.empty()) {
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoKeepColumnsVisible, ImVec2(400_scaled, 0))) {
ImGui::TableSetupColumn("type");
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoKeepColumnsVisible, ImVec2(400_scaled, 0))) {
ImGui::TableSetupColumn("type");
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextRow();
for (auto &[name, value] : description) {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", name);
ImGui::TableNextColumn();
ImGuiExt::TextFormattedWrapped("{}", value);
for (auto &[name, value] : description) {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", name);
ImGui::TableNextColumn();
ImGuiExt::TextFormattedWrapped("{}", value);
}
ImGui::EndTable();
}
ImGui::EndTable();
} else {
ImGuiExt::TextFormattedDisabled("hex.builtin.provider.tooltip.show_more"_lang);
}
} else {
ImGuiExt::TextFormattedDisabled("hex.builtin.provider.tooltip.show_more"_lang);
}
}
@@ -423,10 +427,14 @@ namespace hex::plugin::builtin {
});
EventFrameBegin::subscribe([] {
if (rightClickedProvider != nullptr && !rightClickedProvider->getMenuEntries().empty()) {
if (ImGui::BeginPopup("ProviderMenu")) {
drawProviderContextMenu(rightClickedProvider);
ImGui::EndPopup();
if (rightClickedProvider != nullptr) {
if (auto *menuItemProvider = dynamic_cast<prv::IProviderMenuItems*>(rightClickedProvider); menuItemProvider != nullptr) {
if (!menuItemProvider->getMenuEntries().empty()) {
if (ImGui::BeginPopup("ProviderMenu")) {
drawProviderContextMenu(rightClickedProvider);
ImGui::EndPopup();
}
}
}
}
});

View File

@@ -1453,7 +1453,7 @@ namespace hex::plugin::builtin {
bool foundCorrectType = false;
auto mimeType = magic::getMIMEType(provider, 0, 100_KiB, true);
auto mimeType = magic::getMIMEType(provider, 0, 4_KiB, true);
runtime.addPragma("MIME", [&mimeType, &foundCorrectType](const pl::PatternLanguage &runtime, const std::string &value) {
std::ignore = runtime;

View File

@@ -10,20 +10,20 @@ namespace hex::plugin::builtin {
ViewProviderSettings::ViewProviderSettings() : View::Modal("hex.builtin.view.provider_settings.name") {
EventProviderCreated::subscribe(this, [this](const hex::prv::Provider *provider) {
if (provider->hasLoadInterface() && !provider->shouldSkipLoadInterface())
if (dynamic_cast<const prv::IProviderLoadInterface*>(provider) != nullptr && !provider->shouldSkipLoadInterface())
this->getWindowOpenState() = true;
});
ContentRegistry::Interface::addSidebarItem(ICON_VS_SERVER_PROCESS, [] {
auto provider = hex::ImHexApi::Provider::get();
if (provider != nullptr)
provider->drawInterface();
if (auto *sidebarInterfaceProvider = dynamic_cast<prv::IProviderSidebarInterface*>(provider); sidebarInterfaceProvider != nullptr)
sidebarInterfaceProvider->drawSidebarInterface();
},
[] {
auto provider = hex::ImHexApi::Provider::get();
return provider != nullptr && provider->hasInterface() && provider->isAvailable();
return provider != nullptr && dynamic_cast<prv::IProviderSidebarInterface*>(provider) != nullptr && provider->isAvailable();
});
}
@@ -33,8 +33,8 @@ namespace hex::plugin::builtin {
void ViewProviderSettings::drawContent() {
auto provider = hex::ImHexApi::Provider::get();
if (provider != nullptr) {
bool settingsValid = provider->drawLoadInterface();
if (auto *loadInterfaceProvider = dynamic_cast<prv::IProviderLoadInterface*>(provider); loadInterfaceProvider != nullptr) {
bool settingsValid = loadInterfaceProvider->drawLoadInterface();
ImGui::NewLine();
ImGui::Separator();