@ -131,11 +131,8 @@
ImGui : : NewFrame ( ) ;
// 3) most of your application code here
ImGui : : Begin ( " My window " ) ;
ImGui : : Text ( " Hello, world. " ) ;
ImGui : : End ( ) ;
MyGameUpdate ( ) ; // may use ImGui functions
MyGameRender ( ) ; // may use ImGui functions
MyGameUpdate ( ) ; // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End();
MyGameRender ( ) ; // may use any ImGui functions
// 4) render & swap video buffers
ImGui : : Render ( ) ;
@ -153,8 +150,9 @@
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 .
Also read releases logs https : //github.com/ocornut/imgui/releases for more details.
- 2016 / 06 / xx ( 1. xx ) - removed ColorEditMode ( ) and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit * ( ) functions
- 2016 / 08 / xx ( 1. XX ) - removed ColorEditMode ( ) and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit * ( ) functions
replaced ColorEdit4 ( ) third parameter ' bool show_alpha = true ' to ' ImGuiColorEditFlags flags = 0x01 ' where ImGuiColorEditFlags_Alpha = 0x01 for dodgy compatibility
- 2016 / 07 / 30 ( 1.50 ) - SameLine ( x ) with x > 0.0f is now relative to left of column / group if any , and not always to left of window . This was sort of always the intent and hopefully breakage should be minimal .
- 2016 / 05 / 12 ( 1.49 ) - title bar ( using ImGuiCol_TitleBg / ImGuiCol_TitleBgActive colors ) isn ' t rendered over a window background ( ImGuiCol_WindowBg color ) anymore .
If your TitleBg / TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you .
However if your TitleBg / TitleBgActive alpha was < 1.0f you need to tweak your custom theme to readjust for the fact that we don ' t draw a WindowBg background behind the title bar .
@ -213,15 +211,15 @@
- 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 " open " 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 / 13 ( 1.38 ) - renamed IsClipped ( ) to IsRectClipped ( ) . Kept inline redirection function until 1.50 .
- 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 .
- 2014 / 04 / 03 ( 1.38 ) - removed support for passing - FLT_MAX . . + FLT_MAX as the range for a SliderFloat ( ) . Use DragFloat ( ) or Inputfloat ( ) instead .
- 2015 / 03 / 17 ( 1.36 ) - renamed GetItemBoxMin ( ) / GetItemBoxMax ( ) / IsMouseHoveringBox ( ) to GetItemRectMin ( ) / GetItemRectMax ( ) / IsMouseHoveringRect ( ) . Kept inline redirection function ( will obsolete ) .
- 2015 / 03 / 17 ( 1.36 ) - renamed GetItemBoxMin ( ) / GetItemBoxMax ( ) / IsMouseHoveringBox ( ) to GetItemRectMin ( ) / GetItemRectMax ( ) / IsMouseHoveringRect ( ) . Kept inline redirection function until 1.50 .
- 2015 / 03 / 15 ( 1.36 ) - renamed style . TreeNodeSpacing to style . IndentSpacing , ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing
- 2015 / 03 / 13 ( 1.36 ) - renamed GetWindowIsFocused ( ) to IsWindowFocused ( ) . Kept inline redirection function ( will obsolete ) .
- 2015 / 03 / 13 ( 1.36 ) - renamed GetWindowIsFocused ( ) to IsWindowFocused ( ) . Kept inline redirection function until 1.50 .
- 2015 / 03 / 08 ( 1.35 ) - renamed style . ScrollBarWidth to style . ScrollbarWidth ( casing )
- 2015 / 02 / 27 ( 1.34 ) - renamed OpenNextNode ( bool ) to SetNextTreeNodeOpened ( bool , ImGuiSetCond ) . Kept inline redirection function ( will obsolete ) .
- 2015 / 02 / 27 ( 1.34 ) - renamed OpenNextNode ( bool ) to SetNextTreeNodeOpened ( bool , ImGuiSetCond ) . Kept inline redirection function until 1.50 .
- 2015 / 02 / 27 ( 1.34 ) - renamed ImGuiSetCondition_ * * * to ImGuiSetCond_ * * * , and _FirstUseThisSession becomes _Once .
- 2015 / 02 / 11 ( 1.32 ) - changed text input callback ImGuiTextEditCallback return type from void - - > int . reserved for future use , return 0 for now .
- 2015 / 02 / 10 ( 1.32 ) - renamed GetItemWidth ( ) to CalcItemWidth ( ) to clarify its evolving behavior
@ -393,10 +391,12 @@
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 can I tell when ImGui wants my mouse / keyboard inputs and when I can pass them to my application ?
A : You can read the ' io . WantCaptureXXX ' flags in the ImGuiIO structure . Preferably read them after calling ImGui : : NewFrame ( ) to avoid those flags lagging by one frame .
A : You can read the ' io . WantCaptureXXX ' flags in the ImGuiIO structure . Preferably read them after calling ImGui : : NewFrame ( ) to avoid those flags lagging by one frame , but either should be fine .
When ' io . WantCaptureMouse ' or ' io . WantCaptureKeyboard ' flags are set you may want to discard / hide the inputs from the rest of your application .
When ' io . WantInputsCharacters ' is set to may want to notify your OS to popup an on - screen keyboard , if available .
ImGui is tracking dragging and widget activity that may occur outside the boundary of a window , so ' io . WantCaptureMouse ' is a more accurate and complete than testing for ImGui : : IsMouseHoveringAnyWindow ( ) .
( Advanced note : text input releases focus on Return ' KeyDown ' , so the following Return ' KeyUp ' event that your application receive will typically have ' io . WantcaptureKeyboard = false ' .
Depending on your application logic it may or not be inconvenient . You might want to track which key - downs were for ImGui ( e . g . with an array of bool ) and filter out the corresponding key - ups . )
Q : How can I load a different font than the default ? ( default is an embedded version of ProggyClean . ttf , rendered at size 13 )
A : Use the font atlas to load the TTF file you want :
@ -490,9 +490,11 @@
- input text : flag to disable live update of the user buffer ( also applies to float / int text input )
- input text : resize behavior - field could stretch when being edited ? hover tooltip shows more text ?
- input text : add ImGuiInputTextFlags_EnterToApply ? ( off # 218 )
- input text : add discard flag ( e . g . ImGuiInputTextFlags_DiscardActiveBuffer ) or make it easier to clear active focus for text replacement during edition ( # 725 )
- input text multi - line : don ' t directly call AddText ( ) which does an unnecessary vertex reserve for character count prior to clipping . and / or more line - based clipping to AddText ( ) . and / or reorganize TextUnformatted / RenderText for more efficiency for large text ( e . g TextUnformatted could clip and log separately , etc ) .
- input text multi - line : way to dynamically grow the buffer without forcing the user to initially allocate for worse case ( follow up on # 200 )
- input text multi - line : line numbers ? status bar ? ( follow up on # 200 )
- input text multi - line : behave better when user changes input buffer while editing is active ( even though it is illegal behavior ) . namely , the change of buffer can create a scrollbar glitch ( # 725 )
- input text : allow centering / positioning text so that ctrl + clicking Drag or Slider keeps the textual value at the same pixel position .
- input number : optional range min / max for Input * ( ) functions
- input number : holding [ - ] / [ + ] buttons could increase the step speed non - linearly ( or user - controlled )
@ -831,10 +833,7 @@ ImGuiIO::ImGuiIO()
// Set OS X style defaults based on __APPLE__ compile time flag
# ifdef __APPLE__
WordMovementUsesAltKey = true ; // OS X style: Text editing cursor movement using Alt instead of Ctrl
ShortcutsUseSuperKey = true ; // OS X style: Shortcuts using Cmd/Super instead of Ctrl
DoubleClickSelectsWord = true ; // OS X style: Double click selects by word instead of selecting whole text
MultiSelectUsesSuperKey = true ; // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl
OSXBehaviors = true ;
# endif
}
@ -865,7 +864,8 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
// HELPERS
//-----------------------------------------------------------------------------
# define IM_F32_TO_INT8(_VAL) ((int)((_VAL) * 255.0f + 0.5f))
# define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
# define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n.
# ifdef _WIN32
@ -896,6 +896,13 @@ int ImStrnicmp(const char* str1, const char* str2, int count)
return d ;
}
void ImStrncpy ( char * dst , const char * src , int count )
{
if ( count < 1 ) return ;
strncpy ( dst , src , ( size_t ) count ) ;
dst [ count - 1 ] = 0 ;
}
char * ImStrdup ( const char * str )
{
size_t len = strlen ( str ) + 1 ;
@ -994,7 +1001,6 @@ ImU32 ImHash(const void* data, int data_size, ImU32 seed)
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller.
if ( c = = ' # ' & & current [ 0 ] = = ' # ' & & current [ 1 ] = = ' # ' )
crc = seed ;
crc = ( crc > > 8 ) ^ crc32_lut [ ( crc & 0xFF ) ^ c ] ;
}
}
@ -1186,13 +1192,27 @@ ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in)
ImU32 ImGui : : ColorConvertFloat4ToU32 ( const ImVec4 & in )
{
ImU32 out ;
out = ( ( ImU32 ) IM_F32_TO_INT8 ( ImSaturate ( in . x ) ) ) ;
out | = ( ( ImU32 ) IM_F32_TO_INT8 ( ImSaturate ( in . y ) ) ) < < 8 ;
out | = ( ( ImU32 ) IM_F32_TO_INT8 ( ImSaturate ( in . z ) ) ) < < 16 ;
out | = ( ( ImU32 ) IM_F32_TO_INT8 ( ImSaturate ( in . w ) ) ) < < 24 ;
out = ( ( ImU32 ) IM_F32_TO_INT8 _SAT( in . x ) ) ;
out | = ( ( ImU32 ) IM_F32_TO_INT8 _SAT( in . y ) ) < < 8 ;
out | = ( ( ImU32 ) IM_F32_TO_INT8 _SAT( in . z ) ) < < 16 ;
out | = ( ( ImU32 ) IM_F32_TO_INT8 _SAT( in . w ) ) < < 24 ;
return out ;
}
ImU32 ImGui : : GetColorU32 ( ImGuiCol idx , float alpha_mul )
{
ImVec4 c = GImGui - > Style . Colors [ idx ] ;
c . w * = GImGui - > Style . Alpha * alpha_mul ;
return ImGui : : ColorConvertFloat4ToU32 ( c ) ;
}
ImU32 ImGui : : GetColorU32 ( const ImVec4 & col )
{
ImVec4 c = col ;
c . w * = GImGui - > Style . Alpha ;
return ImGui : : ColorConvertFloat4ToU32 ( c ) ;
}
// Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592
// Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
void ImGui : : ColorConvertRGBtoHSV ( float r , float g , float b , float & out_h , float & out_s , float & out_v )
@ -1297,7 +1317,7 @@ void ImGuiStorage::Clear()
}
// std::lower_bound but without the bullshit
static ImVector < ImGuiStorage : : Pair > : : iterator LowerBound ( ImVector < ImGuiStorage : : Pair > & data , Im U32 key )
static ImVector < ImGuiStorage : : Pair > : : iterator LowerBound ( ImVector < ImGuiStorage : : Pair > & data , Im GuiID key )
{
ImVector < ImGuiStorage : : Pair > : : iterator first = data . begin ( ) ;
ImVector < ImGuiStorage : : Pair > : : iterator last = data . end ( ) ;
@ -1319,7 +1339,7 @@ static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::
return first ;
}
int ImGuiStorage : : GetInt ( Im U32 key , int default_val ) const
int ImGuiStorage : : GetInt ( Im GuiID key , int default_val ) const
{
ImVector < Pair > : : iterator it = LowerBound ( const_cast < ImVector < ImGuiStorage : : Pair > & > ( Data ) , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
@ -1327,12 +1347,12 @@ int ImGuiStorage::GetInt(ImU32 key, int default_val) const
return it - > val_i ;
}
bool ImGuiStorage : : GetBool ( Im U32 key , bool default_val ) const
bool ImGuiStorage : : GetBool ( Im GuiID key , bool default_val ) const
{
return GetInt ( key , default_val ? 1 : 0 ) ! = 0 ;
}
float ImGuiStorage : : GetFloat ( Im U32 key , float default_val ) const
float ImGuiStorage : : GetFloat ( Im GuiID key , float default_val ) const
{
ImVector < Pair > : : iterator it = LowerBound ( const_cast < ImVector < ImGuiStorage : : Pair > & > ( Data ) , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
@ -1379,7 +1399,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
}
// FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame)
void ImGuiStorage : : SetInt ( Im U32 key , int val )
void ImGuiStorage : : SetInt ( Im GuiID key , int val )
{
ImVector < Pair > : : iterator it = LowerBound ( Data , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
@ -1390,12 +1410,12 @@ void ImGuiStorage::SetInt(ImU32 key, int val)
it - > val_i = val ;
}
void ImGuiStorage : : SetBool ( Im U32 key , bool val )
void ImGuiStorage : : SetBool ( Im GuiID key , bool val )
{
SetInt ( key , val ? 1 : 0 ) ;
}
void ImGuiStorage : : SetFloat ( Im U32 key , float val )
void ImGuiStorage : : SetFloat ( Im GuiID key , float val )
{
ImVector < Pair > : : iterator it = LowerBound ( Data , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
@ -1406,7 +1426,7 @@ void ImGuiStorage::SetFloat(ImU32 key, float val)
it - > val_f = val ;
}
void ImGuiStorage : : SetVoidPtr ( Im U32 key , void * val )
void ImGuiStorage : : SetVoidPtr ( Im GuiID key , void * val )
{
ImVector < Pair > : : iterator it = LowerBound ( Data , key ) ;
if ( it = = Data . end ( ) | | it - > key ! = key )
@ -1432,7 +1452,7 @@ ImGuiTextFilter::ImGuiTextFilter(const char* default_filter)
{
if ( default_filter )
{
Im FormatString( InputBuf , IM_ARRAYSIZE ( InputBuf ) , " %s " , default_filter ) ;
Im Strncpy( InputBuf , default_filter , IM_ARRAYSIZE ( InputBuf ) ) ;
Build ( ) ;
}
else
@ -1614,12 +1634,14 @@ float ImGuiSimpleColumns::CalcExtraSpace(float avail_w)
static void SetCursorPosYAndSetupDummyPrevLine ( float pos_y , float line_height )
{
// Set ting those fields so that SetScrollHere() can properly function after the end of our clipper usage.
// If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
// Set cursor position and a few other things so that SetScrollHere() and Columns() can work when seeking cursor.
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. Consider moving within SetCursorXXX functions?
ImGui : : SetCursorPosY ( pos_y ) ;
ImGuiWindow * window = ImGui : : GetCurrentWindow ( ) ;
window - > DC . CursorPosPrevLine . y = window - > DC . CursorPos . y - line_height ;
window - > DC . PrevLineHeight = ( line_height - GImGui - > Style . ItemSpacing . y ) ;
window - > DC . CursorPosPrevLine . y = window - > DC . CursorPos . y - line_height ; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage.
window - > DC . PrevLineHeight = ( line_height - GImGui - > Style . ItemSpacing . y ) ; // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
if ( window - > DC . ColumnsCount > 1 )
window - > DC . ColumnsCellMinY = window - > DC . CursorPos . y ; // Setting this so that cell Y position are set properly
}
// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
@ -1672,8 +1694,9 @@ bool ImGuiListClipper::Step()
if ( ItemsCount = = 1 ) { ItemsCount = - 1 ; return false ; }
float items_height = ImGui : : GetCursorPosY ( ) - StartPosY ;
IM_ASSERT ( items_height > 0.0f ) ; // If this triggers, it means Item 0 hasn't moved the cursor vertically
ImGui : : SetCursorPosY ( StartPosY ) ; // Rewind cursor so we can Begin() again, this time with a known height.
Begin ( ItemsCount , items_height ) ;
Begin ( ItemsCount - 1 , items_height ) ;
DisplayStart + + ;
DisplayEnd + + ;
StepNo = 3 ;
return true ;
}
@ -1765,6 +1788,12 @@ ImGuiID ImGuiWindow::GetID(const void* ptr)
return id ;
}
ImGuiID ImGuiWindow : : GetIDNoKeepAlive ( const char * str , const char * str_end )
{
ImGuiID seed = IDStack . back ( ) ;
return ImHash ( str , str_end ? ( int ) ( str_end - str ) : 0 , seed ) ;
}
//-----------------------------------------------------------------------------
// Internal API exposed in imgui_internal.h
//-----------------------------------------------------------------------------
@ -1823,7 +1852,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_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->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255) , 4); // Debug
window - > DC . PrevLineHeight = line_height ;
window - > DC . PrevLineTextBaseOffset = text_base_offset ;
@ -1947,8 +1976,7 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
else if ( wrap_pos_x > 0.0f )
wrap_pos_x + = window - > Pos . x - window - > Scroll . 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 ;
return ImMax ( wrap_pos_x - pos . x , 1.0f ) ;
}
//-----------------------------------------------------------------------------
@ -2235,14 +2263,11 @@ void ImGui::NewFrame()
window - > SizeFull * = scale ;
}
}
else
else if ( ! ( window - > Flags & ImGuiWindowFlags_NoScrollWithMouse ) )
{
// Scroll
if ( ! ( window - > Flags & ImGuiWindowFlags_NoScrollWithMouse ) )
{
const int scroll_lines = ( window - > Flags & ImGuiWindowFlags_ComboBox ) ? 3 : 5 ;
SetWindowScrollY ( window , window - > Scroll . y - g . IO . MouseWheel * window - > CalcFontSize ( ) * scroll_lines ) ;
}
const int scroll_lines = ( window - > Flags & ImGuiWindowFlags_ComboBox ) ? 3 : 5 ;
SetWindowScrollY ( window , window - > Scroll . y - g . IO . MouseWheel * window - > CalcFontSize ( ) * scroll_lines ) ;
}
}
@ -2260,6 +2285,15 @@ void ImGui::NewFrame()
window - > Accessed = false ;
}
// Closing the focused window restore focus to the first active root window in descending z-order
if ( g . FocusedWindow & & ! g . FocusedWindow - > WasActive )
for ( int i = g . Windows . Size - 1 ; i > = 0 ; i - - )
if ( g . Windows [ i ] - > WasActive & & ! ( g . Windows [ i ] - > Flags & ImGuiWindowFlags_ChildWindow ) )
{
FocusWindow ( g . Windows [ i ] ) ;
break ;
}
// No window should be open at the beginning of the frame.
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
g . CurrentWindowStack . resize ( 0 ) ;
@ -2670,10 +2704,10 @@ void ImGui::Render()
const ImVec2 size = cursor_data . Size ;
const ImTextureID tex_id = g . IO . Fonts - > TexID ;
g . OverlayDrawList . PushTextureID ( tex_id ) ;
g . OverlayDrawList . AddImage ( tex_id , pos + ImVec2 ( 1 , 0 ) , pos + ImVec2 ( 1 , 0 ) + size , cursor_data . TexUvMin [ 1 ] , cursor_data . TexUvMax [ 1 ] , 0x30000000 ) ; // Shadow
g . OverlayDrawList . AddImage ( tex_id , pos + ImVec2 ( 2 , 0 ) , pos + ImVec2 ( 2 , 0 ) + size , cursor_data . TexUvMin [ 1 ] , cursor_data . TexUvMax [ 1 ] , 0x30000000 ) ; // Shadow
g . OverlayDrawList . AddImage ( tex_id , pos , pos + size , cursor_data . TexUvMin [ 1 ] , cursor_data . TexUvMax [ 1 ] , 0xFF000000 ) ; // Black border
g . OverlayDrawList . AddImage ( tex_id , pos , pos + size , cursor_data . TexUvMin [ 0 ] , cursor_data . TexUvMax [ 0 ] , 0xFFFFFFFF ) ; // White fill
g . OverlayDrawList . AddImage ( tex_id , pos + ImVec2 ( 1 , 0 ) , pos + ImVec2 ( 1 , 0 ) + size , cursor_data . TexUvMin [ 1 ] , cursor_data . TexUvMax [ 1 ] , IM_COL32 ( 0 , 0 , 0 , 48 ) ) ; // Shadow
g . OverlayDrawList . AddImage ( tex_id , pos + ImVec2 ( 2 , 0 ) , pos + ImVec2 ( 2 , 0 ) + size , cursor_data . TexUvMin [ 1 ] , cursor_data . TexUvMax [ 1 ] , IM_COL32 ( 0 , 0 , 0 , 48 ) ) ; // Shadow
g . OverlayDrawList . AddImage ( tex_id , pos , pos + size , cursor_data . TexUvMin [ 1 ] , cursor_data . TexUvMax [ 1 ] , IM_COL32 ( 0 , 0 , 0 , 255 ) ) ; // Black border
g . OverlayDrawList . AddImage ( tex_id , pos , pos + size , cursor_data . TexUvMin [ 0 ] , cursor_data . TexUvMax [ 0 ] , IM_COL32 ( 255 , 255 , 255 , 255 ) ) ; // White fill
g . OverlayDrawList . PopTextureID ( ) ;
}
if ( ! g . OverlayDrawList . VtxBuffer . empty ( ) )
@ -3897,16 +3931,10 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
else
PushClipRect ( fullscreen_rect . Min , fullscreen_rect . Max , true ) ;
// New windows appears in front
if ( ! window_was_active )
{
window - > AutoPosLastDirection = - 1 ;
if ( ! ( flags & ImGuiWindowFlags_NoFocusOnAppearing ) )
if ( ! ( flags & ( ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip ) ) | | ( flags & ImGuiWindowFlags_Popup ) )
FocusWindow ( window ) ;
// Popup first latch mouse position, will position itself when it appears next frame
window - > AutoPosLastDirection = - 1 ;
if ( ( flags & ImGuiWindowFlags_Popup ) ! = 0 & & ! window_pos_set_by_api )
window - > PosFloat = g . IO . MousePos ;
}
@ -4083,7 +4111,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if ( window - > ScrollTarget . y < FLT_MAX )
{
float center_ratio = window - > ScrollTargetCenterRatio . y ;
window - > Scroll . y = window - > ScrollTarget . y - ( ( 1.0f - center_ratio ) * window - > TitleBarHeight ( ) ) - ( center_ratio * window - > SizeFull . y ) ;
window - > Scroll . y = window - > ScrollTarget . y - ( ( 1.0f - center_ratio ) * ( window - > TitleBarHeight ( ) + window - > MenuBarHeight ( ) ) ) - ( center_ratio * window - > SizeFull . y ) ;
window - > ScrollTarget . y = FLT_MAX ;
}
window - > Scroll = ImMax ( window - > Scroll , ImVec2 ( 0.0f , 0.0f ) ) ;
@ -4209,6 +4237,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// Setup drawing context
window - > DC . IndentX = 0.0f + window - > WindowPadding . x - window - > Scroll . x ;
window - > DC . GroupOffsetX = 0.0f ;
window - > DC . ColumnsOffsetX = 0.0f ;
window - > DC . CursorStartPos = window - > Pos + ImVec2 ( window - > DC . IndentX + window - > DC . ColumnsOffsetX , window - > TitleBarHeight ( ) + window - > MenuBarHeight ( ) + window - > WindowPadding . y - window - > Scroll . y ) ;
window - > DC . CursorPos = window - > DC . CursorStartPos ;
@ -4243,6 +4272,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if ( window - > AutoFitFramesY > 0 )
window - > AutoFitFramesY - - ;
// New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there)
if ( ! window_was_active & & ! ( flags & ImGuiWindowFlags_NoFocusOnAppearing ) )
if ( ! ( flags & ( ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip ) ) | | ( flags & ImGuiWindowFlags_Popup ) )
FocusWindow ( window ) ;
// Title bar
if ( ! ( flags & ImGuiWindowFlags_NoTitleBar ) )
{
@ -4266,7 +4300,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if ( style . WindowTitleAlign & ImGuiAlign_Center ) pad_right = pad_left ;
if ( pad_left ) text_min . x + = g . FontSize + style . ItemInnerSpacing . x ;
if ( pad_right ) text_max . x - = g . FontSize + style . ItemInnerSpacing . x ;
RenderTextClipped ( text_min , text_max , name , NULL , & text_size , style . WindowTitleAlign , NULL , & clip_max ) ;
ImVec2 clip_min = ImVec2 ( text_min . x , window - > Pos . y ) ;
RenderTextClipped ( text_min , text_max , name , NULL , & text_size , style . WindowTitleAlign , & clip_min , & clip_max ) ;
}
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
@ -4907,8 +4942,7 @@ void ImGui::SetWindowFocus(const char* name)
{
if ( name )
{
ImGuiWindow * window = FindWindowByName ( name ) ;
if ( window )
if ( ImGuiWindow * window = FindWindowByName ( name ) )
FocusWindow ( window ) ;
}
else
@ -5071,13 +5105,13 @@ ImVec2 ImGui::GetCursorPos()
float ImGui : : GetCursorPosX ( )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow Read ( ) ;
return window - > DC . CursorPos . x - window - > Pos . x + window - > Scroll . x ;
}
float ImGui : : GetCursorPosY ( )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow Read ( ) ;
return window - > DC . CursorPos . y - window - > Pos . y + window - > Scroll . y ;
}
@ -5118,6 +5152,7 @@ void ImGui::SetCursorScreenPos(const ImVec2& screen_pos)
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
window - > DC . CursorPos = screen_pos ;
window - > DC . CursorMaxPos = ImMax ( window - > DC . CursorMaxPos , window - > DC . CursorPos ) ;
}
float ImGui : : GetScrollX ( )
@ -5152,7 +5187,7 @@ void ImGui::SetScrollX(float scroll_x)
void ImGui : : SetScrollY ( float scroll_y )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
window - > ScrollTarget . y = scroll_y + window - > TitleBarHeight ( ) ; // title bar height canceled out when using ScrollTargetRelY
window - > ScrollTarget . y = scroll_y + window - > TitleBarHeight ( ) + window - > MenuBarHeight ( ) ; // title bar height canceled out when using ScrollTargetRelY
window - > ScrollTargetCenterRatio . y = 0.0f ;
}
@ -5355,9 +5390,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
const ImVec2 text_size = CalcTextSize ( text_begin , text_end , false , wrap_width ) ;
// Account of baseline offset
ImVec2 text_pos = window - > DC . CursorPos ;
text_pos . y + = window - > DC . CurrentLineTextBaseOffset ;
ImVec2 text_pos ( window - > DC . CursorPos . x , window - > DC . CursorPos . y + window - > DC . CurrentLineTextBaseOffset ) ;
ImRect bb ( text_pos , text_pos + text_size ) ;
ItemSize ( text_size ) ;
if ( ! ItemAdd ( bb , NULL ) )
@ -6148,7 +6181,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
const char * text_begin = g . TempBuffer ;
const char * text_end = text_begin + ImFormatStringV ( g . TempBuffer , IM_ARRAYSIZE ( g . TempBuffer ) , fmt , args ) ;
const ImVec2 label_size = CalcTextSize ( text_begin , text_end , tru e) ;
const ImVec2 label_size = CalcTextSize ( text_begin , text_end , fals e) ;
const float text_base_offset_y = ImMax ( 0.0f , window - > DC . CurrentLineTextBaseOffset ) ; // Latch before ItemSize changes it
const float line_height = ImMax ( ImMin ( window - > DC . CurrentLineHeight , g . FontSize + g . Style . FramePadding . y * 2 ) , g . FontSize ) ;
const ImRect bb ( window - > DC . CursorPos , window - > DC . CursorPos + ImVec2 ( g . FontSize + ( label_size . x > 0.0f ? ( label_size . x + style . FramePadding . x * 2 ) : 0.0f ) , ImMax ( line_height , label_size . y ) ) ) ; // Empty text doesn't add padding
@ -6158,7 +6191,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
// Render
RenderBullet ( bb . Min + ImVec2 ( style . FramePadding . x + g . FontSize * 0.5f , line_height * 0.5f ) ) ;
RenderText ( bb . Min + ImVec2 ( g . FontSize + style . FramePadding . x * 2 , text_base_offset_y ) , text_begin , text_end );
RenderText ( bb . Min + ImVec2 ( g . FontSize + style . FramePadding . x * 2 , text_base_offset_y ) , text_begin , text_end , false );
}
void ImGui : : BulletText ( const char * fmt , . . . )
@ -7400,6 +7433,7 @@ static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n)
static bool STB_TEXTEDIT_INSERTCHARS ( STB_TEXTEDIT_STRING * obj , int pos , const ImWchar * new_text , int new_text_len )
{
const int text_len = obj - > CurLenW ;
IM_ASSERT ( pos < = text_len ) ;
if ( new_text_len + text_len + 1 > obj - > Text . Size )
return false ;
@ -7607,10 +7641,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// NB: we are only allowed to access 'edit_state' if we are the active widget.
ImGuiTextEditState & edit_state = g . InputTextState ;
const bool is_ctrl_down = io . KeyCtrl ;
const bool is_shift_down = io . KeyShift ;
const bool is_alt_down = io . KeyAlt ;
const bool is_super_down = io . KeySuper ;
const bool focus_requested = FocusableItemRegister ( window , g . ActiveId = = id , ( flags & ( ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput ) ) = = 0 ) ; // Using completion callback disable keyboard tabbing
const bool focus_requested_by_code = focus_requested & & ( window - > FocusIdxAllCounter = = window - > FocusIdxAllRequestCurrent ) ;
const bool focus_requested_by_tab = focus_requested & & ! focus_requested_by_code ;
@ -7622,7 +7652,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
g . MouseCursor = ImGuiMouseCursor_TextInput ;
}
const bool user_clicked = hovered & & io . MouseClicked [ 0 ] ;
const bool user_scrolled = is_multiline & & g . ActiveId = = 0 & & edit_state . Id = = id & & g . ActiveIdPreviousFrame = = draw_window - > GetID ( " #SCROLLY " ) ;
const bool user_scrolled = is_multiline & & g . ActiveId = = 0 & & edit_state . Id = = id & & g . ActiveIdPreviousFrame = = draw_window - > GetID NoKeepAlive ( " #SCROLLY " ) ;
bool select_all = ( g . ActiveId ! = id ) & & ( flags & ImGuiInputTextFlags_AutoSelectAll ) ! = 0 ;
if ( focus_requested | | user_clicked | | user_scrolled )
@ -7633,9 +7663,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar)
// From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode)
const int prev_len_w = edit_state . CurLenW ;
edit_state . Text . resize ( buf_size + 1 ) ; // wchar count <= utf -8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
edit_state . InitialText . resize ( buf_size + 1 ) ; // utf -8. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
Im FormatString ( edit_state . InitialText . Data , edit_state. InitialText . Size , " %s " , buf ) ;
edit_state . Text . resize ( buf_size + 1 ) ; // wchar count <= UTF -8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
edit_state . InitialText . resize ( buf_size + 1 ) ; // UTF -8. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
Im Strncpy ( edit_state . InitialText . Data , buf, edit_state. InitialText . Size ) ;
const char * buf_end = NULL ;
edit_state . CurLenW = ImTextStrFromUtf8 ( edit_state . Text . Data , edit_state . Text . Size , buf , NULL , & buf_end ) ;
edit_state . CurLenA = ( int ) ( buf_end - buf ) ; // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8.
@ -7660,7 +7690,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
}
if ( flags & ImGuiInputTextFlags_AlwaysInsertMode )
edit_state . StbState . insert_mode = true ;
if ( ! is_multiline & & ( focus_requested_by_tab | | ( user_clicked & & i s_ctrl_down ) ) )
if ( ! is_multiline & & ( focus_requested_by_tab | | ( user_clicked & & i o. KeyCtrl ) ) )
select_all = true ;
}
SetActiveID ( id , window ) ;
@ -7695,15 +7725,16 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
g . ActiveIdAllowOverlap = ! io . MouseDown [ 0 ] ;
// Edit in progress
const float mouse_x = ( g. IO . MousePos . x - frame_bb . Min . x - style . FramePadding . x ) + edit_state . ScrollX ;
const float mouse_y = ( is_multiline ? ( g. IO . MousePos . y - draw_window - > DC . CursorPos . y - style . FramePadding . y ) : ( g . FontSize * 0.5f ) ) ;
const float mouse_x = ( io . MousePos . x - frame_bb . Min . x - style . FramePadding . x ) + edit_state . ScrollX ;
const float mouse_y = ( is_multiline ? ( io . MousePos . y - draw_window - > DC . CursorPos . y - style . FramePadding . y ) : ( g . FontSize * 0.5f ) ) ;
if ( select_all | | ( hovered & & ! io . DoubleClickSelectsWord & & io . MouseDoubleClicked [ 0 ] ) )
const bool osx_double_click_selects_words = io . OSXBehaviors ; // OS X style: Double click selects by word instead of selecting whole text
if ( select_all | | ( hovered & & ! osx_double_click_selects_words & & io . MouseDoubleClicked [ 0 ] ) )
{
edit_state . SelectAll ( ) ;
edit_state . SelectedAllMouseLock = true ;
}
else if ( hovered & & io. DoubleClickSelectsWord & & io . MouseDoubleClicked [ 0 ] )
else if ( hovered & & osx_double_click_selects_words & & io . MouseDoubleClicked [ 0 ] )
{
// Select a word only, OS X style (by simulating keystrokes)
edit_state . OnKeyPressed ( STB_TEXTEDIT_K_WORDLEFT ) ;
@ -7723,14 +7754,14 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
if ( edit_state . SelectedAllMouseLock & & ! io . MouseDown [ 0 ] )
edit_state . SelectedAllMouseLock = false ;
if ( g. IO . InputCharacters [ 0 ] )
if ( io . InputCharacters [ 0 ] )
{
// Process text input (before we check for Return because using some IME will effectively send a Return?)
// We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters.
if ( ! ( i s_ctrl_down & & ! is_alt_down ) & & is_editable )
if ( ! ( i o. KeyCtrl & & ! io . KeyAlt ) & & is_editable )
{
for ( int n = 0 ; n < IM_ARRAYSIZE ( g. IO . InputCharacters ) & & g . IO . InputCharacters [ n ] ; n + + )
if ( unsigned int c = ( unsigned int ) g. IO . InputCharacters [ n ] )
for ( int n = 0 ; n < IM_ARRAYSIZE ( io. InputCharacters ) & & io . InputCharacters [ n ] ; n + + )
if ( unsigned int c = ( unsigned int ) io . InputCharacters [ n ] )
{
// Insert character if they pass filtering
if ( ! InputTextFilterCharacter ( & c , flags , callback , user_data ) )
@ -7745,22 +7776,31 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Handle various key-presses
bool cancel_edit = false ;
const int k_mask = ( is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0 ) ;
const bool is_shortcutkey_only = ( io . ShortcutsUseSuperKey ? ( is_super_down & & ! is_alt_down & & ! is_shift_down & & ! is_ctrl_down ) : ( is_ctrl_down & & ! is_alt_down & & ! is_shift_down & & ! is_super_down ) ) ;
const bool is_wordmove_key_down = ( io . WordMovementUsesAltKey ? io . KeyAlt : io . KeyCtrl ) ;
if ( IsKeyPressedMap ( ImGuiKey_LeftArrow ) ) { edit_state . OnKeyPressed ( is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_RightArrow ) ) { edit_state . OnKeyPressed ( is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask ) ; }
else if ( is_multiline & & IsKeyPressedMap ( ImGuiKey_UpArrow ) ) { if ( is_ctrl_down ) SetWindowScrollY ( draw_window , draw_window - > Scroll . y - g . FontSize ) ; else edit_state . OnKeyPressed ( STB_TEXTEDIT_K_UP | k_mask ) ; }
else if ( is_multiline & & IsKeyPressedMap ( ImGuiKey_DownArrow ) ) { if ( is_ctrl_down ) SetWindowScrollY ( draw_window , draw_window - > Scroll . y + g . FontSize ) ; else edit_state . OnKeyPressed ( STB_TEXTEDIT_K_DOWN | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Home ) ) { edit_state . OnKeyPressed ( is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_End ) ) { edit_state . OnKeyPressed ( is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask ) ; }
const int k_mask = ( io . KeyShift ? STB_TEXTEDIT_K_SHIFT : 0 ) ;
const bool is_shortcut_key_only = ( io . OSXBehaviors ? ( io . KeySuper & & ! io . KeyCtrl ) : ( io . KeyCtrl & & ! io . KeySuper ) ) & & ! io . KeyAlt & & ! io . KeyShift ; // OS X style: Shortcuts using Cmd/Super instead of Ctrl
const bool is_wordmove_key_down = io . OSXBehaviors ? io . KeyAlt : io . KeyCtrl ; // OS X style: Text editing cursor movement using Alt instead of Ctrl
const bool is_startend_key_down = io . OSXBehaviors & & io . KeySuper & & ! io . KeyCtrl & & ! io . KeyAlt ; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
if ( IsKeyPressedMap ( ImGuiKey_LeftArrow ) ) { edit_state . OnKeyPressed ( ( is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT ) | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_RightArrow ) ) { edit_state . OnKeyPressed ( ( is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT ) | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_UpArrow ) & & is_multiline ) { if ( io . KeyCtrl ) SetWindowScrollY ( draw_window , ImMax ( draw_window - > Scroll . y - g . FontSize , 0.0f ) ) ; else edit_state . OnKeyPressed ( ( is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP ) | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_DownArrow ) & & is_multiline ) { if ( io . KeyCtrl ) SetWindowScrollY ( draw_window , ImMin ( draw_window - > Scroll . y + g . FontSize , GetScrollMaxY ( ) ) ) ; else edit_state . OnKeyPressed ( ( is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN ) | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Home ) ) { edit_state . OnKeyPressed ( io . KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_End ) ) { edit_state . OnKeyPressed ( io . KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Delete ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_DELETE | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Backspace ) & & is_editable ) { if ( is_ctrl_down & & ! edit_state . HasSelection ( ) ) edit_state . OnKeyPressed ( STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT ) ; edit_state . OnKeyPressed ( STB_TEXTEDIT_K_BACKSPACE | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Backspace ) & & is_editable )
{
if ( ! edit_state . HasSelection ( ) )
{
if ( is_wordmove_key_down ) edit_state . OnKeyPressed ( STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT ) ;
else if ( io . OSXBehaviors & & io . KeySuper & & ! io . KeyAlt & & ! io . KeyCtrl ) edit_state . OnKeyPressed ( STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT ) ;
}
edit_state . OnKeyPressed ( STB_TEXTEDIT_K_BACKSPACE | k_mask ) ;
}
else if ( IsKeyPressedMap ( ImGuiKey_Enter ) )
{
bool ctrl_enter_for_new_line = ( flags & ImGuiInputTextFlags_CtrlEnterForNewLine ) ! = 0 ;
if ( ! is_multiline | | ( ctrl_enter_for_new_line & & ! is_ctrl_down ) | | ( ! ctrl_enter_for_new_line & & is_ctrl_down ) )
if ( ! is_multiline | | ( ctrl_enter_for_new_line & & ! i o. KeyCtrl ) | | ( ! ctrl_enter_for_new_line & & i o. KeyCtrl ) )
{
SetActiveID ( 0 ) ;
enter_pressed = true ;
@ -7772,30 +7812,30 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
edit_state . OnKeyPressed ( ( int ) c ) ;
}
}
else if ( ( flags & ImGuiInputTextFlags_AllowTabInput ) & & IsKeyPressedMap ( ImGuiKey_Tab ) & & ! i s_ctrl_down & & ! is_shift_down & & ! is_alt_down & & is_editable )
else if ( ( flags & ImGuiInputTextFlags_AllowTabInput ) & & IsKeyPressedMap ( ImGuiKey_Tab ) & & ! i o. KeyCtrl & & ! io . KeyShift & & ! io . KeyAlt & & is_editable )
{
unsigned int c = ' \t ' ; // Insert TAB
if ( InputTextFilterCharacter ( & c , flags , callback , user_data ) )
edit_state . OnKeyPressed ( ( int ) c ) ;
}
else if ( IsKeyPressedMap ( ImGuiKey_Escape ) ) { SetActiveID ( 0 ) ; cancel_edit = true ; }
else if ( is_shortcut key_only & & IsKeyPressedMap ( ImGuiKey_Z ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_UNDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_shortcut key_only & & IsKeyPressedMap ( ImGuiKey_Y ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_REDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_shortcut key_only & & IsKeyPressedMap ( ImGuiKey_A ) ) { edit_state . SelectAll ( ) ; edit_state . CursorFollow = true ; }
else if ( is_shortcut key_only & & ! is_password & & ( ( IsKeyPressedMap ( ImGuiKey_X ) & & is_editable ) | | IsKeyPressedMap ( ImGuiKey_C ) ) & & ( ! is_multiline | | edit_state . HasSelection ( ) ) )
else if ( is_shortcut _ key_only & & IsKeyPressedMap ( ImGuiKey_Z ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_UNDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_shortcut _ key_only & & IsKeyPressedMap ( ImGuiKey_Y ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_REDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_shortcut _ key_only & & IsKeyPressedMap ( ImGuiKey_A ) ) { edit_state . SelectAll ( ) ; edit_state . CursorFollow = true ; }
else if ( is_shortcut _ key_only & & ! is_password & & ( ( IsKeyPressedMap ( ImGuiKey_X ) & & is_editable ) | | IsKeyPressedMap ( ImGuiKey_C ) ) & & ( ! is_multiline | | edit_state . HasSelection ( ) ) )
{
// Cut, Copy
const bool cut = IsKeyPressedMap ( ImGuiKey_X ) ;
if ( cut & & ! edit_state . HasSelection ( ) )
edit_state . SelectAll ( ) ;
if ( g. IO . SetClipboardTextFn )
if ( io . SetClipboardTextFn )
{
const int ib = edit_state . HasSelection ( ) ? ImMin ( edit_state . StbState . select_start , edit_state . StbState . select_end ) : 0 ;
const int ie = edit_state . HasSelection ( ) ? ImMax ( edit_state . StbState . select_start , edit_state . StbState . select_end ) : edit_state . CurLenW ;
edit_state . TempTextBuffer . resize ( ( ie - ib ) * 4 + 1 ) ;
ImTextStrToUtf8 ( edit_state . TempTextBuffer . Data , edit_state . TempTextBuffer . Size , edit_state . Text . Data + ib , edit_state . Text . Data + ie ) ;
g. IO . SetClipboardTextFn ( edit_state . TempTextBuffer . Data ) ;
io . SetClipboardTextFn ( edit_state . TempTextBuffer . Data ) ;
}
if ( cut )
@ -7804,35 +7844,32 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
stb_textedit_cut ( & edit_state , & edit_state . StbState ) ;
}
}
else if ( is_shortcut key_only & & IsKeyPressedMap ( ImGuiKey_V ) & & is_editable )
else if ( is_shortcut _ key_only & & IsKeyPressedMap ( ImGuiKey_V ) & & is_editable )
{
// Paste
if ( g . IO . GetClipboardTextFn )
if ( const char * clipboard = io . GetClipboardTextFn ? io . GetClipboardTextFn ( ) : NULL )
{
if ( const char * clipboard = g . IO . GetClipboardTextFn ( ) )
// Filter pasted buffer
const int clipboard_len = ( int ) strlen ( clipboard ) ;
ImWchar * clipboard_filtered = ( ImWchar * ) ImGui : : MemAlloc ( ( clipboard_len + 1 ) * sizeof ( ImWchar ) ) ;
int clipboard_filtered_len = 0 ;
for ( const char * s = clipboard ; * s ; )
{
// Remove new-line from pasted buffer
const int clipboard_len = ( int ) strlen ( clipboard ) ;
ImWchar * clipboard_filtered = ( ImWchar * ) ImGui : : MemAlloc ( ( clipboard_len + 1 ) * sizeof ( ImWchar ) ) ;
int clipboard_filtered_len = 0 ;
for ( const char * s = clipboard ; * s ; )
{
unsigned int c ;
s + = ImTextCharFromUtf8 ( & c , s , NULL ) ;
if ( c = = 0 )
break ;
if ( c > = 0x10000 | | ! InputTextFilterCharacter ( & c , flags , callback , user_data ) )
continue ;
clipboard_filtered [ clipboard_filtered_len + + ] = ( ImWchar ) c ;
}
clipboard_filtered [ clipboard_filtered_len ] = 0 ;
if ( clipboard_filtered_len > 0 ) // If everything was filtered, ignore the pasting operation
{
stb_textedit_paste ( & edit_state , & edit_state . StbState , clipboard_filtered , clipboard_filtered_len ) ;
edit_state . CursorFollow = true ;
}
ImGui : : MemFree ( clipboard_filtered ) ;
unsigned int c ;
s + = ImTextCharFromUtf8 ( & c , s , NULL ) ;
if ( c = = 0 )
break ;
if ( c > = 0x10000 | | ! InputTextFilterCharacter ( & c , flags , callback , user_data ) )
continue ;
clipboard_filtered [ clipboard_filtered_len + + ] = ( ImWchar ) c ;
}
clipboard_filtered [ clipboard_filtered_len ] = 0 ;
if ( clipboard_filtered_len > 0 ) // If everything was filtered, ignore the pasting operation
{
stb_textedit_paste ( & edit_state , & edit_state . StbState , clipboard_filtered , clipboard_filtered_len ) ;
edit_state . CursorFollow = true ;
}
ImGui : : MemFree ( clipboard_filtered ) ;
}
}
@ -7841,7 +7878,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Restore initial value
if ( is_editable )
{
Im FormatString( buf , buf_size , " %s " , edit_state . InitialText . Data ) ;
Im Strncpy( buf , edit_state . InitialText . Data , buf_size ) ;
value_changed = true ;
}
}
@ -7927,28 +7964,33 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Copy back to user buffer
if ( is_editable & & strcmp ( edit_state . TempTextBuffer . Data , buf ) ! = 0 )
{
Im FormatString( buf , buf_size , " %s " , edit_state . TempTextBuffer . Data ) ;
Im Strncpy( buf , edit_state . TempTextBuffer . Data , buf_size ) ;
value_changed = true ;
}
}
}
// Render
// Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on.
const char * buf_display = ( g . ActiveId = = id & & is_editable ) ? edit_state . TempTextBuffer . Data : buf ; buf = NULL ;
if ( ! is_multiline )
RenderFrame ( frame_bb . Min , frame_bb . Max , GetColorU32 ( ImGuiCol_FrameBg ) , true , style . FrameRounding ) ;
// Render
const ImVec4 clip_rect ( frame_bb . Min . x , frame_bb . Min . y , frame_bb . Min . x + size . x , frame_bb . Min . y + size . y ) ; // Not using frame_bb.Max because we have adjusted size
ImVec2 render_pos = is_multiline ? draw_window - > DC . CursorPos : frame_bb . Min + style . FramePadding ;
ImVec2 text_size ( 0.f , 0.f ) ;
if ( g . ActiveId = = id | | ( edit_state . Id = = id & & is_multiline & & g . ActiveId = = draw_window - > GetID ( " #SCROLLY " ) ) )
const bool is_currently_scrolling = ( edit_state . Id = = id & & is_multiline & & g . ActiveId = = draw_window - > GetIDNoKeepAlive ( " #SCROLLY " ) ) ;
if ( g . ActiveId = = id | | is_currently_scrolling )
{
edit_state . CursorAnim + = g. IO . DeltaTime ;
edit_state . CursorAnim + = io . DeltaTime ;
// We need to:
// - Display the text (this can be more easily clipped)
// This is going to be messy. We need to:
// - Display the text (this alone can be more easily clipped)
// - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation)
// - Measure text height (for scrollbar)
// We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
// FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8.
const ImWchar * text_begin = edit_state . Text . Data ;
ImVec2 cursor_offset , select_start_offset ;
@ -8062,7 +8104,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
}
}
draw_window - > DrawList - > AddText ( g . Font , g . FontSize , render_pos - render_scroll , GetColorU32 ( ImGuiCol_Text ) , buf , buf + edit_state . CurLenA , 0.0f , is_multiline ? NULL : & clip_rect ) ;
draw_window - > DrawList - > AddText ( g . Font , g . FontSize , render_pos - render_scroll , GetColorU32 ( ImGuiCol_Text ) , buf _display , buf _display + edit_state . CurLenA , 0.0f , is_multiline ? NULL : & clip_rect ) ;
// Draw blinking cursor
bool cursor_is_visible = ( g . InputTextState . CursorAnim < = 0.0f ) | | fmodf ( g . InputTextState . CursorAnim , 1.20f ) < = 0.80f ;
@ -8080,8 +8122,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Render text only
const char * buf_end = NULL ;
if ( is_multiline )
text_size = ImVec2 ( size . x , InputTextCalcTextLenAndLineCount ( buf , & buf_end ) * g . FontSize ) ; // We don't need width
draw_window - > DrawList - > AddText ( g . Font , g . FontSize , render_pos , GetColorU32 ( ImGuiCol_Text ) , buf , buf_end , 0.0f , is_multiline ? NULL : & clip_rect ) ;
text_size = ImVec2 ( size . x , InputTextCalcTextLenAndLineCount ( buf _display , & buf_end ) * g . FontSize ) ; // We don't need width
draw_window - > DrawList - > AddText ( g . Font , g . FontSize , render_pos , GetColorU32 ( ImGuiCol_Text ) , buf _display , buf_end , 0.0f , is_multiline ? NULL : & clip_rect ) ;
}
if ( is_multiline )
@ -8089,6 +8131,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
Dummy ( text_size + ImVec2 ( 0.0f , g . FontSize ) ) ; // Always add room to scroll an extra line
EndChildFrame ( ) ;
EndGroup ( ) ;
if ( g . ActiveId = = id | | is_currently_scrolling ) // Set LastItemId which was lost by EndChild/EndGroup, so user can use IsItemActive()
window - > DC . LastItemId = g . ActiveId ;
}
if ( is_password )
@ -8096,7 +8140,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Log as text
if ( g . LogEnabled & & ! is_password )
LogRenderedText ( render_pos , buf , NULL ) ;
LogRenderedText ( render_pos , buf _display , NULL ) ;
if ( label_size . x > 0 )
RenderText ( ImVec2 ( frame_bb . Max . x + style . ItemInnerSpacing . x , frame_bb . Min . y + style . FramePadding . y ) , label ) ;
@ -8110,14 +8154,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
bool ImGui : : InputText ( const char * label , char * buf , size_t buf_size , ImGuiInputTextFlags flags , ImGuiTextEditCallback callback , void * user_data )
{
IM_ASSERT ( ! ( flags & ImGuiInputTextFlags_Multiline ) ) ; // call InputTextMultiline()
bool ret = InputTextEx ( label , buf , ( int ) buf_size , ImVec2 ( 0 , 0 ) , flags , callback , user_data ) ;
return ret ;
return InputTextEx ( label , buf , ( int ) buf_size , ImVec2 ( 0 , 0 ) , flags , callback , user_data ) ;
}
bool ImGui : : InputTextMultiline ( const char * label , char * buf , size_t buf_size , const ImVec2 & size , ImGuiInputTextFlags flags , ImGuiTextEditCallback callback , void * user_data )
{
bool ret = InputTextEx ( label , buf , ( int ) buf_size , size , flags | ImGuiInputTextFlags_Multiline , callback , user_data ) ;
return ret ;
return InputTextEx ( label , buf , ( int ) buf_size , size , flags | ImGuiInputTextFlags_Multiline , callback , user_data ) ;
}
// NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument)
@ -8851,7 +8893,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde
RenderFrame ( bb . Min , bb . Max , GetColorU32 ( col ) , outline_border , style . FrameRounding ) ;
if ( hovered )
SetTooltip ( " Color: \n (%.2f,%.2f,%.2f,%.2f) \n #%02X%02X%02X%02X " , col . x , col . y , col . z , col . w , IM_F32_TO_INT8 ( col . x ) , IM_F32_TO_INT8 ( col . y ) , IM_F32_TO_INT8 ( col . z ) , IM_F32_TO_INT8 ( col . z ) ) ;
SetTooltip ( " Color: \n (%.2f,%.2f,%.2f,%.2f) \n #%02X%02X%02X%02X " , col . x , col . y , col . z , col . w , IM_F32_TO_INT8 _SAT ( col . x ) , IM_F32_TO_INT8 _SAT ( col . y ) , IM_F32_TO_INT8 _SAT ( col . z ) , IM_F32_TO_INT8 _SAT ( col . z ) ) ;
return pressed ;
}
@ -8898,7 +8940,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
if ( flags & ImGuiColorEditFlags_HSV )
ColorConvertRGBtoHSV ( f [ 0 ] , f [ 1 ] , f [ 2 ] , f [ 0 ] , f [ 1 ] , f [ 2 ] ) ;
int i [ 4 ] = { IM_F32_TO_INT8 ( f [ 0 ] ) , IM_F32_TO_INT8 ( f [ 1 ] ) , IM_F32_TO_INT8 ( f [ 2 ] ) , IM_F32_TO_INT8 ( f [ 3 ] ) } ;
int i [ 4 ] = { IM_F32_TO_INT8 _UNBOUND ( f [ 0 ] ) , IM_F32_TO_INT8 _UNBOUND ( f [ 1 ] ) , IM_F32_TO_INT8 _UNBOUND ( f [ 2 ] ) , IM_F32_TO_INT8 _UNBOUND ( f [ 3 ] ) } ;
bool alpha = ( flags & ImGuiColorEditFlags_Alpha ) ! = 0 ;
bool value_changed = false ;
@ -9004,7 +9046,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
// Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here
if ( IsItemHovered ( ) )
SetTooltip ( " Color: \n (%.2f,%.2f,%.2f,%.2f) \n #%02X%02X%02X%02X " , col [ 0 ] , col [ 1 ] , col [ 2 ] , col [ 3 ] , IM_F32_TO_INT8 ( col [ 0 ] ) , IM_F32_TO_INT8 ( col [ 1 ] ) , IM_F32_TO_INT8 ( col [ 2 ] ) , IM_F32_TO_INT8 ( col [ 3 ] ) ) ;
SetTooltip ( " Color: \n (%.2f,%.2f,%.2f,%.2f) \n #%02X%02X%02X%02X " , col [ 0 ] , col [ 1 ] , col [ 2 ] , col [ 3 ] , IM_F32_TO_INT8 _SAT ( col [ 0 ] ) , IM_F32_TO_INT8 _SAT ( col [ 1 ] ) , IM_F32_TO_INT8 _SAT ( col [ 2 ] ) , IM_F32_TO_INT8 _SAT ( col [ 3 ] ) ) ;
}
if ( label ! = label_display_end )
@ -9066,6 +9108,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
float bar0_pos_x = picker_pos . x + sv_picker_size + style . ItemInnerSpacing . x ;
float bar1_pos_x = bar0_pos_x + bars_width + style . ItemInnerSpacing . x ;
// Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here
if ( IsItemHovered ( ) )
SetTooltip ( " Color: \n (%.2f,%.2f,%.2f,%.2f) \n #%02X%02X%02X%02X " , col [ 0 ] , col [ 1 ] , col [ 2 ] , col [ 3 ] , IM_F32_TO_INT8_SAT ( col [ 0 ] ) , IM_F32_TO_INT8_SAT ( col [ 1 ] ) , IM_F32_TO_INT8_SAT ( col [ 2 ] ) , IM_F32_TO_INT8_SAT ( col [ 3 ] ) ) ;
float H , S , V ;
ImGui : : ColorConvertRGBtoHSV ( col [ 0 ] , col [ 1 ] , col [ 2 ] , H , S , V ) ;
@ -9245,6 +9291,12 @@ bool ImGui::IsRectVisible(const ImVec2& size)
return window - > ClipRect . Overlaps ( ImRect ( window - > DC . CursorPos , window - > DC . CursorPos + size ) ) ;
}
bool ImGui : : IsRectVisible ( const ImVec2 & rect_min , const ImVec2 & rect_max )
{
ImGuiWindow * window = GetCurrentWindowRead ( ) ;
return window - > ClipRect . Overlaps ( ImRect ( rect_min , rect_max ) ) ;
}
// Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
void ImGui : : BeginGroup ( )
{
@ -9260,7 +9312,8 @@ void ImGui::BeginGroup()
group_data . BackupLogLinePosY = window - > DC . LogLinePosY ;
group_data . AdvanceCursor = true ;
window - > DC . IndentX = window - > DC . CursorPos . x - window - > Pos . x - window - > DC . ColumnsOffsetX ;
window - > DC . GroupOffsetX = window - > DC . CursorPos . x - window - > Pos . x - window - > DC . ColumnsOffsetX ;
window - > DC . IndentX = window - > DC . GroupOffsetX ;
window - > DC . CursorMaxPos = window - > DC . CursorPos ;
window - > DC . CurrentLineHeight = 0.0f ;
window - > DC . LogLinePosY = window - > DC . CursorPos . y - 9999.0f ;
@ -9284,6 +9337,7 @@ void ImGui::EndGroup()
window - > DC . CurrentLineHeight = group_data . BackupCurrentLineHeight ;
window - > DC . CurrentLineTextBaseOffset = group_data . BackupCurrentLineTextBaseOffset ;
window - > DC . IndentX = group_data . BackupIndentX ;
window - > DC . GroupOffsetX = window - > DC . IndentX ;
window - > DC . LogLinePosY = window - > DC . CursorPos . y - 9999.0f ;
if ( group_data . AdvanceCursor )
@ -9300,7 +9354,7 @@ void ImGui::EndGroup()
// Gets back to previous line and continue with horizontal layout
// pos_x == 0 : follow right after previous item
// pos_x != 0 : align to specified x position
// pos_x != 0 : align to specified x position (relative to window/group left)
// spacing_w < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0
// spacing_w >= 0 : enforce spacing amount
void ImGui : : SameLine ( float pos_x , float spacing_w )
@ -9313,7 +9367,7 @@ void ImGui::SameLine(float pos_x, float spacing_w)
if ( pos_x ! = 0.0f )
{
if ( spacing_w < 0.0f ) spacing_w = 0.0f ;
window - > DC . CursorPos . x = window - > Pos . x - window - > Scroll . x + pos_x + spacing_w ;
window - > DC . CursorPos . x = window - > Pos . x - window - > Scroll . x + pos_x + spacing_w + window - > DC . GroupOffsetX + window - > DC . ColumnsOffsetX ;
window - > DC . CursorPos . y = window - > DC . CursorPosPrevLine . y ;
}
else
@ -9340,37 +9394,34 @@ void ImGui::NewLine()
void ImGui : : NextColumn ( )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems | | window - > DC . ColumnsCount < = 1 )
return ;
ImGuiContext & g = * GImGui ;
if ( window - > DC . ColumnsCount > 1 )
{
PopItemWidth ( ) ;
PopClipRect ( ) ;
window - > DC . ColumnsCellMaxY = ImMax ( window - > DC . ColumnsCellMaxY , window - > DC . CursorPos . y ) ;
if ( + + window - > DC . ColumnsCurrent < window - > DC . ColumnsCount )
{
// Columns 1+ cancel out IndentX
window - > DC . ColumnsOffsetX = GetColumnOffset ( window - > DC . ColumnsCurrent ) - window - > DC . IndentX + g . Style . ItemSpacing . x ;
window - > DrawList - > ChannelsSetCurrent ( window - > DC . ColumnsCurrent ) ;
}
else
{
window - > DC . ColumnsCurrent = 0 ;
window - > DC . ColumnsOffsetX = 0.0f ;
window - > DC . ColumnsCellMinY = window - > DC . ColumnsCellMaxY ;
window - > DrawList - > ChannelsSetCurrent ( 0 ) ;
}
window - > DC . CursorPos . x = ( float ) ( int ) ( window - > Pos . x + window - > DC . IndentX + window - > DC . ColumnsOffsetX ) ;
window - > DC . CursorPos . y = window - > DC . ColumnsCellMinY ;
window - > DC . CurrentLineHeight = 0.0f ;
window - > DC . CurrentLineTextBaseOffset = 0.0f ;
PopItemWidth ( ) ;
PopClipRect ( ) ;
PushColumnClipRect ( ) ;
PushItemWidth ( GetColumnWidth ( ) * 0.65f ) ; // FIXME: Move on columns setup
window - > DC . ColumnsCellMaxY = ImMax ( window - > DC . ColumnsCellMaxY , window - > DC . CursorPos . y ) ;
if ( + + window - > DC . ColumnsCurrent < window - > DC . ColumnsCount )
{
// Columns 1+ cancel out IndentX
window - > DC . ColumnsOffsetX = GetColumnOffset ( window - > DC . ColumnsCurrent ) - window - > DC . IndentX + g . Style . ItemSpacing . x ;
window - > DrawList - > ChannelsSetCurrent ( window - > DC . ColumnsCurrent ) ;
}
else
{
window - > DC . ColumnsCurrent = 0 ;
window - > DC . ColumnsOffsetX = 0.0f ;
window - > DC . ColumnsCellMinY = window - > DC . ColumnsCellMaxY ;
window - > DrawList - > ChannelsSetCurrent ( 0 ) ;
}
window - > DC . CursorPos . x = ( float ) ( int ) ( window - > Pos . x + window - > DC . IndentX + window - > DC . ColumnsOffsetX ) ;
window - > DC . CursorPos . y = window - > DC . ColumnsCellMinY ;
window - > DC . CurrentLineHeight = 0.0f ;
window - > DC . CurrentLineTextBaseOffset = 0.0f ;
PushColumnClipRect ( ) ;
PushItemWidth ( GetColumnWidth ( ) * 0.65f ) ; // FIXME: Move on columns setup
}
int ImGui : : GetColumnIndex ( )
@ -9499,7 +9550,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
if ( held )
{
if ( g . ActiveIdIsJustActivated )
g . ActiveIdClickOffset . x - = 4 ; // Store from center of column line
g . ActiveIdClickOffset . x - = 4 ; // Store from center of column line (we used a 8 wide rect for columns clicking)
x = GetDraggedColumnOffset ( i ) ;
SetColumnOffset ( i , x ) ;
}
@ -9632,7 +9683,7 @@ void ImGui::ValueColor(const char* prefix, const ImVec4& v)
ColorButton ( v , true ) ;
}
void ImGui : : ValueColor ( const char * prefix , unsigned int v )
void ImGui : : ValueColor ( const char * prefix , ImU32 v )
{
Text ( " %s: %08X " , prefix , v ) ;
SameLine ( ) ;
@ -9664,12 +9715,8 @@ void ImGui::ValueColor(const char* prefix, unsigned int v)
static const char * GetClipboardTextFn_DefaultImpl ( )
{
static char * buf_local = NULL ;
if ( buf_local )
{
ImGui : : MemFree ( buf_local ) ;
buf_local = NULL ;
}
static ImVector < char > buf_local ;
buf_local . clear ( ) ;
if ( ! OpenClipboard ( NULL ) )
return NULL ;
HANDLE wbuf_handle = GetClipboardData ( CF_UNICODETEXT ) ;
@ -9678,19 +9725,18 @@ static const char* GetClipboardTextFn_DefaultImpl()
if ( ImWchar * wbuf_global = ( ImWchar * ) GlobalLock ( wbuf_handle ) )
{
int buf_len = ImTextCountUtf8BytesFromStr ( wbuf_global , NULL ) + 1 ;
buf_local = ( char * ) ImGui : : MemAlloc ( buf_len * sizeof ( char ) ) ;
ImTextStrToUtf8 ( buf_local , buf_len , wbuf_global , NULL ) ;
buf_local . resize ( buf_len ) ;
ImTextStrToUtf8 ( buf_local .Data , buf_len , wbuf_global , NULL ) ;
}
GlobalUnlock ( wbuf_handle ) ;
CloseClipboard ( ) ;
return buf_local ;
return buf_local .Data ;
}
static void SetClipboardTextFn_DefaultImpl ( const char * text )
{
if ( ! OpenClipboard ( NULL ) )
return ;
const int wbuf_length = ImTextCountCharsFromUtf8 ( text , NULL ) + 1 ;
HGLOBAL wbuf_handle = GlobalAlloc ( GMEM_MOVEABLE , ( SIZE_T ) wbuf_length * sizeof ( ImWchar ) ) ;
if ( wbuf_handle = = NULL )
@ -9729,7 +9775,7 @@ static void SetClipboardTextFn_DefaultImpl(const char* text)
# endif
// Win32 API IME support (for Asian languages, etc.)
# if defined(_WIN32) && !defined( IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)
# if defined(_WIN32) && !defined( __GNUC__) && !defined( IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)
# include <imm.h>
# ifdef _MSC_VER
@ -9847,6 +9893,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
return ;
NodeDrawList ( window - > DrawList , " DrawList " ) ;
ImGui : : BulletText ( " Size: (%.1f,%.1f), SizeContents (%.1f,%.1f) " , window - > Size . x , window - > Size . y , window - > SizeContents . x , window - > SizeContents . y ) ;
ImGui : : BulletText ( " Scroll: (%.2f,%.2f) " , window - > Scroll . x , window - > Scroll . y ) ;
if ( window - > RootWindow ! = window ) NodeWindow ( window - > RootWindow , " RootWindow " ) ;
if ( window - > DC . ChildWindows . Size > 0 ) NodeWindows ( window - > DC . ChildWindows , " ChildWindows " ) ;
ImGui : : BulletText ( " Storage: %d bytes " , window - > StateStorage . Data . Size * ( int ) sizeof ( ImGuiStorage : : Pair ) ) ;