mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
feat: Added basic toast popups
This commit is contained in:
@@ -45,6 +45,7 @@ set(LIBIMHEX_SOURCES
|
||||
source/ui/imgui_imhex_extensions.cpp
|
||||
source/ui/view.cpp
|
||||
source/ui/popup.cpp
|
||||
source/ui/toast.cpp
|
||||
|
||||
source/subcommands/subcommands.cpp
|
||||
)
|
||||
|
||||
@@ -56,8 +56,9 @@ namespace hex {
|
||||
return m_close;
|
||||
}
|
||||
|
||||
protected:
|
||||
static std::mutex& getMutex();
|
||||
private:
|
||||
|
||||
UnlocalizedString m_unlocalizedName;
|
||||
bool m_closeButton, m_modal;
|
||||
std::atomic<bool> m_close = false;
|
||||
@@ -74,8 +75,7 @@ namespace hex {
|
||||
public:
|
||||
template<typename ...Args>
|
||||
static void open(Args && ... args) {
|
||||
static std::mutex mutex;
|
||||
std::lock_guard lock(mutex);
|
||||
std::lock_guard lock(getMutex());
|
||||
|
||||
auto popup = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
|
||||
|
||||
60
lib/libimhex/include/hex/ui/toast.hpp
Normal file
60
lib/libimhex/include/hex/ui/toast.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <imgui.h>
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class ToastBase {
|
||||
public:
|
||||
ToastBase(ImColor color) : m_color(color) {}
|
||||
virtual ~ToastBase() = default;
|
||||
|
||||
virtual void draw() { drawContent(); }
|
||||
virtual void drawContent() = 0;
|
||||
|
||||
[[nodiscard]] static std::list<std::unique_ptr<ToastBase>> &getQueuedToasts();
|
||||
|
||||
[[nodiscard]] const ImColor& getColor() const {
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void setAppearTime(double appearTime) {
|
||||
m_appearTime = appearTime;
|
||||
}
|
||||
|
||||
[[nodiscard]] double getAppearTime() const {
|
||||
return m_appearTime;
|
||||
}
|
||||
|
||||
constexpr static double VisibilityTime = 4.0;
|
||||
|
||||
protected:
|
||||
static std::mutex& getMutex();
|
||||
|
||||
double m_appearTime = 0;
|
||||
ImColor m_color;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class Toast : public impl::ToastBase {
|
||||
public:
|
||||
using impl::ToastBase::ToastBase;
|
||||
|
||||
template<typename ...Args>
|
||||
static void open(Args && ... args) {
|
||||
std::lock_guard lock(getMutex());
|
||||
|
||||
auto toast = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
getQueuedToasts().emplace_back(std::move(toast));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -9,5 +9,12 @@ namespace hex::impl {
|
||||
return openPopups;
|
||||
}
|
||||
|
||||
std::mutex& PopupBase::getMutex() {
|
||||
static std::mutex mutex;
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
17
lib/libimhex/source/ui/toast.cpp
Normal file
17
lib/libimhex/source/ui/toast.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <hex/ui/toast.hpp>
|
||||
|
||||
namespace hex::impl {
|
||||
|
||||
[[nodiscard]] std::list<std::unique_ptr<ToastBase>> &ToastBase::getQueuedToasts() {
|
||||
static std::list<std::unique_ptr<ToastBase>> queuedToasts;
|
||||
|
||||
return queuedToasts;
|
||||
}
|
||||
|
||||
std::mutex& ToastBase::getMutex() {
|
||||
static std::mutex mutex;
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <hex/ui/toast.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -753,6 +754,45 @@ 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 {
|
||||
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)) {
|
||||
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->PopClipRect();
|
||||
|
||||
ImGui::Indent();
|
||||
currToast->draw();
|
||||
ImGui::Unindent();
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if ((currToast->getAppearTime() + impl::ToastBase::VisibilityTime) < ImGui::GetTime()) {
|
||||
currToast.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Run all deferred calls
|
||||
TaskManager::runDeferredCalls();
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
#include <hex/ui/toast.hpp>
|
||||
|
||||
#include <fonts/codicons_font.h>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
namespace hex::plugin::builtin::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)) {}
|
||||
|
||||
void drawContent() final {
|
||||
ImGuiExt::TextFormattedColored(this->getColor(), "{}", m_icon);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushFont(ImHexApi::Fonts::Bold());
|
||||
{
|
||||
ImGuiExt::TextFormatted("{}", hex::limitStringLength(Lang(m_title).get(), 30));
|
||||
}
|
||||
ImGui::PopFont();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGuiExt::TextFormattedWrapped("{}", hex::limitStringLength(Lang(m_message).get(), 60));
|
||||
}
|
||||
|
||||
private:
|
||||
const char *m_icon;
|
||||
UnlocalizedString m_title, 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)) {}
|
||||
};
|
||||
|
||||
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 ToastError : impl::ToastNotification<ToastError> {
|
||||
ToastError(UnlocalizedString title, UnlocalizedString message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError), ICON_VS_ERROR, std::move(title), std::move(message)) {}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user