1
0
mirror of synced 2025-01-18 00:56:49 +01:00

impr: Switch most usages of modals over to toasts

This commit is contained in:
WerWolv 2023-12-26 00:22:47 +01:00
parent 52192a3b26
commit 96fe608d60
25 changed files with 129 additions and 121 deletions

@ -1 +1 @@
Subproject commit b998f3d47940970d0ff74451ea6a7ca06c803af5
Subproject commit 5b54c3b814c784500fb40fb6cfe55f8aa7187fcb

View File

@ -289,11 +289,6 @@ namespace hex {
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
EVENT_DEF(RequestInitThemeHandlers);
EVENT_DEF(RequestOpenInfoPopup, const std::string);
EVENT_DEF(RequestOpenErrorPopup, const std::string);
EVENT_DEF(RequestOpenFatalPopup, const std::string);
/**
* @brief Send an event to the main Imhex instance
*/

View File

@ -672,7 +672,6 @@ namespace hex {
// Draw popup stack
{
static bool popupDisplaying = false;
static bool positionSet = false;
static bool sizeSet = false;
static double popupDelay = -2.0;
@ -724,7 +723,6 @@ namespace hex {
const auto createPopup = [&](bool displaying) {
if (displaying) {
currPopup->drawContent();
popupDisplaying = true;
if (ImGui::GetWindowSize().x > ImGui::GetStyle().FramePadding.x * 10)
sizeSet = true;
@ -742,8 +740,6 @@ namespace hex {
}
ImGui::EndPopup();
} else {
popupDisplaying = false;
}
};
@ -752,7 +748,7 @@ namespace hex {
else
createPopup(ImGui::BeginPopup(name, flags));
if (!popupDisplaying || currPopup->shouldClose()) {
if (currPopup->shouldClose()) {
log::debug("Closing popup '{}'", name);
positionSet = sizeSet = false;
@ -763,41 +759,38 @@ namespace hex {
// Draw Toasts
{
static std::unique_ptr<impl::ToastBase> currToast;
if (currToast == nullptr) {
if (auto &queuedToasts = impl::ToastBase::getQueuedToasts(); !queuedToasts.empty()) {
currToast = std::move(queuedToasts.front());
queuedToasts.pop_front();
currToast->setAppearTime(ImGui::GetTime());
}
} else {
u32 index = 0;
for (const auto &toast : impl::ToastBase::getQueuedToasts() | std::views::take(4)) {
const auto toastHeight = 60_scaled;
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5_scaled);
ImGui::SetNextWindowSize(scaled({ 280, 60 }));
ImGui::SetNextWindowPos((ImHexApi::System::getMainWindowPosition() + ImHexApi::System::getMainWindowSize()) - scaled({ 10, 10 }), ImGuiCond_Always, ImVec2(1, 1));
if (ImGui::Begin("##Toast", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs)) {
ImGui::SetNextWindowSize(ImVec2(280_scaled, toastHeight));
ImGui::SetNextWindowPos((ImHexApi::System::getMainWindowPosition() + ImHexApi::System::getMainWindowSize()) - scaled({ 10, 10 }) - scaled({ 0, (10 + toastHeight) * index }), ImGuiCond_Always, ImVec2(1, 1));
if (ImGui::Begin(hex::format("##Toast_{}", index).c_str(), nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing)) {
auto drawList = ImGui::GetWindowDrawList();
const auto min = ImGui::GetWindowPos();
const auto max = min + ImGui::GetWindowSize();
drawList->PushClipRect(min, min + scaled({ 5, 60 }));
drawList->AddRectFilled(min, max, currToast->getColor(), 5_scaled);
drawList->AddRectFilled(min, max, toast->getColor(), 5_scaled);
drawList->PopClipRect();
ImGui::Indent();
currToast->draw();
toast->draw();
ImGui::Unindent();
if (ImGui::IsWindowHovered() || toast->getAppearTime() <= 0)
toast->setAppearTime(ImGui::GetTime());
}
ImGui::End();
ImGui::PopStyleVar();
if ((currToast->getAppearTime() + impl::ToastBase::VisibilityTime) < ImGui::GetTime()) {
currToast.reset();
}
index += 1;
}
std::erase_if(impl::ToastBase::getQueuedToasts(), [](const auto &toast){
return toast->getAppearTime() > 0 && (toast->getAppearTime() + impl::ToastBase::VisibilityTime) < ImGui::GetTime();
});
}
// Run all deferred calls

View File

@ -4,6 +4,7 @@
#include <hex/helpers/crypto.hpp>
#include <toasts/toast_notification.hpp>
#include <popups/popup_notification.hpp>
#include <popups/popup_text_input.hpp>
@ -275,7 +276,7 @@ namespace hex::plugin::builtin {
if (input == password)
achievement.setUnlocked(true);
else
ui::PopupInfo::open("The password you entered was incorrect.");
ui::ToastWarning::open("The password you entered was incorrect.");
});
});

View File

@ -14,6 +14,7 @@
#include <wolv/io/fs.hpp>
#include <wolv/utils/string.hpp>
#include <toasts/toast_notification.hpp>
#include <popups/popup_notification.hpp>
#include <popups/popup_question.hpp>
#include <content/popups/popup_tasks_waiting.hpp>
@ -26,7 +27,7 @@ namespace hex::plugin::builtin {
if (auto *fileProvider = dynamic_cast<FileProvider*>(provider); fileProvider != nullptr) {
fileProvider->setPath(path);
if (!provider->open() || !provider->isAvailable()) {
ui::PopupError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
ui::ToastError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
} else {
EventProviderOpened::post(fileProvider);
@ -104,7 +105,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Open, { }, [](const auto &path) {
if (path.extension() == ".hexproj") {
if (!ProjectFile::load(path)) {
ui::PopupError::open(hex::format("hex.builtin.popup.error.project.load"_lang, wolv::util::toUTF8String(path)));
ui::ToastError::open(hex::format("hex.builtin.popup.error.project.load"_lang, wolv::util::toUTF8String(path)));
}
} else {
FileProvider* newProvider = static_cast<FileProvider*>(
@ -128,7 +129,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} },
[](const auto &path) {
if (!ProjectFile::load(path)) {
ui::PopupError::open(hex::format("hex.builtin.popup.error.project.load"_lang, wolv::util::toUTF8String(path)));
ui::ToastError::open(hex::format("hex.builtin.popup.error.project.load"_lang, wolv::util::toUTF8String(path)));
}
});
}
@ -149,7 +150,7 @@ namespace hex::plugin::builtin {
return;
}
if (!provider->open()) {
ui::PopupError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
ui::ToastError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
@ -158,7 +159,7 @@ namespace hex::plugin::builtin {
}
else if (!provider->hasLoadInterface()) {
if (!provider->open() || !provider->isAvailable()) {
ui::PopupError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
ui::ToastError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
@ -171,18 +172,6 @@ namespace hex::plugin::builtin {
ImHexApi::HexEditor::impl::setCurrentSelection(region);
});
RequestOpenInfoPopup::subscribe([](const std::string &message) {
ui::PopupInfo::open(message);
});
RequestOpenErrorPopup::subscribe([](const std::string &message) {
ui::PopupError::open(message);
});
RequestOpenFatalPopup::subscribe([](const std::string &message) {
ui::PopupFatal::open(message);
});
fs::setFileBrowserErrorCallback([](const std::string& errMsg){
#if defined(NFD_PORTAL)
ui::PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg));

View File

@ -3,7 +3,7 @@
#include <hex/api/project_file_manager.hpp>
#include <hex/helpers/logger.hpp>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <wolv/utils/string.hpp>
@ -13,7 +13,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} },
[](const auto &path) {
if (!ProjectFile::load(path)) {
ui::PopupError::open(hex::format("hex.builtin.popup.error.project.load"_lang, wolv::util::toUTF8String(path)));
ui::ToastError::open(hex::format("hex.builtin.popup.error.project.load"_lang, wolv::util::toUTF8String(path)));
}
});
}
@ -21,7 +21,7 @@ namespace hex::plugin::builtin {
void saveProject() {
if (ImHexApi::Provider::isValid() && ProjectFile::hasPath()) {
if (!ProjectFile::store()) {
ui::PopupError::open("hex.builtin.popup.error.project.save"_lang);
ui::ToastError::open("hex.builtin.popup.error.project.save"_lang);
} else {
log::debug("Project saved");
}
@ -36,7 +36,7 @@ namespace hex::plugin::builtin {
}
if (!ProjectFile::store(path)) {
ui::PopupError::open("hex.builtin.popup.error.project.save"_lang);
ui::ToastError::open("hex.builtin.popup.error.project.save"_lang);
}
});
}

View File

@ -1,16 +1,16 @@
#include <hex/helpers/logger.hpp>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
namespace hex::plugin::builtin {
void showError(const std::string& message){
ui::PopupError::open(message);
ui::ToastError::open(message);
log::error(message);
}
void showWarning(const std::string& message){
ui::PopupWarning::open(message);
ui::ToastWarning::open(message);
log::warn(message);
}
}

View File

@ -14,7 +14,7 @@
#include <hex/helpers/debugging.hpp>
#include <content/global_actions.hpp>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <popups/popup_text_input.hpp>
#include <hex/api/workspace_manager.hpp>
@ -50,19 +50,19 @@ namespace hex::plugin::builtin {
TaskManager::doLater([error]{
switch (error) {
case IPSError::InvalidPatchHeader:
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang);
break;
case IPSError::AddressOutOfRange:
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang);
break;
case IPSError::PatchTooLarge:
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang);
break;
case IPSError::InvalidPatchFormat:
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang);
break;
case IPSError::MissingEOF:
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang);
break;
}
});
@ -77,7 +77,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
wolv::io::File inputFile(path, wolv::io::File::Mode::Read);
if (!inputFile.isValid()) {
ui::PopupError::open("hex.builtin.menu.file.import.base64.popup.open_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.open_error"_lang);
return;
}
@ -87,19 +87,19 @@ namespace hex::plugin::builtin {
auto data = crypt::decode64(base64);
if (data.empty())
ui::PopupError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
else {
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) {
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
if (!outputFile.isValid())
ui::PopupError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
outputFile.writeVector(data);
});
}
} else {
ui::PopupError::open("hex.builtin.popup.file_open_error"_lang);
ui::ToastError::open("hex.builtin.popup.file_open_error"_lang);
}
});
}
@ -163,7 +163,7 @@ namespace hex::plugin::builtin {
auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector();
if (patchData.size() != provider->getActualSize()) {
ui::PopupError::open("hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang);
ui::ToastError::open("hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang);
return;
}
@ -203,7 +203,7 @@ namespace hex::plugin::builtin {
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
if (!outputFile.isValid()) {
TaskManager::doLater([] {
ui::PopupError::open("hex.builtin.menu.file.export.base64.popup.export_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.base64.popup.export_error"_lang);
});
return;
}
@ -238,7 +238,7 @@ namespace hex::plugin::builtin {
wolv::io::File file(path, wolv::io::File::Mode::Create);
if (!file.isValid()) {
TaskManager::doLater([] {
ui::PopupError::open("hex.builtin.menu.file.export.as_language.popup.export_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.as_language.popup.export_error"_lang);
});
return;
}
@ -269,7 +269,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Save, { { "Markdown File", "md" }}, [&data](const auto &path) {
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
if (!file.isValid()) {
ui::PopupError::open("hex.builtin.menu.file.export.report.popup.export_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.report.popup.export_error"_lang);
return;
}
@ -302,7 +302,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
if (!file.isValid()) {
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang);
return;
}
@ -341,7 +341,7 @@ namespace hex::plugin::builtin {
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
auto file = wolv::io::File(path, wolv::io::File::Mode::Create);
if (!file.isValid()) {
ui::PopupError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang);
ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang);
return;
}

View File

@ -155,8 +155,10 @@ namespace hex::plugin::builtin {
m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
m_writable = false;
if (m_diskHandle == INVALID_HANDLE_VALUE)
if (m_diskHandle == INVALID_HANDLE_VALUE) {
this->setErrorMessage(std::system_category().message(::GetLastError()));
return false;
}
}
{
@ -178,6 +180,7 @@ namespace hex::plugin::builtin {
}
if (m_diskHandle == nullptr || m_diskHandle == INVALID_HANDLE_VALUE) {
this->setErrorMessage(std::system_category().message(::GetLastError()));
m_readable = false;
m_diskHandle = nullptr;
CloseHandle(m_diskHandle);
@ -220,9 +223,9 @@ namespace hex::plugin::builtin {
#if defined(OS_WINDOWS)
if (m_diskHandle != INVALID_HANDLE_VALUE)
::CloseHandle(m_diskHandle);
::CloseHandle(m_diskHandle);
m_diskHandle = INVALID_HANDLE_VALUE;
m_diskHandle = INVALID_HANDLE_VALUE;
#else

View File

@ -16,6 +16,8 @@
#include <hex/helpers/fmt.hpp>
#include <hex/ui/view.hpp>
#include <toasts/toast_notification.hpp>
#include <wolv/io/fs.hpp>
#include <wolv/io/file.hpp>
#include <wolv/utils/guards.hpp>
@ -294,7 +296,7 @@ namespace hex::plugin::builtin {
if (loadLibraryW != nullptr) {
if (auto threadHandle = CreateRemoteThread(m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
WaitForSingleObject(threadHandle, INFINITE);
RequestOpenErrorPopup::post(hex::format("hex.builtin.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string()));
ui::ToastInfo::open(hex::format("hex.builtin.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string()));
this->reloadProcessModules();
CloseHandle(threadHandle);
return;
@ -303,7 +305,7 @@ namespace hex::plugin::builtin {
}
}
RequestOpenErrorPopup::post(hex::format("hex.builtin.provider.process_memory.utils.inject_dll.failure"_lang, path.filename().string()));
ui::ToastError::open(hex::format("hex.builtin.provider.process_memory.utils.inject_dll.failure"_lang, path.filename().string()));
});
}
#endif

View File

@ -15,7 +15,7 @@
#include <wolv/utils/string.hpp>
#include <content/recent.hpp>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <fonts/codicons_font.h>
namespace hex::plugin::builtin::recent {
@ -224,7 +224,7 @@ namespace hex::plugin::builtin::recent {
provider->loadSettings(recentEntry.data);
if (!provider->open() || !provider->isAvailable()) {
ui::PopupError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
ui::ToastError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}

View File

@ -2,6 +2,7 @@
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <algorithm>
#include <random>
@ -9,7 +10,7 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <wolv/io/file.hpp>
@ -113,7 +114,7 @@ namespace hex::plugin::builtin {
wolv::io::File output(outputPath, wolv::io::File::Mode::Create);
if (!output.isValid()) {
ui::PopupError::open("hex.builtin.tools.file_tools.combiner.error.open_output"_lang);
ui::ToastError::open("hex.builtin.tools.file_tools.combiner.error.open_output"_lang);
return;
}
@ -126,7 +127,7 @@ namespace hex::plugin::builtin {
wolv::io::File input(file, wolv::io::File::Mode::Read);
if (!input.isValid()) {
ui::PopupError::open(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, wolv::util::toUTF8String(file)));
ui::ToastError::open(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, wolv::util::toUTF8String(file)));
return;
}
@ -142,7 +143,7 @@ namespace hex::plugin::builtin {
selectedIndex = 0;
outputPath.clear();
ui::PopupInfo::open("hex.builtin.tools.file_tools.combiner.success"_lang);
ui::ToastInfo::open("hex.builtin.tools.file_tools.combiner.success"_lang);
});
}
}

View File

@ -1,5 +1,6 @@
#include <hex/helpers/fs.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <algorithm>
#include <random>
@ -7,7 +8,7 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <wolv/io/file.hpp>
#include <wolv/utils/guards.hpp>
@ -54,7 +55,7 @@ namespace hex::plugin::builtin {
wolv::io::File file(selectedFile, wolv::io::File::Mode::Write);
if (!file.isValid()) {
ui::PopupError::open("hex.builtin.tools.file_tools.shredder.error.open"_lang);
ui::ToastError::open("hex.builtin.tools.file_tools.shredder.error.open"_lang);
return;
}
@ -128,7 +129,7 @@ namespace hex::plugin::builtin {
file.remove();
ui::PopupInfo::open("hex.builtin.tools.file_tools.shredder.success"_lang);
ui::ToastInfo::open("hex.builtin.tools.file_tools.shredder.success"_lang);
});
}
}

View File

@ -3,13 +3,14 @@
#include <hex/helpers/literals.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <algorithm>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <wolv/io/file.hpp>
#include <wolv/utils/guards.hpp>
@ -101,12 +102,12 @@ namespace hex::plugin::builtin {
wolv::io::File file(selectedFile, wolv::io::File::Mode::Read);
if (!file.isValid()) {
ui::PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang);
ui::ToastError::open("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang);
return;
}
if (file.getSize() < splitSize) {
ui::PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang);
ui::ToastError::open("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang);
return;
}
@ -122,7 +123,7 @@ namespace hex::plugin::builtin {
wolv::io::File partFile(path, wolv::io::File::Mode::Create);
if (!partFile.isValid()) {
ui::PopupError::open(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index));
ui::ToastError::open(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index));
return;
}
@ -135,7 +136,7 @@ namespace hex::plugin::builtin {
index++;
}
ui::PopupInfo::open("hex.builtin.tools.file_tools.splitter.picker.success"_lang);
ui::ToastInfo::open("hex.builtin.tools.file_tools.splitter.picker.success"_lang);
});
}
}

View File

@ -1,6 +1,7 @@
#include <hex/api/content_registry.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/ui/view.hpp>
#include <hex/helpers/utils.hpp>
@ -13,7 +14,7 @@
#include <implot.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
namespace hex::plugin::builtin {
@ -43,10 +44,10 @@ namespace hex::plugin::builtin {
}
static void drawGlobalPopups() {
// Task exception popup
// Task exception toast
for (const auto &task : TaskManager::getRunningTasks()) {
if (task->hadException()) {
ui::PopupError::open(hex::format("hex.builtin.popup.error.task_exception"_lang, Lang(task->getUnlocalizedName()), task->getExceptionMessage()));
ui::ToastError::open(hex::format("hex.builtin.popup.error.task_exception"_lang, Lang(task->getUnlocalizedName()), task->getExceptionMessage()));
task->clearException();
break;
}

View File

@ -1,5 +1,5 @@
#include "content/views/view_data_processor.hpp"
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/api/project_file_manager.hpp>
@ -1194,7 +1194,7 @@ namespace hex::plugin::builtin {
m_updateNodePositions = true;
} catch (nlohmann::json::exception &e) {
ui::PopupError::open(hex::format("Failed to load nodes: {}", e.what()));
ui::ToastError::open(hex::format("Failed to load nodes: {}", e.what()));
}
}

View File

@ -14,7 +14,7 @@
#include <implot.h>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
namespace hex::plugin::builtin {
@ -48,7 +48,7 @@ namespace hex::plugin::builtin {
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Magic)) {
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
ui::PopupInfo::open("hex.builtin.view.information.magic_db_added"_lang);
ui::ToastInfo::open("hex.builtin.view.information.magic_db_added"_lang);
return true;
}
}

View File

@ -1,7 +1,9 @@
#include "content/views/view_provider_settings.hpp"
#include <popups/popup_notification.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/api/task_manager.hpp>
#include <toasts/toast_notification.hpp>
namespace hex::plugin::builtin {
@ -49,9 +51,9 @@ namespace hex::plugin::builtin {
ImGui::CloseCurrentPopup();
auto errorMessage = provider->getErrorMessage();
if (errorMessage.empty()) {
ui::PopupError::open("hex.builtin.view.provider_settings.load_error"_lang);
ui::ToastError::open("hex.builtin.view.provider_settings.load_error"_lang);
} else {
ui::PopupError::open(hex::format("hex.builtin.view.provider_settings.load_error_details"_lang, errorMessage));
ui::ToastError::open(hex::format("hex.builtin.view.provider_settings.load_error_details"_lang, errorMessage));
}
TaskManager::doLater([=] { ImHexApi::Provider::remove(provider); });
}

View File

@ -6,6 +6,7 @@
#include <hex/api/content_registry.hpp>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <imgui.h>
@ -310,7 +311,7 @@ namespace hex::plugin::builtin {
}
if (!downloading) {
ui::PopupError::open("hex.builtin.view.store.download_error"_lang);
ui::ToastError::open("hex.builtin.view.store.download_error"_lang);
return false;
}

View File

@ -12,6 +12,9 @@ add_imhex_plugin(
INCLUDES
include
LIBRARIES
ui
)
if (CoreClrEmbed_FOUND)

View File

@ -8,6 +8,8 @@
#include <hex/helpers/utils.hpp>
#include <popups/popup_notification.hpp>
using namespace hex;
#define VERSION V1
@ -114,7 +116,7 @@ private:
};
SCRIPT_API(void showMessageBox, const char *message) {
hex::RequestOpenInfoPopup::post(message);
ui::PopupInfo::open(message);
}
SCRIPT_API(void showInputTextBox, const char *title, const char *message, char *buffer, u32 bufferSize) {

View File

@ -7,49 +7,59 @@
#include <fonts/codicons_font.h>
#include <hex/helpers/utils.hpp>
#include <popups/popup_notification.hpp>
namespace hex::ui {
namespace impl {
template<typename T>
struct ToastNotification : Toast<T> {
ToastNotification(ImColor color, const char *icon, UnlocalizedString title, UnlocalizedString message)
: Toast<T>(color), m_icon(icon), m_title(std::move(title)), m_message(std::move(message)) {}
ToastNotification(ImColor color, const char *icon, UnlocalizedString unlocalizedTitle, std::string message)
: Toast<T>(color), m_icon(icon), m_unlocalizedTitle(std::move(unlocalizedTitle)), m_message(std::move(message)) {}
void drawContent() final {
if (ImGui::IsWindowHovered()) {
if (ImGui::BeginTooltip()) {
ImGuiExt::Header(Lang(m_unlocalizedTitle), true);
ImGui::PushTextWrapPos(300_scaled);
ImGui::TextUnformatted(m_message.c_str());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
ImGuiExt::TextFormattedColored(this->getColor(), "{}", m_icon);
ImGui::SameLine();
ImGui::PushFont(ImHexApi::Fonts::Bold());
{
ImGuiExt::TextFormatted("{}", hex::limitStringLength(Lang(m_title).get(), 30));
}
ImGui::PopFont();
ImGuiExt::TextFormatted("{}", hex::limitStringLength(Lang(m_unlocalizedTitle).get(), 30));
ImGui::Separator();
ImGuiExt::TextFormattedWrapped("{}", hex::limitStringLength(Lang(m_message).get(), 60));
ImGuiExt::TextFormattedWrapped("{}", hex::limitStringLength(m_message, 60));
}
private:
const char *m_icon;
UnlocalizedString m_title, m_message;
UnlocalizedString m_unlocalizedTitle;
std::string m_message;
};
}
struct ToastInfo : impl::ToastNotification<ToastInfo> {
ToastInfo(UnlocalizedString title, UnlocalizedString message)
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerInfo), ICON_VS_INFO, std::move(title), std::move(message)) {}
ToastInfo(std::string message)
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerInfo), ICON_VS_INFO, "hex.ui.common.info", std::move(message)) {}
};
struct ToastWarn : impl::ToastNotification<ToastWarn> {
ToastWarn(UnlocalizedString title, UnlocalizedString message)
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerWarning), ICON_VS_WARNING, std::move(title), std::move(message)) {}
struct ToastWarning : impl::ToastNotification<ToastWarning> {
ToastWarning(std::string message)
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerWarning), ICON_VS_WARNING, "hex.ui.common.warning", std::move(message)) {}
};
struct ToastError : impl::ToastNotification<ToastError> {
ToastError(UnlocalizedString title, UnlocalizedString message)
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError), ICON_VS_ERROR, std::move(title), std::move(message)) {}
ToastError(std::string message)
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError), ICON_VS_ERROR, "hex.ui.common.error", std::move(message)) {}
};
}

