bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) { if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos)) return false; for (int i = 0; i < get_child_count(); i++) { Control *child = Object::cast_to<Control>(get_child(i)); if (!child) continue; Rect2 rect = child->get_rect(); if (rect.has_point(p_mouse_pos)) { //check sub-controls Vector2 subpos = p_mouse_pos - rect.position; for (int j = 0; j < child->get_child_count(); j++) { Control *subchild = Object::cast_to<Control>(child->get_child(j)); if (!subchild) continue; if (_check_clickable_control(subchild, subpos - subchild->get_position())) { return false; } } } } return true; }
int ItemList::get_item_at_pos(const Point2& p_pos) const { Vector2 pos=p_pos; 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; } } return closest; }
void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect) { if (r_to == r_from) return; //this could be optimized... Vector2 n = (r_to - r_from).normalized(); while (p_rect.has_point(r_to)) { r_to -= n; } }
int Tabs::get_tab_idx_at_point(const Point2 &p_point) const { int hover_now = -1; for (int i = 0; i < tabs.size(); i++) { if (i < offset) continue; Rect2 rect = get_tab_rect(i); if (rect.has_point(p_point)) { hover_now = i; } } return hover_now; }
DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start) { if (node->get_cell(p_start.x, p_start.y) != TileMap::INVALID_CELL) return DVector<Vector2>(); int id = get_selected_tile(); if (id == TileMap::INVALID_CELL) return DVector<Vector2>(); Rect2 r = node->get_item_rect(); r.pos = r.pos/node->get_cell_size(); r.size = r.size/node->get_cell_size(); DVector<Vector2> points; List<Point2i> queue; queue.push_back(p_start); while (queue.size()) { Point2i n = queue.front()->get(); queue.pop_front(); if (!r.has_point(n)) continue; if (node->get_cell(n.x, n.y) == TileMap::INVALID_CELL) { node->set_cellv(n, id, flip_h, flip_v, transpose); points.push_back(n); queue.push_back(n + Point2i(0, 1)); queue.push_back(n + Point2i(0, -1)); queue.push_back(n + Point2i(1, 0)); queue.push_back(n + Point2i(-1, 0)); } } return points; }
// slow as hell Control* ControlEditor::_select_control_at_pos(const Point2& p_pos,Node* p_node) { for (int i=p_node->get_child_count()-1;i>=0;i--) { Control *r=_select_control_at_pos(p_pos,p_node->get_child(i)); if (r) return r; } Control *c=p_node->cast_to<Control>(); if (c) { Rect2 rect = c->get_window_rect(); if (c->get_window()==current_window) { rect.pos=transform.xform(rect.pos).floor(); } if (rect.has_point(p_pos)) return c; } return NULL; }
void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } if (mm.is_valid() && dragging) { just_selected = true; // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats //drag_accum+=Vector2(mm->get_relative().x,mm->get_relative().y); drag_accum = get_local_mouse_position() - drag_origin; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn && gn->is_selected()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; if (is_using_snap()) { int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } gn->set_offset(pos); } } } if (mm.is_valid() && box_selecting) { box_selecting_to = get_local_mouse_position(); box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), MIN(box_selecting_from.y, box_selecting_to.y), ABS(box_selecting_from.x - box_selecting_to.x), ABS(box_selecting_from.y - box_selecting_to.y)); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; Rect2 r = gn->get_rect(); r.size *= zoom; bool in_box = r.intersects(box_selecting_rect); if (in_box) gn->set_selected(box_selection_mode_aditive); else gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } Ref<InputEventMouseButton> b = p_ev; if (b.is_valid()) { if (b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { if (box_selecting) { box_selecting = false; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } else { if (connecting) { connecting = false; top_layer->update(); } else { emit_signal("popup_request", b->get_global_position()); } } } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) { if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_position())) gn->set_selected(false); } } } if (drag_accum != Vector2()) { emit_signal("_begin_node_move"); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn && gn->is_selected()) gn->set_drag(false); } emit_signal("_end_node_move"); } dragging = false; top_layer->update(); update(); connections_layer->update(); } if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { GraphNode *gn = NULL; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn_selected = Object::cast_to<GraphNode>(get_child(i)); if (gn_selected) { if (gn_selected->is_resizing()) continue; if (gn_selected->has_point(gn_selected->get_local_mouse_position())) { gn = gn_selected; break; } } } if (gn) { if (_filter_input(b->get_position())) return; dragging = true; drag_accum = Vector2(); drag_origin = get_local_mouse_position(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (o_gn) o_gn->set_selected(o_gn == gn); } } gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (!o_gn) continue; if (o_gn->is_selected()) o_gn->set_drag(true); } } else { if (_filter_input(b->get_position())) return; if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_position(); if (b->get_control()) { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2 || !gn2->is_selected()) continue; previus_selected.push_back(gn2); } } else if (b->get_shift()) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2 || !gn2->is_selected()) continue; previus_selected.push_back(gn2); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2) continue; gn2->set_selected(false); } } } } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && box_selecting) { box_selecting = false; previus_selected.clear(); top_layer->update(); } if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) { //too difficult to get right //set_zoom(zoom*ZOOM_SCALE); } if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8); } } Ref<InputEventKey> k = p_ev; if (k.is_valid() && k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) { emit_signal("duplicate_nodes_request"); accept_event(); } if (k.is_valid() && k->get_scancode() == KEY_DELETE && k->is_pressed()) { emit_signal("delete_nodes_request"); accept_event(); } Ref<InputEventMagnifyGesture> magnify_gesture = p_ev; if (magnify_gesture.is_valid()) { set_zoom_custom(zoom * magnify_gesture->get_factor(), magnify_gesture->get_position()); } Ref<InputEventPanGesture> pan_gesture = p_ev; if (pan_gesture.is_valid()) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8); v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); } }
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 Tabs::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { Point2 pos = mm->get_position(); highlight_arrow = -1; if (buttons_visible) { Ref<Texture> incr = get_icon("increment"); Ref<Texture> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); if (pos.x > limit + decr->get_width()) { highlight_arrow = 1; } else if (pos.x > limit) { highlight_arrow = 0; } } // test hovering to display right or close button int hover_now = -1; int hover_buttons = -1; for (int i = 0; i < tabs.size(); i++) { if (i < offset) continue; Rect2 rect = get_tab_rect(i); if (rect.has_point(pos)) { hover_now = i; } if (tabs[i].rb_rect.has_point(pos)) { rb_hover = i; cb_hover = -1; hover_buttons = i; break; } else if (!tabs[i].disabled && tabs[i].cb_rect.has_point(pos)) { cb_hover = i; rb_hover = -1; hover_buttons = i; break; } } if (hover != hover_now) { hover = hover_now; emit_signal("tab_hover", hover); } if (hover_buttons == -1) { // no hover rb_hover = hover_buttons; cb_hover = hover_buttons; } update(); return; } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) { if (scrolling_enabled && buttons_visible) { if (offset > 0) { offset--; update(); } } } if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) { if (scrolling_enabled && buttons_visible) { if (missing_right) { offset++; update(); } } } if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (rb_hover != -1) { //pressed emit_signal("right_button_pressed", rb_hover); } rb_pressing = false; update(); } if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (cb_hover != -1) { //pressed emit_signal("tab_close", cb_hover); } cb_pressing = false; update(); } if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { // clicks Point2 pos(mb->get_position().x, mb->get_position().y); if (buttons_visible) { Ref<Texture> incr = get_icon("increment"); Ref<Texture> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); if (pos.x > limit + decr->get_width()) { if (missing_right) { offset++; update(); } return; } else if (pos.x > limit) { if (offset > 0) { offset--; update(); } return; } } int found = -1; for (int i = 0; i < tabs.size(); i++) { if (i < offset) continue; if (tabs[i].rb_rect.has_point(pos)) { rb_pressing = true; update(); return; } if (tabs[i].cb_rect.has_point(pos)) { cb_pressing = true; update(); return; } if (pos.x >= tabs[i].ofs_cache && pos.x < tabs[i].ofs_cache + tabs[i].size_cache) { if (!tabs[i].disabled) { found = i; } break; } } if (found != -1) { set_current_tab(found); emit_signal("tab_clicked", found); } } } }
void TextureRegionEditor::_edit_region() { Ref<Texture> texture = NULL; if (node_sprite) texture = node_sprite->get_texture(); else if (node_patch9) texture = node_patch9->get_texture(); else if (obj_styleBox.is_valid()) texture = obj_styleBox->get_texture(); else if (atlas_tex.is_valid()) texture = atlas_tex->get_atlas(); if (texture.is_null()) { return; } autoslice_cache.clear(); Ref<Image> i; i.instance(); if (i->load(texture->get_path()) == OK) { BitMap bm; bm.create_from_image_alpha(i); for (int y = 0; y < i->get_height(); y++) { for (int x = 0; x < i->get_width(); x++) { if (bm.get_bit(Point2(x, y))) { bool found = false; for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) { Rect2 grown = E->get().grow(1.5); if (grown.has_point(Point2(x, y))) { E->get().expand_to(Point2(x, y)); E->get().expand_to(Point2(x + 1, y + 1)); x = E->get().position.x + E->get().size.x - 1; bool merged = true; while (merged) { merged = false; bool queue_erase = false; for (List<Rect2>::Element *F = autoslice_cache.front(); F; F = F->next()) { if (queue_erase) { autoslice_cache.erase(F->prev()); queue_erase = false; } if (F == E) continue; if (E->get().grow(1).intersects(F->get())) { E->get().expand_to(F->get().position); E->get().expand_to(F->get().position + F->get().size); if (F->prev()) { F = F->prev(); autoslice_cache.erase(F->next()); } else { queue_erase = true; //Can't delete the first rect in the list. } merged = true; } } } found = true; break; } } if (!found) { Rect2 new_rect(x, y, 1, 1); autoslice_cache.push_back(new_rect); } } } } } if (node_sprite) rect = node_sprite->get_region_rect(); else if (node_patch9) rect = node_patch9->get_region_rect(); else if (obj_styleBox.is_valid()) rect = obj_styleBox->get_region_rect(); else if (atlas_tex.is_valid()) rect = atlas_tex->get_region(); edit_draw->update(); }
void GraphEdit::_gui_input(const InputEvent &p_ev) { if (p_ev.type == InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask & BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - p_ev.mouse_motion.relative_x); v_scroll->set_value(v_scroll->get_value() - p_ev.mouse_motion.relative_y); } if (p_ev.type == InputEvent::MOUSE_MOTION && dragging) { just_selected = true; // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats //drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); drag_accum = get_local_mouse_pos() - drag_origin; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn && gn->is_selected()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; if (is_using_snap()) { int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } gn->set_offset(pos); } } } if (p_ev.type == InputEvent::MOUSE_MOTION && box_selecting) { box_selecting_to = get_local_mouse_pos(); box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), MIN(box_selecting_from.y, box_selecting_to.y), ABS(box_selecting_from.x - box_selecting_to.x), ABS(box_selecting_from.y - box_selecting_to.y)); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; Rect2 r = gn->get_rect(); r.size *= zoom; bool in_box = r.intersects(box_selecting_rect); if (in_box) gn->set_selected(box_selection_mode_aditive); else gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } if (p_ev.type == InputEvent::MOUSE_BUTTON) { const InputEventMouseButton &b = p_ev.mouse_button; if (b.button_index == BUTTON_RIGHT && b.pressed) { if (box_selecting) { box_selecting = false; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } else { if (connecting) { connecting = false; top_layer->update(); } else { emit_signal("popup_request", Vector2(b.global_x, b.global_y)); } } } if (b.button_index == BUTTON_LEFT && !b.pressed && dragging) { if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_pos())) gn->set_selected(false); } } } if (drag_accum != Vector2()) { emit_signal("_begin_node_move"); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn && gn->is_selected()) gn->set_drag(false); } emit_signal("_end_node_move"); } dragging = false; top_layer->update(); update(); connections_layer->update(); } if (b.button_index == BUTTON_LEFT && b.pressed) { GraphNode *gn = NULL; GraphNode *gn_selected = NULL; for (int i = get_child_count() - 1; i >= 0; i--) { gn_selected = get_child(i)->cast_to<GraphNode>(); if (gn_selected) { if (gn_selected->is_resizing()) continue; Rect2 r = gn_selected->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_pos())) gn = gn_selected; break; } } if (gn) { if (_filter_input(Vector2(b.x, b.y))) return; dragging = true; drag_accum = Vector2(); drag_origin = get_local_mouse_pos(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = get_child(i)->cast_to<GraphNode>(); if (o_gn) o_gn->set_selected(o_gn == gn); } } gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = get_child(i)->cast_to<GraphNode>(); if (!o_gn) continue; if (o_gn->is_selected()) o_gn->set_drag(true); } } else { if (_filter_input(Vector2(b.x, b.y))) return; if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_pos(); if (b.mod.control) { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn || !gn->is_selected()) continue; previus_selected.push_back(gn); } } else if (b.mod.shift) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn || !gn->is_selected()) continue; previus_selected.push_back(gn); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; gn->set_selected(false); } } } } if (b.button_index == BUTTON_LEFT && !b.pressed && box_selecting) { box_selecting = false; previus_selected.clear(); top_layer->update(); } if (b.button_index == BUTTON_WHEEL_UP && b.pressed) { //too difficult to get right //set_zoom(zoom*ZOOM_SCALE); } if (b.button_index == BUTTON_WHEEL_DOWN && b.pressed) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } } if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_D && p_ev.key.pressed && p_ev.key.mod.command) { emit_signal("duplicate_nodes_request"); accept_event(); } if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_DELETE && p_ev.key.pressed) { emit_signal("delete_nodes_request"); accept_event(); } }
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; } } } } } }