summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp33
-rw-r--r--editor/plugins/animation_player_editor_plugin.h1
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp41
-rw-r--r--editor/plugins/script_editor_plugin.cpp78
-rw-r--r--editor/plugins/script_text_editor.cpp93
-rw-r--r--editor/plugins/script_text_editor.h3
-rw-r--r--editor/plugins/shader_editor_plugin.cpp41
-rw-r--r--editor/plugins/shader_editor_plugin.h2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp11
-rw-r--r--editor/plugins/text_editor.cpp64
-rw-r--r--editor/plugins/text_editor.h4
-rw-r--r--editor/plugins/theme_editor_plugin.cpp12
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp8
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp21
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp202
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h6
16 files changed, 382 insertions, 238 deletions
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 5163b372b2..f42716c827 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/animation_track_editor.h"
@@ -293,10 +294,6 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
}
}
frame->set_max(anim->get_length());
- if (anim->get_step())
- frame->set_step(anim->get_step());
- else
- frame->set_step(0.00001);
} else {
track_editor->set_animation(Ref<Animation>());
@@ -1008,7 +1005,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
};
updating = true;
- String current = player->get_assigned_animation(); //animation->get_item_text( animation->get_selected() );
+ String current = player->get_assigned_animation();
if (current == "" || !player->has_animation(current)) {
updating = false;
current = "";
@@ -1018,14 +1015,9 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
Ref<Animation> anim;
anim = player->get_animation(current);
- float pos = anim->get_length() * (p_value / frame->get_max());
- float step = anim->get_step();
- if (step) {
- pos = Math::stepify(pos, step);
- if (pos < 0)
- pos = 0;
- if (pos >= anim->get_length())
- pos = anim->get_length();
+ float pos = CLAMP(anim->get_length() * (p_value / frame->get_max()), 0, anim->get_length());
+ if (track_editor->is_snap_enabled()) {
+ pos = Math::stepify(pos, anim->get_step());
}
if (player->is_valid() && !p_set) {
@@ -1063,14 +1055,6 @@ void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len)
frame->set_max(p_len);
}
-void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len) {
-
- if (p_len)
- frame->set_step(p_len);
- else
- frame->set_step(0.00001);
-}
-
void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) {
if (!is_visible_in_tree())
@@ -1081,8 +1065,10 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag)
if (player->is_playing())
return;
+ Ref<Animation> anim = player->get_animation(player->get_assigned_animation());
+
updating = true;
- frame->set_value(p_pos);
+ frame->set_value(Math::stepify(p_pos, track_editor->is_snap_enabled() ? anim->get_step() : 0));
updating = false;
_seek_value_changed(p_pos, !p_drag);
@@ -1558,7 +1544,6 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed);
ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"), &AnimationPlayerEditor::_animation_key_editor_seek);
ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_len_changed);
- ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_step_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_step_changed);
ClassDB::bind_method(D_METHOD("_hide_anim_editors"), &AnimationPlayerEditor::_hide_anim_editors);
ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"), &AnimationPlayerEditor::_blend_editor_next_changed);
@@ -1621,6 +1606,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
hb->add_child(frame);
frame->set_custom_minimum_size(Size2(60, 0));
frame->set_stretch_ratio(2);
+ frame->set_step(0.0001);
frame->set_tooltip(TTR("Animation position (in seconds)."));
hb->add_child(memnew(VSeparator));
@@ -1774,7 +1760,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
track_editor->set_v_size_flags(SIZE_EXPAND_FILL);
track_editor->connect("timeline_changed", this, "_animation_key_editor_seek");
track_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed");
- track_editor->connect("animation_step_changed", this, "_animation_key_editor_anim_step_changed");
_update_player();
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 398ef6ff14..22152fa8f4 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -203,7 +203,6 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_key_editor_seek(float p_pos, bool p_drag);
void _animation_key_editor_anim_len_changed(float p_len);
- void _animation_key_editor_anim_step_changed(float p_len);
void _unhandled_key_input(const Ref<InputEvent> &p_ev);
void _animation_tool_menu(int p_option);
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 31b11d8bea..5679426eb5 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -333,18 +333,14 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
switch (p_status) {
- case HTTPRequest::RESULT_CANT_RESOLVE: {
- error_text = TTR("Can't resolve hostname:") + " " + host;
- status->set_text(TTR("Can't resolve."));
- } break;
- case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED:
+ case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH:
case HTTPRequest::RESULT_CONNECTION_ERROR:
- case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: {
+ case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: {
error_text = TTR("Connection error, please try again.");
status->set_text(TTR("Can't connect."));
} break;
- case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
- case HTTPRequest::RESULT_CANT_CONNECT: {
+ case HTTPRequest::RESULT_CANT_CONNECT:
+ case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: {
error_text = TTR("Can't connect to host:") + " " + host;
status->set_text(TTR("Can't connect."));
} break;
@@ -352,13 +348,26 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
error_text = TTR("No response from host:") + " " + host;
status->set_text(TTR("No response."));
} break;
+ case HTTPRequest::RESULT_CANT_RESOLVE: {
+ error_text = TTR("Can't resolve hostname:") + " " + host;
+ status->set_text(TTR("Can't resolve."));
+ } break;
case HTTPRequest::RESULT_REQUEST_FAILED: {
error_text = TTR("Request failed, return code:") + " " + itos(p_code);
- status->set_text(TTR("Request Failed."));
+ status->set_text(TTR("Request failed."));
+ } break;
+ case HTTPRequest::RESULT_DOWNLOAD_FILE_CANT_OPEN:
+ case HTTPRequest::RESULT_DOWNLOAD_FILE_WRITE_ERROR: {
+ error_text = TTR("Cannot save response to:") + " " + download->get_download_file();
+ status->set_text(TTR("Write error."));
} break;
case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
error_text = TTR("Request failed, too many redirects");
- status->set_text(TTR("Redirect Loop."));
+ status->set_text(TTR("Redirect loop."));
+ } break;
+ case HTTPRequest::RESULT_TIMEOUT: {
+ error_text = TTR("Request failed, timeout");
+ status->set_text(TTR("Timeout."));
} break;
default: {
if (p_code != 200) {
@@ -398,8 +407,6 @@ void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asse
icon->set_texture(get_icon("DefaultProjectIcon", "EditorIcons"));
host = p_download_url;
sha256 = p_sha256_hash;
- asset_installer->connect("confirmed", this, "_close");
- dismiss->set_normal_texture(get_icon("Close", "EditorIcons"));
_make_request();
}
@@ -407,9 +414,11 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
+ // FIXME: The editor crashes if 'NOTICATION_THEME_CHANGED' is used.
+ case NOTIFICATION_ENTER_TREE: {
add_style_override("panel", get_stylebox("panel", "TabContainer"));
+ dismiss->set_normal_texture(get_icon("Close", "EditorIcons"));
} break;
case NOTIFICATION_PROCESS: {
@@ -463,9 +472,8 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
}
void EditorAssetLibraryItemDownload::_close() {
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->remove(download->get_download_file()); //clean up removed file
- memdelete(da);
+ // Clean up downloaded file.
+ DirAccess::remove_file_or_error(download->get_download_file());
queue_delete();
}
@@ -562,6 +570,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
asset_installer = memnew(EditorAssetInstaller);
add_child(asset_installer);
+ asset_installer->connect("confirmed", this, "_close");
prev_status = -1;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 9418349d71..1072c3cad1 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -44,6 +44,7 @@
#include "editor/script_editor_debugger.h"
#include "scene/main/viewport.h"
#include "script_text_editor.h"
+#include "text_editor.h"
/*** SCRIPT EDITOR ****/
@@ -55,7 +56,7 @@ void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line")));
ADD_SIGNAL(MethodInfo("request_save_history"));
ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what")));
- // TODO This signal is no use for VisualScript...
+ // TODO: This signal is no use for VisualScript.
ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
}
@@ -204,11 +205,13 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
connect("confirmed", this, "_confirmed");
- search_box->set_right_icon(get_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
+ FALLTHROUGH;
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
} break;
case NOTIFICATION_EXIT_TREE: {
disconnect("confirmed", this, "_confirmed");
@@ -241,6 +244,8 @@ ScriptEditorQuickOpen::ScriptEditorQuickOpen() {
set_hide_on_ok(false);
search_options->connect("item_activated", this, "_confirmed");
search_options->set_hide_root(true);
+ search_options->set_hide_folding(true);
+ search_options->add_constant_override("draw_guides", 1);
}
/////////////////////////////////
@@ -1067,6 +1072,7 @@ void ScriptEditor::_menu_option(int p_option) {
save_all_scripts();
} break;
case SEARCH_IN_FILES: {
+
_on_find_in_files_requested("");
} break;
case SEARCH_HELP: {
@@ -1419,15 +1425,25 @@ void ScriptEditor::_notification(int p_what) {
}
EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed");
+ FALLTHROUGH;
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+
help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
site_search->set_icon(get_icon("Instance", "EditorIcons"));
request_docs->set_icon(get_icon("Issue", "EditorIcons"));
script_forward->set_icon(get_icon("Forward", "EditorIcons"));
script_back->set_icon(get_icon("Back", "EditorIcons"));
+
members_overview_alphabeta_sort_button->set_icon(get_icon("Sort", "EditorIcons"));
+
filter_scripts->set_right_icon(get_icon("Search", "EditorIcons"));
filter_methods->set_right_icon(get_icon("Search", "EditorIcons"));
+
+ filename->add_style_override("normal", editor->get_gui_base()->get_stylebox("normal", "LineEdit"));
+
+ recent_scripts->set_as_minsize();
} break;
case NOTIFICATION_READY: {
@@ -1450,20 +1466,6 @@ void ScriptEditor::_notification(int p_what) {
_update_modified_scripts_for_external_editor();
} break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
- help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
- site_search->set_icon(get_icon("Instance", "EditorIcons"));
-
- script_forward->set_icon(get_icon("Forward", "EditorIcons"));
- script_back->set_icon(get_icon("Back", "EditorIcons"));
-
- members_overview_alphabeta_sort_button->set_icon(get_icon("Sort", "EditorIcons"));
- filename->add_style_override("normal", editor->get_gui_base()->get_stylebox("normal", "LineEdit"));
-
- recent_scripts->set_as_minsize();
- } break;
-
case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
@@ -2988,18 +2990,38 @@ void ScriptEditor::_on_find_in_files_requested(String text) {
void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) {
- RES res = ResourceLoader::load(fpath);
- if (fpath.get_extension() == "shader") {
- ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
- shader_editor->edit(res.ptr());
- shader_editor->make_visible(true);
- shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
- } else {
- edit(res);
+ if (ResourceLoader::exists(fpath)) {
+ RES res = ResourceLoader::load(fpath);
+
+ if (fpath.get_extension() == "shader") {
+ ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
+ shader_editor->edit(res.ptr());
+ shader_editor->make_visible(true);
+ shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
+ return;
+ } else {
+ Ref<Script> script = res;
+ if (script.is_valid()) {
+ edit(script);
+
+ ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor());
+ if (ste) {
+ ste->goto_line_selection(line_number - 1, begin, end);
+ }
+ return;
+ }
+ }
+ }
+
+ // If the file is not a valid resource/script, load it as a text file.
+ Error err;
+ Ref<TextFile> text_file = _load_text_file(fpath, &err);
+ if (text_file.is_valid()) {
+ edit(text_file);
- ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor());
- if (ste) {
- ste->goto_line_selection(line_number - 1, begin, end);
+ TextEditor *te = Object::cast_to<TextEditor>(_get_current_editor());
+ if (te) {
+ te->goto_line_selection(line_number - 1, begin, end);
}
}
}
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 07303da2ff..87248c53b1 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -30,6 +30,7 @@
#include "script_text_editor.h"
+#include "core/math/expression.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
@@ -1147,6 +1148,32 @@ void ScriptTextEditor::_edit_option(int p_op) {
_convert_case(CodeTextEditor::CAPITALIZE);
} break;
+ case EDIT_EVALUATE: {
+
+ Expression expression;
+ Vector<String> lines = code_editor->get_text_edit()->get_selection_text().split("\n");
+ PoolStringArray results;
+
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines[i];
+ String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); //extract the whitespace at the beginning
+
+ if (expression.parse(line) == OK) {
+ Variant result = expression.execute(Array(), Variant(), false);
+ if (expression.get_error_text() == "") {
+ results.append(whitespace + (String)result);
+ } else {
+ results.append(line);
+ }
+ } else {
+ results.append(line);
+ }
+ }
+
+ code_editor->get_text_edit()->begin_complex_operation(); //prevents creating a two-step undo
+ code_editor->get_text_edit()->insert_text_at_cursor(results.join("\n"));
+ code_editor->get_text_edit()->end_complex_operation();
+ } break;
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
@@ -1170,7 +1197,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
// Yep, because it doesn't make sense to instance this dialog for every single script open...
// So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
-
} break;
case SEARCH_LOCATE_FUNCTION: {
@@ -1572,7 +1598,9 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (has_color) {
String line = tx->get_line(row);
- color_line = row;
+ color_position.x = row;
+ color_position.y = col;
+
int begin = 0;
int end = 0;
bool valid = false;
@@ -1612,10 +1640,17 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
new_args = String("(" + rtos(p_color.r) + ", " + rtos(p_color.g) + ", " + rtos(p_color.b) + ", " + rtos(p_color.a) + ")");
}
- String line = code_editor->get_text_edit()->get_line(color_line);
- String new_line = line.replace(color_args, new_args);
+ String line = code_editor->get_text_edit()->get_line(color_position.x);
+ int color_args_pos = line.find(color_args, color_position.y);
+ String line_with_replaced_args = line;
+ line_with_replaced_args.erase(color_args_pos, color_args.length());
+ line_with_replaced_args = line_with_replaced_args.insert(color_args_pos, new_args);
+
color_args = new_args;
- code_editor->get_text_edit()->set_line(color_line, new_line);
+ code_editor->get_text_edit()->begin_complex_operation();
+ code_editor->get_text_edit()->set_line(color_position.x, line_with_replaced_args);
+ code_editor->get_text_edit()->end_complex_operation();
+ code_editor->get_text_edit()->update();
}
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
@@ -1641,6 +1676,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
}
if (p_foldable)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
@@ -1710,6 +1746,7 @@ ScriptTextEditor::ScriptTextEditor() {
color_panel = memnew(PopupPanel);
add_child(color_panel);
color_picker = memnew(ColorPicker);
+ color_picker->set_deferred_mode(true);
color_panel->add_child(color_picker);
color_picker->connect("color_changed", this, "_color_changed");
@@ -1740,6 +1777,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
@@ -1776,11 +1814,7 @@ ScriptTextEditor::ScriptTextEditor() {
search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION);
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
- search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL);
-
search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
edit_hb->add_child(edit_menu);
@@ -1789,6 +1823,11 @@ ScriptTextEditor::ScriptTextEditor() {
edit_hb->add_child(goto_menu);
goto_menu->set_text(TTR("Go To"));
goto_menu->set_switch_on_hover(true);
+ goto_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION);
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
bookmarks_menu = memnew(PopupMenu);
bookmarks_menu->set_name("Bookmarks");
@@ -1848,16 +1887,12 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN);
ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K);
- //leave these at zero, same can be accomplished with tab/shift-tab, including selection
- //the next/previous in history shortcut in this case makes a lot more sene.
+ // Leave these at zero, same can be accomplished with tab/shift-tab, including selection.
+ // The next/previous in history shortcut in this case makes a lot more sense.
ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), 0);
ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0);
ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K);
- ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_B);
- ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KEY_MASK_CMD | KEY_B);
- ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
- ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), 0);
ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KEY_MASK_ALT | KEY_F);
ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), 0);
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
@@ -1868,20 +1903,12 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D);
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
#endif
+ ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E);
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I);
ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I);
-#ifdef OSX_ENABLED
- ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
-#else
- ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
-#endif
- ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9);
- ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
- ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
-
ED_SHORTCUT("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G);
@@ -1896,6 +1923,17 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F);
#ifdef OSX_ENABLED
+ ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
+#else
+ ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_F1);
+#endif
+
+ ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_B);
+ ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KEY_MASK_CMD | KEY_B);
+ ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
+ ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), 0);
+
+#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J);
#else
ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
@@ -1903,10 +1941,13 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KEY_MASK_CMD | KEY_L);
#ifdef OSX_ENABLED
- ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
+ ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
#else
- ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_F1);
+ ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
#endif
+ ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9);
+ ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
+ ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
ScriptEditor::register_create_script_editor_function(create_editor);
}
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 4dbade472c..38c6da5c33 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -81,7 +81,7 @@ class ScriptTextEditor : public ScriptEditorBase {
PopupPanel *color_panel;
ColorPicker *color_picker;
- int color_line;
+ Vector2 color_position;
String color_args;
void _update_member_keywords();
@@ -120,6 +120,7 @@ class ScriptTextEditor : public ScriptEditorBase {
EDIT_TO_UPPERCASE,
EDIT_TO_LOWERCASE,
EDIT_CAPITALIZE,
+ EDIT_EVALUATE,
EDIT_TOGGLE_FOLD_LINE,
EDIT_FOLD_ALL_LINES,
EDIT_UNFOLD_ALL_LINES,
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 37460c58ff..04820b8a8f 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -529,19 +529,19 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
void ShaderEditor::_update_bookmark_list() {
- bookmarks_menu->get_popup()->clear();
+ bookmarks_menu->clear();
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
Array bookmark_list = shader_editor->get_text_edit()->get_bookmarks_array();
if (bookmark_list.size() == 0) {
return;
}
- bookmarks_menu->get_popup()->add_separator();
+ bookmarks_menu->add_separator();
for (int i = 0; i < bookmark_list.size(); i++) {
String line = shader_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
@@ -550,17 +550,17 @@ void ShaderEditor::_update_bookmark_list() {
line = line.substr(0, 50);
}
- bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
- bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]);
+ bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
+ bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]);
}
}
void ShaderEditor::_bookmark_item_pressed(int p_idx) {
if (p_idx < 4) { // Any item before the separator.
- _menu_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ _menu_option(bookmarks_menu->get_item_id(p_idx));
} else {
- shader_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ shader_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx));
}
}
@@ -649,16 +649,23 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
- search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
search_menu->get_popup()->connect("id_pressed", this, "_menu_option");
- bookmarks_menu = memnew(MenuButton);
- bookmarks_menu->set_text(TTR("Bookmarks"));
- bookmarks_menu->set_switch_on_hover(true);
+ MenuButton *goto_menu = memnew(MenuButton);
+ goto_menu->set_text(TTR("Go To"));
+ goto_menu->set_switch_on_hover(true);
+ goto_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
+
+ bookmarks_menu = memnew(PopupMenu);
+ bookmarks_menu->set_name("Bookmarks");
+ goto_menu->get_popup()->add_child(bookmarks_menu);
+ goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks");
_update_bookmark_list();
bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
- bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
+ bookmarks_menu->connect("index_pressed", this, "_bookmark_item_pressed");
help_menu = memnew(MenuButton);
help_menu->set_text(TTR("Help"));
@@ -670,7 +677,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
main_container->add_child(hbc);
hbc->add_child(search_menu);
hbc->add_child(edit_menu);
- hbc->add_child(bookmarks_menu);
+ hbc->add_child(goto_menu);
hbc->add_child(help_menu);
hbc->add_style_override("panel", p_node->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles"));
main_container->add_child(shader_editor);
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 5d03c37dc4..8d3f4d4fe8 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -99,7 +99,7 @@ class ShaderEditor : public PanelContainer {
MenuButton *edit_menu;
MenuButton *search_menu;
- MenuButton *bookmarks_menu;
+ PopupMenu *bookmarks_menu;
MenuButton *help_menu;
PopupMenu *context_menu;
uint64_t idle;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 6af6d48618..58234ba954 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -2922,8 +2922,14 @@ void SpatialEditorViewport::update_transform_gizmo_view() {
if (dd == 0)
dd = 0.0001;
- float gsize = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
- gizmo_scale = (gsize / Math::abs(dd)) * MAX(1, EDSCALE) / viewport_container->get_stretch_shrink();
+ float gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
+ // At low viewport heights, multiply the gizmo scale based on the viewport height.
+ // This prevents the gizmo from growing very large and going outside the viewport.
+ const int viewport_base_height = 400 * MAX(1, EDSCALE);
+ gizmo_scale =
+ (gizmo_size / Math::abs(dd)) * MAX(1, EDSCALE) *
+ MIN(viewport_base_height, viewport_container->get_size().height) / viewport_base_height /
+ viewport_container->get_stretch_shrink();
Vector3 scale = Vector3(1, 1, 1) * gizmo_scale;
xform.basis.scale(scale);
@@ -5432,6 +5438,7 @@ void SpatialEditor::_register_all_gizmos() {
add_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
add_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
add_gizmo_plugin(Ref<ParticlesGizmoPlugin>(memnew(ParticlesGizmoPlugin)));
+ add_gizmo_plugin(Ref<CPUParticlesGizmoPlugin>(memnew(CPUParticlesGizmoPlugin)));
add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 34d8e6aff5..89e419ede8 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -221,19 +221,19 @@ void TextEditor::_validate_script() {
void TextEditor::_update_bookmark_list() {
- bookmarks_menu->get_popup()->clear();
+ bookmarks_menu->clear();
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
Array bookmark_list = code_editor->get_text_edit()->get_bookmarks_array();
if (bookmark_list.size() == 0) {
return;
}
- bookmarks_menu->get_popup()->add_separator();
+ bookmarks_menu->add_separator();
for (int i = 0; i < bookmark_list.size(); i++) {
String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
@@ -242,17 +242,17 @@ void TextEditor::_update_bookmark_list() {
line = line.substr(0, 50);
}
- bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
- bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]);
+ bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
+ bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]);
}
}
void TextEditor::_bookmark_item_pressed(int p_idx) {
if (p_idx < 4) { // Any item before the separator.
- _edit_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ _edit_option(bookmarks_menu->get_item_id(p_idx));
} else {
- code_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx));
}
}
@@ -313,6 +313,11 @@ void TextEditor::goto_line(int p_line, bool p_with_error) {
code_editor->goto_line(p_line);
}
+void TextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
+
+ code_editor->goto_line_selection(p_line, p_begin, p_end);
+}
+
void TextEditor::set_executing_line(int p_line) {
code_editor->set_executing_line(p_line);
@@ -477,6 +482,14 @@ void TextEditor::_edit_option(int p_op) {
code_editor->get_find_replace_bar()->popup_replace();
} break;
+ case SEARCH_IN_FILES: {
+
+ String selected_text = code_editor->get_text_edit()->get_selection_text();
+
+ // Yep, because it doesn't make sense to instance this dialog for every single script open...
+ // So this will be delegated to the ScriptEditor.
+ emit_signal("search_in_files_requested", selected_text);
+ } break;
case SEARCH_GOTO_LINE: {
goto_line_dialog->popup_find_line(tx);
@@ -553,7 +566,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
int to_column = tx->get_selection_to_column();
if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
- // Right click is outside the selected text
+ // Right click is outside the selected text.
tx->deselect();
}
}
@@ -632,17 +645,14 @@ TextEditor::TextEditor() {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
-
- goto_line_dialog = memnew(GotoLineDialog);
- add_child(goto_line_dialog);
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
edit_menu = memnew(MenuButton);
+ edit_hb->add_child(edit_menu);
edit_menu->set_text(TTR("Edit"));
edit_menu->set_switch_on_hover(true);
edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
- edit_hb->add_child(edit_menu);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -684,13 +694,25 @@ TextEditor::TextEditor() {
highlighter_menu->add_radio_check_item(TTR("Standard"));
highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
- bookmarks_menu = memnew(MenuButton);
- edit_hb->add_child(bookmarks_menu);
- bookmarks_menu->set_text(TTR("Bookmarks"));
- bookmarks_menu->set_switch_on_hover(true);
+ MenuButton *goto_menu = memnew(MenuButton);
+ edit_hb->add_child(goto_menu);
+ goto_menu->set_text(TTR("Go To"));
+ goto_menu->set_switch_on_hover(true);
+ goto_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
+
+ bookmarks_menu = memnew(PopupMenu);
+ bookmarks_menu->set_name(TTR("Bookmarks"));
+ goto_menu->get_popup()->add_child(bookmarks_menu);
+ goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks");
_update_bookmark_list();
bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
- bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
+ bookmarks_menu->connect("index_pressed", this, "_bookmark_item_pressed");
+
+ goto_line_dialog = memnew(GotoLineDialog);
+ add_child(goto_line_dialog);
code_editor->get_text_edit()->set_drag_forwarding(this);
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 3a330576ae..c8b49a61e0 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -46,7 +46,7 @@ private:
MenuButton *edit_menu;
PopupMenu *highlighter_menu;
MenuButton *search_menu;
- MenuButton *bookmarks_menu;
+ PopupMenu *bookmarks_menu;
PopupMenu *context_menu;
GotoLineDialog *goto_line_dialog;
@@ -87,6 +87,7 @@ private:
SEARCH_FIND_NEXT,
SEARCH_FIND_PREV,
SEARCH_REPLACE,
+ SEARCH_IN_FILES,
SEARCH_GOTO_LINE,
BOOKMARK_TOGGLE,
BOOKMARK_GOTO_NEXT,
@@ -131,6 +132,7 @@ public:
virtual Vector<String> get_functions();
virtual void get_breakpoints(List<int> *p_breakpoints);
virtual void goto_line(int p_line, bool p_with_error = false);
+ void goto_line_selection(int p_line, int p_begin, int p_end);
virtual void set_executing_line(int p_line);
virtual void clear_executing_line();
virtual void trim_trailing_whitespace();
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 5b67d259ba..873b125200 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -631,14 +631,12 @@ ThemeEditor::ThemeEditor() {
scroll = memnew(ScrollContainer);
add_child(scroll);
- scroll->set_theme(Theme::get_default());
scroll->set_enable_v_scroll(true);
scroll->set_enable_h_scroll(false);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
main_container = memnew(MarginContainer);
scroll->add_child(main_container);
- main_container->set_theme(Theme::get_default());
main_container->set_clip_contents(true);
main_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
main_container->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -648,9 +646,11 @@ ThemeEditor::ThemeEditor() {
Panel *panel = memnew(Panel);
main_container->add_child(panel);
+ panel->set_theme(Theme::get_default());
MarginContainer *mc = memnew(MarginContainer);
main_container->add_child(mc);
+ mc->set_theme(Theme::get_default());
mc->add_constant_override("margin_right", 4 * EDSCALE);
mc->add_constant_override("margin_top", 4 * EDSCALE);
mc->add_constant_override("margin_left", 4 * EDSCALE);
@@ -695,19 +695,19 @@ ThemeEditor::ThemeEditor() {
test_menu_button->get_popup()->add_separator();
test_menu_button->get_popup()->add_check_item(TTR("Check Item"));
test_menu_button->get_popup()->add_check_item(TTR("Checked Item"));
- test_menu_button->get_popup()->set_item_checked(3, true);
+ test_menu_button->get_popup()->set_item_checked(4, true);
test_menu_button->get_popup()->add_separator();
test_menu_button->get_popup()->add_radio_check_item(TTR("Radio Item"));
test_menu_button->get_popup()->add_radio_check_item(TTR("Checked Radio Item"));
- test_menu_button->get_popup()->set_item_checked(6, true);
+ test_menu_button->get_popup()->set_item_checked(7, true);
test_menu_button->get_popup()->add_separator(TTR("Named Sep."));
PopupMenu *test_submenu = memnew(PopupMenu);
test_menu_button->get_popup()->add_child(test_submenu);
test_submenu->set_name("submenu");
test_menu_button->get_popup()->add_submenu_item(TTR("Submenu"), "submenu");
- test_submenu->add_item(TTR("Item 1"));
- test_submenu->add_item(TTR("Item 2"));
+ test_submenu->add_item(TTR("Subitem 1"));
+ test_submenu->add_item(TTR("Subitem 2"));
first_vb->add_child(test_menu_button);
OptionButton *test_option_button = memnew(OptionButton);
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 766890242f..b2f06ca41f 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -521,7 +521,13 @@ void TileMapEditor::_update_palette() {
for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
entries2.push_back(E->key());
}
- entries2.sort();
+ // Sort tiles in row-major order
+ struct SwapComparator {
+ _FORCE_INLINE_ bool operator()(const Vector2 &v_l, const Vector2 &v_r) const {
+ return v_l.y != v_r.y ? v_l.y < v_r.y : v_l.x < v_r.x;
+ }
+ };
+ entries2.sort_custom<SwapComparator>();
Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index f135becf5f..1a27e749e2 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -924,8 +924,7 @@ void TileSetEditor::_on_workspace_draw() {
case EDITMODE_OCCLUSION:
case EDITMODE_NAVIGATION: {
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Vector2 coord = edited_shape_coord;
- draw_highlight_subtile(coord);
+ draw_highlight_subtile(edited_shape_coord);
}
draw_polygon_shapes();
draw_grid_snap();
@@ -1519,6 +1518,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
undo_redo->create_action(TTR("Edit Navigation Polygon"));
undo_redo->add_do_method(edited_navigation_shape.ptr(), "set_vertices", polygon);
undo_redo->add_undo_method(edited_navigation_shape.ptr(), "set_vertices", edited_navigation_shape->get_vertices());
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "clear_polygons");
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "clear_polygons");
undo_redo->add_do_method(edited_navigation_shape.ptr(), "add_polygon", indices);
undo_redo->add_undo_method(edited_navigation_shape.ptr(), "add_polygon", edited_navigation_shape->get_polygon(0));
undo_redo->add_do_method(this, "_select_edited_shape_coord");
@@ -1872,7 +1873,7 @@ void TileSetEditor::_update_tile_data() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
for (int y = 0; y < cell_count.y; y++) {
for (int x = 0; x < cell_count.x; x++) {
SubtileData data;
@@ -1974,7 +1975,7 @@ void TileSetEditor::_select_previous_tile() {
case EDITMODE_Z_INDEX: {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
cell_count -= Vector2(1, 1);
edited_shape_coord = cell_count;
_select_edited_shape_coord();
@@ -2031,7 +2032,7 @@ void TileSetEditor::_select_next_subtile() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
if (edited_shape_coord.x >= cell_count.x - 1 && edited_shape_coord.y >= cell_count.y - 1) {
_select_next_tile();
} else {
@@ -2057,7 +2058,7 @@ void TileSetEditor::_select_previous_subtile() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
if (edited_shape_coord.x <= 0 && edited_shape_coord.y <= 0) {
_select_previous_tile();
} else {
@@ -2077,9 +2078,9 @@ void TileSetEditor::_select_next_shape() {
} else if (edit_mode != EDITMODE_COLLISION) {
_select_next_subtile();
} else {
- Vector2i edited_coord = Vector2();
+ Vector2i edited_coord = Vector2i();
if (tileset->tile_get_tile_mode(get_current_tile()) != TileSet::SINGLE_TILE) {
- edited_coord = edited_shape_coord;
+ edited_coord = Vector2i(edited_shape_coord);
}
SubtileData data = current_tile_data[edited_coord];
if (data.collisions.size() == 0) {
@@ -2130,9 +2131,9 @@ void TileSetEditor::_select_previous_shape() {
} else if (edit_mode != EDITMODE_COLLISION) {
_select_previous_subtile();
} else {
- Vector2i edited_coord = Vector2();
+ Vector2i edited_coord = Vector2i();
if (tileset->tile_get_tile_mode(get_current_tile()) != TileSet::SINGLE_TILE) {
- edited_coord = edited_shape_coord;
+ edited_coord = Vector2i(edited_shape_coord);
}
SubtileData data = current_tile_data[edited_coord];
if (data.collisions.size() == 0) {
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 4376e3e68f..863cf75a93 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -42,17 +42,17 @@
#include "scene/main/viewport.h"
#include "scene/resources/visual_shader_nodes.h"
-Control *VisualShaderNodePlugin::create_editor(const Ref<VisualShaderNode> &p_node) {
+Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (get_script_instance()) {
- return get_script_instance()->call("create_editor", p_node);
+ return get_script_instance()->call("create_editor", p_parent_resource, p_node);
}
return NULL;
}
void VisualShaderNodePlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
+ BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
}
///////////////////
@@ -78,6 +78,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
hide();
} else {
if (changed) { // to avoid tree collapse
+ _clear_buffer();
_update_options_menu();
}
_update_graph();
@@ -210,6 +211,9 @@ void VisualShaderEditor::_update_options_menu() {
if (!use_filter || add_options[i].name.findn(filter) != -1) {
+ if ((add_options[i].func != current_func && add_options[i].func != -1) || !_is_available(add_options[i].mode))
+ continue;
+
if (prev_category != add_options[i].category) {
if (category != NULL && item_count == 0) {
memdelete(category);
@@ -240,73 +244,53 @@ void VisualShaderEditor::_update_options_menu() {
sub_category->set_collapsed(true);
}
}
- if (sub_category != NULL) {
- if ((add_options[i].func == current_func || add_options[i].func == -1) && _is_available(add_options[i].mode)) {
- ++item_count2;
- TreeItem *item = members->create_item(sub_category);
- if (add_options[i].highend && low_driver)
- item->set_custom_color(0, unsupported_color);
- else if (add_options[i].highend)
- item->set_custom_color(0, supported_color);
- item->set_text(0, add_options[i].name);
- if (is_first_item) {
- item->select(0);
- is_first_item = false;
- }
- switch (add_options[i].return_type) {
- case VisualShaderNode::PORT_TYPE_SCALAR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_VECTOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_COLOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
- break;
- default:
- break;
- }
- item->set_meta("id", i);
- }
- }
} else {
- if (category != NULL) {
- if ((add_options[i].func == current_func || add_options[i].func == -1) && _is_available(add_options[i].mode)) {
- ++item_count;
- TreeItem *item = members->create_item(category);
- if (add_options[i].highend && low_driver)
- item->set_custom_color(0, unsupported_color);
- else if (add_options[i].highend)
- item->set_custom_color(0, supported_color);
- item->set_text(0, add_options[i].name);
- switch (add_options[i].return_type) {
- case VisualShaderNode::PORT_TYPE_SCALAR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_VECTOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_COLOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
- break;
- default:
- break;
- }
- item->set_meta("id", i);
+ sub_category = NULL;
+ }
+
+ TreeItem *p_category = NULL;
+
+ if (sub_category != NULL) {
+ p_category = sub_category;
+ ++item_count2;
+ } else if (category != NULL) {
+ p_category = category;
+ ++item_count;
+ }
+
+ if (p_category != NULL) {
+ TreeItem *item = members->create_item(p_category);
+ if (add_options[i].highend && low_driver)
+ item->set_custom_color(0, unsupported_color);
+ else if (add_options[i].highend)
+ item->set_custom_color(0, supported_color);
+ item->set_text(0, add_options[i].name);
+ if (p_category == sub_category) {
+ if (is_first_item) {
+ item->select(0);
+ is_first_item = false;
}
}
+ switch (add_options[i].return_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_COLOR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
+ break;
+ default:
+ break;
+ }
+ item->set_meta("id", i);
}
prev_sub_category = add_options[i].sub_category;
@@ -462,7 +446,7 @@ void VisualShaderEditor::_update_graph() {
}
for (int i = 0; i < plugins.size(); i++) {
- custom_editor = plugins.write[i]->create_editor(vsnode);
+ custom_editor = plugins.write[i]->create_editor(visual_shader, vsnode);
if (custom_editor) {
break;
}
@@ -604,6 +588,10 @@ void VisualShaderEditor::_update_graph() {
}
}
+ if (!is_group) {
+ hb->add_spacer();
+ }
+
if (valid_right) {
if (is_group) {
Button *remove_btn = memnew(Button);
@@ -1590,22 +1578,38 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int
selection_center /= (float)r_nodes.size();
}
-void VisualShaderEditor::_dup_paste_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select) {
+void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select) {
VisualShader::Type type = (VisualShader::Type)p_type;
+ VisualShader::Type pasted_type = (VisualShader::Type)p_pasted_type;
int base_id = visual_shader->get_valid_node_id(type);
int id_from = base_id;
Map<int, int> connection_remap;
+ Set<int> unsupported_set;
for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) {
connection_remap[E->get()] = id_from;
- Ref<VisualShaderNode> node = visual_shader->get_node(type, E->get());
+ Ref<VisualShaderNode> node = visual_shader->get_node(pasted_type, E->get());
+
+ bool unsupported = false;
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].type == node->get_class_name()) {
+ if (!_is_available(add_options[i].mode)) {
+ unsupported = true;
+ }
+ break;
+ }
+ }
+ if (unsupported) {
+ unsupported_set.insert(E->get());
+ continue;
+ }
Ref<VisualShaderNode> dupli = node->duplicate();
- undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(type, E->get()) + p_offset, id_from);
+ undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(pasted_type, E->get()) + p_offset, id_from);
undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from);
// duplicate size, inputs and outputs if node is group
@@ -1625,9 +1629,12 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<int> &r_nodes, Set<in
}
List<VisualShader::Connection> conns;
- visual_shader->get_node_connections(type, &conns);
+ visual_shader->get_node_connections(pasted_type, &conns);
for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (unsupported_set.has(E->get().from_node) || unsupported_set.has(E->get().to_node)) {
+ continue;
+ }
if (connection_remap.has(E->get().from_node) && connection_remap.has(E->get().to_node)) {
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port);
}
@@ -1674,7 +1681,7 @@ void VisualShaderEditor::_duplicate_nodes() {
undo_redo->create_action(TTR("Duplicate Nodes"));
- _dup_paste_nodes(type, nodes, excluded, Vector2(10, 10) * EDSCALE, true);
+ _dup_paste_nodes(type, type, nodes, excluded, Vector2(10, 10) * EDSCALE, true);
}
void VisualShaderEditor::_copy_nodes() {
@@ -1697,7 +1704,7 @@ void VisualShaderEditor::_paste_nodes() {
float scale = graph->get_zoom();
- _dup_paste_nodes(type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + graph->get_local_mouse_position() / scale - selection_center), false);
+ _dup_paste_nodes(type, copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + graph->get_local_mouse_position() / scale - selection_center), false);
_dup_update_excluded(type, copy_nodes_excluded_buffer); // to prevent selection of previous copies at new paste
}
@@ -1776,9 +1783,6 @@ void VisualShaderEditor::_on_nodes_delete() {
void VisualShaderEditor::_mode_selected(int p_id) {
- copy_nodes_buffer.clear();
- copy_nodes_excluded_buffer.clear();
-
_update_options_menu();
_update_graph();
}
@@ -2425,6 +2429,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeVectorInterp", TTR("Linear interpolation between two vectors."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeVectorScalarMix", TTR("Linear interpolation between two vectors using scalar."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -2586,6 +2591,7 @@ public:
class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer);
+ Ref<Resource> parent_resource;
public:
void _property_changed(const String &prop, const Variant &p_value, const String &p_field, bool p_changing = false) {
@@ -2599,7 +2605,27 @@ public:
undo_redo->create_action(TTR("Edit Visual Property") + ": " + prop, UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(node.ptr(), prop, p_value);
undo_redo->add_undo_property(node.ptr(), prop, node->get(prop));
+
+ if (p_value.get_type() == Variant::OBJECT) {
+
+ RES prev_res = node->get(prop);
+ RES curr_res = p_value;
+
+ if (curr_res.is_null()) {
+ undo_redo->add_do_method(this, "_open_inspector", (RES)parent_resource.ptr());
+ } else {
+ undo_redo->add_do_method(this, "_open_inspector", (RES)curr_res.ptr());
+ }
+ if (!prev_res.is_null()) {
+ undo_redo->add_undo_method(this, "_open_inspector", (RES)prev_res.ptr());
+ } else {
+ undo_redo->add_undo_method(this, "_open_inspector", (RES)parent_resource.ptr());
+ }
+ undo_redo->add_do_method(this, "_refresh_request");
+ undo_redo->add_undo_method(this, "_refresh_request");
+ }
undo_redo->commit_action();
+
updating = false;
}
@@ -2615,11 +2641,20 @@ public:
VisualShaderEditor::get_singleton()->call_deferred("_update_graph");
}
+ void _resource_selected(const String &p_path, RES p_resource) {
+ _open_inspector(p_resource);
+ }
+
+ void _open_inspector(RES p_resource) {
+ EditorNode::get_singleton()->get_inspector()->edit(p_resource.ptr());
+ }
+
bool updating;
Ref<VisualShaderNode> node;
Vector<EditorProperty *> properties;
- void setup(Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ parent_resource = p_parent_resource;
updating = false;
node = p_node;
properties = p_properties;
@@ -2628,6 +2663,11 @@ public:
add_child(p_properties[i]);
+ bool res_prop = Object::cast_to<EditorPropertyResource>(p_properties[i]);
+ if (res_prop) {
+ p_properties[i]->connect("resource_selected", this, "_resource_selected");
+ }
+
properties[i]->connect("property_changed", this, "_property_changed");
properties[i]->set_object_and_property(node.ptr(), p_names[i]);
properties[i]->update_property();
@@ -2641,10 +2681,12 @@ public:
ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed, DEFVAL(String()), DEFVAL(false));
ClassDB::bind_method("_node_changed", &VisualShaderNodePluginDefaultEditor::_node_changed);
ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request);
+ ClassDB::bind_method("_resource_selected", &VisualShaderNodePluginDefaultEditor::_resource_selected);
+ ClassDB::bind_method("_open_inspector", &VisualShaderNodePluginDefaultEditor::_open_inspector);
}
};
-Control *VisualShaderNodePluginDefault::create_editor(const Ref<VisualShaderNode> &p_node) {
+Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (p_node->is_class("VisualShaderNodeInput")) {
//create input
@@ -2702,7 +2744,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<VisualShaderNode
properties.push_back(pinfo[i].name);
}
VisualShaderNodePluginDefaultEditor *editor = memnew(VisualShaderNodePluginDefaultEditor);
- editor->setup(editors, properties, p_node);
+ editor->setup(p_parent_resource, editors, properties, p_node);
return editor;
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index d396243bf3..d2b1e8bc45 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -48,7 +48,7 @@ protected:
static void _bind_methods();
public:
- virtual Control *create_editor(const Ref<VisualShaderNode> &p_node);
+ virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
class VisualShaderEditor : public VBoxContainer {
@@ -178,7 +178,7 @@ class VisualShaderEditor : public VBoxContainer {
void _dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded);
void _dup_update_excluded(int p_type, Set<int> &r_excluded);
- void _dup_paste_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select);
+ void _dup_paste_nodes(int p_type, int p_pasted_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select);
void _duplicate_nodes();
@@ -272,7 +272,7 @@ class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {
GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin);
public:
- virtual Control *create_editor(const Ref<VisualShaderNode> &p_node);
+ virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
class EditorPropertyShaderMode : public EditorProperty {