@ -70,6 +70,7 @@ CODE 
			
		
	
		
		
			
				
					
					// [SECTION] STYLING
 // [SECTION] STYLING
  
			
		
	
		
		
			
				
					
					// [SECTION] RENDER HELPERS
 // [SECTION] RENDER HELPERS
  
			
		
	
		
		
			
				
					
					// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
 // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
  
			
		
	
		
		
			
				
					
					// [SECTION] INPUTS
  
			
		
	
		
		
			
				
					
					// [SECTION] ERROR CHECKING
 // [SECTION] ERROR CHECKING
  
			
		
	
		
		
			
				
					
					// [SECTION] LAYOUT
 // [SECTION] LAYOUT
  
			
		
	
		
		
			
				
					
					// [SECTION] SCROLLING
 // [SECTION] SCROLLING
  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -4767,238 +4768,6 @@ static void FindHoveredWindow() 
			
		
	
		
		
			
				
					
					    g . HoveredWindowUnderMovingWindow  =  hovered_window_ignoring_moving_window ;      g . HoveredWindowUnderMovingWindow  =  hovered_window_ignoring_moving_window ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Test if mouse cursor is hovering given rectangle
  
			
		
	
		
		
			
				
					
					// NB- Rectangle is clipped by our current clip setting
  
			
		
	
		
		
			
				
					
					// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseHoveringRect ( const  ImVec2 &  r_min ,  const  ImVec2 &  r_max ,  bool  clip )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // Clip
   
			
		
	
		
		
			
				
					
					    ImRect  rect_clipped ( r_min ,  r_max ) ;   
			
		
	
		
		
			
				
					
					    if  ( clip )   
			
		
	
		
		
			
				
					
					        rect_clipped . ClipWith ( g . CurrentWindow - > ClipRect ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // Expand for touch input
   
			
		
	
		
		
			
				
					
					    const  ImRect  rect_for_touch ( rect_clipped . Min  -  g . Style . TouchExtraPadding ,  rect_clipped . Max  +  g . Style . TouchExtraPadding ) ;   
			
		
	
		
		
			
				
					
					    if  ( ! rect_for_touch . Contains ( g . IO . MousePos ) )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    return  true ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					int  ImGui : : GetKeyIndex ( ImGuiKey  imgui_key )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    IM_ASSERT ( imgui_key  > =  0  & &  imgui_key  <  ImGuiKey_COUNT ) ;   
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    return  g . IO . KeyMap [ imgui_key ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Note that dear imgui doesn't know the semantic of each entry of io.KeysDown[]!
  
			
		
	
		
		
			
				
					
					// Use your own indices/enums according to how your backend/engine stored them into io.KeysDown[]!
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsKeyDown ( int  user_key_index )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    if  ( user_key_index  <  0 )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( user_key_index  > =  0  & &  user_key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . KeysDown [ user_key_index ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime)
  
			
		
	
		
		
			
				
					
					// t1 = current time (e.g.: g.Time)
  
			
		
	
		
		
			
				
					
					// An event is triggered at:
  
			
		
	
		
		
			
				
					
					//  t = 0.0f     t = repeat_delay,    t = repeat_delay + repeat_rate*N
  
			
		
	
		
		
			
				
					
					int  ImGui : : CalcTypematicRepeatAmount ( float  t0 ,  float  t1 ,  float  repeat_delay ,  float  repeat_rate )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    if  ( t1  = =  0.0f )   
			
		
	
		
		
			
				
					
					        return  1 ;   
			
		
	
		
		
			
				
					
					    if  ( t0  > =  t1 )   
			
		
	
		
		
			
				
					
					        return  0 ;   
			
		
	
		
		
			
				
					
					    if  ( repeat_rate  < =  0.0f )   
			
		
	
		
		
			
				
					
					        return  ( t0  <  repeat_delay )  & &  ( t1  > =  repeat_delay ) ;   
			
		
	
		
		
			
				
					
					    const  int  count_t0  =  ( t0  <  repeat_delay )  ?  - 1  :  ( int ) ( ( t0  -  repeat_delay )  /  repeat_rate ) ;   
			
		
	
		
		
			
				
					
					    const  int  count_t1  =  ( t1  <  repeat_delay )  ?  - 1  :  ( int ) ( ( t1  -  repeat_delay )  /  repeat_rate ) ;   
			
		
	
		
		
			
				
					
					    const  int  count  =  count_t1  -  count_t0 ;   
			
		
	
		
		
			
				
					
					    return  count ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					int  ImGui : : GetKeyPressedAmount ( int  key_index ,  float  repeat_delay ,  float  repeat_rate )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( key_index  <  0 )   
			
		
	
		
		
			
				
					
					        return  0 ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( key_index  > =  0  & &  key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    const  float  t  =  g . IO . KeysDownDuration [ key_index ] ;   
			
		
	
		
		
			
				
					
					    return  CalcTypematicRepeatAmount ( t  -  g . IO . DeltaTime ,  t ,  repeat_delay ,  repeat_rate ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsKeyPressed ( int  user_key_index ,  bool  repeat )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( user_key_index  <  0 )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( user_key_index  > =  0  & &  user_key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    const  float  t  =  g . IO . KeysDownDuration [ user_key_index ] ;   
			
		
	
		
		
			
				
					
					    if  ( t  = =  0.0f )   
			
		
	
		
		
			
				
					
					        return  true ;   
			
		
	
		
		
			
				
					
					    if  ( repeat  & &  t  >  g . IO . KeyRepeatDelay )   
			
		
	
		
		
			
				
					
					        return  GetKeyPressedAmount ( user_key_index ,  g . IO . KeyRepeatDelay ,  g . IO . KeyRepeatRate )  >  0 ;   
			
		
	
		
		
			
				
					
					    return  false ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsKeyReleased ( int  user_key_index )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( user_key_index  <  0 )  return  false ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( user_key_index  > =  0  & &  user_key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . KeysDownDurationPrev [ user_key_index ]  > =  0.0f  & &  ! g . IO . KeysDown [ user_key_index ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDown ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseDown [ button ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseClicked ( ImGuiMouseButton  button ,  bool  repeat )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    const  float  t  =  g . IO . MouseDownDuration [ button ] ;   
			
		
	
		
		
			
				
					
					    if  ( t  = =  0.0f )   
			
		
	
		
		
			
				
					
					        return  true ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    if  ( repeat  & &  t  >  g . IO . KeyRepeatDelay )   
			
		
	
		
		
			
				
					
					    {   
			
		
	
		
		
			
				
					
					        // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
   
			
		
	
		
		
			
				
					
					        int  amount  =  CalcTypematicRepeatAmount ( t  -  g . IO . DeltaTime ,  t ,  g . IO . KeyRepeatDelay ,  g . IO . KeyRepeatRate  *  0.50f ) ;   
			
		
	
		
		
			
				
					
					        if  ( amount  >  0 )   
			
		
	
		
		
			
				
					
					            return  true ;   
			
		
	
		
		
			
				
					
					    }   
			
		
	
		
		
			
				
					
					    return  false ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseReleased ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseReleased [ button ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDoubleClicked ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseClickedCount [ button ]  = =  2 ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					int  ImGui : : GetMouseClickedCount ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseClickedCount [ button ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
  
			
		
	
		
		
			
				
					
					// [Internal] This doesn't test if the button is pressed
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDragPastThreshold ( ImGuiMouseButton  button ,  float  lock_threshold )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    if  ( lock_threshold  <  0.0f )   
			
		
	
		
		
			
				
					
					        lock_threshold  =  g . IO . MouseDragThreshold ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseDragMaxDistanceSqr [ button ]  > =  lock_threshold  *  lock_threshold ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDragging ( ImGuiMouseButton  button ,  float  lock_threshold )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    if  ( ! g . IO . MouseDown [ button ] )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    return  IsMouseDragPastThreshold ( button ,  lock_threshold ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					ImVec2  ImGui : : GetMousePos ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MousePos ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
  
			
		
	
		
		
			
				
					
					ImVec2  ImGui : : GetMousePosOnOpeningCurrentPopup ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( g . BeginPopupStack . Size  >  0 )   
			
		
	
		
		
			
				
					
					        return  g . OpenPopupStack [ g . BeginPopupStack . Size  -  1 ] . OpenMousePos ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MousePos ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position.
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMousePosValid ( const  ImVec2 *  mouse_pos )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    // The assert is only to silence a false-positive in XCode Static Analysis.
   
			
		
	
		
		
			
				
					
					    // Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions).
   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( GImGui  ! =  NULL ) ;   
			
		
	
		
		
			
				
					
					    const  float  MOUSE_INVALID  =  - 256000.0f ;   
			
		
	
		
		
			
				
					
					    ImVec2  p  =  mouse_pos  ?  * mouse_pos  :  GImGui - > IO . MousePos ;   
			
		
	
		
		
			
				
					
					    return  p . x  > =  MOUSE_INVALID  & &  p . y  > =  MOUSE_INVALID ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsAnyMouseDown ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    for  ( int  n  =  0 ;  n  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ;  n + + )   
			
		
	
		
		
			
				
					
					        if  ( g . IO . MouseDown [ n ] )   
			
		
	
		
		
			
				
					
					            return  true ;   
			
		
	
		
		
			
				
					
					    return  false ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Return the delta from the initial clicking position while the mouse button is clicked or was just released.
  
			
		
	
		
		
			
				
					
					// This is locked and return 0.0f until the mouse moves past a distance threshold at least once.
  
			
		
	
		
		
			
				
					
					// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window.
  
			
		
	
		
		
			
				
					
					ImVec2  ImGui : : GetMouseDragDelta ( ImGuiMouseButton  button ,  float  lock_threshold )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    if  ( lock_threshold  <  0.0f )   
			
		
	
		
		
			
				
					
					        lock_threshold  =  g . IO . MouseDragThreshold ;   
			
		
	
		
		
			
				
					
					    if  ( g . IO . MouseDown [ button ]  | |  g . IO . MouseReleased [ button ] )   
			
		
	
		
		
			
				
					
					        if  ( g . IO . MouseDragMaxDistanceSqr [ button ]  > =  lock_threshold  *  lock_threshold )   
			
		
	
		
		
			
				
					
					            if  ( IsMousePosValid ( & g . IO . MousePos )  & &  IsMousePosValid ( & g . IO . MouseClickedPos [ button ] ) )   
			
		
	
		
		
			
				
					
					                return  g . IO . MousePos  -  g . IO . MouseClickedPos [ button ] ;   
			
		
	
		
		
			
				
					
					    return  ImVec2 ( 0.0f ,  0.0f ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : ResetMouseDragDelta ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr
   
			
		
	
		
		
			
				
					
					    g . IO . MouseClickedPos [ button ]  =  g . IO . MousePos ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					ImGuiMouseCursor  ImGui : : GetMouseCursor ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    return  GImGui - > MouseCursor ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : SetMouseCursor ( ImGuiMouseCursor  cursor_type )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    GImGui - > MouseCursor  =  cursor_type ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : CaptureKeyboardFromApp ( bool  capture )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    GImGui - > WantCaptureKeyboardNextFrame  =  capture  ?  1  :  0 ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : CaptureMouseFromApp ( bool  capture )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    GImGui - > WantCaptureMouseNextFrame  =  capture  ?  1  :  0 ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsItemActive ( ) bool  ImGui : : IsItemActive ( )  
			
		
	
		
		
			
				
					
					{ {  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;      ImGuiContext &  g  =  * GImGui ;   
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -7460,6 +7229,247 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					//-----------------------------------------------------------------------------
  
			
		
	
		
		
			
				
					
					// [SECTION] INPUTS
  
			
		
	
		
		
			
				
					
					//-----------------------------------------------------------------------------
  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Test if mouse cursor is hovering given rectangle
  
			
		
	
		
		
			
				
					
					// NB- Rectangle is clipped by our current clip setting
  
			
		
	
		
		
			
				
					
					// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseHoveringRect ( const  ImVec2 &  r_min ,  const  ImVec2 &  r_max ,  bool  clip )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // Clip
   
			
		
	
		
		
			
				
					
					    ImRect  rect_clipped ( r_min ,  r_max ) ;   
			
		
	
		
		
			
				
					
					    if  ( clip )   
			
		
	
		
		
			
				
					
					        rect_clipped . ClipWith ( g . CurrentWindow - > ClipRect ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // Expand for touch input
   
			
		
	
		
		
			
				
					
					    const  ImRect  rect_for_touch ( rect_clipped . Min  -  g . Style . TouchExtraPadding ,  rect_clipped . Max  +  g . Style . TouchExtraPadding ) ;   
			
		
	
		
		
			
				
					
					    if  ( ! rect_for_touch . Contains ( g . IO . MousePos ) )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    return  true ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					int  ImGui : : GetKeyIndex ( ImGuiKey  imgui_key )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    IM_ASSERT ( imgui_key  > =  0  & &  imgui_key  <  ImGuiKey_COUNT ) ;   
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    return  g . IO . KeyMap [ imgui_key ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Note that dear imgui doesn't know the semantic of each entry of io.KeysDown[]!
  
			
		
	
		
		
			
				
					
					// Use your own indices/enums according to how your backend/engine stored them into io.KeysDown[]!
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsKeyDown ( int  user_key_index )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    if  ( user_key_index  <  0 )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( user_key_index  > =  0  & &  user_key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . KeysDown [ user_key_index ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime)
  
			
		
	
		
		
			
				
					
					// t1 = current time (e.g.: g.Time)
  
			
		
	
		
		
			
				
					
					// An event is triggered at:
  
			
		
	
		
		
			
				
					
					//  t = 0.0f     t = repeat_delay,    t = repeat_delay + repeat_rate*N
  
			
		
	
		
		
			
				
					
					int  ImGui : : CalcTypematicRepeatAmount ( float  t0 ,  float  t1 ,  float  repeat_delay ,  float  repeat_rate )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    if  ( t1  = =  0.0f )   
			
		
	
		
		
			
				
					
					        return  1 ;   
			
		
	
		
		
			
				
					
					    if  ( t0  > =  t1 )   
			
		
	
		
		
			
				
					
					        return  0 ;   
			
		
	
		
		
			
				
					
					    if  ( repeat_rate  < =  0.0f )   
			
		
	
		
		
			
				
					
					        return  ( t0  <  repeat_delay )  & &  ( t1  > =  repeat_delay ) ;   
			
		
	
		
		
			
				
					
					    const  int  count_t0  =  ( t0  <  repeat_delay )  ?  - 1  :  ( int ) ( ( t0  -  repeat_delay )  /  repeat_rate ) ;   
			
		
	
		
		
			
				
					
					    const  int  count_t1  =  ( t1  <  repeat_delay )  ?  - 1  :  ( int ) ( ( t1  -  repeat_delay )  /  repeat_rate ) ;   
			
		
	
		
		
			
				
					
					    const  int  count  =  count_t1  -  count_t0 ;   
			
		
	
		
		
			
				
					
					    return  count ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					int  ImGui : : GetKeyPressedAmount ( int  key_index ,  float  repeat_delay ,  float  repeat_rate )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( key_index  <  0 )   
			
		
	
		
		
			
				
					
					        return  0 ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( key_index  > =  0  & &  key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    const  float  t  =  g . IO . KeysDownDuration [ key_index ] ;   
			
		
	
		
		
			
				
					
					    return  CalcTypematicRepeatAmount ( t  -  g . IO . DeltaTime ,  t ,  repeat_delay ,  repeat_rate ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsKeyPressed ( int  user_key_index ,  bool  repeat )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( user_key_index  <  0 )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( user_key_index  > =  0  & &  user_key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    const  float  t  =  g . IO . KeysDownDuration [ user_key_index ] ;   
			
		
	
		
		
			
				
					
					    if  ( t  = =  0.0f )   
			
		
	
		
		
			
				
					
					        return  true ;   
			
		
	
		
		
			
				
					
					    if  ( repeat  & &  t  >  g . IO . KeyRepeatDelay )   
			
		
	
		
		
			
				
					
					        return  GetKeyPressedAmount ( user_key_index ,  g . IO . KeyRepeatDelay ,  g . IO . KeyRepeatRate )  >  0 ;   
			
		
	
		
		
			
				
					
					    return  false ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsKeyReleased ( int  user_key_index )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( user_key_index  <  0 )  return  false ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( user_key_index  > =  0  & &  user_key_index  <  IM_ARRAYSIZE ( g . IO . KeysDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . KeysDownDurationPrev [ user_key_index ]  > =  0.0f  & &  ! g . IO . KeysDown [ user_key_index ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDown ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseDown [ button ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseClicked ( ImGuiMouseButton  button ,  bool  repeat )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    const  float  t  =  g . IO . MouseDownDuration [ button ] ;   
			
		
	
		
		
			
				
					
					    if  ( t  = =  0.0f )   
			
		
	
		
		
			
				
					
					        return  true ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    if  ( repeat  & &  t  >  g . IO . KeyRepeatDelay )   
			
		
	
		
		
			
				
					
					    {   
			
		
	
		
		
			
				
					
					        // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
   
			
		
	
		
		
			
				
					
					        int  amount  =  CalcTypematicRepeatAmount ( t  -  g . IO . DeltaTime ,  t ,  g . IO . KeyRepeatDelay ,  g . IO . KeyRepeatRate  *  0.50f ) ;   
			
		
	
		
		
			
				
					
					        if  ( amount  >  0 )   
			
		
	
		
		
			
				
					
					            return  true ;   
			
		
	
		
		
			
				
					
					    }   
			
		
	
		
		
			
				
					
					    return  false ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseReleased ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseReleased [ button ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDoubleClicked ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseClickedCount [ button ]  = =  2 ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					int  ImGui : : GetMouseClickedCount ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseClickedCount [ button ] ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
  
			
		
	
		
		
			
				
					
					// [Internal] This doesn't test if the button is pressed
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDragPastThreshold ( ImGuiMouseButton  button ,  float  lock_threshold )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    if  ( lock_threshold  <  0.0f )   
			
		
	
		
		
			
				
					
					        lock_threshold  =  g . IO . MouseDragThreshold ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MouseDragMaxDistanceSqr [ button ]  > =  lock_threshold  *  lock_threshold ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMouseDragging ( ImGuiMouseButton  button ,  float  lock_threshold )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    if  ( ! g . IO . MouseDown [ button ] )   
			
		
	
		
		
			
				
					
					        return  false ;   
			
		
	
		
		
			
				
					
					    return  IsMouseDragPastThreshold ( button ,  lock_threshold ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					ImVec2  ImGui : : GetMousePos ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MousePos ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
  
			
		
	
		
		
			
				
					
					ImVec2  ImGui : : GetMousePosOnOpeningCurrentPopup ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    if  ( g . BeginPopupStack . Size  >  0 )   
			
		
	
		
		
			
				
					
					        return  g . OpenPopupStack [ g . BeginPopupStack . Size  -  1 ] . OpenMousePos ;   
			
		
	
		
		
			
				
					
					    return  g . IO . MousePos ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position.
  
			
		
	
		
		
			
				
					
					bool  ImGui : : IsMousePosValid ( const  ImVec2 *  mouse_pos )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    // The assert is only to silence a false-positive in XCode Static Analysis.
   
			
		
	
		
		
			
				
					
					    // Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions).
   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( GImGui  ! =  NULL ) ;   
			
		
	
		
		
			
				
					
					    const  float  MOUSE_INVALID  =  - 256000.0f ;   
			
		
	
		
		
			
				
					
					    ImVec2  p  =  mouse_pos  ?  * mouse_pos  :  GImGui - > IO . MousePos ;   
			
		
	
		
		
			
				
					
					    return  p . x  > =  MOUSE_INVALID  & &  p . y  > =  MOUSE_INVALID ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  ImGui : : IsAnyMouseDown ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    for  ( int  n  =  0 ;  n  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ;  n + + )   
			
		
	
		
		
			
				
					
					        if  ( g . IO . MouseDown [ n ] )   
			
		
	
		
		
			
				
					
					            return  true ;   
			
		
	
		
		
			
				
					
					    return  false ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Return the delta from the initial clicking position while the mouse button is clicked or was just released.
  
			
		
	
		
		
			
				
					
					// This is locked and return 0.0f until the mouse moves past a distance threshold at least once.
  
			
		
	
		
		
			
				
					
					// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window.
  
			
		
	
		
		
			
				
					
					ImVec2  ImGui : : GetMouseDragDelta ( ImGuiMouseButton  button ,  float  lock_threshold )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    if  ( lock_threshold  <  0.0f )   
			
		
	
		
		
			
				
					
					        lock_threshold  =  g . IO . MouseDragThreshold ;   
			
		
	
		
		
			
				
					
					    if  ( g . IO . MouseDown [ button ]  | |  g . IO . MouseReleased [ button ] )   
			
		
	
		
		
			
				
					
					        if  ( g . IO . MouseDragMaxDistanceSqr [ button ]  > =  lock_threshold  *  lock_threshold )   
			
		
	
		
		
			
				
					
					            if  ( IsMousePosValid ( & g . IO . MousePos )  & &  IsMousePosValid ( & g . IO . MouseClickedPos [ button ] ) )   
			
		
	
		
		
			
				
					
					                return  g . IO . MousePos  -  g . IO . MouseClickedPos [ button ] ;   
			
		
	
		
		
			
				
					
					    return  ImVec2 ( 0.0f ,  0.0f ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : ResetMouseDragDelta ( ImGuiMouseButton  button )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    IM_ASSERT ( button  > =  0  & &  button  <  IM_ARRAYSIZE ( g . IO . MouseDown ) ) ;   
			
		
	
		
		
			
				
					
					    // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr
   
			
		
	
		
		
			
				
					
					    g . IO . MouseClickedPos [ button ]  =  g . IO . MousePos ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					ImGuiMouseCursor  ImGui : : GetMouseCursor ( )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    return  g . MouseCursor ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : SetMouseCursor ( ImGuiMouseCursor  cursor_type )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    g . MouseCursor  =  cursor_type ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : CaptureKeyboardFromApp ( bool  capture )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    g . WantCaptureKeyboardNextFrame  =  capture  ?  1  :  0 ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  ImGui : : CaptureMouseFromApp ( bool  capture )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    ImGuiContext &  g  =  * GImGui ;   
			
		
	
		
		
			
				
					
					    g . WantCaptureMouseNextFrame  =  capture  ?  1  :  0 ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					//-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
  
			
		
	
		
		
			
				
					
					// [SECTION] ERROR CHECKING
 // [SECTION] ERROR CHECKING
  
			
		
	
		
		
			
				
					
					//-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------