diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/graph_edit.cpp | 113 | ||||
-rw-r--r-- | scene/gui/graph_edit.h | 38 | ||||
-rw-r--r-- | scene/gui/graph_node.cpp | 24 | ||||
-rw-r--r-- | scene/gui/graph_node.h | 4 |
4 files changed, 164 insertions, 15 deletions
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 06b1c42690..d24c59a21f 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -178,6 +178,7 @@ void GraphEdit::_graph_node_raised(Node* p_gn) { ERR_FAIL_COND(!gn); gn->raise(); top_layer->raise(); + emit_signal("node_selected",p_gn); } @@ -295,6 +296,36 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); if (pos.distance_to(mpos)<grab_r) { + + if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { + //check disconnect + for (List<Connection>::Element*E=connections.front();E;E=E->next()) { + + if (E->get().from==gn->get_name() && E->get().from_port==j) { + + Node*to = get_node(String(E->get().to)); + if (to && to->cast_to<GraphNode>()) { + + connecting_from=E->get().to; + connecting_index=E->get().to_port; + connecting_out=false; + connecting_type=to->cast_to<GraphNode>()->get_connection_input_type(E->get().to_port); + connecting_color=to->cast_to<GraphNode>()->get_connection_input_color(E->get().to_port); + connecting_target=false; + connecting_to=pos; + + emit_signal("disconnection_request",E->get().from,E->get().from_port,E->get().to,E->get().to_port); + to = get_node(String(connecting_from)); //maybe it was erased + if (to && to->cast_to<GraphNode>()) { + connecting=true; + } + return; + } + + } + } + } + connecting=true; connecting_from=gn->get_name(); connecting_index=j; @@ -315,7 +346,7 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { if (pos.distance_to(mpos)<grab_r) { - if (right_disconnects) { + if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (List<Connection>::Element*E=connections.front();E;E=E->next()) { @@ -381,7 +412,7 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); int type =gn->get_connection_output_type(j); - if (type==connecting_type && pos.distance_to(mpos)<grab_r) { + if ((type==connecting_type ||valid_connection_types.has(ConnType(type,connecting_type))) && pos.distance_to(mpos)<grab_r) { connecting_target=true; connecting_to=pos; @@ -398,7 +429,7 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); int type =gn->get_connection_input_type(j); - if (type==connecting_type && pos.distance_to(mpos)<grab_r) { + if ((type==connecting_type ||valid_connection_types.has(ConnType(type,connecting_type))) && pos.distance_to(mpos)<grab_r) { connecting_target=true; connecting_to=pos; connecting_target_to=gn->get_name(); @@ -433,7 +464,7 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { } -void GraphEdit::_draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color) { +void GraphEdit::_draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color,const Color& p_to_color) { static const int steps = 20; @@ -454,7 +485,7 @@ void GraphEdit::_draw_cos_line(const Vector2& p_from, const Vector2& p_to,const if (i>0) { - top_layer->draw_line(prev,p,p_color,2); + top_layer->draw_line(prev,p,p_color.linear_interpolate(p_to_color,d),2); } prev=p; @@ -488,7 +519,7 @@ void GraphEdit::_top_layer_draw() { col.g+=0.4; col.b+=0.4; } - _draw_cos_line(pos,topos,col); + _draw_cos_line(pos,topos,col,col); } List<List<Connection>::Element* > to_erase; @@ -526,7 +557,8 @@ void GraphEdit::_top_layer_draw() { Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos(); Color color = gfrom->get_connection_output_color(E->get().from_port); Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos(); - _draw_cos_line(frompos,topos,color); + Color tocolor = gto->get_connection_input_color(E->get().to_port); + _draw_cos_line(frompos,topos,color,tocolor); } @@ -538,6 +570,18 @@ void GraphEdit::_top_layer_draw() { top_layer->draw_rect(box_selecting_rect,Color(0.7,0.7,1.0,0.3)); } +void GraphEdit::set_selected(Node* p_child) { + + for(int i=get_child_count()-1;i>=0;i--) { + + GraphNode *gn=get_child(i)->cast_to<GraphNode>(); + if (!gn) + continue; + + gn->set_selected(gn==p_child); + } +} + void GraphEdit::_input_event(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)))) { @@ -804,6 +848,29 @@ bool GraphEdit::is_right_disconnects_enabled() const{ return right_disconnects; } +void GraphEdit::add_valid_right_disconnect_type(int p_type) { + + valid_right_disconnect_types.insert(p_type); +} + +void GraphEdit::remove_valid_right_disconnect_type(int p_type){ + + valid_right_disconnect_types.erase(p_type); + +} + +void GraphEdit::add_valid_left_disconnect_type(int p_type){ + + valid_left_disconnect_types.insert(p_type); + +} + +void GraphEdit::remove_valid_left_disconnect_type(int p_type){ + + valid_left_disconnect_types.erase(p_type); + +} + Array GraphEdit::_get_connection_list() const { List<Connection> conns; @@ -838,6 +905,35 @@ void GraphEdit::_zoom_plus() { set_zoom(zoom*ZOOM_SCALE); } +void GraphEdit::add_valid_connection_type(int p_type,int p_with_type) { + + ConnType ct; + ct.type_a=p_type; + ct.type_b=p_with_type; + + valid_connection_types.insert(ct); +} + +void GraphEdit::remove_valid_connection_type(int p_type,int p_with_type) { + + ConnType ct; + ct.type_a=p_type; + ct.type_b=p_with_type; + + valid_connection_types.erase(ct); + +} + +bool GraphEdit::is_valid_connection_type(int p_type,int p_with_type) const { + + ConnType ct; + ct.type_a=p_type; + ct.type_b=p_with_type; + + return valid_connection_types.has(ct); + +} + void GraphEdit::_bind_methods() { @@ -865,10 +961,13 @@ void GraphEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event); + ObjectTypeDB::bind_method(_MD("set_selected","node"),&GraphEdit::set_selected); + 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("node_selected",PropertyInfo(Variant::OBJECT,"node"))); ADD_SIGNAL(MethodInfo("delete_nodes_request")); ADD_SIGNAL(MethodInfo("_begin_node_move")); ADD_SIGNAL(MethodInfo("_end_node_move")); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index ac4e71ba49..100b6e94ab 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -106,7 +106,7 @@ private: bool updating; List<Connection> connections; - void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); + void _draw_cos_line(const Vector2& p_from, const Vector2& p_to, const Color& p_color, const Color &p_to_color); void _graph_node_raised(Node* p_gn); void _graph_node_moved(Node *p_gn); @@ -122,6 +122,30 @@ private: Array _get_connection_list() const; + struct ConnType { + + union { + struct { + uint32_t type_a; + uint32_t type_b; + }; + uint64_t key; + }; + + bool operator<(const ConnType& p_type) const { + return key<p_type.key; + } + + ConnType(uint32_t a=0, uint32_t b=0) { + type_a=a; + type_b=b; + } + }; + + Set<ConnType> valid_connection_types; + Set<int> valid_left_disconnect_types; + Set<int> valid_right_disconnect_types; + friend class GraphEditFilter; bool _filter_input(const Point2& p_point); protected: @@ -138,6 +162,10 @@ public: void disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); void clear_connections(); + void add_valid_connection_type(int p_type,int p_with_type); + void remove_valid_connection_type(int p_type,int p_with_type); + bool is_valid_connection_type(int p_type,int p_with_type) const; + void set_zoom(float p_zoom); float get_zoom() const; @@ -147,8 +175,16 @@ public: void set_right_disconnects(bool p_enable); bool is_right_disconnects_enabled() const; + void add_valid_right_disconnect_type(int p_type); + void remove_valid_right_disconnect_type(int p_type); + + void add_valid_left_disconnect_type(int p_type); + void remove_valid_left_disconnect_type(int p_type); + Vector2 get_scroll_ofs() const; + void set_selected(Node* p_child); + GraphEdit(); }; diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 94001b2ac1..5914ea222d 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -223,10 +223,20 @@ void GraphNode::_notification(int p_what) { continue; const Slot &s=slot_info[E->key()]; //left - if (s.enable_left) - port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); - if (s.enable_right) - port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); + if (s.enable_left) { + Ref<Texture> p = port; + if (s.custom_slot_left.is_valid()) { + p=s.custom_slot_left; + } + p->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); + } + if (s.enable_right) { + Ref<Texture> p = port; + if (s.custom_slot_right.is_valid()) { + p=s.custom_slot_right; + } + p->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); + } } } @@ -239,7 +249,7 @@ void GraphNode::_notification(int p_what) { } -void GraphNode::set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right) { +void GraphNode::set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right,const Ref<Texture>& p_custom_left,const Ref<Texture>& p_custom_right) { ERR_FAIL_COND(p_idx<0); @@ -255,6 +265,8 @@ void GraphNode::set_slot(int p_idx,bool p_enable_left,int p_type_left,const Colo s.enable_right=p_enable_right; s.type_right=p_type_right; s.color_right=p_color_right; + s.custom_slot_left=p_custom_left; + s.custom_slot_right=p_custom_right; slot_info[p_idx]=s; update(); connpos_dirty=true; @@ -580,7 +592,7 @@ void GraphNode::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_title"),&GraphNode::get_title); ObjectTypeDB::bind_method(_MD("_input_event"),&GraphNode::_input_event); - ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right"),&GraphNode::set_slot); + ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right","custom_left","custom_right"),&GraphNode::set_slot,DEFVAL(Ref<Texture>()),DEFVAL(Ref<Texture>())); ObjectTypeDB::bind_method(_MD("clear_slot","idx"),&GraphNode::clear_slot); ObjectTypeDB::bind_method(_MD("clear_all_slots","idx"),&GraphNode::clear_all_slots); ObjectTypeDB::bind_method(_MD("is_slot_enabled_left","idx"),&GraphNode::is_slot_enabled_left); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 5a50d0d68d..f308f30b81 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -44,6 +44,8 @@ class GraphNode : public Container { bool enable_right; int type_right; Color color_right; + Ref<Texture> custom_slot_left; + Ref<Texture> custom_slot_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); } @@ -91,7 +93,7 @@ public: - void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right); + void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right,const Ref<Texture>& p_custom_left=Ref<Texture>(),const Ref<Texture>& p_custom_right=Ref<Texture>()); void clear_slot(int p_idx); void clear_all_slots(); bool is_slot_enabled_left(int p_idx) const; |