@ -39,14 +39,13 @@ Index of this file:
DOCUMENTATION
- MISSION STATEMENT
- END - USER GUIDE
- CONTROLS GUIDE
- PROGRAMMER GUIDE
- READ FIRST
- HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
- GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE / ENGINE
- HOW A SIMPLE APPLICATION MAY LOOK LIKE
- HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
- USING KEYBOARD / GAMEPAD NAVIGATION CONTROLS
- API BREAKING CHANGES ( read me when you update ! )
- FREQUENTLY ASKED QUESTIONS ( FAQ )
- Read all answers online : https : //www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
@ -114,27 +113,73 @@ CODE
- Limited layout features , intricate layouts are typically crafted in code .
END - USER GUIDE
CONTROLS GUIDE
= = = = = = = = = = = = = =
- Double - click on title bar to collapse window .
- Click upper right corner to close a window , available when ' bool * p_open ' is passed to ImGui : : Begin ( ) .
- Click and drag on lower right corner to resize window ( double - click to auto fit window to its contents ) .
- Click and drag on any empty space to move window .
- TAB / SHIFT + TAB to cycle through keyboard editable fields .
- CTRL + Click on a slider or drag box to input value as text .
- Use mouse wheel to scroll .
- Text editor :
- Hold SHIFT or use mouse to select text .
- CTRL + Left / Right to word jump .
- CTRL + Shift + Left / Right to select words .
- CTRL + A or Double - Click to select all .
- CTRL + X , CTRL + C , CTRL + V to use OS clipboard /
- CTRL + Z , CTRL + Y to undo / redo .
- ESCAPE to revert text to its original value .
- Controls are automatically adjusted for OSX to match standard OSX text editing operations .
- General Keyboard controls : enable with ImGuiConfigFlags_NavEnableKeyboard .
- General Gamepad controls : enable with ImGuiConfigFlags_NavEnableGamepad . Download controller mapping PNG / PSD at http : //dearimgui.org/controls_sheets
- MOUSE CONTROLS
- Mouse wheel : Scroll vertically .
- SHIFT + Mouse wheel : Scroll horizontally .
- Click [ X ] : Close a window , available when ' bool * p_open ' is passed to ImGui : : Begin ( ) .
- Click ^ , Double - Click title : Collapse window .
- Drag on corner / border : Resize window ( double - click to auto fit window to its contents ) .
- Drag on any empty space : Move window ( unless io . ConfigWindowsMoveFromTitleBarOnly = true ) .
- Left - click outside popup : Close popup stack ( right - click over underlying popup : Partially close popup stack ) .
- TEXT EDITOR
- Hold SHIFT or Drag Mouse : Select text .
- CTRL + Left / Right : Word jump .
- CTRL + Shift + Left / Right : Select words .
- CTRL + A or Double - Click : Select All .
- CTRL + X , CTRL + C , CTRL + V : Use OS clipboard .
- CTRL + Z , CTRL + Y : Undo , Redo .
- ESCAPE : Revert text to its original value .
- On OSX , controls are automatically adjusted to match standard OSX text editing shortcuts and behaviors .
- KEYBOARD CONTROLS
- Basic :
- Tab , SHIFT + Tab Cycle through text editable fields .
- CTRL + Tab , CTRL + Shift + Tab Cycle through windows .
- CTRL + Click Input text into a Slider or Drag widget .
- Extended features with ` io . ConfigFlags | = ImGuiConfigFlags_NavEnableKeyboard ` :
- Tab , SHIFT + Tab : Cycle through every items .
- Arrow keys Move through items using directional navigation . Tweak value .
- Arrow keys + Alt , Shift Tweak slower , tweak faster ( when using arrow keys ) .
- Enter Activate item ( prefer text input when possible ) .
- Space Activate item ( prefer tweaking with arrows when possible ) .
- Escape Deactivate item , leave child window , close popup .
- Page Up , Page Down Previous page , next page .
- Home , End Scroll to top , scroll to bottom .
- Alt Toggle between scrolling layer and menu layer .
- CTRL + Tab then Ctrl + Arrows Move window . Hold SHIFT to resize instead of moving .
- Output when ImGuiConfigFlags_NavEnableKeyboard set ,
- io . WantCaptureKeyboard flag is set when keyboard is claimed .
- io . NavActive : true when a window is focused and it doesn ' t have the ImGuiWindowFlags_NoNavInputs flag set .
- io . NavVisible : true when the navigation cursor is visible ( usually goes to back false when mouse is used ) .
- GAMEPAD CONTROLS
- Enable with ' io . ConfigFlags | = ImGuiConfigFlags_NavEnableGamepad ' .
- Particularly useful to use Dear ImGui on a console system ( e . g . PlayStation , Switch , Xbox ) without a mouse !
- Download controller mapping PNG / PSD at http : //dearimgui.org/controls_sheets
- Backend support : backend needs to :
- Set ' io . BackendFlags | = ImGuiBackendFlags_HasGamepad ' + call io . AddKeyEvent / AddKeyAnalogEvent ( ) with ImGuiKey_Gamepad_XXX keys .
- For analog values ( 0.0f to 1.0f ) , backend is responsible to handling a dead - zone and rescaling inputs accordingly .
Backend code will probably need to transform your raw inputs ( such as e . g . remapping your 0.2 . .0 .9 raw input range to 0.0 . .1 .0 imgui range , etc . ) .
- BEFORE 1.87 , BACKENDS USED TO WRITE TO io . NavInputs [ ] . This is now obsolete . Please call io functions instead !
- If you need to share inputs between your game and the Dear ImGui interface , the easiest approach is to go all - or - nothing ,
with a buttons combo to toggle the target . Please reach out if you think the game vs navigation input sharing could be improved .
- REMOTE INPUTS SHARING & MOUSE EMULATION
- PS4 / PS5 users : Consider emulating a mouse cursor with DualShock touch pad or a spare analog stick as a mouse - emulation fallback .
- Consoles / Tablet / Phone users : Consider using a Synergy 1. x server ( on your PC ) + run examples / libs / synergy / uSynergy . c ( on your console / tablet / phone app )
in order to share your PC mouse / keyboard .
- See https : //github.com/ocornut/imgui/wiki/Useful-Extensions#remoting for other remoting solutions.
- On a TV / console system where readability may be lower or mouse inputs may be awkward , you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag .
Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs Dear ImGui to move your mouse cursor along with navigation movements .
When enabled , the NewFrame ( ) function may alter ' io . MousePos ' and set ' io . WantSetMousePos ' to notify you that it wants the mouse cursor to be moved .
When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame . Some of the backends in examples / do that .
( If you set the NavEnableSetMousePos flag but don ' t honor ' io . WantSetMousePos ' properly , Dear ImGui will misbehave as it will see your mouse moving back & forth ! )
( In a setup when you may not have easy control over the mouse cursor , e . g . uSynergy . c doesn ' t expose moving remote mouse cursor , you may want
to set a boolean to ignore your other external mouse positions until the external source is moved again . )
PROGRAMMER GUIDE
@ -344,41 +389,6 @@ CODE
}
USING KEYBOARD / GAMEPAD NAVIGATION CONTROLS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- The keyboard / gamepad navigation is fairly functional and keeps being improved .
- Gamepad support is particularly useful to use Dear ImGui on a console system ( e . g . PlayStation , Switch , Xbox ) without a mouse !
- The initial focus was to support game controllers , but keyboard is becoming increasingly and decently usable .
- Keyboard :
- Application : Set io . ConfigFlags | = ImGuiConfigFlags_NavEnableKeyboard to enable .
- Arrow keys to move . Space or Enter to activate ( on a slider / drag : Space will tweak with arrow , Enter will input text ) .
- When keyboard navigation is active ( io . NavActive + ImGuiConfigFlags_NavEnableKeyboard ) ,
the io . WantCaptureKeyboard flag will be set . For more advanced uses , you may want to read from :
- io . NavActive : true when a window is focused and it doesn ' t have the ImGuiWindowFlags_NoNavInputs flag set .
- io . NavVisible : true when the navigation cursor is visible ( and usually goes false when mouse is used ) .
- or query focus information with e . g . IsWindowFocused ( ImGuiFocusedFlags_AnyWindow ) , IsItemFocused ( ) etc . functions .
Please reach out if you think the game vs navigation input sharing could be improved .
- Gamepad :
- Application : Set io . ConfigFlags | = ImGuiConfigFlags_NavEnableGamepad to enable .
- Backend : Set io . BackendFlags | = ImGuiBackendFlags_HasGamepad + call io . AddKeyEvent / AddKeyAnalogEvent ( ) with ImGuiKey_Gamepad_XXX keys .
For analog values ( 0.0f to 1.0f ) , backend is responsible to handling a dead - zone and rescaling inputs accordingly .
Backend code will probably need to transform your raw inputs ( such as e . g . remapping your 0.2 . .0 .9 raw input range to 0.0 . .1 .0 imgui range , etc . ) .
- BEFORE 1.87 , BACKENDS USED TO WRITE TO io . NavInputs [ ] . This is now obsolete . Please call io functions instead !
- You can download PNG / PSD files depicting the gamepad controls for common controllers at : http : //dearimgui.org/controls_sheets
- If you need to share inputs between your game and the Dear ImGui interface , the easiest approach is to go all - or - nothing ,
with a buttons combo to toggle the target . Please reach out if you think the game vs navigation input sharing could be improved .
- Mouse :
- PS4 / PS5 users : Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse - emulation fallback .
- Consoles / Tablet / Phone users : Consider using a Synergy 1. x server ( on your PC ) + uSynergy . c ( on your console / tablet / phone app ) to share your PC mouse / keyboard .
- On a TV / console system where readability may be lower or mouse inputs may be awkward , you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag .
Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs dear imgui to move your mouse cursor along with navigation movements .
When enabled , the NewFrame ( ) function may alter ' io . MousePos ' and set ' io . WantSetMousePos ' to notify you that it wants the mouse cursor to be moved .
When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame . Some of the backends in examples / do that .
( If you set the NavEnableSetMousePos flag but don ' t honor ' io . WantSetMousePos ' properly , imgui will misbehave as it will see your mouse moving back and forth ! )
( In a setup when you may not have easy control over the mouse cursor , e . g . uSynergy . c doesn ' t expose moving remote mouse cursor , you may want
to set a boolean to ignore your other external mouse positions until the external source is moved again . )
API BREAKING CHANGES
= = = = = = = = = = = = = = = = = = = =
@ -1013,7 +1023,7 @@ static void NavEndFrame();
static bool NavScoreItem ( ImGuiNavItemData * result ) ;
static void NavApplyItemToResult ( ImGuiNavItemData * result ) ;
static void NavProcessItem ( ) ;
static void NavProcessItemForTabbingRequest ( ImGuiID id ) ;
static void NavProcessItemForTabbingRequest ( ImGuiID id , ImGuiItemFlags item_flags , ImGuiNavMoveFlags move_flags ) ;
static ImVec2 NavCalcPreferredRefPos ( ) ;
static void NavSaveLastChildNavWindowIntoParent ( ImGuiWindow * nav_window ) ;
static ImGuiWindow * NavRestoreLastChildNavWindow ( ImGuiWindow * window ) ;
@ -10746,16 +10756,14 @@ static void ImGui::NavProcessItem()
// Process Move Request (scoring for navigation)
// FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy)
if ( g . NavMoveScoringItems )
if ( g . NavMoveScoringItems & & ( item_flags & ImGuiItemFlags_Disabled ) = = 0 )
{
const bool is_tab_stop = ( item_flags & ImGuiItemFlags_Inputable ) & & ( item_flags & ( ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled ) ) = = 0 ;
const bool is_tabbing = ( g . NavMoveFlags & ImGuiNavMoveFlags_Tabbing ) ! = 0 ;
if ( is_tabbing )
{
if ( is_tab_stop | | ( g . NavMoveFlags & ImGuiNavMoveFlags_FocusApi ) )
NavProcessItemForTabbingRequest ( id ) ;
NavProcessItemForTabbingRequest ( id , item_flags , g . NavMoveFlags ) ;
}
else if ( ( g . NavId ! = id | | ( g . NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId ) ) & & ! ( item_flags & ImGuiItemFlags_Disable d ) )
else if ( g . NavId ! = id | | ( g . NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId ) )
{
ImGuiNavItemData * result = ( window = = g . NavWindow ) ? & g . NavMoveResultLocal : & g . NavMoveResultOther ;
if ( NavScoreItem ( result ) )
@ -10789,18 +10797,31 @@ static void ImGui::NavProcessItem()
// - Case 3: tab forward wrap: set result to first eligible item (preemptively), on ref id set counter, on next frame if counter hasn't elapsed store result. // FIXME-TABBING: Could be done as a next-frame forwarded request
// - Case 4: tab backward: store all results, on ref id pick prev, stop storing
// - Case 5: tab backward wrap: store all results, on ref id if no result keep storing until last // FIXME-TABBING: Could be done as next-frame forwarded requested
void ImGui : : NavProcessItemForTabbingRequest ( ImGuiID id )
void ImGui : : NavProcessItemForTabbingRequest ( ImGuiID id , ImGuiItemFlags item_flags , ImGuiNavMoveFlags move_flags )
{
ImGuiContext & g = * GImGui ;
if ( ( move_flags & ImGuiNavMoveFlags_FocusApi ) = = 0 )
if ( g . NavLayer ! = g . CurrentWindow - > DC . NavLayerCurrent )
return ;
// - Can always land on an item when using API call.
// - Tabbing with _NavEnableKeyboard (space/enter/arrows): goes through every item.
// - Tabbing without _NavEnableKeyboard: goes through inputable items only.
bool can_stop ;
if ( move_flags & ImGuiNavMoveFlags_FocusApi )
can_stop = true ;
else
can_stop = ( item_flags & ImGuiItemFlags_NoTabStop ) = = 0 & & ( ( g . IO . ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard ) | | ( item_flags & ImGuiItemFlags_Inputable ) ) ;
// Always store in NavMoveResultLocal (unlike directional request which uses NavMoveResultOther on sibling/flattened windows)
ImGuiNavItemData * result = & g . NavMoveResultLocal ;
if ( g . NavTabbingDir = = + 1 )
{
// Tab Forward or SetKeyboardFocusHere() with >= 0
if ( g . NavTabbingResultFirst . ID = = 0 )
if ( can_stop & & g . NavTabbingResultFirst . ID = = 0 )
NavApplyItemToResult ( & g . NavTabbingResultFirst ) ;
if ( - - g . NavTabbingCounter = = 0 )
if ( can_stop & & g . NavTabbingCounter > 0 & & - - g . NavTabbingCounter = = 0 )
NavMoveRequestResolveWithLastItem ( result ) ;
else if ( g . NavId = = id )
g . NavTabbingCounter = 1 ;
@ -10816,16 +10837,18 @@ void ImGui::NavProcessItemForTabbingRequest(ImGuiID id)
NavUpdateAnyRequestFlag ( ) ;
}
}
else
else if ( can_stop )
{
// Keep applying until reaching NavId
NavApplyItemToResult ( result ) ;
}
}
else if ( g . NavTabbingDir = = 0 )
{
// Tab Init
if ( g . NavTabbingResultFirst . ID = = 0 )
NavMoveRequestResolveWithLastItem ( & g . NavTabbingResultFirst ) ;
if ( can_stop & & g . NavId = = id )
NavMoveRequestResolveWithLastItem ( result ) ;
if ( can_stop & & g . NavTabbingResultFirst . ID = = 0 ) // Tab init
NavApplyItemToResult ( & g . NavTabbingResultFirst ) ;
}
}
@ -11348,8 +11371,11 @@ void ImGui::NavUpdateCreateTabbingRequest()
// (this is ALWAYS ENABLED, regardless of ImGuiConfigFlags_NavEnableKeyboard flag!)
// Initially this was designed to use counters and modulo arithmetic, but that could not work with unsubmitted items (list clipper). Instead we use a strategy close to other move requests.
// See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping.
//// FIXME: We use (g.ActiveId == 0) but (g.NavDisableHighlight == false) might be righter once we can tab through anything
g . NavTabbingDir = g . IO . KeyShift ? - 1 : ( g . ActiveId = = 0 ) ? 0 : + 1 ;
const bool nav_keyboard_active = ( g . IO . ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard ) ! = 0 ;
if ( nav_keyboard_active )
g . NavTabbingDir = g . IO . KeyShift ? - 1 : ( g . NavDisableHighlight = = true & & g . ActiveId = = 0 ) ? 0 : + 1 ;
else
g . NavTabbingDir = g . IO . KeyShift ? - 1 : ( g . ActiveId = = 0 ) ? 0 : + 1 ;
ImGuiScrollFlags scroll_flags = window - > Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY ;
ImGuiDir clip_dir = ( g . NavTabbingDir < 0 ) ? ImGuiDir_Up : ImGuiDir_Down ;
NavMoveRequestSubmit ( ImGuiDir_None , clip_dir , ImGuiNavMoveFlags_Tabbing , scroll_flags ) ; // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
@ -11369,7 +11395,7 @@ void ImGui::NavMoveRequestApplyResult()
ImGuiNavItemData * result = ( g . NavMoveResultLocal . ID ! = 0 ) ? & g . NavMoveResultLocal : ( g . NavMoveResultOther . ID ! = 0 ) ? & g . NavMoveResultOther : NULL ;
// Tabbing forward wrap
if ( g . NavMoveFlags & ImGuiNavMoveFlags_Tabbing )
if ( ( g . NavMoveFlags & ImGuiNavMoveFlags_Tabbing ) & & result = = NULL )
if ( ( g . NavTabbingCounter = = 1 | | g . NavTabbingDir = = 0 ) & & g . NavTabbingResultFirst . ID )
result = & g . NavTabbingResultFirst ;