You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-19 14:31:59 +00:00
Duplicate GraphNode(s) [Control+D]
This commit is contained in:
@@ -534,7 +534,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
|
|||||||
top_layer->update();
|
top_layer->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_ev.type== InputEvent::MOUSE_BUTTON) {
|
if (p_ev.type==InputEvent::MOUSE_BUTTON) {
|
||||||
|
|
||||||
const InputEventMouseButton &b=p_ev.mouse_button;
|
const InputEventMouseButton &b=p_ev.mouse_button;
|
||||||
|
|
||||||
@@ -667,6 +667,11 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
|
|||||||
top_layer->update();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphEdit::clear_connections() {
|
void GraphEdit::clear_connections() {
|
||||||
@@ -723,6 +728,7 @@ 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("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("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("popup_request", PropertyInfo(Variant::VECTOR2,"p_position")));
|
||||||
|
ADD_SIGNAL(MethodInfo("duplicate_nodes_request"));
|
||||||
ADD_SIGNAL(MethodInfo("_begin_node_move"));
|
ADD_SIGNAL(MethodInfo("_begin_node_move"));
|
||||||
ADD_SIGNAL(MethodInfo("_end_node_move"));
|
ADD_SIGNAL(MethodInfo("_end_node_move"));
|
||||||
}
|
}
|
||||||
@@ -730,6 +736,8 @@ void GraphEdit::_bind_methods() {
|
|||||||
|
|
||||||
|
|
||||||
GraphEdit::GraphEdit() {
|
GraphEdit::GraphEdit() {
|
||||||
|
set_focus_mode(FOCUS_ALL);
|
||||||
|
|
||||||
top_layer=NULL;
|
top_layer=NULL;
|
||||||
top_layer=memnew(GraphEditFilter(this));
|
top_layer=memnew(GraphEditFilter(this));
|
||||||
add_child(top_layer);
|
add_child(top_layer);
|
||||||
|
|||||||
@@ -525,7 +525,9 @@ Color GraphNode::get_connection_output_color(int p_idx) {
|
|||||||
|
|
||||||
void GraphNode::_input_event(const InputEvent& p_ev) {
|
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);
|
Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y);
|
||||||
if (close_rect.size!=Size2() && close_rect.has_point(mpos)) {
|
if (close_rect.size!=Size2() && close_rect.has_point(mpos)) {
|
||||||
@@ -533,7 +535,7 @@ void GraphNode::_input_event(const InputEvent& p_ev) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit_signal("raise_request");
|
emit_signal("raise_request");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -824,6 +824,47 @@ float ShaderGraph::texture_node_get_filter_strength(ShaderType p_type,float p_id
|
|||||||
return arr[1];
|
return arr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderGraph::duplicate_nodes(ShaderType p_which, List<int> &p_nodes)
|
||||||
|
{
|
||||||
|
//Create new node IDs
|
||||||
|
Map<int,int> duplicates = Map<int,int>();
|
||||||
|
int i=1;
|
||||||
|
for(List<int>::Element *E=p_nodes.front();E; E=E->next()) {
|
||||||
|
while (shader[p_which].node_map.has(i))
|
||||||
|
i++;
|
||||||
|
duplicates.insert(E->get(), i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(List<int>::Element *E = p_nodes.front();E; E=E->next()) {
|
||||||
|
|
||||||
|
const Node &n=shader[p_which].node_map[E->get()];
|
||||||
|
Node nn=n;
|
||||||
|
nn.id=duplicates.find(n.id)->get();
|
||||||
|
nn.pos += Vector2(0,100);
|
||||||
|
for (Map<int,SourceSlot>::Element *C=nn.connections.front();C;C=C->next()) {
|
||||||
|
SourceSlot &c=C->get();
|
||||||
|
if (p_nodes.find(c.id))
|
||||||
|
c.id=duplicates.find(c.id)->get();
|
||||||
|
}
|
||||||
|
shader[p_which].node_map[nn.id]=nn;
|
||||||
|
}
|
||||||
|
_request_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> ShaderGraph::generate_ids(ShaderType p_type, int count)
|
||||||
|
{
|
||||||
|
List<int> ids = List<int>();
|
||||||
|
int i=1;
|
||||||
|
while (ids.size() < count) {
|
||||||
|
while (shader[p_type].node_map.has(i))
|
||||||
|
i++;
|
||||||
|
ids.push_back(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ShaderGraph::scalar_op_node_set_op(ShaderType p_type,float p_id,ScalarOp p_op){
|
void ShaderGraph::scalar_op_node_set_op(ShaderType p_type,float p_id,ScalarOp p_op){
|
||||||
|
|
||||||
|
|||||||
@@ -216,6 +216,10 @@ public:
|
|||||||
void texture_node_set_filter_strength(ShaderType p_which,float p_id,float p_strength);
|
void texture_node_set_filter_strength(ShaderType p_which,float p_id,float p_strength);
|
||||||
float texture_node_get_filter_strength(ShaderType p_which,float p_id) const;
|
float texture_node_get_filter_strength(ShaderType p_which,float p_id) const;
|
||||||
|
|
||||||
|
void duplicate_nodes(ShaderType p_which, List<int> &p_nodes);
|
||||||
|
|
||||||
|
List<int> generate_ids(ShaderType p_type, int count);
|
||||||
|
|
||||||
enum ScalarOp {
|
enum ScalarOp {
|
||||||
SCALAR_OP_ADD,
|
SCALAR_OP_ADD,
|
||||||
SCALAR_OP_SUB,
|
SCALAR_OP_SUB,
|
||||||
|
|||||||
@@ -1184,6 +1184,43 @@ void ShaderGraphView::_move_node(int p_id,const Vector2& p_to) {
|
|||||||
graph->node_set_pos(type,p_id,p_to);
|
graph->node_set_pos(type,p_id,p_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderGraphView::_duplicate_nodes_request()
|
||||||
|
{
|
||||||
|
Array s_id;
|
||||||
|
|
||||||
|
for(Map<int,GraphNode*>::Element *E=node_map.front();E;E=E->next()) {
|
||||||
|
ShaderGraph::NodeType t=graph->node_get_type(type, E->key());
|
||||||
|
if (t==ShaderGraph::NODE_OUTPUT || t==ShaderGraph::NODE_INPUT)
|
||||||
|
continue;
|
||||||
|
GraphNode *gn = E->get();
|
||||||
|
if (gn && gn->is_selected())
|
||||||
|
s_id.push_back(E->key());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_id.size()==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
|
||||||
|
ur->create_action("Duplicate Graph Node(s)");
|
||||||
|
ur->add_do_method(this,"_duplicate_nodes",s_id);
|
||||||
|
List<int> n_ids = graph->generate_ids(type, s_id.size());
|
||||||
|
for (List<int>::Element *E=n_ids.front();E;E=E->next())
|
||||||
|
ur->add_undo_method(graph.ptr(),"node_remove",type,E->get());
|
||||||
|
ur->add_do_method(this,"_update_graph");
|
||||||
|
ur->add_undo_method(this,"_update_graph");
|
||||||
|
ur->commit_action();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderGraphView::_duplicate_nodes(Array &p_nodes)
|
||||||
|
{
|
||||||
|
List<int> n = List<int>();
|
||||||
|
for (int i=0; i<p_nodes.size();i++)
|
||||||
|
n.push_back(p_nodes.get(i));
|
||||||
|
graph->duplicate_nodes(type, n);
|
||||||
|
call_deferred("_update_graph");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ShaderGraphView::_create_node(int p_id) {
|
void ShaderGraphView::_create_node(int p_id) {
|
||||||
|
|
||||||
@@ -2087,8 +2124,6 @@ void ShaderGraphView::_update_graph() {
|
|||||||
graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot);
|
graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderGraphView::_sg_updated() {
|
void ShaderGraphView::_sg_updated() {
|
||||||
@@ -2175,6 +2210,8 @@ void ShaderGraphView::_bind_methods() {
|
|||||||
ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed);
|
ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed);
|
||||||
ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request);
|
ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request);
|
||||||
ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request);
|
ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request);
|
||||||
|
ObjectTypeDB::bind_method("_duplicate_nodes_request", &ShaderGraphView::_duplicate_nodes_request);
|
||||||
|
ObjectTypeDB::bind_method("_duplicate_nodes", &ShaderGraphView::_duplicate_nodes);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed);
|
ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed);
|
||||||
ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed);
|
ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed);
|
||||||
@@ -2250,7 +2287,6 @@ void ShaderGraphEditor::_popup_requested(const Vector2 &p_position)
|
|||||||
popup->set_invalidate_click_until_motion();
|
popup->set_invalidate_click_until_motion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ShaderGraphEditor::_notification(int p_what) {
|
void ShaderGraphEditor::_notification(int p_what) {
|
||||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||||
|
|
||||||
@@ -2349,6 +2385,7 @@ ShaderGraphEditor::ShaderGraphEditor(bool p_2d) {
|
|||||||
tabs->add_child(graph_edits[i]->get_graph_edit());
|
tabs->add_child(graph_edits[i]->get_graph_edit());
|
||||||
graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request");
|
graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request");
|
||||||
graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request");
|
graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request");
|
||||||
|
graph_edits[i]->get_graph_edit()->connect("duplicate_nodes_request", graph_edits[i], "_duplicate_nodes_request");
|
||||||
graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested");
|
graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested");
|
||||||
graph_edits[i]->get_graph_edit()->set_right_disconnects(true);
|
graph_edits[i]->get_graph_edit()->set_right_disconnects(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ class ShaderGraphView : public Node {
|
|||||||
void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id);
|
void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id);
|
||||||
void _end_node_move();
|
void _end_node_move();
|
||||||
void _move_node(int p_id,const Vector2& p_to);
|
void _move_node(int p_id,const Vector2& p_to);
|
||||||
|
void _duplicate_nodes_request();
|
||||||
|
void _duplicate_nodes(Array &p_nodes);
|
||||||
|
|
||||||
void _scalar_const_changed(double p_value,int p_id);
|
void _scalar_const_changed(double p_value,int p_id);
|
||||||
void _vec_const_changed(double p_value, int p_id, Array p_arr);
|
void _vec_const_changed(double p_value, int p_id, Array p_arr);
|
||||||
|
|||||||
Reference in New Issue
Block a user