@@ -61,9 +61,6 @@ void uilist_impl::on_resized()
61
61
62
62
void uilist_impl::draw_controls ()
63
63
{
64
- float hotkey_width =
65
- ImGui::CalcTextSize ( " [X]" ).x + ImGui::GetStyle ().ItemSpacing .x ;
66
-
67
64
if ( !parent.text .empty () ) {
68
65
cataimgui::draw_colored_text ( parent.text );
69
66
ImGui::Separator ();
@@ -81,47 +78,58 @@ void uilist_impl::draw_controls()
81
78
ImGui::TableNextRow ();
82
79
ImGui::TableSetColumnIndex ( 1 );
83
80
81
+ float entry_height = ImGui::GetTextLineHeightWithSpacing ();
84
82
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
+ }
104
114
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
+ }
116
131
}
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 ();
125
133
}
126
134
}
127
135
ImGui::EndChild ();
@@ -357,6 +365,9 @@ void uilist::init()
357
365
desired_bounds = std::nullopt;
358
366
calculated_bounds = { -1 .f , -1 .f , -1 .f , -1 .f };
359
367
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 ;
360
371
extra_space_left = 0.0 ;
361
372
extra_space_right = 0.0 ;
362
373
ret = UILIST_WAIT_INPUT;
@@ -556,6 +567,8 @@ static ImVec2 calc_size( const std::string_view line )
556
567
557
568
void uilist::calc_data ()
558
569
{
570
+ ImGuiStyle s = ImGui::GetStyle ();
571
+
559
572
std::vector<int > autoassign;
560
573
for ( size_t i = 0 ; i < entries.size (); i++ ) {
561
574
if ( entries[ i ].enabled ) {
@@ -594,13 +607,13 @@ void uilist::calc_data()
594
607
bool has_titlebar = !title.empty ();
595
608
if ( has_titlebar ) {
596
609
title_size = calc_size ( title );
597
- title_size.y += ImGui::GetStyle () .FramePadding .y * 2.0 ;
610
+ title_size.y += s .FramePadding .y * 2.0 ;
598
611
}
599
612
600
613
ImVec2 text_size = {};
601
614
if ( !text.empty () ) {
602
615
text_size = calc_size ( text );
603
- text_size.y += ImGui::GetStyle () .ItemSpacing .y * 2.0 ;
616
+ text_size.y += s .ItemSpacing .y * 2.0 ;
604
617
}
605
618
606
619
ImVec2 desc_size = {};
@@ -614,37 +627,51 @@ void uilist::calc_data()
614
627
if ( desc_size.y <= 0.0 ) {
615
628
desc_enabled = false ;
616
629
}
617
- desc_size.y += ImGui::GetStyle () .ItemSpacing .y * 2.0 ;
630
+ desc_size.y += s .ItemSpacing .y * 2.0 ;
618
631
}
619
632
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 );
621
634
622
635
if ( vmax * ImGui::GetTextLineHeightWithSpacing () + additional_height >
623
636
ImGui::GetMainViewport ()->Size .y ) {
624
637
vmax = floorf ( ( ImGui::GetMainViewport ()->Size .y - additional_height ) /
625
638
ImGui::GetTextLineHeightWithSpacing () );
626
639
}
627
640
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 ;
629
645
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 );
631
649
}
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;
633
654
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 );
635
656
636
657
extra_space_left = 0.0 ;
637
658
extra_space_right = 0.0 ;
638
659
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 ;
641
662
}
642
663
643
664
float longest_line_width = std::max ( std::max ( title_size.x , text_size.x ),
644
665
std::max ( calculated_menu_size.x , desc_size.x ) );
645
666
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 );
647
668
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
+ }
648
675
}
649
676
650
677
void uilist::setup ()
0 commit comments