Skip to content

Commit 081c902

Browse files
committed
use an ImGuiListClipper in the keybindings window
Just to avoid doing any real work for invisible rows. We don’t have enough rows to make this _necessary_, but we do have a fair number of rows so go ahead and do it so that it never becomes a problem.
1 parent 6a79f38 commit 081c902

File tree

1 file changed

+73
-68
lines changed

1 file changed

+73
-68
lines changed

src/input_context.cpp

Lines changed: 73 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class keybindings_ui : public cataimgui::window
6161
std::vector<std::string> filtered_registered_actions;
6262
std::string hotkeys;
6363
int highlight_row_index = -1;
64-
size_t scroll_offset = 0;
64+
int scroll_offset = 0;
6565
//std::string filter_text;
6666
keybindings_ui( bool permit_execute_action, input_context *parent );
6767
void init();
@@ -663,7 +663,7 @@ cataimgui::bounds keybindings_ui::get_bounds()
663663

664664
void keybindings_ui::draw_controls()
665665
{
666-
scroll_offset = SIZE_MAX;
666+
scroll_offset = INT_MAX;
667667
size_t legend_idx = 0;
668668
for( ; legend_idx < 4; legend_idx++ ) {
669669
cataimgui::draw_colored_text( legend[legend_idx], c_white );
@@ -700,77 +700,82 @@ void keybindings_ui::draw_controls()
700700
float keys_col_width = str_width_to_pixels( width ) - str_width_to_pixels( TERMX >= 100 ? 62 : 52 );
701701
ImGui::TableSetupColumn( "Assigned Key(s)",
702702
ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoSort, keys_col_width );
703-
for( size_t i = 0; i < filtered_registered_actions.size(); i++ ) {
704-
ImGui::TableNextRow();
705-
const std::string &action_id = filtered_registered_actions[i];
706-
ImGui::PushID( action_id.c_str() );
707-
708-
bool overwrite_default;
709-
const action_attributes &attributes = inp_mngr.get_action_attributes( action_id, ctxt->category,
710-
&overwrite_default );
711-
bool basic_overwrite_default;
712-
const action_attributes &basic_attributes = inp_mngr.get_action_attributes( action_id,
713-
ctxt->category, &basic_overwrite_default, true );
714-
bool customized_keybinding = overwrite_default != basic_overwrite_default
715-
|| attributes.input_events != basic_attributes.input_events;
716-
717-
ImGui::TableSetColumnIndex( 1 );
718-
if( customized_keybinding ) {
719-
ImGui::TextUnformatted( "*" );
720-
}
703+
float row_height = ImGui::GetTextLineHeightWithSpacing();
704+
ImGuiListClipper clipper;
705+
clipper.Begin( filtered_registered_actions.size(), row_height );
706+
while( clipper.Step() ) {
707+
for( int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++ ) {
708+
ImGui::TableNextRow();
709+
const std::string &action_id = filtered_registered_actions[i];
710+
ImGui::PushID( action_id.c_str() );
711+
712+
bool overwrite_default;
713+
const action_attributes &attributes = inp_mngr.get_action_attributes( action_id, ctxt->category,
714+
&overwrite_default );
715+
bool basic_overwrite_default;
716+
const action_attributes &basic_attributes = inp_mngr.get_action_attributes( action_id,
717+
ctxt->category, &basic_overwrite_default, true );
718+
bool customized_keybinding = overwrite_default != basic_overwrite_default
719+
|| attributes.input_events != basic_attributes.input_events;
720+
721+
ImGui::TableSetColumnIndex( 1 );
722+
if( customized_keybinding ) {
723+
ImGui::TextUnformatted( "*" );
724+
}
721725

722-
ImGui::TableSetColumnIndex( 2 );
723-
nc_color col;
724-
if( attributes.input_events.empty() ) {
725-
col = i == size_t( highlight_row_index ) ? h_unbound_key : unbound_key;
726-
} else if( overwrite_default ) {
727-
col = i == size_t( highlight_row_index ) ? h_local_key : local_key;
728-
} else {
729-
col = i == size_t( highlight_row_index ) ? h_global_key : global_key;
730-
}
731-
bool is_selected = false;
732-
bool is_hovered = false;
733-
cataimgui::draw_colored_text( ctxt->get_action_name( action_id ),
734-
col, 0.0f,
735-
status == kb_menu_status::show ? nullptr : &is_selected,
736-
nullptr, &is_hovered );
737-
738-
ImGui::TableSetColumnIndex( 3 );
739-
ImGui::Text( "%s", ctxt->get_desc( action_id ).c_str() );
740-
741-
// handle the first column last because
742-
// ImGui::IsItemVisble() tells you the status of the most
743-
// recent item, not the item you’re about to create. If we
744-
// did this column first, then when we call it for the
745-
// first row it would tell us that the headers were
746-
// hidden, which is not what we want to know.
747-
ImGui::TableSetColumnIndex( 0 );
748-
char invlet = ' ';
749-
if( ImGui::IsItemVisible() ) {
750-
if( scroll_offset == SIZE_MAX ) {
751-
scroll_offset = i;
726+
ImGui::TableSetColumnIndex( 2 );
727+
nc_color col;
728+
if( attributes.input_events.empty() ) {
729+
col = i == highlight_row_index ? h_unbound_key : unbound_key;
730+
} else if( overwrite_default ) {
731+
col = i == highlight_row_index ? h_local_key : local_key;
732+
} else {
733+
col = i == highlight_row_index ? h_global_key : global_key;
734+
}
735+
bool is_selected = false;
736+
bool is_hovered = false;
737+
cataimgui::draw_colored_text( ctxt->get_action_name( action_id ),
738+
col, 0.0f,
739+
status == kb_menu_status::show ? nullptr : &is_selected,
740+
nullptr, &is_hovered );
741+
742+
ImGui::TableSetColumnIndex( 3 );
743+
ImGui::Text( "%s", ctxt->get_desc( action_id ).c_str() );
744+
745+
// handle the first column last because
746+
// ImGui::IsItemVisble() tells you the status of the most
747+
// recent item, not the item you’re about to create. If we
748+
// did this column first, then when we call it for the
749+
// first row it would tell us that the headers were
750+
// hidden, which is not what we want to know.
751+
ImGui::TableSetColumnIndex( 0 );
752+
char invlet = ' ';
753+
if( ImGui::IsItemVisible() ) {
754+
if( scroll_offset == INT_MAX ) {
755+
scroll_offset = i;
756+
}
757+
if( i >= scroll_offset && size_t( i - scroll_offset ) < hotkeys.size() ) {
758+
invlet = hotkeys[i - scroll_offset];
759+
}
752760
}
753-
if( i >= scroll_offset && ( i - scroll_offset ) < hotkeys.size() ) {
754-
invlet = hotkeys[i - scroll_offset];
761+
if( ( status == kb_menu_status::add_global && overwrite_default )
762+
|| ( status == kb_menu_status::reset && !customized_keybinding )
763+
) {
764+
// We're trying to add a global, but this action has a local
765+
// defined, so gray out the invlet.
766+
ImGui::TextColored( c_dark_gray, "%c", invlet );
767+
} else if( status == kb_menu_status::add || status == kb_menu_status::add_global ||
768+
status == kb_menu_status::remove || status == kb_menu_status::reset ) {
769+
ImGui::TextColored( c_light_blue, "%c", invlet );
770+
} else if( status == kb_menu_status::execute ) {
771+
ImGui::TextColored( c_white, "%c", invlet );
755772
}
756-
}
757-
if( ( status == kb_menu_status::add_global && overwrite_default )
758-
|| ( status == kb_menu_status::reset && !customized_keybinding )
759-
) {
760-
// We're trying to add a global, but this action has a local
761-
// defined, so gray out the invlet.
762-
ImGui::TextColored( c_dark_gray, "%c", invlet );
763-
} else if( status == kb_menu_status::add || status == kb_menu_status::add_global ||
764-
status == kb_menu_status::remove || status == kb_menu_status::reset ) {
765-
ImGui::TextColored( c_light_blue, "%c", invlet );
766-
} else if( status == kb_menu_status::execute ) {
767-
ImGui::TextColored( c_white, "%c", invlet );
768-
}
769773

770-
if( ( is_selected || is_hovered ) && invlet != ' ' ) {
771-
highlight_row_index = i;
774+
if( ( is_selected || is_hovered ) && invlet != ' ' ) {
775+
highlight_row_index = i;
776+
}
777+
ImGui::PopID();
772778
}
773-
ImGui::PopID();
774779
}
775780
ImGui::EndTable();
776781
}

0 commit comments

Comments
 (0)