diff options
Diffstat (limited to 'editor/plugins')
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 31 | ||||
-rw-r--r-- | editor/plugins/debugger_editor_plugin.cpp | 32 | ||||
-rw-r--r-- | editor/plugins/editor_debugger_plugin.cpp | 124 | ||||
-rw-r--r-- | editor/plugins/editor_debugger_plugin.h | 64 | ||||
-rw-r--r-- | editor/plugins/editor_preview_plugins.cpp | 4 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 36 | ||||
-rw-r--r-- | editor/plugins/packed_scene_translation_parser_plugin.cpp | 8 | ||||
-rw-r--r-- | editor/plugins/packed_scene_translation_parser_plugin.h | 2 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 193 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.h | 25 | ||||
-rw-r--r-- | editor/plugins/texture_region_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/theme_editor_plugin.cpp | 6 | ||||
-rw-r--r-- | editor/plugins/tile_map_editor_plugin.cpp | 6 | ||||
-rw-r--r-- | editor/plugins/tile_set_editor_plugin.cpp | 18 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 35 |
15 files changed, 521 insertions, 65 deletions
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index f3508cedbd..9427f82f9e 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2599,6 +2599,11 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { void CanvasItemEditor::_update_cursor() { CursorShape c = CURSOR_ARROW; + bool should_switch = false; + if (drag_selection.size() != 0) { + float angle = drag_selection[0]->_edit_get_rotation(); + should_switch = abs(Math::cos(angle)) < Math_SQRT12; + } switch (drag_type) { case DRAG_NONE: switch (tool) { @@ -2621,21 +2626,37 @@ void CanvasItemEditor::_update_cursor() { case DRAG_LEFT: case DRAG_RIGHT: case DRAG_V_GUIDE: - c = CURSOR_HSIZE; + if (should_switch) { + c = CURSOR_VSIZE; + } else { + c = CURSOR_HSIZE; + } break; case DRAG_TOP: case DRAG_BOTTOM: case DRAG_H_GUIDE: - c = CURSOR_VSIZE; + if (should_switch) { + c = CURSOR_HSIZE; + } else { + c = CURSOR_VSIZE; + } break; case DRAG_TOP_LEFT: case DRAG_BOTTOM_RIGHT: case DRAG_DOUBLE_GUIDE: - c = CURSOR_FDIAGSIZE; + if (should_switch) { + c = CURSOR_BDIAGSIZE; + } else { + c = CURSOR_FDIAGSIZE; + } break; case DRAG_TOP_RIGHT: case DRAG_BOTTOM_LEFT: - c = CURSOR_BDIAGSIZE; + if (should_switch) { + c = CURSOR_FDIAGSIZE; + } else { + c = CURSOR_BDIAGSIZE; + } break; case DRAG_MOVE: c = CURSOR_MOVE; @@ -6235,7 +6256,7 @@ void CanvasItemEditorViewport::_perform_drop_data() { files_str += error_files[i].get_file().get_basename() + ","; } files_str = files_str.substr(0, files_str.length() - 1); - accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); + accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.get_data())); accept->popup_centered(); } } diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 0a4d173923..0747e42045 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -47,7 +47,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open")); ED_SHORTCUT("debugger/debug_with_external_editor", TTR("Debug with External Editor")); - // File Server for deploy with remote fs. + // File Server for deploy with remote filesystem. file_server = memnew(EditorFileServer); EditorDebuggerNode *debugger = memnew(EditorDebuggerNode); @@ -59,19 +59,31 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d PopupMenu *p = debug_menu->get_popup(); p->set_hide_on_checkable_item_selection(false); p->add_check_shortcut(ED_SHORTCUT("editor/deploy_with_remote_debug", TTR("Deploy with Remote Debug")), RUN_DEPLOY_REMOTE_DEBUG); - p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged.")); - p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network FS")), RUN_FILE_SERVER); - p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is enabled, export or deploy will produce a minimal executable.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploy will use the USB cable for faster performance. This option speeds up testing for games with a large footprint.")); + p->set_item_tooltip( + p->get_item_count() - 1, + TTR("When this option is enabled, using one-click deploy will make the executable attempt to connect to this computer's IP so the running project can be debugged.\nThis option is intended to be used for remote debugging (typically with a mobile device).\nYou don't need to enable it to use the GDScript debugger locally.")); + p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network Filesystem")), RUN_FILE_SERVER); + p->set_item_tooltip( + p->get_item_count() - 1, + TTR("When this option is enabled, using one-click deploy for Android will only export an executable without the project data.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploying will use the USB cable for faster performance. This option speeds up testing for projects with large assets.")); p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS); - p->set_item_tooltip(p->get_item_count() - 1, TTR("Collision shapes and raycast nodes (for 2D and 3D) will be visible on the running game if this option is turned on.")); + p->set_item_tooltip( + p->get_item_count() - 1, + TTR("When this option is enabled, collision shapes and raycast nodes (for 2D and 3D) will be visible in the running project.")); p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION); - p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on.")); + p->set_item_tooltip( + p->get_item_count() - 1, + TTR("When this option is enabled, navigation meshes and polygons will be visible in the running project.")); p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Sync Scene Changes")), RUN_LIVE_DEBUG); - p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem.")); - p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Sync Script Changes")), RUN_RELOAD_SCRIPTS); - p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem.")); + p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Synchronize Scene Changes")), RUN_LIVE_DEBUG); + p->set_item_tooltip( + p->get_item_count() - 1, + TTR("When this option is enabled, any changes made to the scene in the editor will be replicated in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled.")); + p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS); + p->set_item_tooltip( + p->get_item_count() - 1, + TTR("When this option is enabled, any script that is saved will be reloaded in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled.")); // Multi-instance, start/stop instances_menu = memnew(PopupMenu); diff --git a/editor/plugins/editor_debugger_plugin.cpp b/editor/plugins/editor_debugger_plugin.cpp new file mode 100644 index 0000000000..b775e871e2 --- /dev/null +++ b/editor/plugins/editor_debugger_plugin.cpp @@ -0,0 +1,124 @@ +/*************************************************************************/ +/* editor_debugger_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_debugger_plugin.h" + +#include "editor/debugger/script_editor_debugger.h" + +void EditorDebuggerPlugin::_breaked(bool p_really_did, bool p_can_debug) { + if (p_really_did) { + emit_signal("breaked", p_can_debug); + } else { + emit_signal("continued"); + } +} + +void EditorDebuggerPlugin::_started() { + emit_signal("started"); +} + +void EditorDebuggerPlugin::_stopped() { + emit_signal("stopped"); +} + +void EditorDebuggerPlugin::_bind_methods() { + ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &EditorDebuggerPlugin::send_message); + ClassDB::bind_method(D_METHOD("register_message_capture", "name", "callable"), &EditorDebuggerPlugin::register_message_capture); + ClassDB::bind_method(D_METHOD("unregister_message_capture", "name"), &EditorDebuggerPlugin::unregister_message_capture); + ClassDB::bind_method(D_METHOD("has_capture", "name"), &EditorDebuggerPlugin::has_capture); + ClassDB::bind_method(D_METHOD("is_breaked"), &EditorDebuggerPlugin::is_breaked); + ClassDB::bind_method(D_METHOD("is_debuggable"), &EditorDebuggerPlugin::is_debuggable); + ClassDB::bind_method(D_METHOD("is_session_active"), &EditorDebuggerPlugin::is_session_active); + + ADD_SIGNAL(MethodInfo("started")); + ADD_SIGNAL(MethodInfo("stopped")); + ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "can_debug"))); + ADD_SIGNAL(MethodInfo("continued")); +} + +void EditorDebuggerPlugin::attach_debugger(ScriptEditorDebugger *p_debugger) { + debugger = p_debugger; + if (debugger) { + debugger->connect("started", callable_mp(this, &EditorDebuggerPlugin::_started)); + debugger->connect("stopped", callable_mp(this, &EditorDebuggerPlugin::_stopped)); + debugger->connect("breaked", callable_mp(this, &EditorDebuggerPlugin::_breaked)); + } +} + +void EditorDebuggerPlugin::detach_debugger(bool p_call_debugger) { + if (debugger) { + debugger->disconnect("started", callable_mp(this, &EditorDebuggerPlugin::_started)); + debugger->disconnect("stopped", callable_mp(this, &EditorDebuggerPlugin::_stopped)); + debugger->disconnect("breaked", callable_mp(this, &EditorDebuggerPlugin::_breaked)); + if (p_call_debugger && get_script_instance()) { + debugger->remove_debugger_plugin(get_script_instance()->get_script()); + } + debugger = nullptr; + } +} + +void EditorDebuggerPlugin::send_message(const String &p_message, const Array &p_args) { + ERR_FAIL_COND_MSG(!debugger, "Plugin is not attached to debugger"); + debugger->send_message(p_message, p_args); +} + +void EditorDebuggerPlugin::register_message_capture(const StringName &p_name, const Callable &p_callable) { + ERR_FAIL_COND_MSG(!debugger, "Plugin is not attached to debugger"); + debugger->register_message_capture(p_name, p_callable); +} + +void EditorDebuggerPlugin::unregister_message_capture(const StringName &p_name) { + ERR_FAIL_COND_MSG(!debugger, "Plugin is not attached to debugger"); + debugger->unregister_message_capture(p_name); +} + +bool EditorDebuggerPlugin::has_capture(const StringName &p_name) { + ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); + return debugger->has_capture(p_name); +} + +bool EditorDebuggerPlugin::is_breaked() { + ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); + return debugger->is_breaked(); +} + +bool EditorDebuggerPlugin::is_debuggable() { + ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); + return debugger->is_debuggable(); +} + +bool EditorDebuggerPlugin::is_session_active() { + ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); + return debugger->is_session_active(); +} + +EditorDebuggerPlugin::~EditorDebuggerPlugin() { + detach_debugger(true); +} diff --git a/editor/plugins/editor_debugger_plugin.h b/editor/plugins/editor_debugger_plugin.h new file mode 100644 index 0000000000..10fd1151de --- /dev/null +++ b/editor/plugins/editor_debugger_plugin.h @@ -0,0 +1,64 @@ +/*************************************************************************/ +/* editor_debugger_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_DEBUGGER_PLUGIN_H +#define EDITOR_DEBUGGER_PLUGIN_H + +#include "scene/gui/control.h" + +class ScriptEditorDebugger; + +class EditorDebuggerPlugin : public Control { + GDCLASS(EditorDebuggerPlugin, Control); + +private: + ScriptEditorDebugger *debugger = nullptr; + + void _breaked(bool p_really_did, bool p_can_debug); + void _started(); + void _stopped(); + +protected: + static void _bind_methods(); + +public: + void attach_debugger(ScriptEditorDebugger *p_debugger); + void detach_debugger(bool p_call_debugger); + void send_message(const String &p_message, const Array &p_args); + void register_message_capture(const StringName &p_name, const Callable &p_callable); + void unregister_message_capture(const StringName &p_name); + bool has_capture(const StringName &p_name); + bool is_breaked(); + bool is_debuggable(); + bool is_session_active(); + ~EditorDebuggerPlugin(); +}; + +#endif // EDITOR_DEBUGGER_PLUGIN_H diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 2889cb50a0..3cf4dc5ac8 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -466,7 +466,7 @@ EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// -static bool _is_text_char(CharType c) { +static bool _is_text_char(char32_t c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } @@ -525,7 +525,7 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size bool prev_is_text = false; bool in_keyword = false; for (int i = 0; i < code.length(); i++) { - CharType c = code[i]; + char32_t c = code[i]; if (c > 32) { if (col < thumbnail_size) { Color color = text_color; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index b4b81cc7f0..952487c13c 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2059,7 +2059,12 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const camera_transform.translate(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - Vector3 translation(-p_relative.x * pan_speed, p_relative.y * pan_speed, 0); + const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); + const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + Vector3 translation( + (invert_x_axis ? -1 : 1) * -p_relative.x * pan_speed, + (invert_y_axis ? -1 : 1) * p_relative.y * pan_speed, + 0); translation *= cursor.distance / DISTANCE_DEFAULT; camera_transform.translate(translation); cursor.pos = camera_transform.origin; @@ -2100,17 +2105,24 @@ void Node3DEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, cons _menu_option(VIEW_PERSPECTIVE); } - real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); - real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); - bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); + const real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); if (invert_y_axis) { cursor.x_rot -= p_relative.y * radians_per_pixel; } else { cursor.x_rot += p_relative.y * radians_per_pixel; } - cursor.y_rot += p_relative.x * radians_per_pixel; + // Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented. cursor.x_rot = CLAMP(cursor.x_rot, -1.57, 1.57); + + if (invert_x_axis) { + cursor.y_rot -= p_relative.x * radians_per_pixel; + } else { + cursor.y_rot += p_relative.x * radians_per_pixel; + } name = ""; _update_name(); } @@ -2125,21 +2137,23 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const _menu_option(VIEW_PERSPECTIVE); } - real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_sensitivity"); - real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); - bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_sensitivity"); + const real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag". - Transform prev_camera_transform = to_camera_transform(cursor); + const Transform prev_camera_transform = to_camera_transform(cursor); if (invert_y_axis) { cursor.x_rot -= p_relative.y * radians_per_pixel; } else { cursor.x_rot += p_relative.y * radians_per_pixel; } - cursor.y_rot += p_relative.x * radians_per_pixel; + // Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented. cursor.x_rot = CLAMP(cursor.x_rot, -1.57, 1.57); + cursor.y_rot += p_relative.x * radians_per_pixel; + // Look is like the opposite of Orbit: the focus point rotates around the camera Transform camera_transform = to_camera_transform(cursor); Vector3 pos = camera_transform.xform(Vector3(0, 0, 0)); @@ -3715,7 +3729,7 @@ void Node3DEditorViewport::_perform_drop_data() { files_str += error_files[i].get_file().get_basename() + ","; } files_str = files_str.substr(0, files_str.length() - 1); - accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); + accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.get_data())); accept->popup_centered(); } } diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 52af0008b7..608b5c3104 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -37,7 +37,7 @@ void PackedSceneEditorTranslationParserPlugin::get_recognized_extensions(List<St ResourceLoader::get_recognized_extensions_for_type("PackedScene", r_extensions); } -Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_extracted_strings) { +Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) { // Parse specific scene Node's properties (see in constructor) that are auto-translated by the engine when set. E.g Label's text property. // These properties are translated with the tr() function in the C++ code when being set or updated. @@ -71,8 +71,10 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, String extension = s->get_language()->get_extension(); if (EditorTranslationParser::get_singleton()->can_parse(extension)) { Vector<String> temp; - EditorTranslationParser::get_singleton()->get_parser(extension)->parse_file(s->get_path(), &temp); + Vector<Vector<String>> ids_context_plural; + EditorTranslationParser::get_singleton()->get_parser(extension)->parse_file(s->get_path(), &temp, &ids_context_plural); parsed_strings.append_array(temp); + r_ids_ctx_plural->append_array(ids_context_plural); } } else if (property_name == "filters") { // Extract FileDialog's filters property with values in format "*.png ; PNG Images","*.gd ; GDScript Files". @@ -93,7 +95,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, } } - r_extracted_strings->append_array(parsed_strings); + r_ids->append_array(parsed_strings); return OK; } diff --git a/editor/plugins/packed_scene_translation_parser_plugin.h b/editor/plugins/packed_scene_translation_parser_plugin.h index 2bd4dae995..a0ffdf692c 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.h +++ b/editor/plugins/packed_scene_translation_parser_plugin.h @@ -40,7 +40,7 @@ class PackedSceneEditorTranslationParserPlugin : public EditorTranslationParserP Set<String> lookup_properties; public: - virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings) override; + virtual Error parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) override; virtual void get_recognized_extensions(List<String> *r_extensions) const override; PackedSceneEditorTranslationParserPlugin(); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 1073da7d8c..5007983581 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -36,6 +36,8 @@ #include "editor/editor_settings.h" #include "scene/3d/sprite_3d.h" #include "scene/gui/center_container.h" +#include "scene/gui/margin_container.h" +#include "scene/gui/panel_container.h" void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) { } @@ -140,8 +142,27 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { } } +void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) { + const Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid()) { + // Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer + // to allow performing this action anywhere, even if the cursor isn't + // hovering the texture in the workspace. + if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + _sheet_zoom_in(); + // Don't scroll up after zooming in. + accept_event(); + } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + _sheet_zoom_out(); + // Don't scroll down after zooming out. + accept_event(); + } + } +} + void SpriteFramesEditor::_sheet_add_frames() { - Size2i size = split_sheet_preview->get_size(); + Size2i size = split_sheet_preview->get_texture()->get_size(); int h = split_sheet_h->get_value(); int v = split_sheet_v->get_value(); @@ -180,6 +201,28 @@ void SpriteFramesEditor::_sheet_add_frames() { undo_redo->commit_action(); } +void SpriteFramesEditor::_sheet_zoom_in() { + if (sheet_zoom < max_sheet_zoom) { + sheet_zoom *= scale_ratio; + Size2 texture_size = split_sheet_preview->get_texture()->get_size(); + split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom); + } +} + +void SpriteFramesEditor::_sheet_zoom_out() { + if (sheet_zoom > min_sheet_zoom) { + sheet_zoom /= scale_ratio; + Size2 texture_size = split_sheet_preview->get_texture()->get_size(); + split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom); + } +} + +void SpriteFramesEditor::_sheet_zoom_reset() { + sheet_zoom = 1.f; + Size2 texture_size = split_sheet_preview->get_texture()->get_size(); + split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom); +} + void SpriteFramesEditor::_sheet_select_clear_all_frames() { bool should_clear = true; for (int i = 0; i < split_sheet_h->get_value() * split_sheet_v->get_value(); i++) { @@ -207,15 +250,18 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { EditorNode::get_singleton()->show_warning(TTR("Unable to load images")); ERR_FAIL_COND(!texture.is_valid()); } - if (texture != split_sheet_preview->get_texture()) { - //different texture, reset to 4x4 - split_sheet_h->set_value(4); - split_sheet_v->set_value(4); - } + bool new_texture = texture != split_sheet_preview->get_texture(); frames_selected.clear(); last_frame_selected = -1; split_sheet_preview->set_texture(texture); + if (new_texture) { + //different texture, reset to 4x4 + split_sheet_h->set_value(4); + split_sheet_v->set_value(4); + //reset zoom + _sheet_zoom_reset(); + } split_sheet_dialog->popup_centered_ratio(0.65); } @@ -231,8 +277,14 @@ void SpriteFramesEditor::_notification(int p_what) { move_up->set_icon(get_theme_icon("MoveLeft", "EditorIcons")); move_down->set_icon(get_theme_icon("MoveRight", "EditorIcons")); _delete->set_icon(get_theme_icon("Remove", "EditorIcons")); + zoom_out->set_icon(get_theme_icon("ZoomLess", "EditorIcons")); + zoom_1->set_icon(get_theme_icon("ZoomReset", "EditorIcons")); + zoom_in->set_icon(get_theme_icon("ZoomMore", "EditorIcons")); new_anim->set_icon(get_theme_icon("New", "EditorIcons")); remove_anim->set_icon(get_theme_icon("Remove", "EditorIcons")); + split_sheet_zoom_out->set_icon(get_theme_icon("ZoomLess", "EditorIcons")); + split_sheet_zoom_1->set_icon(get_theme_icon("ZoomReset", "EditorIcons")); + split_sheet_zoom_in->set_icon(get_theme_icon("ZoomMore", "EditorIcons")); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { @@ -636,6 +688,54 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) { undo_redo->commit_action(); } +void SpriteFramesEditor::_tree_input(const Ref<InputEvent> &p_event) { + const Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid()) { + if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + _zoom_in(); + // Don't scroll up after zooming in. + accept_event(); + } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + _zoom_out(); + // Don't scroll down after zooming out. + accept_event(); + } + } +} + +void SpriteFramesEditor::_zoom_in() { + // Do not zoom in or out with no visible frames + if (frames->get_frame_count(edited_anim) <= 0) { + return; + } + if (thumbnail_zoom < max_thumbnail_zoom) { + thumbnail_zoom *= scale_ratio; + int thumbnail_size = (int)(thumbnail_default_size * thumbnail_zoom); + tree->set_fixed_column_width(thumbnail_size * 3 / 2); + tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size)); + } +} + +void SpriteFramesEditor::_zoom_out() { + // Do not zoom in or out with no visible frames + if (frames->get_frame_count(edited_anim) <= 0) { + return; + } + if (thumbnail_zoom > min_thumbnail_zoom) { + thumbnail_zoom /= scale_ratio; + int thumbnail_size = (int)(thumbnail_default_size * thumbnail_zoom); + tree->set_fixed_column_width(thumbnail_size * 3 / 2); + tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size)); + } +} + +void SpriteFramesEditor::_zoom_reset() { + thumbnail_zoom = 1.0f; + tree->set_fixed_column_width(thumbnail_default_size * 3 / 2); + tree->set_fixed_icon_size(Size2(thumbnail_default_size, thumbnail_default_size)); +} + void SpriteFramesEditor::_update_library(bool p_skip_selector) { updating = true; @@ -727,6 +827,9 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) { } _update_library(); + // Clear zoom and split sheet texture + split_sheet_preview->set_texture(Ref<Texture2D>()); + _zoom_reset(); } else { hide(); } @@ -892,11 +995,16 @@ SpriteFramesEditor::SpriteFramesEditor() { animations->connect("item_edited", callable_mp(this, &SpriteFramesEditor::_animation_name_edited)); animations->set_allow_reselect(true); + HBoxContainer *hbc_anim_speed = memnew(HBoxContainer); + hbc_anim_speed->add_child(memnew(Label(TTR("Speed:")))); + vbc_animlist->add_child(hbc_anim_speed); anim_speed = memnew(SpinBox); - vbc_animlist->add_margin_child(TTR("Speed (FPS):"), anim_speed); + anim_speed->set_suffix(TTR("FPS")); anim_speed->set_min(0); anim_speed->set_max(100); anim_speed->set_step(0.01); + anim_speed->set_h_size_flags(SIZE_EXPAND_FILL); + hbc_anim_speed->add_child(anim_speed); anim_speed->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_animation_fps_changed)); anim_loop = memnew(CheckButton); @@ -965,6 +1073,24 @@ SpriteFramesEditor::SpriteFramesEditor() { _delete->set_tooltip(TTR("Delete")); hbc->add_child(_delete); + hbc->add_spacer(); + + zoom_out = memnew(Button); + zoom_out->connect("pressed", callable_mp(this, &SpriteFramesEditor::_zoom_out)); + zoom_out->set_flat(true); + zoom_out->set_tooltip(TTR("Zoom Out")); + hbc->add_child(zoom_out); + zoom_1 = memnew(Button); + zoom_1->connect("pressed", callable_mp(this, &SpriteFramesEditor::_zoom_reset)); + zoom_1->set_flat(true); + zoom_1->set_tooltip(TTR("Zoom Reset")); + hbc->add_child(zoom_1); + zoom_in = memnew(Button); + zoom_in->connect("pressed", callable_mp(this, &SpriteFramesEditor::_zoom_in)); + zoom_in->set_flat(true); + zoom_in->set_tooltip(TTR("Zoom In")); + hbc->add_child(zoom_in); + file = memnew(EditorFileDialog); add_child(file); @@ -972,13 +1098,11 @@ SpriteFramesEditor::SpriteFramesEditor() { tree->set_v_size_flags(SIZE_EXPAND_FILL); tree->set_icon_mode(ItemList::ICON_MODE_TOP); - int thumbnail_size = 96; tree->set_max_columns(0); tree->set_icon_mode(ItemList::ICON_MODE_TOP); - tree->set_fixed_column_width(thumbnail_size * 3 / 2); tree->set_max_text_lines(2); - tree->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size)); tree->set_drag_forwarding(this); + tree->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_tree_input)); sub_vb->add_child(tree); @@ -1042,8 +1166,13 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_vb->add_child(split_sheet_hb); + PanelContainer *split_sheet_panel = memnew(PanelContainer); + split_sheet_panel->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_panel->set_v_size_flags(SIZE_EXPAND_FILL); + split_sheet_vb->add_child(split_sheet_panel); + split_sheet_preview = memnew(TextureRect); - split_sheet_preview->set_expand(false); + split_sheet_preview->set_expand(true); split_sheet_preview->set_mouse_filter(MOUSE_FILTER_PASS); split_sheet_preview->connect("draw", callable_mp(this, &SpriteFramesEditor::_sheet_preview_draw)); split_sheet_preview->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_preview_input)); @@ -1051,20 +1180,58 @@ SpriteFramesEditor::SpriteFramesEditor() { splite_sheet_scroll = memnew(ScrollContainer); splite_sheet_scroll->set_enable_h_scroll(true); splite_sheet_scroll->set_enable_v_scroll(true); - splite_sheet_scroll->set_v_size_flags(SIZE_EXPAND_FILL); + splite_sheet_scroll->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_scroll_input)); + split_sheet_panel->add_child(splite_sheet_scroll); CenterContainer *cc = memnew(CenterContainer); cc->add_child(split_sheet_preview); cc->set_h_size_flags(SIZE_EXPAND_FILL); cc->set_v_size_flags(SIZE_EXPAND_FILL); splite_sheet_scroll->add_child(cc); - split_sheet_vb->add_child(splite_sheet_scroll); + MarginContainer *split_sheet_zoom_margin = memnew(MarginContainer); + split_sheet_panel->add_child(split_sheet_zoom_margin); + split_sheet_zoom_margin->set_h_size_flags(0); + split_sheet_zoom_margin->set_v_size_flags(0); + split_sheet_zoom_margin->add_theme_constant_override("margin_top", 5); + split_sheet_zoom_margin->add_theme_constant_override("margin_left", 5); + HBoxContainer *split_sheet_zoom_hb = memnew(HBoxContainer); + split_sheet_zoom_margin->add_child(split_sheet_zoom_hb); + + split_sheet_zoom_out = memnew(Button); + split_sheet_zoom_out->set_flat(true); + split_sheet_zoom_out->set_focus_mode(FOCUS_NONE); + split_sheet_zoom_out->set_tooltip(TTR("Zoom Out")); + split_sheet_zoom_out->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_out)); + split_sheet_zoom_hb->add_child(split_sheet_zoom_out); + split_sheet_zoom_1 = memnew(Button); + split_sheet_zoom_1->set_flat(true); + split_sheet_zoom_1->set_focus_mode(FOCUS_NONE); + split_sheet_zoom_1->set_tooltip(TTR("Zoom Reset")); + split_sheet_zoom_1->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_reset)); + split_sheet_zoom_hb->add_child(split_sheet_zoom_1); + split_sheet_zoom_in = memnew(Button); + split_sheet_zoom_in->set_flat(true); + split_sheet_zoom_in->set_focus_mode(FOCUS_NONE); + split_sheet_zoom_in->set_tooltip(TTR("Zoom In")); + split_sheet_zoom_in->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_in)); + split_sheet_zoom_hb->add_child(split_sheet_zoom_in); file_split_sheet = memnew(EditorFileDialog); file_split_sheet->set_title(TTR("Create Frames from Sprite Sheet")); file_split_sheet->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); add_child(file_split_sheet); file_split_sheet->connect("file_selected", callable_mp(this, &SpriteFramesEditor::_prepare_sprite_sheet)); + + // Config scale. + scale_ratio = 1.2f; + thumbnail_default_size = 96; + thumbnail_zoom = 1.0f; + max_thumbnail_zoom = 8.0f; + min_thumbnail_zoom = 0.1f; + sheet_zoom = 1.0f; + max_sheet_zoom = 16.0f; + min_sheet_zoom = 0.01f; + _zoom_reset(); } void SpriteFramesEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index ee743fe60d..0dce93f55a 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -36,6 +36,7 @@ #include "scene/2d/animated_sprite_2d.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" +#include "scene/gui/scroll_container.h" #include "scene/gui/split_container.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" @@ -52,6 +53,9 @@ class SpriteFramesEditor : public HSplitContainer { Button *empty2; Button *move_up; Button *move_down; + Button *zoom_out; + Button *zoom_1; + Button *zoom_in; ItemList *tree; bool loading_scene; int sel; @@ -79,10 +83,22 @@ class SpriteFramesEditor : public HSplitContainer { TextureRect *split_sheet_preview; SpinBox *split_sheet_h; SpinBox *split_sheet_v; + Button *split_sheet_zoom_out; + Button *split_sheet_zoom_1; + Button *split_sheet_zoom_in; EditorFileDialog *file_split_sheet; Set<int> frames_selected; int last_frame_selected; + float scale_ratio; + int thumbnail_default_size; + float thumbnail_zoom; + float max_thumbnail_zoom; + float min_thumbnail_zoom; + float sheet_zoom; + float max_sheet_zoom; + float min_sheet_zoom; + void _load_pressed(); void _load_scene_pressed(); void _file_load_request(const Vector<String> &p_path, int p_at_pos = -1); @@ -103,6 +119,11 @@ class SpriteFramesEditor : public HSplitContainer { void _animation_loop_changed(); void _animation_fps_changed(double p_value); + void _tree_input(const Ref<InputEvent> &p_event); + void _zoom_in(); + void _zoom_out(); + void _zoom_reset(); + bool updating; UndoRedo *undo_redo; @@ -117,7 +138,11 @@ class SpriteFramesEditor : public HSplitContainer { void _sheet_preview_draw(); void _sheet_spin_changed(double); void _sheet_preview_input(const Ref<InputEvent> &p_event); + void _sheet_scroll_input(const Ref<InputEvent> &p_event); void _sheet_add_frames(); + void _sheet_zoom_in(); + void _sheet_zoom_out(); + void _sheet_zoom_reset(); void _sheet_select_clear_all_frames(); protected: diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 762f42abeb..6e722607f7 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -875,7 +875,7 @@ void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_pro if (!is_visible()) { return; } - if (p_prop == StringName("atlas") || p_prop == StringName("texture")) { + if (p_prop == StringName("atlas") || p_prop == StringName("texture") || p_prop == StringName("region")) { _edit_region(); } } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 18a107ff75..932ded6938 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -206,8 +206,8 @@ void ThemeEditor::_save_template_cbk(String fname) { file->store_line("; [value] examples:"); file->store_line("; "); file->store_line("; Type.item = 6 ; numeric constant. "); - file->store_line("; Type.item = #FF00FF ; HTML color "); - file->store_line("; Type.item = #55FF00FF ; HTML color with alpha 55."); + file->store_line("; Type.item = #FF00FF ; HTML color (magenta)."); + file->store_line("; Type.item = #FF00FF55 ; HTML color (magenta with alpha 0x55)."); file->store_line("; Type.item = icon(image.png) ; icon in a png file (relative to theme file)."); file->store_line("; Type.item = font(font.xres) ; font in a resource (relative to theme file)."); file->store_line("; Type.item = sbox(stylebox.xres) ; stylebox in a resource (relative to theme file)."); @@ -629,7 +629,7 @@ ThemeEditor::ThemeEditor() { ScrollContainer *scroll = memnew(ScrollContainer); add_child(scroll); scroll->set_enable_v_scroll(true); - scroll->set_enable_h_scroll(false); + scroll->set_enable_h_scroll(true); scroll->set_v_size_flags(SIZE_EXPAND_FILL); MarginContainer *root_container = memnew(MarginContainer); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 307a8a9001..e71485e9fc 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -886,17 +886,17 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p rect.position += tile_ofs; } - rect.position = p_xform.xform(rect.position); - rect.size *= sc; - Color modulate = node->get_tileset()->tile_get_modulate(p_cell); modulate.a = 0.5; + Transform2D old_transform = p_viewport->get_viewport_transform(); + p_viewport->draw_set_transform_matrix(p_xform); // Take into account TileMap transformation when displaying cell if (r.has_no_area()) { p_viewport->draw_texture_rect(t, rect, false, modulate, p_transpose); } else { p_viewport->draw_texture_rect_region(t, rect, r, modulate, p_transpose); } + p_viewport->draw_set_transform_matrix(old_transform); } void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform) { diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index a613174ed9..274c64263f 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -342,11 +342,13 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { left_container->add_child(tileset_toolbar_container); tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE] = memnew(Button); + tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->set_flat(true); tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tileset_toolbar_button_pressed), varray(TOOL_TILESET_ADD_TEXTURE)); tileset_toolbar_container->add_child(tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]); tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->set_tooltip(TTR("Add Texture(s) to TileSet.")); tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE] = memnew(Button); + tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->set_flat(true); tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tileset_toolbar_button_pressed), varray(TOOL_TILESET_REMOVE_TEXTURE)); tileset_toolbar_container->add_child(tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]); tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->set_tooltip(TTR("Remove selected Texture from TileSet.")); @@ -405,12 +407,14 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { tools[SELECT_NEXT] = memnew(Button); tool_hb->add_child(tools[SELECT_NEXT]); tool_hb->move_child(tools[SELECT_NEXT], WORKSPACE_CREATE_SINGLE); + tools[SELECT_NEXT]->set_flat(true); tools[SELECT_NEXT]->set_shortcut(ED_SHORTCUT("tileset_editor/next_shape", TTR("Next Coordinate"), KEY_PAGEDOWN)); tools[SELECT_NEXT]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(SELECT_NEXT)); tools[SELECT_NEXT]->set_tooltip(TTR("Select the next shape, subtile, or Tile.")); tools[SELECT_PREVIOUS] = memnew(Button); tool_hb->add_child(tools[SELECT_PREVIOUS]); tool_hb->move_child(tools[SELECT_PREVIOUS], WORKSPACE_CREATE_SINGLE); + tools[SELECT_PREVIOUS]->set_flat(true); tools[SELECT_PREVIOUS]->set_shortcut(ED_SHORTCUT("tileset_editor/previous_shape", TTR("Previous Coordinate"), KEY_PAGEUP)); tools[SELECT_PREVIOUS]->set_tooltip(TTR("Select the previous shape, subtile, or Tile.")); tools[SELECT_PREVIOUS]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(SELECT_PREVIOUS)); @@ -467,6 +471,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { tools[TOOL_SELECT] = memnew(Button); toolbar->add_child(tools[TOOL_SELECT]); + tools[TOOL_SELECT]->set_flat(true); tools[TOOL_SELECT]->set_toggle_mode(true); tools[TOOL_SELECT]->set_button_group(tg); tools[TOOL_SELECT]->set_pressed(true); @@ -475,20 +480,24 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { separator_bitmask = memnew(VSeparator); toolbar->add_child(separator_bitmask); tools[BITMASK_COPY] = memnew(Button); + tools[BITMASK_COPY]->set_flat(true); tools[BITMASK_COPY]->set_tooltip(TTR("Copy bitmask.")); tools[BITMASK_COPY]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(BITMASK_COPY)); toolbar->add_child(tools[BITMASK_COPY]); tools[BITMASK_PASTE] = memnew(Button); + tools[BITMASK_PASTE]->set_flat(true); tools[BITMASK_PASTE]->set_tooltip(TTR("Paste bitmask.")); tools[BITMASK_PASTE]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(BITMASK_PASTE)); toolbar->add_child(tools[BITMASK_PASTE]); tools[BITMASK_CLEAR] = memnew(Button); + tools[BITMASK_CLEAR]->set_flat(true); tools[BITMASK_CLEAR]->set_tooltip(TTR("Erase bitmask.")); tools[BITMASK_CLEAR]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(BITMASK_CLEAR)); toolbar->add_child(tools[BITMASK_CLEAR]); tools[SHAPE_NEW_RECTANGLE] = memnew(Button); toolbar->add_child(tools[SHAPE_NEW_RECTANGLE]); + tools[SHAPE_NEW_RECTANGLE]->set_flat(true); tools[SHAPE_NEW_RECTANGLE]->set_toggle_mode(true); tools[SHAPE_NEW_RECTANGLE]->set_button_group(tg); tools[SHAPE_NEW_RECTANGLE]->set_tooltip(TTR("Create a new rectangle.")); @@ -496,6 +505,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { tools[SHAPE_NEW_POLYGON] = memnew(Button); toolbar->add_child(tools[SHAPE_NEW_POLYGON]); + tools[SHAPE_NEW_POLYGON]->set_flat(true); tools[SHAPE_NEW_POLYGON]->set_toggle_mode(true); tools[SHAPE_NEW_POLYGON]->set_button_group(tg); tools[SHAPE_NEW_POLYGON]->set_tooltip(TTR("Create a new polygon.")); @@ -504,12 +514,14 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { separator_shape_toggle = memnew(VSeparator); toolbar->add_child(separator_shape_toggle); tools[SHAPE_TOGGLE_TYPE] = memnew(Button); + tools[SHAPE_TOGGLE_TYPE]->set_flat(true); tools[SHAPE_TOGGLE_TYPE]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(SHAPE_TOGGLE_TYPE)); toolbar->add_child(tools[SHAPE_TOGGLE_TYPE]); separator_delete = memnew(VSeparator); toolbar->add_child(separator_delete); tools[SHAPE_DELETE] = memnew(Button); + tools[SHAPE_DELETE]->set_flat(true); tools[SHAPE_DELETE]->connect("pressed", callable_mp(this, &TileSetEditor::_on_tool_clicked), varray(SHAPE_DELETE)); toolbar->add_child(tools[SHAPE_DELETE]); @@ -534,11 +546,13 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { separator_grid = memnew(VSeparator); toolbar->add_child(separator_grid); tools[SHAPE_KEEP_INSIDE_TILE] = memnew(Button); + tools[SHAPE_KEEP_INSIDE_TILE]->set_flat(true); tools[SHAPE_KEEP_INSIDE_TILE]->set_toggle_mode(true); tools[SHAPE_KEEP_INSIDE_TILE]->set_pressed(true); tools[SHAPE_KEEP_INSIDE_TILE]->set_tooltip(TTR("Keep polygon inside region Rect.")); toolbar->add_child(tools[SHAPE_KEEP_INSIDE_TILE]); tools[TOOL_GRID_SNAP] = memnew(Button); + tools[TOOL_GRID_SNAP]->set_flat(true); tools[TOOL_GRID_SNAP]->set_toggle_mode(true); tools[TOOL_GRID_SNAP]->set_tooltip(TTR("Enable snap and show grid (configurable via the Inspector).")); tools[TOOL_GRID_SNAP]->connect("toggled", callable_mp(this, &TileSetEditor::_on_grid_snap_toggled)); @@ -549,19 +563,23 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { toolbar->add_child(separator); tools[ZOOM_OUT] = memnew(Button); + tools[ZOOM_OUT]->set_flat(true); tools[ZOOM_OUT]->connect("pressed", callable_mp(this, &TileSetEditor::_zoom_out)); toolbar->add_child(tools[ZOOM_OUT]); tools[ZOOM_OUT]->set_tooltip(TTR("Zoom Out")); tools[ZOOM_1] = memnew(Button); + tools[ZOOM_1]->set_flat(true); tools[ZOOM_1]->connect("pressed", callable_mp(this, &TileSetEditor::_zoom_reset)); toolbar->add_child(tools[ZOOM_1]); tools[ZOOM_1]->set_tooltip(TTR("Zoom Reset")); tools[ZOOM_IN] = memnew(Button); + tools[ZOOM_IN]->set_flat(true); tools[ZOOM_IN]->connect("pressed", callable_mp(this, &TileSetEditor::_zoom_in)); toolbar->add_child(tools[ZOOM_IN]); tools[ZOOM_IN]->set_tooltip(TTR("Zoom In")); tools[VISIBLE_INFO] = memnew(Button); + tools[VISIBLE_INFO]->set_flat(true); tools[VISIBLE_INFO]->set_toggle_mode(true); tools[VISIBLE_INFO]->set_tooltip(TTR("Display Tile Names (Hold Alt Key)")); toolbar->add_child(tools[VISIBLE_INFO]); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 53bd1150ec..217294464c 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -177,6 +177,9 @@ bool VisualShaderEditor::_is_available(int p_mode) { case VisualShader::TYPE_LIGHT: current_mode = 4; break; + case VisualShader::TYPE_COMPUTE: + current_mode = 8; + break; default: break; } @@ -191,6 +194,10 @@ bool VisualShaderEditor::_is_available(int p_mode) { temp_mode |= 4; } + if (p_mode == VisualShader::TYPE_COMPUTE) { + temp_mode = 8; + } + if (temp_mode == 0) { temp_mode |= 1; } @@ -2432,6 +2439,7 @@ VisualShaderEditor::VisualShaderEditor() { edit_type->add_item(TTR("Vertex")); edit_type->add_item(TTR("Fragment")); edit_type->add_item(TTR("Light")); + edit_type->add_item(TTR("Compute")); edit_type->select(1); edit_type->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); graph->get_zoom_hbox()->add_child(edit_type); @@ -2644,6 +2652,7 @@ VisualShaderEditor::VisualShaderEditor() { const String input_param_for_fragment_shader_mode = TTR("'%s' input parameter for fragment shader mode."); const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode."); const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode."); + const String input_param_for_compute_shader_mode = TTR("'%s' input parameter for compute shader mode."); const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode."); add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); @@ -2717,19 +2726,19 @@ VisualShaderEditor::VisualShaderEditor() { // PARTICLES INPUTS - add_options.push_back(AddOption("Active", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Delta", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("EmissionTransform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("LifeTime", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Restart", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Time", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Transform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Active", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Alpha", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CustomAlpha", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Delta", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("EmissionTransform", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("LifeTime", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Restart", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Time", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Transform", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_COMPUTE, Shader::MODE_PARTICLES)); // SKY INPUTS |