void ItemList::_input_event(const InputEvent& p_event) { if (defer_select_single>=0 && p_event.type==InputEvent::MOUSE_MOTION) { defer_select_single=-1; return; } if (defer_select_single>=0 && p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT && !p_event.mouse_button.pressed) { select(defer_select_single,true); emit_signal("multi_selected",defer_select_single,true); defer_select_single=-1; return; } if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT && p_event.mouse_button.pressed) { const InputEventMouseButton &mb = p_event.mouse_button; search_string=""; //any mousepress cancels Vector2 pos(mb.x,mb.y); Ref<StyleBox> bg = get_stylebox("bg"); pos-=bg->get_offset(); pos.y+=scroll_bar->get_val(); int closest = -1; int closest_dist=0x7FFFFFFF; for(int i=0;i<items.size();i++) { Rect2 rc = items[i].rect_cache; if (i%current_columns==current_columns-1) { rc.size.width=get_size().width; //not right but works } if (rc.has_point(pos)) { closest=i; break; } float dist = rc.distance_to(pos); if (dist<closest_dist) { closest=i; closest_dist=dist; } } if (closest!=-1) { int i = closest; if (select_mode==SELECT_MULTI && items[i].selected && mb.mod.command) { unselect(i); emit_signal("multi_selected",i,false); } else if (select_mode==SELECT_MULTI && mb.mod.shift && current>=0 && current<items.size() && current!=i) { int from = current; int to = i; if (i<current) { SWAP(from,to); } for(int j=from;j<=to;j++) { bool selected = !items[j].selected; select(j,false); if (selected) emit_signal("multi_selected",i,true); } } else { if (!mb.doubleclick && !mb.mod.command && select_mode==SELECT_MULTI && items[i].selectable && items[i].selected) { defer_select_single=i; return; } bool selected = !items[i].selected; select(i,select_mode==SELECT_SINGLE || !mb.mod.command); if (selected) { if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",i); } else emit_signal("multi_selected",i,true); } if (/*select_mode==SELECT_SINGLE &&*/ mb.doubleclick) { emit_signal("item_activated",i); } } return; } } if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_WHEEL_UP && p_event.mouse_button.pressed) { scroll_bar->set_val( scroll_bar->get_val()-scroll_bar->get_page()/8 ); } if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_WHEEL_DOWN && p_event.mouse_button.pressed) { scroll_bar->set_val( scroll_bar->get_val()+scroll_bar->get_page()/8 ); } if (p_event.is_pressed() && items.size()>0) { if (p_event.is_action("ui_up")) { if (search_string!="") { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now-search_time_msec; if (diff<int(Globals::get_singleton()->get("gui/incr_search_max_interval_msec"))*2) { for(int i=current-1;i>=0;i--) { if (items[i].text.begins_with(search_string)) { set_current(i); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } break; } } accept_event(); return; } } if (current>=current_columns) { set_current(current-current_columns); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } accept_event(); } } else if (p_event.is_action("ui_down")) { if (search_string!="") { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now-search_time_msec; if (diff<int(Globals::get_singleton()->get("gui/incr_search_max_interval_msec"))*2) { for(int i=current+1;i<items.size();i++) { if (items[i].text.begins_with(search_string)) { set_current(i); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } break; } } accept_event(); return; } } if (current<items.size()-current_columns) { set_current(current+current_columns); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } accept_event(); } } else if (p_event.is_action("ui_page_up")) { search_string=""; //any mousepress cancels for(int i=4;i>0;i--) { if (current-current_columns*i >=0 ) { set_current( current- current_columns*i); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } accept_event(); break; } } } else if (p_event.is_action("ui_page_down")) { search_string=""; //any mousepress cancels for(int i=4;i>0;i--) { if (current+current_columns*i < items.size() ) { set_current( current+ current_columns*i); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } accept_event(); break; } } } else if (p_event.is_action("ui_left")) { search_string=""; //any mousepress cancels if (current%current_columns!=0) { set_current(current-1); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } accept_event(); } } else if (p_event.is_action("ui_right")) { search_string=""; //any mousepress cancels if (current%current_columns!=(current_columns-1)) { set_current(current+1); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } accept_event(); } } else if (p_event.is_action("ui_cancel")) { search_string=""; } else if (p_event.is_action("ui_select")) { if (select_mode==SELECT_MULTI && current>=0 && current<items.size()) { if (items[current].selectable && !items[current].selected) { select(current,false); emit_signal("multi_selected",current,true); } else if (items[current].selected) { unselect(current); emit_signal("multi_selected",current,false); } } } else if (p_event.is_action("ui_accept")) { search_string=""; //any mousepress cance if (current>=0 && current<items.size()) { emit_signal("item_activated",current); } } else if (p_event.type==InputEvent::KEY) { if (p_event.key.unicode) { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now-search_time_msec; uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/incr_search_max_interval_msec",2000)); search_time_msec = now; if (diff>max_interval) { search_string=""; } search_string+=String::chr(p_event.key.unicode); for(int i=0;i<items.size();i++) { if (items[i].text.begins_with(search_string)) { set_current(i); ensure_current_is_visible(); if (select_mode==SELECT_SINGLE) { emit_signal("item_selected",current); } break; } } } } } }
void ItemList::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; if (defer_select_single >= 0 && mm.is_valid()) { defer_select_single = -1; return; } Ref<InputEventMouseButton> mb = p_event; if (defer_select_single >= 0 && mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { select(defer_select_single, true); emit_signal("multi_selected", defer_select_single, true); defer_select_single = -1; return; } if (mb.is_valid() && (mb->get_button_index() == BUTTON_LEFT || (allow_rmb_select && mb->get_button_index() == BUTTON_RIGHT)) && mb->is_pressed()) { search_string = ""; //any mousepress cancels Vector2 pos = mb->get_position(); Ref<StyleBox> bg = get_stylebox("bg"); pos -= bg->get_offset(); pos.y += scroll_bar->get_value(); int closest = -1; for (int i = 0; i < items.size(); i++) { Rect2 rc = items[i].rect_cache; if (i % current_columns == current_columns - 1) { rc.size.width = get_size().width; //not right but works } if (rc.has_point(pos)) { closest = i; break; } } if (closest != -1) { int i = closest; if (select_mode == SELECT_MULTI && items[i].selected && mb->get_command()) { unselect(i); emit_signal("multi_selected", i, false); } else if (select_mode == SELECT_MULTI && mb->get_shift() && current >= 0 && current < items.size() && current != i) { int from = current; int to = i; if (i < current) { SWAP(from, to); } for (int j = from; j <= to; j++) { bool selected = !items[j].selected; select(j, false); if (selected) emit_signal("multi_selected", i, true); } if (mb->get_button_index() == BUTTON_RIGHT) { emit_signal("item_rmb_selected", i, get_local_mouse_position()); } } else { if (!mb->is_doubleclick() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == BUTTON_LEFT) { defer_select_single = i; return; } if (items[i].selected && mb->get_button_index() == BUTTON_RIGHT) { emit_signal("item_rmb_selected", i, get_local_mouse_position()); } else { bool selected = !items[i].selected; select(i, select_mode == SELECT_SINGLE || !mb->get_command()); if (selected) { if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", i); } else emit_signal("multi_selected", i, true); } if (mb->get_button_index() == BUTTON_RIGHT) { emit_signal("item_rmb_selected", i, get_local_mouse_position()); } else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_doubleclick()) { emit_signal("item_activated", i); } } } return; } } if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) { scroll_bar->set_value(scroll_bar->get_value() - scroll_bar->get_page() * mb->get_factor() / 8); } if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) { scroll_bar->set_value(scroll_bar->get_value() + scroll_bar->get_page() * mb->get_factor() / 8); } if (p_event->is_pressed() && items.size() > 0) { if (p_event->is_action("ui_up")) { if (search_string != "") { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) { for (int i = current - 1; i >= 0; i--) { if (items[i].text.begins_with(search_string)) { set_current(i); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } break; } } accept_event(); return; } } if (current >= current_columns) { set_current(current - current_columns); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } accept_event(); } } else if (p_event->is_action("ui_down")) { if (search_string != "") { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) { for (int i = current + 1; i < items.size(); i++) { if (items[i].text.begins_with(search_string)) { set_current(i); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } break; } } accept_event(); return; } } if (current < items.size() - current_columns) { set_current(current + current_columns); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } accept_event(); } } else if (p_event->is_action("ui_page_up")) { search_string = ""; //any mousepress cancels for (int i = 4; i > 0; i--) { if (current - current_columns * i >= 0) { set_current(current - current_columns * i); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } accept_event(); break; } } } else if (p_event->is_action("ui_page_down")) { search_string = ""; //any mousepress cancels for (int i = 4; i > 0; i--) { if (current + current_columns * i < items.size()) { set_current(current + current_columns * i); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } accept_event(); break; } } } else if (p_event->is_action("ui_left")) { search_string = ""; //any mousepress cancels if (current % current_columns != 0) { set_current(current - 1); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } accept_event(); } } else if (p_event->is_action("ui_right")) { search_string = ""; //any mousepress cancels if (current % current_columns != (current_columns - 1)) { set_current(current + 1); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } accept_event(); } } else if (p_event->is_action("ui_cancel")) { search_string = ""; } else if (p_event->is_action("ui_select")) { if (select_mode == SELECT_MULTI && current >= 0 && current < items.size()) { if (items[current].selectable && !items[current].disabled && !items[current].selected) { select(current, false); emit_signal("multi_selected", current, true); } else if (items[current].selected) { unselect(current); emit_signal("multi_selected", current, false); } } } else if (p_event->is_action("ui_accept")) { search_string = ""; //any mousepress cance if (current >= 0 && current < items.size()) { emit_signal("item_activated", current); } } else { Ref<InputEventKey> k = p_event; if (k.is_valid() && k->get_unicode()) { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000)); search_time_msec = now; if (diff > max_interval) { search_string = ""; } search_string += String::chr(k->get_unicode()); for (int i = 0; i < items.size(); i++) { if (items[i].text.begins_with(search_string)) { set_current(i); ensure_current_is_visible(); if (select_mode == SELECT_SINGLE) { emit_signal("item_selected", current); } break; } } } } } }