@ -1,4 +1,4 @@
// ImGui library v1.38 WIP
// ImGui library v1.38
// 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
@ -19,6 +19,7 @@
- API BREAKING CHANGES ( read me when you update ! )
- FREQUENTLY ASKED QUESTIONS ( FAQ ) , TIPS
- Can I have multiple widgets with the same label ? ( Yes )
- How do I update to a newer version of ImGui ?
- Why is my text output blurry ?
- How can I load a different font than the default ?
- How can I load multiple fonts ?
@ -274,6 +275,15 @@
e . g . when displaying a single object that may change over time ( 1 - 1 relationship ) , using a static string as ID will preserve your node open / closed state when the targeted object change .
e . g . when displaying a list of objects , using indices or pointers as ID will preserve the node open / closed state differently . experiment and see what makes more sense !
Q : How do I update to a newer version of ImGui ?
A : Overwrite the following files :
imgui . cpp
imgui . h
stb_rect_pack . h
stb_textedit . h
stb_truetype . h
Check the " API BREAKING CHANGES " sections for a list of occasional API breaking changes .
Q : Why is my text output blurry ?
A : In your Render function , try translating your projection matrix by ( 0.5f , 0.5f ) or ( 0.375f , 0.375f )
@ -498,7 +508,7 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id);
static void ItemSize ( ImVec2 size , float text_offset_y = 0.0f ) ;
static void ItemSize ( const ImRect & bb , float text_offset_y = 0.0f ) ;
static void PushColumnClipRect ( int column_index = - 1 ) ;
static bool IsClippedEx ( const ImRect & bb , bool clip_even_when_logged ) ;
static bool IsClippedEx ( const ImRect & bb , const ImGuiID * id , bool clip_even_when_logged ) ;
static bool IsMouseHoveringRect ( const ImRect & bb ) ;
static bool IsKeyPressedMap ( ImGuiKey key , bool repeat = true ) ;
@ -1152,8 +1162,10 @@ struct ImGuiState
ImGuiID ScalarAsInputTextId ; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiStorage ColorEditModeStorage ; // for user selection
ImGuiID ActiveComboID ;
ImVec2 ActiveClickDeltaToCenter ;
float DragCurrentValue ; // current dragged value, always float, not rounded by end-user precision settings
ImVec2 DragLastMouseDelta ;
float DragSpeedDefaultRatio ; // if speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
float DragSpeedScaleSlow ;
float DragSpeedScaleFast ;
float ScrollbarClickDeltaToGrabCenter ; // distance between mouse and center of grab box, normalized in parent space
@ -1209,8 +1221,10 @@ struct ImGuiState
ScalarAsInputTextId = 0 ;
ActiveComboID = 0 ;
ActiveClickDeltaToCenter = ImVec2 ( 0.0f , 0.0f ) ;
DragCurrentValue = 0.0f ;
DragLastMouseDelta = ImVec2 ( 0.0f , 0.0f ) ;
DragSpeedDefaultRatio = 0.01f ;
DragSpeedScaleSlow = 0.01f ;
DragSpeedScaleFast = 10.0f ;
ScrollbarClickDeltaToGrabCenter = 0.0f ;
@ -4253,7 +4267,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
while ( line < text_end )
{
const char * line_end = strchr ( line , ' \n ' ) ;
if ( IsClippedEx ( line_rect , false) )
if ( IsClippedEx ( line_rect , NULL, false) )
break ;
const ImVec2 line_size = CalcTextSize ( line , line_end , false ) ;
@ -5124,7 +5138,7 @@ static inline float RoundScalar(float value, int decimal_precision)
return value ;
}
static bool Slider Behavior( const ImRect & frame _bb, const ImRect & slider _bb, ImGuiID id , float * v , float v_min , float v_max , float power , int decimal_precision , bool horizontal )
static bool Slider Scalar Behavior( const ImRect & frame _bb, ImGuiID id , float * v , float v_min , float v_max , float power , int decimal_precision , bool horizontal )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
@ -5135,15 +5149,16 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu
const bool is_non_linear = fabsf ( power - 1.0f ) > 0.0001f ;
const float slider_sz = horizontal ? slider_bb . GetWidth ( ) : slider_bb . GetHeight ( ) ;
const float padding = horizontal ? style . FramePadding . x : style . FramePadding . y ;
const float slider_sz = horizontal ? ( frame_bb . GetWidth ( ) - padding * 2.0f ) : ( frame_bb . GetHeight ( ) - padding * 2.0f ) ;
float grab_sz ;
if ( decimal_precision > 0 )
grab_sz = ImMin ( style . GrabMinSize , slider_sz ) ;
else
grab_sz = ImMin ( ImMax ( 1.0f * ( slider_sz / ( v_max - v_min + 1.0f ) ) , style . GrabMinSize ) , slider_sz ) ; // Integer sliders, if possible have the grab size represent 1 unit
const float slider_usable_sz = slider_sz - grab_sz ;
const float slider_usable_pos_min = ( horizontal ? slider_bb. Min . x : slider _bb. Min . y ) + grab_sz * 0.5f ;
const float slider_usable_pos_max = ( horizontal ? slider_bb. Max . x : slider _bb. Max . y ) - grab_sz * 0.5f ;
const float slider_usable_pos_min = ( horizontal ? frame_bb. Min . x : frame _bb. Min . y ) + padding + grab_sz * 0.5f ;
const float slider_usable_pos_max = ( horizontal ? frame_bb. Max . x : frame _bb. Max . y ) - padding - grab_sz * 0.5f ;
bool value_changed = false ;
@ -5181,7 +5196,7 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu
// Negative: rescale to the negative range before powering
float a = 1.0f - ( normalized_pos / linear_zero_pos ) ;
a = powf ( a , power ) ;
new_value = ImLerp ( ImMin ( v_max , 0. f) , v_min , a ) ;
new_value = ImLerp ( ImMin ( v_max , 0. 0 f) , v_min , a ) ;
}
else
{
@ -5270,7 +5285,6 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
const ImVec2 label_size = CalcTextSize ( label , NULL , true ) ;
const ImRect frame_bb ( window - > DC . CursorPos , window - > DC . CursorPos + ImVec2 ( w , label_size . y ) + style . FramePadding * 2.0f ) ;
const ImRect inner_bb ( frame_bb . Min + style . FramePadding , frame_bb . Max - style . FramePadding ) ;
const ImRect total_bb ( frame_bb . Min , frame_bb . Max + ImVec2 ( label_size . x > 0.0f ? style . ItemInnerSpacing . x + label_size . x : 0.0f , 0.0f ) ) ;
// NB- we don't call ItemSize() yet because we may turn into a text edit box below
@ -5310,16 +5324,16 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
ItemSize ( total_bb , style . FramePadding . y ) ;
// Actual slider behavior + render grab
const bool value_changed = Slider Behavior( frame _bb, inner _bb, id , v , v_min , v_max , power , decimal_precision , true ) ;
const bool value_changed = Slider Scalar Behavior( frame _bb, id , v , v_min , v_max , power , decimal_precision , true ) ;
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf [ 64 ] ;
const char * value_buf_end = value_buf + ImFormatString ( value_buf , IM_ARRAYSIZE ( value_buf ) , display_format , * v ) ;
const ImVec2 value_text_size = CalcTextSize ( value_buf , value_buf_end , true ) ;
RenderTextClipped ( ImVec2 ( ImMax ( frame_bb . Min . x + style . FramePadding . x , inner _bb. GetCenter ( ) . x - value_text_size . x * 0.5f ) , frame_bb . Min . y + style . FramePadding . y ) , value_buf , value_buf_end , & value_text_size , frame_bb . Max ) ;
RenderTextClipped ( ImVec2 ( ImMax ( frame_bb . Min . x + style . FramePadding . x , frame _bb. GetCenter ( ) . x - value_text_size . x * 0.5f ) , frame_bb . Min . y + style . FramePadding . y ) , value_buf , value_buf_end , & value_text_size , frame_bb . Max ) ;
if ( label_size . x > 0.0f )
RenderText ( ImVec2 ( frame_bb . Max . x + style . ItemInnerSpacing . x , inner_bb. Min . y ) , label ) ;
RenderText ( ImVec2 ( frame_bb . Max . x + style . ItemInnerSpacing . x , frame_bb. Min . y + style . FramePadding . y ) , label ) ;
return value_changed ;
}
@ -5336,7 +5350,6 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
const ImVec2 label_size = CalcTextSize ( label , NULL , true ) ;
const ImRect frame_bb ( window - > DC . CursorPos , window - > DC . CursorPos + size ) ;
const ImRect slider_bb ( frame_bb . Min + style . FramePadding , frame_bb . Max - style . FramePadding ) ;
const ImRect bb ( frame_bb . Min , frame_bb . Max + ImVec2 ( label_size . x > 0.0f ? style . ItemInnerSpacing . x + label_size . x : 0.0f , 0.0f ) ) ;
ItemSize ( bb , style . FramePadding . y ) ;
@ -5359,17 +5372,17 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
}
// Actual slider behavior + render grab
bool value_changed = Slider Behavior( frame _bb, slider _bb, id , v , v_min , v_max , power , decimal_precision , false ) ;
bool value_changed = Slider Scalar Behavior( frame _bb, id , v , v_min , v_max , power , decimal_precision , false ) ;
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
// For the vertical slider we allow centered text to overlap the frame padding
char value_buf [ 64 ] ;
char * value_buf_end = value_buf + ImFormatString ( value_buf , IM_ARRAYSIZE ( value_buf ) , display_format , * v ) ;
const ImVec2 value_text_size = CalcTextSize ( value_buf , value_buf_end , true ) ;
RenderTextClipped ( ImVec2 ( ImMax ( frame_bb . Min . x , slider _bb. GetCenter ( ) . x - value_text_size . x * 0.5f ) , frame_bb . Min . y + style . FramePadding . y ) , value_buf , value_buf_end , & value_text_size , frame_bb . Max ) ;
RenderTextClipped ( ImVec2 ( ImMax ( frame_bb . Min . x , frame _bb. GetCenter ( ) . x - value_text_size . x * 0.5f ) , frame_bb . Min . y + style . FramePadding . y ) , value_buf , value_buf_end , & value_text_size , frame_bb . Max ) ;
if ( label_size . x > 0.0f )
RenderText ( ImVec2 ( frame_bb . Max . x + style . ItemInnerSpacing . x , slider_bb. Min . y ) , label ) ;
RenderText ( ImVec2 ( frame_bb . Max . x + style . ItemInnerSpacing . x , frame_bb. Min . y + style . FramePadding . y ) , label ) ;
return value_changed ;
}
@ -5520,7 +5533,7 @@ static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, flo
bool value_changed = false ;
// Process clicking on the sli de r
// Process clicking on the drag
if ( g . ActiveId = = id )
{
if ( g . IO . MouseDown [ 0 ] )
@ -5536,10 +5549,12 @@ static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, flo
if ( fabsf ( mouse_drag_delta . x - g . DragLastMouseDelta . x ) > 0.0f )
{
float speed = v_speed ;
if ( speed = = 0.0f & & ( v_max - v_min ) ! = 0.0f & & ( v_max - v_min ) < FLT_MAX )
speed = ( v_max - v_min ) * g . DragSpeedDefaultRatio ;
if ( g . IO . KeyShift & & g . DragSpeedScaleFast > = 0.0f )
speed = v_speed * g . DragSpeedScaleFast ;
speed = speed * g . DragSpeedScaleFast ;
if ( g . IO . KeyAlt & & g . DragSpeedScaleSlow > = 0.0f )
speed = v_ speed * g . DragSpeedScaleSlow ;
speed = speed * g . DragSpeedScaleSlow ;
float v_cur = g . DragCurrentValue ;
float delta = ( mouse_drag_delta . x - g . DragLastMouseDelta . x ) * speed ;
@ -7252,15 +7267,16 @@ static inline void ItemSize(const ImRect& bb, float text_offset_y)
ItemSize ( bb . GetSize ( ) , text_offset_y ) ;
}
static bool IsClippedEx ( const ImRect & bb , bool clip_even_when_logged )
static bool IsClippedEx ( const ImRect & bb , const ImGuiID * id , bool clip_even_when_logged )
{
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( ! bb . Overlaps ( ImRect ( window - > ClipRectStack . back ( ) ) ) )
{
if ( clip_even_when_logged | | ! g . LogEnabled )
return true ;
if ( ! id | | * id ! = GImGui - > ActiveId )
if ( clip_even_when_logged | | ! g . LogEnabled )
return true ;
}
return false ;
}
@ -7268,7 +7284,7 @@ static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged)
bool ImGui : : IsRectClipped ( const ImVec2 & size )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
return IsClippedEx ( ImRect ( window - > DC . CursorPos , window - > DC . CursorPos + size ) , true) ;
return IsClippedEx ( ImRect ( window - > DC . CursorPos , window - > DC . CursorPos + size ) , NULL, true) ;
}
static bool ItemAdd ( const ImRect & bb , const ImGuiID * id )
@ -7276,13 +7292,10 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id)
ImGuiWindow * window = GetCurrentWindow ( ) ;
window - > DC . LastItemID = id ? * id : 0 ;
window - > DC . LastItemRect = bb ;
if ( IsClippedEx ( bb , false ) )
if ( IsClippedEx ( bb , id , false ) )
{
if ( ! id | | * id ! = GImGui - > ActiveId )
{
window - > DC . LastItemHoveredAndUsable = window - > DC . LastItemHoveredRect = false ;
return 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()
@ -7412,7 +7425,7 @@ void ImGui::NextColumn()
window - > DC . CurrentLineTextBaseOffset = 0.0f ;
PushColumnClipRect ( ) ;
ImGui : : PushItemWidth ( ImGui : : GetColumnWidth ( ) * 0.65f ) ;
ImGui : : PushItemWidth ( ImGui : : GetColumnWidth ( ) * 0.65f ) ; // FIXME
}
}
@ -7428,6 +7441,21 @@ int ImGui::GetColumnsCount()
return window - > DC . ColumnsCount ;
}
static float GetDraggedColumnOffset ( int column_index )
{
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
// window creates a feedback loop because we store normalized positions/ So while dragging we enforce absolute positioning
ImGuiState & g = * GImGui ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
IM_ASSERT ( g . ActiveId = = window - > DC . ColumnsSetID + ImGuiID ( column_index ) ) ;
float x = g . IO . MousePos . x + g . ActiveClickDeltaToCenter . x ;
x - = window - > Pos . x ;
x = ImClamp ( x , ImGui : : GetColumnOffset ( column_index - 1 ) + g . Style . ColumnsMinSpacing , ImGui : : GetColumnOffset ( column_index + 1 ) - g . Style . ColumnsMinSpacing ) ;
return x ;
}
float ImGui : : GetColumnOffset ( int column_index )
{
ImGuiState & g = * GImGui ;
@ -7435,6 +7463,13 @@ float ImGui::GetColumnOffset(int column_index)
if ( column_index < 0 )
column_index = window - > DC . ColumnsCurrent ;
if ( g . ActiveId )
{
const ImGuiID column_id = window - > DC . ColumnsSetID + ImGuiID ( column_index ) ;
if ( g . ActiveId = = column_id )
return GetDraggedColumnOffset ( column_index ) ;
}
// Read from cache
IM_ASSERT ( column_index < ( int ) window - > DC . ColumnsOffsetsT . size ( ) ) ;
const float t = window - > DC . ColumnsOffsetsT [ column_index ] ;
@ -7511,7 +7546,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
const ImGuiID column_id = window - > DC . ColumnsSetID + ImGuiID ( i ) ;
const ImRect column_rect ( ImVec2 ( x - 4 , y1 ) , ImVec2 ( x + 4 , y2 ) ) ;
if ( IsClippedEx ( column_rect , false ) )
if ( IsClippedEx ( column_rect , & column_id , false ) )
continue ;
bool hovered , held ;
@ -7526,10 +7561,11 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
if ( held )
{
x - = window - > Pos . x ;
x = ImClamp ( x + g . IO . MouseDelta . x , ImGui : : GetColumnOffset ( i - 1 ) + g . Style . ColumnsMinSpacing , ImGui : : GetColumnOffset ( i + 1 ) - g . Style . ColumnsMinSpacing ) ;
if ( g . ActiveIdIsJustActivated )
g . ActiveClickDeltaToCenter . x = x - g . IO . MousePos . x ;
x = GetDraggedColumnOffset ( i ) ;
SetColumnOffset ( i , x ) ;
x + = window - > Pos . x ;
}
}
}
@ -10011,29 +10047,32 @@ void ImGui::ShowTestWindow(bool* opened)
ImGui : : InputFloat3 ( " input float3 " , vec4a ) ;
}
/*
{
static int i1 = 50 ;
static int i2 = 42 ;
ImGui : : DragInt ( " drag int " , & i1 , 1 ) ;
ImGui : : DragInt ( " drag int 0..100 " , & i2 , 1 , 0 , 100 ) ;
ImGui : : SameLine ( ) ;
ImGui : : TextColored ( ImColor ( 170 , 170 , 170 , 255 ) , " (?) " ) ;
if ( ImGui : : IsItemHovered ( ) )
ImGui : : SetTooltip ( " Click and drag to edit value. \n Hold SHIFT/ALT for faster/slower edit. \n Double-click or CTRL+click to input text " ) ;
ImGui : : DragInt ( " drag int 0..100 " , & i2 , 1 , 0 , 100 , " %.0f%% " ) ;
static float f1 = 1.00f ;
static float f2 = 0.0067f ;
ImGui : : DragFloat ( " drag float " , & f1 , 1.0f ) ;
ImGui : : DragFloat ( " drag small float " , & f2 , 0.0001f , 0.0f , 0.0f , " %.06f " ) ;
ImGui : : DragFloat ( " drag small float " , & f2 , 0.0001f , 0.0f , 0.0f , " %.06f ns " ) ;
}
*/
{
static int i1 = 0 ;
static int i2 = 42 ;
//static int i2=42;
ImGui : : SliderInt ( " slider int 0..3 " , & i1 , 0 , 3 ) ;
ImGui : : SliderInt ( " slider int -100..100 " , & i2 , - 100 , 100 ) ;
//ImGui::SliderInt("slider int -100..100", &i2, -100, 100);
static float f1 = 1 .123f;
static float f2 = 0 ;
ImGui : : SliderFloat ( " slider float " , & f1 , 0.0f , 2.0f ) ;
static float f1 = 0 .123f;
static float f2 = 0.0f ;
ImGui : : SliderFloat ( " slider float " , & f1 , 0.0f , 1.0f, " ratio = %.3f " ) ;
ImGui : : SliderFloat ( " slider log float " , & f2 , - 10.0f , 10.0f , " %.4f " , 3.0f ) ;
static float angle = 0.0f ;
ImGui : : SliderAngle ( " slider angle " , & angle ) ;