diff options
Diffstat (limited to 'source/30-game')
-rw-r--r-- | source/30-game/EditorCorePrivate.cpp | 2 | ||||
-rw-r--r-- | source/30-game/EditorNotification.cpp | 277 | ||||
-rw-r--r-- | source/30-game/EditorNotification.hpp | 81 |
3 files changed, 1 insertions, 359 deletions
diff --git a/source/30-game/EditorCorePrivate.cpp b/source/30-game/EditorCorePrivate.cpp index 358a95a..b335c60 100644 --- a/source/30-game/EditorCorePrivate.cpp +++ b/source/30-game/EditorCorePrivate.cpp @@ -5,7 +5,6 @@ #include "EditorAccessories.hpp" #include "EditorAttachmentImpl.hpp" #include "EditorCommandPalette.hpp" -#include "EditorNotification.hpp" #include "EditorUtils.hpp" #include "GameObject.hpp" #include "Mesh.hpp" @@ -13,6 +12,7 @@ #include "SceneThings.hpp" #include "VertexIndex.hpp" +#include <ImGuiNotification.hpp> #include <Macros.hpp> #include <Metadata.hpp> #include <ScopeGuard.hpp> diff --git a/source/30-game/EditorNotification.cpp b/source/30-game/EditorNotification.cpp deleted file mode 100644 index e4a869e..0000000 --- a/source/30-game/EditorNotification.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// Adapted from https://github.com/patrickcjk/imgui-notify -#include "EditorNotification.hpp" - -#include "Macros.hpp" - -#define IMGUI_DEFINE_MATH_OPERATORS -#include <imgui_internal.h> - -#include <chrono> -#include <cstdarg> -#include <cstdio> -#include <utility> -#include <vector> - -ImGuiToast::ImGuiToast(ImGuiToastType type, int dismissTime) { - IM_ASSERT(type < ImGuiToastType_COUNT); - - mType = type; - mDismissTime = dismissTime; - - using namespace std::chrono; - auto timeStamp = system_clock::now().time_since_epoch(); - mCreationTime = duration_cast<milliseconds>(timeStamp).count(); - - memset(mTitle, 0, sizeof(mTitle)); - memset(mContent, 0, sizeof(mContent)); -} - -ImGuiToast::ImGuiToast(ImGuiToastType type, const char* format, ...) - : ImGuiToast(type) { - if (format) { - va_list args; - va_start(args, format); - SetContent(format, args); - va_end(args); - } -} - -ImGuiToast::ImGuiToast(ImGuiToastType type, int dismissTime, const char* format, ...) - : ImGuiToast(type, dismissTime) { - if (format) { - va_list args; - va_start(args, format); - SetContent(format, args); - va_end(args); - } -} - -void ImGuiToast::SetTitle(const char* format, ...) { - if (format) { - va_list args; - va_start(args, format); - SetTitle(format, args); - va_end(args); - } -} - -void ImGuiToast::SetContent(const char* format, ...) { - if (format) { - va_list args; - va_start(args, format); - SetContent(format, args); - va_end(args); - } -} - -void ImGuiToast::SetType(const ImGuiToastType& type) { - IM_ASSERT(type < ImGuiToastType_COUNT); - mType = type; -} - -const char* ImGuiToast::GetTitle() { - return mTitle; -} - -const char* ImGuiToast::GetDefaultTitle() { - if (!strlen(mTitle)) { - switch (mType) { - case ImGuiToastType_None: return nullptr; - case ImGuiToastType_Success: return "Success"; - case ImGuiToastType_Warning: return "Warning"; - case ImGuiToastType_Error: return "Error"; - case ImGuiToastType_Info: return "Info"; - case ImGuiToastType_COUNT: UNREACHABLE; - } - } - - return mTitle; -} - -ImGuiToastType ImGuiToast::GetType() { - return mType; -} - -ImVec4 ImGuiToast::GetColor() { - switch (mType) { - case ImGuiToastType_None: return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // White - case ImGuiToastType_Success: return ImVec4(0, 1.0f, 0, 1.0f); // Green - case ImGuiToastType_Warning: return ImVec4(1.0f, 1.0f, 0, 1.0f); // Yellow - case ImGuiToastType_Error: return ImVec4(1.0f, 0, 0, 1.0f); // Red - case ImGuiToastType_Info: return ImVec4(0, 0.616, 1.0f, 1.0f); // Blue - case ImGuiToastType_COUNT: UNREACHABLE; - } - return ImVec4(); -} - -const char* ImGuiToast::GetIcon() { - switch (mType) { - case ImGuiToastType_None: return nullptr; -#if 1 - // TODO add IconFontHeaders and replace with proper icons - case ImGuiToastType_Success: return nullptr; - case ImGuiToastType_Warning: return nullptr; - case ImGuiToastType_Error: return nullptr; - case ImGuiToastType_Info: return nullptr; -#else - case ImGuiToastType_Success: return ICON_FA_CHECK_CIRCLE; - case ImGuiToastType_Warning: return ICON_FA_EXCLAMATION_TRIANGLE; - case ImGuiToastType_Error: return ICON_FA_TIMES_CIRCLE; - case ImGuiToastType_Info: return ICON_FA_INFO_CIRCLE; -#endif - case ImGuiToastType_COUNT: UNREACHABLE; - } - return nullptr; -} - -const char* ImGuiToast::GetContent() { - return this->mContent; -} - -uint64_t ImGuiToast::GetElapsedTime() { - using namespace std::chrono; - auto timeStamp = system_clock::now().time_since_epoch(); - auto timeStampI = duration_cast<milliseconds>(timeStamp).count(); - return timeStampI - mCreationTime; -} - -ImGuiToastPhase ImGuiToast::GetPhase() { - const auto elapsed = GetElapsedTime(); - - if (elapsed > kNotifyFadeInOutTime + mDismissTime + kNotifyFadeInOutTime) { - return ImGuiToastPhase_Expired; - } else if (elapsed > kNotifyFadeInOutTime + mDismissTime) { - return ImGuiToastPhase_FadeOut; - } else if (elapsed > kNotifyFadeInOutTime) { - return ImGuiToastPhase_Wait; - } else { - return ImGuiToastPhase_FadeIn; - } -} - -float ImGuiToast::GetFadePercent() { - const auto phase = GetPhase(); - const auto elapsed = GetElapsedTime(); - - if (phase == ImGuiToastPhase_FadeIn) - { - return ((float)elapsed / (float)kNotifyFadeInOutTime) * kNotifyOpacity; - } else if (phase == ImGuiToastPhase_FadeOut) - { - return (1.0f - (((float)elapsed - (float)kNotifyFadeInOutTime - (float)mDismissTime) / (float)kNotifyFadeInOutTime)) * kNotifyOpacity; - } - - return 1.0f * kNotifyOpacity; -} - -void ImGuiToast::SetTitle(const char* format, va_list args) { - vsnprintf(mTitle, sizeof(mTitle), format, args); -} - -void ImGuiToast::SetContent(const char* format, va_list args) { - vsnprintf(mContent, sizeof(mContent), format, args); -} - -namespace ImGui { -static std::vector<ImGuiToast> notifications; -} - -static bool IsNullOrEmpty(const char* str) { - return !str || !strlen(str); -} - -void ImGui::AddNotification(ImGuiToast toast) { - notifications.push_back(std::move(toast)); -} - -void ImGui::RemoveNotification(int index) { - notifications.erase(notifications.begin() + index); -} - -void ImGui::ShowNotifications() { - auto vpSize = GetMainViewport()->Size; - - float height = 0.0f; - for (auto i = 0; i < notifications.size(); i++) { - auto* currentToast = ¬ifications[i]; - - // Remove toast if expired - if (currentToast->GetPhase() == ImGuiToastPhase_Expired) { - RemoveNotification(i); - continue; - } - - // Get icon, title and other data - const auto icon = currentToast->GetIcon(); - const auto title = currentToast->GetTitle(); - const auto content = currentToast->GetContent(); - const auto defaultTitle = currentToast->GetDefaultTitle(); - const auto opacity = currentToast->GetFadePercent(); // Get opacity based of the current phase - - // Window rendering - auto textColor = currentToast->GetColor(); - textColor.w = opacity; - - // Generate new unique name for this toast - char windowName[50]; - snprintf(windowName, std::size(windowName), "##TOAST%d", i); - - SetNextWindowBgAlpha(opacity); - SetNextWindowPos(ImVec2(vpSize.x - kNotifyPaddingX, vpSize.y - kNotifyPaddingY - height), ImGuiCond_Always, ImVec2(1.0f, 1.0f)); - Begin(windowName, nullptr, kNotifyToastFlags); - BringWindowToDisplayFront(GetCurrentWindow()); - - // Here we render the toast content - { - PushTextWrapPos(vpSize.x / 3.0f); // We want to support multi-line text, this will wrap the text after 1/3 of the screen width - - bool wasTitleRendered = false; - - // If an icon is set - if (!::IsNullOrEmpty(icon)) { - // Render icon text - PushStyleColor(ImGuiCol_Text, textColor); - TextUnformatted(icon); - PopStyleColor(); - wasTitleRendered = true; - } - - // If a title is set - if (!::IsNullOrEmpty(title)) { - // If a title and an icon is set, we want to render on same line - if (!::IsNullOrEmpty(icon)) - SameLine(); - - TextUnformatted(title); // Render title text - wasTitleRendered = true; - } else if (!::IsNullOrEmpty(defaultTitle)) { - if (!::IsNullOrEmpty(icon)) - SameLine(); - - TextUnformatted(defaultTitle); // Render default title text (ImGuiToastType_Success -> "Success", etc...) - wasTitleRendered = true; - } - - // In case ANYTHING was rendered in the top, we want to add a small padding so the text (or icon) looks centered vertically - if (wasTitleRendered && !::IsNullOrEmpty(content)) { - SetCursorPosY(GetCursorPosY() + 5.0f); // Must be a better way to do this!!!! - } - - // If a content is set - if (!::IsNullOrEmpty(content)) { - if (wasTitleRendered) { - Separator(); - } - - TextUnformatted(content); // Render content text - } - - PopTextWrapPos(); - } - - // Save height for next toasts - height += GetWindowHeight() + kNotifyPaddingMessageY; - - End(); - } -} diff --git a/source/30-game/EditorNotification.hpp b/source/30-game/EditorNotification.hpp deleted file mode 100644 index 3af8c2d..0000000 --- a/source/30-game/EditorNotification.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// Adapted from https://github.com/patrickcjk/imgui-notify -#pragma once - -#include <imgui.h> -#include <cstdint> - -enum ImGuiToastType { - ImGuiToastType_None, - ImGuiToastType_Success, - ImGuiToastType_Warning, - ImGuiToastType_Error, - ImGuiToastType_Info, - ImGuiToastType_COUNT -}; - -enum ImGuiToastPhase { - ImGuiToastPhase_FadeIn, - ImGuiToastPhase_Wait, - ImGuiToastPhase_FadeOut, - ImGuiToastPhase_Expired, - ImGuiToastPhase_COUNT -}; - -enum ImGuiToastPos { - ImGuiToastPos_TopLeft, - ImGuiToastPos_TopCenter, - ImGuiToastPos_TopRight, - ImGuiToastPos_BottomLeft, - ImGuiToastPos_BottomCenter, - ImGuiToastPos_BottomRight, - ImGuiToastPos_Center, - ImGuiToastPos_COUNT -}; - -constexpr int kNotifyMaxMsgLength = 4096; // Max message content length -constexpr float kNotifyPaddingX = 20.0f; // Bottom-left X padding -constexpr float kNotifyPaddingY = 20.0f; // Bottom-left Y padding -constexpr float kNotifyPaddingMessageY = 10.0f; // Padding Y between each message -constexpr uint64_t kNotifyFadeInOutTime = 150; // Fade in and out duration -constexpr uint64_t kNotifyDefaultDismiss = 3000; // Auto dismiss after X ms (default, applied only of no data provided in constructors) -constexpr float kNotifyOpacity = 1.0f; // 0-1 Toast opacity -constexpr ImGuiWindowFlags kNotifyToastFlags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing; - -class ImGuiToast { -private: - ImGuiToastType mType = ImGuiToastType_None; - char mTitle[kNotifyMaxMsgLength] = {}; - char mContent[kNotifyMaxMsgLength] = {}; - int mDismissTime = kNotifyDefaultDismiss; - uint64_t mCreationTime = 0; - -public: - ImGuiToast(ImGuiToastType type, int dismissTime = kNotifyDefaultDismiss); - ImGuiToast(ImGuiToastType type, const char* format, ...); - ImGuiToast(ImGuiToastType type, int dismissTime, const char* format, ...); - - void SetTitle(const char* format, ...); - void SetContent(const char* format, ...); - void SetType(const ImGuiToastType& type); - - const char* GetTitle(); - const char* GetDefaultTitle(); - ImGuiToastType GetType(); - ImVec4 GetColor(); - const char* GetIcon(); - const char* GetContent(); - - uint64_t GetElapsedTime(); - ImGuiToastPhase GetPhase(); - float GetFadePercent(); - -private: - void SetTitle(const char* format, va_list args); - void SetContent(const char* format, va_list args); -}; - -namespace ImGui { -void AddNotification(ImGuiToast toast); -void RemoveNotification(int index); -void ShowNotifications(); -} // namespace ImGui |