summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAnton Yabchinskiy <arn@bestmx.ru>2015-01-05 23:56:24 +0300
committerAnton Yabchinskiy <arn@bestmx.ru>2015-01-05 23:56:24 +0300
commita7875c586af74302584544d777b189f4cb85c393 (patch)
treef4929f77383d835b5be8b6e099b9db59000af610 /tools
parent4ab1bcde35a02cfe7b25d630720de1cc81ef5a1a (diff)
parent8c4dd8de3919b789eac1a0f030563008bdcd44f5 (diff)
Merge branch 'master' of github.com:okamstudio/godot
Diffstat (limited to 'tools')
-rw-r--r--tools/SCsub17
-rw-r--r--tools/doc/doc_data.cpp6
-rw-r--r--tools/editor/animation_editor.cpp10
-rw-r--r--tools/editor/animation_editor.h4
-rw-r--r--tools/editor/code_editor.cpp14
-rw-r--r--tools/editor/editor_help.cpp4
-rw-r--r--tools/editor/editor_import_export.cpp12
-rw-r--r--tools/editor/editor_log.cpp4
-rw-r--r--tools/editor/editor_log.h4
-rw-r--r--tools/editor/editor_node.cpp20
-rw-r--r--tools/editor/editor_node.h4
-rw-r--r--tools/editor/editor_settings.cpp3
-rw-r--r--tools/editor/icons/icon_canvas_item_shader.pngbin0 -> 568 bytes
-rw-r--r--tools/editor/icons/icon_canvas_item_shader_graph.pngbin0 -> 575 bytes
-rw-r--r--tools/editor/icons/icon_material_shader.pngbin0 -> 844 bytes
-rw-r--r--tools/editor/icons/icon_material_shader_graph.pngbin0 -> 949 bytes
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp14
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.h6
-rw-r--r--tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/item_list_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/shader_graph_editor_plugin.cpp2041
-rw-r--r--tools/editor/plugins/shader_graph_editor_plugin.h171
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp25
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.h6
-rw-r--r--tools/editor/plugins/tile_map_editor_plugin.cpp54
-rw-r--r--tools/editor/plugins/tile_map_editor_plugin.h13
-rw-r--r--tools/editor/progress_dialog.cpp6
-rw-r--r--tools/editor/project_export.cpp4
-rw-r--r--tools/editor/project_export.h2
-rw-r--r--tools/editor/project_manager.cpp6
-rw-r--r--tools/editor/property_editor.cpp85
-rw-r--r--tools/editor/property_editor.h4
34 files changed, 1520 insertions, 1030 deletions
diff --git a/tools/SCsub b/tools/SCsub
index 875663b849..4d8b05fe79 100644
--- a/tools/SCsub
+++ b/tools/SCsub
@@ -5,13 +5,16 @@ env.add_source_files(env.tool_sources,"*.cpp")
Export('env')
-SConscript('editor/SCsub');
-#SConscript('scintilla/SCsub');
-SConscript('collada/SCsub');
-SConscript('docdump/SCsub');
-SConscript('freetype/SCsub');
-SConscript('doc/SCsub');
-SConscript('pck/SCsub');
+if (env["tools"]!="no"):
+ SConscript('editor/SCsub');
+ #SConscript('scintilla/SCsub');
+ SConscript('collada/SCsub');
+ SConscript('docdump/SCsub');
+ SConscript('freetype/SCsub');
+ SConscript('doc/SCsub')
+ SConscript('pck/SCsub')
+
+
lib = env.Library("tool",env.tool_sources)
diff --git a/tools/doc/doc_data.cpp b/tools/doc/doc_data.cpp
index d13c7ea73c..75759e7d30 100644
--- a/tools/doc/doc_data.cpp
+++ b/tools/doc/doc_data.cpp
@@ -186,8 +186,10 @@ void DocData::generate(bool p_basic_types) {
arginfo=E->get().return_val;
if (arginfo.type==Variant::NIL)
continue;
-
- method.return_type=(arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE)?arginfo.hint_string:Variant::get_type_name(arginfo.type);
+ if (m && m->get_return_type()!=StringName())
+ method.return_type=m->get_return_type();
+ else
+ method.return_type=(arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE)?arginfo.hint_string:Variant::get_type_name(arginfo.type);
} else {
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index 95f9ee6509..db70a2675a 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -2909,11 +2909,11 @@ void AnimationKeyEditor::set_anim_pos(float p_pos) {
void AnimationKeyEditor::_pane_drag(const Point2& p_delta) {
- Size2 ecs = ec->get_minsize();
+ Size2 ecs = ec->get_custom_minimum_size();
ecs.y-=p_delta.y;
if (ecs.y<100)
ecs.y=100;
- ec->set_minsize(ecs);;
+ ec->set_custom_minimum_size(ecs);;
}
@@ -3238,7 +3238,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
move_down_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_MOVE_DOWN));
move_down_button->set_focus_mode(FOCUS_NONE);
move_down_button->set_disabled(true);
- move_down_button->set_tooltip("Move current track dosn.");
+ move_down_button->set_tooltip("Move current track down.");
remove_button = memnew( ToolButton );
hb->add_child(remove_button);
@@ -3296,8 +3296,8 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
// menu->get_popup()->connect("item_pressed",this,"_menu_callback");
- ec = memnew (EmptyControl);
- ec->set_minsize(Size2(0,50));
+ ec = memnew (Control);
+ ec->set_custom_minimum_size(Size2(0,50));
add_child(ec);
ec->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 9d3e692fad..1f17922552 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -37,7 +37,7 @@
#include "scene/gui/scroll_bar.h"
#include "scene/gui/tool_button.h"
#include "scene/gui/file_dialog.h"
-#include "scene/gui/empty_control.h"
+
#include "scene/resources/animation.h"
#include "scene/animation/animation_cache.h"
#include "scene_tree_editor.h"
@@ -157,7 +157,7 @@ class AnimationKeyEditor : public VBoxContainer {
PopupMenu *track_menu;
PopupMenu *type_menu;
- EmptyControl *ec;
+ Control *ec;
TextureFrame *zoomicon;
HSlider *zoom;
//MenuButton *menu;
diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp
index 242654c472..2209b24245 100644
--- a/tools/editor/code_editor.cpp
+++ b/tools/editor/code_editor.cpp
@@ -599,7 +599,19 @@ CodeTextEditor::CodeTextEditor() {
add_child(text_editor);
text_editor->set_area_as_parent_rect();
text_editor->set_margin(MARGIN_BOTTOM,20);
- text_editor->add_font_override("font",get_font("source","Fonts"));
+
+ String editor_font = EDITOR_DEF("text_editor/font", "");
+ bool font_overrode = false;
+ if (editor_font!="") {
+ Ref<Font> fnt = ResourceLoader::load(editor_font);
+ if (fnt.is_valid()) {
+ text_editor->add_font_override("font",fnt);
+ font_overrode = true;
+ }
+ }
+
+ if (!font_overrode)
+ text_editor->add_font_override("font",get_font("source","Fonts"));
text_editor->set_show_line_numbers(true);
text_editor->set_brace_matching(true);
diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp
index 8408436a6c..2283a2df14 100644
--- a/tools/editor/editor_help.cpp
+++ b/tools/editor/editor_help.cpp
@@ -1361,8 +1361,8 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
Separator *hs = memnew( VSeparator );
panel_hb->add_child(hs);
- EmptyControl *ec = memnew( EmptyControl );
- ec->set_minsize(Size2(200,1));
+ Control *ec = memnew( Control );
+ ec->set_custom_minimum_size(Size2(200,1));
panel_hb->add_child(ec);
search = memnew( LineEdit );
ec->add_child(search);
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index a511e78863..58f9afaa5d 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -292,7 +292,11 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
_add_filter_to_list(exported,"*");
} else {
_add_to_list(EditorFileSystem::get_singleton()->get_filesystem(),exported);
- _add_filter_to_list(exported,EditorImportExport::get_singleton()->get_export_custom_filter());
+ String cf = EditorImportExport::get_singleton()->get_export_custom_filter();
+ if (cf!="")
+ cf+=",";
+ cf+="*.flags";
+ _add_filter_to_list(exported,cf);
}
@@ -361,8 +365,12 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
}
}
}
+ String cf = EditorImportExport::get_singleton()->get_export_custom_filter();
+ if (cf!="")
+ cf+=",";
+ cf+="*.flags";
+ _add_filter_to_list(exported,cf);
- _add_filter_to_list(exported,EditorImportExport::get_singleton()->get_export_custom_filter());
}
diff --git a/tools/editor/editor_log.cpp b/tools/editor/editor_log.cpp
index f7f5f596d7..7c3fa6c1bd 100644
--- a/tools/editor/editor_log.cpp
+++ b/tools/editor/editor_log.cpp
@@ -203,9 +203,9 @@ EditorLog::EditorLog() {
tb->connect("pressed",this,"_close_request");
- ec = memnew( EmptyControl);
+ ec = memnew( Control);
vb->add_child(ec);
- ec->set_minsize(Size2(0,100));
+ ec->set_custom_minimum_size(Size2(0,100));
ec->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/tools/editor/editor_log.h b/tools/editor/editor_log.h
index b6cd951287..27cce4a584 100644
--- a/tools/editor/editor_log.h
+++ b/tools/editor/editor_log.h
@@ -33,7 +33,7 @@
#include "scene/gui/label.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/texture_button.h"
-#include "scene/gui/empty_control.h"
+//#include "scene/gui/empty_control.h"
#include "scene/gui/box_container.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/texture_frame.h"
@@ -50,7 +50,7 @@ class EditorLog : public PanelContainer {
TextureButton *tb;
HBoxContainer *title_hb;
// PaneDrag *pd;
- EmptyControl *ec;
+ Control *ec;
static void _error_handler(void *p_self, const char*p_func, const char*p_file,int p_line, const char*p_error,const char*p_errorexp,ErrorHandlerType p_type);
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index dbc896cbb9..5843a7cb28 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -75,6 +75,7 @@
#include "plugins/tile_map_editor_plugin.h"
#include "plugins/cube_grid_theme_editor_plugin.h"
#include "plugins/shader_editor_plugin.h"
+#include "plugins/shader_graph_editor_plugin.h"
#include "plugins/path_editor_plugin.h"
#include "plugins/rich_text_editor_plugin.h"
#include "plugins/collision_polygon_editor_plugin.h"
@@ -3245,7 +3246,7 @@ EditorNode::EditorNode() {
gui_base->set_area_as_parent_rect();
- Ref<Theme> theme( memnew( Theme ) );
+ theme = Ref<Theme>( memnew( Theme ) );
gui_base->set_theme( theme );
editor_register_icons(theme);
editor_register_fonts(theme);
@@ -3308,13 +3309,13 @@ EditorNode::EditorNode() {
main_editor_tabs->connect("tab_changed",this,"_editor_select");
HBoxContainer *srth = memnew( HBoxContainer );
srt->add_child( srth );
- EmptyControl *tec = memnew( EmptyControl );
- tec->set_minsize(Size2(100,0));
+ Control *tec = memnew( Control );
+ tec->set_custom_minimum_size(Size2(100,0));
tec->set_h_size_flags(Control::SIZE_EXPAND_FILL);
srth->add_child(tec);
srth->add_child(main_editor_tabs);
- tec = memnew( EmptyControl );
- tec->set_minsize(Size2(100,0));
+ tec = memnew( Control );
+ tec->set_custom_minimum_size(Size2(100,0));
srth->add_child(tec);
tec->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -3674,8 +3675,8 @@ EditorNode::EditorNode() {
top_pallete->add_child(resources_dock);
top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- EmptyControl *editor_spacer = memnew( EmptyControl );
- editor_spacer->set_minsize(Size2(260,200));
+ Control *editor_spacer = memnew( Control );
+ editor_spacer->set_custom_minimum_size(Size2(260,200));
editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor_vsplit->add_child( editor_spacer );
editor_spacer->add_child( top_pallete );
@@ -3686,8 +3687,8 @@ EditorNode::EditorNode() {
prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor_spacer = memnew( EmptyControl );
- editor_spacer->set_minsize(Size2(260,200));
+ editor_spacer = memnew( Control );
+ editor_spacer->set_custom_minimum_size(Size2(260,200));
editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor_vsplit->add_child( editor_spacer );
editor_spacer->add_child( prop_pallete );
@@ -4016,6 +4017,7 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( ScriptEditorPlugin(this) ) );
add_editor_plugin( memnew( EditorHelpPlugin(this) ) );
add_editor_plugin( memnew( AnimationPlayerEditorPlugin(this) ) );
+ add_editor_plugin( memnew( ShaderGraphEditorPlugin(this) ) );
add_editor_plugin( memnew( ShaderEditorPlugin(this) ) );
add_editor_plugin( memnew( CameraEditorPlugin(this) ) );
add_editor_plugin( memnew( SampleEditorPlugin(this) ) );
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 7b66a7809e..381993646e 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -212,6 +212,7 @@ class EditorNode : public Node {
AcceptDialog *load_error_dialog;
Control *scene_root_base;
+ Ref<Theme> theme;
PopupMenu *recent_scenes;
Button *property_back;
@@ -472,6 +473,9 @@ public:
void stop_child_process();
+ Ref<Theme> get_editor_theme() const { return theme; }
+
+
Error export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after=false);
static void register_editor_types();
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index 8b0fd204e3..bc800d7e9e 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -419,6 +419,8 @@ void EditorSettings::_load_defaults() {
set("3d_editor/navigation_scheme",0);
hints["3d_editor/navigation_scheme"]=PropertyInfo(Variant::INT,"3d_editor/navigation_scheme",PROPERTY_HINT_ENUM,"Godot,Maya,Modo");
+ set("3d_editor/zoom_style",0);
+ hints["3d_editor/zoom_style"]=PropertyInfo(Variant::INT,"3d_editor/zoom_style",PROPERTY_HINT_ENUM,"Vertical, Horizontal");
set("3d_editor/orbit_modifier",0);
hints["3d_editor/orbit_modifier"]=PropertyInfo(Variant::INT,"3d_editor/orbit_modifier",PROPERTY_HINT_ENUM,"None,Shift,Alt,Meta,Ctrl");
set("3d_editor/pan_modifier",1);
@@ -444,6 +446,7 @@ void EditorSettings::_load_defaults() {
set("animation/confirm_insert_track",true);
set("property_editor/texture_preview_width",48);
+ set("property_editor/auto_refresh_interval",0.3);
set("help/doc_path","");
set("import/ask_save_before_reimport",false);
diff --git a/tools/editor/icons/icon_canvas_item_shader.png b/tools/editor/icons/icon_canvas_item_shader.png
new file mode 100644
index 0000000000..a5f4e7bf85
--- /dev/null
+++ b/tools/editor/icons/icon_canvas_item_shader.png
Binary files differ
diff --git a/tools/editor/icons/icon_canvas_item_shader_graph.png b/tools/editor/icons/icon_canvas_item_shader_graph.png
new file mode 100644
index 0000000000..bba966b43e
--- /dev/null
+++ b/tools/editor/icons/icon_canvas_item_shader_graph.png
Binary files differ
diff --git a/tools/editor/icons/icon_material_shader.png b/tools/editor/icons/icon_material_shader.png
new file mode 100644
index 0000000000..0e476b2540
--- /dev/null
+++ b/tools/editor/icons/icon_material_shader.png
Binary files differ
diff --git a/tools/editor/icons/icon_material_shader_graph.png b/tools/editor/icons/icon_material_shader_graph.png
new file mode 100644
index 0000000000..68d8b4cb49
--- /dev/null
+++ b/tools/editor/icons/icon_material_shader_graph.png
Binary files differ
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 8bb37f1d71..f706d67f6d 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -76,6 +76,8 @@ void AnimationPlayerEditor::_notification(int p_what) {
seek->set_val(player->get_current_animation_pos());
if (edit_anim->is_pressed())
editor->get_animation_editor()->set_anim_pos(player->get_current_animation_pos());
+ EditorNode::get_singleton()->get_property_editor()->refresh();
+
} else if (last_active) {
//need the last frame after it stopped
@@ -854,6 +856,8 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos) {
return;
seek->set_val(p_pos);
+ EditorNode::get_singleton()->get_property_editor()->refresh();
+
//seekit
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index 599160eb46..482340ca00 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2307,7 +2307,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case ANIM_INSERT_ROT: {
- key_pos = key_rot_button->is_pressed();
+ key_rot = key_rot_button->is_pressed();
} break;
case ANIM_INSERT_SCALE: {
@@ -2683,6 +2683,11 @@ void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
hb->add_child(p_control);
}
+HSplitContainer *CanvasItemEditor::get_palette_split() {
+
+ return palette_split;
+}
+
CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
tool = TOOL_SELECT;
@@ -2697,15 +2702,20 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
add_child( hb );
hb->set_area_as_parent_rect();
+ palette_split = memnew( HSplitContainer);
+ palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(palette_split);
+
Control *vp_base = memnew (Control);
- add_child(vp_base);
vp_base->set_v_size_flags(SIZE_EXPAND_FILL);
+ palette_split->add_child(vp_base);
Control *vp = memnew (Control);
vp_base->add_child(vp);
vp->set_area_as_parent_rect();
vp->add_child(p_editor->get_scene_root());
+
viewport = memnew( Control );
vp_base->add_child(viewport);
viewport->set_area_as_parent_rect();
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h
index 15ac7b1bb3..c56570d43f 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.h
+++ b/tools/editor/plugins/canvas_item_editor_plugin.h
@@ -289,6 +289,10 @@ class CanvasItemEditor : public VBoxContainer {
void _viewport_input_event(const InputEvent& p_event);
void _viewport_draw();
+
+private:
+ HSplitContainer *palette_split;
+
friend class CanvasItemEditorPlugin;
protected:
@@ -341,6 +345,8 @@ public:
void add_control_to_menu_panel(Control *p_control);
+ HSplitContainer *get_palette_split();
+
Control *get_viewport_control() { return viewport; }
diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index 6bae0d2fd0..ed228e9a1c 100644
--- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -398,11 +398,13 @@ CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) {
add_child(button_create);
button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE));
button_create->set_toggle_mode(true);
+ button_create->set_tooltip("Create a new polygon from scratch");
button_edit = memnew( ToolButton );
add_child(button_edit);
button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT));
button_edit->set_toggle_mode(true);
+ button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point.");
//add_constant_override("separation",0);
diff --git a/tools/editor/plugins/item_list_editor_plugin.cpp b/tools/editor/plugins/item_list_editor_plugin.cpp
index eb7ab69987..a8b34ef503 100644
--- a/tools/editor/plugins/item_list_editor_plugin.cpp
+++ b/tools/editor/plugins/item_list_editor_plugin.cpp
@@ -210,6 +210,7 @@ void ItemListEditor::_bind_methods() {
}
bool ItemListEditor::handles(Object *p_object) const {
+ return false;
for(int i=0;i<item_plugins.size();i++) {
if (item_plugins[i]->handles(p_object)) {
return true;
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 2e5f267d5c..439d8273c7 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -1602,7 +1602,11 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
edit_menu->get_popup()->add_item("Toggle Comment",EDIT_TOGGLE_COMMENT,KEY_MASK_CMD|KEY_K);
edit_menu->get_popup()->add_item("Clone Down",EDIT_CLONE_DOWN,KEY_MASK_CMD|KEY_B);
edit_menu->get_popup()->add_separator();
+#ifdef OSX_ENABLED
+ edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_META|KEY_SPACE);
+#else
edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_CMD|KEY_SPACE);
+#endif
edit_menu->get_popup()->add_item("Auto Indent",EDIT_AUTO_INDENT,KEY_MASK_CMD|KEY_I);
edit_menu->get_popup()->connect("item_pressed", this,"_menu_option");
diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp
index 2686ca895e..710f11e726 100644
--- a/tools/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp
@@ -28,1082 +28,1427 @@
/*************************************************************************/
#include "shader_graph_editor_plugin.h"
-#if 0
+
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
+#include "spatial_editor_plugin.h"
+
+////cbacks
+///
+void ShaderGraphView::_scalar_const_changed(double p_value,int p_id) {
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Scalar Constant",true);
+ ur->add_do_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,p_value);
+ ur->add_undo_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,graph->scalar_const_node_get_value(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
-class _ShaderTester : public ShaderCodeGenerator {
-public:
-
- Set<int> *_set;
-
- virtual void begin() {}
- virtual Error add_node(VS::ShaderNodeType p_type,int p_node_pos,int p_id,const Variant& p_param,const Vector<int>& p_in_connections,const Vector<int>& p_out_connections,const Vector<int>& p_out_connection_outputs) { if (_set) _set->insert(p_id); return OK; }
- virtual void end() {}
-
- _ShaderTester() { _set=NULL; }
-};
+void ShaderGraphView::_vec_const_changed(double p_value, int p_id,Array p_arr){
+ Vector3 val;
+ for(int i=0;i<p_arr.size();i++) {
+ val[i]=p_arr[i].call("get_val");
+ }
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Vec Constant",true);
+ ur->add_do_method(graph.ptr(),"vec_const_node_set_value",type,p_id,val);
+ ur->add_undo_method(graph.ptr(),"vec_const_node_set_value",type,p_id,graph->vec_const_node_get_value(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
-void ShaderEditor::edit(Ref<Shader> p_shader) {
+}
+void ShaderGraphView::_rgb_const_changed(const Color& p_color, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change RGB Constant",true);
+ ur->add_do_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,p_color);
+ ur->add_undo_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,graph->rgb_const_node_get_value(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
+void ShaderGraphView::_scalar_op_changed(int p_op, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Scalar Operator");
+ ur->add_do_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,p_op);
+ ur->add_undo_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,graph->scalar_op_node_get_op(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
- shader=p_shader;
+}
+void ShaderGraphView::_vec_op_changed(int p_op, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Vec Operator");
+ ur->add_do_method(graph.ptr(),"vec_op_node_set_op",type,p_id,p_op);
+ ur->add_undo_method(graph.ptr(),"vec_op_node_set_op",type,p_id,graph->vec_op_node_get_op(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
+void ShaderGraphView::_vec_scalar_op_changed(int p_op, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change VecxScalar Operator");
+ ur->add_do_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,p_op);
+ ur->add_undo_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,graph->vec_scalar_op_node_get_op(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
- if (shader.is_null())
- hide();
- else {
- _read_shader_graph();
- }
+}
+void ShaderGraphView::_rgb_op_changed(int p_op, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change RGB Operator");
+ ur->add_do_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,p_op);
+ ur->add_undo_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,graph->rgb_op_node_get_op(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
+void ShaderGraphView::_xform_inv_rev_changed(bool p_enabled, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Toggle Rot Only");
+ ur->add_do_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,p_enabled);
+ ur->add_undo_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,graph->xform_vec_mult_node_get_no_translation(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
+void ShaderGraphView::_scalar_func_changed(int p_func, int p_id){
+
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Scalar Function");
+ ur->add_do_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,p_func);
+ ur->add_undo_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,graph->scalar_func_node_get_function(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
+void ShaderGraphView::_vec_func_changed(int p_func, int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Vec Function");
+ ur->add_do_method(graph.ptr(),"vec_func_node_set_function",type,p_id,p_func);
+ ur->add_undo_method(graph.ptr(),"vec_func_node_set_function",type,p_id,graph->vec_func_node_get_function(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
}
+void ShaderGraphView::_scalar_input_changed(double p_value,int p_id){
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Scalar Uniform",true);
+ ur->add_do_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,p_value);
+ ur->add_undo_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,graph->scalar_input_node_get_value(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
-Size2 ShaderEditor::_get_maximum_size() {
+}
+void ShaderGraphView::_vec_input_changed(double p_value, int p_id,Array p_arr){
- Size2 max;
+ Vector3 val;
+ for(int i=0;i<p_arr.size();i++) {
+ val[i]=p_arr[i].call("get_val");
+ }
- for(List<int>::Element *E=order.front();E;E=E->next()) {
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Vec Uniform",true);
+ ur->add_do_method(graph.ptr(),"vec_input_node_set_value",type,p_id,val);
+ ur->add_undo_method(graph.ptr(),"vec_input_node_set_value",type,p_id,graph->vec_input_node_get_value(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
- Point2 pos = Point2( shader_graph.node_get_pos_x(E->get()), shader_graph.node_get_pos_y(E->get()) );
+}
+void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){
- if (click_type==CLICK_NODE && click_node==E->get()) {
+ print_line("XFIC");
+ ToolButton *tb = p_button->cast_to<ToolButton>();
+ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
+ ped_popup->set_size(tb->get_size());
+ edited_id=p_id;
+ ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,"");
+ ped_popup->popup();
- pos+=click_motion-click_pos;
- }
- pos+=get_node_size(E->get());
- if (pos.x>max.x)
- max.x=pos.x;
- if (pos.y>max.y)
- max.y=pos.y;
+}
+void ShaderGraphView::_xform_const_changed(int p_id, Node *p_button){
- }
+ ToolButton *tb = p_button->cast_to<ToolButton>();
+ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
+ ped_popup->set_size(tb->get_size());
+ edited_id=p_id;
+ ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,"");
+ ped_popup->popup();
- return max;
}
-Size2 ShaderEditor::get_node_size(int p_node) const {
+void ShaderGraphView::_rgb_input_changed(const Color& p_color, int p_id){
- VisualServer::ShaderNodeType type=shader_graph.node_get_type(p_node);
- Ref<StyleBox> style = get_stylebox("panel","PopupMenu");
- Ref<Font> font = get_font("font","PopupMenu");
- Color font_color = get_color("font_color","PopupMenu");
- Size2 size = style->get_minimum_size();
-
- int count=1; // title
- count += VisualServer::shader_get_input_count( type) + VisualServer::shader_get_output_count( type);
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change RGB Uniform",true);
+ ur->add_do_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,p_color);
+ ur->add_undo_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,graph->rgb_input_node_get_value(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+}
+void ShaderGraphView::_tex_input_change(int p_id, Node *p_button){
- float max_w=font->get_string_size( VisualServer::shader_node_get_type_info(type).name ).width;
- for(int i=0;i<VisualServer::shader_get_input_count(type);i++)
- max_w = MAX( max_w, font->get_string_size( VisualServer::shader_get_input_name(type,i) ).width );
+}
+void ShaderGraphView::_cube_input_change(int p_id){
- for(int i=0;i<VisualServer::shader_get_output_count(type);i++)
- max_w = MAX( max_w, font->get_string_size( VisualServer::shader_get_output_name(type,i) ).width );
+}
+void ShaderGraphView::_variant_edited() {
+ if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) {
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change XForm Uniform");
+ ur->add_do_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,ped_popup->get_variant());
+ ur->add_undo_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,graph->xform_const_node_get_value(type,edited_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
+ }
- switch(type) {
- case VS::NODE_IN:
- case VS::NODE_OUT:
- case VS::NODE_VEC_IN:
- case VS::NODE_VEC_OUT:
- case VS::NODE_PARAMETER:
- case VS::NODE_VEC_PARAMETER:
- case VS::NODE_COLOR_PARAMETER:
- case VS::NODE_TEXTURE_PARAMETER:
- case VS::NODE_TEXTURE_2D_PARAMETER:
- case VS::NODE_TEXTURE_CUBE_PARAMETER:
- case VS::NODE_TRANSFORM_PARAMETER:
- case VS::NODE_LABEL: {
+ if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_INPUT) {
- max_w=MAX( max_w, font->get_string_size( shader_graph.node_get_param(p_node) ).width );
- count++;
- } break;
- case VS::NODE_TIME:
- case VS::NODE_CONSTANT:
- case VS::NODE_VEC_CONSTANT:
- case VS::NODE_COLOR_CONSTANT:
- case VS::NODE_TRANSFORM_CONSTANT: {
- count++;
- } break;
- case VS::NODE_TEXTURE:
- case VS::NODE_VEC_TEXTURE_2D:
- case VS::NODE_VEC_TEXTURE_CUBE: {
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change XForm Uniform");
+ ur->add_do_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,ped_popup->get_variant());
+ ur->add_undo_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,graph->xform_input_node_get_value(type,edited_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
+ }
- RefPtr res = shader_graph.node_get_param(p_node);
- Ref<Texture> texture = res;
- if (texture.is_null() || texture->get_width()==0) {
+ if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_TEXTURE_INPUT) {
- size.y+=max_w;
- } else {
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Texture Uniform");
+ ur->add_do_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,ped_popup->get_variant());
+ ur->add_undo_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,graph->texture_input_node_get_value(type,edited_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
+ }
- size.y+=max_w * texture->get_height() / texture->get_width();
- }
- } break;
- default: {}
+ if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_CUBEMAP_INPUT) {
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Cubemap Uniform");
+ ur->add_do_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,ped_popup->get_variant());
+ ur->add_undo_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,graph->cubemap_input_node_get_value(type,edited_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
}
- size.x+=max_w;
- size.y+=count*(font->get_height()+get_constant("vseparation","PopupMenu"));
-
- return size;
}
+void ShaderGraphView::_comment_edited(int p_id,Node* p_button) {
-Error ShaderEditor::validate_graph() {
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ TextEdit *te=p_button->cast_to<TextEdit>();
+ ur->create_action("Change Comment",true);
+ ur->add_do_method(graph.ptr(),"comment_node_set_text",type,p_id,te->get_text());
+ ur->add_undo_method(graph.ptr(),"comment_node_set_text",type,p_id,graph->comment_node_get_text(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
- _ShaderTester st;
- active_nodes.clear();
- st._set=&active_nodes;
- return shader_graph.generate(&st);
}
-void ShaderEditor::_draw_node(int p_node) {
- VisualServer::ShaderNodeType type=shader_graph.node_get_type(p_node);
- Ref<StyleBox> style = active_nodes.has(p_node)?get_stylebox("panel","PopupMenu"):get_stylebox("panel_disabled","PopupMenu");
- Ref<Font> font = get_font("font","PopupMenu");
- Color font_color = get_color("font_color","PopupMenu");
- Color font_color_title = get_color("font_color_hover","PopupMenu");
- Size2 size=get_node_size(p_node);
- Point2 pos = Point2( shader_graph.node_get_pos_x(p_node), shader_graph.node_get_pos_y(p_node) )-offset;
+void ShaderGraphView::_input_name_changed(const String& p_name, int p_id, Node *p_line_edit) {
- if (click_type==CLICK_NODE && click_node==p_node) {
+ LineEdit *le=p_line_edit->cast_to<LineEdit>();
+ ERR_FAIL_COND(!le);
- pos+=click_motion-click_pos;
- }
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Change Input Name");
+ ur->add_do_method(graph.ptr(),"input_node_set_name",type,p_id,p_name);
+ ur->add_undo_method(graph.ptr(),"input_node_set_name",type,p_id,graph->input_node_get_name(type,p_id));
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ block_update=true;
+ ur->commit_action();
+ block_update=false;
+ le->set_text(graph->input_node_get_name(type,p_id));
+}
- RID ci = get_canvas_item();
- style->draw(ci,Rect2(pos,size));
+void ShaderGraphView::_tex_edited(int p_id,Node* p_button) {
- Point2 ofs=style->get_offset()+pos;
- Point2 ascent=Point2(0,font->get_ascent());
- float w = size.width-style->get_minimum_size().width;
- float h = font->get_height()+get_constant("vseparation","PopupMenu");
+ ToolButton *tb = p_button->cast_to<ToolButton>();
+ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
+ ped_popup->set_size(tb->get_size());
+ edited_id=p_id;
+ ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture");
+}
- font->draw_halign( ci, ofs+ascent, HALIGN_CENTER,w, VisualServer::shader_node_get_type_info(type).name,font_color_title);
- ofs.y+=h;
+void ShaderGraphView::_cube_edited(int p_id,Node* p_button) {
- Ref<Texture> vec_icon = get_icon("NodeVecSlot","EditorIcons");
- Ref<Texture> real_icon = get_icon("NodeRealSlot","EditorIcons");
- float icon_h_ofs = Math::floor(( font->get_height()-vec_icon->get_height())/2.0 )+1;
+ ToolButton *tb = p_button->cast_to<ToolButton>();
+ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
+ ped_popup->set_size(tb->get_size());
+ edited_id=p_id;
+ ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap");
+}
- for(int i=0;i<VisualServer::shader_get_input_count(type);i++) {
+//////////////view/////////////
- String name = VisualServer::shader_get_input_name(type,i);
- font->draw_halign( ci, ofs+ascent, HALIGN_LEFT,w, name,font_color);
- Ref<Texture> icon = VisualServer::shader_is_input_vector(type,i)?vec_icon:real_icon;
- icon->draw(ci,ofs+Point2(-real_icon->get_width(),icon_h_ofs));
- ofs.y+=h;
- }
- for(int i=0;i<VisualServer::shader_get_output_count(type);i++) {
+void ShaderGraphView::_connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) {
- String name = VisualServer::shader_get_output_name(type,i);
- font->draw_halign( ci, ofs+ascent, HALIGN_RIGHT,w, name,font_color);
- Ref<Texture> icon = VisualServer::shader_is_output_vector(type,i)?vec_icon:real_icon;
- icon->draw(ci,ofs+Point2(w,icon_h_ofs));
- ofs.y+=h;
- }
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
- switch(type) {
-
- case VS::NODE_IN:
- case VS::NODE_OUT:
- case VS::NODE_PARAMETER:
- case VS::NODE_VEC_IN:
- case VS::NODE_COLOR_PARAMETER:
- case VS::NODE_VEC_OUT:
- case VS::NODE_TEXTURE_PARAMETER:
- case VS::NODE_TEXTURE_2D_PARAMETER:
- case VS::NODE_TEXTURE_CUBE_PARAMETER:
- case VS::NODE_TRANSFORM_CONSTANT:
- case VS::NODE_TRANSFORM_PARAMETER:
- case VS::NODE_VEC_PARAMETER:
- case VS::NODE_LABEL: {
- String text = shader_graph.node_get_param(p_node);
- font->draw_halign( ci, ofs+ascent, HALIGN_CENTER,w, text,font_color);
- } break;
- case VS::NODE_TIME:
- case VS::NODE_CONSTANT: {
- String text = rtos(shader_graph.node_get_param(p_node));
- font->draw_halign( ci, ofs+ascent, HALIGN_CENTER,w, text,font_color);
-
- } break;
- case VS::NODE_VEC_CONSTANT: {
- String text = Vector3(shader_graph.node_get_param(p_node));
- font->draw_halign( ci, ofs+ascent, HALIGN_CENTER,w, text,font_color);
- } break;
- case VS::NODE_COLOR_CONSTANT: {
-
- Color color = shader_graph.node_get_param(p_node);
- Rect2 r(ofs,Size2(w,h));
- VisualServer::get_singleton()->canvas_item_add_rect(ci,r,color);
- } break;
- case VS::NODE_TEXTURE:
- case VS::NODE_VEC_TEXTURE_2D:
- case VS::NODE_VEC_TEXTURE_CUBE: {
-
- Rect2 r(ofs,Size2(w,(pos.y+size.y-style->get_margin(MARGIN_BOTTOM))-ofs.y));
- Vector<Point2> points;
- Vector<Point2> uvs;
- points.resize(4);
- uvs.resize(4);
- points[0]=r.pos;
- points[1]=r.pos+Point2(r.size.x,0);
- points[2]=r.pos+r.size;
- points[3]=r.pos+Point2(0,r.size.y);
- uvs[0]=Point2(0,0);
- uvs[1]=Point2(1,0);
- uvs[2]=Point2(1,1);
- uvs[3]=Point2(0,1);
-
- Ref<Texture> texture = shader_graph.node_get_param(p_node).operator RefPtr();
- if (texture.is_null() || texture->get_width()==0) {
- texture=get_icon("Click2Edit","EditorIcons");
- }
+ int from_idx=-1;
+ int to_idx=-1;
+ for (Map<int,GraphNode*>::Element *E=node_map.front();E;E=E->next()) {
- VisualServer::get_singleton()->canvas_item_add_primitive(ci,points,Vector<Color>(),uvs,texture->get_rid());
- } break;
- default: {}
+ if (p_from==E->get()->get_name())
+ from_idx=E->key();
+ if (p_to==E->get()->get_name())
+ to_idx=E->key();
}
-}
-
-void ShaderEditor::_node_param_changed() {
-
- shader_graph.node_set_param( click_node,property_editor->get_variant() );
- update();
- _write_shader_graph();
-}
-
-ShaderEditor::ClickType ShaderEditor::_locate_click(const Point2& p_click,int *p_node_id,int *p_slot_index) const {
-
- Ref<StyleBox> style = get_stylebox("panel","PopupMenu");
- Ref<Texture> real_icon = get_icon("NodeRealSlot","EditorIcons");
- Ref<Font> font = get_font("font","PopupMenu");
- float h = font->get_height()+get_constant("vseparation","PopupMenu");
- float extra_left=MAX( real_icon->get_width()-style->get_margin(MARGIN_LEFT), 0 );
- float extra_right=MAX( real_icon->get_width()-style->get_margin(MARGIN_RIGHT), 0 );
+ ERR_FAIL_COND(from_idx==-1);
+ ERR_FAIL_COND(to_idx==-1);
- for(const List<int>::Element *E=order.back();E;E=E->prev()) {
+ ur->create_action("Connect Graph Nodes");
- Size2 size=get_node_size(E->get());
- size.width+=extra_left+extra_right;
- Point2 pos = Point2( shader_graph.node_get_pos_x(E->get()), shader_graph.node_get_pos_y(E->get()) )-offset;
- pos.x-=extra_left;
+ List<ShaderGraph::Connection> conns;
- Rect2 rect( pos, size );
- if (!rect.has_point(p_click))
- continue;
- VisualServer::ShaderNodeType type=shader_graph.node_get_type(E->get());
- if (p_node_id)
- *p_node_id=E->get();
- float y=p_click.y-(pos.y+style->get_margin(MARGIN_TOP));
- if (y<h)
- return CLICK_NODE;
- y-=h;
-
- for(int i=0;i<VisualServer::shader_get_input_count(type);i++) {
-
- if (y<h) {
- if (p_slot_index)
- *p_slot_index=i;
- return CLICK_INPUT_SLOT;
- }
- y-=h;
- }
+ graph->get_node_connections(type,&conns);
+ //disconnect/reconnect dependencies
+ ur->add_undo_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot);
+ for(List<ShaderGraph::Connection>::Element *E=conns.front();E;E=E->next()) {
- for(int i=0;i<VisualServer::shader_get_output_count(type);i++) {
-
- if (y<h) {
- if (p_slot_index)
- *p_slot_index=i;
- return CLICK_OUTPUT_SLOT;
- }
- y-=h;
+ if (E->get().dst_id==to_idx && E->get().dst_slot==p_to_slot) {
+ ur->add_do_method(graph.ptr(),"disconnect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot);
+ ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot);
}
-
- if (p_click.y<(rect.pos.y+rect.size.height-style->get_margin(MARGIN_BOTTOM)))
- return CLICK_PARAMETER;
- else
- return CLICK_NODE;
-
}
+ ur->add_do_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot);
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
- return CLICK_NONE;
}
-Point2 ShaderEditor::_get_slot_pos(int p_node_id,bool p_input,int p_slot) {
+void ShaderGraphView::_node_removed(int p_id) {
- Ref<StyleBox> style = get_stylebox("panel","PopupMenu");
- float w = get_node_size(p_node_id).width;
- Ref<Font> font = get_font("font","PopupMenu");
- float h = font->get_height()+get_constant("vseparation","PopupMenu");
- Ref<Texture> vec_icon = get_icon("NodeVecSlot","EditorIcons");
- Point2 pos = Point2( shader_graph.node_get_pos_x(p_node_id), shader_graph.node_get_pos_y(p_node_id) )-offset;
- pos+=style->get_offset();
- pos.y+=h;
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Remove Shader Graph Node");
- if(p_input) {
+ ur->add_do_method(graph.ptr(),"node_remove",type,p_id);
+ ur->add_undo_method(graph.ptr(),"node_add",type,graph->node_get_type(type,p_id),p_id);
+ ur->add_undo_method(graph.ptr(),"node_set_state",type,p_id,graph->node_get_state(type,p_id));
+ List<ShaderGraph::Connection> conns;
- pos.y+=p_slot*h;
- pos+=Point2( -vec_icon->get_width()/2.0, h/2.0).floor();
- return pos;
- } else {
+ graph->get_node_connections(type,&conns);
+ for(List<ShaderGraph::Connection>::Element *E=conns.front();E;E=E->next()) {
- pos.y+=VisualServer::shader_get_input_count( shader_graph.node_get_type(p_node_id ) )*h;
+ if (E->get().dst_id==p_id || E->get().src_id==p_id) {
+ ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot);
+ }
}
-
- pos.y+=p_slot*h;
- pos+=Point2( w-style->get_minimum_size().width+vec_icon->get_width()/2.0, h/2.0).floor();
-
- return pos;
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
}
-void ShaderEditor::_node_edit_property(int p_node) {
-
- Ref<StyleBox> style = get_stylebox("panel","PopupMenu");
- Size2 size = get_node_size(p_node);
- Point2 pos = Point2( shader_graph.node_get_pos_x(p_node), shader_graph.node_get_pos_y(p_node) )-offset;
-
- VisualServer::ShaderNodeType type=shader_graph.node_get_type(p_node);
-
- PropertyInfo ph = VisualServer::get_singleton()->shader_node_get_type_info(type);
- if (ph.type==Variant::NIL)
- return;
- if (ph.type==Variant::_RID)
- ph.type=Variant::OBJECT;
-
- property_editor->edit(NULL,ph.name,ph.type,shader_graph.node_get_param(p_node),ph.hint,ph.hint_string);
-
- Point2 popup_pos=Point2( pos.x+(size.width-property_editor->get_size().width)/2.0,pos.y+(size.y-style->get_margin(MARGIN_BOTTOM))).floor();
- popup_pos+=get_global_pos();
- property_editor->set_pos(popup_pos);
-
- property_editor->popup();
+void ShaderGraphView::_node_moved(const Vector2& p_from, const Vector2& p_to,int p_id) {
+ print_line("moved from "+p_from+" to "+p_to);
+ ERR_FAIL_COND(!node_map.has(p_id));
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Move Shader Graph Node");
+ ur->add_do_method(this,"_move_node",p_id,p_to);
+ ur->add_undo_method(this,"_move_node",p_id,p_from);
+ ur->commit_action();
}
-bool ShaderEditor::has_point(const Point2& p_point) const {
-
- int n,si;
+void ShaderGraphView::_move_node(int p_id,const Vector2& p_to) {
- return _locate_click(p_point,&n,&si)!=CLICK_NONE;
+ ERR_FAIL_COND(!node_map.has(p_id));
+ node_map[p_id]->set_offset(p_to);
+ graph->node_set_pos(type,p_id,p_to);
}
-void ShaderEditor::_input_event(InputEvent p_event) {
-
- switch(p_event.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
- if (p_event.mouse_button.pressed) {
-
-
- if (p_event.mouse_button.button_index==1) {
- click_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
- click_motion=click_pos;
- click_type = _locate_click(click_pos,&click_node,&click_slot);
- if( click_type!=CLICK_NONE) {
-
- order.erase(click_node);
- order.push_back(click_node);
- update();
- }
- switch(click_type) {
- case CLICK_INPUT_SLOT: {
- click_pos=_get_slot_pos(click_node,true,click_slot);
- } break;
- case CLICK_OUTPUT_SLOT: {
- click_pos=_get_slot_pos(click_node,false,click_slot);
- } break;
- case CLICK_PARAMETER: {
- //open editor
- _node_edit_property(click_node);
- } break;
- }
- }
- if (p_event.mouse_button.button_index==2) {
-
- if (click_type!=CLICK_NONE) {
- click_type=CLICK_NONE;
- update();
- } else {
- // try to disconnect/remove
-
- Point2 rclick_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
- rclick_type = _locate_click(rclick_pos,&rclick_node,&rclick_slot);
- if (rclick_type==CLICK_INPUT_SLOT || rclick_type==CLICK_OUTPUT_SLOT) {
- node_popup->clear();
- node_popup->add_item("Disconnect",NODE_DISCONNECT);
- node_popup->set_pos(rclick_pos);
- node_popup->popup();
+void ShaderGraphView::_create_node(int p_id) {
- }
- if (rclick_type==CLICK_NODE) {
- node_popup->clear();
- node_popup->add_item("Remove",NODE_ERASE);
- node_popup->set_pos(rclick_pos);
- node_popup->popup();
- }
+ GraphNode *gn = memnew( GraphNode );
+ gn->set_show_close_button(true);
+ Color typecol[4]={
+ Color(0.2,1,0.2),
+ Color(0.7,0.1,1),
+ Color(1,0.2,0.2),
+ Color(0,1,1)
+ };
- }
- }
- } else {
-
- if (p_event.mouse_button.button_index==1 && click_type!=CLICK_NONE) {
-
- switch(click_type) {
- case CLICK_INPUT_SLOT:
- case CLICK_OUTPUT_SLOT: {
-
- Point2 dst_click_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
- int id;
- int slot;
- ClickType dst_click_type = _locate_click(dst_click_pos,&id,&slot);
- if (dst_click_type==CLICK_INPUT_SLOT && click_type==CLICK_OUTPUT_SLOT) {
-
- shader_graph.connect(click_node,click_slot,id,slot);
-
- Error err = validate_graph();
- if (err==ERR_CYCLIC_LINK)
- shader_graph.disconnect(click_node,click_slot,id,slot);
- _write_shader_graph();
+ switch(graph->node_get_type(type,p_id)) {
- }
- if (click_type==CLICK_INPUT_SLOT && dst_click_type==CLICK_OUTPUT_SLOT) {
+ case ShaderGraph::NODE_INPUT: {
- shader_graph.connect(id,slot,click_node,click_slot);
+ gn->set_title("Input");
- Error err = validate_graph();
- if (err==ERR_CYCLIC_LINK)
- shader_graph.disconnect(id,slot,click_node,click_slot);
- _write_shader_graph();
- }
+ List<ShaderGraph::SlotInfo> si;
+ ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si);
- } break;
- case CLICK_NODE: {
- int new_x=shader_graph.node_get_pos_x(click_node)+(click_motion.x-click_pos.x);
- int new_y=shader_graph.node_get_pos_y(click_node)+(click_motion.y-click_pos.y);
- shader_graph.node_set_pos(click_node,new_x,new_y);
- _write_shader_graph();
+ int idx=0;
+ for (List<ShaderGraph::SlotInfo>::Element *E=si.front();E;E=E->next()) {
+ ShaderGraph::SlotInfo& s=E->get();
+ if (s.dir==ShaderGraph::SLOT_IN) {
- } break;
- }
-
- click_type=CLICK_NONE;
- update();
+ Label *l= memnew( Label );
+ l->set_text(s.name);
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+ gn->set_slot(idx,false,0,Color(),true,s.type,typecol[s.type]);
+ idx++;
}
}
- }
-
- case InputEvent::MOUSE_MOTION: {
-
- if (p_event.mouse_motion.button_mask&1 && click_type!=CLICK_NONE) {
+ } break; // all inputs (case Shader type dependent)
+ case ShaderGraph::NODE_SCALAR_CONST: {
+ gn->set_title("Scalar");
+ SpinBox *sb = memnew( SpinBox );
+ sb->set_min(-100000);
+ sb->set_max(100000);
+ sb->set_step(0.001);
+ sb->set_val(graph->scalar_const_node_get_value(type,p_id));
+ sb->connect("value_changed",this,"_scalar_const_changed",varray(p_id));
+ gn->add_child(sb);
+ gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; //scalar constant
+ case ShaderGraph::NODE_VEC_CONST: {
+
+ gn->set_title("Vector");
+ Array v3p(true);
+ for(int i=0;i<3;i++) {
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ Label *l = memnew( Label );
+ l->set_text(String::chr('X'+i));
+ hbc->add_child(l);
+ SpinBox *sb = memnew( SpinBox );
+ sb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ sb->set_min(-100000);
+ sb->set_max(100000);
+ sb->set_step(0.001);
+ sb->set_val(graph->vec_const_node_get_value(type,p_id)[i]);
+ sb->connect("value_changed",this,"_vec_const_changed",varray(p_id,v3p));
+ v3p.push_back(sb);
+ hbc->add_child(sb);
+ gn->add_child(hbc);
+ }
+ gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+
+ } break; //vec3 constant
+ case ShaderGraph::NODE_RGB_CONST: {
+
+ gn->set_title("Color");
+ ColorPickerButton *cpb = memnew( ColorPickerButton );
+ cpb->set_color(graph->rgb_const_node_get_value(type,p_id));
+ cpb->connect("color_changed",this,"_rgb_const_changed",varray(p_id));
+ gn->add_child(cpb);
+ Label *l = memnew( Label );
+ l->set_text("RGB");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+ l = memnew( Label );
+ l->set_text("Alpha");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+
+ gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; //rgb constant (shows a color picker instead)
+ case ShaderGraph::NODE_XFORM_CONST: {
+ gn->set_title("XForm");
+ ToolButton *edit = memnew( ToolButton );
+ edit->set_text("edit..");
+ edit->connect("pressed",this,"_xform_const_changed",varray(p_id,edit));
+ gn->add_child(edit);
+ gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]);
+
+ } break; // 4x4 matrix constant
+ case ShaderGraph::NODE_TIME: {
+
+ gn->set_title("Time");
+ Label *l = memnew( Label );
+ l->set_text("(s)");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+ gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; // time in seconds
+ case ShaderGraph::NODE_SCREEN_TEX: {
+
+ gn->set_title("ScreenTex");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("UV")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("RGB")));
+ gn->add_child(hbc);
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+
+ } break; // screen texture sampler (takes UV) (only usable in fragment case Shader)
+ case ShaderGraph::NODE_SCALAR_OP: {
+
+ gn->set_title("ScalarOp");
+ static const char* op_name[ShaderGraph::SCALAR_MAX_OP]={
+ "Add",
+ "Sub",
+ "Mul",
+ "Div",
+ "Mod",
+ "Pow",
+ "Max",
+ "Min",
+ "Atan2"
+ };
+
+ OptionButton *ob = memnew( OptionButton );
+ for(int i=0;i<ShaderGraph::SCALAR_MAX_OP;i++) {
+
+ ob->add_item(op_name[i],i);
+ }
- click_motion=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
- update();
+ ob->select(graph->scalar_op_node_get_op(type,p_id));
+ ob->connect("item_selected",this,"_scalar_op_changed",varray(p_id));
+ gn->add_child(ob);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
+
+
+ } break; // scalar vs scalar op (mul: { } break; add: { } break; div: { } break; etc)
+ case ShaderGraph::NODE_VEC_OP: {
+
+ gn->set_title("VecOp");
+ static const char* op_name[ShaderGraph::VEC_MAX_OP]={
+ "Add",
+ "Sub",
+ "Mul",
+ "Div",
+ "Mod",
+ "Pow",
+ "Max",
+ "Min",
+ "Cross"
+ };
+
+ OptionButton *ob = memnew( OptionButton );
+ for(int i=0;i<ShaderGraph::VEC_MAX_OP;i++) {
+
+ ob->add_item(op_name[i],i);
}
- } break;
- }
-}
+ ob->select(graph->vec_op_node_get_op(type,p_id));
+ ob->connect("item_selected",this,"_vec_op_changed",varray(p_id));
+ gn->add_child(ob);
-void ShaderEditor::_notification(int p_what) {
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
- switch(p_what) {
- case NOTIFICATION_DRAW: {
+ } break; // vec3 vs vec3 op (mul: { } break;ad: { } break;div: { } break;crossprod: { } break;etc)
+ case ShaderGraph::NODE_VEC_SCALAR_OP: {
- _update_scrollbars();
- //VisualServer::get_singleton()->canvas_item_add_rect(get_canvas_item(),Rect2(Point2(),get_size()),Color(0,0,0,1));
+ gn->set_title("VecScalarOp");
+ static const char* op_name[ShaderGraph::VEC_SCALAR_MAX_OP]={
+ "Mul",
+ "Div",
+ "Pow",
+ };
- for(List<int>::Element *E=order.front();E;E=E->next()) {
+ OptionButton *ob = memnew( OptionButton );
+ for(int i=0;i<ShaderGraph::VEC_SCALAR_MAX_OP;i++) {
- _draw_node(E->get());
+ ob->add_item(op_name[i],i);
}
- if (click_type==CLICK_INPUT_SLOT || click_type==CLICK_OUTPUT_SLOT) {
+ ob->select(graph->vec_scalar_op_node_get_op(type,p_id));
+ ob->connect("item_selected",this,"_vec_scalar_op_changed",varray(p_id));
+ gn->add_child(ob);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
+
+
+ } break; // vec3 vs scalar op (mul: { } break; add: { } break; div: { } break; etc)
+ case ShaderGraph::NODE_RGB_OP: {
+
+ gn->set_title("RGB Op");
+ static const char* op_name[ShaderGraph::RGB_MAX_OP]={
+ "Screen",
+ "Difference",
+ "Darken",
+ "Lighten",
+ "Overlay",
+ "Dodge",
+ "Burn",
+ "SoftLight",
+ "HardLight"
+ };
+
+ OptionButton *ob = memnew( OptionButton );
+ for(int i=0;i<ShaderGraph::RGB_MAX_OP;i++) {
+
+ ob->add_item(op_name[i],i);
+ }
- VisualServer::get_singleton()->canvas_item_add_line(get_canvas_item(),click_pos,click_motion,Color(0.5,1,0.5,0.8),2);
+ ob->select(graph->rgb_op_node_get_op(type,p_id));
+ ob->connect("item_selected",this,"_rgb_op_changed",varray(p_id));
+ gn->add_child(ob);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+
+ } break; // vec3 vs vec3 rgb op (with scalar amount): { } break; like brighten: { } break; darken: { } break; burn: { } break; dodge: { } break; multiply: { } break; etc.
+ case ShaderGraph::NODE_XFORM_MULT: {
+
+ gn->set_title("XFMult");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]);
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color());
+
+
+ } break; // mat4 x mat4
+ case ShaderGraph::NODE_XFORM_VEC_MULT:
+ case ShaderGraph::NODE_XFORM_VEC_INV_MULT: {
+
+ if (graph->node_get_type(type,p_id)==ShaderGraph::NODE_XFORM_VEC_INV_MULT)
+ gn->set_title("XFVecMult");
+ else
+ gn->set_title("XFVecInvMult");
+
+
+ Button *button = memnew( Button("RotOnly"));
+ button->set_toggle_mode(true);
+ button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id));
+ button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id));
+
+ gn->add_child(button);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("xf")));
+ hbc->add_spacer();
+ Label *l = memnew(Label("out"));
+ l->set_align(Label::ALIGN_RIGHT);
+ hbc->add_child( l);
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("vec")));
+
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+
+
+ } break; // mat4 x vec3 inverse mult (with no-translation option)
+ case ShaderGraph::NODE_SCALAR_FUNC: {
+
+ gn->set_title("ScalarFunc");
+ static const char* func_name[ShaderGraph::SCALAR_MAX_FUNC]={
+ "Sin",
+ "Cos",
+ "Tan",
+ "ASin",
+ "ACos",
+ "ATan",
+ "SinH",
+ "CosH",
+ "TanH",
+ "Log",
+ "Exp",
+ "Sqrt",
+ "Abs",
+ "Sign",
+ "Floor",
+ "Round",
+ "Ceil",
+ "Frac",
+ "Satr",
+ "Neg"
+ };
+
+ OptionButton *ob = memnew( OptionButton );
+ for(int i=0;i<ShaderGraph::SCALAR_MAX_FUNC;i++) {
+
+ ob->add_item(func_name[i],i);
}
- List<ShaderGraph::Connection> connections = shader_graph.get_connection_list();
- for(List<ShaderGraph::Connection>::Element *E=connections.front();E;E=E->next()) {
+ ob->select(graph->scalar_func_node_get_function(type,p_id));
+ ob->connect("item_selected",this,"_scalar_func_changed",varray(p_id));
+ gn->add_child(ob);
- const ShaderGraph::Connection &c=E->get();
- Point2 source = _get_slot_pos(c.src_id,false,c.src_slot);
- Point2 dest = _get_slot_pos(c.dst_id,true,c.dst_slot);
- bool vec = VisualServer::shader_is_input_vector( shader_graph.node_get_type(c.dst_id), c.dst_slot );
- Color col = vec?Color(1,0.5,0.5,0.8):Color(1,1,0.5,0.8);
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_child( memnew(Label("in")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
- if (click_type==CLICK_NODE && click_node==c.src_id) {
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
- source+=click_motion-click_pos;
- }
- if (click_type==CLICK_NODE && click_node==c.dst_id) {
+ } break; // scalar function (sin: { } break; cos: { } break; etc)
+ case ShaderGraph::NODE_VEC_FUNC: {
- dest+=click_motion-click_pos;
- }
- VisualServer::get_singleton()->canvas_item_add_line(get_canvas_item(),source,dest,col,2);
-
- }
- } break;
- }
-
-}
-void ShaderEditor::_update_scrollbars() {
+ gn->set_title("VecFunc");
+ static const char* func_name[ShaderGraph::VEC_MAX_FUNC]={
+ "Normalize",
+ "Saturate",
+ "Negate",
+ "Reciprocal",
+ "RGB to HSV",
+ "HSV to RGB",
+ };
- Size2 size = get_size();
- Size2 hmin = h_scroll->get_minimum_size();
- Size2 vmin = v_scroll->get_minimum_size();
+ OptionButton *ob = memnew( OptionButton );
+ for(int i=0;i<ShaderGraph::VEC_MAX_FUNC;i++) {
- v_scroll->set_begin( Point2(size.width - vmin.width, 0) );
- v_scroll->set_end( Point2(size.width, size.height) );
-
- h_scroll->set_begin( Point2( 0, size.height - hmin.height) );
- h_scroll->set_end( Point2(size.width-vmin.width, size.height) );
-
-
- Size2 min = _get_maximum_size();
+ ob->add_item(func_name[i],i);
+ }
- if (min.height < size.height - hmin.height) {
+ ob->select(graph->vec_func_node_get_function(type,p_id));
+ ob->connect("item_selected",this,"_vec_func_changed",varray(p_id));
+ gn->add_child(ob);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("in")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("out")));
+ gn->add_child(hbc);
+
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+
+ } break; // vector function (normalize: { } break; negate: { } break; reciprocal: { } break; rgb2hsv: { } break; hsv2rgb: { } break; etc: { } break; etc)
+ case ShaderGraph::NODE_VEC_LEN: {
+ gn->set_title("VecLength");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_child( memnew(Label("in")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("len")));
+ gn->add_child(hbc);
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; // vec3 length
+ case ShaderGraph::NODE_DOT_PROD: {
+
+ gn->set_title("DotProduct");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("dp")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+
+ } break; // vec3 . vec3 (dot product -> scalar output)
+ case ShaderGraph::NODE_VEC_TO_SCALAR: {
+
+ gn->set_title("Vec2Scalar");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("vec")));
+ hbc->add_spacer();
+ Label *l=memnew(Label("x"));
+ l->set_align(Label::ALIGN_RIGHT);
+ hbc->add_child( l);
+ gn->add_child(hbc);
+ l=memnew(Label("y"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child( l );
+ l=memnew(Label("z"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child( l);
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+ gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+ gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+
+
+
+ } break; // 1 vec3 input: { } break; 3 scalar outputs
+ case ShaderGraph::NODE_SCALAR_TO_VEC: {
+
+ gn->set_title("Scalar2Vec");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_child( memnew(Label("x")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("vec")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("y")));
+ gn->add_child( memnew(Label("z")));
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
+
+ } break; // 3 scalar input: { } break; 1 vec3 output
+ case ShaderGraph::NODE_VEC_TO_XFORM: {
+
+ gn->set_title("Vec2XForm");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("x")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("xf")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("y")));
+ gn->add_child( memnew(Label("z")));
+ gn->add_child( memnew(Label("ofs")));
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]);
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+ gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+
+ } break; // 3 vec input: { } break; 1 xform output
+ case ShaderGraph::NODE_XFORM_TO_VEC: {
+
+ gn->set_title("XForm2Vec");
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("xf")));
+ hbc->add_spacer();
+ Label *l=memnew(Label("x"));
+ l->set_align(Label::ALIGN_RIGHT);
+ hbc->add_child( l);
+ gn->add_child(hbc);
+ l=memnew(Label("y"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child( l );
+ l=memnew(Label("z"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child( l);
+ l=memnew(Label("ofs"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child( l);
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+
+ } break; // 3 vec input: { } break; 1 xform output
+ case ShaderGraph::NODE_SCALAR_INTERP: {
+
+ gn->set_title("ScalarInterp");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("interp")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+ gn->add_child( memnew(Label("c")));
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
+
+
+ } break; // scalar interpolation (with optional curve)
+ case ShaderGraph::NODE_VEC_INTERP: {
+
+ gn->set_title("VecInterp");
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_child( memnew(Label("a")));
+ hbc->add_spacer();
+ hbc->add_child( memnew(Label("interp")));
+ gn->add_child(hbc);
+ gn->add_child( memnew(Label("b")));
+ gn->add_child( memnew(Label("c")));
+
+ gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
+
+ } break; // vec3 interpolation (with optional curve)
+ case ShaderGraph::NODE_SCALAR_INPUT: {
+
+ gn->set_title("ScalarUniform");
+ LineEdit *le = memnew( LineEdit );
+ gn->add_child(le);
+ le->set_text(graph->input_node_get_name(type,p_id));
+ le->connect("text_entered",this,"_input_name_changed",varray(p_id,le));
+ SpinBox *sb = memnew( SpinBox );
+ sb->set_min(-100000);
+ sb->set_max(100000);
+ sb->set_step(0.001);
+ sb->set_val(graph->scalar_input_node_get_value(type,p_id));
+ sb->connect("value_changed",this,"_scalar_input_changed",varray(p_id));
+ gn->add_child(sb);
+ gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; // scalar uniform (assignable in material)
+ case ShaderGraph::NODE_VEC_INPUT: {
+
+ gn->set_title("VectorUniform");
+ LineEdit *le = memnew( LineEdit );
+ gn->add_child(le);
+ le->set_text(graph->input_node_get_name(type,p_id));
+ le->connect("text_entered",this,"_input_name_changed",varray(p_id,le));
+ Array v3p(true);
+ for(int i=0;i<3;i++) {
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ Label *l = memnew( Label );
+ l->set_text(String::chr('X'+i));
+ hbc->add_child(l);
+ SpinBox *sb = memnew( SpinBox );
+ sb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ sb->set_min(-100000);
+ sb->set_max(100000);
+ sb->set_step(0.001);
+ sb->set_val(graph->vec_input_node_get_value(type,p_id)[i]);
+ sb->connect("value_changed",this,"_vec_input_changed",varray(p_id,v3p));
+ v3p.push_back(sb);
+ hbc->add_child(sb);
+ gn->add_child(hbc);
+ }
+ gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+
+ } break; // vec3 uniform (assignable in material)
+ case ShaderGraph::NODE_RGB_INPUT: {
+
+ gn->set_title("ColorUniform");
+ LineEdit *le = memnew( LineEdit );
+ gn->add_child(le);
+ le->set_text(graph->input_node_get_name(type,p_id));
+ le->connect("text_entered",this,"_input_name_changed",varray(p_id,le));
+ ColorPickerButton *cpb = memnew( ColorPickerButton );
+ cpb->set_color(graph->rgb_input_node_get_value(type,p_id));
+ cpb->connect("color_changed",this,"_rgb_input_changed",varray(p_id));
+ gn->add_child(cpb);
+ Label *l = memnew( Label );
+ l->set_text("RGB");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+ l = memnew( Label );
+ l->set_text("Alpha");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+
+ gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+
+ } break; // color uniform (assignable in material)
+ case ShaderGraph::NODE_XFORM_INPUT: {
+ gn->set_title("XFUniform");
+ LineEdit *le = memnew( LineEdit );
+ gn->add_child(le);
+ le->set_text(graph->input_node_get_name(type,p_id));
+ le->connect("text_entered",this,"_input_name_changed",varray(p_id,le));
+ ToolButton *edit = memnew( ToolButton );
+ edit->set_text("edit..");
+ edit->connect("pressed",this,"_xform_input_changed",varray(p_id,edit));
+ gn->add_child(edit);
+ gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]);
+
+ } break; // mat4 uniform (assignable in material)
+ case ShaderGraph::NODE_TEXTURE_INPUT: {
+
+ gn->set_title("TexUniform");
+ LineEdit *le = memnew( LineEdit );
+ gn->add_child(le);
+ le->set_text(graph->input_node_get_name(type,p_id));
+ le->connect("text_entered",this,"_input_name_changed",varray(p_id,le));
+ TextureFrame *tex = memnew( TextureFrame );
+ tex->set_expand(true);
+ tex->set_custom_minimum_size(Size2(80,80));
+ gn->add_child(tex);
+ tex->set_texture(graph->texture_input_node_get_value(type,p_id));
+ ToolButton *edit = memnew( ToolButton );
+ edit->set_text("edit..");
+ edit->connect("pressed",this,"_tex_edited",varray(p_id,edit));
+ gn->add_child(edit);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("UV")));
+ hbc->add_spacer();
+ Label *l=memnew(Label("RGB"));
+ l->set_align(Label::ALIGN_RIGHT);
+ hbc->add_child(l);
+ gn->add_child(hbc);
+ l = memnew( Label );
+ l->set_text("Alpha");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+
+ gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(4,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; // texture input (assignable in material)
+ case ShaderGraph::NODE_CUBEMAP_INPUT: {
+
+ gn->set_title("TexUniform");
+ LineEdit *le = memnew( LineEdit );
+ gn->add_child(le);
+ le->set_text(graph->input_node_get_name(type,p_id));
+ le->connect("text_entered",this,"_input_name_changed",varray(p_id,le));
+
+ ToolButton *edit = memnew( ToolButton );
+ edit->set_text("edit..");
+ edit->connect("pressed",this,"_cube_edited",varray(p_id,edit));
+ gn->add_child(edit);
+
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ hbc->add_constant_override("separation",0);
+ hbc->add_child( memnew(Label("UV")));
+ hbc->add_spacer();
+ Label *l=memnew(Label("RGB"));
+ l->set_align(Label::ALIGN_RIGHT);
+ hbc->add_child(l);
+ gn->add_child(hbc);
+ l = memnew( Label );
+ l->set_text("Alpha");
+ l->set_align(Label::ALIGN_RIGHT);
+ gn->add_child(l);
+
+ gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
+ gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
+
+ } break; // cubemap input (assignable in material)
+ case ShaderGraph::NODE_OUTPUT: {
+ gn->set_title("Output");
+
+ List<ShaderGraph::SlotInfo> si;
+ ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si);
+
+ int idx=0;
+ for (List<ShaderGraph::SlotInfo>::Element *E=si.front();E;E=E->next()) {
+ ShaderGraph::SlotInfo& s=E->get();
+ if (s.dir==ShaderGraph::SLOT_OUT) {
+
+ Label *l= memnew( Label );
+ l->set_text(s.name);
+ l->set_align(Label::ALIGN_LEFT);
+ gn->add_child(l);
+ gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color());
+ idx++;
+ }
+ }
- v_scroll->hide();
- offset.y=0;
- } else {
+ } break; // output (case Shader type dependent)
+ case ShaderGraph::NODE_COMMENT: {
+ gn->set_title("Comment");
+ TextEdit *te = memnew(TextEdit);
+ te->set_custom_minimum_size(Size2(100,100));
+ gn->add_child(te);
+ te->set_text(graph->comment_node_get_text(type,p_id));
+ te->connect("text_changed",this,"_comment_edited",varray(p_id,te));
- v_scroll->show();
- v_scroll->set_max(min.height);
- v_scroll->set_page(size.height - hmin.height);
- offset.y=v_scroll->get_val();
- }
+ } break; // comment
- if (min.width < size.width - vmin.width) {
- h_scroll->hide();
- offset.x=0;
- } else {
- h_scroll->show();
- h_scroll->set_max(min.width);
- h_scroll->set_page(size.width - vmin.width);
- offset.x=h_scroll->get_val();
}
-}
-void ShaderEditor::_scroll_moved() {
+ gn->connect("dragged",this,"_node_moved",varray(p_id));
+ gn->connect("close_request",this,"_node_removed",varray(p_id),CONNECT_DEFERRED);
+ graph_edit->add_child(gn);
+ node_map[p_id]=gn;
+ gn->set_offset(graph->node_get_pos(type,p_id));
+ print_line("NODE "+itos(p_id)+" OFS "+gn->get_offset());
- offset.x=h_scroll->get_val();
- offset.y=v_scroll->get_val();
- update();
}
-void ShaderEditor::_bind_methods() {
+void ShaderGraphView::_update_graph() {
- ObjectTypeDB::bind_method( "_node_menu_item", &ShaderEditor::_node_menu_item );
- ObjectTypeDB::bind_method( "_node_add_callback", &ShaderEditor::_node_add_callback );
- ObjectTypeDB::bind_method( "_input_event", &ShaderEditor::_input_event );
- ObjectTypeDB::bind_method( "_node_param_changed", &ShaderEditor::_node_param_changed );
- ObjectTypeDB::bind_method( "_scroll_moved", &ShaderEditor::_scroll_moved );
- ObjectTypeDB::bind_method( "_vertex_item", &ShaderEditor::_vertex_item );
- ObjectTypeDB::bind_method( "_fragment_item", &ShaderEditor::_fragment_item );
- ObjectTypeDB::bind_method( "_post_item", &ShaderEditor::_post_item );
-}
-
-void ShaderEditor::_read_shader_graph() {
- shader_graph.clear();;
- order.clear();
- List<int> nodes;
- shader->get_node_list(&nodes);
- int larger_id=0;
- for(List<int>::Element *E=nodes.front();E;E=E->next()) {
+ if (block_update)
+ return;
- if (E->get() > larger_id)
- larger_id = E->get();
+ for (Map<int,GraphNode*>::Element *E=node_map.front();E;E=E->next()) {
- shader_graph.node_add( (VS::ShaderNodeType)shader->node_get_type(E->get()), E->get() );
- shader_graph.node_set_param( E->get(), shader->node_get_param( E->get() ) );
- Point2 pos = shader->node_get_pos(E->get());
- shader_graph.node_set_pos( E->get(), pos.x,pos.y );
- order.push_back(E->get());
+ memdelete(E->get());
}
- last_id=larger_id+1;
+ node_map.clear();
- List<Shader::Connection> connections;
- shader->get_connections(&connections);
-
- for(List<Shader::Connection>::Element *E=connections.front();E;E=E->next()) {
-
- Shader::Connection &c=E->get();
- shader_graph.connect(c.src_id,c.src_slot,c.dst_id,c.dst_slot);
- }
-
- validate_graph();
- update();
-}
+ if (!graph.is_valid())
+ return;
-void ShaderEditor::_write_shader_graph() {
- shader->clear();
- List<int> nodes;
- shader_graph.get_node_list(&nodes);
- for(List<int>::Element *E=nodes.front();E;E=E->next()) {
+ List<int> nl;
+ graph->get_node_list(type,&nl);
+ print_line("graph nodes: "+itos(nl.size()));
+ for(List<int>::Element *E=nl.front();E;E=E->next()) {
- shader->node_add((Shader::NodeType)shader_graph.node_get_type(E->get()),E->get());
- shader->node_set_param(E->get(),shader_graph.node_get_param(E->get()));
- shader->node_set_pos(E->get(),Point2( shader_graph.node_get_pos_x(E->get()),shader_graph.node_get_pos_y(E->get()) ) );
+ _create_node(E->get());
}
+ graph_edit->clear_connections();
- List<ShaderGraph::Connection> connections = shader_graph.get_connection_list();
+ List<ShaderGraph::Connection> connections;
+ graph->get_node_connections(type,&connections);
for(List<ShaderGraph::Connection>::Element *E=connections.front();E;E=E->next()) {
- const ShaderGraph::Connection &c=E->get();
- shader->connect(c.src_id,c.src_slot,c.dst_id,c.dst_slot);
+ ERR_CONTINUE(!node_map.has(E->get().src_id) || !node_map.has(E->get().dst_id));
+ 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 ShaderEditor::_add_node_from_text(const String& p_text) {
- ERR_FAIL_COND( p_text.get_slice_count(" ") != 3 );
- bool input = p_text.get_slice(" ",0)=="In:";
- String name = p_text.get_slice(" ",1);
- bool vec = p_text.get_slice(" ",2)=="(vec3)";
- _node_add( input?
- ( vec? VisualServer::NODE_VEC_IN : VisualServer::NODE_IN ) :
- ( vec? VisualServer::NODE_VEC_OUT : VisualServer::NODE_OUT ) );
- shader_graph.node_set_param( last_id-1,name );
- _write_shader_graph();
}
-void ShaderEditor::_vertex_item(int p_item) {
+void ShaderGraphView::set_graph(Ref<ShaderGraph> p_graph){
- _add_node_from_text(vertex_popup->get_item_text(p_item));
-}
-void ShaderEditor::_fragment_item(int p_item) {
-
- _add_node_from_text(fragment_popup->get_item_text(p_item));
-}
-void ShaderEditor::_post_item(int p_item) {
+ print_line("GRAPH EDIT: "+itos(p_graph.is_valid()));
+ graph=p_graph;
+ _update_graph();
- _add_node_from_text(post_popup->get_item_text(p_item));
}
+void ShaderGraphView::_notification(int p_what) {
-void ShaderEditor::_node_menu_item(int p_item) {
-
- switch(p_item) {
-
- case GRAPH_ADD_NODE: {
- add_popup->popup_centered_ratio();
- validate_graph();
- } break;
- case NODE_DISCONNECT: {
-
- if (rclick_type==CLICK_INPUT_SLOT) {
-
- List<ShaderGraph::Connection> connections = shader_graph.get_connection_list();
- for(List<ShaderGraph::Connection>::Element *E=connections.front();E;E=E->next()) {
-
- const ShaderGraph::Connection &c=E->get();
- if( c.dst_id==rclick_node && c.dst_slot==rclick_slot) {
-
- shader_graph.disconnect(c.src_id,c.src_slot,c.dst_id,c.dst_slot);
- }
- }
- update();
- _write_shader_graph();
- validate_graph();
- }
-
- if (rclick_type==CLICK_OUTPUT_SLOT) {
-
- List<ShaderGraph::Connection> connections = shader_graph.get_connection_list();
- for(List<ShaderGraph::Connection>::Element *E=connections.front();E;E=E->next()) {
-
- const ShaderGraph::Connection &c=E->get();
- if( c.src_id==rclick_node && c.src_slot==rclick_slot) {
-
- shader_graph.disconnect(c.src_id,c.src_slot,c.dst_id,c.dst_slot);
- }
- }
- update();
- _write_shader_graph();
- validate_graph();
- }
+ if (p_what==NOTIFICATION_ENTER_TREE) {
- } break;
- case NODE_ERASE: {
-
- order.erase(rclick_node);
- shader_graph.node_remove(rclick_node);
- update();
- _write_shader_graph();
- validate_graph();
- } break;
- case GRAPH_CLEAR: {
-
- order.clear();
- shader_graph.clear();
- last_id=1;
- last_x=20;
- last_y=20;
- update();
- _write_shader_graph();
- validate_graph();
-
- } break;
+ ped_popup->connect("variant_changed",this,"_variant_edited");
}
-}
-
-void ShaderEditor::_node_add(VisualServer::ShaderNodeType p_type) {
-
- shader_graph.node_add(p_type,last_id );
- shader_graph.node_set_pos(last_id ,last_x,last_y);
- String test_param;
-
- switch(p_type) {
- case VS::NODE_PARAMETER: {
-
- test_param="param";
- } break;
- case VS::NODE_VEC_PARAMETER: {
-
- test_param="vec";
- } break;
- case VS::NODE_COLOR_PARAMETER: {
-
- test_param="color";
- } break;
- case VS::NODE_TEXTURE_PARAMETER: {
-
- test_param="tex";
- } break;
- case VS::NODE_TEXTURE_2D_PARAMETER: {
-
- test_param="tex2D";
- } break;
- case VS::NODE_TEXTURE_CUBE_PARAMETER: {
-
- test_param="cubemap";
- } break;
- case VS::NODE_TRANSFORM_PARAMETER: {
- test_param="xform";
- } break;
- case VS::NODE_LABEL: {
-
- test_param="label";
- } break;
+ }
+
+void ShaderGraphView::add_node(int p_type) {
+
+ List<int> existing;
+ graph->get_node_list(type,&existing);
+ existing.sort();
+ int newid=1;
+ for(List<int>::Element *E=existing.front();E;E=E->next()) {
+ if (!E->next() || (E->get()+1!=E->next()->get())){
+ newid=E->get()+1;
+ break;
+ }
}
- if(test_param!="") {
-
- int iter=0;
- List<int> l;
-
- shader_graph.get_node_list(&l);
-
- bool found;
- String test;
- do {
- iter++;
- test=test_param;
- if (iter>1)
- test+="_"+itos(iter);
- found=false;
- for(List<int>::Element *E=l.front();E;E=E->next()) {
-
+ Vector2 init_ofs(20,20);
+ while(true) {
+ bool valid=true;
+ for(List<int>::Element *E=existing.front();E;E=E->next()) {
+ Vector2 pos = graph->node_get_pos(type,E->get());
+ if (init_ofs==pos) {
+ init_ofs+=Vector2(20,20);
+ valid=false;
+ break;
- String param = shader_graph.node_get_param( E->get() );
- if (param==test) {
- found=true;
- break;
- }
}
+ }
- } while (found);
-
-
- shader_graph.node_set_param(last_id,test);
-
+ if (valid)
+ break;
}
- order.push_back(last_id);
- last_x+=10;
- last_y+=10;
- last_id++;
- last_x=last_x % (int)get_size().width;
- last_y=last_y % (int)get_size().height;
- update();
- add_popup->hide();;
- _write_shader_graph();
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Add Shader Graph Node");
+ ur->add_do_method(graph.ptr(),"node_add",type,p_type,newid);
+ ur->add_do_method(graph.ptr(),"node_set_pos",type,newid,init_ofs);
+ ur->add_undo_method(graph.ptr(),"node_remove",type,newid);
+ ur->add_do_method(this,"_update_graph");
+ ur->add_undo_method(this,"_update_graph");
+ ur->commit_action();
}
-void ShaderEditor::_node_add_callback() {
+void ShaderGraphView::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_update_graph",&ShaderGraphView::_update_graph);
+ ObjectTypeDB::bind_method("_node_moved",&ShaderGraphView::_node_moved);
+ ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node);
+ ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed);
+ ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request);
+
+ ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed);
+ ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed);
+ ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed);
+ ObjectTypeDB::bind_method("_xform_const_changed",&ShaderGraphView::_xform_const_changed);
+ ObjectTypeDB::bind_method("_scalar_op_changed",&ShaderGraphView::_scalar_op_changed);
+ ObjectTypeDB::bind_method("_vec_op_changed",&ShaderGraphView::_vec_op_changed);
+ ObjectTypeDB::bind_method("_vec_scalar_op_changed",&ShaderGraphView::_vec_scalar_op_changed);
+ ObjectTypeDB::bind_method("_rgb_op_changed",&ShaderGraphView::_rgb_op_changed);
+ ObjectTypeDB::bind_method("_xform_inv_rev_changed",&ShaderGraphView::_xform_inv_rev_changed);
+ ObjectTypeDB::bind_method("_scalar_func_changed",&ShaderGraphView::_scalar_func_changed);
+ ObjectTypeDB::bind_method("_vec_func_changed",&ShaderGraphView::_vec_func_changed);
+ ObjectTypeDB::bind_method("_scalar_input_changed",&ShaderGraphView::_scalar_input_changed);
+ ObjectTypeDB::bind_method("_vec_input_changed",&ShaderGraphView::_vec_input_changed);
+ ObjectTypeDB::bind_method("_xform_input_changed",&ShaderGraphView::_xform_input_changed);
+ ObjectTypeDB::bind_method("_rgb_input_changed",&ShaderGraphView::_rgb_input_changed);
+ ObjectTypeDB::bind_method("_tex_input_change",&ShaderGraphView::_tex_input_change);
+ ObjectTypeDB::bind_method("_cube_input_change",&ShaderGraphView::_cube_input_change);
+ ObjectTypeDB::bind_method("_input_name_changed",&ShaderGraphView::_input_name_changed);
+ ObjectTypeDB::bind_method("_tex_edited",&ShaderGraphView::_tex_edited);
+ ObjectTypeDB::bind_method("_variant_edited",&ShaderGraphView::_variant_edited);
+ ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited);
+ ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited);
- TreeItem * item = add_types->get_selected();
- ERR_FAIL_COND(!item);
- _node_add((VisualServer::ShaderNodeType)(int)item->get_metadata(0));
- add_popup->hide() ;
}
-ShaderEditor::ShaderEditor() {
-
- set_focus_mode(FOCUS_ALL);
-
- Panel* menu_panel = memnew( Panel );
- menu_panel->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
- menu_panel->set_end( Point2(0,22) );
-
- add_child( menu_panel );
-
- PopupMenu *p;
- List<PropertyInfo> defaults;
-
- MenuButton* node_menu = memnew( MenuButton );
- node_menu->set_text("Graph");
- node_menu->set_pos( Point2( 5,0) );
- menu_panel->add_child( node_menu );
-
- p=node_menu->get_popup();
- p->add_item("Add Node",GRAPH_ADD_NODE);
- p->add_separator();
- p->add_item("Clear",GRAPH_CLEAR);
- p->connect("item_pressed", this,"_node_menu_item");
+ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) {
- MenuButton* vertex_menu = memnew( MenuButton );
- vertex_menu->set_text("Vertex");
- vertex_menu->set_pos( Point2( 49,0) );
- menu_panel->add_child( vertex_menu );
+ type=p_type;
+ graph_edit = memnew( GraphEdit );
+ block_update=false;
+ ped_popup = memnew( CustomPropertyEditor );
+ graph_edit->add_child(ped_popup);
- p=vertex_menu->get_popup();
- defaults.clear();
- VisualServer::shader_get_default_input_nodes(VisualServer::SHADER_VERTEX,&defaults);
- int id=0;
- for(int i=0;i<defaults.size();i++) {
-
- p->add_item("In: "+defaults[i].name+(defaults[i].type==Variant::VECTOR3?" (vec3)":" (real)"),id++);
- }
- p->add_separator();
- id++;
-
- defaults.clear();
- VisualServer::shader_get_default_output_nodes(VisualServer::SHADER_VERTEX,&defaults);
-
- for(int i=0;i<defaults.size();i++) {
-
- p->add_item("Out: "+defaults[i].name+(defaults[i].type==Variant::VECTOR3?" (vec3)":" (real)"),id++);
- }
+}
- vertex_popup=p;
- vertex_popup->connect("item_pressed", this,"_vertex_item");
- MenuButton* fragment_menu = memnew( MenuButton );
- fragment_menu->set_text("Fragment");
- fragment_menu->set_pos( Point2( 95 ,0) );
- menu_panel->add_child( fragment_menu );
- p=fragment_menu->get_popup();
- defaults.clear();
- VisualServer::shader_get_default_input_nodes(VisualServer::SHADER_FRAGMENT,&defaults);
- id=0;
- for(int i=0;i<defaults.size();i++) {
+//////////////edit//////////////
+void ShaderGraphEditor::edit(Ref<ShaderGraph> p_shader) {
- p->add_item("In: "+defaults[i].name+(defaults[i].type==Variant::VECTOR3?" (vec3)":" (real)"),id++);
- }
- p->add_separator();
- id++;
- defaults.clear();
- VisualServer::shader_get_default_output_nodes(VisualServer::SHADER_FRAGMENT,&defaults);
-
- for(int i=0;i<defaults.size();i++) {
-
- p->add_item("Out: "+defaults[i].name+(defaults[i].type==Variant::VECTOR3?" (vec3)":" (real)"),id++);
+ for(int i=0;i<ShaderGraph::SHADER_TYPE_MAX;i++) {
+ graph_edits[i]->set_graph(p_shader);
}
+}
- fragment_popup=p;
- fragment_popup->connect("item_pressed", this,"_fragment_item");
+void ShaderGraphEditor::_add_node(int p_type) {
- MenuButton* post_menu = memnew( MenuButton );
- post_menu->set_text("Post");
- post_menu->set_pos( Point2( 161,0) );
- menu_panel->add_child( post_menu );
+ ShaderGraph::ShaderType shader_type=ShaderGraph::ShaderType(tabs->get_current_tab());
- p=post_menu->get_popup();
- defaults.clear();
- VisualServer::shader_get_default_input_nodes(VisualServer::SHADER_POST_PROCESS,&defaults);
- id=0;
- for(int i=0;i<defaults.size();i++) {
+ graph_edits[shader_type]->add_node(p_type);
+}
- p->add_item("In: "+defaults[i].name+(defaults[i].type==Variant::VECTOR3?" (vec3)":" (real)"),id++);
- }
- p->add_separator();
- id++;
- defaults.clear();
- VisualServer::shader_get_default_output_nodes(VisualServer::SHADER_POST_PROCESS,&defaults);
+void ShaderGraphEditor::_notification(int p_what) {
+ if (p_what==NOTIFICATION_ENTER_TREE) {
+ menu->get_popup()->connect("item_pressed",this,"_add_node");
- for(int i=0;i<defaults.size();i++) {
- p->add_item("Out: "+defaults[i].name+(defaults[i].type==Variant::VECTOR3?" (vec3)":" (real)"),id++);
}
+}
- post_popup=p;
- post_popup->connect("item_pressed", this,"_post_item");
-
+void ShaderGraphEditor::_bind_methods() {
- /* add popup */
+ ObjectTypeDB::bind_method("_add_node",&ShaderGraphEditor::_add_node);
- add_popup = memnew( Popup );
- add_child(add_popup);
- add_popup->set_as_toplevel(true);
- Panel *add_panel = memnew( Panel );
- add_popup->add_child(add_panel);
- add_panel->set_area_as_parent_rect();
+}
- Label *add_label = memnew (Label );
- add_label->set_pos(Point2(5,5));
- add_label->set_text("Available Nodes:");
- add_panel->add_child(add_label);
+const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={
+ "Input", // all inputs (shader type dependent)
+ "Scalar Constant", //scalar constant
+ "Vector Constant", //vec3 constant
+ "RGB Constant", //rgb constant (shows a color picker instead)
+ "XForm Constant", // 4x4 matrix constant
+ "Time:", // time in seconds
+ "Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader)
+ "Scalar Operator", // scalar vs scalar op (mul", add", div", etc)
+ "Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc)
+ "Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc)
+ "RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc.
+ "XForm Multiply", // mat4 x mat4
+ "XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option)
+ "XForm+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option)
+ "Scalar Function", // scalar function (sin", cos", etc)
+ "Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc)
+ "Vector Length", // vec3 length
+ "Dot Product:", // vec3 . vec3 (dot product -> scalar output)
+ "Vector -> Scalars", // 1 vec3 input", 3 scalar outputs
+ "Scalars -> Vector", // 3 scalar input", 1 vec3 output
+ "XForm -> Vectors", // 3 vec input", 1 xform output
+ "Vectors -> XForm:", // 3 vec input", 1 xform output
+ "Scalar Interpolate", // scalar interpolation (with optional curve)
+ "Vector Interpolate:", // vec3 interpolation (with optional curve)
+ "Scalar Uniform", // scalar uniform (assignable in material)
+ "Vector Uniform", // vec3 uniform (assignable in material)
+ "RGB Uniform", // color uniform (assignable in material)
+ "XForm Uniform", // mat4 uniform (assignable in material)
+ "Texture Uniform", // texture input (assignable in material)
+ "CubeMap Uniform:", // cubemap input (assignable in material)
+ "Output", // output (shader type dependent)
+ "Comment", // comment
- add_types = memnew( Tree );
- add_types->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- add_types->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
- add_types->set_begin( Point2( 20,25 ) );
- add_types->set_end( Point2( 10, 30 ) );
- add_types->set_hide_root(true);
- add_types->set_columns(4);
- add_types->set_select_mode(Tree::SELECT_ROW);
+};
+ShaderGraphEditor::ShaderGraphEditor() {
- TreeItem *add_types_root = add_types->create_item(NULL);
- TreeItem *info_item = add_types->create_item(add_types_root);
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ menu = memnew( MenuButton );
+ menu->set_text("Add..");
+ hbc->add_child(menu);
+ add_child(hbc);
+ for(int i=0;i<ShaderGraph::NODE_TYPE_MAX;i++) {
- for(int i=0;i<VisualServer::NODE_TYPE_MAX;i++) {
+ if (i==ShaderGraph::NODE_OUTPUT)
+ continue;
+ String v = node_names[i];
+ bool addsep=false;
+ if (v.ends_with(":")) {
+ addsep=true;
+ v=v.substr(0,v.length()-1);
+ }
+ menu->get_popup()->add_item(v,i);
+ if (addsep)
+ menu->get_popup()->add_separator();
+ }
- TreeItem *item = add_types->create_item(add_types_root);
- PropertyInfo prop = VisualServer::shader_node_get_type_info((VisualServer::ShaderNodeType)i);
- item->set_text(0,prop.name);
- item->set_text(1,itos(VisualServer::shader_get_input_count((VisualServer::ShaderNodeType)i)));
- item->set_text(2,itos(VisualServer::shader_get_output_count((VisualServer::ShaderNodeType)i)));
- String hint = (prop.type==Variant::_RID)?prop.hint_string:Variant::get_type_name(prop.type);
- item->set_text(3,hint);
- item->set_metadata(0,i);
+ tabs = memnew(TabContainer);
+ tabs->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(tabs);
+ const char* sname[ShaderGraph::SHADER_TYPE_MAX]={
+ "Vertex",
+ "Fragment",
+ "Light"
+ };
+ for(int i=0;i<ShaderGraph::SHADER_TYPE_MAX;i++) {
+
+ graph_edits[i]= memnew( ShaderGraphView(ShaderGraph::ShaderType(i)) );
+ add_child(graph_edits[i]);
+ graph_edits[i]->get_graph_edit()->set_name(sname[i]);
+ tabs->add_child(graph_edits[i]->get_graph_edit());
+ graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request");
}
- info_item->set_text(0,"::NODE::");
- info_item->set_custom_color(0,Color(0.6,0.1,0.1));
- info_item->set_text(1,"::INPUTS::");
- info_item->set_custom_color(1,Color(0.6,0.1,0.1));
- info_item->set_text(2,"::OUTPUTS::");
- info_item->set_custom_color(2,Color(0.6,0.1,0.1));
- info_item->set_text(3,"::PARAM::");
- info_item->set_custom_color(3,Color(0.6,0.1,0.1));
- info_item->set_selectable(0,false);
- info_item->set_selectable(1,false);
- info_item->set_selectable(2,false);
- info_item->set_selectable(3,false);
-
- add_panel->add_child(add_types);
-
- add_confirm = memnew( Button );
- add_confirm->set_anchor( MARGIN_LEFT, ANCHOR_END );
- add_confirm->set_anchor( MARGIN_TOP, ANCHOR_END );
- add_confirm->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- add_confirm->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
- add_confirm->set_begin( Point2( 75, 29 ) );
- add_confirm->set_end( Point2( 10, 15 ) );
- add_confirm->set_text("Add");
- add_panel->add_child(add_confirm);
- add_confirm->connect("pressed", this,"_node_add_callback");
-
- last_id=1;
- last_x=20;
- last_y=20;
-
- property_editor = memnew( CustomPropertyEditor );
- add_child(property_editor);
- property_editor->connect("variant_changed", this,"_node_param_changed");
-
- h_scroll = memnew( HScrollBar );
- v_scroll = memnew( VScrollBar );
-
- add_child(h_scroll);
- add_child(v_scroll);
-
- h_scroll->connect("value_changed", this,"_scroll_moved");
- v_scroll->connect("value_changed", this,"_scroll_moved");
-
- node_popup= memnew(PopupMenu );
- add_child(node_popup);
- node_popup->set_as_toplevel(true);
-
- node_popup->connect("item_pressed", this,"_node_menu_item");
+ set_custom_minimum_size(Size2(100,300));
}
-void ShaderEditorPlugin::edit(Object *p_object) {
+void ShaderGraphEditorPlugin::edit(Object *p_object) {
- shader_editor->edit(p_object->cast_to<Shader>());
+ shader_editor->edit(p_object->cast_to<ShaderGraph>());
}
-bool ShaderEditorPlugin::handles(Object *p_object) const {
+bool ShaderGraphEditorPlugin::handles(Object *p_object) const {
- return p_object->is_type("Shader");
+ return p_object->is_type("ShaderGraph");
}
-void ShaderEditorPlugin::make_visible(bool p_visible) {
+void ShaderGraphEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
shader_editor->show();
- shader_editor->set_process(true);
} else {
shader_editor->hide();
- shader_editor->set_process(false);
}
}
-ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) {
+ShaderGraphEditorPlugin::ShaderGraphEditorPlugin(EditorNode *p_node) {
editor=p_node;
- shader_editor = memnew( ShaderEditor );
- editor->get_viewport()->add_child(shader_editor);
- shader_editor->set_area_as_parent_rect();
+ shader_editor = memnew( ShaderGraphEditor );
shader_editor->hide();
+ SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor);
+// editor->get_viewport()->add_child(shader_editor);
+// shader_editor->set_area_as_parent_rect();
+// shader_editor->hide();
}
-ShaderEditorPlugin::~ShaderEditorPlugin()
+ShaderGraphEditorPlugin::~ShaderGraphEditorPlugin()
{
}
-#endif
+
diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h
index 5b0767dc82..26dbd1ac6e 100644
--- a/tools/editor/plugins/shader_graph_editor_plugin.h
+++ b/tools/editor/plugins/shader_graph_editor_plugin.h
@@ -29,122 +29,121 @@
#ifndef SHADER_GRAPH_EDITOR_PLUGIN_H
#define SHADER_GRAPH_EDITOR_PLUGIN_H
-#if 0
+
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
#include "scene/resources/shader.h"
#include "servers/visual/shader_graph.h"
#include "scene/gui/tree.h"
#include "scene/gui/button.h"
+#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "tools/editor/property_editor.h"
+#include "scene/resources/shader_graph.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-class ShaderEditor : public Control {
-
- OBJ_TYPE(ShaderEditor, Control );
-
- enum MenuAction {
-
- GRAPH_ADD_NODE,
- GRAPH_CLEAR,
- NODE_DISCONNECT,
- NODE_ERASE,
-
- };
-
- enum ClickType {
- CLICK_NONE,
- CLICK_NODE,
- CLICK_INPUT_SLOT,
- CLICK_OUTPUT_SLOT,
- CLICK_PARAMETER
- };
-
- PopupMenu *node_popup;
- Popup *add_popup;
- PopupMenu *vertex_popup;
- PopupMenu *fragment_popup;
- PopupMenu *post_popup;
- Tree *add_types;
- Button *add_confirm;
- HScrollBar *h_scroll;
- VScrollBar *v_scroll;
-
- Ref<Shader> shader;
- List<int> order;
- Set<int> active_nodes;
- ShaderGraph shader_graph;
- int last_x,last_y;
- uint32_t last_id;
-
- CustomPropertyEditor *property_editor;
-
- Point2 offset;
- ClickType click_type;
- Point2 click_pos;
- int click_node;
- int click_slot;
- Point2 click_motion;
- ClickType rclick_type;
- int rclick_node;
- int rclick_slot;
-
- Size2 _get_maximum_size();
- Size2 get_node_size(int p_node) const;
- void _draw_node(int p_node);
-
- void _add_node_from_text(const String& p_text);
- void _update_scrollbars();
- void _scroll_moved();
- void _node_param_changed();
- void _node_add_callback();
- void _node_add(VisualServer::ShaderNodeType p_type);
- void _node_edit_property(int p_node);
- void _node_menu_item(int p_item);
- void _vertex_item(int p_item);
- void _fragment_item(int p_item);
- void _post_item(int p_item);
-
- ClickType _locate_click(const Point2& p_click,int *p_node_id,int *p_slot_index) const;
- Point2 _get_slot_pos(int p_node_id,bool p_input,int p_slot);
-
- Error validate_graph();
-
- void _read_shader_graph();
- void _write_shader_graph();
-
- virtual bool has_point(const Point2& p_point) const;
+
+class ShaderGraphView : public Node {
+
+ OBJ_TYPE(ShaderGraphView,Node);
+
+
+
+ CustomPropertyEditor *ped_popup;
+ bool block_update;
+
+ GraphEdit *graph_edit;
+ Ref<ShaderGraph> graph;
+ int edited_id;
+
+ ShaderGraph::ShaderType type;
+
+ void _update_graph();
+ void _create_node(int p_id);
+
+
+
+ void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot);
+ void _node_removed(int p_id);
+ void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id);
+ void _move_node(int p_id,const Vector2& p_to);
+
+ void _scalar_const_changed(double p_value,int p_id);
+ void _vec_const_changed(double p_value, int p_id, Array p_arr);
+ void _rgb_const_changed(const Color& p_color, int p_id);
+ void _xform_const_changed(int p_id,Node* p_button);
+ void _scalar_op_changed(int p_op, int p_id);
+ void _vec_op_changed(int p_op, int p_id);
+ void _vec_scalar_op_changed(int p_op, int p_id);
+ void _rgb_op_changed(int p_op, int p_id);
+ void _xform_inv_rev_changed(bool p_enabled, int p_id);
+ void _scalar_func_changed(int p_func, int p_id);
+ void _vec_func_changed(int p_func, int p_id);
+ void _scalar_input_changed(double p_value,int p_id);
+ void _vec_input_changed(double p_value, int p_id, Array p_arr);
+ void _xform_input_changed(int p_id,Node* p_button);
+ void _rgb_input_changed(const Color& p_color, int p_id);
+ void _tex_input_change(int p_id,Node* p_button);
+ void _cube_input_change(int p_id);
+ void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit);
+ void _tex_edited(int p_id,Node* p_button);
+ void _cube_edited(int p_id,Node* p_button);
+ void _variant_edited();
+ void _comment_edited(int p_id,Node* p_button);
+
+
+ Map<int,GraphNode*> node_map;
protected:
void _notification(int p_what);
- void _input_event(InputEvent p_event);
static void _bind_methods();
public:
- void edit(Ref<Shader> p_shader);
- ShaderEditor();
+ void add_node(int p_type);
+ GraphEdit *get_graph_edit() { return graph_edit; }
+ void set_graph(Ref<ShaderGraph> p_graph);
+
+ ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT);
};
-class ShaderEditorPlugin : public EditorPlugin {
+class ShaderGraphEditor : public VBoxContainer {
- OBJ_TYPE( ShaderEditorPlugin, EditorPlugin );
+ OBJ_TYPE(ShaderGraphEditor,VBoxContainer);
- ShaderEditor *shader_editor;
+ MenuButton *menu;
+ TabContainer *tabs;
+ ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX];
+ static const char* node_names[ShaderGraph::NODE_TYPE_MAX];
+
+ void _add_node(int p_type);
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+public:
+
+ void edit(Ref<ShaderGraph> p_shader);
+ ShaderGraphEditor();
+};
+
+class ShaderGraphEditorPlugin : public EditorPlugin {
+
+ OBJ_TYPE( ShaderGraphEditorPlugin, EditorPlugin );
+
+ ShaderGraphEditor *shader_editor;
EditorNode *editor;
public:
- virtual String get_name() const { return "Shader"; }
+ virtual String get_name() const { return "ShaderGraph"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
virtual bool handles(Object *p_node) const;
virtual void make_visible(bool p_visible);
- ShaderEditorPlugin(EditorNode *p_node);
- ~ShaderEditorPlugin();
+ ShaderGraphEditorPlugin(EditorNode *p_node);
+ ~ShaderGraphEditorPlugin();
};
#endif
-#endif // SHADER_GRAPH_EDITOR_PLUGIN_H
+
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index a1f1ccf5e3..0960a961ec 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -535,6 +535,14 @@ SpatialEditorViewport::NavigationScheme SpatialEditorViewport::_get_navigation_s
return NAVIGATION_GODOT;
}
+SpatialEditorViewport::NavigationZoomStyle SpatialEditorViewport::_get_navigation_zoom_style(const String& p_property) {
+ switch(EditorSettings::get_singleton()->get(p_property).operator int()) {
+ case 0: return NAVIGATION_ZOOM_VERTICAL;
+ case 1: return NAVIGATION_ZOOM_HORIZONTAL;
+ }
+ return NAVIGATION_ZOOM_VERTICAL;
+}
+
bool SpatialEditorViewport::_gizmo_select(const Vector2& p_screenpos,bool p_hilite_only) {
if (!spatial_editor->is_gizmo_visible())
@@ -1429,10 +1437,19 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
if (nav_scheme==NAVIGATION_MAYA && m.mod.shift)
zoom_speed *= zoom_speed_modifier;
- if ( m.relative_y > 0)
- cursor.distance*=1+m.relative_y*zoom_speed;
- else if (m.relative_y < 0)
- cursor.distance/=1-m.relative_y*zoom_speed;
+ NavigationZoomStyle zoom_style = _get_navigation_zoom_style("3d_editor/zoom_style");
+ if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) {
+ if ( m.relative_x > 0)
+ cursor.distance*=1-m.relative_x*zoom_speed;
+ else if (m.relative_x < 0)
+ cursor.distance/=1+m.relative_x*zoom_speed;
+ }
+ else {
+ if ( m.relative_y > 0)
+ cursor.distance*=1+m.relative_y*zoom_speed;
+ else if (m.relative_y < 0)
+ cursor.distance/=1-m.relative_y*zoom_speed;
+ }
} break;
diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h
index 1fdc97c49d..646a4d2d86 100644
--- a/tools/editor/plugins/spatial_editor_plugin.h
+++ b/tools/editor/plugins/spatial_editor_plugin.h
@@ -144,6 +144,12 @@ private:
};
NavigationScheme _get_navigation_schema(const String& p_property);
+ enum NavigationZoomStyle {
+ NAVIGATION_ZOOM_VERTICAL,
+ NAVIGATION_ZOOM_HORIZONTAL
+ };
+ NavigationZoomStyle _get_navigation_zoom_style(const String& p_property);
+
enum NavigationMode {
NAVIGATION_NONE,
NAVIGATION_PAN,
diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp
index a25997108b..a7e6a0d1f9 100644
--- a/tools/editor/plugins/tile_map_editor_plugin.cpp
+++ b/tools/editor/plugins/tile_map_editor_plugin.cpp
@@ -42,7 +42,6 @@ void TileMapEditor::_notification(int p_what) {
case NOTIFICATION_READY: {
- pane_drag->connect("dragged", this,"_pane_drag");
mirror_x->set_icon( get_icon("MirrorX","EditorIcons"));
mirror_y->set_icon( get_icon("MirrorY","EditorIcons"));
@@ -701,23 +700,10 @@ void TileMapEditor::_tileset_settings_changed() {
canvas_item_editor->update();
}
-void TileMapEditor::_pane_drag(const Point2& p_to) {
-
- int x = theme_panel->get_margin(MARGIN_RIGHT);
-
- x+=p_to.x;
- if (x<10)
- x=10;
- if (x>300)
- x=300;
- theme_panel->set_margin(MARGIN_RIGHT,x);
-}
-
void TileMapEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_menu_option"),&TileMapEditor::_menu_option);
ObjectTypeDB::bind_method(_MD("_canvas_draw"),&TileMapEditor::_canvas_draw);
- ObjectTypeDB::bind_method(_MD("_pane_drag"),&TileMapEditor::_pane_drag);
ObjectTypeDB::bind_method(_MD("_canvas_mouse_enter"),&TileMapEditor::_canvas_mouse_enter);
ObjectTypeDB::bind_method(_MD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit);
ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed);
@@ -731,36 +717,31 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
editor=p_editor;
undo_redo = editor->get_undo_redo();
- theme_panel = memnew( Panel );
- theme_panel->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
- theme_panel->set_begin( Point2(0,26));
- theme_panel->set_end( Point2(100,0) );
- p_editor->get_viewport()->add_child(theme_panel);
- theme_panel->hide();
+ int mw = EDITOR_DEF("tile_map/palette_min_width",80);
+ Control *ec = memnew( Control);
+ ec->set_custom_minimum_size(Size2(mw,0));
+ add_child(ec);
+ // Add tile palette
palette = memnew( Tree );
- palette->set_area_as_parent_rect(4);
- palette->set_margin(MARGIN_TOP,25);;
- theme_panel->add_child(palette);
-
- pane_drag = memnew( PaneDrag ) ;
- pane_drag->set_anchor(MARGIN_LEFT,ANCHOR_END);
- pane_drag->set_begin(Point2(16,4));
- theme_panel->add_child(pane_drag);
-
- add_child( memnew( VSeparator ));
+ palette->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(palette);
+ // Add menu items
+ canvas_item_editor_hb = memnew( HBoxContainer );
+ CanvasItemEditor::get_singleton()->add_control_to_menu_panel(canvas_item_editor_hb);
+ canvas_item_editor_hb->add_child( memnew( VSeparator ));
mirror_x = memnew( ToolButton );
mirror_x->set_toggle_mode(true);
mirror_x->set_tooltip("Mirror X (A)");
mirror_x->set_focus_mode(FOCUS_NONE);
- add_child(mirror_x);
+ canvas_item_editor_hb->add_child(mirror_x);
mirror_y = memnew( ToolButton );
mirror_y->set_toggle_mode(true);
mirror_y->set_tooltip("Mirror Y (S)");
mirror_y->set_focus_mode(FOCUS_NONE);
- add_child(mirror_y);
-
+ canvas_item_editor_hb->add_child(mirror_y);
+ canvas_item_editor_hb->hide();
tool=TOOL_NONE;
selection_active=false;
@@ -782,12 +763,12 @@ void TileMapEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
tile_map_editor->show();
- tile_map_editor->theme_panel->show();
+ tile_map_editor->get_canvas_item_editor_hb()->show();
} else {
tile_map_editor->hide();
- tile_map_editor->theme_panel->hide();
+ tile_map_editor->get_canvas_item_editor_hb()->hide();
tile_map_editor->edit(NULL);
}
@@ -797,7 +778,8 @@ TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) {
editor=p_node;
tile_map_editor = memnew( TileMapEditor(p_node) );
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(tile_map_editor);
+ CanvasItemEditor::get_singleton()->get_palette_split()->add_child(tile_map_editor);
+ CanvasItemEditor::get_singleton()->get_palette_split()->move_child(tile_map_editor,0);
tile_map_editor->hide();
diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h
index 2336507f1b..ef869591bd 100644
--- a/tools/editor/plugins/tile_map_editor_plugin.h
+++ b/tools/editor/plugins/tile_map_editor_plugin.h
@@ -34,15 +34,14 @@
#include "scene/2d/tile_map.h"
#include "scene/gui/tool_button.h"
#include "scene/gui/button_group.h"
-#include "tools/editor/pane_drag.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class CanvasItemEditor;
-class TileMapEditor : public HBoxContainer {
+class TileMapEditor : public VBoxContainer {
- OBJ_TYPE(TileMapEditor, BoxContainer );
+ OBJ_TYPE(TileMapEditor, VBoxContainer );
UndoRedo *undo_redo;
@@ -63,7 +62,6 @@ class TileMapEditor : public HBoxContainer {
Panel *panel;
TileMap *node;
MenuButton *options;
- PaneDrag *pane_drag;
bool selection_active;
Point2i selection_begin;
@@ -75,6 +73,8 @@ class TileMapEditor : public HBoxContainer {
ToolButton *mirror_x;
ToolButton *mirror_y;
+ HBoxContainer *canvas_item_editor_hb;
+
struct CellOp {
int idx;
@@ -88,7 +88,6 @@ class TileMapEditor : public HBoxContainer {
int get_selected_tile() const;
void _update_palette();
- void _pane_drag(const Point2& p_to);
void _canvas_draw();
void _menu_option(int p_option);
@@ -99,14 +98,13 @@ class TileMapEditor : public HBoxContainer {
void _tileset_settings_changed();
-friend class TileMapEditorPlugin;
- Panel *theme_panel;
protected:
void _notification(int p_what);
void _node_removed(Node *p_node);
static void _bind_methods();
public:
+ HBoxContainer *get_canvas_item_editor_hb() const { return canvas_item_editor_hb; }
Vector2 snap_point(const Vector2& p_point) const;
bool forward_input_event(const InputEvent& p_event);
void edit(Node *p_tile_map);
@@ -120,6 +118,7 @@ class TileMapEditorPlugin : public EditorPlugin {
TileMapEditor *tile_map_editor;
EditorNode *editor;
+
public:
virtual bool forward_input_event(const InputEvent& p_event) { return tile_map_editor->forward_input_event(p_event); }
diff --git a/tools/editor/progress_dialog.cpp b/tools/editor/progress_dialog.cpp
index ac54796c64..df40c5d5a5 100644
--- a/tools/editor/progress_dialog.cpp
+++ b/tools/editor/progress_dialog.cpp
@@ -29,7 +29,7 @@
#include "progress_dialog.h"
#include "main/main.h"
#include "message_queue.h"
-#include "scene/gui/empty_control.h"
+
void BackgroundProgress::_add_task(const String& p_task,const String& p_label, int p_steps) {
@@ -43,12 +43,12 @@ void BackgroundProgress::_add_task(const String& p_task,const String& p_label, i
t.progress = memnew( ProgressBar );
t.progress->set_max(p_steps);
t.progress->set_val(p_steps);
- EmptyControl *ec = memnew( EmptyControl );
+ Control *ec = memnew( Control );
ec->set_h_size_flags(SIZE_EXPAND_FILL);
ec->set_v_size_flags(SIZE_EXPAND_FILL);
t.progress->set_area_as_parent_rect();
ec->add_child(t.progress);
- ec->set_minsize(Size2(80,5));
+ ec->set_custom_minimum_size(Size2(80,5));
t.hb->add_child(ec);
add_child(t.hb);
diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp
index 3a0f1e76b5..449e54e12f 100644
--- a/tools/editor/project_export.cpp
+++ b/tools/editor/project_export.cpp
@@ -1240,8 +1240,8 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
group_options->add_child(atlas_preview);
atlas_preview->show();
atlas_preview->connect("pressed",this,"_group_atlas_preview");
- EmptyControl *ec = memnew(EmptyControl );
- ec->set_minsize(Size2(150,1));
+ Control *ec = memnew(Control );
+ ec->set_custom_minimum_size(Size2(150,1));
gvb->add_child(ec);
VBoxContainer *group_vb_right = memnew( VBoxContainer );
diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h
index dfe7a2d900..e437497dd2 100644
--- a/tools/editor/project_export.h
+++ b/tools/editor/project_export.h
@@ -40,7 +40,7 @@
#include "os/dir_access.h"
#include "os/thread.h"
#include "scene/gui/option_button.h"
-#include "scene/gui/empty_control.h"
+
#include "scene/gui/slider.h"
#include "tools/editor/editor_file_system.h"
#include "property_editor.h"
diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp
index 4eadd980f4..cf94758ad6 100644
--- a/tools/editor/project_manager.cpp
+++ b/tools/editor/project_manager.cpp
@@ -39,7 +39,7 @@
#include "scene/gui/line_edit.h"
#include "scene/gui/panel_container.h"
-#include "scene/gui/empty_control.h"
+
#include "scene/gui/texture_frame.h"
#include "scene/gui/margin_container.h"
#include "io/resource_saver.h"
@@ -580,8 +580,8 @@ void ProjectManager::_load_recent_projects() {
VBoxContainer *vb = memnew(VBoxContainer);
hb->add_child(vb);
- EmptyControl *ec = memnew( EmptyControl );
- ec->set_minsize(Size2(0,1));
+ Control *ec = memnew( Control );
+ ec->set_custom_minimum_size(Size2(0,1));
vb->add_child(ec);
Label *title = memnew( Label(project_name) );
title->add_font_override("font",get_font("large","Fonts"));
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 777694481b..a600683097 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -142,7 +142,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
}
String orig_type = res_orig->get_type();
- print_line("orig type: "+orig_type);
+
Object *inst = ObjectTypeDB::instance( orig_type );
Ref<Resource> res = Ref<Resource>( inst->cast_to<Resource>() );
@@ -187,6 +187,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
ERR_FAIL_COND( inheritors_array.empty() );
+
String intype=inheritors_array[p_which-TYPE_BASE_ID];
Object *obj = ObjectTypeDB::instance(intype);
@@ -603,6 +604,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
if (hint_text!="") {
+ int idx=0;
for(int i=0;i<hint_text.get_slice_count(",");i++) {
@@ -620,19 +622,19 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
E=E->next();
}
- int idx=0;
for(Set<String>::Element *E=valid_inheritors.front();E;E=E->next()) {
String t = E->get();
if (!ObjectTypeDB::can_instance(t))
continue;
inheritors_array.push_back(t);
+ int id = TYPE_BASE_ID+idx;
if (has_icon(t,"EditorIcons")) {
- menu->add_icon_item(get_icon(t,"EditorIcons"),"New "+t,TYPE_BASE_ID+idx);
+ menu->add_icon_item(get_icon(t,"EditorIcons"),"New "+t,id);
} else {
- menu->add_item("New "+t,TYPE_BASE_ID+idx);
+ menu->add_item("New "+t,id);
}
idx++;
@@ -970,9 +972,11 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
if (p_which==0) {
+
ERR_FAIL_COND( inheritors_array.empty() );
String intype=inheritors_array[0];
+
if (hint==PROPERTY_HINT_RESOURCE_TYPE) {
@@ -1876,6 +1880,14 @@ void PropertyEditor::_notification(int p_what) {
if (p_what==NOTIFICATION_FIXED_PROCESS) {
+ if (refresh_countdown>0) {
+ refresh_countdown-=get_fixed_process_delta_time();
+ if (refresh_countdown<=0) {
+ TreeItem *root = tree->get_root();
+ _refresh_item(root);
+ }
+ }
+
changing=true;
if (update_tree_pending) {
@@ -1982,7 +1994,71 @@ TreeItem *PropertyEditor::get_parent_node(String p_path,HashMap<String,TreeItem*
}
+void PropertyEditor::_refresh_item(TreeItem *p_item) {
+
+ if (!p_item)
+ return;
+
+ String name = p_item->get_metadata(1);
+
+ if (name!=String()) {
+
+ if (get_instanced_node()) {
+
+ Dictionary d = get_instanced_node()->get_instance_state();
+ if (d.has(name)) {
+ Variant v = obj->get(name);
+ Variant vorig = d[name];
+
+ int found=-1;
+ for(int i=0;i<p_item->get_button_count(1);i++) {
+
+ if (p_item->get_button_id(1,i)==3) {
+ found=i;
+ break;
+ }
+ }
+
+ bool changed = ! (v==vorig);
+
+ if ((found!=-1)!=changed) {
+
+ if (changed) {
+
+ p_item->add_button(1,get_icon("Reload","EditorIcons"),3);
+ } else {
+
+ p_item->erase_button(1,found);
+ }
+
+ }
+
+ }
+
+ }
+
+ Dictionary d=p_item->get_metadata(0);
+ set_item_text(p_item,d["type"],d["name"],d["hint"],d["hint_text"]);
+ }
+
+ TreeItem *c=p_item->get_children();
+
+ while (c) {
+
+ _refresh_item(c);
+
+ c=c->get_next();
+ }
+
+}
+
+void PropertyEditor::refresh() {
+
+ if (refresh_countdown>0)
+ return;
+ refresh_countdown=EditorSettings::get_singleton()->get("property_editor/auto_refresh_interval");
+}
void PropertyEditor::update_tree() {
@@ -3021,6 +3097,7 @@ PropertyEditor::PropertyEditor() {
keying=false;
read_only=false;
show_categories=false;
+ refresh_countdown=0;
}
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index 08435ad75d..c05e13b90e 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -156,6 +156,7 @@ class PropertyEditor : public Control {
bool keying;
bool read_only;
bool show_categories;
+ float refresh_countdown;
HashMap<String,String> pending;
String selected_property;
@@ -185,6 +186,7 @@ class PropertyEditor : public Control {
void _draw_flags(Object *ti,const Rect2& p_rect);
Node *get_instanced_node();
+ void _refresh_item(TreeItem *p_item);
UndoRedo *undo_redo;
protected:
@@ -203,6 +205,8 @@ public:
void update_tree();
void update_property(const String& p_prop);
+ void refresh();
+
void edit(Object* p_object);
void set_keying(bool p_active);