diff options
Diffstat (limited to 'scene')
-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 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 342 | ||||
-rw-r--r-- | scene/resources/default_theme/default_theme.cpp | 94 | ||||
-rw-r--r-- | scene/resources/default_theme/graph_node_default.png | bin | 0 -> 289 bytes | |||
-rw-r--r-- | scene/resources/default_theme/graph_node_default_focus.png | bin | 0 -> 408 bytes | |||
-rw-r--r-- | scene/resources/default_theme/graph_node_selected.png | bin | 0 -> 738 bytes | |||
-rw-r--r-- | scene/resources/default_theme/theme_data.h | 15 | ||||
-rw-r--r-- | scene/resources/shader_graph.cpp | 287 | ||||
-rw-r--r-- | scene/resources/shader_graph.h | 15 |
12 files changed, 730 insertions, 308 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; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index e639b5cb05..5df6f2ced9 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -121,7 +121,7 @@ void TreeItem::set_cell_mode( int p_column, TreeCellMode p_mode ) { c.val=0; c.checked=false; c.icon=Ref<Texture>(); - c.text=""; + c.text=""; c.icon_max_w=0; _changed_notify(p_column); } @@ -153,9 +153,9 @@ void TreeItem::set_text(int p_column,String p_text) { ERR_FAIL_INDEX( p_column, cells.size() ); cells[p_column].text=p_text; - + if (cells[p_column].mode==TreeItem::CELL_MODE_RANGE) { - + cells[p_column].min=0; cells[p_column].max=p_text.get_slice_count(","); cells[p_column].step=0; @@ -225,7 +225,7 @@ void TreeItem::set_range(int p_column,double p_value) { p_value=cells[p_column].min; if (p_value>cells[p_column].max) p_value=cells[p_column].max; - + cells[p_column].val=p_value; _changed_notify(p_column); @@ -237,7 +237,7 @@ double TreeItem::get_range(int p_column) const { return cells[p_column].val; } - + bool TreeItem::is_range_exponential(int p_column) const { ERR_FAIL_INDEX_V( p_column, cells.size(), false); @@ -304,7 +304,7 @@ void TreeItem::set_collapsed(bool p_collapsed) { if (tree->select_mode==Tree::SELECT_MULTI) { - tree->selected_item=this; + tree->selected_item=this; emit_signal("cell_selected"); } else { @@ -337,11 +337,11 @@ TreeItem *TreeItem::get_prev() { if (!parent || parent->childs==this) return NULL; - + TreeItem *prev = parent->childs; while(prev && prev->next!=this) prev=prev->next; - + return prev; } @@ -636,14 +636,14 @@ void TreeItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_range","column"),&TreeItem::get_range); ObjectTypeDB::bind_method(_MD("set_range_config","column","min","max","step","expr"),&TreeItem::set_range_config,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_range_config","column"),&TreeItem::_get_range_config); - + ObjectTypeDB::bind_method(_MD("set_metadata","column","meta"),&TreeItem::set_metadata); ObjectTypeDB::bind_method(_MD("get_metadata","column"),&TreeItem::get_metadata); ObjectTypeDB::bind_method(_MD("set_custom_draw","column","object","callback"),&TreeItem::set_custom_draw); ObjectTypeDB::bind_method(_MD("set_collapsed","enable"),&TreeItem::set_collapsed); - ObjectTypeDB::bind_method(_MD("is_collapsed"),&TreeItem::is_collapsed); + ObjectTypeDB::bind_method(_MD("is_collapsed"),&TreeItem::is_collapsed); ObjectTypeDB::bind_method(_MD("get_next:TreeItem"),&TreeItem::get_next); ObjectTypeDB::bind_method(_MD("get_prev:TreeItem"),&TreeItem::get_prev); @@ -654,17 +654,17 @@ void TreeItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_prev_visible:TreeItem"),&TreeItem::get_prev_visible); ObjectTypeDB::bind_method(_MD("remove_child:TreeItem","child"),&TreeItem::_remove_child); - + ObjectTypeDB::bind_method(_MD("set_selectable","column","selectable"),&TreeItem::set_selectable); ObjectTypeDB::bind_method(_MD("is_selectable","column"),&TreeItem::is_selectable); ObjectTypeDB::bind_method(_MD("is_selected","column"),&TreeItem::is_selected); ObjectTypeDB::bind_method(_MD("select","column"),&TreeItem::select); ObjectTypeDB::bind_method(_MD("deselect","column"),&TreeItem::deselect); - + ObjectTypeDB::bind_method(_MD("set_editable","column","enabled"),&TreeItem::set_editable); ObjectTypeDB::bind_method(_MD("is_editable","column"),&TreeItem::is_editable); - + ObjectTypeDB::bind_method(_MD("set_custom_color","column","color"),&TreeItem::set_custom_color); ObjectTypeDB::bind_method(_MD("clear_custom_color","column"),&TreeItem::clear_custom_color); @@ -688,7 +688,7 @@ void TreeItem::_bind_methods() { BIND_CONSTANT( CELL_MODE_RANGE ); BIND_CONSTANT( CELL_MODE_ICON ); BIND_CONSTANT( CELL_MODE_CUSTOM ); - + } @@ -774,7 +774,7 @@ void Tree::update_cache() { cache.arrow =get_icon("arrow"); cache.select_arrow =get_icon("select_arrow"); cache.updown=get_icon("updown"); - + cache.font_color=get_color("font_color"); cache.font_color_selected=get_color("font_color_selected"); cache.guide_color=get_color("guide_color"); @@ -802,10 +802,10 @@ int Tree::compute_item_height(TreeItem *p_item) const { if (p_item==root && hide_root) return 0; - + int height=cache.font->get_height(); - + for (int i=0;i<columns.size();i++) { @@ -819,23 +819,23 @@ int Tree::compute_item_height(TreeItem *p_item) const { } switch(p_item->cells[i].mode) { - + case TreeItem::CELL_MODE_CHECK: { - + int check_icon_h = cache.checked->get_height(); if (height<check_icon_h) height=check_icon_h; - - - + + + } case TreeItem::CELL_MODE_STRING: case TreeItem::CELL_MODE_CUSTOM: case TreeItem::CELL_MODE_ICON: { - + Ref<Texture> icon = p_item->cells[i].icon; if (!icon.is_null()) { - + Size2i s = p_item->cells[i].get_icon_size(); if (p_item->cells[i].icon_max_w>0 && s.width > p_item->cells[i].icon_max_w ) { s.height=s.height * p_item->cells[i].icon_max_w / s.width; @@ -843,15 +843,15 @@ int Tree::compute_item_height(TreeItem *p_item) const { if (s.height > height ) height=s.height; } - + } break; default: {} } } - - + + height += cache.vseparation; - + return height; } @@ -927,7 +927,7 @@ void Tree::draw_item_text(String p_text,const Ref<Texture>& p_icon,int p_icon_ma p_rect.size.x-=Math::floor(p_rect.size.y/2); Ref<Font> font = cache.font; - + p_rect.pos.y+=Math::floor((p_rect.size.y-font->get_height())/2.0) +font->get_ascent(); font->draw(ci,p_rect.pos,p_text,p_color,p_rect.size.x); } @@ -950,13 +950,13 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& Point2i guide_from; - bool skip=(p_item==root && hide_root); + bool skip=(p_item==root && hide_root); // printf("skip (%p == %p && %i) %i\n",p_item,root,hide_root,skip); if (!skip && (p_pos.y+label_h-cache.offset.y)>0) { - // printf("entering\n"); + // printf("entering\n"); int height=label_h; @@ -965,7 +965,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& if (p_item->childs) { //has childs, draw the guide box Ref<Texture> arrow; - + if (p_item->collapsed) { arrow=cache.arrow_collapsed; @@ -983,7 +983,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& // if (p_item->get_parent()!=root || !hide_root) Ref<Font> font = cache.font; - + int font_ascent=font->get_ascent(); int ofs = p_pos.x + cache.item_margin; @@ -1066,7 +1066,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& } Color col=p_item->cells[i].custom_color?p_item->cells[i].color:get_color( p_item->cells[i].selected?"font_color_selected":"font_color"); - + Point2i text_pos=item_rect.pos; text_pos.y+=Math::floor((item_rect.size.y-font->get_height())/2) + font_ascent; @@ -1104,7 +1104,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& } break; case TreeItem::CELL_MODE_RANGE: { - + if (p_item->cells[i].text!="") { if (!p_item->cells[i].editable) @@ -1128,7 +1128,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& } else { Ref<Texture> updown = cache.updown; - + String valtext = String::num( p_item->cells[i].val, Math::decimals( p_item->cells[i].step ) ); font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width()); @@ -1185,7 +1185,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& Rect2i ir=item_rect; ir.size.width-=downarrow->get_width(); draw_item_rect(p_item->cells[i],ir,col); - + Point2i arrow_pos=item_rect.pos; arrow_pos.x+=item_rect.size.x-downarrow->get_width(); arrow_pos.y+=Math::floor(((item_rect.size.y-downarrow->get_height()))/2.0); @@ -1227,7 +1227,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& children_pos.x+=cache.item_margin; htotal+=label_h; children_pos.y+=htotal; - + } @@ -1272,12 +1272,12 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col continue; if (select_mode==SELECT_ROW) { - + if (p_selected==p_current) { - + if (!c.selected) { - + c.selected=true; selected_item=p_selected; selected_col=0; @@ -1286,26 +1286,26 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col //if (p_col==i) // p_current->selected_signal.call(p_col); } - + } else { - + if (c.selected) { - - c.selected=false; + + c.selected=false; //p_current->deselected_signal.call(p_col); } - + } - + } else if (select_mode==SELECT_SINGLE || select_mode==SELECT_MULTI) { - + if (!r_in_range && &selected_cell==&c) { - + if (!selected_cell.selected) { - + selected_cell.selected=true; - + selected_item=p_selected; selected_col=i; @@ -1321,7 +1321,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col } } else { - + if (r_in_range && *r_in_range) { @@ -1372,7 +1372,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ int item_h=compute_item_height( p_item )+cache.vseparation; bool skip=(p_item==root && hide_root); - + if (!skip && p_pos.y<item_h) { // check event! @@ -1384,7 +1384,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ return -1; //handled! } - + int x=p_pos.x; /* find clicked column */ int col=-1; @@ -1403,7 +1403,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ break; } - + if (col==-1) return -1; @@ -1487,8 +1487,8 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ //} update(); } - - + + } } @@ -1514,14 +1514,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } break; case TreeItem::CELL_MODE_CHECK: { - + Ref<Texture> checked = cache.checked; bring_up_editor=false; //checkboxes are not edited with editor if (x>=0 && x<= checked->get_width()+cache.hseparation ) { - + p_item->set_checked(col,!c.checked); - item_edited(col,p_item); + item_edited(col,p_item); click_handled=true; //p_item->edited_signal.call(col); } @@ -1549,37 +1549,37 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ //} bring_up_editor=false; } else { - + Ref<Texture> updown = cache.updown; - - + + if (x >= (col_width-item_h/2)) { - + /* touching the combo */ bool up=p_pos.y < (item_h /2); - + if (p_button==BUTTON_LEFT) { p_item->set_range( col, c.val + (up?1.0:-1.0) * c.step ); - - item_edited(col,p_item); + + item_edited(col,p_item); } else if (p_button==BUTTON_RIGHT) { - + p_item->set_range( col, (up?c.max:c.min) ); - item_edited(col,p_item); + item_edited(col,p_item); } else if (p_button==BUTTON_WHEEL_UP) { - + p_item->set_range( col, c.val + c.step ); - item_edited(col,p_item); + item_edited(col,p_item); } else if (p_button==BUTTON_WHEEL_DOWN) { - + p_item->set_range( col, c.val - c.step ); - item_edited(col,p_item); + item_edited(col,p_item); } - - //p_item->edited_signal.call(col); + + //p_item->edited_signal.call(col); bring_up_editor=false; - - + + } else { editor_text=String::num( p_item->cells[col].val, Math::decimals( p_item->cells[col].step ) ); @@ -1587,7 +1587,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ if (select_mode==SELECT_MULTI && get_tree()->get_last_event_id() == focus_in_id) bring_up_editor=false; - } + } } click_handled=true; @@ -1598,12 +1598,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } break; case TreeItem::CELL_MODE_CUSTOM: { edited_item=p_item; - edited_col=col; + edited_col=col; custom_popup_rect=Rect2i(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs+item_h-cache.offset.y), Size2(get_column_width(col),item_h)); emit_signal("custom_popup_edited",((bool)(x >= (col_width-item_h/2)))); bring_up_editor=false; - item_edited(col,p_item); + item_edited(col,p_item); click_handled=true; return -1; } break; @@ -1615,7 +1615,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ - click_handled=true; + click_handled=true; popup_edited_item=p_item; popup_edited_item_col=col; @@ -1627,14 +1627,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } else { Point2i new_pos=p_pos; - + if (!skip) { x_ofs+=cache.item_margin; //new_pos.x-=cache.item_margin; y_ofs+=item_h; new_pos.y-=item_h; } - + if (!p_item->collapsed) { /* if not collapsed, check the childs */ @@ -1697,7 +1697,7 @@ void Tree::text_editor_enter(String p_text) { default: { ERR_FAIL(); } } - item_edited(popup_edited_item_col,popup_edited_item); + item_edited(popup_edited_item_col,popup_edited_item); update(); } @@ -1725,19 +1725,19 @@ void Tree::popup_select(int p_option) { if (popup_edited_item_col<0 || popup_edited_item_col>columns.size()) return; - + popup_edited_item->cells[popup_edited_item_col].val=p_option; //popup_edited_item->edited_signal.call( popup_edited_item_col ); update(); - item_edited(popup_edited_item_col,popup_edited_item); + item_edited(popup_edited_item_col,popup_edited_item); } void Tree::_input_event(InputEvent p_event) { - + switch (p_event.type) { - + case InputEvent::KEY: { if (!p_event.key.pressed) @@ -2091,12 +2091,12 @@ void Tree::_input_event(InputEvent p_event) { } } break; case InputEvent::MOUSE_BUTTON: { - + if (cache.font.is_null()) // avoid a strange case that may fuckup stuff update_cache(); - const InputEventMouseButton& b=p_event.mouse_button; + const InputEventMouseButton& b=p_event.mouse_button; if (!b.pressed) { @@ -2160,7 +2160,7 @@ void Tree::_input_event(InputEvent p_event) { switch(b.button_index) { case BUTTON_LEFT: { Ref<StyleBox> bg = cache.bg; - + Point2 pos = Point2(b.x,b.y) - bg->get_offset(); cache.click_type=Cache::CLICK_NONE; if (show_column_titles) { @@ -2222,18 +2222,18 @@ void Tree::_input_event(InputEvent p_event) { } break; - case BUTTON_WHEEL_UP: { + case BUTTON_WHEEL_UP: { v_scroll->set_val( v_scroll->get_val()-v_scroll->get_page()/8 ); } break; case BUTTON_WHEEL_DOWN: { - + v_scroll->set_val( v_scroll->get_val()+v_scroll->get_page()/8 ); } break; } - + } break; } - + } @@ -2331,10 +2331,10 @@ Size2 Tree::get_internal_min_size() const { if (root) size.height+=get_item_height(root); for (int i=0;i<columns.size();i++) { - + size.width+=columns[i].min_width; } - + return size; } @@ -2353,39 +2353,39 @@ void Tree::update_scrollbars() { Size2 vmin = v_scroll->get_combined_minimum_size(); - + v_scroll->set_begin( Point2(size.width - vmin.width , cache.bg->get_margin(MARGIN_TOP)) ); v_scroll->set_end( Point2(size.width, size.height-cache.bg->get_margin(MARGIN_TOP)-cache.bg->get_margin(MARGIN_BOTTOM)) ); - + h_scroll->set_begin( Point2( 0, size.height - hmin.height) ); h_scroll->set_end( Point2(size.width-vmin.width, size.height) ); - - + + Size2 min = get_internal_min_size(); - + if (min.height < size.height - hmin.height) { - + v_scroll->hide(); cache.offset.y=0; } else { - + v_scroll->show(); v_scroll->set_max(min.height); v_scroll->set_page(size.height - hmin.height - tbh); cache.offset.y=v_scroll->get_val(); } - + if (min.width < size.width - vmin.width) { - + h_scroll->hide(); cache.offset.x=0; } else { - + h_scroll->show(); h_scroll->set_max(min.width); h_scroll->set_page(size.width - vmin.width); cache.offset.x=h_scroll->get_val(); - } + } } @@ -2464,16 +2464,16 @@ void Tree::_notification(int p_what) { } if (p_what==NOTIFICATION_DRAW) { - + update_cache(); update_scrollbars(); - RID ci = get_canvas_item(); - + RID ci = get_canvas_item(); + VisualServer::get_singleton()->canvas_item_set_clip(ci,true); - + Ref<StyleBox> bg = cache.bg; Ref<StyleBox> bg_focus = get_stylebox("bg_focus"); - + Point2 draw_ofs; draw_ofs+=bg->get_offset(); Size2 draw_size=get_size()-bg->get_minimum_size(); @@ -2491,7 +2491,7 @@ void Tree::_notification(int p_what) { draw_size.y-=tbh; if (root) { - + draw_item( Point2(),draw_ofs,draw_size,root); @@ -2502,10 +2502,10 @@ void Tree::_notification(int p_what) { // int size_y=exposed.size.height-bg->get_minimum_size().height; for (int i=0;i<(columns.size()-1-1);i++) { - + ofs+=get_column_width(i); //get_painter()->draw_fill_rect( Point2(ofs+cache.hseparation/2, from_y), Size2( 1, size_y ),color( COLOR_TREE_GRID) ); - } + } if (show_column_titles) { @@ -2605,7 +2605,7 @@ TreeItem* Tree::get_last_item() { } void Tree::item_edited(int p_column,TreeItem *p_item) { - + edited_item=p_item; edited_col=p_column; emit_signal("item_edited"); @@ -2613,14 +2613,14 @@ void Tree::item_edited(int p_column,TreeItem *p_item) { void Tree::item_changed(int p_column,TreeItem *p_item) { - update(); + update(); } void Tree::item_selected(int p_column,TreeItem *p_item) { if (select_mode==SELECT_MULTI) { - + if (!p_item->cells[p_column].selectable) return; @@ -2636,16 +2636,16 @@ void Tree::item_selected(int p_column,TreeItem *p_item) { void Tree::item_deselected(int p_column,TreeItem *p_item) { if (select_mode==SELECT_MULTI) { - + p_item->cells[p_column].selected=false; - } + } update(); } void Tree::set_select_mode(SelectMode p_mode) { - select_mode=p_mode; + select_mode=p_mode; } void Tree::clear() { @@ -2675,15 +2675,15 @@ void Tree::set_hide_root(bool p_enabled) { - hide_root=p_enabled; - update(); + hide_root=p_enabled; + update(); } void Tree::set_column_min_width(int p_column,int p_min_width) { ERR_FAIL_INDEX(p_column,columns.size()); - + if (p_min_width<1) return; columns[p_column].min_width=p_min_width; @@ -2693,8 +2693,8 @@ void Tree::set_column_min_width(int p_column,int p_min_width) { void Tree::set_column_expand(int p_column,bool p_expand) { ERR_FAIL_INDEX(p_column,columns.size()); - - columns[p_column].expand=p_expand; + + columns[p_column].expand=p_expand; update(); } @@ -2709,78 +2709,78 @@ int Tree::get_selected_column() const { } TreeItem *Tree::get_edited() const { - + return edited_item; } int Tree::get_edited_column() const { - + return edited_col; } TreeItem* Tree::get_next_selected( TreeItem* p_item) { - + //if (!p_item) // return NULL; if (!root) - return NULL; - + return NULL; + while(true) { - - + + if (!p_item) { p_item=root; } else { - + if (p_item->childs) { - + p_item=p_item->childs; - + } else if (p_item->next) { - - p_item=p_item->next; + + p_item=p_item->next; } else { - + while(!p_item->next) { - + p_item=p_item->parent; if (p_item==NULL) return NULL; } - + p_item=p_item->next; } - + } - + for (int i=0;i<columns.size();i++) if (p_item->cells[i].selected) return p_item; } - + return NULL; } int Tree::get_column_width(int p_column) const { - + ERR_FAIL_INDEX_V(p_column,columns.size(),-1); - - + + if (!columns[p_column].expand) return columns[p_column].min_width; - + Ref<StyleBox> bg = cache.bg; - + int expand_area=get_size().width-(bg->get_margin(MARGIN_LEFT)+bg->get_margin(MARGIN_RIGHT)); - + if (v_scroll->is_visible()) expand_area-=v_scroll->get_combined_minimum_size().width; - + int expanding_columns=0; int expanding_total=0; - + for (int i=0;i<columns.size();i++) { - + if (!columns[i].expand) { expand_area-=columns[i].min_width; } else { @@ -2791,30 +2791,30 @@ int Tree::get_column_width(int p_column) const { if (expand_area<expanding_total) return columns[p_column].min_width; - + ERR_FAIL_COND_V(expanding_columns==0,-1); // shouldnt happen - + return expand_area * columns[p_column].min_width / expanding_total; } void Tree::propagate_set_columns(TreeItem *p_item) { - + p_item->cells.resize( columns.size() ); - + TreeItem *c = p_item->get_children(); while(c) { - + propagate_set_columns(c); c=c->get_next(); } } void Tree::set_columns(int p_columns) { - + ERR_FAIL_COND(p_columns<1); ERR_FAIL_COND(blocked>0); columns.resize(p_columns); - + if (root) propagate_set_columns(root); if (selected_col>=p_columns) @@ -2824,17 +2824,17 @@ void Tree::set_columns(int p_columns) { } int Tree::get_columns() const { - + return columns.size(); } void Tree::_scroll_moved(float) { - + update(); } Rect2 Tree::get_custom_popup_rect() const { - + return custom_popup_rect; } @@ -3116,7 +3116,7 @@ bool Tree::can_cursor_exit_tree() const { void Tree::_bind_methods() { - + ObjectTypeDB::bind_method(_MD("_input_event"),&Tree::_input_event); ObjectTypeDB::bind_method(_MD("_popup_select"),&Tree::popup_select); ObjectTypeDB::bind_method(_MD("_text_editor_enter"),&Tree::text_editor_enter); @@ -3140,7 +3140,7 @@ void Tree::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_columns","amount"),&Tree::set_columns); ObjectTypeDB::bind_method(_MD("get_columns"),&Tree::get_columns); - + ObjectTypeDB::bind_method(_MD("get_edited:TreeItem"),&Tree::get_edited); ObjectTypeDB::bind_method(_MD("get_edited_column"),&Tree::get_edited_column); ObjectTypeDB::bind_method(_MD("get_custom_popup_rect"),&Tree::get_custom_popup_rect); @@ -3179,7 +3179,7 @@ Tree::Tree() { edited_item=NULL; selected_col=-1; edited_col=-1; - + hide_root=false; select_mode=SELECT_SINGLE; root=0; @@ -3187,8 +3187,8 @@ Tree::Tree() { popup_edited_item=NULL; text_editor=NULL; set_focus_mode(FOCUS_ALL); - - + + popup_menu = memnew( PopupMenu ); popup_menu->hide(); add_child(popup_menu); @@ -3204,7 +3204,7 @@ Tree::Tree() { h_scroll = memnew( HScrollBar ); v_scroll = memnew( VScrollBar ); - + add_child(h_scroll); add_child(v_scroll); @@ -3250,6 +3250,6 @@ Tree::~Tree() { if (root) { memdelete( root ); } - + } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index f1e97fd626..5a99538a5f 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -31,7 +31,7 @@ static TexCacheMap *tex_cache; template<class T> static Ref<StyleBoxTexture> make_stylebox(T p_src,float p_left, float p_top, float p_right, float p_botton,float p_margin_left=-1, float p_margin_top=-1, float p_margin_right=-1, float p_margin_botton=-1, bool p_draw_center=true) { - + Ref<ImageTexture> texture; @@ -56,17 +56,17 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src,float p_left, float p_top, flo style->set_default_margin( MARGIN_BOTTOM, p_margin_botton ); style->set_default_margin( MARGIN_TOP, p_margin_top ); style->set_draw_center(p_draw_center); - + return style; } template<class T> static Ref<Texture> make_icon(T p_src) { - - + + Ref<ImageTexture> texture( memnew( ImageTexture ) ); texture->create_from_image( Image(p_src),ImageTexture::FLAG_FILTER ); - + return texture; } @@ -75,7 +75,7 @@ static Ref<Font> make_font(int p_height,int p_ascent, int p_valign, int p_charco Ref<Font> font( memnew( Font ) ); font->add_texture( p_texture ); - + for (int i=0;i<p_charcount;i++) { const int *c = &p_chars[i*8]; @@ -91,9 +91,9 @@ static Ref<Font> make_font(int p_height,int p_ascent, int p_valign, int p_charco font->add_char( chr, 0, frect, align,advance ); - + } - + font->set_height( p_height ); font->set_ascent( p_ascent ); @@ -152,12 +152,12 @@ static Ref<Font> make_font2(int p_height,int p_ascent, int p_charcount, const in static Ref<StyleBox> make_empty_stylebox(float p_margin_left=-1, float p_margin_top=-1, float p_margin_right=-1, float p_margin_botton=-1) { Ref<StyleBox> style( memnew( StyleBoxEmpty) ); - + style->set_default_margin( MARGIN_LEFT, p_margin_left ); style->set_default_margin( MARGIN_RIGHT, p_margin_right ); style->set_default_margin( MARGIN_BOTTOM, p_margin_botton ); style->set_default_margin( MARGIN_TOP, p_margin_top ); - + return style; } @@ -299,49 +299,49 @@ void make_default_theme() { t->set_constant("hseparation","MenuButton", 3 ); - // CheckBox + // CheckBox - Ref<StyleBox> cbx_empty = memnew( StyleBoxEmpty ); - cbx_empty->set_default_margin(MARGIN_LEFT,22); - cbx_empty->set_default_margin(MARGIN_RIGHT,4); - cbx_empty->set_default_margin(MARGIN_TOP,4); - cbx_empty->set_default_margin(MARGIN_BOTTOM,5); - Ref<StyleBox> cbx_focus = focus; - cbx_focus->set_default_margin(MARGIN_LEFT,4); - cbx_focus->set_default_margin(MARGIN_RIGHT,22); - cbx_focus->set_default_margin(MARGIN_TOP,4); - cbx_focus->set_default_margin(MARGIN_BOTTOM,5); + Ref<StyleBox> cbx_empty = memnew( StyleBoxEmpty ); + cbx_empty->set_default_margin(MARGIN_LEFT,22); + cbx_empty->set_default_margin(MARGIN_RIGHT,4); + cbx_empty->set_default_margin(MARGIN_TOP,4); + cbx_empty->set_default_margin(MARGIN_BOTTOM,5); + Ref<StyleBox> cbx_focus = focus; + cbx_focus->set_default_margin(MARGIN_LEFT,4); + cbx_focus->set_default_margin(MARGIN_RIGHT,22); + cbx_focus->set_default_margin(MARGIN_TOP,4); + cbx_focus->set_default_margin(MARGIN_BOTTOM,5); - t->set_stylebox("normal","CheckBox", cbx_empty ); - t->set_stylebox("pressed","CheckBox", cbx_empty ); - t->set_stylebox("disabled","CheckBox", cbx_empty ); - t->set_stylebox("hover","CheckBox", cbx_empty ); - t->set_stylebox("focus","CheckBox", cbx_focus ); + t->set_stylebox("normal","CheckBox", cbx_empty ); + t->set_stylebox("pressed","CheckBox", cbx_empty ); + t->set_stylebox("disabled","CheckBox", cbx_empty ); + t->set_stylebox("hover","CheckBox", cbx_empty ); + t->set_stylebox("focus","CheckBox", cbx_focus ); - t->set_icon("checked", "CheckBox", make_icon(checked_png)); - t->set_icon("unchecked", "CheckBox", make_icon(unchecked_png)); - t->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png)); - t->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png)); + t->set_icon("checked", "CheckBox", make_icon(checked_png)); + t->set_icon("unchecked", "CheckBox", make_icon(unchecked_png)); + t->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png)); + t->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png)); - t->set_font("font","CheckBox", default_font ); + t->set_font("font","CheckBox", default_font ); - t->set_color("font_color","CheckBox", control_font_color ); - t->set_color("font_color_pressed","CheckBox", control_font_color_pressed ); - t->set_color("font_color_hover","CheckBox", control_font_color_hover ); - t->set_color("font_color_disabled","CheckBox", control_font_color_disabled ); + t->set_color("font_color","CheckBox", control_font_color ); + t->set_color("font_color_pressed","CheckBox", control_font_color_pressed ); + t->set_color("font_color_hover","CheckBox", control_font_color_hover ); + t->set_color("font_color_disabled","CheckBox", control_font_color_disabled ); - t->set_constant("hseparation","CheckBox",4); - t->set_constant("check_vadjust","CheckBox",0); + t->set_constant("hseparation","CheckBox",4); + t->set_constant("check_vadjust","CheckBox",0); // CheckButton - + Ref<StyleBox> cb_empty = memnew( StyleBoxEmpty ); cb_empty->set_default_margin(MARGIN_LEFT,6); cb_empty->set_default_margin(MARGIN_RIGHT,70); cb_empty->set_default_margin(MARGIN_TOP,4); - cb_empty->set_default_margin(MARGIN_BOTTOM,4); + cb_empty->set_default_margin(MARGIN_BOTTOM,4); t->set_stylebox("normal","CheckButton", cb_empty ); t->set_stylebox("pressed","CheckButton", cb_empty ); @@ -365,7 +365,7 @@ void make_default_theme() { // Label - + t->set_font("font","Label", default_font ); t->set_color("font_color","Label", Color(1,1,1) ); @@ -556,10 +556,16 @@ void make_default_theme() { // GraphNode - Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5); + Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png,6,24,6,5,3,24,16,5); + Ref<StyleBoxTexture> graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,3,24,16,5); + Ref<StyleBoxTexture> graphsbdefault = make_stylebox(graph_node_default_png,4,4,4,4,6,4,4,4); + Ref<StyleBoxTexture> graphsbdeffocus = make_stylebox(graph_node_default_focus_png,4,4,4,4,6,4,4,4); //graphsb->set_expand_margin_size(MARGIN_LEFT,10); //graphsb->set_expand_margin_size(MARGIN_RIGHT,10); t->set_stylebox("frame","GraphNode", graphsb ); + t->set_stylebox("selectedframe","GraphNode", graphsbselected ); + t->set_stylebox("defaultframe", "GraphNode", graphsbdefault ); + t->set_stylebox("defaultfocus", "GraphNode", graphsbdeffocus ); t->set_constant("separation","GraphNode", 1 ); t->set_icon("port","GraphNode", make_icon( graph_port_png ) ); t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) ); @@ -713,7 +719,7 @@ void make_default_theme() { // FileDialog - + t->set_icon("folder","FileDialog",make_icon(icon_folder_png)); t->set_color("files_disabled","FileDialog",Color(0,0,0,0.7)); @@ -877,10 +883,10 @@ void make_default_theme() { #endif void clear_default_theme() { - + Theme::set_default( Ref<Theme>() ); Theme::set_default_icon( Ref< Texture >() ); - Theme::set_default_style( Ref< StyleBox >() ); + Theme::set_default_style( Ref< StyleBox >() ); Theme::set_default_font( Ref< Font >() ); } diff --git a/scene/resources/default_theme/graph_node_default.png b/scene/resources/default_theme/graph_node_default.png Binary files differnew file mode 100644 index 0000000000..ea6ec52828 --- /dev/null +++ b/scene/resources/default_theme/graph_node_default.png diff --git a/scene/resources/default_theme/graph_node_default_focus.png b/scene/resources/default_theme/graph_node_default_focus.png Binary files differnew file mode 100644 index 0000000000..b7c38ae481 --- /dev/null +++ b/scene/resources/default_theme/graph_node_default_focus.png diff --git a/scene/resources/default_theme/graph_node_selected.png b/scene/resources/default_theme/graph_node_selected.png Binary files differnew file mode 100644 index 0000000000..06a9db4409 --- /dev/null +++ b/scene/resources/default_theme/graph_node_selected.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 03d851e749..ba818d86b2 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -114,6 +114,21 @@ static const unsigned char graph_node_close_png[]={ }; +static const unsigned char graph_node_default_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x8,0x1a,0x17,0x2e,0xd,0x4c,0xb7,0x38,0x4,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0x85,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x93,0x31,0xa,0x83,0x40,0x14,0x44,0xdf,0xba,0xa5,0x20,0x41,0x30,0x20,0x4,0xab,0x40,0x20,0x7,0xc9,0x69,0xec,0x72,0x4e,0x9b,0xa0,0x1e,0xc1,0x2a,0x42,0x10,0x82,0xbb,0xc5,0x77,0x6d,0x4c,0x11,0x48,0xe3,0xb7,0x49,0xe1,0x6b,0x6,0xa6,0x78,0xd5,0x8c,0x1,0x6e,0x80,0xe1,0x9b,0xb0,0xe4,0xaf,0xde,0x3,0x4f,0xa0,0x3,0x6,0x93,0x67,0xa7,0xc0,0xa,0x44,0x64,0x72,0x7e,0x6c,0x87,0xf7,0xab,0x4,0x1e,0x68,0x38,0x17,0x97,0x90,0xc4,0x87,0xa,0xb8,0xa2,0xe5,0x98,0xe6,0x1,0xb8,0x47,0x5a,0x81,0xb5,0x16,0xa0,0x56,0xb,0x3e,0xec,0x82,0x3f,0x10,0x4c,0x6a,0x81,0x88,0x78,0xc0,0x45,0xda,0x29,0x3b,0x3f,0x36,0x40,0xbf,0xf9,0x4c,0x66,0xeb,0x9d,0x67,0x5c,0x46,0x37,0x51,0xb6,0x55,0x6d,0xc2,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + +static const unsigned char graph_node_default_focus_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x8,0x1b,0x1,0x9,0x1c,0x5c,0xd5,0x12,0x34,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0xfc,0x49,0x44,0x41,0x54,0x38,0xcb,0xbd,0x93,0x41,0x4a,0x4,0x41,0xc,0x45,0x7f,0xca,0x6a,0x14,0x42,0x2f,0xc4,0x85,0x7,0xf0,0x3c,0xde,0xa2,0xbc,0x41,0xd7,0xa2,0xa1,0x60,0xea,0x60,0xae,0x5c,0xea,0x19,0xdc,0xd7,0x42,0x97,0xe5,0xc,0x12,0xeb,0xbb,0x69,0xa5,0x84,0xe9,0x41,0x1d,0xf1,0x43,0x8,0x84,0xe4,0x2d,0x92,0x1f,0xc1,0x22,0x92,0x2,0xc0,0x2d,0x81,0x2e,0x7f,0xa8,0x75,0xb9,0x89,0x8,0x1,0x40,0x48,0x5e,0x76,0xcd,0xad,0x6b,0x74,0x7b,0xea,0x6,0xe0,0x75,0x9,0x13,0x11,0xca,0x34,0x4d,0xc4,0x37,0x35,0xc,0xc3,0xf3,0x38,0x8e,0xb7,0xf3,0x3c,0xdf,0x0,0xd8,0x1,0x30,0x90,0x4,0x49,0xe4,0x9c,0x11,0x42,0x40,0x29,0x65,0x15,0x50,0x4a,0xb9,0x8,0x21,0x30,0xe7,0x7c,0x47,0x52,0x49,0x9e,0x7c,0x2,0x62,0x8c,0x30,0x33,0xa8,0xea,0x2a,0x40,0x55,0xaf,0xcc,0x4c,0x62,0x8c,0x5b,0x92,0xe7,0x24,0x7,0xd7,0x2d,0x11,0xde,0x7b,0xd4,0x5a,0x57,0x1,0xb5,0xd6,0x47,0xef,0x3d,0x49,0x9e,0x1,0xf0,0x0,0x9c,0xc3,0xef,0xe5,0xf6,0x9d,0xea,0x5f,0x1,0x38,0x16,0xd0,0xfe,0x16,0x20,0x22,0x7,0x3d,0xd0,0x7b,0x41,0x44,0xb6,0x8b,0x2b,0x9b,0xeb,0x6e,0x8c,0x94,0x12,0xcc,0x6c,0x75,0xd8,0xcc,0xc6,0x94,0xd2,0x93,0xaa,0xde,0x2f,0x76,0x6e,0x3f,0xb2,0xb2,0x88,0xec,0x54,0xf5,0x61,0xb3,0xd9,0x5c,0x3,0x78,0x1,0x60,0xc7,0x3c,0x53,0x13,0x91,0x37,0xe9,0x9d,0xd8,0xe9,0xf4,0xc0,0xe2,0xbe,0xbc,0xf3,0x3b,0x49,0xa0,0x89,0xbf,0x71,0xc6,0xcd,0x1c,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + +static const unsigned char graph_node_selected_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x40,0x8,0x6,0x0,0x0,0x0,0x13,0x7d,0xf7,0x96,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x7,0x12,0x1,0xc,0x6,0x23,0x98,0xc7,0x50,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x2,0x46,0x49,0x44,0x41,0x54,0x58,0xc3,0xed,0x97,0xcd,0x6a,0x13,0x51,0x14,0xc7,0x7f,0xe7,0xce,0x34,0x49,0xd,0xa6,0xb1,0x2a,0xe2,0x7,0x74,0xa1,0x6e,0x4,0x85,0xe2,0x3,0xb8,0x72,0x21,0xba,0x16,0x5c,0xb9,0x16,0x4,0x7d,0x84,0x3e,0x82,0x82,0xe0,0xda,0x95,0x2f,0x60,0x71,0xe1,0xca,0x7,0xd0,0x82,0xa5,0x6e,0xd4,0x45,0xc1,0x8f,0x4a,0x6c,0x9a,0x46,0x62,0x66,0xa6,0x73,0xef,0x71,0xe1,0x4c,0x92,0x99,0x4c,0x93,0x36,0xdd,0xc9,0xfc,0x37,0x77,0x3e,0xee,0xfd,0xdd,0x73,0xfe,0xf7,0xc,0xcc,0x11,0x86,0x12,0xc0,0x0,0x5e,0x32,0xa,0x59,0x29,0xe0,0x0,0x9b,0x8c,0xca,0xc8,0x24,0x3,0x1c,0x3,0x16,0x81,0xd3,0x40,0x3,0x98,0xcb,0x1,0xf6,0x80,0x2e,0xd0,0x2,0xda,0xc0,0x1f,0xc0,0xa5,0xbb,0xd6,0x81,0x4b,0xb,0xc7,0x9b,0xf,0x6a,0xd5,0xda,0xad,0x4a,0xa5,0x7a,0x81,0x2,0x45,0x51,0xf8,0x35,0x8,0x83,0xd7,0xbb,0xbf,0x3b,0xcf,0x81,0xcf,0x40,0x4f,0x92,0x9d,0x96,0x16,0x9b,0x27,0x9f,0x5c,0x5c,0xba,0x7c,0xfb,0xfe,0xcb,0x3b,0x34,0x2b,0x27,0x8a,0xd6,0xd3,0x89,0x76,0x78,0x71,0xef,0x15,0x5f,0x36,0x3f,0xad,0xb6,0x3b,0xdb,0x8f,0x81,0x4d,0x1,0x6a,0xc0,0xf2,0xd9,0x33,0xe7,0xdf,0xac,0xbc,0x7d,0x54,0xdf,0x73,0x11,0x81,0xed,0x17,0x2,0x6a,0xde,0x3c,0x73,0xa6,0xc2,0xca,0x8d,0xa7,0xbd,0x1f,0x3f,0xbf,0xdd,0x4,0xd6,0xfc,0xc4,0x87,0xba,0xef,0xf9,0xf5,0x6e,0xb4,0xc3,0x24,0xf5,0xe3,0x1e,0x7d,0x7a,0xf8,0x9e,0x5f,0x4f,0xd2,0x96,0x14,0xe0,0x1,0x58,0xb5,0x39,0xdb,0x1d,0x82,0x19,0x5c,0xe7,0xe4,0xa5,0x0,0x4d,0x8f,0x44,0x71,0xa8,0x2a,0x22,0x92,0x81,0x4c,0x92,0x3f,0x7a,0xe3,0xd4,0xe2,0x54,0x41,0xc1,0x13,0xf,0xc5,0xe1,0x54,0x31,0x22,0x8,0xa6,0x10,0x96,0x1,0x58,0x1d,0x4e,0x88,0x35,0x1e,0x79,0x9e,0xd6,0xd0,0x94,0x8,0x54,0xb3,0x93,0x1c,0x8a,0x41,0x6,0x63,0xfa,0x6c,0x5f,0x40,0xe4,0xa2,0xcc,0x4b,0x23,0x32,0xd8,0x37,0x4e,0x52,0x99,0x1c,0x41,0x2e,0x4c,0x9b,0xdd,0x6c,0xec,0xbe,0x20,0x5,0xe5,0xb0,0xca,0x99,0x68,0x93,0x48,0x14,0x41,0x30,0x22,0x3,0x63,0x5,0x41,0x51,0x3c,0x31,0x93,0x8f,0x31,0xf3,0xed,0x6a,0xf6,0x5b,0xfe,0xe7,0x85,0x9b,0x0,0x98,0x52,0x34,0x7,0x2a,0xa4,0xb4,0x74,0x8b,0x4c,0x2d,0x2a,0xa6,0xb1,0x42,0x32,0x8c,0x1b,0x39,0x3c,0x7b,0x37,0xbd,0x90,0xec,0x51,0x52,0x88,0x5d,0x3c,0x36,0x21,0xd,0x39,0x4d,0x4d,0x72,0xc5,0x94,0x1,0xac,0xde,0x7d,0x3f,0xbb,0x89,0xf1,0x9e,0x65,0xf9,0xea,0xf5,0x3,0x2d,0x5a,0x5b,0x7f,0x57,0x1c,0xc1,0x6e,0xb7,0x73,0xe8,0x8,0xc,0x47,0x54,0x9,0x28,0x1,0x25,0xa0,0x4,0x94,0x80,0x12,0x50,0x2,0xfe,0x4b,0x80,0x14,0xf4,0x88,0x87,0x8e,0xc0,0xcd,0xb0,0xd6,0xa5,0x0,0x7,0x4,0xd6,0xda,0xb0,0xe0,0x27,0x6d,0x7c,0x55,0xc,0xd6,0xda,0x10,0x8,0x0,0x67,0x92,0x56,0x76,0x3b,0x8,0xfb,0x1b,0xad,0xf6,0x16,0x93,0x20,0x2e,0x86,0x56,0x7b,0x8b,0x20,0xec,0x6f,0x0,0xdb,0x80,0x4d,0x3b,0xd7,0x5,0xe0,0x5a,0xa3,0xde,0x7c,0x56,0xab,0xce,0x5f,0xf1,0x3c,0xaf,0xd0,0x5c,0x6b,0xad,0xb,0xc2,0xfe,0xc7,0x6e,0xaf,0xf3,0x10,0xf8,0x0,0xec,0xca,0x48,0xb,0xd7,0x0,0xce,0x1,0xa7,0x80,0xea,0x3e,0xcd,0x77,0x8,0xfc,0x2,0xbe,0x27,0x7d,0xb4,0x95,0x9c,0xa1,0x7e,0xda,0xf,0xee,0x93,0x85,0x26,0x29,0xc7,0x33,0x1a,0x3f,0xae,0xbf,0xf0,0x27,0xf6,0x42,0xf6,0xf5,0xfd,0xae,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + static const unsigned char graph_port_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0xa,0x0,0x0,0x0,0xa,0x8,0x6,0x0,0x0,0x0,0x8d,0x32,0xcf,0xbd,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x0,0x0,0x0,0x0,0x0,0xf9,0x43,0xbb,0x7f,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0xc,0x14,0x17,0x20,0x3,0xeb,0x8f,0x3a,0xdb,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x1,0x65,0x49,0x44,0x41,0x54,0x18,0xd3,0x4d,0xd0,0x4f,0x6b,0xda,0x70,0x1c,0x7,0xe0,0xcf,0x37,0x7f,0x7e,0x49,0x66,0xd2,0x64,0x61,0x5,0x61,0x76,0x47,0xf1,0xa4,0x2d,0xdb,0x75,0x5,0x11,0x84,0xb0,0x5e,0xeb,0xd9,0xeb,0xf4,0x6d,0xec,0x2d,0xf8,0x26,0xb6,0x77,0xe0,0x45,0xba,0xa3,0x6c,0xa0,0x3b,0xad,0x39,0xb6,0x36,0x8,0x1b,0x4b,0x32,0xd2,0xc6,0x6c,0x9a,0x4f,0x4f,0x85,0x3e,0x2f,0xe1,0x11,0x0,0x20,0x29,0xd3,0xe9,0xd4,0xda,0x6e,0xb7,0x23,0xdf,0xf7,0xbb,0x0,0x90,0xe7,0xf9,0x8f,0x66,0xb3,0xf9,0x79,0x36,0x9b,0x55,0x22,0x42,0x83,0xa4,0x44,0x51,0xf4,0xea,0xe2,0xe2,0xc3,0xf7,0xf1,0x78,0xdc,0xa,0x82,0x40,0x8,0x20,0xcf,0x32,0x2e,0x97,0xcb,0x4f,0x51,0x14,0xbd,0x25,0xf9,0x5b,0x26,0x93,0x89,0xdd,0xe9,0x74,0xe2,0xf7,0xe7,0xe7,0x27,0x59,0xfa,0x87,0x65,0xb9,0x13,0x0,0xb0,0x1d,0x9b,0xe1,0xcb,0x50,0xbe,0x5e,0x5d,0xdd,0xfe,0xbc,0xbe,0x6e,0x6b,0x49,0x92,0x8c,0x4e,0x7b,0xa7,0xad,0xbf,0x79,0x4e,0xd3,0x54,0x12,0x86,0x21,0xc2,0x30,0x84,0x32,0x95,0xe4,0x79,0xc6,0xde,0xd9,0x59,0x2b,0x49,0xee,0x46,0x86,0xeb,0xba,0x5d,0xfb,0x85,0x23,0x87,0xfd,0x1e,0xb6,0xed,0x40,0xd7,0x35,0x0,0x40,0x7d,0x38,0xa0,0xdc,0xed,0x44,0x37,0x74,0xb8,0xae,0xd7,0x35,0x48,0x62,0xff,0xff,0x1f,0xfc,0x20,0x80,0xae,0xe9,0x78,0x42,0x0,0xca,0xb2,0x90,0x65,0x19,0x58,0xd7,0xd0,0x8a,0xa2,0x58,0xa7,0x69,0x56,0x6b,0xa2,0x51,0x29,0x5,0xcb,0x52,0xb0,0x94,0x5,0x4b,0x29,0x88,0x8,0xd3,0x34,0xad,0x8b,0xfb,0x62,0xad,0xf,0x6,0x83,0xb8,0xaa,0xaa,0xb1,0xe7,0x79,0xbe,0x77,0x74,0x44,0xb7,0xe1,0x89,0x69,0x1a,0x28,0xcb,0x92,0x9b,0xcd,0x46,0x56,0xab,0xd5,0x86,0xe4,0x47,0x21,0x29,0xc3,0xe1,0xf0,0xb8,0xdf,0xef,0x7f,0x6b,0xb7,0xdb,0xaf,0x1b,0x8d,0x86,0x46,0x10,0xf,0xf7,0xf,0x75,0x1c,0xc7,0x77,0x8b,0xc5,0xe2,0xdd,0x7c,0x3e,0xff,0x25,0xcf,0xc3,0x6f,0x6e,0x6f,0x2e,0x1d,0xdb,0xe9,0x9,0x80,0xb2,0x2a,0xd7,0x27,0xad,0x37,0x5f,0x9e,0xc2,0x1f,0x1,0x3a,0xe6,0xa5,0x7b,0xef,0xf2,0xf3,0xcd,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index a0766ff317..4604c42de1 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -80,12 +80,15 @@ void ShaderGraph::_set_data(const Dictionary &p_data) { ERR_FAIL_COND((conns.size()%3)!=0); for(int j=0;j<conns.size();j+=3) { - SourceSlot ss; int ls=conns[j+0]; - ss.id=conns[j+1]; - ss.slot=conns[j+2]; - n.connections[ls]=ss; + if (ls == SLOT_DEFAULT_VALUE) { + n.defaults[conns[j+1]]=conns[j+2]; + } else { + ss.id=conns[j+1]; + ss.slot=conns[j+2]; + n.connections[ls]=ss; + } } shader[t].node_map[n.id]=n; @@ -114,7 +117,7 @@ Dictionary ShaderGraph::_get_data() const { data[idx+4]=E->get().param2; Array conns; - conns.resize(E->get().connections.size()*3); + conns.resize(E->get().connections.size()*3+E->get().defaults.size()*3); int idx2=0; for(Map<int,SourceSlot>::Element*F=E->get().connections.front();F;F=F->next()) { @@ -123,6 +126,14 @@ Dictionary ShaderGraph::_get_data() const { conns[idx2+2]=F->get().slot; idx2+=3; } + for(Map<int,Variant>::Element*F=E->get().defaults.front();F;F=F->next()) { + + conns[idx2+0]=SLOT_DEFAULT_VALUE; + conns[idx2+1]=F->key(); + conns[idx2+2]=F->get(); + idx2+=3; + } + data[idx+5]=conns; idx+=6; } @@ -142,6 +153,15 @@ ShaderGraph::GraphError ShaderGraph::get_graph_error(ShaderType p_type) const { return shader[p_type].error; } +int ShaderGraph::node_count(ShaderType p_which, int p_type) +{ + int count=0; + for (Map<int,Node>::Element *E=shader[p_which].node_map.front();E;E=E->next()) + if (E->get().type==p_type) + count++; + return count; +} + void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("_update_shader"),&ShaderGraph::_update_shader); @@ -155,6 +175,9 @@ void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_node_list","shader_type"),&ShaderGraph::_get_node_list); + ObjectTypeDB::bind_method(_MD("default_set_value","shader_type","id","param_id","value"), &ShaderGraph::default_set_value); + ObjectTypeDB::bind_method(_MD("default_get_value","shader_type","id","param_id"), &ShaderGraph::default_get_value); + ObjectTypeDB::bind_method(_MD("scalar_const_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_const_node_set_value); ObjectTypeDB::bind_method(_MD("scalar_const_node_get_value","shader_type","id"),&ShaderGraph::scalar_const_node_set_value); @@ -537,7 +560,7 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) { case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material) case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material) case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material) - case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) + case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) case NODE_DEFAULT_TEXTURE: {}; break; case NODE_OUTPUT: {} break; // output (shader type dependent) case NODE_COMMENT: {} break; // comment @@ -683,6 +706,18 @@ void ShaderGraph::get_node_connections(ShaderType p_type,List<Connection> *p_con } } +bool ShaderGraph::is_slot_connected(ShaderGraph::ShaderType p_type, int p_dst_id, int slot_id) +{ + for(const Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) { + for (const Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) { + + if (p_dst_id == E->key() && slot_id==F->key()) + return true; + } + } + return false; +} + void ShaderGraph::clear(ShaderType p_type) { @@ -824,6 +859,47 @@ float ShaderGraph::texture_node_get_filter_strength(ShaderType p_type,float p_id 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){ @@ -955,6 +1031,33 @@ ShaderGraph::ScalarFunc ShaderGraph::scalar_func_node_get_function(ShaderType p_ return ScalarFunc(func); } +void ShaderGraph::default_set_value(ShaderGraph::ShaderType p_which, int p_id, int p_param, const Variant &p_value) +{ + ERR_FAIL_INDEX(p_which,3); + ERR_FAIL_COND(!shader[p_which].node_map.has(p_id)); + Node& n = shader[p_which].node_map[p_id]; + if(p_value.get_type()==Variant::NIL) + n.defaults.erase(n.defaults.find(p_param)); + else + n.defaults[p_param]=p_value; + + _request_update(); + +} + +Variant ShaderGraph::default_get_value(ShaderGraph::ShaderType p_which, int p_id, int p_param) +{ + ERR_FAIL_INDEX_V(p_which,3,Variant()); + ERR_FAIL_COND_V(!shader[p_which].node_map.has(p_id),Variant()); + const Node& n = shader[p_which].node_map[p_id]; + + if (!n.defaults.has(p_param)) + return Variant(); + return n.defaults[p_param]; +} + + + void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc p_func){ ERR_FAIL_INDEX(p_type,3); @@ -980,52 +1083,52 @@ ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type, void ShaderGraph::color_ramp_node_set_ramp(ShaderType p_type,int p_id,const DVector<Color>& p_colors, const DVector<real_t>& p_offsets){ - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_colors; - n.param2=p_offsets; - _request_update(); + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_colors; + n.param2=p_offsets; + _request_update(); } DVector<Color> ShaderGraph::color_ramp_node_get_colors(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector<Color>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Color>()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; + ERR_FAIL_INDEX_V(p_type,3,DVector<Color>()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Color>()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; } DVector<real_t> ShaderGraph::color_ramp_node_get_offsets(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector<real_t>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<real_t>()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param2; + ERR_FAIL_INDEX_V(p_type,3,DVector<real_t>()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<real_t>()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param2; } void ShaderGraph::curve_map_node_set_points(ShaderType p_type,int p_id,const DVector<Vector2>& p_points) { - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_points; - _request_update(); + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_points; + _request_update(); } DVector<Vector2> ShaderGraph::curve_map_node_get_points(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector<Vector2>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Vector2>()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; + ERR_FAIL_INDEX_V(p_type,3,DVector<Vector2>()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Vector2>()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; } @@ -1215,6 +1318,12 @@ Variant ShaderGraph::node_get_state(ShaderType p_type,int p_id) const { s["pos"]=n.pos; s["param1"]=n.param1; s["param2"]=n.param2; + Array keys; + for (Map<int,Variant>::Element *E=n.defaults.front();E;E=E->next()) { + keys.append(E->key()); + s[E->key()]=E->get(); + } + s["default_keys"]=keys; return s; } @@ -1227,10 +1336,15 @@ void ShaderGraph::node_set_state(ShaderType p_type,int p_id,const Variant& p_sta ERR_FAIL_COND(!d.has("pos")); ERR_FAIL_COND(!d.has("param1")); ERR_FAIL_COND(!d.has("param2")); + ERR_FAIL_COND(!d.has("default_keys")); + n.pos=d["pos"]; n.param1=d["param1"]; n.param2=d["param2"]; - + Array keys = d["default_keys"]; + for(int i=0;i<keys.size();i++) { + n.defaults[keys[i]]=d[keys[i]]; + } } ShaderGraph::ShaderGraph(Mode p_mode) : Shader(p_mode) { @@ -1735,17 +1849,17 @@ void ShaderGraph::_update_shader() { Vector<String> inputs; int max = get_node_input_slot_count(get_mode(),ShaderType(i),n->type); for(int k=0;k<max;k++) { + String iname; if (!n->connections.has(k)) { - shader[i].error=GRAPH_ERROR_MISSING_CONNECTIONS; - failed=true; - break; + iname="nd"+itos(n->id)+"sl"+itos(k)+"def"; + } else { + iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot); + if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT) { + inputs_used.insert(iname); + } + } - String iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot); inputs.push_back(iname); - if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT) { - inputs_used.insert(iname); - } - } if (failed) @@ -1874,27 +1988,27 @@ void ShaderGraph::_plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector }; for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) + { + for (j = 0; j < 4; j++) { tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] + - CR_basis[i][1] * geometry[1][j] + - CR_basis[i][2] * geometry[2][j] + - CR_basis[i][3] * geometry[3][j]); + CR_basis[i][1] * geometry[1][j] + + CR_basis[i][2] * geometry[2][j] + + CR_basis[i][3] * geometry[3][j]); + } } - } /* compose the above results to get the deltas matrix */ for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) + { + for (j = 0; j < 4; j++) { deltas[i][j] = (tmp2[i][0] * tmp1[0][j] + - tmp2[i][1] * tmp1[1][j] + - tmp2[i][2] * tmp1[2][j] + - tmp2[i][3] * tmp1[3][j]); + tmp2[i][1] * tmp1[1][j] + + tmp2[i][2] * tmp1[2][j] + + tmp2[i][3] * tmp1[3][j]); + } } - } /* extract the x deltas */ @@ -1951,6 +2065,31 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str const char *typestr[4]={"float","vec3","mat4","texture"}; #define OUTNAME(id,slot) (String(typestr[get_node_output_slot_type(get_mode(),p_type,p_node->type,slot)])+" "+("nd"+itos(id)+"sl"+itos(slot))) #define OUTVAR(id,slot) ("nd"+itos(id)+"sl"+itos(slot)) +#define DEF_VEC(slot)\ + if (p_inputs[slot].ends_with("def")){\ + Vector3 v = p_node->defaults[slot];\ + code+=String(typestr[1])+" "+p_inputs[slot]+"=vec3("+v+");\n";\ + } +#define DEF_SCALAR(slot)\ + if (p_inputs[slot].ends_with("def")){\ + double v = p_node->defaults[slot];\ + code+=String(typestr[0])+" "+p_inputs[slot]+"="+rtos(v)+";\n";\ + } +#define DEF_COLOR(slot)\ + if (p_inputs[slot].ends_with("def")){\ + Color col = p_node->defaults[slot];\ + code+=String(typestr[1])+" "+p_inputs[slot]+"=vec3("+rtos(col.r)+","+rtos(col.g)+","+rtos(col.b)+");\n";\ + } +#define DEF_MATRIX(slot) \ + if (p_inputs[slot].ends_with("def")){\ + Transform xf = p_node->defaults[slot]; \ + code+=String(typestr[3])+" "+p_inputs[slot]+"=mat4(\n";\ + code+="\tvec4(vec3("+rtos(xf.basis.get_axis(0).x)+","+rtos(xf.basis.get_axis(0).y)+","+rtos(xf.basis.get_axis(0).z)+"),0),\n";\ + code+="\tvec4(vec3("+rtos(xf.basis.get_axis(1).x)+","+rtos(xf.basis.get_axis(1).y)+","+rtos(xf.basis.get_axis(1).z)+"),0),\n";\ + code+="\tvec4(vec3("+rtos(xf.basis.get_axis(2).x)+","+rtos(xf.basis.get_axis(2).y)+","+rtos(xf.basis.get_axis(2).z)+"),0),\n";\ + code+="\tvec4(vec3("+rtos(xf.origin.x)+","+rtos(xf.origin.y)+","+rtos(xf.origin.z)+"),1)\n";\ + code+=");\n";\ + } switch(p_node->type) { @@ -1987,9 +2126,12 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str code+=OUTNAME(p_node->id,0)+"=TIME;\n"; }break; case NODE_SCREEN_TEX: { + DEF_VEC(0); code+=OUTNAME(p_node->id,0)+"=texscreen("+p_inputs[0]+".xy);\n"; }break; case NODE_SCALAR_OP: { + DEF_SCALAR(0); + DEF_SCALAR(1); int op = p_node->param1; String optxt; switch(op) { @@ -2009,6 +2151,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_VEC_OP: { + DEF_VEC(0); + DEF_VEC(1); int op = p_node->param1; String optxt; switch(op) { @@ -2026,6 +2170,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_VEC_SCALAR_OP: { + DEF_VEC(0); + DEF_SCALAR(1); int op = p_node->param1; String optxt; switch(op) { @@ -2037,6 +2183,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_RGB_OP: { + DEF_COLOR(0); + DEF_COLOR(1); int op = p_node->param1; static const char*axisn[3]={"x","y","z"}; @@ -2048,7 +2196,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str case RGB_OP_DIFFERENCE: { code += OUTNAME(p_node->id,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"; - + print_line(OUTNAME(p_node->id,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"); } break; case RGB_OP_DARKEN: { @@ -2119,11 +2267,15 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str } }break; case NODE_XFORM_MULT: { + DEF_MATRIX(0); + DEF_MATRIX(1); code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*"+p_inputs[1]+";\n"; }break; case NODE_XFORM_VEC_MULT: { + DEF_MATRIX(0); + DEF_VEC(1); bool no_translation = p_node->param1; if (no_translation) { @@ -2134,6 +2286,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_XFORM_VEC_INV_MULT: { + DEF_VEC(0); + DEF_MATRIX(1); bool no_translation = p_node->param1; if (no_translation) { code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",0)).xyz;\n"; @@ -2142,6 +2296,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str } }break; case NODE_SCALAR_FUNC: { + DEF_SCALAR(0); static const char*scalar_func_id[SCALAR_MAX_FUNC]={ "sin($)", "cos($)", @@ -2171,6 +2326,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str } break; case NODE_VEC_FUNC: { + DEF_VEC(0); static const char*vec_func_id[VEC_MAX_FUNC]={ "normalize($)", "max(min($,vec3(1,1,1)),vec3(0,0,0))", @@ -2208,44 +2364,63 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str } }break; case NODE_VEC_LEN: { + DEF_VEC(0); code += OUTNAME(p_node->id,0)+"=length("+p_inputs[0]+");\n"; }break; case NODE_DOT_PROD: { + DEF_VEC(0); + DEF_VEC(1); code += OUTNAME(p_node->id,0)+"=dot("+p_inputs[1]+","+p_inputs[0]+");\n"; }break; case NODE_VEC_TO_SCALAR: { + DEF_VEC(0); code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n"; code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n"; code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n"; }break; case NODE_SCALAR_TO_VEC: { + DEF_SCALAR(0); + DEF_SCALAR(1); + DEF_SCALAR(2); code += OUTNAME(p_node->id,0)+"=vec3("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+""+");\n"; }break; case NODE_VEC_TO_XFORM: { + DEF_VEC(0); + DEF_VEC(1); + DEF_VEC(2); + DEF_VEC(3); code += OUTNAME(p_node->id,0)+"=xform("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+","+","+p_inputs[3]+");\n"; }break; case NODE_XFORM_TO_VEC: { + DEF_MATRIX(0); code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n"; code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n"; code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n"; code += OUTNAME(p_node->id,3)+"="+p_inputs[0]+".o;\n"; }break; case NODE_SCALAR_INTERP: { + DEF_SCALAR(0); + DEF_SCALAR(1); + DEF_SCALAR(2); code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; }break; case NODE_VEC_INTERP: { + DEF_VEC(0); + DEF_VEC(1); + DEF_SCALAR(2); code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; }break; case NODE_COLOR_RAMP: { + DEF_SCALAR(0); static const int color_ramp_len=512; DVector<uint8_t> cramp; @@ -2302,6 +2477,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_CURVE_MAP: { + DEF_SCALAR(0); static const int curve_map_len=256; bool mapped[256]; zeromem(mapped,sizeof(mapped)); @@ -2369,6 +2545,9 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_SCALAR_INPUT: { + DEF_SCALAR(0); + DEF_SCALAR(1); + DEF_SCALAR(2); String name = p_node->param1; float dv=p_node->param2; code +="uniform float "+name+"="+rtos(dv)+";\n"; @@ -2406,6 +2585,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_TEXTURE_INPUT: { + DEF_VEC(0); String name = p_node->param1; String rname="rt_read_tex"+itos(p_node->id); code +="uniform texture "+name+";"; @@ -2415,7 +2595,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str }break; case NODE_CUBEMAP_INPUT: { - + DEF_VEC(0); String name = p_node->param1; code +="uniform cubemap "+name+";"; String rname="rt_read_tex"+itos(p_node->id); @@ -2424,6 +2604,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str code += OUTNAME(p_node->id,1)+"="+rname+".a;\n"; }break; case NODE_DEFAULT_TEXTURE: { + DEF_VEC(0); if (get_mode()==MODE_CANVAS_ITEM && p_type==SHADER_TYPE_FRAGMENT) { diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index fd6540a747..f867ae0388 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -68,7 +68,7 @@ public: NODE_VEC_INTERP, // vec3 interpolation (with optional curve) NODE_COLOR_RAMP, //take scalar, output vec3 NODE_CURVE_MAP, //take scalar, otput scalar - NODE_SCALAR_INPUT, // scalar uniform (assignable in material) + NODE_SCALAR_INPUT, // scalar uniform (assignable in material) NODE_VEC_INPUT, // vec3 uniform (assignable in material) NODE_RGB_INPUT, // color uniform (assignable in material) NODE_XFORM_INPUT, // mat4 uniform (assignable in material) @@ -120,6 +120,7 @@ private: String _find_unique_name(const String& p_base); + enum {SLOT_DEFAULT_VALUE = 0x7FFFFFFF}; struct SourceSlot { int id; @@ -135,6 +136,7 @@ private: NodeType type; Variant param1; Variant param2; + Map<int, Variant> defaults; int id; mutable int order; // used for sorting int sort_order; @@ -216,6 +218,10 @@ public: 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; + void duplicate_nodes(ShaderType p_which, List<int> &p_nodes); + + List<int> generate_ids(ShaderType p_type, int count); + enum ScalarOp { SCALAR_OP_ADD, SCALAR_OP_SUB, @@ -314,6 +320,9 @@ public: VEC_MAX_FUNC }; + void default_set_value(ShaderType p_which,int p_id,int p_param, const Variant& p_value); + Variant default_get_value(ShaderType p_which,int p_id,int p_param); + void vec_func_node_set_function(ShaderType p_which,int p_id,VecFunc p_func); VecFunc vec_func_node_get_function(ShaderType p_which,int p_id) const; @@ -354,6 +363,8 @@ public: void get_node_connections(ShaderType p_which,List<Connection> *p_connections) const; + bool is_slot_connected(ShaderType p_which,int p_dst_id,int slot_id); + void clear(ShaderType p_which); Variant node_get_state(ShaderType p_type, int p_node) const; @@ -361,6 +372,8 @@ public: GraphError get_graph_error(ShaderType p_type) const; + int node_count(ShaderType p_which, int p_type); + static int get_type_input_count(NodeType p_type); static int get_type_output_count(NodeType p_type); static SlotType get_type_input_type(NodeType p_type,int p_idx); |