View File

@ -16,6 +16,7 @@ if (WIN32)
INCLUDES
include
LIBRARIES
ui
${JTHREAD_LIBRARIES}
)

View File

@ -5,6 +5,8 @@
#include <hex/api/task_manager.hpp>
#include <hex/helpers/utils.hpp>
#include <toasts/toast_notification.hpp>
#include <wolv/utils/guards.hpp>
#include <windows.h>
@ -85,7 +87,7 @@ namespace hex::plugin::windows {
if (m_portHandle == INVALID_HANDLE_VALUE) {
if (ImGui::Button("hex.windows.view.tty_console.connect"_lang))
if (!this->connect())
RequestOpenErrorPopup::post("hex.windows.view.tty_console.connect_error"_lang);
ui::ToastError::open("hex.windows.view.tty_console.connect_error"_lang);
} else {
if (ImGui::Button("hex.windows.view.tty_console.disconnect"_lang))
this->disconnect();
@ -184,7 +186,7 @@ namespace hex::plugin::windows {
bool ViewTTYConsole::connect() {
if (m_comPorts.empty() || static_cast<size_t>(m_selectedPort) >= m_comPorts.size()) {
RequestOpenErrorPopup::post("hex.windows.view.tty_console.no_available_port"_lang);
ui::ToastError::open("hex.windows.view.tty_console.no_available_port"_lang);
return true; // If false, connect_error error popup will override this error popup
}
m_portHandle = ::CreateFile((R"(\\.\)" + m_comPorts[m_selectedPort].first).c_str(),

View File

@ -6,7 +6,7 @@
#include <hex/helpers/utils.hpp>
#include <hex/helpers/fs.hpp>
#include <popups/popup_notification.hpp>
#include <toasts/toast_notification.hpp>
#include <popups/popup_file_chooser.hpp>
// <yara/types.h>'s RE type has a zero-sized array, which is not allowed in ISO C++.
@ -33,7 +33,7 @@ namespace hex::plugin::yara {
ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) {
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Yara)) {
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
ui::PopupInfo::open("hex.yara_rules.view.yara.rule_added"_lang);
ui::ToastInfo::open("hex.yara_rules.view.yara.rule_added"_lang);
return true;
}
}