@@ -735,6 +735,11 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
735735 }
736736
737737 Ref<InputEventMouseButton> mb = p_event;
738+ Ref<InputEventKey> ev_key = p_event;
739+
740+ if (ev_key.is_valid () && ev_key->get_keycode () == Key::SHIFT && !ev_key->is_pressed ()) {
741+ shift_anchor = -1 ;
742+ }
738743
739744 if (defer_select_single >= 0 && mb.is_valid () && mb->get_button_index () == MouseButton::LEFT && !mb->is_pressed ()) {
740745 select (defer_select_single, true );
@@ -904,7 +909,14 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
904909 return ;
905910 }
906911 }
907- if (p_event->is_action (" ui_up" , true )) {
912+ // Shift Up Selection.
913+ if (select_mode == SELECT_MULTI && p_event->is_action (" ui_up" , false ) && ev_key.is_valid () && ev_key->is_shift_pressed ()) {
914+ int next = MAX (current - max_columns, 0 );
915+ _shift_range_select (current, next);
916+ accept_event ();
917+ }
918+
919+ else if (p_event->is_action (" ui_up" , true )) {
908920 if (!search_string.is_empty ()) {
909921 uint64_t now = OS::get_singleton ()->get_ticks_msec ();
910922 uint64_t diff = now - search_time_msec;
@@ -942,7 +954,16 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
942954 }
943955 accept_event ();
944956 }
945- } else if (p_event->is_action (" ui_down" , true )) {
957+ }
958+
959+ // Shift Down Selection.
960+ else if (select_mode == SELECT_MULTI && p_event->is_action (" ui_down" , false ) && ev_key.is_valid () && ev_key->is_shift_pressed ()) {
961+ int next = MIN (current + max_columns, items.size () - 1 );
962+ _shift_range_select (current, next);
963+ accept_event ();
964+ }
965+
966+ else if (p_event->is_action (" ui_down" , true )) {
946967 if (!search_string.is_empty ()) {
947968 uint64_t now = OS::get_singleton ()->get_ticks_msec ();
948969 uint64_t diff = now - search_time_msec;
@@ -1010,7 +1031,16 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
10101031 break ;
10111032 }
10121033 }
1013- } else if (p_event->is_action (" ui_left" , true )) {
1034+ }
1035+
1036+ // Shift Left Selection.
1037+ else if (select_mode == SELECT_MULTI && p_event->is_action (" ui_left" , false ) && ev_key.is_valid () && ev_key->is_shift_pressed ()) {
1038+ int next = MAX (current - 1 , 0 );
1039+ _shift_range_select (current, next);
1040+ accept_event ();
1041+ }
1042+
1043+ else if (p_event->is_action (" ui_left" , true )) {
10141044 search_string = " " ; // any mousepress cancels
10151045
10161046 if (current % current_columns != 0 ) {
@@ -1030,7 +1060,16 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
10301060 }
10311061 accept_event ();
10321062 }
1033- } else if (p_event->is_action (" ui_right" , true )) {
1063+ }
1064+
1065+ // Shift Right Selection.
1066+ else if (select_mode == SELECT_MULTI && p_event->is_action (" ui_right" , false ) && ev_key.is_valid () && ev_key->is_shift_pressed ()) {
1067+ int next = MIN (current + 1 , items.size () - 1 );
1068+ _shift_range_select (current, next);
1069+ accept_event ();
1070+ }
1071+
1072+ else if (p_event->is_action (" ui_right" , true )) {
10341073 search_string = " " ; // any mousepress cancels
10351074
10361075 if (current % current_columns != (current_columns - 1 ) && current + 1 < items.size ()) {
@@ -1865,6 +1904,31 @@ void ItemList::_mouse_exited() {
18651904 }
18661905}
18671906
1907+ void ItemList::_shift_range_select (int p_from, int p_to) {
1908+ ERR_FAIL_INDEX (p_from, items.size ());
1909+ ERR_FAIL_INDEX (p_to, items.size ());
1910+
1911+ if (shift_anchor == -1 ) {
1912+ shift_anchor = p_from;
1913+ }
1914+
1915+ for (int i = 0 ; i < items.size (); i++) {
1916+ if (i >= MIN (shift_anchor, p_to) && i <= MAX (shift_anchor, p_to)) {
1917+ if (!is_selected (i)) {
1918+ select (i, false );
1919+ emit_signal (SNAME (" multi_selected" ), i, true );
1920+ }
1921+ } else if (is_selected (i)) {
1922+ deselect (i);
1923+ emit_signal (SNAME (" multi_selected" ), i, false );
1924+ }
1925+ }
1926+
1927+ current = p_to;
1928+ queue_redraw ();
1929+ ensure_current_is_visible ();
1930+ }
1931+
18681932String ItemList::_atr (int p_idx, const String &p_text) const {
18691933 ERR_FAIL_INDEX_V (p_idx, items.size (), atr (p_text));
18701934 switch (items[p_idx].auto_translate_mode ) {
0 commit comments