@@ -61,9 +61,6 @@ void uilist_impl::on_resized()
6161
6262void uilist_impl::draw_controls ()
6363{
64- float hotkey_width =
65- ImGui::CalcTextSize ( " [X]" ).x + ImGui::GetStyle ().ItemSpacing .x ;
66-
6764 if ( !parent.text .empty () ) {
6865 cataimgui::draw_colored_text ( parent.text );
6966 ImGui::Separator ();
@@ -81,47 +78,58 @@ void uilist_impl::draw_controls()
8178 ImGui::TableNextRow ();
8279 ImGui::TableSetColumnIndex ( 1 );
8380
81+ float entry_height = ImGui::GetTextLineHeightWithSpacing ();
8482 if ( ImGui::BeginChild ( " scroll" , parent.calculated_menu_size , false ) ) {
85- // It would be natural to make the entries into buttons, or
86- // combos, or other pre-built ui elements. For now I am mostly
87- // going to copy the style of the original textual ui elements.
88- for ( size_t i = 0 ; i < parent.fentries .size (); i++ ) {
89- auto entry = parent.entries [parent.fentries [i]];
90- ImGui::PushID ( i );
91- ImGuiSelectableFlags_ flags = !entry.enabled ? ImGuiSelectableFlags_Disabled :
92- ImGuiSelectableFlags_None;
93- bool is_selected = static_cast <int >( i ) == parent.fselected ;
94- if ( ImGui::Selectable ( " " , is_selected, flags | ImGuiSelectableFlags_AllowItemOverlap ) ||
95- ImGui::IsItemHovered () ) {
96- parent.fselected = i;
97- parent.selected = parent.fentries [parent.fselected ];
98- }
99- ImGui::SameLine ( 0 , 0 );
100- if ( is_selected ) {
101- ImGui::SetItemDefaultFocus ();
102- ImGui::SetScrollHereY ();
103- }
83+ if ( ImGui::BeginTable ( " menu items" , 3 , ImGuiTableFlags_SizingFixedFit ) ) {
84+ ImGui::TableSetupColumn ( " hotkey" , ImGuiTableColumnFlags_WidthFixed,
85+ parent.calculated_hotkey_width );
86+ ImGui::TableSetupColumn ( " primary" , ImGuiTableColumnFlags_WidthFixed,
87+ parent.calculated_label_width );
88+ ImGui::TableSetupColumn ( " secondary" , ImGuiTableColumnFlags_WidthFixed,
89+ parent.calculated_secondary_width );
90+
91+ // It would be natural to make the entries into buttons, or
92+ // combos, or other pre-built ui elements. For now I am mostly
93+ // going to copy the style of the original textual ui elements.
94+ for ( size_t i = 0 ; i < parent.fentries .size (); i++ ) {
95+ auto entry = parent.entries [parent.fentries [i]];
96+ ImGui::TableNextRow ( ImGuiTableRowFlags_None, entry_height );
97+ ImGui::TableSetColumnIndex ( 0 );
98+
99+ ImVec2 rowMin = ImGui::GetCursorScreenPos ();
100+ ImVec2 rowMax = ImVec2 ( rowMin.x + parent.calculated_menu_size .x , rowMin.y + entry_height );
101+ bool is_hovered = ImGui::IsMouseHoveringRect ( rowMin, rowMax, false );
102+ if ( is_hovered ) {
103+ ImGui::TableSetBgColor ( ImGuiTableBgTarget_RowBg1,
104+ ImColor ( ImGui::GetStyle ().Colors [ ImGuiCol_HeaderHovered ] ) );
105+ parent.fselected = i;
106+ }
107+ bool is_selected = static_cast <int >( i ) == parent.fselected ;
108+ if ( is_selected ) {
109+ ImGui::SetItemDefaultFocus ();
110+ ImGui::SetScrollHereY ();
111+ ImGui::TableSetBgColor ( ImGuiTableBgTarget_RowBg1,
112+ ImColor ( ImGui::GetStyle ().Colors [ ImGuiCol_HeaderActive ] ) );
113+ }
104114
105- if ( entry.hotkey .has_value () ) {
106- ImGui::Text ( " %c" , ' [' );
107- ImGui::SameLine ( 0 , 0 );
108- nc_color color = is_selected ? parent.hilight_color : parent.hotkey_color ;
109- cataimgui::draw_colored_text ( entry.hotkey .value ().short_description (),
110- color );
111- ImGui::SameLine ( 0 , 0 );
112- ImGui::Text ( " %c" , ' ]' );
113- ImGui::SameLine ();
114- } else {
115- ImGui::SetCursorPosX ( hotkey_width );
115+ if ( entry.hotkey .has_value () ) {
116+ nc_color color = is_selected ? parent.hilight_color : parent.hotkey_color ;
117+ cataimgui::draw_colored_text ( entry.hotkey .value ().short_description (),
118+ color );
119+ }
120+ ImGui::TableSetColumnIndex ( 1 );
121+ nc_color color = ( is_selected ?
122+ parent.hilight_color :
123+ ( entry.enabled || entry.force_color ?
124+ entry.text_color :
125+ parent.disabled_color ) );
126+ cataimgui::draw_colored_text ( entry.txt , color );
127+ ImGui::TableSetColumnIndex ( 2 );
128+ if ( !entry.ctxt .empty () ) {
129+ cataimgui::draw_colored_text ( entry.ctxt , color );
130+ }
116131 }
117- nc_color color = ( is_selected ?
118- parent.hilight_color :
119- ( entry.enabled || entry.force_color ?
120- entry.text_color :
121- parent.disabled_color ) );
122- cataimgui::draw_colored_text ( entry.txt ,
123- color );
124- ImGui::PopID ();
132+ ImGui::EndTable ();
125133 }
126134 }
127135 ImGui::EndChild ();
@@ -357,6 +365,9 @@ void uilist::init()
357365 desired_bounds = std::nullopt ;
358366 calculated_bounds = { -1 .f , -1 .f , -1 .f , -1 .f };
359367 calculated_menu_size = { 0.0 , 0.0 };
368+ calculated_hotkey_width = 0.0 ;
369+ calculated_label_width = 0.0 ;
370+ calculated_secondary_width = 0.0 ;
360371 extra_space_left = 0.0 ;
361372 extra_space_right = 0.0 ;
362373 ret = UILIST_WAIT_INPUT;
@@ -556,6 +567,8 @@ static ImVec2 calc_size( const std::string_view line )
556567
557568void uilist::calc_data ()
558569{
570+ ImGuiStyle s = ImGui::GetStyle ();
571+
559572 std::vector<int > autoassign;
560573 for ( size_t i = 0 ; i < entries.size (); i++ ) {
561574 if ( entries[ i ].enabled ) {
@@ -594,13 +607,13 @@ void uilist::calc_data()
594607 bool has_titlebar = !title.empty ();
595608 if ( has_titlebar ) {
596609 title_size = calc_size ( title );
597- title_size.y += ImGui::GetStyle () .FramePadding .y * 2.0 ;
610+ title_size.y += s .FramePadding .y * 2.0 ;
598611 }
599612
600613 ImVec2 text_size = {};
601614 if ( !text.empty () ) {
602615 text_size = calc_size ( text );
603- text_size.y += ImGui::GetStyle () .ItemSpacing .y * 2.0 ;
616+ text_size.y += s .ItemSpacing .y * 2.0 ;
604617 }
605618
606619 ImVec2 desc_size = {};
@@ -614,37 +627,51 @@ void uilist::calc_data()
614627 if ( desc_size.y <= 0.0 ) {
615628 desc_enabled = false ;
616629 }
617- desc_size.y += ImGui::GetStyle () .ItemSpacing .y * 2.0 ;
630+ desc_size.y += s .ItemSpacing .y * 2.0 ;
618631 }
619632 float additional_height = title_size.y + text_size.y + desc_size.y + 2.0 *
620- ( ImGui::GetStyle () .FramePadding .y + ImGui::GetStyle () .WindowBorderSize );
633+ ( s .FramePadding .y + s .WindowBorderSize );
621634
622635 if ( vmax * ImGui::GetTextLineHeightWithSpacing () + additional_height >
623636 ImGui::GetMainViewport ()->Size .y ) {
624637 vmax = floorf ( ( ImGui::GetMainViewport ()->Size .y - additional_height ) /
625638 ImGui::GetTextLineHeightWithSpacing () );
626639 }
627640
628- calculated_menu_size = { 0.0 , 0.0 };
641+ float padding = 2 .0f * s.CellPadding .x ;
642+ calculated_hotkey_width = ImGui::CalcTextSize ( " X" ).x ;
643+ calculated_label_width = 0.0 ;
644+ calculated_secondary_width = 0.0 ;
629645 for ( int fentry : fentries ) {
630- calculated_menu_size.x = std::max ( calculated_menu_size.x , calc_size ( entries[fentry].txt ).x );
646+ calculated_label_width = std::max ( calculated_label_width, calc_size ( entries[fentry].txt ).x );
647+ calculated_secondary_width = std::max ( calculated_secondary_width,
648+ calc_size ( entries[fentry].ctxt ).x );
631649 }
632- calculated_menu_size.x += ImGui::CalcTextSize ( " [X] " ).x ;
650+ calculated_menu_size = { 0.0 , 0.0 };
651+ calculated_menu_size.x += calculated_hotkey_width + padding;
652+ calculated_menu_size.x += calculated_label_width + padding;
653+ calculated_menu_size.x += calculated_secondary_width + padding;
633654 calculated_menu_size.y = std::min ( ImGui::GetMainViewport ()->Size .y - additional_height,
634- vmax * ImGui::GetTextLineHeightWithSpacing () ) + ( ImGui::GetStyle () .FramePadding .y * 2.0 );
655+ vmax * ImGui::GetTextLineHeightWithSpacing () ) + ( s .FramePadding .y * 2.0 );
635656
636657 extra_space_left = 0.0 ;
637658 extra_space_right = 0.0 ;
638659 if ( callback != nullptr ) {
639- extra_space_left = callback->desired_extra_space_left ( ) + ImGui::GetStyle () .FramePadding .x ;
640- extra_space_right = callback->desired_extra_space_right ( ) + ImGui::GetStyle () .FramePadding .x ;
660+ extra_space_left = callback->desired_extra_space_left ( ) + s .FramePadding .x ;
661+ extra_space_right = callback->desired_extra_space_right ( ) + s .FramePadding .x ;
641662 }
642663
643664 float longest_line_width = std::max ( std::max ( title_size.x , text_size.x ),
644665 std::max ( calculated_menu_size.x , desc_size.x ) );
645666 calculated_bounds.w = extra_space_left + extra_space_right + longest_line_width
646- + 2 * ( ImGui::GetStyle () .WindowPadding .x + ImGui::GetStyle () .WindowBorderSize );
667+ + 2 * ( s .WindowPadding .x + s .WindowBorderSize );
647668 calculated_bounds.h = calculated_menu_size.y + additional_height;
669+
670+ if ( longest_line_width > calculated_menu_size.x ) {
671+ calculated_menu_size.x = longest_line_width;
672+ calculated_label_width = calculated_menu_size.x - calculated_hotkey_width - padding -
673+ calculated_secondary_width - padding - padding;
674+ }
648675}
649676
650677void uilist::setup ()
0 commit comments