@ -1495,22 +1495,6 @@ ImGuiWindow::~ImGuiWindow()
Name = NULL ;
Name = NULL ;
}
}
void ImGui : : SetActiveID ( ImGuiID id , ImGuiWindow * window = NULL )
{
ImGuiState & g = * GImGui ;
g . ActiveId = id ;
g . ActiveIdIsFocusedOnly = false ;
g . ActiveIdIsJustActivated = true ;
g . ActiveIdWindow = window ;
}
void ImGui : : KeepAliveID ( ImGuiID id )
{
ImGuiState & g = * GImGui ;
if ( g . ActiveId = = id )
g . ActiveIdIsAlive = true ;
}
ImGuiID ImGuiWindow : : GetID ( const char * str , const char * str_end )
ImGuiID ImGuiWindow : : GetID ( const char * str , const char * str_end )
{
{
ImGuiID seed = IDStack . back ( ) ;
ImGuiID seed = IDStack . back ( ) ;
@ -1527,6 +1511,10 @@ ImGuiID ImGuiWindow::GetID(const void* ptr)
return id ;
return id ;
}
}
//-----------------------------------------------------------------------------
// Internal API exposed in imgui_internal.h
//-----------------------------------------------------------------------------
ImGuiWindow * ImGui : : GetCurrentWindow ( )
ImGuiWindow * ImGui : : GetCurrentWindow ( )
{
{
// If this ever crash it probably means that ImGui::NewFrame() has never been called (which is illegal). We should always have a CurrentWindow in the stack (there is an implicit "Debug" window)
// If this ever crash it probably means that ImGui::NewFrame() has never been called (which is illegal). We should always have a CurrentWindow in the stack (there is an implicit "Debug" window)
@ -1550,6 +1538,113 @@ ImGuiWindow* ImGui::GetParentWindow()
return g . CurrentWindowStack [ g . CurrentWindowStack . Size - 2 ] ;
return g . CurrentWindowStack [ g . CurrentWindowStack . Size - 2 ] ;
}
}
void ImGui : : SetActiveID ( ImGuiID id , ImGuiWindow * window = NULL )
{
ImGuiState & g = * GImGui ;
g . ActiveId = id ;
g . ActiveIdIsFocusedOnly = false ;
g . ActiveIdIsJustActivated = true ;
g . ActiveIdWindow = window ;
}
void ImGui : : KeepAliveID ( ImGuiID id )
{
ImGuiState & g = * GImGui ;
if ( g . ActiveId = = id )
g . ActiveIdIsAlive = true ;
}
// Advance cursor given item size for layout.
void ImGui : : ItemSize ( const ImVec2 & size , float text_offset_y )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return ;
// Always align ourselves on pixel boundaries
ImGuiState & g = * GImGui ;
const float line_height = ImMax ( window - > DC . CurrentLineHeight , size . y ) ;
const float text_base_offset = ImMax ( window - > DC . CurrentLineTextBaseOffset , text_offset_y ) ;
window - > DC . CursorPosPrevLine = ImVec2 ( window - > DC . CursorPos . x + size . x , window - > DC . CursorPos . y ) ;
window - > DC . CursorPos = ImVec2 ( ( float ) ( int ) ( window - > Pos . x + window - > DC . ColumnsStartX + window - > DC . ColumnsOffsetX ) , ( float ) ( int ) ( window - > DC . CursorPos . y + line_height + g . Style . ItemSpacing . y ) ) ;
window - > DC . CursorMaxPos . x = ImMax ( window - > DC . CursorMaxPos . x , window - > DC . CursorPosPrevLine . x ) ;
window - > DC . CursorMaxPos . y = ImMax ( window - > DC . CursorMaxPos . y , window - > DC . CursorPos . y ) ;
//window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug
window - > DC . PrevLineHeight = line_height ;
window - > DC . PrevLineTextBaseOffset = text_base_offset ;
window - > DC . CurrentLineHeight = window - > DC . CurrentLineTextBaseOffset = 0.0f ;
}
void ImGui : : ItemSize ( const ImRect & bb , float text_offset_y )
{
ItemSize ( bb . GetSize ( ) , text_offset_y ) ;
}
// Declare item bounding box for clipping and interaction.
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
// declares their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd().
bool ImGui : : ItemAdd ( const ImRect & bb , const ImGuiID * id )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
window - > DC . LastItemID = id ? * id : 0 ;
window - > DC . LastItemRect = bb ;
if ( IsClippedEx ( bb , id , false ) )
{
window - > DC . LastItemHoveredAndUsable = window - > DC . LastItemHoveredRect = false ;
return false ;
}
// This is a sensible default, but widgets are free to override it after calling ItemAdd()
ImGuiState & g = * GImGui ;
if ( IsMouseHoveringRect ( bb . Min , bb . Max ) )
{
// Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background)
// So that clicking on items with no active id such as Text() still returns true with IsItemHovered()
window - > DC . LastItemHoveredRect = true ;
window - > DC . LastItemHoveredAndUsable = false ;
if ( g . HoveredRootWindow = = window - > RootWindow )
if ( g . ActiveId = = 0 | | ( id & & g . ActiveId = = * id ) | | g . ActiveIdIsFocusedOnly | | ( g . ActiveId = = window - > MoveID ) )
if ( IsWindowContentHoverable ( window ) )
window - > DC . LastItemHoveredAndUsable = true ;
}
else
{
window - > DC . LastItemHoveredAndUsable = window - > DC . LastItemHoveredRect = false ;
}
return true ;
}
bool ImGui : : IsClippedEx ( const ImRect & bb , const ImGuiID * id , bool clip_even_when_logged )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( ! bb . Overlaps ( ImRect ( window - > ClipRect ) ) )
{
if ( ! id | | * id ! = GImGui - > ActiveId )
if ( clip_even_when_logged | | ! g . LogEnabled )
return true ;
}
return false ;
}
bool ImGui : : IsHovered ( const ImRect & bb , ImGuiID id , bool flatten_childs )
{
ImGuiState & g = * GImGui ;
if ( g . HoveredId = = 0 | | g . HoveredId = = id )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( g . HoveredWindow = = window | | ( flatten_childs & & g . HoveredRootWindow = = window - > RootWindow ) )
if ( ( g . ActiveId = = 0 | | g . ActiveId = = id | | g . ActiveIdIsFocusedOnly ) & & ImGui : : IsMouseHoveringRect ( bb . Min , bb . Max ) )
if ( IsWindowContentHoverable ( g . HoveredRootWindow ) )
return true ;
}
return false ;
}
bool ImGui : : FocusableItemRegister ( ImGuiWindow * window , bool is_active , bool tab_stop )
bool ImGui : : FocusableItemRegister ( ImGuiWindow * window , bool is_active , bool tab_stop )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
@ -1583,140 +1678,46 @@ void ImGui::FocusableItemUnregister(ImGuiWindow* window)
window - > FocusIdxTabCounter - - ;
window - > FocusIdxTabCounter - - ;
}
}
//-----------------------------------------------------------------------------
ImVec2 ImGui : : CalcItemSize ( ImVec2 size , float default_x , float default_y )
void * ImGui : : MemAlloc ( size_t sz )
{
GImGui - > IO . MetricsAllocs + + ;
return GImGui - > IO . MemAllocFn ( sz ) ;
}
void ImGui : : MemFree ( void * ptr )
{
if ( ptr ) GImGui - > IO . MetricsAllocs - - ;
return GImGui - > IO . MemFreeFn ( ptr ) ;
}
static ImGuiIniData * FindWindowSettings ( const char * name )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
ImGuiID id = ImHash ( name , 0 ) ;
ImVec2 content_max ;
for ( int i = 0 ; i ! = g . Settings . Size ; i + + )
if ( size . x < 0.0f | | size . y < 0.0f )
{
content_max = g . CurrentWindow - > Pos + ImGui : : GetContentRegionMax ( ) ;
ImGuiIniData * ini = & g . Settings [ i ] ;
if ( size . x < = 0.0f )
if ( ini - > ID = = id )
size . x = ( size . x = = 0.0f ) ? default_x : ImMax ( content_max . x - g . CurrentWindow - > DC . CursorPos . x , 4.0f ) + size . x ;
return ini ;
if ( size . y < = 0.0f )
}
size . y = ( size . y = = 0.0f ) ? default_y : ImMax ( content_max . y - g . CurrentWindow - > DC . CursorPos . y , 4.0f ) + size . y ;
return NULL ;
return size ;
}
static ImGuiIniData * AddWindowSettings ( const char * name )
{
GImGui - > Settings . resize ( GImGui - > Settings . Size + 1 ) ;
ImGuiIniData * ini = & GImGui - > Settings . back ( ) ;
ini - > Name = ImStrdup ( name ) ;
ini - > ID = ImHash ( name , 0 ) ;
ini - > Collapsed = false ;
ini - > Pos = ImVec2 ( FLT_MAX , FLT_MAX ) ;
ini - > Size = ImVec2 ( 0 , 0 ) ;
return ini ;
}
}
// Zero-tolerance, poor-man .ini parsing
float ImGui : : CalcWrapWidthForPos ( const ImVec2 & pos , float wrap_pos_x )
// FIXME: Write something less rubbish
static void LoadSettings ( )
{
{
ImGuiState & g = * GImGui ;
if ( wrap_pos_x < 0.0f )
const char * filename = g . IO . IniFilename ;
return 0.0f ;
if ( ! filename )
return ;
char * file_data ;
int file_size ;
if ( ! ImLoadFileToMemory ( filename , " rb " , ( void * * ) & file_data , & file_size , 1 ) )
return ;
ImGuiIniData * settings = NULL ;
const char * buf_end = file_data + file_size ;
for ( const char * line_start = file_data ; line_start < buf_end ; )
{
const char * line_end = line_start ;
while ( line_end < buf_end & & * line_end ! = ' \n ' & & * line_end ! = ' \r ' )
line_end + + ;
if ( line_start [ 0 ] = = ' [ ' & & line_end > line_start & & line_end [ - 1 ] = = ' ] ' )
{
char name [ 64 ] ;
ImFormatString ( name , IM_ARRAYSIZE ( name ) , " %.*s " , line_end - line_start - 2 , line_start + 1 ) ;
settings = FindWindowSettings ( name ) ;
if ( ! settings )
settings = AddWindowSettings ( name ) ;
}
else if ( settings )
{
float x , y ;
int i ;
if ( sscanf ( line_start , " Pos=%f,%f " , & x , & y ) = = 2 )
settings - > Pos = ImVec2 ( x , y ) ;
else if ( sscanf ( line_start , " Size=%f,%f " , & x , & y ) = = 2 )
settings - > Size = ImMax ( ImVec2 ( x , y ) , g . Style . WindowMinSize ) ;
else if ( sscanf ( line_start , " Collapsed=%d " , & i ) = = 1 )
settings - > Collapsed = ( i ! = 0 ) ;
}
line_start = line_end + 1 ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
}
if ( wrap_pos_x = = 0.0f )
wrap_pos_x = ImGui : : GetContentRegionMax ( ) . x ;
if ( wrap_pos_x > 0.0f )
wrap_pos_x + = window - > Pos . x ; // wrap_pos_x is provided is window local space
ImGui : : MemFree ( file_data ) ;
const float wrap_width = wrap_pos_x > 0.0f ? ImMax ( wrap_pos_x - pos . x , 0.00001f ) : 0.0f ;
return wrap_width ;
}
}
static void SaveSettings ( )
//-----------------------------------------------------------------------------
{
ImGuiState & g = * GImGui ;
const char * filename = g . IO . IniFilename ;
if ( ! filename )
return ;
// Gather data from windows that were active during this session
for ( int i = 0 ; i ! = g . Windows . Size ; i + + )
{
ImGuiWindow * window = g . Windows [ i ] ;
if ( window - > Flags & ImGuiWindowFlags_NoSavedSettings )
continue ;
ImGuiIniData * settings = FindWindowSettings ( window - > Name ) ;
settings - > Pos = window - > Pos ;
settings - > Size = window - > SizeFull ;
settings - > Collapsed = window - > Collapsed ;
}
// Write .ini file
// If a window wasn't opened in this session we preserve its settings
FILE * f = fopen ( filename , " wt " ) ;
if ( ! f )
return ;
for ( int i = 0 ; i ! = g . Settings . Size ; i + + )
{
const ImGuiIniData * settings = & g . Settings [ i ] ;
if ( settings - > Pos . x = = FLT_MAX )
continue ;
const char * name = settings - > Name ;
if ( const char * p = strstr ( name , " ### " ) ) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
name = p ;
fprintf ( f , " [%s] \n " , name ) ;
fprintf ( f , " Pos=%d,%d \n " , ( int ) settings - > Pos . x , ( int ) settings - > Pos . y ) ;
fprintf ( f , " Size=%d,%d \n " , ( int ) settings - > Size . x , ( int ) settings - > Size . y ) ;
fprintf ( f , " Collapsed=%d \n " , settings - > Collapsed ) ;
fprintf ( f , " \n " ) ;
}
fclose ( f ) ;
void * ImGui : : MemAlloc ( size_t sz )
{
GImGui - > IO . MetricsAllocs + + ;
return GImGui - > IO . MemAllocFn ( sz ) ;
}
}
static void MarkSettingsDirty ( )
void ImGui : : MemFree ( void * ptr )
{
{
ImGuiState & g = * GImGui ;
if ( ptr ) GImGui - > IO . MetricsAllocs - - ;
if ( g . SettingsDirtyTimer < = 0.0f )
return GImGui - > IO . MemFreeFn ( ptr ) ;
g . SettingsDirtyTimer = g . IO . IniSavingRate ;
}
}
const char * ImGui : : GetVersion ( )
const char * ImGui : : GetVersion ( )
@ -1740,18 +1741,27 @@ void ImGui::SetInternalState(void* state, bool construct)
{
{
if ( construct )
if ( construct )
new ( state ) ImGuiState ( ) ;
new ( state ) ImGuiState ( ) ;
GImGui = ( ImGuiState * ) state ;
GImGui = ( ImGuiState * ) state ;
}
}
ImGuiIO & ImGui : : GetIO ( )
ImGuiIO & ImGui : : GetIO ( )
{
{
return GImGui - > IO ;
return GImGui - > IO ;
}
ImGuiStyle & ImGui : : GetStyle ( )
{
return GImGui - > Style ;
}
float ImGui : : GetTime ( )
{
return GImGui - > Time ;
}
}
ImGuiStyle & ImGui : : GetStyle ( )
int ImGui : : GetFrameCount ( )
{
{
return GImGui - > Style ;
return GImGui - > FrameCount ;
}
}
void ImGui : : NewFrame ( )
void ImGui : : NewFrame ( )
@ -2005,6 +2015,128 @@ void ImGui::Shutdown()
g . Initialized = false ;
g . Initialized = false ;
}
}
static ImGuiIniData * FindWindowSettings ( const char * name )
{
ImGuiState & g = * GImGui ;
ImGuiID id = ImHash ( name , 0 ) ;
for ( int i = 0 ; i ! = g . Settings . Size ; i + + )
{
ImGuiIniData * ini = & g . Settings [ i ] ;
if ( ini - > ID = = id )
return ini ;
}
return NULL ;
}
static ImGuiIniData * AddWindowSettings ( const char * name )
{
GImGui - > Settings . resize ( GImGui - > Settings . Size + 1 ) ;
ImGuiIniData * ini = & GImGui - > Settings . back ( ) ;
ini - > Name = ImStrdup ( name ) ;
ini - > ID = ImHash ( name , 0 ) ;
ini - > Collapsed = false ;
ini - > Pos = ImVec2 ( FLT_MAX , FLT_MAX ) ;
ini - > Size = ImVec2 ( 0 , 0 ) ;
return ini ;
}
// Zero-tolerance, poor-man .ini parsing
// FIXME: Write something less rubbish
static void LoadSettings ( )
{
ImGuiState & g = * GImGui ;
const char * filename = g . IO . IniFilename ;
if ( ! filename )
return ;
char * file_data ;
int file_size ;
if ( ! ImLoadFileToMemory ( filename , " rb " , ( void * * ) & file_data , & file_size , 1 ) )
return ;
ImGuiIniData * settings = NULL ;
const char * buf_end = file_data + file_size ;
for ( const char * line_start = file_data ; line_start < buf_end ; )
{
const char * line_end = line_start ;
while ( line_end < buf_end & & * line_end ! = ' \n ' & & * line_end ! = ' \r ' )
line_end + + ;
if ( line_start [ 0 ] = = ' [ ' & & line_end > line_start & & line_end [ - 1 ] = = ' ] ' )
{
char name [ 64 ] ;
ImFormatString ( name , IM_ARRAYSIZE ( name ) , " %.*s " , line_end - line_start - 2 , line_start + 1 ) ;
settings = FindWindowSettings ( name ) ;
if ( ! settings )
settings = AddWindowSettings ( name ) ;
}
else if ( settings )
{
float x , y ;
int i ;
if ( sscanf ( line_start , " Pos=%f,%f " , & x , & y ) = = 2 )
settings - > Pos = ImVec2 ( x , y ) ;
else if ( sscanf ( line_start , " Size=%f,%f " , & x , & y ) = = 2 )
settings - > Size = ImMax ( ImVec2 ( x , y ) , g . Style . WindowMinSize ) ;
else if ( sscanf ( line_start , " Collapsed=%d " , & i ) = = 1 )
settings - > Collapsed = ( i ! = 0 ) ;
}
line_start = line_end + 1 ;
}
ImGui : : MemFree ( file_data ) ;
}
static void SaveSettings ( )
{
ImGuiState & g = * GImGui ;
const char * filename = g . IO . IniFilename ;
if ( ! filename )
return ;
// Gather data from windows that were active during this session
for ( int i = 0 ; i ! = g . Windows . Size ; i + + )
{
ImGuiWindow * window = g . Windows [ i ] ;
if ( window - > Flags & ImGuiWindowFlags_NoSavedSettings )
continue ;
ImGuiIniData * settings = FindWindowSettings ( window - > Name ) ;
settings - > Pos = window - > Pos ;
settings - > Size = window - > SizeFull ;
settings - > Collapsed = window - > Collapsed ;
}
// Write .ini file
// If a window wasn't opened in this session we preserve its settings
FILE * f = fopen ( filename , " wt " ) ;
if ( ! f )
return ;
for ( int i = 0 ; i ! = g . Settings . Size ; i + + )
{
const ImGuiIniData * settings = & g . Settings [ i ] ;
if ( settings - > Pos . x = = FLT_MAX )
continue ;
const char * name = settings - > Name ;
if ( const char * p = strstr ( name , " ### " ) ) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
name = p ;
fprintf ( f , " [%s] \n " , name ) ;
fprintf ( f , " Pos=%d,%d \n " , ( int ) settings - > Pos . x , ( int ) settings - > Pos . y ) ;
fprintf ( f , " Size=%d,%d \n " , ( int ) settings - > Size . x , ( int ) settings - > Size . y ) ;
fprintf ( f , " Collapsed=%d \n " , settings - > Collapsed ) ;
fprintf ( f , " \n " ) ;
}
fclose ( f ) ;
}
static void MarkSettingsDirty ( )
{
ImGuiState & g = * GImGui ;
if ( g . SettingsDirtyTimer < = 0.0f )
g . SettingsDirtyTimer = g . IO . IniSavingRate ;
}
// FIXME: Add a more explicit sort order in the window structure.
// FIXME: Add a more explicit sort order in the window structure.
static int ChildWindowComparer ( const void * lhs , const void * rhs )
static int ChildWindowComparer ( const void * lhs , const void * rhs )
{
{
@ -2313,21 +2445,6 @@ static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char*
}
}
}
}
float ImGui : : CalcWrapWidthForPos ( const ImVec2 & pos , float wrap_pos_x )
{
if ( wrap_pos_x < 0.0f )
return 0.0f ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
if ( wrap_pos_x = = 0.0f )
wrap_pos_x = ImGui : : GetContentRegionMax ( ) . x ;
if ( wrap_pos_x > 0.0f )
wrap_pos_x + = window - > Pos . x ; // wrap_pos_x is provided is window local space
const float wrap_width = wrap_pos_x > 0.0f ? ImMax ( wrap_pos_x - pos . x , 0.00001f ) : 0.0f ;
return wrap_width ;
}
// Internal ImGui functions to render text
// Internal ImGui functions to render text
// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
void ImGui : : RenderText ( ImVec2 pos , const char * text , const char * text_end , bool hide_text_after_hash )
void ImGui : : RenderText ( ImVec2 pos , const char * text , const char * text_end , bool hide_text_after_hash )
@ -2820,16 +2937,6 @@ void ImGui::SetTooltip(const char* fmt, ...)
va_end ( args ) ;
va_end ( args ) ;
}
}
float ImGui : : GetTime ( )
{
return GImGui - > Time ;
}
int ImGui : : GetFrameCount ( )
{
return GImGui - > FrameCount ;
}
static ImVec4 GetVisibleRect ( )
static ImVec4 GetVisibleRect ( )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
@ -4814,20 +4921,6 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window)
return true ;
return true ;
}
}
bool ImGui : : IsHovered ( const ImRect & bb , ImGuiID id , bool flatten_childs )
{
ImGuiState & g = * GImGui ;
if ( g . HoveredId = = 0 | | g . HoveredId = = id )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( g . HoveredWindow = = window | | ( flatten_childs & & g . HoveredRootWindow = = window - > RootWindow ) )
if ( ( g . ActiveId = = 0 | | g . ActiveId = = id | | g . ActiveIdIsFocusedOnly ) & & ImGui : : IsMouseHoveringRect ( bb . Min , bb . Max ) )
if ( IsWindowContentHoverable ( g . HoveredRootWindow ) )
return true ;
}
return false ;
}
bool ImGui : : ButtonBehavior ( const ImRect & bb , ImGuiID id , bool * out_hovered , bool * out_held , bool allow_key_modifiers , ImGuiButtonFlags flags )
bool ImGui : : ButtonBehavior ( const ImRect & bb , ImGuiID id , bool * out_hovered , bool * out_held , bool allow_key_modifiers , ImGuiButtonFlags flags )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
@ -4894,19 +4987,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
return pressed ;
return pressed ;
}
}
ImVec2 ImGui : : CalcItemSize ( ImVec2 size , float default_x , float default_y )
{
ImGuiState & g = * GImGui ;
ImVec2 content_max ;
if ( size . x < 0.0f | | size . y < 0.0f )
content_max = g . CurrentWindow - > Pos + ImGui : : GetContentRegionMax ( ) ;
if ( size . x < = 0.0f )
size . x = ( size . x = = 0.0f ) ? default_x : ImMax ( content_max . x - g . CurrentWindow - > DC . CursorPos . x , 4.0f ) + size . x ;
if ( size . y < = 0.0f )
size . y = ( size . y = = 0.0f ) ? default_y : ImMax ( content_max . y - g . CurrentWindow - > DC . CursorPos . y , 4.0f ) + size . y ;
return size ;
}
bool ImGui : : ButtonEx ( const char * label , const ImVec2 & size_arg , ImGuiButtonFlags flags )
bool ImGui : : ButtonEx ( const char * label , const ImVec2 & size_arg , ImGuiButtonFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
@ -8242,48 +8322,6 @@ void ImGui::Dummy(const ImVec2& size)
ItemSize ( size ) ;
ItemSize ( size ) ;
}
}
// Advance cursor given item size for layout.
void ImGui : : ItemSize ( const ImVec2 & size , float text_offset_y )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return ;
// Always align ourselves on pixel boundaries
ImGuiState & g = * GImGui ;
const float line_height = ImMax ( window - > DC . CurrentLineHeight , size . y ) ;
const float text_base_offset = ImMax ( window - > DC . CurrentLineTextBaseOffset , text_offset_y ) ;
window - > DC . CursorPosPrevLine = ImVec2 ( window - > DC . CursorPos . x + size . x , window - > DC . CursorPos . y ) ;
window - > DC . CursorPos = ImVec2 ( ( float ) ( int ) ( window - > Pos . x + window - > DC . ColumnsStartX + window - > DC . ColumnsOffsetX ) , ( float ) ( int ) ( window - > DC . CursorPos . y + line_height + g . Style . ItemSpacing . y ) ) ;
window - > DC . CursorMaxPos . x = ImMax ( window - > DC . CursorMaxPos . x , window - > DC . CursorPosPrevLine . x ) ;
window - > DC . CursorMaxPos . y = ImMax ( window - > DC . CursorMaxPos . y , window - > DC . CursorPos . y ) ;
//window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug
window - > DC . PrevLineHeight = line_height ;
window - > DC . PrevLineTextBaseOffset = text_base_offset ;
window - > DC . CurrentLineHeight = window - > DC . CurrentLineTextBaseOffset = 0.0f ;
}
void ImGui : : ItemSize ( const ImRect & bb , float text_offset_y )
{
ItemSize ( bb . GetSize ( ) , text_offset_y ) ;
}
bool ImGui : : IsClippedEx ( const ImRect & bb , const ImGuiID * id , bool clip_even_when_logged )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( ! bb . Overlaps ( ImRect ( window - > ClipRect ) ) )
{
if ( ! id | | * id ! = GImGui - > ActiveId )
if ( clip_even_when_logged | | ! g . LogEnabled )
return true ;
}
return false ;
}
bool ImGui : : IsRectVisible ( const ImVec2 & size )
bool ImGui : : IsRectVisible ( const ImVec2 & size )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
@ -8291,41 +8329,6 @@ bool ImGui::IsRectVisible(const ImVec2& size)
return r . Overlaps ( ImRect ( window - > DC . CursorPos , window - > DC . CursorPos + size ) ) ;
return r . Overlaps ( ImRect ( window - > DC . CursorPos , window - > DC . CursorPos + size ) ) ;
}
}
// Declare item bounding box for clipping and interaction.
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
// declares their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd().
bool ImGui : : ItemAdd ( const ImRect & bb , const ImGuiID * id )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
window - > DC . LastItemID = id ? * id : 0 ;
window - > DC . LastItemRect = bb ;
if ( IsClippedEx ( bb , id , false ) )
{
window - > DC . LastItemHoveredAndUsable = window - > DC . LastItemHoveredRect = false ;
return false ;
}
// This is a sensible default, but widgets are free to override it after calling ItemAdd()
ImGuiState & g = * GImGui ;
if ( ImGui : : IsMouseHoveringRect ( bb . Min , bb . Max ) )
{
// Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background)
// So that clicking on items with no active id such as Text() still returns true with IsItemHovered()
window - > DC . LastItemHoveredRect = true ;
window - > DC . LastItemHoveredAndUsable = false ;
if ( g . HoveredRootWindow = = window - > RootWindow )
if ( g . ActiveId = = 0 | | ( id & & g . ActiveId = = * id ) | | g . ActiveIdIsFocusedOnly | | ( g . ActiveId = = window - > MoveID ) )
if ( IsWindowContentHoverable ( window ) )
window - > DC . LastItemHoveredAndUsable = true ;
}
else
{
window - > DC . LastItemHoveredAndUsable = window - > DC . LastItemHoveredRect = false ;
}
return true ;
}
void ImGui : : BeginGroup ( )
void ImGui : : BeginGroup ( )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;