@@ -735,6 +735,11 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
735
735
}
736
736
737
737
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
+ }
738
743
739
744
if (defer_select_single >= 0 && mb.is_valid () && mb->get_button_index () == MouseButton::LEFT && !mb->is_pressed ()) {
740
745
select (defer_select_single, true );
@@ -904,7 +909,14 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
904
909
return ;
905
910
}
906
911
}
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 )) {
908
920
if (!search_string.is_empty ()) {
909
921
uint64_t now = OS::get_singleton ()->get_ticks_msec ();
910
922
uint64_t diff = now - search_time_msec;
@@ -942,7 +954,16 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
942
954
}
943
955
accept_event ();
944
956
}
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 )) {
946
967
if (!search_string.is_empty ()) {
947
968
uint64_t now = OS::get_singleton ()->get_ticks_msec ();
948
969
uint64_t diff = now - search_time_msec;
@@ -1010,7 +1031,16 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
1010
1031
break ;
1011
1032
}
1012
1033
}
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 )) {
1014
1044
search_string = " " ; // any mousepress cancels
1015
1045
1016
1046
if (current % current_columns != 0 ) {
@@ -1030,7 +1060,16 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
1030
1060
}
1031
1061
accept_event ();
1032
1062
}
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 )) {
1034
1073
search_string = " " ; // any mousepress cancels
1035
1074
1036
1075
if (current % current_columns != (current_columns - 1 ) && current + 1 < items.size ()) {
@@ -1865,6 +1904,31 @@ void ItemList::_mouse_exited() {
1865
1904
}
1866
1905
}
1867
1906
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
+
1868
1932
String ItemList::_atr (int p_idx, const String &p_text) const {
1869
1933
ERR_FAIL_INDEX_V (p_idx, items.size (), atr (p_text));
1870
1934
switch (items[p_idx].auto_translate_mode ) {
0 commit comments