#pragma once #include #include #include #include #include #include #include #include #include #include enum ImGuiCustomCol { ImGuiCustomCol_DescButton, ImGuiCustomCol_DescButtonHovered, ImGuiCustomCol_DescButtonActive, ImGuiCustomCol_ToolbarGray, ImGuiCustomCol_ToolbarRed, ImGuiCustomCol_ToolbarYellow, ImGuiCustomCol_ToolbarGreen, ImGuiCustomCol_ToolbarBlue, ImGuiCustomCol_ToolbarPurple, ImGuiCustomCol_ToolbarBrown, ImGuiCustomCol_LoggerDebug, ImGuiCustomCol_LoggerInfo, ImGuiCustomCol_LoggerWarning, ImGuiCustomCol_LoggerError, ImGuiCustomCol_LoggerFatal, ImGuiCustomCol_AchievementUnlocked, ImGuiCustomCol_FindHighlight, ImGuiCustomCol_DiffAdded, ImGuiCustomCol_DiffRemoved, ImGuiCustomCol_DiffChanged, ImGuiCustomCol_AdvancedEncodingASCII, ImGuiCustomCol_AdvancedEncodingSingleChar, ImGuiCustomCol_AdvancedEncodingMultiChar, ImGuiCustomCol_AdvancedEncodingUnknown, ImGuiCustomCol_Highlight, ImGuiCustomCol_Patches, ImGuiCustomCol_PatternSelected, ImGuiCustomCol_IEEEToolSign, ImGuiCustomCol_IEEEToolExp, ImGuiCustomCol_IEEEToolMantissa, ImGuiCustomCol_BlurBackground, ImGuiCustomCol_COUNT }; enum ImGuiCustomStyle { ImGuiCustomStyle_WindowBlur, ImGuiCustomStyle_COUNT }; namespace ImGuiExt { class Texture { public: Texture() = default; Texture(const ImU8 *buffer, int size, int width = 0, int height = 0); Texture(std::span bytes, int width = 0, int height = 0); explicit Texture(const char *path); Texture(unsigned int texture, int width, int height); Texture(const Texture&) = delete; Texture(Texture&& other) noexcept; ~Texture(); Texture& operator=(const Texture&) = delete; Texture& operator=(Texture&& other) noexcept; [[nodiscard]] constexpr bool isValid() const noexcept { return this->m_textureId != nullptr; } [[nodiscard]] constexpr operator ImTextureID() const noexcept { return this->m_textureId; } [[nodiscard]] auto getSize() const noexcept { return ImVec2(this->m_width, this->m_height); } [[nodiscard]] constexpr auto getAspectRatio() const noexcept { if (this->m_height == 0) return 1.0F; return float(this->m_width) / float(this->m_height); } private: ImTextureID m_textureId = nullptr; int m_width = 0, m_height = 0; }; int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data); bool IconHyperlink(const char *icon, const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); bool Hyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); bool BulletHyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); bool DescriptionButton(const char *label, const char *description, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); bool DescriptionButtonProgress(const char *label, const char *description, float fraction, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); void HelpHover(const char *text); void UnderlinedText(const char *label, ImColor color = ImGui::GetStyleColorVec4(ImGuiCol_Text), const ImVec2 &size_arg = ImVec2(0, 0)); void TextSpinner(const char *label); void Header(const char *label, bool firstEntry = false); void HeaderColored(const char *label, ImColor color, bool firstEntry); bool InfoTooltip(const char *text = ""); bool TitleBarButton(const char *label, ImVec2 size_arg); bool ToolBarButton(const char *symbol, ImVec4 color); bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0)); bool InputIntegerPrefix(const char* label, const char *prefix, void *value, ImGuiDataType type, const char *format, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); bool InputHexadecimal(const char* label, u32 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); bool InputHexadecimal(const char* label, u64 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); inline bool HasSecondPassed() { return static_cast(ImGui::GetTime() * 100) % 100 <= static_cast(ImGui::GetIO().DeltaTime * 100); } void OpenPopupInWindow(const char *window_name, const char *popup_name); struct ImHexCustomData { ImVec4 Colors[ImGuiCustomCol_COUNT]; struct Styles { float WindowBlur = 0.0F; } styles; }; ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul = 1.0F); ImVec4 GetCustomColorVec4(ImGuiCustomCol idx, float alpha_mul = 1.0F); inline ImHexCustomData::Styles& GetCustomStyle() { auto &customData = *static_cast(GImGui->IO.UserData); return customData.styles; } float GetCustomStyleFloat(ImGuiCustomStyle idx); ImVec2 GetCustomStyleVec2(ImGuiCustomStyle idx); void StyleCustomColorsDark(); void StyleCustomColorsLight(); void StyleCustomColorsClassic(); void SmallProgressBar(float fraction, float yOffset = 0.0F); inline void TextFormatted(const std::string &fmt, auto &&...args) { ImGui::TextUnformatted(hex::format(fmt, std::forward(args)...).c_str()); } inline void TextFormattedSelectable(const std::string &fmt, auto &&...args) { auto text = hex::format(fmt, std::forward(args)...); ImGui::PushID(text.c_str()); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2()); ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4()); ImGui::PushItemWidth(-FLT_MIN); ImGui::InputText("##", const_cast(text.c_str()), text.size(), ImGuiInputTextFlags_ReadOnly); ImGui::PopItemWidth(); ImGui::PopStyleColor(); ImGui::PopStyleVar(); ImGui::PopID(); } inline void TextFormattedColored(ImColor color, const std::string &fmt, auto &&...args) { ImGui::TextColored(color, "%s", hex::format(fmt, std::forward(args)...).c_str()); } inline void TextFormattedDisabled(const std::string &fmt, auto &&...args) { ImGui::TextDisabled("%s", hex::format(fmt, std::forward(args)...).c_str()); } inline void TextFormattedWrapped(const std::string &fmt, auto &&...args) { ImGui::TextWrapped("%s", hex::format(fmt, std::forward(args)...).c_str()); } inline void TextFormattedWrappedSelectable(const std::string &fmt, auto &&...args) { // Manually wrap text, using the letter M (generally the widest character in non-monospaced fonts) to calculate the character width to use. auto text = wolv::util::wrapMonospacedString( hex::format(fmt, std::forward(args)...), ImGui::CalcTextSize("M").x, ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize ); ImGui::PushID(text.c_str()); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2()); ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4()); ImGui::PushItemWidth(-FLT_MIN); ImGui::InputTextMultiline( "##", const_cast(text.c_str()), text.size(), ImVec2(0, -FLT_MIN), ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll ); ImGui::PopItemWidth(); ImGui::PopStyleColor(); ImGui::PopStyleVar(); ImGui::PopID(); } inline void TextFormattedCentered(const std::string &fmt, auto &&...args) { auto text = hex::format(fmt, std::forward(args)...); auto availableSpace = ImGui::GetContentRegionAvail(); auto textSize = ImGui::CalcTextSize(text.c_str(), nullptr, false); ImGui::SetCursorPos(((availableSpace - textSize) / 2.0F)); ImGui::PushTextWrapPos(availableSpace.x * 0.75F); ImGuiExt::TextFormattedWrapped("{}", text); ImGui::PopTextWrapPos(); } inline void TextFormattedCenteredHorizontal(const std::string &fmt, auto &&...args) { auto text = hex::format(fmt, std::forward(args)...); auto availableSpace = ImGui::GetContentRegionAvail(); auto textSize = ImGui::CalcTextSize(text.c_str(), nullptr, false); ImGui::SetCursorPosX(((availableSpace - textSize) / 2.0F).x); ImGui::PushTextWrapPos(availableSpace.x * 0.75F); ImGuiExt::TextFormattedWrapped("{}", text); ImGui::PopTextWrapPos(); } bool InputTextIcon(const char* label, const char *icon, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); bool InputScalarCallback(const char* label, ImGuiDataType data_type, void* p_data, const char* format, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); void HideTooltip(); bool BitCheckbox(const char* label, bool* v); bool DimmedButton(const char* label, ImVec2 size = ImVec2(0, 0)); bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0)); bool DimmedIconToggle(const char *icon, bool *v); void TextOverlay(const char *text, ImVec2 pos); bool BeginBox(); void EndBox(); void BeginSubWindow(const char *label, ImVec2 size = ImVec2(0, 0), ImGuiChildFlags flags = ImGuiChildFlags_None); void EndSubWindow(); template constexpr ImGuiDataType getImGuiDataType() { if constexpr (std::same_as) return ImGuiDataType_U8; else if constexpr (std::same_as) return ImGuiDataType_U16; else if constexpr (std::same_as) return ImGuiDataType_U32; else if constexpr (std::same_as) return ImGuiDataType_U64; else if constexpr (std::same_as) return ImGuiDataType_S8; else if constexpr (std::same_as) return ImGuiDataType_S16; else if constexpr (std::same_as) return ImGuiDataType_S32; else if constexpr (std::same_as) return ImGuiDataType_S64; else if constexpr (std::same_as) return ImGuiDataType_Float; else if constexpr (std::same_as) return ImGuiDataType_Double; else static_assert(hex::always_false::value, "Invalid data type!"); } template constexpr const char *getFormatLengthSpecifier() { if constexpr (std::same_as) return "hh"; else if constexpr (std::same_as) return "h"; else if constexpr (std::same_as) return "l"; else if constexpr (std::same_as) return "ll"; else if constexpr (std::same_as) return "hh"; else if constexpr (std::same_as) return "h"; else if constexpr (std::same_as) return "l"; else if constexpr (std::same_as) return "ll"; else static_assert(hex::always_false::value, "Invalid data type!"); } } // these functions are exception because they just allow conversion from string to char*, they do not really add anything namespace ImGui { bool InputText(const char* label, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); bool InputText(const char *label, std::u8string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); bool InputTextMultiline(const char* label, std::string &buffer, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); bool InputTextWithHint(const char *label, const char *hint, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None); }