@ -1,4 +1,4 @@
// ImGui library v1.4 0 WIP
// ImGui library v1.4 1 WIP
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui
@ -142,11 +142,13 @@
Occasionally introducing changes that are breaking the API . The breakage are generally minor and easy to fix .
Here is a change - log of API breaking changes , if you are using one of the functions listed , expect to have to fix some code .
- 2015 / 05 / 31 ( 1.39 ) - renamed GetWindowCollapsed ( ) to IsWindowCollapsed ( ) for consistency . Kept inline redirection function ( will obsolete ) .
- 2015 / 05 / 31 ( 1.39 ) - renamed IsRectClipped ( ) to IsRectVisible ( ) for consistency . Note that return value is opposite ! Kept inline redirection function ( will obsolete ) .
- 2015 / 05 / 27 ( 1.39 ) - removed the third ' repeat_if_held ' parameter from Button ( ) - sorry ! it was rarely used and inconsistent . Use PushButtonRepeat ( true ) / PopButtonRepeat ( ) to enable repeat on desired buttons .
- 2015 / 05 / 11 ( 1.39 ) - changed BeginPopup ( ) API , takes a string identifier instead of a bool . ImGui needs to manage the open / closed state of popups . Call OpenPopup ( ) to actually set the " opened " state of a popup . BeginPopup ( ) returns true if the popup is opened .
- 2015 / 05 / 03 ( 1.39 ) - removed style . AutoFitPadding , using style . WindowPadding makes more sense ( the default values were already the same ) .
- 2015 / 06 / 14 ( 1.41 ) - changed ImageButton ( ) default bg_col parameter from ( 0 , 0 , 0 , 1 ) ( black ) to ( 0 , 0 , 0 , 0 ) ( transparent ) - makes a difference when texture have transparence
- 2015 / 06 / 14 ( 1.41 ) - changed Selectable ( ) API from ( label , selected , size ) to ( label , selected , flags , size ) . Size override should have been rarely be used . Sorry !
- 2015 / 05 / 31 ( 1.40 ) - renamed GetWindowCollapsed ( ) to IsWindowCollapsed ( ) for consistency . Kept inline redirection function ( will obsolete ) .
- 2015 / 05 / 31 ( 1.40 ) - renamed IsRectClipped ( ) to IsRectVisible ( ) for consistency . Note that return value is opposite ! Kept inline redirection function ( will obsolete ) .
- 2015 / 05 / 27 ( 1.40 ) - removed the third ' repeat_if_held ' parameter from Button ( ) - sorry ! it was rarely used and inconsistent . Use PushButtonRepeat ( true ) / PopButtonRepeat ( ) to enable repeat on desired buttons .
- 2015 / 05 / 11 ( 1.40 ) - changed BeginPopup ( ) API , takes a string identifier instead of a bool . ImGui needs to manage the open / closed state of popups . Call OpenPopup ( ) to actually set the " opened " state of a popup . BeginPopup ( ) returns true if the popup is opened .
- 2015 / 05 / 03 ( 1.40 ) - removed style . AutoFitPadding , using style . WindowPadding makes more sense ( the default values were already the same ) .
- 2015 / 04 / 13 ( 1.38 ) - renamed IsClipped ( ) to IsRectClipped ( ) . Kept inline redirection function ( will obsolete ) .
- 2015 / 04 / 09 ( 1.38 ) - renamed ImDrawList : : AddArc ( ) to ImDrawList : : AddArcFast ( ) for compatibility with future API
- 2015 / 04 / 03 ( 1.38 ) - removed ImGuiCol_CheckHovered , ImGuiCol_CheckActive , replaced with the more general ImGuiCol_FrameBgHovered , ImGuiCol_FrameBgActive .
@ -338,12 +340,16 @@
- window : allow resizing of child windows ( possibly given min / max for each axis ? )
- window : background options for child windows , border option ( disable rounding )
- window : resizing from any sides ? + mouse cursor directives for app .
- scrolling : add horizontal scroll
! - scrolling : set scrolling given a position .
! - scrolling : allow immediately effective change of scroll if we haven ' t appended items yet
- widgets : display mode : widget - label , label - widget ( aligned on column or using fixed size ) , label - newline - tab - widget etc .
- widgets : clean up widgets internal toward exposing everything .
- main : considering adding EndFrame ( ) / Init ( ) . some constructs are awkward in the implementation because of the lack of them .
- main : IsItemHovered ( ) make it more consistent for various type of widgets , widgets with multiple components , etc . also effectively IsHovered ( ) region sometimes differs from hot region , e . g tree nodes
- main : IsItemHovered ( ) info stored in a stack ? so that ' if TreeNode ( ) { Text ; TreePop ; } if IsHovered ' return the hover state of the TreeNode ?
- input text : add ImGuiInputTextFlags_EnterToApply ? ( off github issue # 218 )
! - input text : multiple lines inputs ( # 200 )
! - input number : large int not reliably supported because of int < > float conversions .
- input number : optional range min / max for Input * ( ) functions
- input number : holding [ - ] / [ + ] buttons could increase the step speed non - linearly ( or user - controlled )
@ -364,8 +370,12 @@
- combo / listbox : keyboard control . need inputtext like non - active focus + key handling . considering keybord for custom listbox ( see github pr # 203 )
- listbox : multiple selection
- listbox : user may want to initial scroll to focus on the one selected value ?
- listbox : keyboard navigation .
- listbox : scrolling should track modified selection .
- menus : local shortcuts , global shortcuts ( github issue # 126 )
- menus : icons
- menus : see we can allow for click - menu - hold - release - on - item to work ( like Windows does )
- menus : menubars : some sort of priority / effect of main menu - bar on desktop size ?
- tabs
- separator : separator on the initial position of a window is not visible ( cursorpos . y < = clippos . y )
- gauge : various forms of gauge / loading bars widgets
@ -386,7 +396,7 @@
- tooltip : figure out a way to use TextWrapped ( ) in a tooltip .
- settings : write more decent code to allow saving / loading new fields
- settings : api for per - tool simple persistent data ( bool , int , float , columns sizes , etc . ) in . ini file
! style : store rounded corners in texture to use 1 quad per corner ( filled and wireframe ) . so rounding have minor cost .
- style : store rounded corners in texture to use 1 quad per corner ( filled and wireframe ) . so rounding have minor cost .
- style : checkbox : padding for " active " color should be a multiplier of the
- style : colorbox not always square ?
- text : simple markup language for color change ?
@ -397,7 +407,7 @@
- filters : set a current filter that tree node can automatically query to hide themselves
- filters : handle wildcards ( with implicit leading / trailing * ) , regexps
- shortcuts : add a shortcut api , e . g . parse " &Save " and / or " Save (CTRL+S) " , pass in to widgets or provide simple ways to use ( button = activate , input = focus )
! keyboard : tooltip & combo boxes are messing up / not honoring keyboard tabbing
! - keyboard : tooltip & combo boxes are messing up / not honoring keyboard tabbing
- keyboard : full keyboard navigation and focus .
- input : rework IO to be able to pass actual events to fix temporal aliasing issues .
- input : support track pad style scrolling & slider edit .
@ -517,7 +527,6 @@ struct ImGuiState;
struct ImGuiWindow ;
typedef int ImGuiLayoutType ; // enum ImGuiLayoutType_
typedef int ImGuiButtonFlags ; // enum ImGuiButtonFlags_
typedef int ImGuiSelectableFlags ; // enum ImGuiSelectableFlags_
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 ) ;
@ -978,18 +987,19 @@ enum ImGuiLayoutType_
enum ImGuiButtonFlags_
{
ImGuiButtonFlags_Repeat = ( 1 < < 0 ) ,
ImGuiButtonFlags_PressedOnClick = ( 1 < < 1 ) ,
ImGuiButtonFlags_FlattenChilds = ( 1 < < 2 ) ,
ImGuiButtonFlags_DontClosePopups = ( 1 < < 3 ) ,
ImGuiButtonFlags_Disabled = ( 1 < < 4 )
ImGuiButtonFlags_Repeat = 1 < < 0 ,
ImGuiButtonFlags_PressedOnClick = 1 < < 1 ,
ImGuiButtonFlags_FlattenChilds = 1 < < 2 ,
ImGuiButtonFlags_DontClosePopups = 1 < < 3 ,
ImGuiButtonFlags_Disabled = 1 < < 4
} ;
enum ImGuiSelectableFlags _
enum ImGuiSelectableFlags Private _
{
ImGuiSelectableFlags_MenuItem = ( 1 < < 0 ) ,
ImGuiSelectableFlags_DontClosePopups = ( 1 < < 1 ) ,
ImGuiSelectableFlags_Disabled = ( 1 < < 2 )
// NB: need to be in sync with last value of ImGuiSelectableFlags_
ImGuiSelectableFlags_MenuItem = 1 < < 2 ,
ImGuiSelectableFlags_Disabled = 1 < < 3 ,
ImGuiSelectableFlags_DrawFillAvailWidth = 1 < < 4
} ;
@ -1300,7 +1310,6 @@ struct ImGuiState
ImGuiTextEditState InputTextState ;
ImGuiID ScalarAsInputTextId ; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiStorage ColorEditModeStorage ; // Store user selection of color edit mode
ImGuiID ActiveComboID ;
ImVec2 ActiveClickDeltaToCenter ;
float DragCurrentValue ; // current dragged value, always float, not rounded by end-user precision settings
ImVec2 DragLastMouseDelta ;
@ -1361,7 +1370,6 @@ struct ImGuiState
SetNextTreeNodeOpenedCond = 0 ;
ScalarAsInputTextId = 0 ;
ActiveComboID = 0 ;
ActiveClickDeltaToCenter = ImVec2 ( 0.0f , 0.0f ) ;
DragCurrentValue = 0.0f ;
DragLastMouseDelta = ImVec2 ( 0.0f , 0.0f ) ;
@ -1401,7 +1409,7 @@ struct ImGuiWindow
ImVec2 SizeContents ; // Size of contents (== extents reach of the drawing cursor) from previous frame
ImGuiID MoveID ; // == window->GetID("#MOVE")
float ScrollY ;
float Next ScrollY;
float ScrollTargetCenter Y; // position which we aim to center on
bool ScrollbarY ;
bool Active ; // Set to true on Begin()
bool WasActive ;
@ -1767,7 +1775,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
Size = SizeFull = ImVec2 ( 0.0f , 0.0f ) ;
SizeContents = ImVec2 ( 0.0f , 0.0f ) ;
ScrollY = 0.0f ;
NextScrollY = 0 .0f;
ScrollTargetCenterY = - 1 .0f;
ScrollbarY = false ;
Active = WasActive = false ;
Accessed = false ;
@ -2193,7 +2201,7 @@ void ImGui::NewFrame()
if ( ! ( window - > Flags & ImGuiWindowFlags_NoScrollWithMouse ) )
{
const int scroll_lines = ( window - > Flags & ImGuiWindowFlags_ComboBox ) ? 3 : 5 ;
window - > Next ScrollY - = g . IO . MouseWheel * window - > CalcFontSize ( ) * scroll_lines ;
window - > ScrollY - = g . IO . MouseWheel * window - > CalcFontSize ( ) * scroll_lines ;
}
}
}
@ -2701,7 +2709,7 @@ static void RenderCheckMark(ImVec2 pos, ImU32 col)
a . x = pos . x + start_x ;
b . x = a . x + rem_third ;
c . x = a . x + rem_third * 3.0f ;
b . y = pos . y + ( float ) ( int ) ( g . Font - > BaseLine * ( g . FontSize / g . Font - > FontSize ) + 0.5f ) + ( float ) ( int ) ( g . Font - > DisplayOffset . y ) ;
b . y = pos . y + ( float ) ( int ) ( g . Font - > Ascent * ( g . FontSize / g . Font - > FontSize ) + 0.5f ) + ( float ) ( int ) ( g . Font - > DisplayOffset . y ) ;
a . y = b . y - rem_third ;
c . y = b . y - rem_third * 2.0f ;
@ -3124,6 +3132,14 @@ static void ClosePopupToLevel(int remaining)
g . OpenedPopupStack . resize ( remaining ) ;
}
static void ClosePopup ( ImGuiID id )
{
if ( ! IsPopupOpen ( id ) )
return ;
ImGuiState & g = * GImGui ;
ClosePopupToLevel ( g . OpenedPopupStack . size ( ) - 1 ) ;
}
// Close the popup we have begin-ed into.
void ImGui : : CloseCurrentPopup ( )
{
@ -3154,7 +3170,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
}
ImGui : : PushStyleVar ( ImGuiStyleVar_WindowRounding , 0.0f ) ;
ImGuiWindowFlags flags = extra_flags | ImGuiWindowFlags_Popup | ImGuiWindowFlags_ ShowBorders| ImGuiWindowFlags_ NoTitleBar| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize ;
ImGuiWindowFlags flags = extra_flags | ImGuiWindowFlags_Popup | ImGuiWindowFlags_ NoTitleBar| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize ;
char name [ 32 ] ;
if ( flags & ImGuiWindowFlags_ChildMenu )
@ -3174,7 +3190,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
bool ImGui : : BeginPopup ( const char * str_id )
{
return BeginPopupEx ( str_id , 0 ) ;
return BeginPopupEx ( str_id , ImGuiWindowFlags_ShowBorders ) ;
}
void ImGui : : EndPopup ( )
@ -3466,7 +3482,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
}
// Process SetNextWindow***() calls
bool window_pos_set_by_api = false ;
bool window_pos_set_by_api = false , window_size_set_by_api = false ;
if ( g . SetNextWindowPosCond )
{
const ImVec2 backup_cursor_pos = window - > DC . CursorPos ; // FIXME: not sure of the exact reason of this anymore :( need to look into that.
@ -3479,6 +3495,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
if ( g . SetNextWindowSizeCond )
{
if ( ! window_was_visible ) window - > SetWindowSizeAllowFlags | = ImGuiSetCond_Appearing ;
window_size_set_by_api = ( window - > SetWindowSizeAllowFlags & g . SetNextWindowSizeCond ) ! = 0 ;
ImGui : : SetWindowSize ( g . SetNextWindowSizeVal , g . SetNextWindowSizeCond ) ;
g . SetNextWindowSizeCond = 0 ;
}
@ -3570,7 +3587,9 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
if ( ( flags & ( ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip ) ) ! = 0 & & ! window_was_visible )
{
window - > HiddenFrames = 1 ;
window - > Size = window - > SizeFull = window - > SizeContents = ImVec2 ( 0.f , 0.f ) ; // TODO: We don't support SetNextWindowSize() for tooltips or popups yet
if ( ! window_size_set_by_api )
window - > Size = window - > SizeFull = ImVec2 ( 0.f , 0.f ) ;
window - > SizeContents = ImVec2 ( 0.f , 0.f ) ;
}
// Calculate auto-fit size
@ -3600,11 +3619,11 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
}
else
{
if ( flags & ImGuiWindowFlags_AlwaysAutoResize )
if ( ( flags & ImGuiWindowFlags_AlwaysAutoResize ) & & ! window_size_set_by_api )
{
window - > SizeFull = size_auto_fit ;
}
else if ( window - > AutoFitFrames > 0 )
else if ( window - > AutoFitFrames > 0 & & ! window_size_set_by_api )
{
// Auto-fit only grows during the first few frames
window - > SizeFull = window - > AutoFitOnlyGrows ? ImMax ( window - > SizeFull , size_auto_fit ) : size_auto_fit ;
@ -3704,11 +3723,14 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
window - > FocusIdxAllRequestNext = window - > FocusIdxTabRequestNext = IM_INT_MAX ;
// Apply scrolling
window - > ScrollY = window - > NextScrollY ;
if ( window - > ScrollTargetCenterY > = 0.0f )
{
window - > ScrollY = window - > ScrollTargetCenterY - ( window - > Pos . y + ( window - > SizeFull . y + window - > TitleBarHeight ( ) + window - > WindowPadding ( ) . y ) * 0.5f ) ;
window - > ScrollTargetCenterY = - 1.0f ;
}
window - > ScrollY = ImMax ( window - > ScrollY , 0.0f ) ;
if ( ! window - > Collapsed & & ! window - > SkipItems )
window - > ScrollY = ImMin ( window - > ScrollY , ImMax ( 0.0f , window - > SizeContents . y - window - > SizeFull . y ) ) ;
window - > NextScrollY = window - > ScrollY ;
// Draw window + handle manual resize
ImRect title_bar_rect = window - > TitleBarRect ( ) ;
@ -3998,7 +4020,6 @@ static void Scrollbar(ImGuiWindow* window)
// Apply scroll
const float scroll_y_norm = ImSaturate ( ( clicked_y_norm - g . ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f ) / ( 1.0f - grab_h_norm ) ) ;
window - > ScrollY = ( float ) ( int ) ( 0.5f + scroll_y_norm * ( window - > SizeContents . y - window - > Size . y ) ) ;
window - > NextScrollY = window - > ScrollY ;
// Update values for rendering
scroll_ratio = ImSaturate ( window - > ScrollY / scroll_max ) ;
@ -4303,36 +4324,43 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
return " Unknown " ;
}
bool ImGui : : IsWindowHovered ( )
{
ImGuiState & g = * GImGui ;
return g . HoveredWindow = = g . CurrentWindow ;
}
bool ImGui : : IsWindowFocused ( )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
return g . FocusedWindow = = window ;
return g . FocusedWindow = = g . CurrentWindow ;
}
bool ImGui : : IsRootWindowFocused ( )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * root_window = GetCurrentWindow( ) - > RootWindow ;
ImGuiWindow * root_window = g. CurrentWindow - > RootWindow ;
return g . FocusedWindow = = root_window ;
}
bool ImGui : : IsRootWindowOrAnyChildFocused ( )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * root_window = GetCurrentWindow( ) - > RootWindow ;
ImGuiWindow * root_window = g. CurrentWindow - > RootWindow ;
return g . FocusedWindow & & g . FocusedWindow - > RootWindow = = root_window ;
}
float ImGui : : GetWindowWidth ( )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiState & g = * GImGui ;
ImGuiWindow * window = g . CurrentWindow ;
return window - > Size . x ;
}
ImVec2 ImGui : : GetWindowPos ( )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiState & g = * GImGui ;
ImGuiWindow * window = g . CurrentWindow ;
return window - > Pos ;
}
@ -4621,7 +4649,7 @@ float ImGui::GetScrollMaxY()
void ImGui : : SetScrollPosHere ( )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
window - > Next ScrollY = ( window - > DC . CursorPos . y + window - > ScrollY ) - ( window - > Pos . y + window - > SizeFull . y * 0.5f ) - ( window - > TitleBarHeight ( ) + window - > WindowPadding ( ) . y ) ;
window - > ScrollTargetCenter Y = ( float ) ( int ) ( window - > DC . CursorPos . y + window - > ScrollY - window - > DC . PrevLineHeight * 0.5f ) ;
}
void ImGui : : SetKeyboardFocusHere ( int offset )
@ -5083,7 +5111,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
const ImGuiStyle & style = g . Style ;
// Default to using texture ID as ID. User can still push string/integer prefixes.
// We could hash the size/uv to create a unique ID but that would prevent the user from animating buttons .
// We could hash the size/uv to create a unique ID but that would prevent the user from animating UV .
ImGui : : PushID ( ( void * ) user_texture_id ) ;
const ImGuiID id = window - > GetID ( " #image " ) ;
ImGui : : PopID ( ) ;
@ -5100,8 +5128,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
// Render
const ImU32 col = window - > Color ( ( hovered & & held ) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button ) ;
if ( padding . x > 0.0f | | padding . y > 0.0f )
RenderFrame ( bb . Min , bb . Max , col ) ;
RenderFrame ( bb . Min , bb . Max , col ) ;
if ( bg_col . w > 0.0f )
window - > DrawList - > AddRectFilled ( image_bb . Min , image_bb . Max , window - > Color ( bg_col ) ) ;
window - > DrawList - > AddImage ( user_texture_id , image_bb . Min , image_bb . Max , uv0 , uv1 , window - > Color ( tint_col ) ) ;
@ -5615,13 +5642,15 @@ static inline float RoundScalar(float value, int decimal_precision)
// 0: 1, 1: 0.1, 2: 0.01, etc.
// So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
// FIXME: Investigate better rounding methods
const float min_step = 1.0f / powf ( 10.0f , ( float ) decimal_precision ) ;
const float remainder = fmodf ( value , min_step ) ;
float min_step = 1.0f / powf ( 10.0f , ( float ) decimal_precision ) ;
bool negative = value < 0.0f ;
value = fabsf ( value ) ;
float remainder = fmodf ( value , min_step ) ;
if ( remainder < = min_step * 0.5f )
value - = remainder ;
else
value + = ( min_step - remainder ) ;
return value;
return negative ? - value : value;
}
static bool SliderScalarBehavior ( const ImRect & frame_bb , ImGuiID id , float * v , float v_min , float v_max , float power , int decimal_precision , bool horizontal )
@ -5704,7 +5733,6 @@ static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, f
// Round past decimal precision
new_value = RoundScalar ( new_value , decimal_precision ) ;
if ( * v ! = new_value )
{
* v = new_value ;
@ -7270,7 +7298,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char** items, int
bool ImGui : : Combo ( const char * label , int * current_item , const char * items_separated_by_zeros , int height_in_items )
{
int items_count = 0 ;
const char * p = items_separated_by_zeros ; // FIXME-OPT: Avoid computing this
const char * p = items_separated_by_zeros ; // FIXME-OPT: Avoid computing this , or at least only when combo is open
while ( * p )
{
p + = strlen ( p ) + 1 ;
@ -7302,7 +7330,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
const float arrow_size = ( g . FontSize + style . FramePadding . x * 2.0f ) ;
const bool hovered = IsHovered ( frame_bb , id ) ;
bool value_changed = false ;
const ImRect value_bb ( frame_bb . Min , frame_bb . Max - ImVec2 ( arrow_size , 0.0f ) ) ;
RenderFrame ( frame_bb . Min , frame_bb . Max , window - > Color ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
RenderFrame ( ImVec2 ( frame_bb . Max . x - arrow_size , frame_bb . Min . y ) , frame_bb . Max , window - > Color ( hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button ) , true , style . FrameRounding ) ; // FIXME-ROUNDING
@ -7318,80 +7345,81 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
if ( label_size . x > 0 )
RenderText ( ImVec2 ( frame_bb . Max . x + style . ItemInnerSpacing . x , frame_bb . Min . y + style . FramePadding . y ) , label ) ;
ImGui : : PushID ( ( int ) id ) ;
bool menu_toggled = false ;
if ( hovered )
{
g . HoveredId = id ;
if ( g . IO . MouseClicked [ 0 ] )
{
menu_toggled = true ;
g . ActiveComboID = ( g . ActiveComboID = = id ) ? 0 : id ;
if ( g . ActiveComboID )
FocusWindow ( window ) ;
SetActiveId ( 0 ) ;
if ( IsPopupOpen ( id ) )
{
ClosePopup ( id ) ;
}
else
{
FocusWindow ( window ) ;
ImGui : : OpenPopup ( label ) ;
menu_toggled = true ;
}
}
}
if ( g . ActiveComboID = = id )
bool value_changed = false ;
if ( IsPopupOpen ( id ) )
{
// Size default to hold ~7 items
if ( height_in_items < 0 )
height_in_items = 7 ;
const ImVec2 backup_pos = ImGui : : GetCursorPos ( ) ;
const float popup_off_x = 0.0f ; //style.ItemInnerSpacing.x;
const float popup_height = ( label_size . y + style . ItemSpacing . y ) * ImMin ( items_count , height_in_items ) + ( style . FramePadding . y * 3 ) ;
const ImRect popup_rect ( ImVec2 ( frame_bb . Min . x + popup_off_x , frame_bb . Max . y ) , ImVec2 ( frame_bb . Max . x + popup_off_x , frame_bb . Max . y + popup_height ) ) ;
ImGui : : SetCursorPos ( popup_rect . Min - window - > Pos ) ;
const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ( ( window - > Flags & ImGuiWindowFlags_ShowBorders ) ? ImGuiWindowFlags_ShowBorders : 0 ) ;
const ImRect popup_rect ( ImVec2 ( frame_bb . Min . x , frame_bb . Max . y ) , ImVec2 ( frame_bb . Max . x , frame_bb . Max . y + popup_height ) ) ;
ImGui : : SetNextWindowPos ( popup_rect . Min ) ;
ImGui : : SetNextWindowSize ( popup_rect . GetSize ( ) ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_WindowPadding , style . FramePadding ) ;
ImGui : : BeginChild ( " #ComboBox " , popup_rect . GetSize ( ) , false , flags ) ;
ImGui : : Spacing ( ) ;
bool combo_item_active = false ;
combo_item_active | = ( g . ActiveId = = GetCurrentWindow ( ) - > GetID ( " #SCROLLY " ) ) ;
// Display items
for ( int i = 0 ; i < items_count ; i + + )
const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ( ( window - > Flags & ImGuiWindowFlags_ShowBorders ) ? ImGuiWindowFlags_ShowBorders : 0 ) ;
if ( BeginPopupEx ( label , flags ) )
{
ImGui : : PushID ( ( void * ) ( intptr_t ) i ) ;
const bool item_selected = ( i = = * current_item ) ;
const char * item_text ;
if ( ! items_getter ( data , i , & item_text ) )
item_text = " *Unknown item* " ;
if ( ImGui : : Selectable ( item_text , item_selected ) )
// Display items
ImGui : : Spacing ( ) ;
for ( int i = 0 ; i < items_count ; i + + )
{
SetActiveId ( 0 ) ;
g . ActiveComboID = 0 ;
value_changed = true ;
* current_item = i ;
ImGui : : PushID ( ( void * ) ( intptr_t ) i ) ;
const bool item_selected = ( i = = * current_item ) ;
const char * item_text ;
if ( ! items_getter ( data , i , & item_text ) )
item_text = " *Unknown item* " ;
if ( ImGui : : Selectable ( item_text , item_selected ) )
{
SetActiveId ( 0 ) ;
value_changed = true ;
* current_item = i ;
}
if ( item_selected & & menu_toggled )
ImGui : : SetScrollPosHere ( ) ;
ImGui : : PopID ( ) ;
}
if ( item_selected & & menu_toggled )
ImGui : : SetScrollPosHere ( ) ;
combo_item_active | = ImGui : : IsItemActive ( ) ;
ImGui : : PopID ( ) ;
ImGui : : EndPopup ( ) ;
}
ImGui : : EndChild ( ) ;
ImGui : : PopStyleVar ( ) ;
ImGui : : SetCursorPos ( backup_pos ) ;
if ( ! combo_item_active & & g . ActiveId ! = 0 )
g . ActiveComboID = 0 ;
}
ImGui : : PopID ( ) ;
return value_changed ;
}
static bool SelectableEx ( const char * label , bool selected , const ImVec2 & size_arg , const ImVec2 size_draw_arg , ImGuiSelectableFlags flags )
// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image.
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID.
bool ImGui : : Selectable ( const char * label , bool selected , ImGuiSelectableFlags flags , const ImVec2 & size_arg )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
return false ;
if ( ( flags & ImGuiSelectableFlags_SpanAllColumns ) & & window - > DC . ColumnsCount > 1 )
PopClipRect ( ) ;
const ImGuiStyle & style = g . Style ;
ImGuiID id = window - > GetID ( label ) ;
ImVec2 label_size = ImGui : : CalcTextSize ( label , NULL , true ) ;
@ -7403,10 +7431,11 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
// Fill horizontal space.
ImVec2 window_padding = window - > WindowPadding ( ) ;
float w_draw = ImMax ( label_size . x , window - > Pos . x + ImGui : : GetContentRegionMax ( ) . x - window_padding . x - window - > DC . CursorPos . x ) ;
ImVec2 size_draw ( size_draw_arg . x ! = 0.0f ? size_draw_arg . x : w_draw , size_draw_arg . y ! = 0.0f ? size_draw_arg . y : size . y ) ;
float max_x = ( flags & ImGuiSelectableFlags_SpanAllColumns ) ? ImGui : : GetWindowContentRegionMax ( ) . x : ImGui : : GetContentRegionMax ( ) . x ;
float w_draw = ImMax ( label_size . x , window - > Pos . x + max_x - window_padding . x - window - > DC . CursorPos . x ) ;
ImVec2 size_draw ( ( size_arg . x ! = 0 & & ! ( flags & ImGuiSelectableFlags_DrawFillAvailWidth ) ) ? size_arg . x : w_draw , size_arg . y ! = 0.0f ? size_arg . y : size . y ) ;
ImRect bb_with_spacing ( pos , pos + size_draw ) ;
if ( size_ draw_ arg. x = = 0.0f )
if ( size_ arg. x = = 0.0f | | ( flags & ImGuiSelectableFlags_DrawFillAvailWidth ) )
bb_with_spacing . Max . x + = window_padding . x ;
// Selectables are tightly packed together, we extend the box to cover spacing between selectable.
@ -7419,7 +7448,11 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
bb_with_spacing . Max . x + = spacing_R ;
bb_with_spacing . Max . y + = spacing_D ;
if ( ! ItemAdd ( bb_with_spacing , & id ) )
{
if ( ( flags & ImGuiSelectableFlags_SpanAllColumns ) & & window - > DC . ColumnsCount > 1 )
PushColumnClipRect ( ) ;
return false ;
}
bool hovered , held ;
bool pressed = ButtonBehavior ( bb_with_spacing , id , & hovered , & held , true , ( ( flags & ImGuiSelectableFlags_MenuItem ) ? ImGuiButtonFlags_PressedOnClick : 0 ) | ( ( flags & ImGuiSelectableFlags_Disabled ) ? ImGuiButtonFlags_Disabled : 0 ) ) ;
@ -7430,8 +7463,15 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
if ( hovered | | selected )
{
const ImU32 col = window - > Color ( ( held & & hovered ) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header ) ;
RenderFrame ( bb_with_spacing . Min , bb_with_spacing . Max , col , false , style . FrameRounding ) ;
RenderFrame ( bb_with_spacing . Min , bb_with_spacing . Max , col , false , 0.0f ) ;
}
if ( ( flags & ImGuiSelectableFlags_SpanAllColumns ) & & window - > DC . ColumnsCount > 1 )
{
PushColumnClipRect ( ) ;
bb_with_spacing . Max . x - = ( ImGui : : GetContentRegionMax ( ) . x - max_x ) ;
}
if ( flags & ImGuiSelectableFlags_Disabled ) ImGui : : PushStyleColor ( ImGuiCol_Text , g . Style . Colors [ ImGuiCol_TextDisabled ] ) ;
RenderTextClipped ( bb . Min , bb_with_spacing . Max , label , NULL , & label_size ) ;
if ( flags & ImGuiSelectableFlags_Disabled ) ImGui : : PopStyleColor ( ) ;
@ -7442,16 +7482,9 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
return pressed ;
}
// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image.
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID.
bool ImGui : : Selectable ( const char * label , bool selected , const ImVec2 & size_arg )
{
return SelectableEx ( label , selected , size_arg , size_arg , 0 ) ;
}
bool ImGui : : Selectable ( const char * label , bool * p_selected , const ImVec2 & size_arg )
bool ImGui : : Selectable ( const char * label , bool * p_selected , ImGuiSelectableFlags flags , const ImVec2 & size_arg )
{
if ( SelectableEx ( label , * p_selected , size_arg, size_arg , 0 ) )
if ( ImGui : : Selectable ( label , * p_selected , flags , size_arg ) )
{
* p_selected = ! * p_selected ;
return true ;
@ -7567,7 +7600,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
float w = window - > MenuColumns . DeclColumns ( label_size . x , shortcut_size . x , ( float ) ( int ) ( g . FontSize * 1.20f ) ) ; // Feedback for next frame
float extra_w = ImMax ( 0.0f , window - > Pos . x + ImGui : : GetContentRegionMax ( ) . x - pos . x - w ) ;
bool pressed = SelectableEx ( label , false , Im Vec2( w , 0.0f ) , ImVec2 ( 0.0f , 0.0f ) , ImGuiSelectableFlags_MenuItem | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) ) ;
bool pressed = ImGui: : Selectable( label , false , Im GuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( w , 0.0f ) ) ;
if ( shortcut_size . x > 0.0f )
{
ImGui : : PushStyleColor ( ImGuiCol_Text , g . Style . Colors [ ImGuiCol_TextDisabled ] ) ;
@ -7680,7 +7713,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
window - > DC . CursorPos . x + = ( float ) ( int ) ( style . ItemSpacing . x * 0.5f ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_ItemSpacing , style . ItemSpacing * 2.0f ) ;
float w = label_size . x ;
pressed = SelectableEx ( label , opened , ImVec2 ( w , 0.0f ) , ImVec2 ( w , 0.0f ) , ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) ) ;
pressed = ImGui: : Selectable( label , opened , ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( w , 0.0f ) ) ;
ImGui : : PopStyleVar ( ) ;
ImGui : : SameLine ( ) ;
window - > DC . CursorPos . x + = ( float ) ( int ) ( style . ItemSpacing . x * 0.5f ) ;
@ -7690,7 +7723,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
popup_pos = ImVec2 ( pos . x , pos . y - style . WindowPadding . y ) ;
float w = window - > MenuColumns . DeclColumns ( label_size . x , 0.0f , ( float ) ( int ) ( g . FontSize * 1.20f ) ) ; // Feedback to next frame
float extra_w = ImMax ( 0.0f , window - > Pos . x + ImGui : : GetContentRegionMax ( ) . x - pos . x - w ) ;
pressed = SelectableEx ( label , opened , Im Vec2( w , 0.0f ) , ImVec2 ( 0.0f , 0.0f ) , Im GuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) ) ;
pressed = ImGui: : Selectable( label , opened , Im GuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( w , 0.0f ) ) ;
if ( ! enabled ) ImGui : : PushStyleColor ( ImGuiCol_Text , g . Style . Colors [ ImGuiCol_TextDisabled ] ) ;
RenderCollapseTriangle ( pos + ImVec2 ( window - > MenuColumns . Pos [ 2 ] + extra_w + g . FontSize * 0.20f , 0.0f ) , false ) ;
if ( ! enabled ) ImGui : : PopStyleColor ( ) ;
@ -7750,7 +7783,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
if ( opened )
{
ImGui : : SetNextWindowPos ( popup_pos , ImGuiSetCond_Always ) ;
ImGuiWindowFlags flags = ( window - > Flags & ( ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu ) ) ? ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu ;
ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ( ( window - > Flags & ( ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu ) ) ? ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu ) ;
opened = BeginPopupEx ( label , flags ) ; // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
}
@ -7773,7 +7806,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( " #colorbutton " ) ;
const float square_size = g . FontSize ;
const ImRect bb ( window - > DC . CursorPos , window - > DC . CursorPos + ImVec2 ( square_size + style . FramePadding . x * 2 , square_size + ( small_height ? 0 : style . FramePadding . y * 2 ) ) ) ;
const ImRect bb ( window - > DC . CursorPos , window - > DC . CursorPos + ImVec2 ( square_size + style . FramePadding . y * 2 , square_size + ( small_height ? 0 : style . FramePadding . y * 2 ) ) ) ;
ItemSize ( bb , small_height ? 0.0f : style . FramePadding . y ) ;
if ( ! ItemAdd ( bb , & id ) )
return false ;
@ -7820,7 +7853,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( label ) ;
const float w_full = ImGui : : CalcItemWidth ( ) ;
const float square_sz = ( g . FontSize + style . FramePadding . x * 2.0f ) ;
const float square_sz = ( g . FontSize + style . FramePadding . y * 2.0f ) ;
ImGuiColorEditMode edit_mode = window - > DC . ColorEditMode ;
if ( edit_mode = = ImGuiColorEditMode_UserSelect | | edit_mode = = ImGuiColorEditMode_UserSelectShowButton )
@ -9330,7 +9363,8 @@ bool ImFontAtlas::Build()
const float font_scale = stbtt_ScaleForPixelHeight ( & data . FontInfo , data . SizePixels ) ;
int font_ascent , font_descent , font_line_gap ;
stbtt_GetFontVMetrics ( & data . FontInfo , & font_ascent , & font_descent , & font_line_gap ) ;
data . OutFont - > BaseLine = ( font_ascent * font_scale ) ;
data . OutFont - > Ascent = ( font_ascent * font_scale ) ;
data . OutFont - > Descent = ( font_descent * font_scale ) ;
data . OutFont - > Glyphs . resize ( 0 ) ;
const float uv_scale_x = 1.0f / TexWidth ;
@ -9489,7 +9523,7 @@ void ImFont::Clear()
{
FontSize = 0.0f ;
DisplayOffset = ImVec2 ( - 0.5f , 0.5f ) ;
BaseLine = 0.0f ;
Ascent = Descent = 0.0f ;
ContainerAtlas = NULL ;
Glyphs . clear ( ) ;
FallbackGlyph = NULL ;
@ -9846,12 +9880,20 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
if ( c = = 0 )
break ;
if ( c == ' \n ' )
if ( c < 32 )
{
line_width = word_width = blank_width = 0.0f ;
inside_word = true ;
s = next_s ;
continue ;
if ( c = = ' \n ' )
{
line_width = word_width = blank_width = 0.0f ;
inside_word = true ;
s = next_s ;
continue ;
}
if ( c = = ' \r ' )
{
s = next_s ;
continue ;
}
}
const float char_width = ( ( size_t ) c < IndexXAdvance . size ( ) ) ? IndexXAdvance [ ( size_t ) c ] * scale : FallbackXAdvance ;
@ -9957,12 +9999,17 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
break ;
}
if ( c == ' \n ' )
if ( c < 32 )
{
text_size . x = ImMax ( text_size . x , line_width ) ;
text_size . y + = line_height ;
line_width = 0.0f ;
continue ;
if ( c = = ' \n ' )
{
text_size . x = ImMax ( text_size . x , line_width ) ;
text_size . y + = line_height ;
line_width = 0.0f ;
continue ;
}
if ( c = = ' \r ' )
continue ;
}
const float char_width = ( ( size_t ) c < IndexXAdvance . size ( ) ) ? IndexXAdvance [ ( size_t ) c ] * scale : FallbackXAdvance ;
@ -10004,12 +10051,17 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be
{
const unsigned int c = ( unsigned int ) ( * s + + ) ;
if ( c == ' \n ' )
if ( c < 32 )
{
text_size . x = ImMax ( text_size . x , line_width ) ;
text_size . y + = line_height ;
line_width = 0.0f ;
continue ;
if ( c = = ' \n ' )
{
text_size . x = ImMax ( text_size . x , line_width ) ;
text_size . y + = line_height ;
line_width = 0.0f ;
continue ;
}
if ( c = = ' \r ' )
continue ;
}
const float char_width = ( ( size_t ) c < IndexXAdvance . size ( ) ) ? IndexXAdvance [ ( size_t ) c ] * scale : FallbackXAdvance ;
@ -10103,11 +10155,16 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
break ;
}
if ( c == ' \n ' )
if ( c < 32 )
{
x = pos . x ;
y + = line_height ;
continue ;
if ( c = = ' \n ' )
{
x = pos . x ;
y + = line_height ;
continue ;
}
if ( c = = ' \r ' )
continue ;
}
float char_width = 0.0f ;
@ -10708,7 +10765,7 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui : : SameLine ( ) ;
ImGui : : PushID ( i ) ;
int frame_padding = - 1 + i ; // -1 = uses default padding
if ( ImGui : : ImageButton ( tex_id , ImVec2 ( 32 , 32 ) , ImVec2 ( 0 , 0 ) , ImVec2 ( 32.0f / tex_w , 32 / tex_h ) , frame_padding ))
if ( ImGui : : ImageButton ( tex_id , ImVec2 ( 32 , 32 ) , ImVec2 ( 0 , 0 ) , ImVec2 ( 32.0f / tex_w , 32 / tex_h ) , frame_padding , ImColor ( 0 , 0 , 0 , 255 ) ))
pressed_count + = 1 ;
ImGui : : PopID ( ) ;
}
@ -10741,7 +10798,7 @@ void ImGui::ShowTestWindow(bool* opened)
for ( int i = 0 ; i < 16 ; i + + )
{
ImGui : : PushID ( i ) ;
if ( ImGui : : Selectable ( " Me " , & selected [ i ] , ImVec2 ( 50 , 50 ) ) )
if ( ImGui : : Selectable ( " Me " , & selected [ i ] , 0 , ImVec2 ( 50 , 50 ) ) )
{
int x = i % 4 , y = i / 4 ;
if ( x > 0 ) selected [ i - 1 ] ^ = 1 ;
@ -10943,13 +11000,13 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui : : DragInt ( " drag int 0..100 " , & i2 , 1 , 0 , 100 , " %.0f%% " ) ;
static float f1 = 1.00f , f2 = 0.0067f ;
ImGui : : DragFloat ( " drag float " , & f1 , 1.0 f) ;
ImGui : : DragFloat ( " drag float " , & f1 , 0.005 f) ;
ImGui : : DragFloat ( " drag small float " , & f2 , 0.0001f , 0.0f , 0.0f , " %.06f ns " ) ;
}
{
static int i1 = 0 ;
ImGui : : SliderInt ( " slider int " , & i1 , 0 , 3 ) ;
ImGui : : SliderInt ( " slider int " , & i1 , - 1 , 3 ) ;
ImGui : : SameLine ( ) ; ShowHelpMarker ( " CTRL+click to input value. " ) ;
static float f1 = 0.123f , f2 = 0.0f ;
@ -11328,9 +11385,14 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui : : Separator ( ) ;
const char * names [ 3 ] = { " One " , " Two " , " Three " } ;
const char * paths [ 3 ] = { " /path/one " , " /path/two " , " /path/three " } ;
static int selected = - 1 ;
for ( int i = 0 ; i < 3 ; i + + )
{
ImGui : : Text ( " %04d " , i ) ; ImGui : : NextColumn ( ) ;
char label [ 32 ] ;
sprintf ( label , " %04d " , i ) ;
if ( ImGui : : Selectable ( label , selected = = i , ImGuiSelectableFlags_SpanAllColumns ) )
selected = i ;
ImGui : : NextColumn ( ) ;
ImGui : : Text ( names [ i ] ) ; ImGui : : NextColumn ( ) ;
ImGui : : Text ( paths [ i ] ) ; ImGui : : NextColumn ( ) ;
ImGui : : Text ( " .... " ) ; ImGui : : NextColumn ( ) ;
@ -11580,6 +11642,7 @@ void ImGui::ShowMetricsWindow(bool* opened)
NodeDrawList ( window - > DrawList , " DrawList " ) ;
if ( window - > RootWindow ! = window ) NodeWindow ( window - > RootWindow , " RootWindow " ) ;
if ( window - > DC . ChildWindows . size ( ) > 0 ) NodeWindows ( window - > DC . ChildWindows , " ChildWindows " ) ;
ImGui : : BulletText ( " Storage: %d bytes " , ( int ) window - > StateStorage . Data . size ( ) * sizeof ( ImGuiStorage : : Pair ) ) ;
ImGui : : TreePop ( ) ;
}
} ;