2021-12-31 01:10:06 +01:00
# include <hex/ui/imgui_imhex_extensions.h>
2021-01-27 00:00:20 +01:00
# include <imgui.h>
# include <imgui_internal.h>
2023-12-02 23:46:20 +01:00
# include <implot.h>
# include <implot_internal.h>
2024-03-12 23:17:49 +01:00
# include <cimgui.h>
2023-11-20 23:58:49 +01:00
# include <opengl_support.h>
2023-11-20 23:51:50 +01:00
2021-01-27 00:00:20 +01:00
# undef IMGUI_DEFINE_MATH_OPERATORS
2021-04-17 15:46:26 +02:00
# define STB_IMAGE_IMPLEMENTATION
# include <stb_image.h>
2024-05-01 20:36:10 +02:00
# include <lunasvg.h>
2023-12-13 11:24:25 +01:00
# include <set>
2021-01-27 12:04:42 +01:00
# include <string>
2022-08-17 16:15:36 +02:00
# include <hex/api/imhex_api.hpp>
2023-12-13 11:24:25 +01:00
# include <hex/api/task_manager.hpp>
# include <hex/api/theme_manager.hpp>
2024-05-03 19:27:12 +02:00
# include <hex/helpers/logger.hpp>
2023-05-11 12:00:45 +02:00
2021-01-27 00:00:20 +01:00
2023-11-16 22:24:06 +01:00
namespace ImGuiExt {
using namespace ImGui ;
2023-12-09 22:00:35 +01:00
namespace {
2024-05-03 19:27:12 +02:00
bool isOpenGLExtensionSupported ( const char * name ) {
2024-05-08 22:09:47 +02:00
static std : : set < std : : string > extensions ;
2024-05-03 19:27:12 +02:00
2024-05-08 22:09:47 +02:00
if ( extensions . empty ( ) ) {
GLint extensionCount = 0 ;
glGetIntegerv ( GL_NUM_EXTENSIONS , & extensionCount ) ;
for ( GLint i = 0 ; i < extensionCount ; i + + ) {
std : : string extension = reinterpret_cast < const char * > ( glGetStringi ( GL_EXTENSIONS , i ) ) ;
extensions . emplace ( std : : move ( extension ) ) ;
2024-05-03 19:27:12 +02:00
}
}
2024-05-08 22:09:47 +02:00
return extensions . contains ( name ) ;
}
bool isOpenGLVersionAtLeast ( u8 major , u8 minor ) {
static GLint actualMajor = 0 , actualMinor = 0 ;
if ( actualMajor = = 0 | | actualMinor = = 0 ) {
glGetIntegerv ( GL_MAJOR_VERSION , & actualMajor ) ;
glGetIntegerv ( GL_MINOR_VERSION , & actualMinor ) ;
}
return actualMajor > major | | ( actualMajor = = major & & actualMinor > = minor ) ;
2024-05-03 19:27:12 +02:00
}
2023-12-09 22:00:35 +01:00
constexpr auto getGLFilter ( Texture : : Filter filter ) {
switch ( filter ) {
using enum Texture : : Filter ;
case Nearest :
return GL_NEAREST ;
case Linear :
return GL_LINEAR ;
}
return GL_NEAREST ;
}
2024-05-01 20:36:10 +02:00
GLuint createTextureFromRGBA8Array ( const ImU8 * buffer , int width , int height , Texture : : Filter filter ) {
GLuint texture ;
// Generate texture
glGenTextures ( 1 , & texture ) ;
glBindTexture ( GL_TEXTURE_2D , texture ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , getGLFilter ( filter ) ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , getGLFilter ( filter ) ) ;
# if defined(GL_UNPACK_ROW_LENGTH)
glPixelStorei ( GL_UNPACK_ROW_LENGTH , 0 ) ;
# endif
// Allocate storage for the texture
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA8 , width , height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , buffer ) ;
return texture ;
}
GLuint createMultisampleTextureFromRGBA8Array ( const ImU8 * buffer , int width , int height , Texture : : Filter filter ) {
// Create a regular texture from the RGBA8 array
GLuint texture = createTextureFromRGBA8Array ( buffer , width , height , filter ) ;
2024-05-08 22:09:47 +02:00
if ( filter = = Texture : : Filter : : Nearest ) {
2024-05-01 20:36:10 +02:00
return texture ;
2024-05-08 22:09:47 +02:00
}
if ( ! isOpenGLVersionAtLeast ( 3 , 2 ) ) {
return texture ;
}
2024-05-01 20:36:10 +02:00
2024-05-03 19:27:12 +02:00
if ( ! isOpenGLExtensionSupported ( " GL_ARB_texture_multisample " ) ) {
return texture ;
}
# if defined(GL_TEXTURE_2D_MULTISAMPLE)
2024-05-03 14:02:43 +02:00
constexpr static auto SampleCount = 8 ;
2024-05-02 09:40:39 +02:00
2024-05-03 14:02:43 +02:00
// Generate renderbuffer
GLuint renderbuffer ;
glGenRenderbuffers ( 1 , & renderbuffer ) ;
glBindRenderbuffer ( GL_RENDERBUFFER , renderbuffer ) ;
glRenderbufferStorageMultisample ( GL_RENDERBUFFER , SampleCount , GL_DEPTH24_STENCIL8 , width , height ) ;
2024-05-01 20:36:10 +02:00
2024-05-03 14:02:43 +02:00
// Generate framebuffer
GLuint framebuffer ;
glGenFramebuffers ( 1 , & framebuffer ) ;
glBindFramebuffer ( GL_FRAMEBUFFER , framebuffer ) ;
2024-05-01 20:36:10 +02:00
2024-05-03 14:02:43 +02:00
// Attach texture to color attachment 0
2024-05-03 19:27:12 +02:00
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D_MULTISAMPLE , texture , 0 ) ;
2024-05-01 20:36:10 +02:00
2024-05-03 14:02:43 +02:00
// Attach renderbuffer to depth-stencil attachment
glFramebufferRenderbuffer ( GL_FRAMEBUFFER , GL_DEPTH_STENCIL_ATTACHMENT , GL_RENDERBUFFER , renderbuffer ) ;
2024-05-01 20:36:10 +02:00
2024-05-03 14:02:43 +02:00
// Check framebuffer status
if ( glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ! = GL_FRAMEBUFFER_COMPLETE ) {
2024-05-03 21:41:02 +02:00
hex : : log : : error ( " Driver claims to support texture multisampling but it's not working " ) ;
2024-05-03 19:27:12 +02:00
return texture ;
2024-05-03 14:02:43 +02:00
}
2024-05-01 20:36:10 +02:00
2024-05-03 14:02:43 +02:00
// Unbind framebuffer
glBindFramebuffer ( GL_FRAMEBUFFER , 0 ) ;
2024-05-03 19:27:12 +02:00
2024-05-03 14:02:43 +02:00
# endif
2024-05-01 20:36:10 +02:00
return texture ;
}
2023-12-09 22:00:35 +01:00
}
2023-11-16 22:24:06 +01:00
2024-05-01 20:36:10 +02:00
Texture Texture : : fromImage ( const ImU8 * buffer , int size , Filter filter ) {
2023-12-11 11:42:33 +01:00
if ( size = = 0 )
2024-05-01 20:36:10 +02:00
return { } ;
2023-12-11 11:42:33 +01:00
2024-01-08 09:39:01 +01:00
unsigned char * imageData = nullptr ;
2024-05-01 20:36:10 +02:00
Texture result ;
imageData = stbi_load_from_memory ( buffer , size , & result . m_width , & result . m_height , nullptr , 4 ) ;
if ( imageData = = nullptr )
return { } ;
2024-01-08 09:39:01 +01:00
2024-05-01 20:36:10 +02:00
GLuint texture = createMultisampleTextureFromRGBA8Array ( imageData , result . m_width , result . m_height , filter ) ;
STBI_FREE ( imageData ) ;
result . m_textureId = reinterpret_cast < ImTextureID > ( static_cast < intptr_t > ( texture ) ) ;
return result ;
}
Texture Texture : : fromImage ( std : : span < const std : : byte > buffer , Filter filter ) {
return Texture : : fromImage ( reinterpret_cast < const ImU8 * > ( buffer . data ( ) ) , buffer . size ( ) , filter ) ;
}
2022-10-13 15:13:53 +02:00
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
Texture Texture : : fromImage ( const std : : fs : : path & path , Filter filter ) {
return Texture : : fromImage ( wolv : : util : : toUTF8String ( path ) . c_str ( ) , filter ) ;
}
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
Texture Texture : : fromImage ( const char * path , Filter filter ) {
Texture result ;
unsigned char * imageData = stbi_load ( path , & result . m_width , & result . m_height , nullptr , 4 ) ;
if ( imageData = = nullptr )
return { } ;
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
GLuint texture = createMultisampleTextureFromRGBA8Array ( imageData , result . m_width , result . m_height , filter ) ;
2022-09-18 20:38:45 +02:00
2024-02-24 23:23:53 +01:00
STBI_FREE ( imageData ) ;
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
result . m_textureId = reinterpret_cast < ImTextureID > ( static_cast < intptr_t > ( texture ) ) ;
return result ;
2022-09-18 20:38:45 +02:00
}
2024-05-01 20:36:10 +02:00
Texture Texture : : fromGLTexture ( unsigned int glTexture , int width , int height ) {
Texture texture ;
texture . m_textureId = reinterpret_cast < ImTextureID > ( static_cast < intptr_t > ( glTexture ) ) ;
texture . m_width = width ;
texture . m_height = height ;
2023-08-26 12:54:52 +02:00
2024-05-01 20:36:10 +02:00
return texture ;
}
2023-12-05 10:49:51 +01:00
2024-05-01 20:36:10 +02:00
Texture Texture : : fromBitmap ( std : : span < const std : : byte > buffer , int width , int height , Filter filter ) {
return Texture : : fromBitmap ( reinterpret_cast < const ImU8 * > ( buffer . data ( ) ) , buffer . size ( ) , width , height , filter ) ;
}
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
Texture Texture : : fromBitmap ( const ImU8 * buffer , int size , int width , int height , Filter filter ) {
if ( width * height * 4 > size )
return { } ;
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
GLuint texture = createMultisampleTextureFromRGBA8Array ( buffer , width , height , filter ) ;
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
Texture result ;
result . m_width = width ;
result . m_height = height ;
result . m_textureId = reinterpret_cast < ImTextureID > ( static_cast < intptr_t > ( texture ) ) ;
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
return result ;
}
Texture Texture : : fromSVG ( const char * path , int width , int height , Filter filter ) {
auto document = lunasvg : : Document : : loadFromFile ( path ) ;
auto bitmap = document - > renderToBitmap ( width , height ) ;
auto texture = createMultisampleTextureFromRGBA8Array ( bitmap . data ( ) , bitmap . width ( ) , bitmap . height ( ) , filter ) ;
2022-09-18 20:38:45 +02:00
2024-05-01 20:36:10 +02:00
Texture result ;
result . m_width = bitmap . width ( ) ;
result . m_height = bitmap . height ( ) ;
result . m_textureId = reinterpret_cast < ImTextureID > ( static_cast < intptr_t > ( texture ) ) ;
return result ;
}
Texture Texture : : fromSVG ( const std : : fs : : path & path , int width , int height , Filter filter ) {
return Texture : : fromSVG ( wolv : : util : : toUTF8String ( path ) . c_str ( ) , width , height , filter ) ;
2022-09-18 20:38:45 +02:00
}
2024-05-01 20:36:10 +02:00
Texture Texture : : fromSVG ( std : : span < const std : : byte > buffer , int width , int height , Filter filter ) {
auto document = lunasvg : : Document : : loadFromData ( reinterpret_cast < const char * > ( buffer . data ( ) ) , buffer . size ( ) ) ;
auto bitmap = document - > renderToBitmap ( width , height ) ;
bitmap . convertToRGBA ( ) ;
auto texture = createMultisampleTextureFromRGBA8Array ( bitmap . data ( ) , bitmap . width ( ) , bitmap . height ( ) , filter ) ;
Texture result ;
result . m_width = bitmap . width ( ) ;
result . m_height = bitmap . height ( ) ;
result . m_textureId = reinterpret_cast < ImTextureID > ( static_cast < intptr_t > ( texture ) ) ;
2023-01-20 21:16:28 +01:00
2024-05-01 20:36:10 +02:00
return result ;
2023-01-20 21:16:28 +01:00
}
2022-09-18 20:38:45 +02:00
Texture : : Texture ( Texture & & other ) noexcept {
2024-02-24 18:07:10 +01:00
if ( m_textureId ! = nullptr )
glDeleteTextures ( 1 , reinterpret_cast < GLuint * > ( & m_textureId ) ) ;
2023-12-19 13:10:25 +01:00
m_textureId = other . m_textureId ;
m_width = other . m_width ;
m_height = other . m_height ;
2022-09-18 20:38:45 +02:00
other . m_textureId = nullptr ;
}
2022-10-02 17:30:26 +02:00
Texture & Texture : : operator = ( Texture & & other ) noexcept {
2024-02-24 18:07:10 +01:00
if ( m_textureId ! = nullptr )
glDeleteTextures ( 1 , reinterpret_cast < GLuint * > ( & m_textureId ) ) ;
2023-12-19 13:10:25 +01:00
m_textureId = other . m_textureId ;
m_width = other . m_width ;
m_height = other . m_height ;
2022-09-18 20:38:45 +02:00
other . m_textureId = nullptr ;
2022-10-02 17:30:26 +02:00
return * this ;
2022-09-18 20:38:45 +02:00
}
Texture : : ~ Texture ( ) {
2023-12-19 13:10:25 +01:00
if ( m_textureId = = nullptr )
2022-09-18 20:38:45 +02:00
return ;
2023-12-19 13:10:25 +01:00
auto glTextureId = static_cast < GLuint > ( reinterpret_cast < intptr_t > ( m_textureId ) ) ;
2022-09-18 20:38:45 +02:00
glDeleteTextures ( 1 , & glTextureId ) ;
}
2021-12-07 22:47:41 +01:00
int UpdateStringSizeCallback ( ImGuiInputTextCallbackData * data ) {
2022-03-01 16:12:00 +01:00
if ( data - > EventFlag = = ImGuiInputTextFlags_CallbackResize ) {
auto & string = * static_cast < std : : string * > ( data - > UserData ) ;
2022-05-30 16:36:46 +02:00
string . resize ( data - > BufTextLen ) ;
2022-03-01 16:12:00 +01:00
data - > Buf = string . data ( ) ;
}
2021-12-07 22:47:41 +01:00
return 0 ;
}
2022-01-24 20:53:17 +01:00
bool IconHyperlink ( const char * icon , const char * label , const ImVec2 & size_arg , ImGuiButtonFlags flags ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-08-04 14:01:24 +02:00
if ( window - > SkipItems )
return false ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
const ImGuiID id = window - > GetID ( label ) ;
2022-10-02 17:30:26 +02:00
ImVec2 label_size = CalcTextSize ( icon , nullptr , false ) ;
label_size . x + = CalcTextSize ( " " , nullptr , false ) . x + CalcTextSize ( label , nullptr , false ) . x ;
2021-08-04 14:01:24 +02:00
2022-02-01 22:09:44 +01:00
ImVec2 pos = window - > DC . CursorPos ;
2021-08-04 14:01:24 +02:00
ImVec2 size = CalcItemSize ( size_arg , label_size . x , label_size . y ) ;
const ImRect bb ( pos , pos + size ) ;
if ( ! ItemAdd ( bb , id ) )
return false ;
2021-08-21 00:51:50 +02:00
if ( g . LastItemData . InFlags & ImGuiItemFlags_ButtonRepeat )
2021-08-04 14:01:24 +02:00
flags | = ImGuiButtonFlags_Repeat ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , flags ) ;
// Render
const ImU32 col = hovered ? GetColorU32 ( ImGuiCol_ButtonHovered ) : GetColorU32 ( ImGuiCol_ButtonActive ) ;
PushStyleColor ( ImGuiCol_Text , ImU32 ( col ) ) ;
Text ( " %s %s " , icon , label ) ;
2024-04-29 20:06:50 +02:00
if ( hovered )
GetWindowDrawList ( ) - > AddLine ( ImVec2 ( pos . x , pos . y + size . y ) , pos + size , ImU32 ( col ) ) ;
2021-08-04 14:01:24 +02:00
PopStyleColor ( ) ;
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags ) ;
2021-08-04 14:01:24 +02:00
return pressed ;
}
2022-01-24 20:53:17 +01:00
bool Hyperlink ( const char * label , const ImVec2 & size_arg , ImGuiButtonFlags flags ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-01-27 00:00:20 +01:00
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
const ImGuiID id = window - > GetID ( label ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2021-01-27 00:00:20 +01:00
2022-02-01 22:09:44 +01:00
ImVec2 pos = window - > DC . CursorPos ;
2021-01-27 00:00:20 +01:00
ImVec2 size = CalcItemSize ( size_arg , label_size . x , label_size . y ) ;
const ImRect bb ( pos , pos + size ) ;
2023-12-27 02:14:38 +01:00
ItemAdd ( bb , id ) ;
2021-01-27 00:00:20 +01:00
2021-08-21 00:51:50 +02:00
if ( g . LastItemData . InFlags & ImGuiItemFlags_ButtonRepeat )
2021-01-27 00:00:20 +01:00
flags | = ImGuiButtonFlags_Repeat ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , flags ) ;
// Render
2021-01-27 12:04:42 +01:00
const ImU32 col = hovered ? GetColorU32 ( ImGuiCol_ButtonHovered ) : GetColorU32 ( ImGuiCol_ButtonActive ) ;
2021-01-27 00:00:20 +01:00
PushStyleColor ( ImGuiCol_Text , ImU32 ( col ) ) ;
2022-10-02 17:30:26 +02:00
TextEx ( label , nullptr , ImGuiTextFlags_NoWidthForLargeClippedText ) ; // Skip formatting
2024-04-29 20:06:50 +02:00
if ( hovered )
GetWindowDrawList ( ) - > AddLine ( ImVec2 ( pos . x , pos . y + size . y ) , pos + size , ImU32 ( col ) ) ;
2021-01-27 00:00:20 +01:00
PopStyleColor ( ) ;
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags ) ;
2021-01-27 00:00:20 +01:00
return pressed ;
}
2022-01-24 20:53:17 +01:00
bool BulletHyperlink ( const char * label , const ImVec2 & size_arg , ImGuiButtonFlags flags ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-01-27 12:04:42 +01:00
if ( window - > SkipItems )
return false ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
2022-01-24 20:53:17 +01:00
const ImGuiStyle & style = g . Style ;
2022-02-01 22:09:44 +01:00
const ImGuiID id = window - > GetID ( label ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2021-01-27 12:04:42 +01:00
2022-02-01 22:09:44 +01:00
ImVec2 pos = window - > DC . CursorPos ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( size_arg , label_size . x , label_size . y ) + ImVec2 ( g . FontSize + style . FramePadding . x * 2 , 0.0F ) ;
2021-01-27 12:04:42 +01:00
const ImRect bb ( pos , pos + size ) ;
2022-03-04 19:06:29 +01:00
ItemSize ( size , 0 ) ;
2021-01-27 12:04:42 +01:00
if ( ! ItemAdd ( bb , id ) )
return false ;
2021-08-21 00:51:50 +02:00
if ( g . LastItemData . InFlags & ImGuiItemFlags_ButtonRepeat )
2021-01-27 12:04:42 +01:00
flags | = ImGuiButtonFlags_Repeat ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , flags ) ;
// Render
const ImU32 col = hovered ? GetColorU32 ( ImGuiCol_ButtonHovered ) : GetColorU32 ( ImGuiCol_ButtonActive ) ;
PushStyleColor ( ImGuiCol_Text , ImU32 ( col ) ) ;
2024-02-24 23:34:29 +01:00
RenderBullet ( window - > DrawList , bb . Min + ImVec2 ( style . FramePadding . x , g . FontSize * 0.5F ) , col ) ;
RenderText ( bb . Min + ImVec2 ( g . FontSize * 0.5 + style . FramePadding . x , 0.0F ) , label , nullptr , false ) ;
2022-03-04 19:06:29 +01:00
GetWindowDrawList ( ) - > AddLine ( bb . Min + ImVec2 ( g . FontSize * 0.5 + style . FramePadding . x , size . y ) , pos + size - ImVec2 ( g . FontSize * 0.5 + style . FramePadding . x , 0 ) , ImU32 ( col ) ) ;
2021-01-27 12:04:42 +01:00
PopStyleColor ( ) ;
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags ) ;
2021-01-27 12:04:42 +01:00
return pressed ;
}
2022-01-24 20:53:17 +01:00
bool DescriptionButton ( const char * label , const char * description , const ImVec2 & size_arg , ImGuiButtonFlags flags ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-01-27 12:04:42 +01:00
if ( window - > SkipItems )
return false ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
2022-01-24 20:53:17 +01:00
const ImGuiStyle & style = g . Style ;
2022-02-01 22:09:44 +01:00
const ImGuiID id = window - > GetID ( label ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 text_size = CalcTextSize ( ( std : : string ( label ) + " \n " + std : : string ( description ) ) . c_str ( ) , nullptr , true ) ;
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2021-01-27 12:04:42 +01:00
ImVec2 pos = window - > DC . CursorPos ;
2022-01-24 20:53:17 +01:00
if ( ( flags & ImGuiButtonFlags_AlignTextBaseLine ) & & style . FramePadding . y < window - > DC . CurrLineTextBaseOffset ) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
2021-01-27 12:04:42 +01:00
pos . y + = window - > DC . CurrLineTextBaseOffset - style . FramePadding . y ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( size_arg , text_size . x + style . FramePadding . x * 4.0F , text_size . y + style . FramePadding . y * 4.0F ) ;
2021-01-27 12:04:42 +01:00
const ImRect bb ( pos , pos + size ) ;
ItemSize ( size , style . FramePadding . y ) ;
if ( ! ItemAdd ( bb , id ) )
return false ;
2021-08-21 00:51:50 +02:00
if ( g . LastItemData . InFlags & ImGuiItemFlags_ButtonRepeat )
2021-01-27 12:04:42 +01:00
flags | = ImGuiButtonFlags_Repeat ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , flags ) ;
2023-11-16 09:32:24 +01:00
PushStyleVar ( ImGuiStyleVar_ButtonTextAlign , ImVec2 ( 0.0 , 0.5 ) ) ;
PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 1 ) ;
2021-01-27 12:04:42 +01:00
// Render
2022-01-24 20:53:17 +01:00
const ImU32 col = GetCustomColorU32 ( ( held & & hovered ) ? ImGuiCustomCol_DescButtonActive : hovered ? ImGuiCustomCol_DescButtonHovered
: ImGuiCustomCol_DescButton ) ;
2021-01-27 12:04:42 +01:00
RenderNavHighlight ( bb , id ) ;
RenderFrame ( bb . Min , bb . Max , col , true , style . FrameRounding ) ;
PushStyleColor ( ImGuiCol_Text , GetColorU32 ( ImGuiCol_ButtonActive ) ) ;
2023-12-18 13:08:17 +01:00
RenderTextClipped ( bb . Min + style . FramePadding * 2 , bb . Max - style . FramePadding , label , nullptr , nullptr ) ;
2021-01-27 12:04:42 +01:00
PopStyleColor ( ) ;
PushStyleColor ( ImGuiCol_Text , GetColorU32 ( ImGuiCol_Text ) ) ;
2023-12-18 13:08:17 +01:00
auto clipBb = bb ;
clipBb . Max . x - = style . FramePadding . x ;
RenderTextClipped ( bb . Min + style . FramePadding * 2 + ImVec2 ( style . FramePadding . x * 2 , label_size . y ) , bb . Max - style . FramePadding , description , nullptr , & text_size , style . ButtonTextAlign , & clipBb ) ;
2021-01-27 12:04:42 +01:00
PopStyleColor ( ) ;
2023-11-16 09:32:24 +01:00
PopStyleVar ( 2 ) ;
2021-01-27 12:04:42 +01:00
// Automatically close popups
2022-01-24 20:53:17 +01:00
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
2021-01-27 12:04:42 +01:00
// CloseCurrentPopup();
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags ) ;
2021-01-27 12:04:42 +01:00
return pressed ;
}
2023-11-16 13:23:28 +01:00
bool DescriptionButtonProgress ( const char * label , const char * description , float fraction , const ImVec2 & size_arg , ImGuiButtonFlags flags ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return false ;
ImGuiContext & g = * GImGui ;
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( label ) ;
const ImVec2 text_size = CalcTextSize ( ( std : : string ( label ) + " \n " + std : : string ( description ) ) . c_str ( ) , nullptr , true ) ;
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
ImVec2 pos = window - > DC . CursorPos ;
if ( ( flags & ImGuiButtonFlags_AlignTextBaseLine ) & & style . FramePadding . y < window - > DC . CurrLineTextBaseOffset ) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
pos . y + = window - > DC . CurrLineTextBaseOffset - style . FramePadding . y ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( size_arg , text_size . x + style . FramePadding . x * 4.0F , text_size . y + style . FramePadding . y * 6.0F ) ;
2023-11-16 13:23:28 +01:00
const ImRect bb ( pos , pos + size ) ;
ItemSize ( size , style . FramePadding . y ) ;
if ( ! ItemAdd ( bb , id ) )
return false ;
if ( g . LastItemData . InFlags & ImGuiItemFlags_ButtonRepeat )
flags | = ImGuiButtonFlags_Repeat ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , flags ) ;
PushStyleVar ( ImGuiStyleVar_ButtonTextAlign , ImVec2 ( 0.0 , 0.5 ) ) ;
PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 1 ) ;
// Render
const ImU32 col = GetCustomColorU32 ( ( held & & hovered ) ? ImGuiCustomCol_DescButtonActive : hovered ? ImGuiCustomCol_DescButtonHovered
: ImGuiCustomCol_DescButton ) ;
RenderNavHighlight ( bb , id ) ;
RenderFrame ( bb . Min , bb . Max , col , false , style . FrameRounding ) ;
PushStyleColor ( ImGuiCol_Text , GetColorU32 ( ImGuiCol_ButtonActive ) ) ;
2023-12-18 13:08:17 +01:00
RenderTextClipped ( bb . Min + style . FramePadding * 2 , bb . Max - style . FramePadding , label , nullptr , nullptr ) ;
2023-11-16 13:23:28 +01:00
PopStyleColor ( ) ;
PushStyleColor ( ImGuiCol_Text , GetColorU32 ( ImGuiCol_Text ) ) ;
2023-12-18 13:08:17 +01:00
auto clipBb = bb ;
clipBb . Max . x - = style . FramePadding . x ;
RenderTextClipped ( bb . Min + style . FramePadding * 2 + ImVec2 ( style . FramePadding . x * 2 , label_size . y ) , bb . Max - style . FramePadding , description , nullptr , & text_size , style . ButtonTextAlign , & clipBb ) ;
2023-11-16 13:23:28 +01:00
PopStyleColor ( ) ;
RenderFrame ( ImVec2 ( bb . Min . x , bb . Max . y - 5 * hex : : ImHexApi : : System : : getGlobalScale ( ) ) , bb . Max , GetColorU32 ( ImGuiCol_ScrollbarBg ) , false , style . FrameRounding ) ;
RenderFrame ( ImVec2 ( bb . Min . x , bb . Max . y - 5 * hex : : ImHexApi : : System : : getGlobalScale ( ) ) , ImVec2 ( bb . Min . x + fraction * bb . GetSize ( ) . x , bb . Max . y ) , GetColorU32 ( ImGuiCol_Button ) , false , style . FrameRounding ) ;
RenderFrame ( bb . Min , bb . Max , 0x00 , true , style . FrameRounding ) ;
PopStyleVar ( 2 ) ;
// Automatically close popups
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
// CloseCurrentPopup();
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags ) ;
2023-11-16 13:23:28 +01:00
return pressed ;
}
2023-05-11 12:00:45 +02:00
void HelpHover ( const char * text ) {
2023-11-16 22:24:06 +01:00
const auto iconColor = GetStyleColorVec4 ( ImGuiCol_ButtonActive ) ;
PushStyleColor ( ImGuiCol_Button , ImVec4 ( 0 , 0 , 0 , 0 ) ) ;
PushStyleColor ( ImGuiCol_ButtonHovered , ImVec4 ( 0 , 0 , 0 , 0 ) ) ;
PushStyleColor ( ImGuiCol_ButtonActive , ImVec4 ( 0 , 0 , 0 , 0 ) ) ;
PushStyleVar ( ImGuiStyleVar_FramePadding , ImVec2 ( 0 , GetStyle ( ) . FramePadding . y ) ) ;
PushStyleColor ( ImGuiCol_Text , iconColor ) ;
2024-01-28 22:14:59 +01:00
Button ( " (?) " ) ;
2023-11-16 22:24:06 +01:00
PopStyleColor ( ) ;
if ( IsItemHovered ( ImGuiHoveredFlags_AllowWhenDisabled ) ) {
SetNextWindowSizeConstraints ( ImVec2 ( GetTextLineHeight ( ) * 25 , 0 ) , ImVec2 ( GetTextLineHeight ( ) * 25 , FLT_MAX ) ) ;
BeginTooltip ( ) ;
TextFormattedWrapped ( " {} " , text ) ;
EndTooltip ( ) ;
2023-05-11 12:00:45 +02:00
}
2023-11-16 22:24:06 +01:00
PopStyleVar ( ) ;
PopStyleColor ( 3 ) ;
2023-05-11 12:00:45 +02:00
}
2022-01-24 20:53:17 +01:00
void UnderlinedText ( const char * label , ImColor color , const ImVec2 & size_arg ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-01-27 12:04:42 +01:00
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2021-01-27 12:04:42 +01:00
2022-02-01 22:09:44 +01:00
ImVec2 pos = window - > DC . CursorPos ;
2021-01-27 12:04:42 +01:00
ImVec2 size = CalcItemSize ( size_arg , label_size . x , label_size . y ) ;
PushStyleColor ( ImGuiCol_Text , ImU32 ( color ) ) ;
2022-10-02 17:30:26 +02:00
TextEx ( label , nullptr , ImGuiTextFlags_NoWidthForLargeClippedText ) ; // Skip formatting
2021-01-27 14:26:24 +01:00
GetWindowDrawList ( ) - > AddLine ( ImVec2 ( pos . x , pos . y + size . y ) , pos + size , ImU32 ( color ) ) ;
2021-01-27 12:04:42 +01:00
PopStyleColor ( ) ;
}
2022-01-24 20:53:17 +01:00
void TextSpinner ( const char * label ) {
2023-11-16 22:24:06 +01:00
Text ( " [%c] %s " , " |/- \\ " [ ImU32 ( GetTime ( ) * 20 ) % 4 ] , label ) ;
2021-02-22 13:06:53 +01:00
}
2021-03-02 13:49:45 +01:00
void Header ( const char * label , bool firstEntry ) {
if ( ! firstEntry )
2023-11-16 22:24:06 +01:00
NewLine ( ) ;
SeparatorText ( label ) ;
2021-03-02 13:49:45 +01:00
}
2021-08-28 16:02:53 +02:00
void HeaderColored ( const char * label , ImColor color , bool firstEntry ) {
if ( ! firstEntry )
2023-11-16 22:24:06 +01:00
NewLine ( ) ;
TextFormattedColored ( color , " {} " , label ) ;
Separator ( ) ;
2021-08-28 16:02:53 +02:00
}
2023-12-05 10:49:51 +01:00
bool InfoTooltip ( const char * text , bool isSeparator ) {
2021-08-21 00:51:50 +02:00
static double lastMoveTime ;
static ImGuiID lastHoveredID ;
2023-11-16 22:24:06 +01:00
double currTime = GetTime ( ) ;
ImGuiID hoveredID = GetHoveredID ( ) ;
2021-08-21 00:51:50 +02:00
2023-06-05 09:07:58 +02:00
bool result = false ;
2021-08-21 00:51:50 +02:00
if ( IsItemHovered ( ) & & ( currTime - lastMoveTime ) > = 0.5 & & hoveredID = = lastHoveredID ) {
2023-06-05 09:07:58 +02:00
if ( ! std : : string_view ( text ) . empty ( ) ) {
BeginTooltip ( ) ;
2023-12-05 10:49:51 +01:00
if ( isSeparator )
SeparatorText ( text ) ;
else
TextUnformatted ( text ) ;
2023-06-05 09:07:58 +02:00
EndTooltip ( ) ;
}
result = true ;
2021-08-18 23:12:27 +02:00
}
2021-08-21 00:51:50 +02:00
if ( hoveredID ! = lastHoveredID ) {
lastMoveTime = currTime ;
}
lastHoveredID = hoveredID ;
2023-06-05 09:07:58 +02:00
return result ;
2021-08-18 23:12:27 +02:00
}
2021-02-25 00:17:41 +01:00
ImU32 GetCustomColorU32 ( ImGuiCustomCol idx , float alpha_mul ) {
2022-01-24 20:53:17 +01:00
auto & customData = * static_cast < ImHexCustomData * > ( GImGui - > IO . UserData ) ;
2022-02-01 22:09:44 +01:00
ImVec4 c = customData . Colors [ idx ] ;
2021-02-25 00:17:41 +01:00
c . w * = GImGui - > Style . Alpha * alpha_mul ;
return ColorConvertFloat4ToU32 ( c ) ;
}
2021-08-21 00:51:50 +02:00
ImVec4 GetCustomColorVec4 ( ImGuiCustomCol idx , float alpha_mul ) {
2022-01-24 20:53:17 +01:00
auto & customData = * static_cast < ImHexCustomData * > ( GImGui - > IO . UserData ) ;
2022-02-01 22:09:44 +01:00
ImVec4 c = customData . Colors [ idx ] ;
2021-08-21 00:51:50 +02:00
c . w * = GImGui - > Style . Alpha * alpha_mul ;
return c ;
}
2023-05-22 12:00:35 +02:00
float GetCustomStyleFloat ( ImGuiCustomStyle idx ) {
auto & customData = * static_cast < ImHexCustomData * > ( GImGui - > IO . UserData ) ;
switch ( idx ) {
case ImGuiCustomStyle_WindowBlur :
return customData . styles . WindowBlur ;
default :
2024-02-24 23:34:29 +01:00
return 0.0F ;
2023-05-22 12:00:35 +02:00
}
}
ImVec2 GetCustomStyleVec2 ( ImGuiCustomStyle idx ) {
switch ( idx ) {
default :
return { } ;
}
}
2021-02-25 00:17:41 +01:00
void StyleCustomColorsDark ( ) {
2022-01-24 20:53:17 +01:00
auto & colors = static_cast < ImHexCustomData * > ( GImGui - > IO . UserData ) - > Colors ;
2021-02-25 00:17:41 +01:00
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_DescButton ] = ImColor ( 20 , 20 , 20 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_DescButtonHovered ] = ImColor ( 40 , 40 , 40 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_DescButtonActive ] = ImColor ( 60 , 60 , 60 ) ;
2021-08-21 00:51:50 +02:00
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarGray ] = ImColor ( 230 , 230 , 230 ) ;
colors [ ImGuiCustomCol_ToolbarRed ] = ImColor ( 231 , 76 , 60 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_ToolbarYellow ] = ImColor ( 241 , 196 , 15 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarGreen ] = ImColor ( 56 , 139 , 66 ) ;
colors [ ImGuiCustomCol_ToolbarBlue ] = ImColor ( 6 , 83 , 155 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_ToolbarPurple ] = ImColor ( 103 , 42 , 120 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarBrown ] = ImColor ( 219 , 179 , 119 ) ;
2021-08-28 16:02:53 +02:00
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_Highlight ] = ImColor ( 77 , 198 , 155 ) ;
2023-05-19 21:18:38 +02:00
colors [ ImGuiCustomCol_IEEEToolSign ] = ImColor ( 93 , 93 , 127 ) ;
colors [ ImGuiCustomCol_IEEEToolExp ] = ImColor ( 93 , 127 , 93 ) ;
colors [ ImGuiCustomCol_IEEEToolMantissa ] = ImColor ( 127 , 93 , 93 ) ;
2021-02-25 00:17:41 +01:00
}
void StyleCustomColorsLight ( ) {
2022-01-24 20:53:17 +01:00
auto & colors = static_cast < ImHexCustomData * > ( GImGui - > IO . UserData ) - > Colors ;
2021-02-25 00:17:41 +01:00
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_DescButton ] = ImColor ( 230 , 230 , 230 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_DescButtonHovered ] = ImColor ( 210 , 210 , 210 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_DescButtonActive ] = ImColor ( 190 , 190 , 190 ) ;
2021-08-21 00:51:50 +02:00
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarGray ] = ImColor ( 25 , 25 , 25 ) ;
colors [ ImGuiCustomCol_ToolbarRed ] = ImColor ( 231 , 76 , 60 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_ToolbarYellow ] = ImColor ( 241 , 196 , 15 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarGreen ] = ImColor ( 56 , 139 , 66 ) ;
colors [ ImGuiCustomCol_ToolbarBlue ] = ImColor ( 6 , 83 , 155 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_ToolbarPurple ] = ImColor ( 103 , 42 , 120 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarBrown ] = ImColor ( 219 , 179 , 119 ) ;
2021-08-28 16:02:53 +02:00
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_Highlight ] = ImColor ( 41 , 151 , 112 ) ;
2023-05-19 21:18:38 +02:00
colors [ ImGuiCustomCol_IEEEToolSign ] = ImColor ( 187 , 187 , 255 ) ;
colors [ ImGuiCustomCol_IEEEToolExp ] = ImColor ( 187 , 255 , 187 ) ;
colors [ ImGuiCustomCol_IEEEToolMantissa ] = ImColor ( 255 , 187 , 187 ) ;
2021-02-25 00:17:41 +01:00
}
void StyleCustomColorsClassic ( ) {
2022-01-24 20:53:17 +01:00
auto & colors = static_cast < ImHexCustomData * > ( GImGui - > IO . UserData ) - > Colors ;
2021-02-25 00:17:41 +01:00
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_DescButton ] = ImColor ( 40 , 40 , 80 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_DescButtonHovered ] = ImColor ( 60 , 60 , 100 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_DescButtonActive ] = ImColor ( 80 , 80 , 120 ) ;
2021-08-21 00:51:50 +02:00
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarGray ] = ImColor ( 230 , 230 , 230 ) ;
colors [ ImGuiCustomCol_ToolbarRed ] = ImColor ( 231 , 76 , 60 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_ToolbarYellow ] = ImColor ( 241 , 196 , 15 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarGreen ] = ImColor ( 56 , 139 , 66 ) ;
colors [ ImGuiCustomCol_ToolbarBlue ] = ImColor ( 6 , 83 , 155 ) ;
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_ToolbarPurple ] = ImColor ( 103 , 42 , 120 ) ;
2022-02-01 22:09:44 +01:00
colors [ ImGuiCustomCol_ToolbarBrown ] = ImColor ( 219 , 179 , 119 ) ;
2021-08-28 16:02:53 +02:00
2022-01-24 20:53:17 +01:00
colors [ ImGuiCustomCol_Highlight ] = ImColor ( 77 , 198 , 155 ) ;
2023-05-19 21:18:38 +02:00
colors [ ImGuiCustomCol_IEEEToolSign ] = ImColor ( 93 , 93 , 127 ) ;
colors [ ImGuiCustomCol_IEEEToolExp ] = ImColor ( 93 , 127 , 93 ) ;
colors [ ImGuiCustomCol_IEEEToolMantissa ] = ImColor ( 127 , 93 , 93 ) ;
2021-02-25 00:17:41 +01:00
}
2021-09-28 12:34:55 +02:00
void OpenPopupInWindow ( const char * window_name , const char * popup_name ) {
2023-11-16 22:24:06 +01:00
if ( Begin ( window_name ) ) {
OpenPopup ( popup_name ) ;
2021-09-28 12:34:55 +02:00
}
2023-11-16 22:24:06 +01:00
End ( ) ;
2021-09-28 12:34:55 +02:00
}
2021-08-21 00:51:50 +02:00
2022-01-24 20:53:17 +01:00
bool TitleBarButton ( const char * label , ImVec2 size_arg ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-08-21 00:51:50 +02:00
if ( window - > SkipItems )
return false ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
2022-01-24 20:53:17 +01:00
const ImGuiStyle & style = g . Style ;
2022-02-01 22:09:44 +01:00
const ImGuiID id = window - > GetID ( label ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2021-08-21 00:51:50 +02:00
ImVec2 pos = window - > DC . CursorPos ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( size_arg , label_size . x + style . FramePadding . x * 2.0F , label_size . y + style . FramePadding . y * 2.0F ) ;
2021-08-21 00:51:50 +02:00
const ImRect bb ( pos , pos + size ) ;
ItemSize ( size , style . FramePadding . y ) ;
if ( ! ItemAdd ( bb , id ) )
return false ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held ) ;
// Render
2022-01-24 20:53:17 +01:00
const ImU32 col = GetColorU32 ( ( held & & hovered ) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered
: ImGuiCol_Button ) ;
2021-08-21 00:51:50 +02:00
RenderNavHighlight ( bb , id ) ;
RenderFrame ( bb . Min , bb . Max , col , true , style . FrameRounding ) ;
2023-06-09 00:30:12 +02:00
RenderTextClipped ( bb . Min + style . FramePadding , bb . Max - style . FramePadding , label , nullptr , & label_size , style . ButtonTextAlign , & bb ) ;
2021-08-21 00:51:50 +02:00
// Automatically close popups
2022-01-24 20:53:17 +01:00
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
2021-08-21 00:51:50 +02:00
// CloseCurrentPopup();
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags ) ;
2021-08-21 00:51:50 +02:00
return pressed ;
}
2022-01-24 20:53:17 +01:00
bool ToolBarButton ( const char * symbol , ImVec4 color ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-08-21 00:51:50 +02:00
if ( window - > SkipItems )
return false ;
color . w = 1.0F ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
2022-01-24 20:53:17 +01:00
const ImGuiStyle & style = g . Style ;
2022-02-01 22:09:44 +01:00
const ImGuiID id = window - > GetID ( symbol ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( symbol , nullptr , true ) ;
2021-08-21 00:51:50 +02:00
ImVec2 pos = window - > DC . CursorPos ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( ImVec2 ( 1 , 1 ) * GetCurrentWindow ( ) - > MenuBarHeight ( ) , label_size . x + style . FramePadding . x * 2.0F , label_size . y + style . FramePadding . y * 2.0F ) ;
2021-08-21 00:51:50 +02:00
const ImRect bb ( pos , pos + size ) ;
ItemSize ( size , style . FramePadding . y ) ;
if ( ! ItemAdd ( bb , id ) )
return false ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held ) ;
PushStyleColor ( ImGuiCol_Text , color ) ;
// Render
2022-01-24 20:53:17 +01:00
const ImU32 col = GetColorU32 ( ( held & & hovered ) ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered
: ImGuiCol_MenuBarBg ) ;
2021-08-21 00:51:50 +02:00
RenderNavHighlight ( bb , id ) ;
RenderFrame ( bb . Min , bb . Max , col , false , style . FrameRounding ) ;
2023-06-09 00:30:12 +02:00
RenderTextClipped ( bb . Min + style . FramePadding , bb . Max - style . FramePadding , symbol , nullptr , & label_size , style . ButtonTextAlign , & bb ) ;
2021-08-21 00:51:50 +02:00
PopStyleColor ( ) ;
// Automatically close popups
2022-01-24 20:53:17 +01:00
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
2021-08-21 00:51:50 +02:00
// CloseCurrentPopup();
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , symbol , g . LastItemData . StatusFlags ) ;
2021-08-21 00:51:50 +02:00
return pressed ;
}
2022-01-24 20:53:17 +01:00
bool IconButton ( const char * symbol , ImVec4 color , ImVec2 size_arg ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-10-07 11:34:46 +02:00
if ( window - > SkipItems )
return false ;
color . w = 1.0F ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
2022-01-24 20:53:17 +01:00
const ImGuiStyle & style = g . Style ;
2022-02-01 22:09:44 +01:00
const ImGuiID id = window - > GetID ( symbol ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( symbol , nullptr , true ) ;
2021-10-07 11:34:46 +02:00
ImVec2 pos = window - > DC . CursorPos ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( size_arg , label_size . x + style . FramePadding . x * 2.0F , label_size . y + style . FramePadding . y * 2.0F ) ;
2021-10-07 11:34:46 +02:00
const ImRect bb ( pos , pos + size ) ;
ItemSize ( size , style . FramePadding . y ) ;
if ( ! ItemAdd ( bb , id ) )
return false ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held ) ;
PushStyleColor ( ImGuiCol_Text , color ) ;
// Render
2022-01-24 20:53:17 +01:00
const ImU32 col = GetColorU32 ( ( held & & hovered ) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered
: ImGuiCol_Button ) ;
2021-10-07 11:34:46 +02:00
RenderNavHighlight ( bb , id ) ;
2023-05-11 12:00:45 +02:00
RenderFrame ( bb . Min , bb . Max , col , true , style . FrameRounding ) ;
2023-12-14 13:49:46 +01:00
RenderTextClipped ( bb . Min + style . FramePadding * ImVec2 ( 1.3 , 1 ) , bb . Max - style . FramePadding , symbol , nullptr , & label_size , style . ButtonTextAlign , & bb ) ;
2021-10-07 11:34:46 +02:00
PopStyleColor ( ) ;
// Automatically close popups
2022-01-24 20:53:17 +01:00
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
2021-10-07 11:34:46 +02:00
// CloseCurrentPopup();
2023-12-13 11:24:25 +01:00
IMGUI_TEST_ENGINE_ITEM_INFO ( id , symbol , g . LastItemData . StatusFlags ) ;
2021-10-07 11:34:46 +02:00
return pressed ;
}
2023-01-18 14:30:44 +01:00
bool InputIntegerPrefix ( const char * label , const char * prefix , void * value , ImGuiDataType type , const char * format , ImGuiInputTextFlags flags ) {
2023-11-16 22:24:06 +01:00
auto window = GetCurrentWindow ( ) ;
2022-02-08 21:10:48 +01:00
const ImGuiID id = window - > GetID ( label ) ;
const ImGuiStyle & style = GImGui - > Style ;
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2024-02-24 23:34:29 +01:00
const ImVec2 frame_size = CalcItemSize ( ImVec2 ( 0 , 0 ) , CalcTextSize ( prefix ) . x , label_size . y + style . FramePadding . y * 2.0F ) ;
2022-02-08 21:10:48 +01:00
const ImRect frame_bb ( window - > DC . CursorPos , window - > DC . CursorPos + frame_size ) ;
2023-11-16 22:24:06 +01:00
SetCursorPosX ( GetCursorPosX ( ) + frame_size . x ) ;
2022-02-08 21:51:09 +01:00
char buf [ 64 ] ;
2023-01-18 14:30:44 +01:00
DataTypeFormatString ( buf , IM_ARRAYSIZE ( buf ) , type , value , format ) ;
2022-02-08 21:51:09 +01:00
bool value_changed = false ;
2024-02-24 23:34:29 +01:00
if ( InputTextEx ( label , nullptr , buf , IM_ARRAYSIZE ( buf ) , ImVec2 ( CalcItemWidth ( ) - frame_size . x , label_size . y + style . FramePadding . y * 2.0F ) , flags ) )
2023-01-18 14:30:44 +01:00
value_changed = DataTypeApplyFromText ( buf , type , value , format ) ;
2022-02-08 21:51:09 +01:00
if ( value_changed )
MarkItemEdited ( GImGui - > LastItemData . ID ) ;
2022-02-08 21:10:48 +01:00
RenderNavHighlight ( frame_bb , id ) ;
RenderFrame ( frame_bb . Min , frame_bb . Max , GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
2022-02-08 22:19:54 +01:00
2023-11-16 22:24:06 +01:00
PushStyleVar ( ImGuiStyleVar_Alpha , 0.6F ) ;
2022-02-08 21:10:48 +01:00
RenderText ( ImVec2 ( frame_bb . Min . x + style . FramePadding . x , frame_bb . Min . y + style . FramePadding . y ) , prefix ) ;
2023-11-16 22:24:06 +01:00
PopStyleVar ( ) ;
2022-02-08 21:10:48 +01:00
2022-02-08 21:51:09 +01:00
return value_changed ;
2022-02-08 21:10:48 +01:00
}
2022-05-30 16:36:46 +02:00
bool InputHexadecimal ( const char * label , u32 * value , ImGuiInputTextFlags flags ) {
2023-01-18 14:30:44 +01:00
return InputIntegerPrefix ( label , " 0x " , value , ImGuiDataType_U32 , " %lX " , flags | ImGuiInputTextFlags_CharsHexadecimal ) ;
2022-05-30 16:36:46 +02:00
}
2022-02-08 22:25:25 +01:00
bool InputHexadecimal ( const char * label , u64 * value , ImGuiInputTextFlags flags ) {
2023-01-18 14:30:44 +01:00
return InputIntegerPrefix ( label , " 0x " , value , ImGuiDataType_U64 , " %llX " , flags | ImGuiInputTextFlags_CharsHexadecimal ) ;
2022-02-08 21:10:48 +01:00
}
2021-12-16 23:48:52 +01:00
void SmallProgressBar ( float fraction , float yOffset ) {
2022-01-24 20:53:17 +01:00
ImGuiWindow * window = GetCurrentWindow ( ) ;
2021-12-16 23:48:52 +01:00
if ( window - > SkipItems )
return ;
2022-02-01 22:09:44 +01:00
ImGuiContext & g = * GImGui ;
2022-01-24 20:53:17 +01:00
const ImGuiStyle & style = g . Style ;
2021-12-16 23:48:52 +01:00
2022-02-01 22:09:44 +01:00
ImVec2 pos = window - > DC . CursorPos + ImVec2 ( 0 , yOffset ) ;
2024-02-24 23:34:29 +01:00
ImVec2 size = CalcItemSize ( ImVec2 ( 100 , 5 ) * hex : : ImHexApi : : System : : getGlobalScale ( ) , 100 , g . FontSize + style . FramePadding . y * 2.0F ) ;
2021-12-16 23:48:52 +01:00
ImRect bb ( pos , pos + size ) ;
ItemSize ( size , 0 ) ;
if ( ! ItemAdd ( bb , 0 ) )
return ;
// Render
2023-12-28 22:14:45 +01:00
bool no_progress = fraction < 0 ;
2021-12-16 23:48:52 +01:00
fraction = ImSaturate ( fraction ) ;
RenderFrame ( bb . Min , bb . Max , GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
bb . Expand ( ImVec2 ( - style . FrameBorderSize , - style . FrameBorderSize ) ) ;
2023-12-28 22:14:45 +01:00
if ( no_progress ) {
auto time = ( fmod ( ImGui : : GetTime ( ) * 2 , 1.8 ) - 0.4 ) ;
RenderRectFilledRangeH ( window - > DrawList , bb , GetColorU32 ( ImGuiCol_PlotHistogram ) , ImSaturate ( time ) , ImSaturate ( time + 0.2 ) , style . FrameRounding ) ;
} else {
2024-02-24 23:34:29 +01:00
RenderRectFilledRangeH ( window - > DrawList , bb , GetColorU32 ( ImGuiCol_PlotHistogram ) , 0.0F , fraction , style . FrameRounding ) ;
2023-12-28 22:14:45 +01:00
}
2021-12-16 23:48:52 +01:00
}
2023-12-02 23:46:20 +01:00
void TextUnformattedCentered ( const char * text ) {
auto availableSpace = ImGui : : GetContentRegionAvail ( ) ;
std : : string drawString ;
auto textEnd = text + strlen ( text ) ;
for ( auto wrapPos = text ; wrapPos ! = textEnd ; ) {
wrapPos = ImGui : : GetFont ( ) - > CalcWordWrapPositionA ( 1 , wrapPos , textEnd , availableSpace . x * 0.8F ) ;
drawString + = std : : string ( text , wrapPos ) + " \n " ;
text = wrapPos ;
}
drawString . pop_back ( ) ;
auto textSize = ImGui : : CalcTextSize ( drawString . c_str ( ) ) ;
ImPlot : : AddTextCentered ( ImGui : : GetWindowDrawList ( ) , ImGui : : GetCursorScreenPos ( ) + availableSpace / 2 - ImVec2 ( 0 , textSize . y / 2 ) , ImGui : : GetColorU32 ( ImGuiCol_Text ) , drawString . c_str ( ) ) ;
}
2023-11-16 22:24:06 +01:00
2022-09-19 11:29:51 +02:00
bool InputTextIcon ( const char * label , const char * icon , std : : string & buffer , ImGuiInputTextFlags flags ) {
2023-11-16 22:24:06 +01:00
auto window = GetCurrentWindow ( ) ;
2022-09-19 11:29:51 +02:00
const ImGuiID id = window - > GetID ( label ) ;
const ImGuiStyle & style = GImGui - > Style ;
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2024-02-24 23:34:29 +01:00
const ImVec2 icon_frame_size = CalcTextSize ( icon ) + style . FramePadding * 2.0F ;
const ImVec2 frame_size = CalcItemSize ( ImVec2 ( 0 , 0 ) , icon_frame_size . x , label_size . y + style . FramePadding . y * 2.0F ) ;
2022-09-19 11:29:51 +02:00
const ImRect frame_bb ( window - > DC . CursorPos , window - > DC . CursorPos + frame_size ) ;
2023-11-16 22:24:06 +01:00
SetCursorPosX ( GetCursorPosX ( ) + frame_size . x ) ;
2022-09-19 11:29:51 +02:00
2024-02-24 23:34:29 +01:00
bool value_changed = InputTextEx ( label , nullptr , buffer . data ( ) , buffer . size ( ) + 1 , ImVec2 ( CalcItemWidth ( ) , label_size . y + style . FramePadding . y * 2.0F ) , ImGuiInputTextFlags_CallbackResize | flags , UpdateStringSizeCallback , & buffer ) ;
2022-09-19 11:29:51 +02:00
if ( value_changed )
MarkItemEdited ( GImGui - > LastItemData . ID ) ;
RenderNavHighlight ( frame_bb , id ) ;
RenderFrame ( frame_bb . Min , frame_bb . Max , GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
RenderFrame ( frame_bb . Min , frame_bb . Min + icon_frame_size , GetColorU32 ( ImGuiCol_TableBorderStrong ) , true , style . FrameRounding ) ;
2023-06-09 00:30:12 +02:00
RenderText ( ImVec2 ( frame_bb . Min . x + style . FramePadding . x , frame_bb . Min . y + style . FramePadding . y ) , icon ) ;
2022-09-19 11:29:51 +02:00
return value_changed ;
}
2022-05-27 20:42:07 +02:00
bool InputScalarCallback ( const char * label , ImGuiDataType data_type , void * p_data , const char * format , ImGuiInputTextFlags flags , ImGuiInputTextCallback callback , void * user_data ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return false ;
ImGuiContext & g = * GImGui ;
2022-10-02 17:30:26 +02:00
if ( format = = nullptr )
2022-05-27 20:42:07 +02:00
format = DataTypeGetInfo ( data_type ) - > PrintFmt ;
char buf [ 64 ] ;
DataTypeFormatString ( buf , IM_ARRAYSIZE ( buf ) , data_type , p_data , format ) ;
bool value_changed = false ;
if ( ( flags & ( ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific ) ) = = 0 )
flags | = ImGuiInputTextFlags_CharsDecimal ;
flags | = ImGuiInputTextFlags_AutoSelectAll ;
flags | = ImGuiInputTextFlags_NoMarkEdited ; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
2023-11-16 22:24:06 +01:00
if ( ImGui : : InputText ( label , buf , IM_ARRAYSIZE ( buf ) , flags , callback , user_data ) )
2022-08-03 23:32:34 +02:00
value_changed = DataTypeApplyFromText ( buf , data_type , p_data , format ) ;
2022-05-27 20:42:07 +02:00
if ( value_changed )
MarkItemEdited ( g . LastItemData . ID ) ;
return value_changed ;
}
void HideTooltip ( ) {
char window_name [ 16 ] ;
ImFormatString ( window_name , IM_ARRAYSIZE ( window_name ) , " ##Tooltip_%02d " , GImGui - > TooltipOverrideCount ) ;
if ( ImGuiWindow * window = FindWindowByName ( window_name ) ; window ! = nullptr ) {
if ( window - > Active )
window - > Hidden = true ;
}
}
2022-05-29 14:57:59 +02:00
bool BitCheckbox ( const char * label , bool * v ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return false ;
ImGuiContext & g = * GImGui ;
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( label ) ;
2022-10-02 17:30:26 +02:00
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2022-05-29 14:57:59 +02:00
const ImVec2 size = ImVec2 ( CalcTextSize ( " 0 " ) . x + style . FramePadding . x * 2 , GetFrameHeight ( ) ) ;
const ImVec2 pos = window - > DC . CursorPos ;
const ImRect total_bb ( pos , pos + size ) ;
ItemSize ( total_bb , style . FramePadding . y ) ;
if ( ! ItemAdd ( total_bb , id ) )
{
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags | ImGuiItemStatusFlags_Checkable | ( * v ? ImGuiItemStatusFlags_Checked : 0 ) ) ;
return false ;
}
bool hovered , held ;
bool pressed = ButtonBehavior ( total_bb , id , & hovered , & held ) ;
if ( pressed )
{
* v = ! ( * v ) ;
MarkItemEdited ( id ) ;
}
const ImRect check_bb ( pos , pos + size ) ;
RenderNavHighlight ( total_bb , id ) ;
RenderFrame ( check_bb . Min , check_bb . Max , GetColorU32 ( ( held & & hovered ) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
RenderText ( check_bb . Min + style . FramePadding , * v ? " 1 " : " 0 " ) ;
ImVec2 label_pos = ImVec2 ( check_bb . Max . x + style . ItemInnerSpacing . x , check_bb . Min . y + style . FramePadding . y ) ;
2024-02-24 23:34:29 +01:00
if ( label_size . x > 0.0F )
2022-05-29 14:57:59 +02:00
RenderText ( label_pos , label ) ;
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags | ImGuiItemStatusFlags_Checkable | ( * v ? ImGuiItemStatusFlags_Checked : 0 ) ) ;
return pressed ;
}
2023-11-18 17:23:15 +01:00
bool DimmedButton ( const char * label , ImVec2 size ) {
2023-11-16 22:24:06 +01:00
PushStyleColor ( ImGuiCol_ButtonHovered , GetCustomColorU32 ( ImGuiCustomCol_DescButtonHovered ) ) ;
PushStyleColor ( ImGuiCol_Button , GetCustomColorU32 ( ImGuiCustomCol_DescButton ) ) ;
PushStyleColor ( ImGuiCol_Text , GetColorU32 ( ImGuiCol_ButtonActive ) ) ;
PushStyleColor ( ImGuiCol_ButtonActive , GetCustomColorU32 ( ImGuiCustomCol_DescButtonActive ) ) ;
PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 1 ) ;
2023-05-05 22:00:17 +02:00
2023-11-18 17:23:15 +01:00
bool res = Button ( label , size ) ;
2023-05-05 22:00:17 +02:00
2023-11-16 22:24:06 +01:00
PopStyleColor ( 4 ) ;
PopStyleVar ( 1 ) ;
2023-05-11 12:00:45 +02:00
return res ;
}
2023-11-18 17:23:15 +01:00
bool DimmedIconButton ( const char * symbol , ImVec4 color , ImVec2 size ) {
2023-11-16 22:24:06 +01:00
PushStyleColor ( ImGuiCol_ButtonHovered , GetCustomColorU32 ( ImGuiCustomCol_DescButtonHovered ) ) ;
PushStyleColor ( ImGuiCol_Button , GetCustomColorU32 ( ImGuiCustomCol_DescButton ) ) ;
PushStyleColor ( ImGuiCol_Text , GetColorU32 ( ImGuiCol_ButtonActive ) ) ;
PushStyleColor ( ImGuiCol_ButtonActive , GetCustomColorU32 ( ImGuiCustomCol_DescButtonActive ) ) ;
PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 1 ) ;
2023-05-11 12:00:45 +02:00
2023-11-18 17:23:15 +01:00
bool res = IconButton ( symbol , color , size ) ;
2023-05-11 12:00:45 +02:00
2023-11-16 22:24:06 +01:00
PopStyleColor ( 4 ) ;
PopStyleVar ( 1 ) ;
2023-05-11 12:00:45 +02:00
2023-05-05 22:00:17 +02:00
return res ;
}
2023-11-19 16:08:21 +01:00
bool DimmedButtonToggle ( const char * icon , bool * v , ImVec2 size ) {
bool pushed = false ;
bool toggled = false ;
if ( * v ) {
PushStyleColor ( ImGuiCol_Border , GetStyleColorVec4 ( ImGuiCol_ButtonActive ) ) ;
pushed = true ;
}
if ( DimmedIconButton ( icon , GetStyleColorVec4 ( ImGuiCol_Text ) , size ) ) {
* v = ! * v ;
toggled = true ;
}
if ( pushed )
PopStyleColor ( ) ;
return toggled ;
}
2023-07-23 09:14:00 +02:00
bool DimmedIconToggle ( const char * icon , bool * v ) {
bool pushed = false ;
bool toggled = false ;
if ( * v ) {
2023-11-16 22:24:06 +01:00
PushStyleColor ( ImGuiCol_Border , GetStyleColorVec4 ( ImGuiCol_ButtonActive ) ) ;
2023-07-23 09:14:00 +02:00
pushed = true ;
}
2023-11-16 22:24:06 +01:00
if ( DimmedIconButton ( icon , GetStyleColorVec4 ( ImGuiCol_Text ) ) ) {
2023-07-23 09:14:00 +02:00
* v = ! * v ;
toggled = true ;
}
if ( pushed )
2023-11-16 22:24:06 +01:00
PopStyleColor ( ) ;
2023-07-23 09:14:00 +02:00
return toggled ;
}
2023-12-05 10:49:51 +01:00
bool DimmedIconToggle ( const char * iconOn , const char * iconOff , bool * v ) {
bool pushed = false ;
bool toggled = false ;
if ( * v ) {
PushStyleColor ( ImGuiCol_Border , GetStyleColorVec4 ( ImGuiCol_ButtonActive ) ) ;
pushed = true ;
}
if ( DimmedIconButton ( * v ? iconOn : iconOff , GetStyleColorVec4 ( ImGuiCol_Text ) ) ) {
* v = ! * v ;
toggled = true ;
}
if ( pushed )
PopStyleColor ( ) ;
return toggled ;
}
2023-08-30 10:04:06 +02:00
void TextOverlay ( const char * text , ImVec2 pos ) {
2023-11-16 22:24:06 +01:00
const auto textSize = CalcTextSize ( text ) ;
2023-08-30 10:04:06 +02:00
const auto textPos = pos - textSize / 2 ;
2023-11-16 22:24:06 +01:00
const auto margin = GetStyle ( ) . FramePadding * 2 ;
2023-08-30 10:04:06 +02:00
const auto textRect = ImRect ( textPos - margin , textPos + textSize + margin ) ;
2023-11-16 22:24:06 +01:00
auto drawList = GetForegroundDrawList ( ) ;
2023-08-30 10:04:06 +02:00
2023-11-16 22:24:06 +01:00
drawList - > AddRectFilled ( textRect . Min , textRect . Max , GetColorU32 ( ImGuiCol_WindowBg ) | 0xFF000000 ) ;
drawList - > AddRect ( textRect . Min , textRect . Max , GetColorU32 ( ImGuiCol_Border ) ) ;
drawList - > AddText ( textPos , GetColorU32 ( ImGuiCol_Text ) , text ) ;
2023-08-30 10:04:06 +02:00
}
2023-11-07 00:46:44 +01:00
bool BeginBox ( ) {
2023-11-16 22:24:06 +01:00
PushStyleVar ( ImGuiStyleVar_CellPadding , ImVec2 ( 5 , 5 ) ) ;
auto result = BeginTable ( " ##box " , 1 , ImGuiTableFlags_BordersOuter | ImGuiTableFlags_SizingStretchSame ) ;
TableNextRow ( ) ;
TableNextColumn ( ) ;
2023-11-07 00:46:44 +01:00
return result ;
}
void EndBox ( ) {
2023-11-16 22:24:06 +01:00
EndTable ( ) ;
PopStyleVar ( ) ;
2023-11-07 00:46:44 +01:00
}
2023-11-16 09:32:24 +01:00
void BeginSubWindow ( const char * label , ImVec2 size , ImGuiChildFlags flags ) {
2023-11-15 22:22:57 +01:00
const bool hasMenuBar = ! std : : string_view ( label ) . empty ( ) ;
2024-02-24 23:34:29 +01:00
ImGui : : PushStyleVar ( ImGuiStyleVar_ChildRounding , 5.0F ) ;
2023-11-17 16:05:45 +01:00
if ( ImGui : : BeginChild ( hex : : format ( " {}##SubWindow " , label ) . c_str ( ) , size , ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY | flags , hasMenuBar ? ImGuiWindowFlags_MenuBar : ImGuiWindowFlags_None ) ) {
2023-11-15 22:22:57 +01:00
if ( hasMenuBar & & ImGui : : BeginMenuBar ( ) ) {
ImGui : : TextUnformatted ( label ) ;
ImGui : : EndMenuBar ( ) ;
}
}
2023-11-16 09:32:24 +01:00
ImGui : : PopStyleVar ( ) ;
2023-11-15 22:22:57 +01:00
}
void EndSubWindow ( ) {
ImGui : : EndChild ( ) ;
}
2023-12-09 22:00:35 +01:00
bool VSliderAngle ( const char * label , const ImVec2 & size , float * v_rad , float v_degrees_min , float v_degrees_max , const char * format , ImGuiSliderFlags flags ) {
if ( format = = nullptr )
2023-12-05 10:49:51 +01:00
format = " %.0f deg " ;
2024-02-24 23:34:29 +01:00
float v_deg = ( * v_rad ) * 360.0F / ( 2 * IM_PI ) ;
2023-12-05 10:49:51 +01:00
bool value_changed = ImGui : : VSliderFloat ( label , size , & v_deg , v_degrees_min , v_degrees_max , format , flags ) ;
2024-02-24 23:34:29 +01:00
* v_rad = v_deg * ( 2 * IM_PI ) / 360.0F ;
2023-12-05 10:49:51 +01:00
return value_changed ;
}
bool InputFilePicker ( const char * label , std : : fs : : path & path , const std : : vector < hex : : fs : : ItemFilter > & validExtensions ) {
bool picked = false ;
ImGui : : PushID ( label ) ;
2024-01-28 22:14:59 +01:00
const auto buttonSize = ImGui : : CalcTextSize ( " ... " ) + ImGui : : GetStyle ( ) . FramePadding * 2 ;
2023-12-05 10:49:51 +01:00
ImGui : : PushItemWidth ( ImGui : : CalcItemWidth ( ) - buttonSize . x - ImGui : : GetStyle ( ) . FramePadding . x ) ;
std : : string string = wolv : : util : : toUTF8String ( path ) ;
if ( ImGui : : InputText ( " ##pathInput " , string , ImGuiInputTextFlags_AutoSelectAll ) ) {
path = std : : u8string ( string . begin ( ) , string . end ( ) ) ;
picked = true ;
}
ImGui : : PopItemWidth ( ) ;
ImGui : : SameLine ( ) ;
2024-01-28 22:14:59 +01:00
if ( ImGui : : Button ( " ... " , buttonSize ) ) {
2023-12-05 10:49:51 +01:00
hex : : fs : : openFileBrowser ( hex : : fs : : DialogMode : : Open , validExtensions , [ & ] ( const std : : fs : : path & pickedPath ) {
path = pickedPath ;
picked = true ;
} ) ;
}
ImGui : : SameLine ( ) ;
ImGui : : TextUnformatted ( label ) ;
ImGui : : PopID ( ) ;
return picked ;
}
2023-12-07 11:18:49 +01:00
bool ToggleSwitch ( const char * label , bool * v ) {
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return false ;
ImGuiContext & g = * GImGui ;
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( label ) ;
2023-12-09 22:00:35 +01:00
const ImVec2 label_size = CalcTextSize ( label , nullptr , true ) ;
2023-12-07 11:18:49 +01:00
const ImVec2 size = ImVec2 ( GetFrameHeight ( ) * 2.0F , GetFrameHeight ( ) ) ;
const ImVec2 pos = window - > DC . CursorPos ;
2024-02-24 23:34:29 +01:00
const ImRect total_bb ( pos , pos + ImVec2 ( size . x + ( label_size . x > 0.0F ? style . ItemInnerSpacing . x + label_size . x : 0.0F ) , label_size . y + style . FramePadding . y * 2.0F ) ) ;
2023-12-07 11:18:49 +01:00
ItemSize ( total_bb , style . FramePadding . y ) ;
if ( ! ItemAdd ( total_bb , id ) )
{
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags | ImGuiItemStatusFlags_Checkable | ( * v ? ImGuiItemStatusFlags_Checked : 0 ) ) ;
return false ;
}
bool hovered , held ;
bool pressed = ButtonBehavior ( total_bb , id , & hovered , & held ) ;
if ( pressed )
{
* v = ! ( * v ) ;
MarkItemEdited ( id ) ;
}
const ImRect knob_bb ( pos , pos + size ) ;
window - > DrawList - > AddRectFilled ( knob_bb . Min , knob_bb . Max , GetColorU32 ( held ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : * v ? ImGuiCol_ButtonActive : ImGuiCol_Button ) , size . y / 2 ) ;
if ( * v )
window - > DrawList - > AddCircleFilled ( knob_bb . Max - ImVec2 ( size . y / 2 , size . y / 2 ) , ( size . y - style . ItemInnerSpacing . y ) / 2 , GetColorU32 ( ImGuiCol_Text ) , 16 ) ;
else
window - > DrawList - > AddCircleFilled ( knob_bb . Min + ImVec2 ( size . y / 2 , size . y / 2 ) , ( size . y - style . ItemInnerSpacing . y ) / 2 , GetColorU32 ( ImGuiCol_Text ) , 16 ) ;
ImVec2 label_pos = ImVec2 ( knob_bb . Max . x + style . ItemInnerSpacing . x , knob_bb . Min . y + style . FramePadding . y ) ;
if ( g . LogEnabled )
LogRenderedText ( & label_pos , * v ? " ((*) ) " : " ( (*)) " ) ;
2024-02-24 23:34:29 +01:00
if ( label_size . x > 0.0F )
2023-12-07 11:18:49 +01:00
RenderText ( label_pos , label ) ;
IMGUI_TEST_ENGINE_ITEM_INFO ( id , label , g . LastItemData . StatusFlags | ImGuiItemStatusFlags_Checkable | ( * v ? ImGuiItemStatusFlags_Checked : 0 ) ) ;
return pressed ;
}
bool ToggleSwitch ( const char * label , bool v ) {
return ToggleSwitch ( label , & v ) ;
}
2023-11-16 22:24:06 +01:00
}
namespace ImGui {
bool InputText ( const char * label , std : : u8string & buffer , ImGuiInputTextFlags flags ) {
return ImGui : : InputText ( label , reinterpret_cast < char * > ( buffer . data ( ) ) , buffer . size ( ) + 1 , ImGuiInputTextFlags_CallbackResize | flags , ImGuiExt : : UpdateStringSizeCallback , & buffer ) ;
}
bool InputText ( const char * label , std : : string & buffer , ImGuiInputTextFlags flags ) {
return ImGui : : InputText ( label , buffer . data ( ) , buffer . size ( ) + 1 , ImGuiInputTextFlags_CallbackResize | flags , ImGuiExt : : UpdateStringSizeCallback , & buffer ) ;
}
bool InputTextMultiline ( const char * label , std : : string & buffer , const ImVec2 & size , ImGuiInputTextFlags flags ) {
return ImGui : : InputTextMultiline ( label , buffer . data ( ) , buffer . size ( ) + 1 , size , ImGuiInputTextFlags_CallbackResize | flags , ImGuiExt : : UpdateStringSizeCallback , & buffer ) ;
}
bool InputTextWithHint ( const char * label , const char * hint , std : : string & buffer , ImGuiInputTextFlags flags ) {
return ImGui : : InputTextWithHint ( label , hint , buffer . data ( ) , buffer . size ( ) + 1 , ImGuiInputTextFlags_CallbackResize | flags , ImGuiExt : : UpdateStringSizeCallback , & buffer ) ;
}
2021-01-27 00:00:20 +01:00
}