@ -6614,19 +6614,21 @@ void ImGuiMenuColumns::CalcNextTotalWidth(bool update_offsets)
want_spacing | = ( width > 0 ) ;
if ( update_offsets )
{
if ( i = = 1 ) { OffsetShortcut = offset ; }
if ( i = = 2 ) { OffsetMark = offset ; }
if ( i = = 1 ) { OffsetLabel = offset ; }
if ( i = = 2 ) { OffsetShortcut = offset ; }
if ( i = = 3 ) { OffsetMark = offset ; }
}
offset + = width ;
}
NextTotalWidth = offset ;
}
float ImGuiMenuColumns : : DeclColumns ( float w_ label, float w_shortcut , float w_mark )
float ImGuiMenuColumns : : DeclColumns ( float w_ icon, float w_ label, float w_shortcut , float w_mark )
{
Widths [ 0 ] = ImMax ( Widths [ 0 ] , ( ImU16 ) w_label ) ;
Widths [ 1 ] = ImMax ( Widths [ 1 ] , ( ImU16 ) w_shortcut ) ;
Widths [ 2 ] = ImMax ( Widths [ 2 ] , ( ImU16 ) w_mark ) ;
Widths [ 0 ] = ImMax ( Widths [ 0 ] , ( ImU16 ) w_icon ) ;
Widths [ 1 ] = ImMax ( Widths [ 1 ] , ( ImU16 ) w_label ) ;
Widths [ 2 ] = ImMax ( Widths [ 2 ] , ( ImU16 ) w_shortcut ) ;
Widths [ 3 ] = ImMax ( Widths [ 3 ] , ( ImU16 ) w_mark ) ;
CalcNextTotalWidth ( false ) ;
return ( float ) ImMax ( TotalWidth , NextTotalWidth ) ;
}
@ -6818,6 +6820,10 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
// However the final position is going to be different! It is chosen by FindBestWindowPosForPopup().
// e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
ImVec2 popup_pos , pos = window - > DC . CursorPos ;
PushID ( label ) ;
if ( ! enabled )
PushStyleColor ( ImGuiCol_Text , style . Colors [ ImGuiCol_TextDisabled ] ) ;
const ImGuiMenuColumns * offsets = & window - > DC . MenuColumns ;
if ( window - > DC . LayoutType = = ImGuiLayoutType_Horizontal )
{
// Menu inside an horizontal menu bar
@ -6827,7 +6833,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
window - > DC . CursorPos . x + = IM_FLOOR ( style . ItemSpacing . x * 0.5f ) ;
PushStyleVar ( ImGuiStyleVar_ItemSpacing , ImVec2 ( style . ItemSpacing . x * 2.0f , style . ItemSpacing . y ) ) ;
float w = label_size . x ;
pressed = Selectable ( label , menu_is_open , ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( w , 0.0f ) ) ;
ImVec2 text_pos ( window - > DC . CursorPos . x + offsets - > OffsetLabel , window - > DC . CursorPos . y + window - > DC . CurrLineTextBaseOffset ) ;
pressed = Selectable ( " " , menu_is_open , ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( w , 0.0f ) ) ;
RenderText ( text_pos , label ) ;
PopStyleVar ( ) ;
window - > DC . CursorPos . x + = IM_FLOOR ( style . ItemSpacing . x * ( - 1.0f + 0.5f ) ) ; // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
}
@ -6837,12 +6845,18 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
popup_pos = ImVec2 ( pos . x , pos . y - style . WindowPadding . y ) ;
float min_w = window - > DC . MenuColumns . DeclColumns ( label_size . x , 0.0f , IM_FLOOR ( g . FontSize * 1.20f ) ) ; // Feedback to next frame
float icon_w = 0.0f ; // FIXME: This not currently exposed for BeginMenu() however you can call window->DC.MenuColumns.DeclColumns(w, 0, 0, 0) yourself
float checkmark_w = IM_FLOOR ( g . FontSize * 1.20f ) ;
float min_w = window - > DC . MenuColumns . DeclColumns ( icon_w , label_size . x , 0.0f , checkmark_w ) ; // Feedback to next frame
float extra_w = ImMax ( 0.0f , GetContentRegionAvail ( ) . x - min_w ) ;
pressed = Selectable ( label , menu_is_open , ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( min_w , 0.0f ) ) ;
ImU32 text_col = GetColorU32 ( enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled ) ;
RenderArrow ( window - > DrawList , pos + ImVec2 ( window - > DC . MenuColumns . OffsetMark + extra_w + g . FontSize * 0.30f , 0.0f ) , text_col , ImGuiDir_Right ) ;
ImVec2 text_pos ( window - > DC . CursorPos . x + offsets - > OffsetLabel , window - > DC . CursorPos . y + window - > DC . CurrLineTextBaseOffset ) ;
pressed = Selectable ( " " , menu_is_open , ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth | ( ! enabled ? ImGuiSelectableFlags_Disabled : 0 ) , ImVec2 ( min_w , 0.0f ) ) ;
RenderText ( text_pos , label ) ;
RenderArrow ( window - > DrawList , pos + ImVec2 ( offsets - > OffsetMark + extra_w + g . FontSize * 0.30f , 0.0f ) , GetColorU32 ( ImGuiCol_Text ) , ImGuiDir_Right ) ;
}
if ( ! enabled )
PopStyleColor ( ) ;
PopID ( ) ;
const bool hovered = enabled & & ItemHoverable ( window - > DC . LastItemRect , id ) ;
if ( menuset_is_open )
@ -6958,7 +6972,7 @@ void ImGui::EndMenu()
EndPopup ( ) ;
}
bool ImGui : : MenuItem ( const char * label , const char * shortcut , bool selected , bool enabled )
bool ImGui : : MenuItem Ex ( const char * label , const char * icon , const char * shortcut , bool selected , bool enabled )
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
@ -6973,6 +6987,10 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
// but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only.
ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover | ( enabled ? 0 : ImGuiSelectableFlags_Disabled ) ;
bool pressed ;
PushID ( label ) ;
if ( ! enabled )
PushStyleColor ( ImGuiCol_Text , style . Colors [ ImGuiCol_TextDisabled ] ) ;
const ImGuiMenuColumns * offsets = & window - > DC . MenuColumns ;
if ( window - > DC . LayoutType = = ImGuiLayoutType_Horizontal )
{
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
@ -6980,8 +6998,9 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
float w = label_size . x ;
window - > DC . CursorPos . x + = IM_FLOOR ( style . ItemSpacing . x * 0.5f ) ;
PushStyleVar ( ImGuiStyleVar_ItemSpacing , ImVec2 ( style . ItemSpacing . x * 2.0f , style . ItemSpacing . y ) ) ;
pressed = Selectable ( label , selected , flags , ImVec2 ( w , 0.0f ) ) ;
pressed = Selectable ( " " , selected , flags , ImVec2 ( w , 0.0f ) ) ;
PopStyleVar ( ) ;
RenderText ( pos + ImVec2 ( offsets - > OffsetLabel , 0.0f ) , label ) ;
window - > DC . CursorPos . x + = IM_FLOOR ( style . ItemSpacing . x * ( - 1.0f + 0.5f ) ) ; // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
}
else
@ -6989,27 +7008,40 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
// Menu item inside a vertical menu
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
float shortcut_w = shortcut ? CalcTextSize ( shortcut , NULL ) . x : 0.0f ;
float min_w = window - > DC . MenuColumns . DeclColumns ( label_size . x , shortcut_w , IM_FLOOR ( g . FontSize * 1.20f ) ) ; // Feedback for next frame
float extra_w = ImMax ( 0.0f , GetContentRegionAvail ( ) . x - min_w ) ;
pressed = Selectable ( label , false , flags | ImGuiSelectableFlags_SpanAvailWidth , ImVec2 ( min_w , 0.0f ) ) ;
float icon_w = ( icon & & icon [ 0 ] ) ? CalcTextSize ( icon , NULL ) . x : 0.0f ;
float shortcut_w = ( shortcut & & shortcut [ 0 ] ) ? CalcTextSize ( shortcut , NULL ) . x : 0.0f ;
float checkmark_w = IM_FLOOR ( g . FontSize * 1.20f ) ;
float min_w = window - > DC . MenuColumns . DeclColumns ( icon_w , label_size . x , shortcut_w , checkmark_w ) ; // Feedback for next frame
float stretch_w = ImMax ( 0.0f , GetContentRegionAvail ( ) . x - min_w ) ;
pressed = Selectable ( " " , false , flags | ImGuiSelectableFlags_SpanAvailWidth , ImVec2 ( min_w , 0.0f ) ) ;
RenderText ( pos + ImVec2 ( offsets - > OffsetLabel , 0.0f ) , label ) ;
if ( icon_w > 0.0f )
RenderText ( pos + ImVec2 ( offsets - > OffsetIcon , 0.0f ) , icon ) ;
if ( shortcut_w > 0.0f )
{
PushStyleColor ( ImGuiCol_Text , g . Style . Colors [ ImGuiCol_TextDisabled ] ) ;
RenderText ( pos + ImVec2 ( window - > DC . MenuColumns . OffsetShortcut + extra_w , 0.0f ) , shortcut , NULL , false ) ;
PushStyleColor ( ImGuiCol_Text , s tyle. Colors [ ImGuiCol_TextDisabled ] ) ;
RenderText ( pos + ImVec2 ( offsets- > OffsetShortcut + stretch _w, 0.0f ) , shortcut , NULL , false ) ;
PopStyleColor ( ) ;
}
if ( selected )
RenderCheckMark ( window - > DrawList , pos + ImVec2 ( window- > DC . MenuColumns . OffsetMark + extra _w + g . FontSize * 0.40f , g . FontSize * 0.134f * 0.5f ) , GetColorU32 ( enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled ) , g . FontSize * 0.866f ) ;
RenderCheckMark ( window - > DrawList , pos + ImVec2 ( offsets- > OffsetMark + stretch _w + g . FontSize * 0.40f , g . FontSize * 0.134f * 0.5f ) , GetColorU32 ( ImGuiCol_Text) , g . FontSize * 0.866f ) ;
}
if ( ! enabled )
PopStyleColor ( ) ;
PopID ( ) ;
IMGUI_TEST_ENGINE_ITEM_INFO ( window - > DC . LastItemId , label , window - > DC . LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | ( selected ? ImGuiItemStatusFlags_Checked : 0 ) ) ;
return pressed ;
}
bool ImGui : : MenuItem ( const char * label , const char * shortcut , bool selected , bool enabled )
{
return MenuItemEx ( label , NULL , shortcut , selected , enabled ) ;
}
bool ImGui : : MenuItem ( const char * label , const char * shortcut , bool * p_selected , bool enabled )
{
if ( MenuItem ( label , shortcut , p_selected ? * p_selected : false , enabled ) )
if ( MenuItem Ex ( label , NULL , shortcut , p_selected ? * p_selected : false , enabled ) )
{
if ( p_selected )
* p_selected = ! * p_selected ;