@ -77,6 +77,7 @@
# if !defined(IMGUI_DISABLE_DEMO_WINDOWS)
// Forward Declarations
static void ShowExampleAppMainMenuBar ( ) ;
static void ShowExampleAppConsole ( bool * p_open ) ;
static void ShowExampleAppLog ( bool * p_open ) ;
static void ShowExampleAppLayout ( bool * p_open ) ;
@ -87,7 +88,6 @@ static void ShowExampleAppConstrainedResize(bool* p_open);
static void ShowExampleAppSimpleOverlay ( bool * p_open ) ;
static void ShowExampleAppWindowTitles ( bool * p_open ) ;
static void ShowExampleAppCustomRendering ( bool * p_open ) ;
static void ShowExampleAppMainMenuBar ( ) ;
static void ShowExampleMenuFile ( ) ;
// Helper to display a little (?) mark which shows a tooltip when hovered.
@ -2252,6 +2252,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
}
}
// End of ShowDemoWindow()
ImGui : : End ( ) ;
}
@ -2517,6 +2518,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui : : PopItemWidth ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: MAIN MENU BAR
//-----------------------------------------------------------------------------
// Demonstrate creating a fullscreen menu bar and populating it.
static void ShowExampleAppMainMenuBar ( )
{
@ -2606,235 +2611,9 @@ static void ShowExampleMenuFile()
if ( ImGui : : MenuItem ( " Quit " , " Alt+F4 " ) ) { }
}
// Demonstrate creating a window which gets auto-resized according to its content.
static void ShowExampleAppAutoResize ( bool * p_open )
{
if ( ! ImGui : : Begin ( " Example: Auto-resizing window " , p_open , ImGuiWindowFlags_AlwaysAutoResize ) )
{
ImGui : : End ( ) ;
return ;
}
static int lines = 10 ;
ImGui : : Text ( " Window will resize every-frame to the size of its content. \n Note that you probably don't want to query the window size to \n output your content because that would create a feedback loop. " ) ;
ImGui : : SliderInt ( " Number of lines " , & lines , 1 , 20 ) ;
for ( int i = 0 ; i < lines ; i + + )
ImGui : : Text ( " %*sThis is line %d " , i * 4 , " " , i ) ; // Pad with space to extend size horizontally
ImGui : : End ( ) ;
}
// Demonstrate creating a window with custom resize constraints.
static void ShowExampleAppConstrainedResize ( bool * p_open )
{
struct CustomConstraints // Helper functions to demonstrate programmatic constraints
{
static void Square ( ImGuiSizeCallbackData * data ) { data - > DesiredSize = ImVec2 ( IM_MAX ( data - > DesiredSize . x , data - > DesiredSize . y ) , IM_MAX ( data - > DesiredSize . x , data - > DesiredSize . y ) ) ; }
static void Step ( ImGuiSizeCallbackData * data ) { float step = ( float ) ( int ) ( intptr_t ) data - > UserData ; data - > DesiredSize = ImVec2 ( ( int ) ( data - > DesiredSize . x / step + 0.5f ) * step , ( int ) ( data - > DesiredSize . y / step + 0.5f ) * step ) ; }
} ;
static bool auto_resize = false ;
static int type = 0 ;
static int display_lines = 10 ;
if ( type = = 0 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( - 1 , 0 ) , ImVec2 ( - 1 , FLT_MAX ) ) ; // Vertical only
if ( type = = 1 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 0 , - 1 ) , ImVec2 ( FLT_MAX , - 1 ) ) ; // Horizontal only
if ( type = = 2 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 100 , 100 ) , ImVec2 ( FLT_MAX , FLT_MAX ) ) ; // Width > 100, Height > 100
if ( type = = 3 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 400 , - 1 ) , ImVec2 ( 500 , - 1 ) ) ; // Width 400-500
if ( type = = 4 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( - 1 , 400 ) , ImVec2 ( - 1 , 500 ) ) ; // Height 400-500
if ( type = = 5 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 0 , 0 ) , ImVec2 ( FLT_MAX , FLT_MAX ) , CustomConstraints : : Square ) ; // Always Square
if ( type = = 6 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 0 , 0 ) , ImVec2 ( FLT_MAX , FLT_MAX ) , CustomConstraints : : Step , ( void * ) 100 ) ; // Fixed Step
ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0 ;
if ( ImGui : : Begin ( " Example: Constrained Resize " , p_open , flags ) )
{
const char * desc [ ] =
{
" Resize vertical only " ,
" Resize horizontal only " ,
" Width > 100, Height > 100 " ,
" Width 400-500 " ,
" Height 400-500 " ,
" Custom: Always Square " ,
" Custom: Fixed Steps (100) " ,
} ;
if ( ImGui : : Button ( " 200x200 " ) ) { ImGui : : SetWindowSize ( ImVec2 ( 200 , 200 ) ) ; } ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " 500x500 " ) ) { ImGui : : SetWindowSize ( ImVec2 ( 500 , 500 ) ) ; } ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " 800x200 " ) ) { ImGui : : SetWindowSize ( ImVec2 ( 800 , 200 ) ) ; }
ImGui : : PushItemWidth ( 200 ) ;
ImGui : : Combo ( " Constraint " , & type , desc , IM_ARRAYSIZE ( desc ) ) ;
ImGui : : DragInt ( " Lines " , & display_lines , 0.2f , 1 , 100 ) ;
ImGui : : PopItemWidth ( ) ;
ImGui : : Checkbox ( " Auto-resize " , & auto_resize ) ;
for ( int i = 0 ; i < display_lines ; i + + )
ImGui : : Text ( " %*sHello, sailor! Making this line long enough for the example. " , i * 4 , " " ) ;
}
ImGui : : End ( ) ;
}
// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
static void ShowExampleAppSimpleOverlay ( bool * p_open )
{
const float DISTANCE = 10.0f ;
static int corner = 0 ;
ImVec2 window_pos = ImVec2 ( ( corner & 1 ) ? ImGui : : GetIO ( ) . DisplaySize . x - DISTANCE : DISTANCE , ( corner & 2 ) ? ImGui : : GetIO ( ) . DisplaySize . y - DISTANCE : DISTANCE ) ;
ImVec2 window_pos_pivot = ImVec2 ( ( corner & 1 ) ? 1.0f : 0.0f , ( corner & 2 ) ? 1.0f : 0.0f ) ;
if ( corner ! = - 1 )
ImGui : : SetNextWindowPos ( window_pos , ImGuiCond_Always , window_pos_pivot ) ;
ImGui : : SetNextWindowBgAlpha ( 0.3f ) ; // Transparent background
if ( ImGui : : Begin ( " Example: Simple Overlay " , p_open , ( corner ! = - 1 ? ImGuiWindowFlags_NoMove : 0 ) | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav ) )
{
ImGui : : Text ( " Simple overlay \n " " in the corner of the screen. \n " " (right-click to change position) " ) ;
ImGui : : Separator ( ) ;
if ( ImGui : : IsMousePosValid ( ) )
ImGui : : Text ( " Mouse Position: (%.1f,%.1f) " , ImGui : : GetIO ( ) . MousePos . x , ImGui : : GetIO ( ) . MousePos . y ) ;
else
ImGui : : Text ( " Mouse Position: <invalid> " ) ;
if ( ImGui : : BeginPopupContextWindow ( ) )
{
if ( ImGui : : MenuItem ( " Custom " , NULL , corner = = - 1 ) ) corner = - 1 ;
if ( ImGui : : MenuItem ( " Top-left " , NULL , corner = = 0 ) ) corner = 0 ;
if ( ImGui : : MenuItem ( " Top-right " , NULL , corner = = 1 ) ) corner = 1 ;
if ( ImGui : : MenuItem ( " Bottom-left " , NULL , corner = = 2 ) ) corner = 2 ;
if ( ImGui : : MenuItem ( " Bottom-right " , NULL , corner = = 3 ) ) corner = 3 ;
if ( p_open & & ImGui : : MenuItem ( " Close " ) ) * p_open = false ;
ImGui : : EndPopup ( ) ;
}
}
ImGui : : End ( ) ;
}
// Demonstrate using "##" and "###" in identifiers to manipulate ID generation.
// This apply to regular items as well. Read FAQ section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." for details.
static void ShowExampleAppWindowTitles ( bool * )
{
// By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID.
// Using "##" to display same title but have unique identifier.
ImGui : : SetNextWindowPos ( ImVec2 ( 100 , 100 ) , ImGuiCond_FirstUseEver ) ;
ImGui : : Begin ( " Same title as another window##1 " ) ;
ImGui : : Text ( " This is window 1. \n My title is the same as window 2, but my identifier is unique. " ) ;
ImGui : : End ( ) ;
ImGui : : SetNextWindowPos ( ImVec2 ( 100 , 200 ) , ImGuiCond_FirstUseEver ) ;
ImGui : : Begin ( " Same title as another window##2 " ) ;
ImGui : : Text ( " This is window 2. \n My title is the same as window 1, but my identifier is unique. " ) ;
ImGui : : End ( ) ;
// Using "###" to display a changing title but keep a static identifier "AnimatedTitle"
char buf [ 128 ] ;
sprintf ( buf , " Animated title %c %d###AnimatedTitle " , " |/- \\ " [ ( int ) ( ImGui : : GetTime ( ) / 0.25f ) & 3 ] , ImGui : : GetFrameCount ( ) ) ;
ImGui : : SetNextWindowPos ( ImVec2 ( 100 , 300 ) , ImGuiCond_FirstUseEver ) ;
ImGui : : Begin ( buf ) ;
ImGui : : Text ( " This window has a changing title. " ) ;
ImGui : : End ( ) ;
}
// Demonstrate using the low-level ImDrawList to draw custom shapes.
static void ShowExampleAppCustomRendering ( bool * p_open )
{
ImGui : : SetNextWindowSize ( ImVec2 ( 350 , 560 ) , ImGuiCond_FirstUseEver ) ;
if ( ! ImGui : : Begin ( " Example: Custom rendering " , p_open ) )
{
ImGui : : End ( ) ;
return ;
}
// Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc.
// Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4.
// ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types)
// In this example we are not using the maths operators!
ImDrawList * draw_list = ImGui : : GetWindowDrawList ( ) ;
// Primitives
ImGui : : Text ( " Primitives " ) ;
static float sz = 36.0f ;
static float thickness = 4.0f ;
static ImVec4 col = ImVec4 ( 1.0f , 1.0f , 0.4f , 1.0f ) ;
ImGui : : DragFloat ( " Size " , & sz , 0.2f , 2.0f , 72.0f , " %.0f " ) ;
ImGui : : DragFloat ( " Thickness " , & thickness , 0.05f , 1.0f , 8.0f , " %.02f " ) ;
ImGui : : ColorEdit3 ( " Color " , & col . x ) ;
{
const ImVec2 p = ImGui : : GetCursorScreenPos ( ) ;
const ImU32 col32 = ImColor ( col ) ;
float x = p . x + 4.0f , y = p . y + 4.0f , spacing = 8.0f ;
for ( int n = 0 ; n < 2 ; n + + )
{
float curr_thickness = ( n = = 0 ) ? 1.0f : thickness ;
draw_list - > AddCircle ( ImVec2 ( x + sz * 0.5f , y + sz * 0.5f ) , sz * 0.5f , col32 , 20 , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddRect ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 0.0f , ImDrawCornerFlags_All , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddRect ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f , ImDrawCornerFlags_All , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddRect ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f , ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddTriangle ( ImVec2 ( x + sz * 0.5f , y ) , ImVec2 ( x + sz , y + sz - 0.5f ) , ImVec2 ( x , y + sz - 0.5f ) , col32 , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddLine ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y ) , col32 , curr_thickness ) ; x + = sz + spacing ; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list - > AddLine ( ImVec2 ( x , y ) , ImVec2 ( x , y + sz ) , col32 , curr_thickness ) ; x + = spacing ; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list - > AddLine ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , curr_thickness ) ; x + = sz + spacing ; // Diagonal line
draw_list - > AddBezierCurve ( ImVec2 ( x , y ) , ImVec2 ( x + sz * 1.3f , y + sz * 0.3f ) , ImVec2 ( x + sz - sz * 1.3f , y + sz - sz * 0.3f ) , ImVec2 ( x + sz , y + sz ) , col32 , curr_thickness ) ;
x = p . x + 4 ;
y + = sz + spacing ;
}
draw_list - > AddCircleFilled ( ImVec2 ( x + sz * 0.5f , y + sz * 0.5f ) , sz * 0.5f , col32 , 32 ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f , ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight ) ; x + = sz + spacing ;
draw_list - > AddTriangleFilled ( ImVec2 ( x + sz * 0.5f , y ) , ImVec2 ( x + sz , y + sz - 0.5f ) , ImVec2 ( x , y + sz - 0.5f ) , col32 ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + thickness ) , col32 ) ; x + = sz + spacing ; // Horizontal line (faster than AddLine, but only handle integer thickness)
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + thickness , y + sz ) , col32 ) ; x + = spacing + spacing ; // Vertical line (faster than AddLine, but only handle integer thickness)
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + 1 , y + 1 ) , col32 ) ; x + = sz ; // Pixel (faster than AddLine)
draw_list - > AddRectFilledMultiColor ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , IM_COL32 ( 0 , 0 , 0 , 255 ) , IM_COL32 ( 255 , 0 , 0 , 255 ) , IM_COL32 ( 255 , 255 , 0 , 255 ) , IM_COL32 ( 0 , 255 , 0 , 255 ) ) ;
ImGui : : Dummy ( ImVec2 ( ( sz + spacing ) * 8 , ( sz + spacing ) * 3 ) ) ;
}
ImGui : : Separator ( ) ;
{
static ImVector < ImVec2 > points ;
static bool adding_line = false ;
ImGui : : Text ( " Canvas example " ) ;
if ( ImGui : : Button ( " Clear " ) ) points . clear ( ) ;
if ( points . Size > = 2 ) { ImGui : : SameLine ( ) ; if ( ImGui : : Button ( " Undo " ) ) { points . pop_back ( ) ; points . pop_back ( ) ; } }
ImGui : : Text ( " Left-click and drag to add lines, \n Right-click to undo " ) ;
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
// But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
// If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
ImVec2 canvas_pos = ImGui : : GetCursorScreenPos ( ) ; // ImDrawList API uses screen coordinates!
ImVec2 canvas_size = ImGui : : GetContentRegionAvail ( ) ; // Resize canvas to what's available
if ( canvas_size . x < 50.0f ) canvas_size . x = 50.0f ;
if ( canvas_size . y < 50.0f ) canvas_size . y = 50.0f ;
draw_list - > AddRectFilledMultiColor ( canvas_pos , ImVec2 ( canvas_pos . x + canvas_size . x , canvas_pos . y + canvas_size . y ) , IM_COL32 ( 50 , 50 , 50 , 255 ) , IM_COL32 ( 50 , 50 , 60 , 255 ) , IM_COL32 ( 60 , 60 , 70 , 255 ) , IM_COL32 ( 50 , 50 , 60 , 255 ) ) ;
draw_list - > AddRect ( canvas_pos , ImVec2 ( canvas_pos . x + canvas_size . x , canvas_pos . y + canvas_size . y ) , IM_COL32 ( 255 , 255 , 255 , 255 ) ) ;
bool adding_preview = false ;
ImGui : : InvisibleButton ( " canvas " , canvas_size ) ;
ImVec2 mouse_pos_in_canvas = ImVec2 ( ImGui : : GetIO ( ) . MousePos . x - canvas_pos . x , ImGui : : GetIO ( ) . MousePos . y - canvas_pos . y ) ;
if ( adding_line )
{
adding_preview = true ;
points . push_back ( mouse_pos_in_canvas ) ;
if ( ! ImGui : : IsMouseDown ( 0 ) )
adding_line = adding_preview = false ;
}
if ( ImGui : : IsItemHovered ( ) )
{
if ( ! adding_line & & ImGui : : IsMouseClicked ( 0 ) )
{
points . push_back ( mouse_pos_in_canvas ) ;
adding_line = true ;
}
if ( ImGui : : IsMouseClicked ( 1 ) & & ! points . empty ( ) )
{
adding_line = adding_preview = false ;
points . pop_back ( ) ;
points . pop_back ( ) ;
}
}
draw_list - > PushClipRect ( canvas_pos , ImVec2 ( canvas_pos . x + canvas_size . x , canvas_pos . y + canvas_size . y ) , true ) ; // clip lines within the canvas (if we resize it, etc.)
for ( int i = 0 ; i < points . Size - 1 ; i + = 2 )
draw_list - > AddLine ( ImVec2 ( canvas_pos . x + points [ i ] . x , canvas_pos . y + points [ i ] . y ) , ImVec2 ( canvas_pos . x + points [ i + 1 ] . x , canvas_pos . y + points [ i + 1 ] . y ) , IM_COL32 ( 255 , 255 , 0 , 255 ) , 2.0f ) ;
draw_list - > PopClipRect ( ) ;
if ( adding_preview )
points . pop_back ( ) ;
}
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: CONSOLE
//-----------------------------------------------------------------------------
// Demonstrating creating a simple console window, with scrolling, filtering, completion and history.
// For the console example, here we are using a more C++ like approach of declaring a class to hold the data and the functions.
@ -2855,7 +2634,7 @@ struct ExampleAppConsole
Commands . push_back ( " HELP " ) ;
Commands . push_back ( " HISTORY " ) ;
Commands . push_back ( " CLEAR " ) ;
Commands . push_back ( " CLASSIFY " ) ; // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
Commands . push_back ( " CLASSIFY " ) ; // "classify" is only here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
AddLog ( " Welcome to Dear ImGui! " ) ;
}
~ ExampleAppConsole ( )
@ -3143,6 +2922,10 @@ static void ShowExampleAppConsole(bool* p_open)
console . Draw ( " Example: Console " , p_open ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: LOG
//-----------------------------------------------------------------------------
// Usage:
// static ExampleAppLog my_log;
// my_log.AddLog("Hello %d world\n", 123);
@ -3229,6 +3012,10 @@ static void ShowExampleAppLog(bool* p_open)
log . Draw ( " Example: Log " , p_open ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: SIMPLE LAYOUT
//-----------------------------------------------------------------------------
// Demonstrate create a window with multiple child windows.
static void ShowExampleAppLayout ( bool * p_open )
{
@ -3273,6 +3060,10 @@ static void ShowExampleAppLayout(bool* p_open)
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: PROPERTY EDITOR
//-----------------------------------------------------------------------------
// Demonstrate create a simple property editor.
static void ShowExampleAppPropertyEditor ( bool * p_open )
{
@ -3342,6 +3133,10 @@ static void ShowExampleAppPropertyEditor(bool* p_open)
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: LONG TEXT
//-----------------------------------------------------------------------------
// Demonstrate/test rendering huge amount of text, and the incidence of clipping.
static void ShowExampleAppLongText ( bool * p_open )
{
@ -3396,6 +3191,256 @@ static void ShowExampleAppLongText(bool* p_open)
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: AUTO RESIZE
//-----------------------------------------------------------------------------
// Demonstrate creating a window which gets auto-resized according to its content.
static void ShowExampleAppAutoResize ( bool * p_open )
{
if ( ! ImGui : : Begin ( " Example: Auto-resizing window " , p_open , ImGuiWindowFlags_AlwaysAutoResize ) )
{
ImGui : : End ( ) ;
return ;
}
static int lines = 10 ;
ImGui : : Text ( " Window will resize every-frame to the size of its content. \n Note that you probably don't want to query the window size to \n output your content because that would create a feedback loop. " ) ;
ImGui : : SliderInt ( " Number of lines " , & lines , 1 , 20 ) ;
for ( int i = 0 ; i < lines ; i + + )
ImGui : : Text ( " %*sThis is line %d " , i * 4 , " " , i ) ; // Pad with space to extend size horizontally
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: CONSTRAINED RESIZE
//-----------------------------------------------------------------------------
// Demonstrate creating a window with custom resize constraints.
static void ShowExampleAppConstrainedResize ( bool * p_open )
{
struct CustomConstraints // Helper functions to demonstrate programmatic constraints
{
static void Square ( ImGuiSizeCallbackData * data ) { data - > DesiredSize = ImVec2 ( IM_MAX ( data - > DesiredSize . x , data - > DesiredSize . y ) , IM_MAX ( data - > DesiredSize . x , data - > DesiredSize . y ) ) ; }
static void Step ( ImGuiSizeCallbackData * data ) { float step = ( float ) ( int ) ( intptr_t ) data - > UserData ; data - > DesiredSize = ImVec2 ( ( int ) ( data - > DesiredSize . x / step + 0.5f ) * step , ( int ) ( data - > DesiredSize . y / step + 0.5f ) * step ) ; }
} ;
static bool auto_resize = false ;
static int type = 0 ;
static int display_lines = 10 ;
if ( type = = 0 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( - 1 , 0 ) , ImVec2 ( - 1 , FLT_MAX ) ) ; // Vertical only
if ( type = = 1 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 0 , - 1 ) , ImVec2 ( FLT_MAX , - 1 ) ) ; // Horizontal only
if ( type = = 2 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 100 , 100 ) , ImVec2 ( FLT_MAX , FLT_MAX ) ) ; // Width > 100, Height > 100
if ( type = = 3 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 400 , - 1 ) , ImVec2 ( 500 , - 1 ) ) ; // Width 400-500
if ( type = = 4 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( - 1 , 400 ) , ImVec2 ( - 1 , 500 ) ) ; // Height 400-500
if ( type = = 5 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 0 , 0 ) , ImVec2 ( FLT_MAX , FLT_MAX ) , CustomConstraints : : Square ) ; // Always Square
if ( type = = 6 ) ImGui : : SetNextWindowSizeConstraints ( ImVec2 ( 0 , 0 ) , ImVec2 ( FLT_MAX , FLT_MAX ) , CustomConstraints : : Step , ( void * ) 100 ) ; // Fixed Step
ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0 ;
if ( ImGui : : Begin ( " Example: Constrained Resize " , p_open , flags ) )
{
const char * desc [ ] =
{
" Resize vertical only " ,
" Resize horizontal only " ,
" Width > 100, Height > 100 " ,
" Width 400-500 " ,
" Height 400-500 " ,
" Custom: Always Square " ,
" Custom: Fixed Steps (100) " ,
} ;
if ( ImGui : : Button ( " 200x200 " ) ) { ImGui : : SetWindowSize ( ImVec2 ( 200 , 200 ) ) ; } ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " 500x500 " ) ) { ImGui : : SetWindowSize ( ImVec2 ( 500 , 500 ) ) ; } ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " 800x200 " ) ) { ImGui : : SetWindowSize ( ImVec2 ( 800 , 200 ) ) ; }
ImGui : : PushItemWidth ( 200 ) ;
ImGui : : Combo ( " Constraint " , & type , desc , IM_ARRAYSIZE ( desc ) ) ;
ImGui : : DragInt ( " Lines " , & display_lines , 0.2f , 1 , 100 ) ;
ImGui : : PopItemWidth ( ) ;
ImGui : : Checkbox ( " Auto-resize " , & auto_resize ) ;
for ( int i = 0 ; i < display_lines ; i + + )
ImGui : : Text ( " %*sHello, sailor! Making this line long enough for the example. " , i * 4 , " " ) ;
}
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: SIMPLE OVERLAY
//-----------------------------------------------------------------------------
// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
static void ShowExampleAppSimpleOverlay ( bool * p_open )
{
const float DISTANCE = 10.0f ;
static int corner = 0 ;
ImVec2 window_pos = ImVec2 ( ( corner & 1 ) ? ImGui : : GetIO ( ) . DisplaySize . x - DISTANCE : DISTANCE , ( corner & 2 ) ? ImGui : : GetIO ( ) . DisplaySize . y - DISTANCE : DISTANCE ) ;
ImVec2 window_pos_pivot = ImVec2 ( ( corner & 1 ) ? 1.0f : 0.0f , ( corner & 2 ) ? 1.0f : 0.0f ) ;
if ( corner ! = - 1 )
ImGui : : SetNextWindowPos ( window_pos , ImGuiCond_Always , window_pos_pivot ) ;
ImGui : : SetNextWindowBgAlpha ( 0.3f ) ; // Transparent background
if ( ImGui : : Begin ( " Example: Simple Overlay " , p_open , ( corner ! = - 1 ? ImGuiWindowFlags_NoMove : 0 ) | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav ) )
{
ImGui : : Text ( " Simple overlay \n " " in the corner of the screen. \n " " (right-click to change position) " ) ;
ImGui : : Separator ( ) ;
if ( ImGui : : IsMousePosValid ( ) )
ImGui : : Text ( " Mouse Position: (%.1f,%.1f) " , ImGui : : GetIO ( ) . MousePos . x , ImGui : : GetIO ( ) . MousePos . y ) ;
else
ImGui : : Text ( " Mouse Position: <invalid> " ) ;
if ( ImGui : : BeginPopupContextWindow ( ) )
{
if ( ImGui : : MenuItem ( " Custom " , NULL , corner = = - 1 ) ) corner = - 1 ;
if ( ImGui : : MenuItem ( " Top-left " , NULL , corner = = 0 ) ) corner = 0 ;
if ( ImGui : : MenuItem ( " Top-right " , NULL , corner = = 1 ) ) corner = 1 ;
if ( ImGui : : MenuItem ( " Bottom-left " , NULL , corner = = 2 ) ) corner = 2 ;
if ( ImGui : : MenuItem ( " Bottom-right " , NULL , corner = = 3 ) ) corner = 3 ;
if ( p_open & & ImGui : : MenuItem ( " Close " ) ) * p_open = false ;
ImGui : : EndPopup ( ) ;
}
}
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: WINDOW TITLES
//-----------------------------------------------------------------------------
// Demonstrate using "##" and "###" in identifiers to manipulate ID generation.
// This apply to all regular items as well. Read FAQ section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." for details.
static void ShowExampleAppWindowTitles ( bool * )
{
// By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID.
// Using "##" to display same title but have unique identifier.
ImGui : : SetNextWindowPos ( ImVec2 ( 100 , 100 ) , ImGuiCond_FirstUseEver ) ;
ImGui : : Begin ( " Same title as another window##1 " ) ;
ImGui : : Text ( " This is window 1. \n My title is the same as window 2, but my identifier is unique. " ) ;
ImGui : : End ( ) ;
ImGui : : SetNextWindowPos ( ImVec2 ( 100 , 200 ) , ImGuiCond_FirstUseEver ) ;
ImGui : : Begin ( " Same title as another window##2 " ) ;
ImGui : : Text ( " This is window 2. \n My title is the same as window 1, but my identifier is unique. " ) ;
ImGui : : End ( ) ;
// Using "###" to display a changing title but keep a static identifier "AnimatedTitle"
char buf [ 128 ] ;
sprintf ( buf , " Animated title %c %d###AnimatedTitle " , " |/- \\ " [ ( int ) ( ImGui : : GetTime ( ) / 0.25f ) & 3 ] , ImGui : : GetFrameCount ( ) ) ;
ImGui : : SetNextWindowPos ( ImVec2 ( 100 , 300 ) , ImGuiCond_FirstUseEver ) ;
ImGui : : Begin ( buf ) ;
ImGui : : Text ( " This window has a changing title. " ) ;
ImGui : : End ( ) ;
}
//-----------------------------------------------------------------------------
// EXAMPLE APP CODE: CUSTOM RENDERING
//-----------------------------------------------------------------------------
// Demonstrate using the low-level ImDrawList to draw custom shapes.
static void ShowExampleAppCustomRendering ( bool * p_open )
{
ImGui : : SetNextWindowSize ( ImVec2 ( 350 , 560 ) , ImGuiCond_FirstUseEver ) ;
if ( ! ImGui : : Begin ( " Example: Custom rendering " , p_open ) )
{
ImGui : : End ( ) ;
return ;
}
// Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc.
// Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4.
// ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types)
// In this example we are not using the maths operators!
ImDrawList * draw_list = ImGui : : GetWindowDrawList ( ) ;
// Primitives
ImGui : : Text ( " Primitives " ) ;
static float sz = 36.0f ;
static float thickness = 4.0f ;
static ImVec4 col = ImVec4 ( 1.0f , 1.0f , 0.4f , 1.0f ) ;
ImGui : : DragFloat ( " Size " , & sz , 0.2f , 2.0f , 72.0f , " %.0f " ) ;
ImGui : : DragFloat ( " Thickness " , & thickness , 0.05f , 1.0f , 8.0f , " %.02f " ) ;
ImGui : : ColorEdit3 ( " Color " , & col . x ) ;
{
const ImVec2 p = ImGui : : GetCursorScreenPos ( ) ;
const ImU32 col32 = ImColor ( col ) ;
float x = p . x + 4.0f , y = p . y + 4.0f , spacing = 8.0f ;
for ( int n = 0 ; n < 2 ; n + + )
{
float curr_thickness = ( n = = 0 ) ? 1.0f : thickness ;
draw_list - > AddCircle ( ImVec2 ( x + sz * 0.5f , y + sz * 0.5f ) , sz * 0.5f , col32 , 20 , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddRect ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 0.0f , ImDrawCornerFlags_All , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddRect ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f , ImDrawCornerFlags_All , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddRect ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f , ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddTriangle ( ImVec2 ( x + sz * 0.5f , y ) , ImVec2 ( x + sz , y + sz - 0.5f ) , ImVec2 ( x , y + sz - 0.5f ) , col32 , curr_thickness ) ; x + = sz + spacing ;
draw_list - > AddLine ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y ) , col32 , curr_thickness ) ; x + = sz + spacing ; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list - > AddLine ( ImVec2 ( x , y ) , ImVec2 ( x , y + sz ) , col32 , curr_thickness ) ; x + = spacing ; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list - > AddLine ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , curr_thickness ) ; x + = sz + spacing ; // Diagonal line
draw_list - > AddBezierCurve ( ImVec2 ( x , y ) , ImVec2 ( x + sz * 1.3f , y + sz * 0.3f ) , ImVec2 ( x + sz - sz * 1.3f , y + sz - sz * 0.3f ) , ImVec2 ( x + sz , y + sz ) , col32 , curr_thickness ) ;
x = p . x + 4 ;
y + = sz + spacing ;
}
draw_list - > AddCircleFilled ( ImVec2 ( x + sz * 0.5f , y + sz * 0.5f ) , sz * 0.5f , col32 , 32 ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , col32 , 10.0f , ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight ) ; x + = sz + spacing ;
draw_list - > AddTriangleFilled ( ImVec2 ( x + sz * 0.5f , y ) , ImVec2 ( x + sz , y + sz - 0.5f ) , ImVec2 ( x , y + sz - 0.5f ) , col32 ) ; x + = sz + spacing ;
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + thickness ) , col32 ) ; x + = sz + spacing ; // Horizontal line (faster than AddLine, but only handle integer thickness)
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + thickness , y + sz ) , col32 ) ; x + = spacing + spacing ; // Vertical line (faster than AddLine, but only handle integer thickness)
draw_list - > AddRectFilled ( ImVec2 ( x , y ) , ImVec2 ( x + 1 , y + 1 ) , col32 ) ; x + = sz ; // Pixel (faster than AddLine)
draw_list - > AddRectFilledMultiColor ( ImVec2 ( x , y ) , ImVec2 ( x + sz , y + sz ) , IM_COL32 ( 0 , 0 , 0 , 255 ) , IM_COL32 ( 255 , 0 , 0 , 255 ) , IM_COL32 ( 255 , 255 , 0 , 255 ) , IM_COL32 ( 0 , 255 , 0 , 255 ) ) ;
ImGui : : Dummy ( ImVec2 ( ( sz + spacing ) * 8 , ( sz + spacing ) * 3 ) ) ;
}
ImGui : : Separator ( ) ;
{
static ImVector < ImVec2 > points ;
static bool adding_line = false ;
ImGui : : Text ( " Canvas example " ) ;
if ( ImGui : : Button ( " Clear " ) ) points . clear ( ) ;
if ( points . Size > = 2 ) { ImGui : : SameLine ( ) ; if ( ImGui : : Button ( " Undo " ) ) { points . pop_back ( ) ; points . pop_back ( ) ; } }
ImGui : : Text ( " Left-click and drag to add lines, \n Right-click to undo " ) ;
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
// But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
// If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
ImVec2 canvas_pos = ImGui : : GetCursorScreenPos ( ) ; // ImDrawList API uses screen coordinates!
ImVec2 canvas_size = ImGui : : GetContentRegionAvail ( ) ; // Resize canvas to what's available
if ( canvas_size . x < 50.0f ) canvas_size . x = 50.0f ;
if ( canvas_size . y < 50.0f ) canvas_size . y = 50.0f ;
draw_list - > AddRectFilledMultiColor ( canvas_pos , ImVec2 ( canvas_pos . x + canvas_size . x , canvas_pos . y + canvas_size . y ) , IM_COL32 ( 50 , 50 , 50 , 255 ) , IM_COL32 ( 50 , 50 , 60 , 255 ) , IM_COL32 ( 60 , 60 , 70 , 255 ) , IM_COL32 ( 50 , 50 , 60 , 255 ) ) ;
draw_list - > AddRect ( canvas_pos , ImVec2 ( canvas_pos . x + canvas_size . x , canvas_pos . y + canvas_size . y ) , IM_COL32 ( 255 , 255 , 255 , 255 ) ) ;
bool adding_preview = false ;
ImGui : : InvisibleButton ( " canvas " , canvas_size ) ;
ImVec2 mouse_pos_in_canvas = ImVec2 ( ImGui : : GetIO ( ) . MousePos . x - canvas_pos . x , ImGui : : GetIO ( ) . MousePos . y - canvas_pos . y ) ;
if ( adding_line )
{
adding_preview = true ;
points . push_back ( mouse_pos_in_canvas ) ;
if ( ! ImGui : : IsMouseDown ( 0 ) )
adding_line = adding_preview = false ;
}
if ( ImGui : : IsItemHovered ( ) )
{
if ( ! adding_line & & ImGui : : IsMouseClicked ( 0 ) )
{
points . push_back ( mouse_pos_in_canvas ) ;
adding_line = true ;
}
if ( ImGui : : IsMouseClicked ( 1 ) & & ! points . empty ( ) )
{
adding_line = adding_preview = false ;
points . pop_back ( ) ;
points . pop_back ( ) ;
}
}
draw_list - > PushClipRect ( canvas_pos , ImVec2 ( canvas_pos . x + canvas_size . x , canvas_pos . y + canvas_size . y ) , true ) ; // clip lines within the canvas (if we resize it, etc.)
for ( int i = 0 ; i < points . Size - 1 ; i + = 2 )
draw_list - > AddLine ( ImVec2 ( canvas_pos . x + points [ i ] . x , canvas_pos . y + points [ i ] . y ) , ImVec2 ( canvas_pos . x + points [ i + 1 ] . x , canvas_pos . y + points [ i + 1 ] . y ) , IM_COL32 ( 255 , 255 , 0 , 255 ) , 2.0f ) ;
draw_list - > PopClipRect ( ) ;
if ( adding_preview )
points . pop_back ( ) ;
}
ImGui : : End ( ) ;
}
// End of Demo code
# else