diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/connections_dialog.cpp | 7 | ||||
-rw-r--r-- | editor/editor_node.cpp | 44 | ||||
-rw-r--r-- | editor/editor_spin_slider.cpp | 56 | ||||
-rw-r--r-- | editor/node_dock.cpp | 7 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.cpp | 112 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 99 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 9 | ||||
-rw-r--r-- | editor/scene_tree_editor.cpp | 33 |
8 files changed, 228 insertions, 139 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 48bc409b73..c5b81c4685 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -881,7 +881,6 @@ void ConnectionsDock::update_tree() { icon = get_icon(scr->get_class(), "EditorIcons"); } } - } else { ClassDB::get_signal_list(base, &node_signals2, true); @@ -891,6 +890,10 @@ void ConnectionsDock::update_tree() { name = base; } + if (!icon.is_valid()) { + icon = get_icon("Object", "EditorIcons"); + } + TreeItem *pitem = NULL; if (node_signals2.size()) { @@ -939,7 +942,7 @@ void ConnectionsDock::update_tree() { item->set_metadata(0, sinfo); item->set_icon(0, get_icon("Signal", "EditorIcons")); - // Set tooltip with the signal's documentation + // Set tooltip with the signal's documentation. { String descr; bool found = false; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 1b0ffd4c89..311f8b295b 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2921,31 +2921,35 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, return; } - String path = cf->get_value("plugin", "script"); - path = String("res://addons").plus_file(p_addon).plus_file(path); + String script_path = cf->get_value("plugin", "script"); + Ref<Script> script; // We need to save it for creating "ep" below. - Ref<Script> script = ResourceLoader::load(path); + // Only try to load the script if it has a name. Else, the plugin has no init script. + if (script_path.length() > 0) { + script_path = String("res://addons").plus_file(p_addon).plus_file(script_path); + script = ResourceLoader::load(script_path); - if (script.is_null()) { - show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), path)); - return; - } + if (script.is_null()) { + show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), script_path)); + return; + } - //errors in the script cause the base_type to be "" - if (String(script->get_instance_base_type()) == "") { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), path)); - return; - } + // Errors in the script cause the base_type to be an empty string. + if (String(script->get_instance_base_type()) == "") { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), script_path)); + return; + } - //could check inheritance.. - if (String(script->get_instance_base_type()) != "EditorPlugin") { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), path)); - return; - } + // Plugin init scripts must inherit from EditorPlugin and be tools. + if (String(script->get_instance_base_type()) != "EditorPlugin") { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), script_path)); + return; + } - if (!script->is_tool()) { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), path)); - return; + if (!script->is_tool()) { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), script_path)); + return; + } } EditorPlugin *ep = memnew(EditorPlugin); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 379b8a2980..46a30b7554 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -47,42 +47,48 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { return; Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid()) { - if (mb->is_pressed()) { + if (mb->get_button_index() == BUTTON_LEFT) { + if (mb->is_pressed()) { - if (updown_offset != -1 && mb->get_position().x > updown_offset) { - //there is an updown, so use it. - if (mb->get_position().y < get_size().height / 2) { - set_value(get_value() + get_step()); + if (updown_offset != -1 && mb->get_position().x > updown_offset) { + //there is an updown, so use it. + if (mb->get_position().y < get_size().height / 2) { + set_value(get_value() + get_step()); + } else { + set_value(get_value() - get_step()); + } + return; } else { - set_value(get_value() - get_step()); + + grabbing_spinner_attempt = true; + grabbing_spinner_dist_cache = 0; + pre_grab_value = get_value(); + grabbing_spinner = false; + grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position(); } - return; } else { - grabbing_spinner_attempt = true; - grabbing_spinner_dist_cache = 0; - pre_grab_value = get_value(); - grabbing_spinner = false; - grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position(); - } - } else { + if (grabbing_spinner_attempt) { - if (grabbing_spinner_attempt) { + if (grabbing_spinner) { - if (grabbing_spinner) { + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos); + update(); + } else { + _focus_entered(); + } - Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); - Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos); - update(); - } else { - _focus_entered(); + grabbing_spinner = false; + grabbing_spinner_attempt = false; } - - grabbing_spinner = false; - grabbing_spinner_attempt = false; } + } else if (mb->get_button_index() == BUTTON_WHEEL_UP || mb->get_button_index() == BUTTON_WHEEL_DOWN) { + + if (grabber->is_visible()) + call_deferred("update"); } } diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp index 1c0151ed0a..d6df3bd369 100644 --- a/editor/node_dock.cpp +++ b/editor/node_dock.cpp @@ -56,10 +56,7 @@ void NodeDock::_bind_methods() { void NodeDock::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - connections_button->set_icon(get_icon("Signals", "EditorIcons")); - groups_button->set_icon(get_icon("Groups", "EditorIcons")); - } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { connections_button->set_icon(get_icon("Signals", "EditorIcons")); groups_button->set_icon(get_icon("Groups", "EditorIcons")); } @@ -131,7 +128,7 @@ NodeDock::NodeDock() { groups->hide(); select_a_node = memnew(Label); - select_a_node->set_text(TTR("Select a Node to edit Signals and Groups.")); + select_a_node->set_text(TTR("Select a single node to edit its signals and groups.")); select_a_node->set_v_size_flags(SIZE_EXPAND_FILL); select_a_node->set_valign(Label::VALIGN_CENTER); select_a_node->set_align(Label::ALIGN_CENTER); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 20a06f3ac0..2eb3ce1ec3 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -5176,7 +5176,7 @@ void SpatialEditor::snap_selected_nodes_to_floor() { // We add a bit of margin to the from position to avoid it from snapping // when the spatial is already on a floor and there's another floor under // it - from = from + Vector3(0.0, 0.1, 0.0); + from = from + Vector3(0.0, 0.2, 0.0); Dictionary d; @@ -5191,31 +5191,56 @@ void SpatialEditor::snap_selected_nodes_to_floor() { Array keys = snap_data.keys(); - if (keys.size()) { - undo_redo->create_action(TTR("Snap Nodes To Floor")); + // The maximum height an object can travel to be snapped + const float max_snap_height = 20.0; + + // Will be set to `true` if at least one node from the selection was sucessfully snapped + bool snapped_to_floor = false; + if (keys.size()) { + // For snapping to be performed, there must be solid geometry under at least one of the selected nodes. + // We need to check this before snapping to register the undo/redo action only if needed. for (int i = 0; i < keys.size(); i++) { Node *node = keys[i]; Spatial *sp = Object::cast_to<Spatial>(node); - Dictionary d = snap_data[node]; Vector3 from = d["from"]; - Vector3 position_offset = d["position_offset"]; - - Vector3 to = from - Vector3(0.0, 10.0, 0.0); + Vector3 to = from - Vector3(0.0, max_snap_height, 0.0); Set<RID> excluded = _get_physics_bodies_rid(sp); if (ss->intersect_ray(from, to, result, excluded)) { - Transform new_transform = sp->get_global_transform(); - new_transform.origin.y = result.position.y; - new_transform.origin = new_transform.origin - position_offset; - - undo_redo->add_do_method(sp, "set_global_transform", new_transform); - undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform()); + snapped_to_floor = true; } } - undo_redo->commit_action(); + if (snapped_to_floor) { + undo_redo->create_action(TTR("Snap Nodes To Floor")); + + // Perform snapping if at least one node can be snapped + for (int i = 0; i < keys.size(); i++) { + Node *node = keys[i]; + Spatial *sp = Object::cast_to<Spatial>(node); + Dictionary d = snap_data[node]; + Vector3 from = d["from"]; + Vector3 to = from - Vector3(0.0, max_snap_height, 0.0); + Set<RID> excluded = _get_physics_bodies_rid(sp); + + if (ss->intersect_ray(from, to, result, excluded)) { + Vector3 position_offset = d["position_offset"]; + Transform new_transform = sp->get_global_transform(); + + new_transform.origin.y = result.position.y; + new_transform.origin = new_transform.origin - position_offset; + + undo_redo->add_do_method(sp, "set_global_transform", new_transform); + undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform()); + } + } + + undo_redo->commit_action(); + } else { + EditorNode::get_singleton()->show_warning(TTR("Couldn't find a solid floor to snap the selection to.")); + } } } @@ -5225,42 +5250,6 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) { return; snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL); - - Ref<InputEventKey> k = p_event; - - if (k.is_valid()) { - - // Note: need to check is_echo because first person movement keys might still be held - if (!is_any_freelook_active() && !p_event->is_echo()) { - - if (!k->is_pressed()) - return; - - if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event)) { - _menu_item_pressed(MENU_TOOL_SELECT); - } else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event)) { - _menu_item_pressed(MENU_TOOL_MOVE); - } else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event)) { - _menu_item_pressed(MENU_TOOL_ROTATE); - } else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) { - _menu_item_pressed(MENU_TOOL_SCALE); - } else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event)) { - snap_selected_nodes_to_floor(); - } else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) { - if (are_local_coords_enabled()) { - _menu_item_toggled(false, MENU_TOOL_LOCAL_COORDS); - } else { - _menu_item_toggled(true, MENU_TOOL_LOCAL_COORDS); - } - } else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) { - if (is_snap_enabled()) { - _menu_item_toggled(false, MENU_TOOL_USE_SNAP); - } else { - _menu_item_toggled(true, MENU_TOOL_USE_SNAP); - } - } - } - } } void SpatialEditor::_notification(int p_what) { @@ -5534,7 +5523,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SELECT]->set_pressed(true); button_binds.write[0] = MENU_TOOL_SELECT; tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds); - tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection")); + tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q)); + tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection")); hbc_menu->add_child(memnew(VSeparator)); @@ -5544,7 +5534,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_MOVE]->set_flat(true); button_binds.write[0] = MENU_TOOL_MOVE; tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds); - tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)")); + tool_button[TOOL_MODE_MOVE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_move", TTR("Move Mode"), KEY_W)); tool_button[TOOL_MODE_ROTATE] = memnew(ToolButton); hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]); @@ -5552,7 +5542,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_ROTATE]->set_flat(true); button_binds.write[0] = MENU_TOOL_ROTATE; tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds); - tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)")); + tool_button[TOOL_MODE_ROTATE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Rotate Mode"), KEY_E)); tool_button[TOOL_MODE_SCALE] = memnew(ToolButton); hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]); @@ -5560,7 +5550,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SCALE]->set_flat(true); button_binds.write[0] = MENU_TOOL_SCALE; tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds); - tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)")); + tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), KEY_R)); hbc_menu->add_child(memnew(VSeparator)); @@ -5604,9 +5594,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true); button_binds.write[0] = MENU_TOOL_LOCAL_COORDS; tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds); - ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T); - sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text(); - tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_tooltip(vformat(TTR("Local Space Mode (%s)"), sct)); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Use Local Space"), KEY_T)); tool_option_button[TOOL_OPT_USE_SNAP] = memnew(ToolButton); hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]); @@ -5614,9 +5602,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true); button_binds.write[0] = MENU_TOOL_USE_SNAP; tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds); - ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y); - sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text(); - tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct)); + tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), KEY_Y)); hbc_menu->add_child(memnew(VSeparator)); @@ -5636,12 +5622,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F); ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_M); ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F); - - ED_SHORTCUT("spatial_editor/tool_select", TTR("Tool Select"), KEY_Q); - ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W); - ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E); - ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R); - ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F); PopupMenu *p; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index e193e237de..619fb15a68 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -69,8 +69,16 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { } } visual_shader = Ref<VisualShader>(p_visual_shader); + if (!visual_shader->is_connected("changed", this, "_update_preview")) { + visual_shader->connect("changed", this, "_update_preview"); + } visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE); } else { + if (visual_shader.is_valid()) { + if (visual_shader->is_connected("changed", this, "")) { + visual_shader->disconnect("changed", this, "_update_preview"); + } + } visual_shader.unref(); } @@ -81,6 +89,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { _clear_buffer(); _update_custom_nodes(); _update_options_menu(); + _update_preview(); } _update_graph(); } @@ -524,21 +533,23 @@ void VisualShaderEditor::_update_graph() { offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE)); node->add_child(offset); - HBoxContainer *hb2 = memnew(HBoxContainer); + if (group_node->is_editable()) { + HBoxContainer *hb2 = memnew(HBoxContainer); - Button *add_input_btn = memnew(Button); - add_input_btn->set_text(TTR("Add input +")); - add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED); - hb2->add_child(add_input_btn); + Button *add_input_btn = memnew(Button); + add_input_btn->set_text(TTR("Add input +")); + add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED); + hb2->add_child(add_input_btn); - hb2->add_spacer(); + hb2->add_spacer(); - Button *add_output_btn = memnew(Button); - add_output_btn->set_text(TTR("Add output +")); - add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED); - hb2->add_child(add_output_btn); + Button *add_output_btn = memnew(Button); + add_output_btn->set_text(TTR("Add output +")); + add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED); + hb2->add_child(add_output_btn); - node->add_child(hb2); + node->add_child(hb2); + } } for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { @@ -1566,6 +1577,29 @@ void VisualShaderEditor::_notification(int p_what) { node_filter->set_right_icon(Control::get_icon("Search", "EditorIcons")); + preview_shader->set_icon(Control::get_icon("Shader", "EditorIcons")); + + { + Color background_color = EDITOR_GET("text_editor/highlighting/background_color"); + Color text_color = EDITOR_GET("text_editor/highlighting/text_color"); + Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color"); + Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color"); + Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color"); + + preview_text->add_color_override("background_color", background_color); + + for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) { + + preview_text->add_keyword_color(E->get(), keyword_color); + } + + preview_text->add_font_override("font", get_font("expression", "EditorFonts")); + preview_text->add_color_override("font_color", text_color); + preview_text->add_color_override("symbol_color", symbol_color); + preview_text->add_color_region("/*", "*/", comment_color, false); + preview_text->add_color_region("//", "", comment_color, false); + } + tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Tools", "EditorIcons")); if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) @@ -2016,6 +2050,15 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } } +void VisualShaderEditor::_show_preview_text() { + preview_showed = !preview_showed; + preview_text->set_visible(preview_showed); +} + +void VisualShaderEditor::_update_preview() { + preview_text->set_text(visual_shader->get_code()); +} + void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_rebuild", &VisualShaderEditor::_rebuild); ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph); @@ -2055,6 +2098,8 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_node_resized", &VisualShaderEditor::_node_resized); ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size); ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer); + ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text); + ClassDB::bind_method("_update_preview", &VisualShaderEditor::_update_preview); ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw); @@ -2081,13 +2126,23 @@ VisualShaderEditor::VisualShaderEditor() { saved_node_pos = Point2(0, 0); ShaderLanguage::get_keyword_list(&keyword_list); + preview_showed = false; + to_node = -1; to_slot = -1; from_node = -1; from_slot = -1; + main_box = memnew(HSplitContainer); + main_box->set_v_size_flags(SIZE_EXPAND_FILL); + main_box->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(main_box); + graph = memnew(GraphEdit); - add_child(graph); + graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL); + graph->set_v_size_flags(SIZE_EXPAND_FILL); + graph->set_h_size_flags(SIZE_EXPAND_FILL); + main_box->add_child(graph); graph->set_drag_forwarding(this); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN); @@ -2136,6 +2191,25 @@ VisualShaderEditor::VisualShaderEditor() { graph->get_zoom_hbox()->move_child(add_node, 0); add_node->connect("pressed", this, "_show_members_dialog", varray(false)); + preview_shader = memnew(ToolButton); + preview_shader->set_toggle_mode(true); + preview_shader->set_tooltip(TTR("Show resulted shader code.")); + graph->get_zoom_hbox()->add_child(preview_shader); + preview_shader->connect("pressed", this, "_show_preview_text"); + + /////////////////////////////////////// + // PREVIEW PANEL + /////////////////////////////////////// + + preview_text = memnew(TextEdit); + main_box->add_child(preview_text); + preview_text->set_h_size_flags(SIZE_EXPAND_FILL); + preview_text->set_v_size_flags(SIZE_EXPAND_FILL); + preview_text->set_visible(preview_showed); + preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0)); + preview_text->set_syntax_coloring(true); + preview_text->set_readonly(true); + /////////////////////////////////////// // SHADER NODES TREE /////////////////////////////////////// @@ -2528,6 +2602,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside."))); add_options.push_back(AddOption("Fresnel", "Special", "", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants."))); add_options.push_back(AddOption("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); add_options.push_back(AddOption("VectorDerivativeFunc", "Special", "Common", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) Vector derivative function."), -1, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index b5b00f2b5e..1556c7cd43 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -60,14 +60,18 @@ class VisualShaderEditor : public VBoxContainer { int editing_port; Ref<VisualShader> visual_shader; + HSplitContainer *main_box; GraphEdit *graph; ToolButton *add_node; + ToolButton *preview_shader; OptionButton *edit_type; PanelContainer *error_panel; Label *error_label; + TextEdit *preview_text; + UndoRedo *undo_redo; Point2 saved_node_pos; bool saved_node_pos_dirty; @@ -75,6 +79,8 @@ class VisualShaderEditor : public VBoxContainer { ConfirmationDialog *members_dialog; MenuButton *tools; + bool preview_showed; + enum ToolsMenuOptions { EXPAND_ALL, COLLAPSE_ALL @@ -146,6 +152,9 @@ class VisualShaderEditor : public VBoxContainer { void _update_custom_nodes(); void _update_options_menu(); + void _show_preview_text(); + void _update_preview(); + static VisualShaderEditor *singleton; void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 458d8273c5..43f540e688 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -270,15 +270,30 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->add_button(0, get_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning()); } - bool has_connections = p_node->has_persistent_signal_connections(); - bool has_groups = p_node->has_persistent_groups(); - - if (has_connections && has_groups) { - item->add_button(0, get_icon("SignalsAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s).\nClick to show signals dock.")); - } else if (has_connections) { - item->add_button(0, get_icon("Signals", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock.")); - } else if (has_groups) { - item->add_button(0, get_icon("Groups", "EditorIcons"), BUTTON_GROUPS, false, TTR("Node is in group(s).\nClick to show groups dock.")); + int num_connections = p_node->get_persistent_signal_connection_count(); + int num_groups = p_node->get_persistent_group_count(); + + if (num_connections >= 1 && num_groups >= 1) { + item->add_button( + 0, + get_icon("SignalsAndGroups", "EditorIcons"), + BUTTON_SIGNALS, + false, + vformat(TTR("Node has %s connection(s) and %s group(s).\nClick to show signals dock."), num_connections, num_groups)); + } else if (num_connections >= 1) { + item->add_button( + 0, + get_icon("Signals", "EditorIcons"), + BUTTON_SIGNALS, + false, + vformat(TTR("Node has %s connection(s).\nClick to show signals dock."), num_connections)); + } else if (num_groups >= 1) { + item->add_button( + 0, + get_icon("Groups", "EditorIcons"), + BUTTON_GROUPS, + false, + vformat(TTR("Node is in %s group(s).\nClick to show groups dock."), num_groups)); } } |