@ -13,7 +13,7 @@
- API BREAKING CHANGES ( read me when you update ! )
- API BREAKING CHANGES ( read me when you update ! )
- FREQUENTLY ASKED QUESTIONS ( FAQ ) , TIPS
- FREQUENTLY ASKED QUESTIONS ( FAQ ) , TIPS
- How do I update to a newer version of ImGui ?
- How do I update to a newer version of ImGui ?
- Can I have multiple widgets with the same label ? ( Yes )
- Can I have multiple widgets with the same label ? Can I have widget without a label ? ( Yes )
- Why is my text output blurry ?
- Why is my text output blurry ?
- How can I load a different font than the default ?
- How can I load a different font than the default ?
- How can I load multiple fonts ?
- How can I load multiple fonts ?
@ -196,38 +196,42 @@
Check the " API BREAKING CHANGES " sections for a list of occasional API breaking changes . If you have a problem with a function , search for its name
Check the " API BREAKING CHANGES " sections for a list of occasional API breaking changes . If you have a problem with a function , search for its name
in the code , there will likely be a comment about it . Please report any issue to the GitHub page !
in the code , there will likely be a comment about it . Please report any issue to the GitHub page !
Q : Can I have multiple widgets with the same label ?
Q : Can I have multiple widgets with the same label ? Can I have widget without a label ? ( Yes )
A : Yes . A primer on the use of labels / IDs in ImGui . .
A : Yes . A primer on the use of labels / IDs in ImGui . .
- Elements that are not clickable , such as Text ( ) items don ' t need an ID .
- Interactive widgets require state to be carried over multiple frames ( most typically ImGui often needs to remember what is the " active " widget ) .
- Interactive widgets require state to be carried over multiple frames ( most typically ImGui often needs to remember what is the " active " widget ) .
to do so they need an unique ID . unique ID are typically derived from a string label , an integer index or a pointer .
to do so they need an unique ID . unique ID are typically derived from a string label , an integer index or a pointer .
Button ( " OK " ) ; // Label = "OK", ID = hash of "OK"
Button ( " OK " ) ; // Label = "OK", ID = hash of "OK"
Button ( " Cancel " ) ; // Label = "Cancel", ID = hash of "Cancel"
Button ( " Cancel " ) ; // Label = "Cancel", ID = hash of "Cancel"
- Elements that are not clickable , such as Text ( ) items don ' t need an ID .
- ID are uniquely scoped within windows , tree nodes , etc . so no conflict can happen if you have two buttons called " OK " in two different windows
- ID are uniquely scoped within windows , tree nodes , etc . so no conflict can happen if you have two buttons called " OK " in two different windows
or in two different locations of a tree .
or in two different locations of a tree .
- if you have a same ID twice in the same location , you ' ll have a conflict :
- if you have a same ID twice in the same location , you ' ll have a conflict :
Button ( " OK " ) ;
Button ( " OK " ) ;
Button ( " OK " ) ; // ID collision! Both buttons will be treated as the same.
Button ( " OK " ) ; // ID collision! Both buttons will be treated as the same.
Fear not ! this is easy to solve and there are many ways to solve it !
Fear not ! this is easy to solve and there are many ways to solve it !
- when passing a label you can optionally specify extra unique ID information within string itself . This helps solving the simpler collision cases .
- when passing a label you can optionally specify extra unique ID information within string itself . This helps solving the simpler collision cases .
use " ## " to pass a complement to the ID that won ' t be visible to the end - user :
use " ## " to pass a complement to the ID that won ' t be visible to the end - user :
Button ( " Play##0 " ) ; // Label = "Play", ID = hash of "Play##0"
Button ( " Play##0 " ) ; // Label = "Play", ID = hash of "Play##0"
Button ( " Play##1 " ) ; // Label = "Play", ID = hash of "Play##1" (different from above)
Button ( " Play##1 " ) ; // Label = "Play", ID = hash of "Play##1" (different from above)
- so if you want to hide the label but need an ID :
Checkbox ( " ##On " , & b ) ; // Label = "", ID = hash of "##On"
- occasionally ( rarely ) you might want change a label while preserving a constant ID . This allows you to animate labels .
- occasionally ( rarely ) you might want change a label while preserving a constant ID . This allows you to animate labels .
use " ### " to pass a label that isn ' t part of ID :
use " ### " to pass a label that isn ' t part of ID :
Button ( " Hello###ID " ; // Label = "Hello", ID = hash of "ID"
Button ( " Hello###ID " ; // Label = "Hello", ID = hash of "ID"
Button ( " World###ID " ; // Label = "World", ID = hash of "ID" (same as above)
Button ( " World###ID " ; // Label = "World", ID = hash of "ID" (same as above)
- use PushID ( ) / PopID ( ) to create scopes and avoid ID conflicts within the same Window .
- use PushID ( ) / PopID ( ) to create scopes and avoid ID conflicts within the same Window .
this is the most convenient way of distinguish ID if you are iterating and creating many UI elements .
this is the most convenient way of distinguish ID if you are iterating and creating many UI elements .
@ -495,8 +499,9 @@ struct ImGuiTextEditState;
struct ImGuiIniData ;
struct ImGuiIniData ;
struct ImGuiState ;
struct ImGuiState ;
struct ImGuiWindow ;
struct ImGuiWindow ;
typedef int ImGuiButtonFlags ; // enum ImGuiButtonFlags_
static bool ButtonBehavior ( const ImRect & bb , ImGuiID id , bool * out_hovered , bool * out_held , bool allow_key_modifiers , bool repeat = false , bool pressed_on_click = false ) ;
static bool ButtonBehavior ( const ImRect & bb , ImGuiID id , bool * out_hovered , bool * out_held , bool allow_key_modifiers , ImGuiButtonFlags flags = 0 ) ;
static void LogText ( const ImVec2 & ref_pos , const char * text , const char * text_end = NULL ) ;
static void LogText ( const ImVec2 & ref_pos , const char * text , const char * text_end = NULL ) ;
static void RenderText ( ImVec2 pos , const char * text , const char * text_end = NULL , bool hide_text_after_hash = true ) ;
static void RenderText ( ImVec2 pos , const char * text , const char * text_end = NULL , bool hide_text_after_hash = true ) ;
@ -700,6 +705,7 @@ static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs)
static inline ImVec2 & operator - = ( ImVec2 & lhs , const ImVec2 & rhs ) { lhs . x - = rhs . x ; lhs . y - = rhs . y ; return lhs ; }
static inline ImVec2 & operator - = ( ImVec2 & lhs , const ImVec2 & rhs ) { lhs . x - = rhs . x ; lhs . y - = rhs . y ; return lhs ; }
static inline ImVec2 & operator * = ( ImVec2 & lhs , const float rhs ) { lhs . x * = rhs ; lhs . y * = rhs ; return lhs ; }
static inline ImVec2 & operator * = ( ImVec2 & lhs , const float rhs ) { lhs . x * = rhs ; lhs . y * = rhs ; return lhs ; }
//static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
//static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
static inline ImVec4 operator - ( const ImVec4 & lhs , const ImVec4 & rhs ) { return ImVec4 ( lhs . x - rhs . x , lhs . y - rhs . y , lhs . z - rhs . z , lhs . w - lhs . w ) ; }
static inline int ImMin ( int lhs , int rhs ) { return lhs < rhs ? lhs : rhs ; }
static inline int ImMin ( int lhs , int rhs ) { return lhs < rhs ? lhs : rhs ; }
static inline int ImMax ( int lhs , int rhs ) { return lhs > = rhs ? lhs : rhs ; }
static inline int ImMax ( int lhs , int rhs ) { return lhs > = rhs ? lhs : rhs ; }
@ -714,6 +720,7 @@ static inline float ImSaturate(float f)
static inline float ImLerp ( float a , float b , float t ) { return a + ( b - a ) * t ; }
static inline float ImLerp ( float a , float b , float t ) { return a + ( b - a ) * t ; }
static inline ImVec2 ImLerp ( const ImVec2 & a , const ImVec2 & b , const ImVec2 & t ) { return ImVec2 ( a . x + ( b . x - a . x ) * t . x , a . y + ( b . y - a . y ) * t . y ) ; }
static inline ImVec2 ImLerp ( const ImVec2 & a , const ImVec2 & b , const ImVec2 & t ) { return ImVec2 ( a . x + ( b . x - a . x ) * t . x , a . y + ( b . y - a . y ) * t . y ) ; }
static inline float ImLengthSqr ( const ImVec2 & lhs ) { return lhs . x * lhs . x + lhs . y * lhs . y ; }
static inline float ImLengthSqr ( const ImVec2 & lhs ) { return lhs . x * lhs . x + lhs . y * lhs . y ; }
static inline float ImLengthSqr ( const ImVec4 & lhs ) { return lhs . x * lhs . x + lhs . y * lhs . y + lhs . z * lhs . z + lhs . w * lhs . w ; }
static int ImStricmp ( const char * str1 , const char * str2 )
static int ImStricmp ( const char * str1 , const char * str2 )
{
{
@ -932,6 +939,13 @@ static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode,
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
enum ImGuiButtonFlags_
{
ImGuiButtonFlags_Repeat = ( 1 < < 0 ) ,
ImGuiButtonFlags_PressedOnClick = ( 1 < < 1 ) ,
ImGuiButtonFlags_FlattenChilds = ( 1 < < 2 )
} ;
struct ImGuiColMod // Color modifier, backup of modified data so we can restore it
struct ImGuiColMod // Color modifier, backup of modified data so we can restore it
{
{
ImGuiCol Col ;
ImGuiCol Col ;
@ -1277,6 +1291,7 @@ struct ImGuiWindow
bool Accessed ; // Set to true when any widget access the current window
bool Accessed ; // Set to true when any widget access the current window
bool Collapsed ; // Set when collapsing window to become only title-bar
bool Collapsed ; // Set when collapsing window to become only title-bar
bool SkipItems ; // == Visible && !Collapsed
bool SkipItems ; // == Visible && !Collapsed
int BeginCount ; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
int AutoFitFrames ;
int AutoFitFrames ;
bool AutoFitOnlyGrows ;
bool AutoFitOnlyGrows ;
int AutoPosLastDirection ;
int AutoPosLastDirection ;
@ -1636,6 +1651,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
Accessed = false ;
Accessed = false ;
Collapsed = false ;
Collapsed = false ;
SkipItems = false ;
SkipItems = false ;
BeginCount = 0 ;
AutoFitFrames = - 1 ;
AutoFitFrames = - 1 ;
AutoFitOnlyGrows = false ;
AutoFitOnlyGrows = false ;
AutoPosLastDirection = - 1 ;
AutoPosLastDirection = - 1 ;
@ -1868,7 +1884,6 @@ static void SaveSettings()
static void MarkSettingsDirty ( )
static void MarkSettingsDirty ( )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
if ( g . SettingsDirtyTimer < = 0.0f )
if ( g . SettingsDirtyTimer < = 0.0f )
g . SettingsDirtyTimer = g . IO . IniSavingRate ;
g . SettingsDirtyTimer = g . IO . IniSavingRate ;
}
}
@ -2981,7 +2996,7 @@ void ImGui::EndChild()
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
IM_ASSERT ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ;
IM_ASSERT ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ;
if ( window - > Flags & ImGuiWindowFlags_ComboBox )
if ( ( window - > Flags & ImGuiWindowFlags_ComboBox ) | | window - > BeginCount > 1 )
{
{
ImGui : : End ( ) ;
ImGui : : End ( ) ;
}
}
@ -3218,21 +3233,19 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
if ( first_begin_of_the_frame )
if ( first_begin_of_the_frame )
{
{
window - > Active = true ;
window - > Active = true ;
window - > BeginCount = 0 ;
window - > DrawList - > Clear ( ) ;
window - > DrawList - > Clear ( ) ;
window - > ClipRectStack . resize ( 0 ) ;
window - > ClipRectStack . resize ( 0 ) ;
window - > LastFrameDrawn = current_frame ;
window - > LastFrameDrawn = current_frame ;
window - > IDStack . resize ( 1 ) ;
window - > IDStack . resize ( 1 ) ;
}
// Setup texture, outer clipping rectangle
// Setup texture, outer clipping rectangle
window - > DrawList - > PushTextureID ( g . Font - > ContainerAtlas - > TexID ) ;
window - > DrawList - > PushTextureID ( g . Font - > ContainerAtlas - > TexID ) ;
if ( ( flags & ImGuiWindowFlags_ChildWindow ) & & ! ( flags & ImGuiWindowFlags_ComboBox ) )
if ( ( flags & ImGuiWindowFlags_ChildWindow ) & & ! ( flags & ImGuiWindowFlags_ComboBox ) )
PushClipRect ( parent_window - > ClipRectStack . back ( ) ) ;
PushClipRect ( parent_window - > ClipRectStack . back ( ) ) ;
else
else
PushClipRect ( GetVisibleRect ( ) ) ;
PushClipRect ( GetVisibleRect ( ) ) ;
if ( first_begin_of_the_frame )
{
// New windows appears in front
// New windows appears in front
if ( ! window_was_visible )
if ( ! window_was_visible )
{
{
@ -3431,7 +3444,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
const ImRect resize_rect ( window - > Rect ( ) . GetBR ( ) - ImVec2 ( 14 , 14 ) , window - > Rect ( ) . GetBR ( ) ) ;
const ImRect resize_rect ( window - > Rect ( ) . GetBR ( ) - ImVec2 ( 14 , 14 ) , window - > Rect ( ) . GetBR ( ) ) ;
const ImGuiID resize_id = window - > GetID ( " #RESIZE " ) ;
const ImGuiID resize_id = window - > GetID ( " #RESIZE " ) ;
bool hovered , held ;
bool hovered , held ;
ButtonBehavior ( resize_rect , resize_id , & hovered , & held , true );
ButtonBehavior ( resize_rect , resize_id , & hovered , & held , true , ImGuiButtonFlags_FlattenChilds );
resize_col = window - > Color ( held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip ) ;
resize_col = window - > Color ( held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip ) ;
if ( hovered | | held )
if ( hovered | | held )
@ -3584,6 +3597,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
ImGui : : LogToClipboard ( ) ;
ImGui : : LogToClipboard ( ) ;
*/
*/
}
}
window - > BeginCount + + ;
// Inner clipping rectangle
// Inner clipping rectangle
// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
@ -3628,8 +3642,6 @@ void ImGui::End()
ImGui : : Columns ( 1 , " #CloseColumns " ) ;
ImGui : : Columns ( 1 , " #CloseColumns " ) ;
PopClipRect ( ) ; // inner window clip rectangle
PopClipRect ( ) ; // inner window clip rectangle
PopClipRect ( ) ; // outer window clip rectangle
window - > DrawList - > PopTextureID ( ) ;
// Stop logging
// Stop logging
if ( ! ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ) // FIXME: add more options for scope of logging
if ( ! ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ) // FIXME: add more options for scope of logging
@ -3782,7 +3794,6 @@ float ImGui::CalcItemWidth()
static void SetFont ( ImFont * font )
static void SetFont ( ImFont * font )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
IM_ASSERT ( font & & font - > IsLoaded ( ) ) ;
IM_ASSERT ( font & & font - > IsLoaded ( ) ) ;
IM_ASSERT ( font - > Scale > 0.0f ) ;
IM_ASSERT ( font - > Scale > 0.0f ) ;
g . Font = font ;
g . Font = font ;
@ -3794,10 +3805,8 @@ static void SetFont(ImFont* font)
void ImGui : : PushFont ( ImFont * font )
void ImGui : : PushFont ( ImFont * font )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
if ( ! font )
if ( ! font )
font = g . IO . Fonts - > Fonts [ 0 ] ;
font = g . IO . Fonts - > Fonts [ 0 ] ;
SetFont ( font ) ;
SetFont ( font ) ;
g . FontStack . push_back ( font ) ;
g . FontStack . push_back ( font ) ;
g . CurrentWindow - > DrawList - > PushTextureID ( font - > ContainerAtlas - > TexID ) ;
g . CurrentWindow - > DrawList - > PushTextureID ( font - > ContainerAtlas - > TexID ) ;
@ -3806,7 +3815,6 @@ void ImGui::PushFont(ImFont* font)
void ImGui : : PopFont ( )
void ImGui : : PopFont ( )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
g . CurrentWindow - > DrawList - > PopTextureID ( ) ;
g . CurrentWindow - > DrawList - > PopTextureID ( ) ;
g . FontStack . pop_back ( ) ;
g . FontStack . pop_back ( ) ;
SetFont ( g . FontStack . empty ( ) ? g . IO . Fonts - > Fonts [ 0 ] : g . FontStack . back ( ) ) ;
SetFont ( g . FontStack . empty ( ) ? g . IO . Fonts - > Fonts [ 0 ] : g . FontStack . back ( ) ) ;
@ -3839,7 +3847,6 @@ void ImGui::PopTextWrapPos()
void ImGui : : PushStyleColor ( ImGuiCol idx , const ImVec4 & col )
void ImGui : : PushStyleColor ( ImGuiCol idx , const ImVec4 & col )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
ImGuiColMod backup ;
ImGuiColMod backup ;
backup . Col = idx ;
backup . Col = idx ;
backup . PreviousValue = g . Style . Colors [ idx ] ;
backup . PreviousValue = g . Style . Colors [ idx ] ;
@ -3850,7 +3857,6 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
void ImGui : : PopStyleColor ( int count )
void ImGui : : PopStyleColor ( int count )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
while ( count > 0 )
while ( count > 0 )
{
{
ImGuiColMod & backup = g . ColorModifiers . back ( ) ;
ImGuiColMod & backup = g . ColorModifiers . back ( ) ;
@ -3891,7 +3897,6 @@ static ImVec2* GetStyleVarVec2Addr(ImGuiStyleVar idx)
void ImGui : : PushStyleVar ( ImGuiStyleVar idx , float val )
void ImGui : : PushStyleVar ( ImGuiStyleVar idx , float val )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
float * pvar = GetStyleVarFloatAddr ( idx ) ;
float * pvar = GetStyleVarFloatAddr ( idx ) ;
IM_ASSERT ( pvar ! = NULL ) ; // Called function with wrong-type? Variable is not a float.
IM_ASSERT ( pvar ! = NULL ) ; // Called function with wrong-type? Variable is not a float.
ImGuiStyleMod backup ;
ImGuiStyleMod backup ;
@ -3905,7 +3910,6 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
void ImGui : : PushStyleVar ( ImGuiStyleVar idx , const ImVec2 & val )
void ImGui : : PushStyleVar ( ImGuiStyleVar idx , const ImVec2 & val )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
ImVec2 * pvar = GetStyleVarVec2Addr ( idx ) ;
ImVec2 * pvar = GetStyleVarVec2Addr ( idx ) ;
IM_ASSERT ( pvar ! = NULL ) ; // Called function with wrong-type? Variable is not a ImVec2.
IM_ASSERT ( pvar ! = NULL ) ; // Called function with wrong-type? Variable is not a ImVec2.
ImGuiStyleMod backup ;
ImGuiStyleMod backup ;
@ -3918,7 +3922,6 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
void ImGui : : PopStyleVar ( int count )
void ImGui : : PopStyleVar ( int count )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
while ( count > 0 )
while ( count > 0 )
{
{
ImGuiStyleMod & backup = g . StyleModifiers . back ( ) ;
ImGuiStyleMod & backup = g . StyleModifiers . back ( ) ;
@ -4521,10 +4524,9 @@ void ImGui::LabelText(const char* label, const char* fmt, ...)
static inline bool IsWindowContentHoverable ( ImGuiWindow * window )
static inline bool IsWindowContentHoverable ( ImGuiWindow * window )
{
{
ImGuiState & g = * GImGui ;
// An active popup disable hovering on other windows (apart from its own children)
// An active popup disable hovering on other windows (apart from its own children)
if ( ImGuiWindow * focused_window = g . FocusedWindow )
ImGuiState & g = * GImGui ;
if ( ImGuiWindow * focused_window = g . FocusedWindow )
if ( ImGuiWindow * focused_root_window = focused_window - > RootWindow )
if ( ImGuiWindow * focused_root_window = focused_window - > RootWindow )
if ( ( focused_root_window - > Flags & ImGuiWindowFlags_Popup ) ! = 0 & & focused_root_window - > WasActive & & focused_root_window ! = window - > RootWindow )
if ( ( focused_root_window - > Flags & ImGuiWindowFlags_Popup ) ! = 0 & & focused_root_window - > WasActive & & focused_root_window ! = window - > RootWindow )
return false ;
return false ;
@ -4532,13 +4534,13 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window)
return true ;
return true ;
}
}
static bool IsHovered ( const ImRect & bb , ImGuiID id )
static bool IsHovered ( const ImRect & bb , ImGuiID id , bool flatten_childs = false )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
if ( g . HoveredId = = 0 )
if ( g . HoveredId = = 0 )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( g . Hovered RootWindow = = window - > RootWindow )
if ( g . Hovered Window = = window | | ( flatten_childs & & g . Hovered RootWindow = = window - > RootWindow ) )
if ( ( g . ActiveId = = 0 | | g . ActiveId = = id | | g . ActiveIdIsFocusedOnly ) & & IsMouseHoveringRect ( bb ) )
if ( ( g . ActiveId = = 0 | | g . ActiveId = = id | | g . ActiveIdIsFocusedOnly ) & & IsMouseHoveringRect ( bb ) )
if ( IsWindowContentHoverable ( g . HoveredRootWindow ) )
if ( IsWindowContentHoverable ( g . HoveredRootWindow ) )
return true ;
return true ;
@ -4546,13 +4548,13 @@ static bool IsHovered(const ImRect& bb, ImGuiID id)
return false ;
return false ;
}
}
static bool ButtonBehavior ( const ImRect & bb , ImGuiID id , bool * out_hovered , bool * out_held , bool allow_key_modifiers , bool repeat , bool pressed_on_click )
static bool ButtonBehavior ( const ImRect & bb , ImGuiID id , bool * out_hovered , bool * out_held , bool allow_key_modifiers , ImGuiButtonFlags flags )
{
{
ImGuiState & g = * GImGui ;
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
const bool hovered = IsHovered ( bb , id ) ;
bool pressed = false ;
bool pressed = false ;
const bool hovered = IsHovered ( bb , id , ( flags & ImGuiButtonFlags_FlattenChilds ) ! = 0 ) ;
if ( hovered )
if ( hovered )
{
{
g . HoveredId = id ;
g . HoveredId = id ;
@ -4560,7 +4562,7 @@ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
{
if ( g . IO . MouseClicked [ 0 ] )
if ( g . IO . MouseClicked [ 0 ] )
{
{
if ( pressed_on_c lick)
if ( flags & ImGuiButtonFlags_PressedOnC lick)
{
{
pressed = true ;
pressed = true ;
SetActiveId ( 0 ) ;
SetActiveId ( 0 ) ;
@ -4571,7 +4573,7 @@ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
}
}
FocusWindow ( window ) ;
FocusWindow ( window ) ;
}
}
else if ( repeat & & g . ActiveI d & & ImGui : : IsMouseClicked ( 0 , true ) )
else if ( ( flags & ImGuiButtonFlags_Repeat ) & & g . ActiveI d = = i d & & ImGui : : IsMouseClicked ( 0 , true ) )
{
{
pressed = true ;
pressed = true ;
}
}
@ -4617,7 +4619,7 @@ bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_h
return false ;
return false ;
bool hovered , held ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , true , repeat_when_held ) ;
bool pressed = ButtonBehavior ( bb , id , & hovered , & held , true , repeat_when_held ? ImGuiButtonFlags_Repeat : 0 ) ;
// Render
// Render
const ImU32 col = window - > Color ( ( hovered & & held ) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button ) ;
const ImU32 col = window - > Color ( ( hovered & & held ) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button ) ;
@ -6801,7 +6803,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
// Draw blinking cursor
// Draw blinking cursor
if ( g . InputTextState . CursorIsVisible ( ) )
if ( g . InputTextState . CursorIsVisible ( ) )
window - > DrawList - > Add Rect ( cursor_pos - font_off_up + ImVec2 ( 0 , 2 ) , cursor_pos + font_off_dn - ImVec2 ( 0 , 3 ) , window - > Color ( ImGuiCol_Text ) ) ;
window - > DrawList - > Add Line ( cursor_pos - font_off_up + ImVec2 ( 0 , 2 ) , cursor_pos + font_off_dn - ImVec2 ( 0 , 3 ) , window - > Color ( ImGuiCol_Text ) ) ;
// Notify OS of text input position for advanced IME
// Notify OS of text input position for advanced IME
if ( io . ImeSetInputScreenPosFn & & ImLengthSqr ( edit_state . InputCursorScreenPos - cursor_pos ) > 0.0001f )
if ( io . ImeSetInputScreenPosFn & & ImLengthSqr ( edit_state . InputCursorScreenPos - cursor_pos ) > 0.0001f )
@ -7093,7 +7095,7 @@ bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg)
return false ;
return false ;
bool hovered , held ;
bool hovered , held ;
bool pressed = ButtonBehavior ( bb_with_spacing , id , & hovered , & held , true , false , false );
bool pressed = ButtonBehavior ( bb_with_spacing , id , & hovered , & held , true );
// Render
// Render
if ( hovered | | selected )
if ( hovered | | selected )
@ -8005,7 +8007,11 @@ void ImDrawList::UpdateClipRect()
}
}
else
else
{
{
current_cmd - > clip_rect = clip_rect_stack . empty ( ) ? GNullClipRect : clip_rect_stack . back ( ) ;
ImVec4 current_clip_rect = clip_rect_stack . empty ( ) ? GNullClipRect : clip_rect_stack . back ( ) ;
if ( commands . size ( ) > 2 & & ImLengthSqr ( commands [ commands . size ( ) - 2 ] . clip_rect - current_clip_rect ) < 0.00001f )
commands . pop_back ( ) ;
else
current_cmd - > clip_rect = current_clip_rect ;
}
}
}
}