diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/graph_edit.cpp | 199 | ||||
-rw-r--r-- | scene/gui/graph_edit.h | 13 | ||||
-rw-r--r-- | scene/gui/graph_node.cpp | 62 | ||||
-rw-r--r-- | scene/gui/graph_node.h | 11 |
4 files changed, 246 insertions, 39 deletions
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 3cd0dd3d16..deb3151798 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -141,9 +141,6 @@ void GraphEdit::_graph_node_moved(Node *p_gn) { GraphNode *gn=p_gn->cast_to<GraphNode>(); ERR_FAIL_COND(!gn); - - //gn->set_pos(gn->get_offset()+scroll_offset); - top_layer->update(); } @@ -172,7 +169,6 @@ void GraphEdit::remove_child_notify(Node *p_child) { void GraphEdit::_notification(int p_what) { if (p_what==NOTIFICATION_READY) { - Size2 size = top_layer->get_size(); Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); @@ -491,7 +487,8 @@ void GraphEdit::_top_layer_draw() { connections.erase(to_erase.front()->get()); to_erase.pop_front(); } - //draw connections + if (box_selecting) + top_layer->draw_rect(box_selecting_rect,Color(0.7,0.7,1.0,0.3)); } void GraphEdit::_input_event(const InputEvent& p_ev) { @@ -500,6 +497,187 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); } + + if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { + + just_selected=true; + drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); + 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_offset(gn->get_drag_from()+drag_accum); + } + } + + 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; + + bool in_box = gn->get_rect().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 { + 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 && gn->get_rect().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(); + } + + if (b.button_index==BUTTON_LEFT && b.pressed) { + + GraphNode *gn; + for(int i=get_child_count()-1;i>=0;i--) { + + gn=get_child(i)->cast_to<GraphNode>(); + + if (gn && gn->get_rect().has_point(get_local_mouse_pos())) + break; + } + + if (gn) { + + if (_filter_input(Vector2(b.x,b.y))) + return; + + dragging = true; + drag_accum = Vector2(); + 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 { + 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 (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 GraphEdit::clear_connections() { @@ -555,12 +733,18 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); - + ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); + ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); + ADD_SIGNAL(MethodInfo("delete_nodes_request")); + ADD_SIGNAL(MethodInfo("_begin_node_move")); + ADD_SIGNAL(MethodInfo("_end_node_move")); } GraphEdit::GraphEdit() { + set_focus_mode(FOCUS_ALL); + top_layer=NULL; top_layer=memnew(GraphEditFilter(this)); add_child(top_layer); @@ -581,6 +765,9 @@ GraphEdit::GraphEdit() { connecting=false; right_disconnects=false; + box_selecting = false; + dragging = false; + h_scroll->connect("value_changed", this,"_scroll_moved"); v_scroll->connect("value_changed", this,"_scroll_moved"); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 0a9da73ab6..44f5a369c2 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -10,7 +10,7 @@ class GraphEditFilter : public Control { OBJ_TYPE(GraphEditFilter,Control); -friend class GraphEdit; + friend class GraphEdit; GraphEdit *ge; virtual bool has_point(const Point2& p_point) const; @@ -49,7 +49,16 @@ private: String connecting_target_to; int connecting_target_index; + bool dragging; + bool just_selected; + Vector2 drag_accum; + bool box_selecting; + bool box_selection_mode_aditive; + Point2 box_selecting_from; + Point2 box_selecting_to; + Rect2 box_selecting_rect; + List<GraphNode*> previus_selected; bool right_disconnects; bool updating; @@ -71,7 +80,7 @@ private: Array _get_connection_list() const; -friend class GraphEditFilter; + friend class GraphEditFilter; bool _filter_input(const Point2& p_point); protected: diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 444b37855f..5efc9757b7 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -40,7 +40,7 @@ bool GraphNode::_get(const StringName& p_name,Variant &r_ret) const{ - if (!p_name.operator String().begins_with("slot/")) { + if (!p_name.operator String().begins_with("slot/")) { return false; } @@ -160,7 +160,7 @@ void GraphNode::_notification(int p_what) { if (p_what==NOTIFICATION_DRAW) { - Ref<StyleBox> sb=get_stylebox("frame"); + Ref<StyleBox> sb=get_stylebox(selected ? "selectedframe" : "frame"); Ref<Texture> port =get_icon("port"); Ref<Texture> close =get_icon("close"); int close_offset = get_constant("close_offset"); @@ -360,6 +360,29 @@ Vector2 GraphNode::get_offset() const { return offset; } +void GraphNode::set_selected(bool p_selected) +{ + selected = p_selected; + update(); +} + +bool GraphNode::is_selected() +{ + return selected; +} + +void GraphNode::set_drag(bool p_drag) +{ + if (p_drag) + drag_from=get_offset(); + else + emit_signal("dragged",drag_from,get_offset()); //useful for undo/redo +} + +Vector2 GraphNode::get_drag_from() +{ + return drag_from; +} void GraphNode::set_show_close_button(bool p_enable){ @@ -379,7 +402,6 @@ void GraphNode::_connpos_update() { int sep=get_constant("separation"); Ref<StyleBox> sb=get_stylebox("frame"); - Ref<Texture> port =get_icon("port"); conn_input_cache.clear(); conn_output_cache.clear(); int vofs=0; @@ -503,31 +525,17 @@ Color GraphNode::get_connection_output_color(int p_idx) { void GraphNode::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { + if (p_ev.type==InputEvent::MOUSE_BUTTON) { + get_parent_control()->grab_focus(); + if(p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); - if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { - emit_signal("close_request"); - return; + Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); + if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { + emit_signal("close_request"); + return; + } + emit_signal("raise_request"); } - - drag_from=get_offset(); - drag_accum=Vector2(); - dragging=true; - emit_signal("raise_request"); - - } - - if (p_ev.type==InputEvent::MOUSE_BUTTON && !p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - - dragging=false; - emit_signal("dragged",drag_from,get_offset()); //useful for undo/redo - } - - if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { - - drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); - set_offset(drag_from+drag_accum); } } @@ -576,8 +584,6 @@ void GraphNode::_bind_methods() { } GraphNode::GraphNode() { - - dragging=false; show_close=false; connpos_dirty=true; } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 0d5cbf8dd3..201529380d 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -18,7 +18,7 @@ class GraphNode : public Container { Color color_right; - Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); }; + Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); } }; String title; @@ -46,8 +46,7 @@ class GraphNode : public Container { void _resort(); Vector2 drag_from; - Vector2 drag_accum; - bool dragging; + bool selected; protected: void _input_event(const InputEvent& p_ev); @@ -79,6 +78,12 @@ public: void set_offset(const Vector2& p_offset); Vector2 get_offset() const; + void set_selected(bool p_selected); + bool is_selected(); + + void set_drag(bool p_drag); + Vector2 get_drag_from(); + void set_show_close_button(bool p_enable); bool is_close_button_visible() const; |