summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml23
-rw-r--r--core/math/delaunay.h4
-rw-r--r--doc/classes/AnimationPlayer.xml1
-rw-r--r--doc/classes/ClassDB.xml4
-rw-r--r--doc/classes/Directory.xml4
-rw-r--r--doc/classes/MainLoop.xml2
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp3
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp2
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/copy.glsl4
-rw-r--r--editor/editor_file_dialog.cpp6
-rw-r--r--editor/editor_help_search.cpp2
-rw-r--r--editor/editor_node.cpp3
-rw-r--r--editor/editor_themes.cpp3
-rw-r--r--editor/filesystem_dock.cpp10
-rw-r--r--editor/icons/icon_editor_curve_handle.svg1
-rw-r--r--editor/icons/icon_editor_path_sharp_handle.svg1
-rw-r--r--editor/icons/icon_editor_path_smooth_handle.svg1
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp3
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp42
-rw-r--r--editor/plugins/path_editor_plugin.cpp3
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp7
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp59
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp111
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h9
-rw-r--r--editor/project_manager.cpp123
-rw-r--r--editor/project_manager.h1
-rw-r--r--modules/csg/csg.cpp10
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp15
-rw-r--r--scene/2d/navigation_2d.cpp4
-rw-r--r--scene/2d/path_2d.cpp2
-rw-r--r--scene/animation/animation_player.cpp4
-rw-r--r--scene/gui/file_dialog.cpp2
-rw-r--r--scene/gui/text_edit.cpp465
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/animation.cpp8
-rw-r--r--scene/resources/default_theme/default_theme.cpp1
-rw-r--r--scene/resources/visual_shader.cpp67
-rw-r--r--scene/resources/visual_shader.h19
41 files changed, 594 insertions, 441 deletions
diff --git a/.gitignore b/.gitignore
index f43f68f25f..0ee2a8b382 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# Godot auto generated files
*.gen.*
+.import/
# Documentation generated by doxygen or from classes.xml
doc/_build/
diff --git a/.travis.yml b/.travis.yml
index b52e40200f..305544d821 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,10 @@ language: cpp
# OS config, depends on actual 'os' in build matrix
dist: xenial
-sudo: false
+
+stages:
+ - check
+ - build
env:
global:
@@ -18,6 +21,7 @@ cache:
matrix:
include:
- name: Static checks (clang-format)
+ stage: check
env: STATIC_CHECKS=yes
os: linux
compiler: gcc
@@ -29,6 +33,7 @@ matrix:
- clang-format-8
- name: Linux editor (debug, GCC 9, with Mono)
+ stage: build
env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="module_mono_enabled=yes mono_glue=no warnings=extra werror=yes"
os: linux
compiler: gcc-9
@@ -52,6 +57,7 @@ matrix:
branch_pattern: coverity_scan
- name: Linux export template (release, Clang)
+ stage: build
env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
os: linux
compiler: clang
@@ -61,22 +67,26 @@ matrix:
- *linux_deps
- name: Android export template (release_debug, Clang)
+ stage: build
env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
os: linux
compiler: clang
- name: macOS editor (debug, Clang)
+ stage: build
env: PLATFORM=osx TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-clang
os: osx
compiler: clang
- name: iOS export template (debug, Clang)
+ stage: build
env: PLATFORM=iphone TOOLS=no TARGET=debug CACHE_NAME=${PLATFORM}-clang
os: osx
compiler: clang
- - name: Linux headless editor (release_debug, GCC 9)
- env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="warnings=extra werror=yes"
+ - name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running)
+ stage: build
+ env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="warnings=extra werror=yes" TEST_PROJECT=yes
os: linux
compiler: gcc-9
addons:
@@ -88,6 +98,7 @@ matrix:
- *linux_deps
- name: Linux export template (release_debug, GCC 5, without 3D support)
+ stage: build
env: PLATFORM=x11 TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-gcc-5 EXTRA_ARGS="disable_3d=yes"
os: linux
compiler: gcc
@@ -125,4 +136,10 @@ script:
sh ./misc/travis/clang-format.sh;
else
scons -j2 CC=$CC CXX=$CXX platform=$PLATFORM tools=$TOOLS target=$TARGET $OPTIONS $EXTRA_ARGS;
+
+ if [ "$TEST_PROJECT" = "yes" ]; then
+ git clone --depth 1 "https://github.com/godotengine/godot-tests.git";
+ sed -i "s:custom_template/release=\"\":custom_template/release=\"$(readlink -e bin/godot_server.x11.opt.tools.64)\":" godot-tests/tests/project_export/export_presets.cfg;
+ godot-tests/tests/project_export/test_project.sh "bin/godot_server.x11.opt.tools.64";
+ fi
fi
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index ed52c506db..3f8013a3e6 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -80,11 +80,11 @@ public:
}
static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) {
- if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]))) {
+ if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) {
return true;
}
- if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]))) {
+ if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[1]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[0]]) {
return true;
}
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index b4c44fe8eb..e510603281 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -165,6 +165,7 @@
</argument>
<description>
Queues an animation for playback once the current one is done.
+ [b]Note:[/b] If a looped animation is currently playing, the queued animation will never play unless the looped animation is stopped somehow.
</description>
</method>
<method name="remove_animation">
diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml
index b7b77bc02a..fd08643dd5 100644
--- a/doc/classes/ClassDB.xml
+++ b/doc/classes/ClassDB.xml
@@ -134,7 +134,7 @@
<argument index="2" name="no_inheritance" type="bool" default="false">
</argument>
<description>
- Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/code] is false) has a method called [code]method[/code] or not.
+ Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/code] is [code]false[/code]) has a method called [code]method[/code] or not.
</description>
</method>
<method name="class_has_signal" qualifiers="const">
@@ -201,7 +201,7 @@
<argument index="0" name="class" type="String">
</argument>
<description>
- Returns whether this class is enabled or not.
+ Returns whether this [code]class[/code] is enabled or not.
</description>
</method>
<method name="is_parent_class" qualifiers="const">
diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml
index 9294a515d2..8aae85563a 100644
--- a/doc/classes/Directory.xml
+++ b/doc/classes/Directory.xml
@@ -127,8 +127,8 @@
</argument>
<description>
Initializes the stream used to list all files and directories using the [method get_next] function, closing the current opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end].
- If you pass [code]skip_navigational[/code], then [code].[/code] and [code]..[/code] would be filtered out.
- If you pass [code]skip_hidden[/code], then hidden files would be filtered out.
+ If [code]skip_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are filtered out.
+ If [code]skip_hidden[/code] is [code]true[/code], hidden files are filtered out.
</description>
</method>
<method name="list_dir_end">
diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml
index f5bf12a876..fedf77bfd2 100644
--- a/doc/classes/MainLoop.xml
+++ b/doc/classes/MainLoop.xml
@@ -4,7 +4,7 @@
Abstract base class for the game's main loop.
</brief_description>
<description>
- [MainLoop] is the abstract base class for a Godot project's game loop. It in inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree.
+ [MainLoop] is the abstract base class for a Godot project's game loop. It is inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree.
Upon the application start, a [MainLoop] implementation must be provided to the OS; otherwise, the application will exit. This happens automatically (and a [SceneTree] is created) unless a main [Script] is provided from the command line (with e.g. [code]godot -s my_loop.gd[/code], which should then be a [MainLoop] implementation.
Here is an example script implementing a simple [MainLoop]:
[codeblock]
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index fd856e5fd7..8e026b96ce 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -3496,6 +3496,8 @@ RID RasterizerStorageGLES2::skeleton_create() {
Skeleton *skeleton = memnew(Skeleton);
+ glGenTextures(1, &skeleton->tex_id);
+
return skeleton_owner.make_rid(skeleton);
}
@@ -3513,7 +3515,6 @@ void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool
skeleton->use_2d = p_2d_skeleton;
if (config.float_texture_supported) {
- glGenTextures(1, &skeleton->tex_id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 9c9a8e9717..40574d8c77 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -758,11 +758,13 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::OP_SELECT_IF: {
+ code += "(";
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += " ? ";
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += " : ";
code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ")";
} break;
case SL::OP_MOD: {
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 6b477ec78b..85ace4b4f0 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -772,11 +772,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::OP_SELECT_IF: {
+ code += "(";
code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "?";
code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += ":";
code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ")";
} break;
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index 232b9ce7c0..1952e201aa 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -165,11 +165,11 @@ void main() {
#elif defined(USE_ASYM_PANO)
// When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
- // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // Asymmetrical projection means the center of projection is no longer in the center of the screen but shifted.
// The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
vec3 cube_normal;
- cube_normal.z = -1000000.0;
+ cube_normal.z = -1.0;
cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
cube_normal = mat3(sky_transform) * mat3(pano_transform) * cube_normal;
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 1f43740858..8c9aedc7b7 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -257,6 +257,7 @@ void EditorFileDialog::_post_popup() {
if (is_visible_in_tree()) {
Ref<Texture> folder = get_icon("folder", "FileDialog");
+ const Color folder_color = get_color("folder", "FileDialog");
recent->clear();
bool res = access == ACCESS_RESOURCES;
@@ -274,6 +275,7 @@ void EditorFileDialog::_post_popup() {
recent->add_item(name, folder);
recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]);
+ recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color);
}
local_history.clear();
@@ -734,6 +736,7 @@ void EditorFileDialog::update_file_list() {
dir_access->list_dir_begin();
Ref<Texture> folder = get_icon("folder", "FileDialog");
+ const Color folder_color = get_color("folder", "FileDialog");
List<String> files;
List<String> dirs;
@@ -774,6 +777,7 @@ void EditorFileDialog::update_file_list() {
d["dir"] = true;
item_list->set_item_metadata(item_list->get_item_count() - 1, d);
+ item_list->set_item_icon_modulate(item_list->get_item_count() - 1, folder_color);
dirs.pop_front();
}
@@ -1200,6 +1204,7 @@ void EditorFileDialog::_update_favorites() {
String current = get_current_dir();
Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons");
+ const Color folder_color = get_color("folder", "FileDialog");
favorites->clear();
favorite->set_pressed(false);
@@ -1230,6 +1235,7 @@ void EditorFileDialog::_update_favorites() {
}
favorites->set_item_metadata(favorites->get_item_count() - 1, favorited[i]);
+ favorites->set_item_icon_modulate(favorites->get_item_count() - 1, folder_color);
if (setthis) {
favorite->set_pressed(true);
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index fbfc999dbf..af79c21f85 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -354,7 +354,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i]));
if (search_flags & SEARCH_PROPERTIES)
for (int i = 0; i < class_doc.properties.size(); i++)
- if (_match_string(term, class_doc.properties[i].name))
+ if (_match_string(term, class_doc.properties[i].name) || _match_string(term, class_doc.properties[i].getter) || _match_string(term, class_doc.properties[i].setter))
match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i]));
if (search_flags & SEARCH_THEME_ITEMS)
for (int i = 0; i < class_doc.theme_properties.size(); i++)
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 71e70300e9..554958117b 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5511,6 +5511,9 @@ EditorNode::EditorNode() {
}
}
+ // Define a minimum window size to prevent UI elements from overlapping or being cut off
+ OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE);
+
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 9c1e919824..d962001b38 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1066,6 +1066,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// FileDialog
theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons"));
+ // Use a different color for folder icons to make them easier to distinguish from files.
+ // On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color.
+ theme->set_color("folder", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(5, 5, 5)).linear_interpolate(accent_color, 0.7));
theme->set_color("files_disabled", "FileDialog", font_color_disabled);
// color picker
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index e4823c7745..83904800e9 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -64,6 +64,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
subdirectory_item->set_text(0, dname);
subdirectory_item->set_icon(0, get_icon("Folder", "EditorIcons"));
+ subdirectory_item->set_icon_color(0, get_color("folder", "FileDialog"));
subdirectory_item->set_selectable(0, true);
String lpath = p_dir->get_path();
subdirectory_item->set_metadata(0, lpath);
@@ -186,15 +187,19 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
continue;
Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons");
+ const Color folder_color = get_color("folder", "FileDialog");
String text;
Ref<Texture> icon;
+ Color color;
if (fave == "res://") {
text = "/";
icon = folder_icon;
+ color = folder_color;
} else if (fave.ends_with("/")) {
text = fave.substr(0, fave.length() - 1).get_file();
icon = folder_icon;
+ color = folder_color;
} else {
text = fave.get_file();
int index;
@@ -204,12 +209,14 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
} else {
icon = get_icon("File", "EditorIcons");
}
+ color = Color(1, 1, 1);
}
if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) {
TreeItem *ti = tree->create_item(favorites);
ti->set_text(0, text);
ti->set_icon(0, icon);
+ ti->set_icon_color(0, color);
ti->set_tooltip(0, fave);
ti->set_selectable(0, true);
ti->set_metadata(0, fave);
@@ -639,6 +646,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
}
Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog");
+ const Color folder_color = get_color("folder", "FileDialog");
// Build the FileInfo list
List<FileInfo> filelist;
@@ -716,6 +724,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->set_item_metadata(files->get_item_count() - 1, bd);
files->set_item_selectable(files->get_item_count() - 1, false);
+ files->set_item_icon_modulate(files->get_item_count() - 1, folder_color);
}
for (int i = 0; i < efd->get_subdir_count(); i++) {
@@ -724,6 +733,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->add_item(dname, folder_icon, true);
files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/");
+ files->set_item_icon_modulate(files->get_item_count() - 1, folder_color);
if (cselection.has(dname)) {
files->select(files->get_item_count() - 1, false);
diff --git a/editor/icons/icon_editor_curve_handle.svg b/editor/icons/icon_editor_curve_handle.svg
new file mode 100644
index 0000000000..c405ceab9d
--- /dev/null
+++ b/editor/icons/icon_editor_curve_handle.svg
@@ -0,0 +1 @@
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill="#fefefe" r="2.75" stroke="#000" stroke-linecap="square"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_editor_path_sharp_handle.svg b/editor/icons/icon_editor_path_sharp_handle.svg
new file mode 100644
index 0000000000..db160dfeae
--- /dev/null
+++ b/editor/icons/icon_editor_path_sharp_handle.svg
@@ -0,0 +1 @@
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m-3.035534-10.106602h6.071068v6.071068h-6.071068z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="matrix(-.70710678 .70710678 -.70710678 -.70710678 0 0)"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_editor_path_smooth_handle.svg b/editor/icons/icon_editor_path_smooth_handle.svg
new file mode 100644
index 0000000000..34f3d290bd
--- /dev/null
+++ b/editor/icons/icon_editor_path_smooth_handle.svg
@@ -0,0 +1 @@
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m1.5-8.5h7v7h-7z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="rotate(90)"/></svg> \ No newline at end of file
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 574b47d770..7f023af848 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -571,7 +571,8 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
return;
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
- const Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
+ // All polygon points are sharp, so use the sharp handle icon
+ const Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");
const Vertex active_point = get_active_point();
const int n_polygons = _get_polygon_count();
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index b87bd29cbd..f02dc0bd6d 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -367,18 +367,18 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
- if (!node)
+ if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid())
return;
- if (!node->is_visible_in_tree())
- return;
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- if (!node->get_curve().is_valid())
- return;
+ const Ref<Texture> path_sharp_handle = get_icon("EditorPathSharpHandle", "EditorIcons");
+ const Ref<Texture> path_smooth_handle = get_icon("EditorPathSmoothHandle", "EditorIcons");
+ // Both handle icons must be of the same size
+ const Size2 handle_size = path_sharp_handle->get_size();
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- Size2 handle_size = handle->get_size();
+ const Ref<Texture> curve_handle = get_icon("EditorCurveHandle", "EditorIcons");
+ const Size2 curve_handle_size = curve_handle->get_size();
Ref<Curve2D> curve = node->get_curve();
@@ -387,19 +387,35 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < len; i++) {
Vector2 point = xform.xform(curve->get_point_position(i));
- vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false, Color(1, 1, 1, 1));
+ // Determines the point icon to be used
+ bool smooth = false;
if (i < len - 1) {
Vector2 pointout = xform.xform(curve->get_point_position(i) + curve->get_point_out(i));
- vpc->draw_line(point, pointout, Color(0.5, 0.5, 1.0, 0.8), 1.0);
- vpc->draw_texture_rect(handle, Rect2(pointout - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
+ if (point != pointout) {
+ smooth = true;
+ // Draw the line with a dark and light color to be visible on all backgrounds
+ vpc->draw_line(point, pointout, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_line(point, pointout, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_texture_rect(curve_handle, Rect2(pointout - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75));
+ }
}
if (i > 0) {
Vector2 pointin = xform.xform(curve->get_point_position(i) + curve->get_point_in(i));
- vpc->draw_line(point, pointin, Color(0.5, 0.5, 1.0, 0.8), 1.0);
- vpc->draw_texture_rect(handle, Rect2(pointin - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
+ if (point != pointin) {
+ smooth = true;
+ // Draw the line with a dark and light color to be visible on all backgrounds
+ vpc->draw_line(point, pointin, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_line(point, pointin, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_texture_rect(curve_handle, Rect2(pointin - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75));
+ }
}
+
+ vpc->draw_texture_rect(
+ smooth ? path_smooth_handle : path_sharp_handle,
+ Rect2(point - handle_size * 0.5, handle_size),
+ false);
}
if (on_edge) {
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 1ae5acc5ff..2493380585 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -652,7 +652,6 @@ PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() {
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
create_material("path_material", path_color);
- path_color.a = 0.4;
- create_material("path_thin_material", path_color);
+ create_material("path_thin_material", Color(0.5, 0.5, 0.5));
create_handle_material("handles");
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 59004a08c0..bd532a6418 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -1045,8 +1045,8 @@ void Polygon2DEditor::_uv_draw() {
}
}
- Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- Ref<Texture> internal_handle = get_icon("EditorInternalHandle", "EditorIcons");
+ // All UV points are sharp, so use the sharp handle icon
+ Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");
Color poly_line_color = Color(0.9, 0.5, 0.5);
if (polygons.size() || polygon_create.size()) {
@@ -1120,7 +1120,8 @@ void Polygon2DEditor::_uv_draw() {
if (i < uv_draw_max) {
uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5);
} else {
- uv_edit_draw->draw_texture(internal_handle, mtx.xform(uvs[i]) - internal_handle->get_size() * 0.5);
+ // Internal vertex
+ uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1));
}
}
}
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 1e3b1ddd49..2eb3ce1ec3 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -5250,42 +5250,6 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
return;
snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
-
- Ref<InputEventKey> k = p_event;
-
- if (k.is_valid()) {
-
- // Note: need to check is_echo because first person movement keys might still be held
- if (!is_any_freelook_active() && !p_event->is_echo()) {
-
- if (!k->is_pressed())
- return;
-
- if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event)) {
- _menu_item_pressed(MENU_TOOL_SELECT);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event)) {
- _menu_item_pressed(MENU_TOOL_MOVE);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event)) {
- _menu_item_pressed(MENU_TOOL_ROTATE);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) {
- _menu_item_pressed(MENU_TOOL_SCALE);
- } else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event)) {
- snap_selected_nodes_to_floor();
- } else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) {
- if (are_local_coords_enabled()) {
- _menu_item_toggled(false, MENU_TOOL_LOCAL_COORDS);
- } else {
- _menu_item_toggled(true, MENU_TOOL_LOCAL_COORDS);
- }
- } else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
- if (is_snap_enabled()) {
- _menu_item_toggled(false, MENU_TOOL_USE_SNAP);
- } else {
- _menu_item_toggled(true, MENU_TOOL_USE_SNAP);
- }
- }
- }
- }
}
void SpatialEditor::_notification(int p_what) {
@@ -5559,7 +5523,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
button_binds.write[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
+ tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q));
+ tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
hbc_menu->add_child(memnew(VSeparator));
@@ -5569,7 +5534,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_MOVE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_MOVE;
tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
+ tool_button[TOOL_MODE_MOVE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_move", TTR("Move Mode"), KEY_W));
tool_button[TOOL_MODE_ROTATE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
@@ -5577,7 +5542,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_ROTATE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_ROTATE;
tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
+ tool_button[TOOL_MODE_ROTATE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Rotate Mode"), KEY_E));
tool_button[TOOL_MODE_SCALE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
@@ -5585,7 +5550,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_SCALE;
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
+ tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), KEY_R));
hbc_menu->add_child(memnew(VSeparator));
@@ -5629,9 +5594,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
- ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
- sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
- tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_tooltip(vformat(TTR("Local Space Mode (%s)"), sct));
+ tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Use Local Space"), KEY_T));
tool_option_button[TOOL_OPT_USE_SNAP] = memnew(ToolButton);
hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
@@ -5639,9 +5602,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
button_binds.write[0] = MENU_TOOL_USE_SNAP;
tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
- ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
- sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
- tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct));
+ tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), KEY_Y));
hbc_menu->add_child(memnew(VSeparator));
@@ -5661,12 +5622,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F);
ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_M);
ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
-
- ED_SHORTCUT("spatial_editor/tool_select", TTR("Tool Select"), KEY_Q);
- ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W);
- ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E);
- ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R);
-
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
PopupMenu *p;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index b2f06ca41f..b4cce9745e 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -2006,7 +2006,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
// Tools
paint_button = memnew(ToolButton);
paint_button->set_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P));
- paint_button->set_tooltip(TTR("Shift+RMB: Line Draw\nShift+Ctrl+RMB: Rectangle Paint"));
+ paint_button->set_tooltip(TTR("Shift+LMB: Line Draw\nShift+Ctrl+LMB: Rectangle Paint"));
paint_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_NONE));
paint_button->set_toggle_mode(true);
toolbar->add_child(paint_button);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index e193e237de..589964f620 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -69,8 +69,16 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
}
visual_shader = Ref<VisualShader>(p_visual_shader);
+ if (!visual_shader->is_connected("changed", this, "_update_preview")) {
+ visual_shader->connect("changed", this, "_update_preview");
+ }
visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE);
} else {
+ if (visual_shader.is_valid()) {
+ if (visual_shader->is_connected("changed", this, "")) {
+ visual_shader->disconnect("changed", this, "_update_preview");
+ }
+ }
visual_shader.unref();
}
@@ -81,6 +89,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
_clear_buffer();
_update_custom_nodes();
_update_options_menu();
+ _update_preview();
}
_update_graph();
}
@@ -524,21 +533,23 @@ void VisualShaderEditor::_update_graph() {
offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
node->add_child(offset);
- HBoxContainer *hb2 = memnew(HBoxContainer);
+ if (group_node->is_editable()) {
+ HBoxContainer *hb2 = memnew(HBoxContainer);
- Button *add_input_btn = memnew(Button);
- add_input_btn->set_text(TTR("Add input +"));
- add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED);
- hb2->add_child(add_input_btn);
+ Button *add_input_btn = memnew(Button);
+ add_input_btn->set_text(TTR("Add input +"));
+ add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED);
+ hb2->add_child(add_input_btn);
- hb2->add_spacer();
+ hb2->add_spacer();
- Button *add_output_btn = memnew(Button);
- add_output_btn->set_text(TTR("Add output +"));
- add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED);
- hb2->add_child(add_output_btn);
+ Button *add_output_btn = memnew(Button);
+ add_output_btn->set_text(TTR("Add output +"));
+ add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED);
+ hb2->add_child(add_output_btn);
- node->add_child(hb2);
+ node->add_child(hb2);
+ }
}
for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) {
@@ -1566,6 +1577,29 @@ void VisualShaderEditor::_notification(int p_what) {
node_filter->set_right_icon(Control::get_icon("Search", "EditorIcons"));
+ preview_shader->set_icon(Control::get_icon("Shader", "EditorIcons"));
+
+ {
+ Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
+ Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
+ Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
+ Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
+ Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
+
+ preview_text->add_color_override("background_color", background_color);
+
+ for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
+
+ preview_text->add_keyword_color(E->get(), keyword_color);
+ }
+
+ preview_text->add_font_override("font", get_font("expression", "EditorFonts"));
+ preview_text->add_color_override("font_color", text_color);
+ preview_text->add_color_override("symbol_color", symbol_color);
+ preview_text->add_color_region("/*", "*/", comment_color, false);
+ preview_text->add_color_region("//", "", comment_color, false);
+ }
+
tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Tools", "EditorIcons"));
if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree())
@@ -2016,6 +2050,15 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
}
+void VisualShaderEditor::_show_preview_text() {
+ preview_showed = !preview_showed;
+ preview_text->set_visible(preview_showed);
+}
+
+void VisualShaderEditor::_update_preview() {
+ preview_text->set_text(visual_shader->get_code());
+}
+
void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_rebuild", &VisualShaderEditor::_rebuild);
ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph);
@@ -2055,6 +2098,8 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_node_resized", &VisualShaderEditor::_node_resized);
ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size);
ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
+ ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text);
+ ClassDB::bind_method("_update_preview", &VisualShaderEditor::_update_preview);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
@@ -2081,13 +2126,23 @@ VisualShaderEditor::VisualShaderEditor() {
saved_node_pos = Point2(0, 0);
ShaderLanguage::get_keyword_list(&keyword_list);
+ preview_showed = false;
+
to_node = -1;
to_slot = -1;
from_node = -1;
from_slot = -1;
+ main_box = memnew(HSplitContainer);
+ main_box->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_box->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_child(main_box);
+
graph = memnew(GraphEdit);
- add_child(graph);
+ graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
+ graph->set_v_size_flags(SIZE_EXPAND_FILL);
+ graph->set_h_size_flags(SIZE_EXPAND_FILL);
+ main_box->add_child(graph);
graph->set_drag_forwarding(this);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN);
@@ -2136,6 +2191,25 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->move_child(add_node, 0);
add_node->connect("pressed", this, "_show_members_dialog", varray(false));
+ preview_shader = memnew(ToolButton);
+ preview_shader->set_toggle_mode(true);
+ preview_shader->set_tooltip(TTR("Show resulted shader code."));
+ graph->get_zoom_hbox()->add_child(preview_shader);
+ preview_shader->connect("pressed", this, "_show_preview_text");
+
+ ///////////////////////////////////////
+ // PREVIEW PANEL
+ ///////////////////////////////////////
+
+ preview_text = memnew(TextEdit);
+ main_box->add_child(preview_text);
+ preview_text->set_h_size_flags(SIZE_EXPAND_FILL);
+ preview_text->set_v_size_flags(SIZE_EXPAND_FILL);
+ preview_text->set_visible(preview_showed);
+ preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0));
+ preview_text->set_syntax_coloring(true);
+ preview_text->set_readonly(true);
+
///////////////////////////////////////
// SHADER NODES TREE
///////////////////////////////////////
@@ -2413,8 +2487,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeScalarFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -2507,10 +2581,10 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -2528,6 +2602,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside.")));
add_options.push_back(AddOption("Fresnel", "Special", "", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
add_options.push_back(AddOption("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true));
add_options.push_back(AddOption("VectorDerivativeFunc", "Special", "Common", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) Vector derivative function."), -1, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true));
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index b5b00f2b5e..1556c7cd43 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -60,14 +60,18 @@ class VisualShaderEditor : public VBoxContainer {
int editing_port;
Ref<VisualShader> visual_shader;
+ HSplitContainer *main_box;
GraphEdit *graph;
ToolButton *add_node;
+ ToolButton *preview_shader;
OptionButton *edit_type;
PanelContainer *error_panel;
Label *error_label;
+ TextEdit *preview_text;
+
UndoRedo *undo_redo;
Point2 saved_node_pos;
bool saved_node_pos_dirty;
@@ -75,6 +79,8 @@ class VisualShaderEditor : public VBoxContainer {
ConfirmationDialog *members_dialog;
MenuButton *tools;
+ bool preview_showed;
+
enum ToolsMenuOptions {
EXPAND_ALL,
COLLAPSE_ALL
@@ -146,6 +152,9 @@ class VisualShaderEditor : public VBoxContainer {
void _update_custom_nodes();
void _update_options_menu();
+ void _show_preview_text();
+ void _update_preview();
+
static VisualShaderEditor *singleton;
void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 0f3c4c924a..a418773131 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -997,7 +997,6 @@ public:
void load_projects();
void set_search_term(String p_search_term);
- void set_filter_option(ProjectListFilter::FilterOption p_option);
void set_order_option(ProjectListFilter::FilterOption p_option);
void sort_projects();
int get_project_count() const;
@@ -1030,7 +1029,6 @@ private:
static void load_project_data(const String &p_property_key, Item &p_item, bool p_favorite);
String _search_term;
- ProjectListFilter::FilterOption _filter_option;
ProjectListFilter::FilterOption _order_option;
Set<String> _selected_project_keys;
String _last_clicked; // Project key
@@ -1063,7 +1061,6 @@ struct ProjectListComparator {
};
ProjectList::ProjectList() {
- _filter_option = ProjectListFilter::FILTER_NAME;
_order_option = ProjectListFilter::FILTER_MODIFIED;
_scroll_children = memnew(VBoxContainer);
@@ -1303,12 +1300,6 @@ void ProjectList::set_search_term(String p_search_term) {
_search_term = p_search_term;
}
-void ProjectList::set_filter_option(ProjectListFilter::FilterOption p_option) {
- if (_filter_option != p_option) {
- _filter_option = p_option;
- }
-}
-
void ProjectList::set_order_option(ProjectListFilter::FilterOption p_option) {
if (_order_option != p_option) {
_order_option = p_option;
@@ -1328,11 +1319,18 @@ void ProjectList::sort_projects() {
bool visible = true;
if (_search_term != "") {
- if (_filter_option == ProjectListFilter::FILTER_PATH) {
- visible = item.path.findn(_search_term) != -1;
- } else if (_filter_option == ProjectListFilter::FILTER_NAME) {
- visible = item.project_name.findn(_search_term) != -1;
+
+ String search_path;
+ if (_search_term.find("/") != -1) {
+ // Search path will match the whole path
+ search_path = item.path;
+ } else {
+ // Search path will only match the last path component to make searching more strict
+ search_path = item.path.get_file();
}
+
+ // When searching, display projects whose name or path contain the search term
+ visible = item.project_name.findn(_search_term) != -1 || search_path.findn(_search_term) != -1;
}
item.control->set_visible(visible);
@@ -1694,7 +1692,6 @@ void ProjectList::_bind_methods() {
ClassDB::bind_method("_panel_input", &ProjectList::_panel_input);
ClassDB::bind_method("_favorite_pressed", &ProjectList::_favorite_pressed);
ClassDB::bind_method("_show_project", &ProjectList::_show_project);
- //ClassDB::bind_method("_unhandled_input", &ProjectList::_unhandled_input);
ADD_SIGNAL(MethodInfo(SIGNAL_SELECTION_CHANGED));
ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN));
@@ -1754,8 +1751,19 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
if (k.is_valid()) {
- if (!k->is_pressed())
+ if (!k->is_pressed()) {
return;
+ }
+
+ // Pressing Command + Q quits the Project Manager
+ // This is handled by the platform implementation on macOS,
+ // so only define the shortcut on other platforms
+#ifndef OSX_ENABLED
+ if (k->get_scancode_with_modifiers() == (KEY_MASK_CMD | KEY_Q)) {
+ _dim_window();
+ get_tree()->quit();
+ }
+#endif
if (tabs->get_current_tab() != 0)
return;
@@ -1834,7 +1842,6 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
void ProjectManager::_load_recent_projects() {
- _project_list->set_filter_option(project_filter->get_filter_option());
_project_list->set_order_option(project_order_filter->get_filter_option());
_project_list->set_search_term(project_filter->get_search_term());
_project_list->load_projects();
@@ -2198,7 +2205,6 @@ void ProjectManager::_on_order_option_changed() {
}
void ProjectManager::_on_filter_option_changed() {
- _project_list->set_filter_option(project_filter->get_filter_option());
_project_list->set_search_term(project_filter->get_search_term());
_project_list->sort_projects();
}
@@ -2270,6 +2276,9 @@ ProjectManager::ProjectManager() {
} break;
}
+ // Define a minimum window size to prevent UI elements from overlapping or being cut off
+ OS::get_singleton()->set_min_window_size(Size2(750, 420) * EDSCALE);
+
#ifndef OSX_ENABLED
// The macOS platform implementation uses its own hiDPI window resizing code
// TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below
@@ -2295,26 +2304,11 @@ ProjectManager::ProjectManager() {
VBoxContainer *vb = memnew(VBoxContainer);
panel->add_child(vb);
vb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8 * EDSCALE);
- vb->add_constant_override("separation", 8 * EDSCALE);
String cp;
cp += 0xA9;
OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2019 Juan Linietsky, Ariel Manzur & Godot Contributors");
- HBoxContainer *top_hb = memnew(HBoxContainer);
- vb->add_child(top_hb);
- Label *l = memnew(Label);
- l->set_text(VERSION_NAME + String(" - ") + TTR("Project Manager"));
- top_hb->add_child(l);
- top_hb->add_spacer();
- l = memnew(Label);
- String hash = String(VERSION_HASH);
- if (hash.length() != 0)
- hash = "." + hash.left(9);
- l->set_text("v" VERSION_FULL_BUILD "" + hash);
- l->set_align(Label::ALIGN_CENTER);
- top_hb->add_child(l);
-
Control *center_box = memnew(Control);
center_box->set_v_size_flags(SIZE_EXPAND_FILL);
vb->add_child(center_box);
@@ -2322,11 +2316,12 @@ ProjectManager::ProjectManager() {
tabs = memnew(TabContainer);
center_box->add_child(tabs);
tabs->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ tabs->set_tab_align(TabContainer::ALIGN_LEFT);
HBoxContainer *tree_hb = memnew(HBoxContainer);
projects_hb = tree_hb;
- projects_hb->set_name(TTR("Project List"));
+ projects_hb->set_name(TTR("Projects"));
tabs->add_child(tree_hb);
@@ -2343,6 +2338,7 @@ ProjectManager::ProjectManager() {
sort_filter_titles.push_back("Path");
sort_filter_titles.push_back("Last Modified");
project_order_filter = memnew(ProjectListFilter);
+ project_order_filter->add_filter_option();
project_order_filter->_setup_filters(sort_filter_titles);
project_order_filter->set_filter_size(150);
sort_filters->add_child(project_order_filter);
@@ -2353,21 +2349,12 @@ ProjectManager::ProjectManager() {
project_order_filter->set_filter_option((ProjectListFilter::FilterOption)projects_sorting_order);
sort_filters->add_spacer(true);
- Label *search_label = memnew(Label);
- search_label->set_text(TTR("Search:"));
- sort_filters->add_child(search_label);
-
- HBoxContainer *search_filters = memnew(HBoxContainer);
- Vector<String> vec2;
- vec2.push_back("Name");
- vec2.push_back("Path");
+
project_filter = memnew(ProjectListFilter);
- project_filter->_setup_filters(vec2);
project_filter->add_search_box();
- search_filters->add_child(project_filter);
project_filter->connect("filter_changed", this, "_on_filter_option_changed");
project_filter->set_custom_minimum_size(Size2(280, 10) * EDSCALE);
- sort_filters->add_child(search_filters);
+ sort_filters->add_child(project_filter);
search_tree_vb->add_child(sort_filters);
@@ -2457,6 +2444,17 @@ ProjectManager::ProjectManager() {
settings_hb->set_alignment(BoxContainer::ALIGN_END);
settings_hb->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
+ Label *version_label = memnew(Label);
+ String hash = String(VERSION_HASH);
+ if (hash.length() != 0) {
+ hash = "." + hash.left(9);
+ }
+ version_label->set_text("v" VERSION_FULL_BUILD "" + hash);
+ // Fade out the version label to be less prominent, but still readable
+ version_label->set_self_modulate(Color(1, 1, 1, 0.6));
+ version_label->set_align(Label::ALIGN_CENTER);
+ settings_hb->add_child(version_label);
+
language_btn = memnew(OptionButton);
language_btn->set_flat(true);
language_btn->set_focus_mode(Control::FOCUS_NONE);
@@ -2489,27 +2487,6 @@ ProjectManager::ProjectManager() {
center_box->add_child(settings_hb);
settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT);
- CenterContainer *cc = memnew(CenterContainer);
- Button *cancel = memnew(Button);
- cancel->set_text(TTR("Exit"));
- cancel->set_custom_minimum_size(Size2(100, 1) * EDSCALE);
-
-#ifndef OSX_ENABLED
- // Pressing Command + Q quits the Project Manager
- // This is handled by the platform implementation on macOS,
- // so only define the shortcut on other platforms
- InputEventKey *quit_key = memnew(InputEventKey);
- quit_key->set_command(true);
- quit_key->set_scancode(KEY_Q);
- ShortCut *quit_shortcut = memnew(ShortCut);
- quit_shortcut->set_shortcut(quit_key);
- cancel->set_shortcut(quit_shortcut);
-#endif
-
- cc->add_child(cancel);
- cancel->connect("pressed", this, "_exit_dialog");
- vb->add_child(cc);
-
//////////////////////////////////////////////////////////////
language_restart_ask = memnew(ConfirmationDialog);
@@ -2630,11 +2607,20 @@ void ProjectListFilter::_bind_methods() {
ADD_SIGNAL(MethodInfo("filter_changed"));
}
+void ProjectListFilter::add_filter_option() {
+ filter_option = memnew(OptionButton);
+ filter_option->set_clip_text(true);
+ filter_option->connect("item_selected", this, "_filter_option_selected");
+ add_child(filter_option);
+}
+
void ProjectListFilter::add_search_box() {
search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Search"));
search_box->connect("text_changed", this, "_search_text_changed");
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(search_box);
+
has_search_box = true;
}
@@ -2645,13 +2631,6 @@ void ProjectListFilter::set_filter_size(int h_size) {
ProjectListFilter::ProjectListFilter() {
_current_filter = FILTER_NAME;
-
- filter_option = memnew(OptionButton);
- set_filter_size(80);
- filter_option->set_clip_text(true);
- filter_option->connect("item_selected", this, "_filter_option_selected");
- add_child(filter_option);
-
has_search_box = false;
}
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 4ccb99d6bd..2a5fd02892 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -152,6 +152,7 @@ protected:
public:
void _setup_filters(Vector<String> options);
+ void add_filter_option();
void add_search_box();
void set_filter_size(int h_size);
String get_search_term();
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index fd0d36eddf..f1b3fa2ac6 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -242,7 +242,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
//check if edge and poly share a vertex, of so, assign it to segment_idx
for (int i = 0; i < points.size(); i++) {
for (int j = 0; j < 2; j++) {
- if (Math::is_zero_approx(segment[j].distance_to(points[i].point))) {
+ if (segment[j] == points[i].point) {
segment_idx[j] = i;
inserted_points.push_back(i);
break;
@@ -310,7 +310,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point };
Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg);
- if (Math::is_zero_approx(closest.distance_to(segment[j]))) {
+ if (closest == segment[j]) {
//point rest of this edge
res = closest;
found = true;
@@ -439,7 +439,7 @@ void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, Mes
//transform A points to 2D
- if (Math::is_zero_approx(segment[0].distance_to(segment[1])))
+ if (segment[0] == segment[1])
return; //too small
_clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B);
@@ -461,10 +461,10 @@ void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map
{
//check if either is a degenerate
- if (Math::is_zero_approx(va[0].distance_to(va[1])) || Math::is_zero_approx(va[0].distance_to(va[2])) || Math::is_zero_approx(va[1].distance_to(va[2])))
+ if (va[0] == va[1] || va[0] == va[2] || va[1] == va[2])
return;
- if (Math::is_zero_approx(vb[0].distance_to(vb[1])) || Math::is_zero_approx(vb[0].distance_to(vb[2])) || Math::is_zero_approx(vb[1].distance_to(vb[2])))
+ if (vb[0] == vb[1] || vb[0] == vb[2] || vb[1] == vb[2])
return;
}
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index 62f09bfbf9..dd86c758bf 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -265,7 +265,10 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons
ERR_FAIL_COND_V(p_to == p_from, FAILED);
- return get_peer(p_to)->put_packet(p_buffer, p_buffer_size); // Sending to specific peer
+ Ref<WebSocketPeer> peer_to = get_peer(p_to);
+ ERR_FAIL_COND_V(peer_to.is_null(), FAILED);
+
+ return peer_to->put_packet(p_buffer, p_buffer_size); // Sending to specific peer
}
}
@@ -296,8 +299,6 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
ERR_FAIL_COND(type != SYS_NONE); // Only server sends sys messages
ERR_FAIL_COND(from != p_peer_id); // Someone is cheating
- _server_relay(from, to, in_buffer, size); // Relay if needed
-
if (to == 1) { // This is for the server
_store_pkt(from, to, in_buffer, data_size);
@@ -312,13 +313,9 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
// All but one, for us if not excluded
if (_peer_id != -(int32_t)p_peer_id)
_store_pkt(from, to, in_buffer, data_size);
-
- } else {
-
- // Send to specific peer
- ERR_FAIL_COND(!_peer_map.has(to));
- get_peer(to)->put_packet(in_buffer, size);
}
+ // Relay if needed (i.e. "to" includes a peer that is not the server)
+ _server_relay(from, to, in_buffer, size);
} else {
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index f644db462b..5cf28d6c89 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
left_poly = p;
portal_left = apex_point;
portal_right = apex_point;
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point)))
+ if (!path.size() || path[path.size() - 1] != apex_point)
path.push_back(apex_point);
skip = true;
}
@@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
right_poly = p;
portal_right = apex_point;
portal_left = apex_point;
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point)))
+ if (!path.size() || path[path.size() - 1] != apex_point)
path.push_back(apex_point);
}
}
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index f2f53d4354..55c8c7f229 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -110,7 +110,7 @@ void Path2D::_notification(int p_what) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, color, line_width);
+ draw_line(prev_p, p, color, line_width, true);
prev_p = p;
}
}
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 30aeebfdac..051f832882 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -1200,7 +1200,9 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
}
}
- _stop_playing_caches();
+ if (get_current_animation() != p_name) {
+ _stop_playing_caches();
+ }
c.current.from = &animation_set[name];
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index f1bdbb5ff5..7305d7459c 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -400,6 +400,7 @@ void FileDialog::update_file_list() {
TreeItem *root = tree->create_item();
Ref<Texture> folder = get_icon("folder");
+ const Color folder_color = get_color("folder");
List<String> files;
List<String> dirs;
@@ -429,6 +430,7 @@ void FileDialog::update_file_list() {
TreeItem *ti = tree->create_item(root);
ti->set_text(0, dir_name);
ti->set_icon(0, folder);
+ ti->set_icon_color(0, folder_color);
Dictionary d;
d["name"] = dir_name;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index c0eaf21215..a771794f25 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -129,7 +129,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
int len = text[p_line].data.length();
const CharType *str = text[p_line].data.c_str();
- //update width
+ // Update width.
for (int i = 0; i < len; i++) {
w += get_char_width(str[i], str[i + 1], w);
@@ -139,7 +139,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
text.write[p_line].wrap_amount_cache = -1;
- //update regions
+ // Update regions.
text.write[p_line].region_info.clear();
@@ -148,7 +148,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
if (!_is_symbol(str[i]))
continue;
if (str[i] == '\\') {
- i++; //skip quoted anything
+ i++; // Skip quoted anything.
continue;
}
@@ -275,7 +275,7 @@ void TextEdit::Text::clear() {
}
int TextEdit::Text::get_max_width(bool p_exclude_hidden) const {
- //quite some work.. but should be fast enough.
+ // Quite some work, but should be fast enough.
int max = 0;
for (int i = 0; i < text.size(); i++) {
@@ -323,7 +323,7 @@ int TextEdit::Text::get_char_width(CharType c, CharType next_c, int px) const {
if (left == 0)
w = tab_w;
else
- w = tab_w - px % tab_w; // is right...
+ w = tab_w - px % tab_w; // Is right.
} else {
w = font->get_char_size(c, next_c).width;
@@ -370,20 +370,18 @@ void TextEdit::_update_scrollbars() {
bool use_hscroll = true;
bool use_vscroll = true;
+ // Thanks yessopie for this clever bit of logic.
if (total_rows <= visible_rows && total_width <= visible_width) {
- //thanks yessopie for this clever bit of logic
+
use_hscroll = false;
use_vscroll = false;
-
} else {
if (total_rows > visible_rows && total_width <= visible_width) {
- //thanks yessopie for this clever bit of logic
use_hscroll = false;
}
if (total_rows <= visible_rows && total_width > visible_width) {
- //thanks yessopie for this clever bit of logic
use_vscroll = false;
}
}
@@ -481,7 +479,7 @@ void TextEdit::_update_selection_mode_word() {
String line = text[row];
int beg = CLAMP(col, 0, line.length());
- // if its the first selection and on whitespace make sure we grab the word instead..
+ // If its the first selection and on whitespace make sure we grab the word instead.
if (!selection.active) {
while (beg > 0 && line[beg] <= 32) {
beg--;
@@ -490,7 +488,7 @@ void TextEdit::_update_selection_mode_word() {
int end = beg;
bool symbol = beg < line.length() && _is_symbol(line[beg]);
- // get the word end and begin points
+ // Get the word end and begin points.
while (beg > 0 && line[beg - 1] > 32 && (symbol == _is_symbol(line[beg - 1]))) {
beg--;
}
@@ -501,7 +499,7 @@ void TextEdit::_update_selection_mode_word() {
end += 1;
}
- // initial selection
+ // Initial selection.
if (!selection.active) {
select(row, beg, row, end);
selection.selecting_column = beg;
@@ -537,11 +535,11 @@ void TextEdit::_update_selection_mode_line() {
col = 0;
if (row < selection.selecting_line) {
- // cursor is above us
+ // Cursor is above us.
cursor_set_line(row - 1, false);
selection.selecting_column = text[selection.selecting_line].length();
} else {
- // cursor is below us
+ // Cursor is below us.
cursor_set_line(row + 1, false);
selection.selecting_column = 0;
col = text[row].length();
@@ -607,7 +605,7 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_DRAW: {
if (first_draw) {
- //size may not be the final one, so attempts to ensure cursor was visible may have failed
+ // Size may not be the final one, so attempts to ensure cursor was visible may have failed.
adjust_viewport_to_cursor();
first_draw = false;
}
@@ -661,7 +659,7 @@ void TextEdit::_notification(int p_what) {
VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width;
int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT);
- //let's do it easy for now:
+ // Let's do it easy for now.
cache.style_normal->draw(ci, Rect2(Point2(), size));
if (readonly) {
cache.style_readonly->draw(ci, Rect2(Point2(), size));
@@ -701,7 +699,7 @@ void TextEdit::_notification(int p_what) {
if (brace_matching_enabled && cursor.line >= 0 && cursor.line < text.size() && cursor.column >= 0) {
if (cursor.column < text[cursor.line].length()) {
- //check for open
+ // Check for open.
CharType c = text[cursor.line][cursor.column];
CharType closec = 0;
@@ -723,7 +721,7 @@ void TextEdit::_notification(int p_what) {
for (int j = from; j < text[i].length(); j++) {
CharType cc = text[i][j];
- //ignore any brackets inside a string
+ // Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
CharType quotation = cc;
do {
@@ -732,7 +730,7 @@ void TextEdit::_notification(int p_what) {
break;
}
cc = text[i][j];
- //skip over escaped quotation marks inside strings
+ // Skip over escaped quotation marks inside strings.
if (cc == '\\') {
bool escaped = true;
while (j + 1 < text[i].length() && text[i][j + 1] == '\\') {
@@ -789,7 +787,7 @@ void TextEdit::_notification(int p_what) {
for (int j = from; j >= 0; j--) {
CharType cc = text[i][j];
- //ignore any brackets inside a string
+ // Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
CharType quotation = cc;
do {
@@ -798,7 +796,7 @@ void TextEdit::_notification(int p_what) {
break;
}
cc = text[i][j];
- //skip over escaped quotation marks inside strings
+ // Skip over escaped quotation marks inside strings.
if (cc == quotation) {
bool escaped = false;
while (j - 1 >= 0 && text[i][j - 1] == '\\') {
@@ -837,10 +835,10 @@ void TextEdit::_notification(int p_what) {
Point2 cursor_pos;
int cursor_insert_offset_y = 0;
- // get the highlighted words
+ // Get the highlighted words.
String highlighted_text = get_selection_text();
- // check if highlighted words contains only whitespaces (tabs or spaces)
+ // Check if highlighted words contains only whitespaces (tabs or spaces).
bool only_whitespaces_highlighted = highlighted_text.strip_edges() == String();
String line_num_padding = line_numbers_zero_padded ? "0" : " ";
@@ -875,7 +873,7 @@ void TextEdit::_notification(int p_what) {
if (syntax_coloring) {
color_map = _get_line_syntax_highlighting(line);
}
- // ensure we at least use the font color
+ // Ensure we at least use the font color.
Color current_color = readonly ? cache.font_color_readonly : cache.font_color;
bool underlined = false;
@@ -916,7 +914,7 @@ void TextEdit::_notification(int p_what) {
if (smooth_scroll_enabled)
ofs_y += (-get_v_scroll_offset()) * get_row_height();
- // check if line contains highlighted word
+ // Check if line contains highlighted word.
int highlighted_text_col = -1;
int search_text_col = -1;
int highlighted_word_col = -1;
@@ -938,25 +936,25 @@ void TextEdit::_notification(int p_what) {
}
if (str.length() == 0) {
- // draw line background if empty as we won't loop at at all
+ // Draw line background if empty as we won't loop at at all.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, get_row_height()), cache.current_line_color);
}
- // give visual indication of empty selected line
+ // Give visual indication of empty selected line.
if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) {
int char_w = cache.font->get_char_size(' ').width;
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, char_w, get_row_height()), cache.selection_color);
}
} else {
- // if it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later.
+ // If it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_beg, get_row_height()), cache.current_line_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_beg + ofs_x, get_row_height()), cache.current_line_color);
}
}
if (line_wrap_index == 0) {
- // only do these if we are on the first wrapped part of a line
+ // Only do these if we are on the first wrapped part of a line.
if (text.is_breakpoint(line) && !draw_breakpoint_gutter) {
#ifdef TOOLS_ENABLED
@@ -966,7 +964,7 @@ void TextEdit::_notification(int p_what) {
#endif
}
- // draw bookmark marker
+ // Draw bookmark marker.
if (text.is_bookmark(line)) {
if (draw_bookmark_gutter) {
int vertical_gap = (get_row_height() * 40) / 100;
@@ -976,26 +974,26 @@ void TextEdit::_notification(int p_what) {
}
}
- // draw breakpoint marker
+ // Draw breakpoint marker.
if (text.is_breakpoint(line)) {
if (draw_breakpoint_gutter) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
int marker_height = get_row_height() - (vertical_gap * 2);
int marker_width = cache.breakpoint_gutter_width - (horizontal_gap * 2);
- // no transparency on marker
+ // No transparency on marker.
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cache.style_normal->get_margin(MARGIN_LEFT) + horizontal_gap - 2, ofs_y + vertical_gap, marker_width, marker_height), Color(cache.breakpoint_color.r, cache.breakpoint_color.g, cache.breakpoint_color.b));
}
}
- // draw info icons
+ // Draw info icons.
if (draw_info_gutter && text.has_info_icon(line)) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.info_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width;
Ref<Texture> info_icon = text.get_info_icon(line);
- // ensure the icon fits the gutter size
+ // Ensure the icon fits the gutter size.
Size2i icon_size = info_icon->get_size();
if (icon_size.width > cache.info_gutter_width - horizontal_gap) {
icon_size.width = cache.info_gutter_width - horizontal_gap;
@@ -1013,7 +1011,7 @@ void TextEdit::_notification(int p_what) {
draw_texture_rect(info_icon, Rect2(icon_pos, icon_size));
}
- // draw execution marker
+ // Draw execution marker.
if (executing_line == line) {
if (draw_breakpoint_gutter) {
int icon_extra_size = 4;
@@ -1031,7 +1029,7 @@ void TextEdit::_notification(int p_what) {
}
}
- // draw fold markers
+ // Draw fold markers.
if (draw_fold_gutter) {
int horizontal_gap = (cache.fold_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + cache.line_number_w + cache.info_gutter_width;
@@ -1046,7 +1044,7 @@ void TextEdit::_notification(int p_what) {
}
}
- // draw line numbers
+ // Draw line numbers.
if (cache.line_number_w) {
int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2;
String fc = String::num(line + 1);
@@ -1058,32 +1056,35 @@ void TextEdit::_notification(int p_what) {
}
}
- //loop through characters in one line
+ // Loop through characters in one line.
for (int j = 0; j < str.length(); j++) {
if (syntax_coloring) {
if (color_map.has(last_wrap_column + j)) {
- current_color = readonly ? cache.font_color_readonly : color_map[last_wrap_column + j].color;
+ current_color = color_map[last_wrap_column + j].color;
+ if (readonly && current_color.a > cache.font_color_readonly.a) {
+ current_color.a = cache.font_color_readonly.a;
+ }
}
color = current_color;
}
int char_w;
- //handle tabulator
+ // Handle tabulator.
char_w = text.get_char_width(str[j], str[j + 1], char_ofs);
if ((char_ofs + char_margin) < xmargin_beg) {
char_ofs += char_w;
- // line highlighting handle horizontal clipping
+ // Line highlighting handle horizontal clipping.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
if (j == str.length() - 1) {
- // end of line when last char is skipped
+ // End of line when last char is skipped.
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
} else if ((char_ofs + char_margin) > xmargin_beg) {
- // char next to margin is skipped
+ // Char next to margin is skipped.
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, (char_ofs + char_margin) - (xmargin_beg + ofs_x), get_row_height()), cache.current_line_color);
}
}
@@ -1097,7 +1098,7 @@ void TextEdit::_notification(int p_what) {
bool in_search_result = false;
if (search_text_col != -1) {
- // if we are at the end check for new search result on same line
+ // If we are at the end check for new search result on same line.
if (j >= search_text_col + search_text.length())
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, j);
@@ -1108,19 +1109,19 @@ void TextEdit::_notification(int p_what) {
}
}
- //current line highlighting
+ // Current line highlighting.
bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || last_wrap_column + j >= selection.from_column) && (line < selection.to_line || last_wrap_column + j < selection.to_column));
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
- // draw the wrap indent offset highlight
+ // Draw the wrap indent offset highlight.
if (line_wrap_index != 0 && j == 0) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin - indent_px, ofs_y, indent_px, get_row_height()), cache.current_line_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + ofs_x - indent_px, ofs_y, indent_px, get_row_height()), cache.current_line_color);
}
- // if its the last char draw to end of the line
+ // If its the last char draw to end of the line.
if (j == str.length() - 1) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + char_w, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + char_w + ofs_x, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
}
- // actual text
+ // Actual text.
if (!in_selection) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y), Size2i(char_w, get_row_height())), cache.current_line_color);
}
@@ -1145,14 +1146,14 @@ void TextEdit::_notification(int p_what) {
if (highlight_all_occurrences && !only_whitespaces_highlighted) {
if (highlighted_text_col != -1) {
- // if we are at the end check for new word on same line
+ // If we are at the end check for new word on same line.
if (j > highlighted_text_col + highlighted_text.length()) {
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, j);
}
bool in_highlighted_word = (j >= highlighted_text_col && j < highlighted_text_col + highlighted_text.length());
- // if this is the original highlighted text we don't want to highlight it again
+ // If this is the original highlighted text we don't want to highlight it again.
if (cursor.line == line && cursor_wrap_index == line_wrap_index && (cursor.column >= highlighted_text_col && cursor.column <= highlighted_text_col + highlighted_text.length())) {
in_highlighted_word = false;
}
@@ -1349,7 +1350,7 @@ void TextEdit::_notification(int p_what) {
bool completion_below = false;
if (completion_active) {
- // code completion box
+ // Code completion box.
Ref<StyleBox> csb = get_stylebox("completion");
int maxlines = get_constant("completion_lines");
int cmax_width = get_constant("completion_max_width") * cache.font->get_char_size('x').x;
@@ -1371,7 +1372,7 @@ void TextEdit::_notification(int p_what) {
w = cmax_width;
}
- // Add space for completion icons
+ // Add space for completion icons.
const int icon_hsep = get_constant("hseparation", "ItemList");
Size2 icon_area_size(get_row_height(), get_row_height());
w += icon_area_size.width + icon_hsep;
@@ -1418,7 +1419,7 @@ void TextEdit::_notification(int p_what) {
int yofs = (get_row_height() - cache.font->get_height()) / 2;
Point2 title_pos(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs);
- //draw completion icon if it is valid
+ // Draw completion icon if it is valid.
Ref<Texture> icon = completion_options[l].icon;
Rect2 icon_area(completion_rect.position.x, completion_rect.position.y + i * get_row_height(), icon_area_size.width, icon_area_size.height);
if (icon.is_valid()) {
@@ -1434,7 +1435,7 @@ void TextEdit::_notification(int p_what) {
}
if (scrollw) {
- //draw a small scroll rectangle to show a position in the options
+ // Draw a small scroll rectangle to show a position in the options.
float r = maxlines / (float)completion_options.size();
float o = line_from / (float)completion_options.size();
draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc);
@@ -1443,7 +1444,7 @@ void TextEdit::_notification(int p_what) {
completion_line_ofs = line_from;
}
- // check to see if the hint should be drawn
+ // Check to see if the hint should be drawn.
bool show_hint = false;
if (completion_hint != "") {
if (completion_active) {
@@ -1662,9 +1663,9 @@ void TextEdit::backspace_at_cursor() {
_is_pair_left_symbol(text[cursor.line][cursor.column - 1])) {
_consume_backspace_for_pair_symbol(prev_line, prev_column);
} else {
- // handle space indentation
+ // Handle space indentation.
if (cursor.column != 0 && indent_using_spaces) {
- // check if there are no other chars before cursor, just indentation
+ // Check if there are no other chars before cursor, just indentation.
bool unindent = true;
int i = 0;
while (i < cursor.column && i < text[cursor.line].length()) {
@@ -1675,10 +1676,9 @@ void TextEdit::backspace_at_cursor() {
i++;
}
- // then we can remove all spaces as a single character.
+ // Then we can remove all spaces as a single character.
if (unindent) {
- // we want to remove spaces up to closest indent
- // or whole indent if cursor is pointing at it
+ // We want to remove spaces up to closest indent, or whole indent if cursor is pointing at it.
int spaces_to_delete = _calculate_spaces_till_next_left_indent(cursor.column);
prev_column = cursor.column - spaces_to_delete;
_remove_text(cursor.line, prev_column, cursor.line, cursor.column);
@@ -1699,8 +1699,8 @@ void TextEdit::indent_right() {
int start_line;
int end_line;
- // this value informs us by how much we changed selection position by indenting right
- // default is 1 for tab indentation
+ // This value informs us by how much we changed selection position by indenting right.
+ // Default is 1 for tab indentation.
int selection_offset = 1;
begin_complex_operation();
@@ -1712,7 +1712,7 @@ void TextEdit::indent_right() {
end_line = start_line;
}
- // ignore if the cursor is not past the first column
+ // Ignore if the cursor is not past the first column.
if (is_selection_active() && get_selection_to_column() == 0) {
end_line--;
}
@@ -1720,10 +1720,10 @@ void TextEdit::indent_right() {
for (int i = start_line; i <= end_line; i++) {
String line_text = get_line(i);
if (indent_using_spaces) {
- // we don't really care where selection is - we just need to know indentation level at the beginning of the line
+ // We don't really care where selection is - we just need to know indentation level at the beginning of the line.
int left = _find_first_non_whitespace_column_of_line(line_text);
int spaces_to_add = _calculate_spaces_till_next_right_indent(left);
- // since we will add this much spaces we want move whole selection and cursor by this much
+ // Since we will add this much spaces we want move whole selection and cursor by this much.
selection_offset = spaces_to_add;
for (int j = 0; j < spaces_to_add; j++)
line_text = ' ' + line_text;
@@ -1733,7 +1733,7 @@ void TextEdit::indent_right() {
set_line(i, line_text);
}
- // fix selection and cursor being off after shifting selection right
+ // Fix selection and cursor being off after shifting selection right.
if (is_selection_active()) {
select(selection.from_line, selection.from_column + selection_offset, selection.to_line, selection.to_column + selection_offset);
}
@@ -1747,10 +1747,9 @@ void TextEdit::indent_left() {
int start_line;
int end_line;
- // moving cursor and selection after unindenting can get tricky
- // because changing content of line can move cursor and selection on it's own (if new line ends before previous position of either)
- // therefore we just remember initial values
- // and at the end of the operation offset them by number of removed characters
+ // Moving cursor and selection after unindenting can get tricky because
+ // changing content of line can move cursor and selection on it's own (if new line ends before previous position of either),
+ // therefore we just remember initial values and at the end of the operation offset them by number of removed characters.
int removed_characters = 0;
int initial_selection_end_column = selection.to_column;
int initial_cursor_column = cursor.column;
@@ -1765,7 +1764,7 @@ void TextEdit::indent_left() {
end_line = start_line;
}
- // ignore if the cursor is not past the first column
+ // Ignore if the cursor is not past the first column.
if (is_selection_active() && get_selection_to_column() == 0) {
end_line--;
}
@@ -1779,12 +1778,12 @@ void TextEdit::indent_left() {
set_line(i, line_text);
removed_characters = 1;
} else if (line_text.begins_with(" ")) {
- // when unindenting we aim to remove spaces before line that has selection no matter what is selected
+ // When unindenting we aim to remove spaces before line that has selection no matter what is selected,
// so we start of by finding first non whitespace character of line
int left = _find_first_non_whitespace_column_of_line(line_text);
- // here we remove only enough spaces to align text to nearest full multiple of indentation_size
- // in case where selection begins at the start of indentation_size multiple we remove whole indentation level
+ // Here we remove only enough spaces to align text to nearest full multiple of indentation_size.
+ // In case where selection begins at the start of indentation_size multiple we remove whole indentation level.
int spaces_to_remove = _calculate_spaces_till_next_left_indent(left);
line_text = line_text.substr(spaces_to_remove, line_text.length());
@@ -1793,7 +1792,7 @@ void TextEdit::indent_left() {
}
}
- // fix selection and cursor being off by one on the last line
+ // Fix selection and cursor being off by one on the last line.
if (is_selection_active() && last_line_text != get_line(end_line)) {
select(selection.from_line, selection.from_column - removed_characters,
selection.to_line, initial_selection_end_column - removed_characters);
@@ -1834,7 +1833,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
}
if (row < 0)
- row = 0; //todo
+ row = 0; // TODO.
int col = 0;
@@ -1848,7 +1847,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
colx += cursor.x_ofs;
col = get_char_pos_for_line(colx, row, wrap_index);
if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) {
- // move back one if we are at the end of the row
+ // Move back one if we are at the end of the row.
Vector<String> rows2 = get_wrap_rows_text(row);
int row_end_col = 0;
for (int i = 0; i < wrap_index + 1; i++) {
@@ -1942,7 +1941,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- // toggle breakpoint on gutter click
+ // Toggle breakpoint on gutter click.
if (draw_breakpoint_gutter) {
int gutter = cache.style_normal->get_margin(MARGIN_LEFT);
if (mb->get_position().x > gutter - 6 && mb->get_position().x <= gutter + cache.breakpoint_gutter_width - 3) {
@@ -1952,7 +1951,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- // emit info clicked
+ // Emit info clicked.
if (draw_info_gutter && text.has_info_icon(row)) {
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
int gutter_left = left_margin + cache.breakpoint_gutter_width;
@@ -1962,7 +1961,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- // toggle fold on gutter click if can
+ // Toggle fold on gutter click if can.
if (draw_fold_gutter) {
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
@@ -1977,7 +1976,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- // unfold on folded icon click
+ // Unfold on folded icon click.
if (is_folded(row)) {
int line_width = text.get_line_width(row);
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.info_gutter_width + cache.fold_gutter_width - cursor.x_ofs;
@@ -2044,9 +2043,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
- //if sel active and dblick last time < something
-
- //else
selection.active = false;
selection.selecting_mode = Selection::MODE_POINTER;
selection.selecting_line = row;
@@ -2054,14 +2050,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
- //tripleclick select line
+
+ // Triple-click select line.
selection.selecting_mode = Selection::MODE_LINE;
_update_selection_mode_line();
last_dblclk = 0;
-
} else if (mb->is_doubleclick() && text[cursor.line].length()) {
- //doubleclick select word
+ // Double-click select word.
selection.selecting_mode = Selection::MODE_WORD;
_update_selection_mode_word();
last_dblclk = OS::get_singleton()->get_ticks_msec();
@@ -2086,7 +2082,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int to_column = 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.
deselect();
}
}
@@ -2107,7 +2103,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (mb->get_button_index() == BUTTON_LEFT)
click_select_held->stop();
- // notify to show soft keyboard
+ // Notify to show soft keyboard.
notification(NOTIFICATION_FOCUS_ENTER);
}
}
@@ -2123,7 +2119,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
h_scroll->set_value(h_scroll->get_value() + pan_gesture->get_delta().x * 100);
if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
- accept_event(); //accept event if scroll changed
+ accept_event(); // Accept event if scroll changed.
return;
}
@@ -2148,7 +2144,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { //ignore if dragging
+ if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { // Ignore if dragging.
_reset_caret_blink_timer();
switch (selection.selecting_mode) {
@@ -2169,13 +2165,13 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
- accept_event(); //accept event if scroll changed
+ accept_event(); // Accept event if scroll changed.
Ref<InputEventKey> k = p_gui_input;
if (k.is_valid()) {
- k = k->duplicate(); //it will be modified later on
+ k = k->duplicate(); // It will be modified later on.
#ifdef OSX_ENABLED
if (k->get_scancode() == KEY_META) {
@@ -2311,11 +2307,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_consume_pair_symbol(chr[0]);
} else {
- // remove the old character if in insert mode
+ // Remove the old character if in insert mode.
if (insert_mode) {
begin_complex_operation();
- // make sure we don't try and remove empty space
+ // Make sure we don't try and remove empty space.
if (cursor.column < get_line(cursor.line).length()) {
_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
@@ -2337,9 +2333,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_cancel_completion();
}
- /* TEST CONTROL FIRST!! */
+ /* TEST CONTROL FIRST! */
- // some remaps for duplicate functions..
+ // Some remaps for duplicate functions.
if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_scancode() == KEY_INSERT) {
k->set_scancode(KEY_C);
@@ -2383,10 +2379,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_reset_caret_blink_timer();
- // save here for insert mode, just in case it is cleared in the following section
+ // Save here for insert mode, just in case it is cleared in the following section.
bool had_selection = selection.active;
- // stuff to do when selection is active..
+ // Stuff to do when selection is active.
if (!readonly && selection.active) {
bool clear = false;
@@ -2406,7 +2402,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
case KEY_X:
case KEY_C:
- //special keys often used with control, wait...
+ // Special keys often used with control, wait.
clear = (!k->get_command() || k->get_shift() || k->get_alt());
break;
case KEY_DELETE:
@@ -2431,7 +2427,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
case KEY_PAGEDOWN:
case KEY_HOME:
case KEY_END:
- // ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys)
+ // Ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys).
if (k->get_command() || k->get_shift() || k->get_alt())
break;
unselect = true;
@@ -2469,7 +2465,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
bool scancode_handled = true;
- // special scancode test...
+ // Special scancode test.
switch (k->get_scancode()) {
@@ -2481,7 +2477,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
String ins = "\n";
- //keep indentation
+ // Keep indentation.
int space_count = 0;
for (int i = 0; i < cursor.column; i++) {
if (text[cursor.line][i] == '\t') {
@@ -2512,10 +2508,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
bool brace_indent = false;
- // no need to indent if we are going upwards.
+ // No need to indent if we are going upwards.
if (auto_indent && !(k->get_command() && k->get_shift())) {
- // indent once again if previous line will end with ':' or '{' and the line is not a comment
- // (i.e. colon/brace precedes current cursor position)
+ // Indent once again if previous line will end with ':' or '{' and the line is not a comment
+ // (i.e. colon/brace precedes current cursor position).
if (cursor.column > 0 && (text[cursor.line][cursor.column - 1] == ':' || text[cursor.line][cursor.column - 1] == '{') && !is_line_comment(cursor.line)) {
if (indent_using_spaces) {
ins += space_indent;
@@ -2523,7 +2519,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
ins += "\t";
}
- // no need to move the brace below if we are not taking the text with us.
+ // No need to move the brace below if we are not taking the text with us.
if (text[cursor.line][cursor.column] == '}' && !k->get_command()) {
brace_indent = true;
ins += "\n" + ins.substr(1, ins.length() - 2);
@@ -2565,7 +2561,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} break;
case KEY_TAB: {
- if (k->get_command()) break; // avoid tab when command
+ if (k->get_command()) break; // Avoid tab when command.
if (readonly)
break;
@@ -2579,7 +2575,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
if (k->get_shift()) {
- // simple unindent
+ // Simple unindent.
int cc = cursor.column;
const String &line = text[cursor.line];
@@ -2591,17 +2587,17 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (cc > 0 && cc <= text[cursor.line].length()) {
if (text[cursor.line][cc - 1] == '\t') {
- // tabs unindentation
+ // Tabs unindentation.
_remove_text(cursor.line, cc - 1, cursor.line, cc);
if (cursor.column >= left)
cursor_set_column(MAX(0, cursor.column - 1));
update();
} else {
- // spaces unindentation
+ // Spaces unindentation.
int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc);
if (spaces_to_remove > 0) {
_remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc);
- if (cursor.column > left - spaces_to_remove) // inside text?
+ if (cursor.column > left - spaces_to_remove) // Inside text?
cursor_set_column(MAX(0, cursor.column - spaces_to_remove));
update();
}
@@ -2611,9 +2607,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
} else {
- // simple indent
+ // Simple indent.
if (indent_using_spaces) {
- // insert only as much spaces as needed till next indentation level
+ // Insert only as much spaces as needed till next indentation level.
int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column);
String indent_to_insert = String();
for (int i = 0; i < spaces_to_add; i++)
@@ -2641,20 +2637,20 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int line = cursor.line;
int column = cursor.column;
- // check if we are removing a single whitespace, if so remove it and the next char type
- // else we just remove the whitespace
+ // Check if we are removing a single whitespace, if so remove it and the next char type,
+ // else we just remove the whitespace.
bool only_whitespace = false;
if (_is_whitespace(text[line][column - 1]) && _is_whitespace(text[line][column - 2])) {
only_whitespace = true;
} else if (_is_whitespace(text[line][column - 1])) {
- // remove the single whitespace
+ // Remove the single whitespace.
column--;
}
- // check if its a text char
+ // Check if its a text char.
bool only_char = (_is_text_char(text[line][column - 1]) && !only_whitespace);
- // if its not whitespace or char then symbol.
+ // If its not whitespace or char then symbol.
bool only_symbols = !(only_whitespace || only_char);
while (column > 0) {
@@ -2940,7 +2936,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int curline_len = text[cursor.line].length();
if (cursor.line == text.size() - 1 && cursor.column == curline_len)
- break; //nothing to do
+ break; // Nothing to do.
int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
int next_column;
@@ -2957,20 +2953,20 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int line = cursor.line;
int column = cursor.column;
- // check if we are removing a single whitespace, if so remove it and the next char type
- // else we just remove the whitespace
+ // Check if we are removing a single whitespace, if so remove it and the next char type,
+ // else we just remove the whitespace.
bool only_whitespace = false;
if (_is_whitespace(text[line][column]) && _is_whitespace(text[line][column + 1])) {
only_whitespace = true;
} else if (_is_whitespace(text[line][column])) {
- // remove the single whitespace
+ // Remove the single whitespace.
column++;
}
- // check if its a text char
+ // Check if its a text char.
bool only_char = (_is_text_char(text[line][column]) && !only_whitespace);
- // if its not whitespace or char then symbol.
+ // If its not whitespace or char then symbol.
bool only_symbols = !(only_whitespace || only_char);
while (column < curline_len) {
@@ -3029,7 +3025,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(0);
} else {
- // move cursor column to start of wrapped row and then to start of text
+ // Move cursor column to start of wrapped row and then to start of text.
Vector<String> rows = get_wrap_rows_text(cursor.line);
int wi = get_cursor_wrap_index();
int row_start_col = 0;
@@ -3037,7 +3033,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
row_start_col += rows[i].length();
}
if (cursor.column == row_start_col || wi == 0) {
- // compute whitespace symbols seq length
+ // Compute whitespace symbols seq length.
int current_line_whitespace_len = 0;
while (current_line_whitespace_len < text[cursor.line].length()) {
CharType c = text[cursor.line][current_line_whitespace_len];
@@ -3088,7 +3084,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (k->get_command())
cursor_set_line(get_last_unhidden_line(), true, false, 9999);
- // move cursor column to end of wrapped row and then to end of text
+ // Move cursor column to end of wrapped row and then to end of text.
Vector<String> rows = get_wrap_rows_text(cursor.line);
int wi = get_cursor_wrap_index();
int row_end_col = -1;
@@ -3274,7 +3270,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
case KEY_SPACE: {
#ifdef OSX_ENABLED
- if (completion_enabled && k->get_metakey()) { //cmd-space is spotlight shortcut in OSX
+ if (completion_enabled && k->get_metakey()) { // cmd-space is spotlight shortcut in OSX
#else
if (completion_enabled && k->get_command()) {
#endif
@@ -3302,18 +3298,18 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- if (!scancode_handled && !k->get_command()) { //for German kbds
+ if (!scancode_handled && !k->get_command()) { // For German keyboards.
if (k->get_unicode() >= 32) {
if (readonly)
return;
- // remove the old character if in insert mode and no selection
+ // Remove the old character if in insert mode and no selection.
if (insert_mode && !had_selection) {
begin_complex_operation();
- // make sure we don't try and remove empty space
+ // Make sure we don't try and remove empty space.
if (cursor.column < get_line(cursor.line).length()) {
_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
@@ -3424,10 +3420,10 @@ void TextEdit::_post_shift_selection() {
void TextEdit::_scroll_lines_up() {
scrolling = false;
- // adjust the vertical scroll
+ // Adjust the vertical scroll.
set_v_scroll(get_v_scroll() - 1);
- // adjust the cursor to viewport
+ // Adjust the cursor to viewport.
if (!selection.active) {
int cur_line = cursor.line;
int cur_wrap = get_cursor_wrap_index();
@@ -3443,10 +3439,10 @@ void TextEdit::_scroll_lines_up() {
void TextEdit::_scroll_lines_down() {
scrolling = false;
- // adjust the vertical scroll
+ // Adjust the vertical scroll.
set_v_scroll(get_v_scroll() + 1);
- // adjust the cursor to viewport
+ // Adjust the cursor to viewport.
if (!selection.active) {
int cur_line = cursor.line;
int cur_wrap = get_cursor_wrap_index();
@@ -3463,15 +3459,15 @@ void TextEdit::_scroll_lines_down() {
void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, int &r_end_line, int &r_end_column) {
- //save for undo...
+ // Save for undo.
ERR_FAIL_INDEX(p_line, text.size());
ERR_FAIL_COND(p_char < 0);
- /* STEP 1 remove \r from source text and separate in substrings */
+ /* STEP 1: Remove \r from source text and separate in substrings. */
Vector<String> substrings = p_text.replace("\r", "").split("\n");
- /* STEP 2 fire breakpoint_toggled signals */
+ /* STEP 2: Fire breakpoint_toggled signals. */
// Is this just a new empty line?
bool shift_first_line = p_char == 0 && p_text.replace("\r", "") == "\n";
@@ -3487,19 +3483,19 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
}
}
- /* STEP 3 add spaces if the char is greater than the end of the line */
+ /* STEP 3: Add spaces if the char is greater than the end of the line. */
while (p_char > text[p_line].length()) {
text.set(p_line, text[p_line] + String::chr(' '));
}
- /* STEP 4 separate dest string in pre and post text */
+ /* STEP 4: Separate dest string in pre and post text. */
String preinsert_text = text[p_line].substr(0, p_char);
String postinsert_text = text[p_line].substr(p_char, text[p_line].size());
for (int j = 0; j < substrings.size(); j++) {
- //insert the substrings
+ // Insert the substrings.
if (j == 0) {
@@ -3544,8 +3540,8 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin
ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, String());
ERR_FAIL_INDEX_V(p_to_line, text.size(), String());
ERR_FAIL_INDEX_V(p_to_column, text[p_to_line].length() + 1, String());
- ERR_FAIL_COND_V(p_to_line < p_from_line, String()); // from > to
- ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column < p_from_column, String()); // from > to
+ ERR_FAIL_COND_V(p_to_line < p_from_line, String()); // 'from > to'.
+ ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column < p_from_column, String()); // 'from > to'.
String ret;
@@ -3568,8 +3564,8 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
ERR_FAIL_INDEX(p_from_column, text[p_from_line].length() + 1);
ERR_FAIL_INDEX(p_to_line, text.size());
ERR_FAIL_INDEX(p_to_column, text[p_to_line].length() + 1);
- ERR_FAIL_COND(p_to_line < p_from_line); // from > to
- ERR_FAIL_COND(p_to_line == p_from_line && p_to_column < p_from_column); // from > to
+ ERR_FAIL_COND(p_to_line < p_from_line); // 'from > to'.
+ ERR_FAIL_COND(p_to_line == p_from_line && p_to_column < p_from_column); // 'from > to'.
String pre_text = text[p_from_line].substr(0, p_from_column);
String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length());
@@ -3631,22 +3627,22 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r
op.chain_forward = false;
op.chain_backward = false;
- //see if it should just be set as current op
+ // See if it should just be set as current op.
if (current_op.type != op.type) {
op.prev_version = get_version();
_push_current_op();
current_op = op;
- return; //set as current op, return
+ return; // Set as current op, return.
}
- //see if it can be merged
+ // See if it can be merged.
if (current_op.to_line != p_line || current_op.to_column != p_char) {
op.prev_version = get_version();
_push_current_op();
current_op = op;
- return; //set as current op, return
+ return; // Set as current op, return.
}
- //merge current op
+ // Merge current op.
current_op.text += p_text;
current_op.to_column = retchar;
@@ -3670,7 +3666,7 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
if (!undo_enabled)
return;
- /* UNDO!! */
+ /* UNDO! */
TextOperation op;
op.type = TextOperation::TYPE_REMOVE;
op.from_line = p_from_line;
@@ -3682,27 +3678,20 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
op.chain_forward = false;
op.chain_backward = false;
- //see if it should just be set as current op
+ // See if it should just be set as current op.
if (current_op.type != op.type) {
op.prev_version = get_version();
_push_current_op();
current_op = op;
- return; //set as current op, return
+ return; // Set as current op, return.
}
- //see if it can be merged
+ // See if it can be merged.
if (current_op.from_line == p_to_line && current_op.from_column == p_to_column) {
- //basckace or similar
+ // Backspace or similar.
current_op.text = text + current_op.text;
current_op.from_line = p_from_line;
current_op.from_column = p_from_column;
- return; //update current op
- }
- if (current_op.from_line == p_from_line && current_op.from_column == p_from_column) {
-
- //current_op.text=text+current_op.text;
- //current_op.from_line=p_from_line;
- //current_op.from_column=p_from_column;
- //return; //update current op
+ return; // Update current op.
}
op.prev_version = get_version();
@@ -3734,11 +3723,11 @@ int TextEdit::get_char_count() {
for (int i = 0; i < text.size(); i++) {
if (i > 0)
- totalsize++; // incliude \n
+ totalsize++; // Include \n.
totalsize += text[i].length();
}
- return totalsize; // omit last \n
+ return totalsize; // Omit last \n.
}
Size2 TextEdit::get_minimum_size() const {
@@ -3758,7 +3747,7 @@ int TextEdit::get_visible_rows() const {
int TextEdit::get_total_visible_rows() const {
- // returns the total amount of rows we need in the editor.
+ // Returns the total amount of rows we need in the editor.
// This skips hidden lines and counts each wrapping of a line.
if (!is_hiding_enabled() && !is_wrap_enabled())
return text.size();
@@ -3780,7 +3769,7 @@ void TextEdit::_update_wrap_at() {
text.clear_wrap_cache();
for (int i = 0; i < text.size(); i++) {
- // update all values that wrap
+ // Update all values that wrap.
if (!line_wraps(i))
continue;
Vector<String> rows = get_wrap_rows_text(i);
@@ -3790,7 +3779,7 @@ void TextEdit::_update_wrap_at() {
void TextEdit::adjust_viewport_to_cursor() {
- // make sure cursor is visible on the screen
+ // Make sure cursor is visible on the screen.
scrolling = false;
int cur_line = cursor.line;
@@ -3802,20 +3791,20 @@ void TextEdit::adjust_viewport_to_cursor() {
int last_vis_wrap = get_last_visible_line_wrap_index();
if (cur_line < first_vis_line || (cur_line == first_vis_line && cur_wrap < first_vis_wrap)) {
- // cursor is above screen
+ // Cursor is above screen.
set_line_as_first_visible(cur_line, cur_wrap);
} else if (cur_line > last_vis_line || (cur_line == last_vis_line && cur_wrap > last_vis_wrap)) {
- // cursor is below screen
+ // Cursor is below screen.
set_line_as_last_visible(cur_line, cur_wrap);
}
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width;
if (v_scroll->is_visible_in_tree())
visible_width -= v_scroll->get_combined_minimum_size().width;
- visible_width -= 20; // give it a little more space
+ visible_width -= 20; // Give it a little more space.
if (!is_wrap_enabled()) {
- // adjust x offset
+ // Adjust x offset.
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
if (cursor_x > (cursor.x_ofs + visible_width))
@@ -3833,7 +3822,7 @@ void TextEdit::adjust_viewport_to_cursor() {
void TextEdit::center_viewport_to_cursor() {
- // move viewport so the cursor is in the center of the screen
+ // Move viewport so the cursor is in the center of the screen.
scrolling = false;
if (is_line_hidden(cursor.line))
@@ -3843,10 +3832,10 @@ void TextEdit::center_viewport_to_cursor() {
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width;
if (v_scroll->is_visible_in_tree())
visible_width -= v_scroll->get_combined_minimum_size().width;
- visible_width -= 20; // give it a little more space
+ visible_width -= 20; // Give it a little more space.
if (is_wrap_enabled()) {
- // center x offset
+ // Center x offset.
int cursor_x = get_column_x_offset_for_line(cursor.column, cursor.line);
if (cursor_x > (cursor.x_ofs + visible_width))
@@ -3888,7 +3877,7 @@ int TextEdit::times_line_wraps(int line) const {
int wrap_amount = text.get_line_wrap_amount(line);
if (wrap_amount == -1) {
- // update the value
+ // Update the value.
Vector<String> rows = get_wrap_rows_text(line);
wrap_amount = rows.size() - 1;
text.set_line_wrap_amount(line, wrap_amount);
@@ -3928,7 +3917,7 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
int indent_ofs = (cur_wrap_index != 0 ? tab_offset_px : 0);
if (indent_ofs + word_px + w > wrap_at) {
- // not enough space to add this char; start next line
+ // Not enough space to add this char; start next line.
wrap_substring += word_str;
lines.push_back(wrap_substring);
cur_wrap_index++;
@@ -3942,7 +3931,7 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
word_str += c;
word_px += w;
if (c == ' ') {
- // end of a word; add this word to the substring
+ // End of a word; add this word to the substring.
wrap_substring += word_str;
px += word_px;
word_str = "";
@@ -3950,9 +3939,9 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
if (indent_ofs + px + word_px > wrap_at) {
- // this word will be moved to the next line
+ // This word will be moved to the next line.
lines.push_back(wrap_substring);
- // reset for next wrap
+ // Reset for next wrap.
cur_wrap_index++;
wrap_substring = "";
px = 0;
@@ -3960,11 +3949,11 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
col++;
}
- // line ends before hit wrap_at; add this word to the substring
+ // Line ends before hit wrap_at; add this word to the substring.
wrap_substring += word_str;
lines.push_back(wrap_substring);
- // update cache
+ // Update cache.
text.set_line_wrap_amount(p_line, lines.size() - 1);
return lines;
@@ -3982,7 +3971,7 @@ int TextEdit::get_line_wrap_index_at_col(int p_line, int p_column) const {
if (!line_wraps(p_line))
return 0;
- // loop through wraps in the line text until we get to the column
+ // Loop through wraps in the line text until we get to the column.
int wrap_index = 0;
int col = 0;
Vector<String> rows = get_wrap_rows_text(p_line);
@@ -4134,7 +4123,7 @@ void TextEdit::_scroll_moved(double p_to_val) {
cursor.x_ofs = h_scroll->get_value();
if (v_scroll->is_visible_in_tree()) {
- // set line ofs and wrap ofs
+ // Set line ofs and wrap ofs.
int v_scroll_i = floor(get_v_scroll());
int sc = 0;
int n_line;
@@ -4289,12 +4278,12 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
_get_mouse_pos(p_pos, row, col);
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
- // breakpoint icon
+ // Breakpoint icon.
if (draw_breakpoint_gutter && p_pos.x > left_margin - 6 && p_pos.x <= left_margin + cache.breakpoint_gutter_width - 3) {
return CURSOR_POINTING_HAND;
}
- // info icons
+ // Info icons.
int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.info_gutter_width;
if (draw_info_gutter && p_pos.x > left_margin + cache.breakpoint_gutter_width - 6 && p_pos.x <= gutter_left - 3) {
if (text.has_info_icon(row)) {
@@ -4303,7 +4292,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_ARROW;
}
- // fold icon
+ // Fold icon.
if (draw_fold_gutter && p_pos.x > gutter_left + cache.line_number_w - 6 && p_pos.x <= gutter_left + cache.line_number_w + cache.fold_gutter_width - 3) {
if (is_folded(row) || can_fold(row))
return CURSOR_POINTING_HAND;
@@ -4315,7 +4304,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
} else {
int row, col;
_get_mouse_pos(p_pos, row, col);
- // eol fold icon
+ // EOL fold icon.
if (is_folded(row)) {
int line_width = text.get_line_width(row);
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
@@ -4349,8 +4338,6 @@ void TextEdit::set_text(String p_text) {
update();
setting_text = false;
-
- //get_range()->set(0);
};
String TextEdit::get_text() {
@@ -4377,7 +4364,7 @@ String TextEdit::get_text_for_lookup_completion() {
if (i == row) {
longthing += text[i].substr(0, col);
- longthing += String::chr(0xFFFF); //not unicode, represents the cursor
+ longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += text[i].substr(col, text[i].size());
} else {
@@ -4399,7 +4386,7 @@ String TextEdit::get_text_for_completion() {
if (i == cursor.line) {
longthing += text[i].substr(0, cursor.column);
- longthing += String::chr(0xFFFF); //not unicode, represents the cursor
+ longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += text[i].substr(cursor.column, text[i].size());
} else {
@@ -4587,12 +4574,12 @@ void TextEdit::_set_syntax_highlighting(SyntaxHighlighter *p_syntax_highlighter)
int TextEdit::_is_line_in_region(int p_line) {
- // do we have in cache?
+ // Do we have in cache?
if (color_region_cache.has(p_line)) {
return color_region_cache[p_line];
}
- // if not find the closest line we have
+ // If not find the closest line we have.
int previous_line = p_line - 1;
for (; previous_line > -1; previous_line--) {
if (color_region_cache.has(p_line)) {
@@ -4600,7 +4587,7 @@ int TextEdit::_is_line_in_region(int p_line) {
}
}
- // calculate up to line we need and update the cache along the way.
+ // Calculate up to line we need and update the cache along the way.
int in_region = color_region_cache[previous_line];
if (previous_line == -1) {
in_region = -1;
@@ -4728,7 +4715,7 @@ void TextEdit::cut() {
OS::get_singleton()->set_clipboard(clipboard);
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- cursor_set_line(selection.from_line); // set afterwards else it causes the view to be offset
+ cursor_set_line(selection.from_line); // Set afterwards else it causes the view to be offset.
cursor_set_column(selection.from_column);
selection.active = false;
@@ -4957,7 +4944,7 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
col = p_search.findn(p_key, p_from_column);
}
- // whole words only
+ // Whole words only.
if (col != -1 && p_search_flags & SEARCH_WHOLE_WORDS) {
p_from_column = col;
@@ -4997,14 +4984,12 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
ERR_FAIL_INDEX_V(p_from_line, text.size(), false);
ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, false);
- //search through the whole document, but start by current line
+ // Search through the whole document, but start by current line.
int line = p_from_line;
int pos = -1;
for (int i = 0; i < text.size() + 1; i++) {
- //backwards is broken...
- //int idx=(p_search_flags&SEARCH_BACKWARDS)?(text.size()-i):i; //do backwards seearch
if (line < 0) {
line = text.size() - 1;
@@ -5018,7 +5003,7 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
if (line == p_from_line) {
if (i == text.size()) {
- //wrapped
+ // Wrapped.
if (p_search_flags & SEARCH_BACKWARDS) {
from_column = text_line.length();
@@ -5066,7 +5051,7 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
bool is_match = true;
if (pos != -1 && (p_search_flags & SEARCH_WHOLE_WORDS)) {
- //validate for whole words
+ // Validate for whole words.
if (pos > 0 && _is_text_char(text_line[pos - 1]))
is_match = false;
else if (pos + p_key.length() < text_line.length() && _is_text_char(text_line[pos + p_key.length()]))
@@ -5264,7 +5249,7 @@ void TextEdit::unhide_all_lines() {
int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
- // returns the number of lines (hidden and unhidden) from p_line_from to (p_line_from + visible_amount of unhidden lines)
+ // Returns the number of lines (hidden and unhidden) from p_line_from to (p_line_from + visible_amount of unhidden lines).
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(visible_amount));
if (!is_hiding_enabled())
@@ -5297,8 +5282,8 @@ int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int visible_amount, int &wrap_index) const {
- // returns the number of lines (hidden and unhidden) from (p_line_from + p_wrap_index_from) row to (p_line_from + visible_amount of unhidden and wrapped rows)
- // wrap index is set to the wrap index of the last line
+ // Returns the number of lines (hidden and unhidden) from (p_line_from + p_wrap_index_from) row to (p_line_from + visible_amount of unhidden and wrapped rows).
+ // Wrap index is set to the wrap index of the last line.
wrap_index = 0;
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(visible_amount));
@@ -5344,7 +5329,7 @@ int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int vi
int TextEdit::get_last_unhidden_line() const {
- // returns the last line in the text that is not hidden
+ // Returns the last line in the text that is not hidden.
if (!is_hiding_enabled())
return text.size() - 1;
@@ -5361,7 +5346,7 @@ int TextEdit::get_indent_level(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
- // counts number of tabs and spaces before line starts
+ // Counts number of tabs and spaces before line starts.
int tab_count = 0;
int whitespace_count = 0;
int line_length = text[p_line].size();
@@ -5379,7 +5364,7 @@ int TextEdit::get_indent_level(int p_line) const {
bool TextEdit::is_line_comment(int p_line) const {
- // checks to see if this line is the start of a comment
+ // Checks to see if this line is the start of a comment.
ERR_FAIL_INDEX_V(p_line, text.size(), false);
const Map<int, Text::ColorRegionInfo> &cri_map = text.get_color_region_info(p_line);
@@ -5459,7 +5444,7 @@ void TextEdit::fold_line(int p_line) {
if (!can_fold(p_line))
return;
- // hide lines below this one
+ // Hide lines below this one.
int start_indent = get_indent_level(p_line);
int last_line = start_indent;
for (int i = p_line + 1; i < text.size(); i++) {
@@ -5477,7 +5462,7 @@ void TextEdit::fold_line(int p_line) {
set_line_as_hidden(i, true);
}
- // fix selection
+ // Fix selection.
if (is_selection_active()) {
if (is_line_hidden(selection.from_line) && is_line_hidden(selection.to_line)) {
deselect();
@@ -5488,7 +5473,7 @@ void TextEdit::fold_line(int p_line) {
}
}
- // reset cursor
+ // Reset cursor.
if (is_line_hidden(cursor.line)) {
cursor_set_line(p_line, false, false);
cursor_set_column(get_line(p_line).length(), false);
@@ -5549,8 +5534,8 @@ void TextEdit::_do_text_op(const TextOperation &p_op, bool p_reverse) {
int check_line;
int check_column;
_base_insert_text(p_op.from_line, p_op.from_column, p_op.text, check_line, check_column);
- ERR_FAIL_COND(check_line != p_op.to_line); // BUG
- ERR_FAIL_COND(check_column != p_op.to_column); // BUG
+ ERR_FAIL_COND(check_line != p_op.to_line); // BUG.
+ ERR_FAIL_COND(check_column != p_op.to_column); // BUG.
} else {
_base_remove_text(p_op.from_line, p_op.from_column, p_op.to_line, p_op.to_column);
@@ -5560,7 +5545,7 @@ void TextEdit::_do_text_op(const TextOperation &p_op, bool p_reverse) {
void TextEdit::_clear_redo() {
if (undo_stack_pos == NULL)
- return; //nothing to clear
+ return; // Nothing to clear.
_push_current_op();
@@ -5578,12 +5563,12 @@ void TextEdit::undo() {
if (undo_stack_pos == NULL) {
if (!undo_stack.size())
- return; //nothing to undo
+ return; // Nothing to undo.
undo_stack_pos = undo_stack.back();
} else if (undo_stack_pos == undo_stack.front())
- return; // at the bottom of the undo stack
+ return; // At the bottom of the undo stack.
else
undo_stack_pos = undo_stack_pos->prev();
@@ -5624,7 +5609,7 @@ void TextEdit::redo() {
_push_current_op();
if (undo_stack_pos == NULL)
- return; //nothing to do.
+ return; // Nothing to do.
deselect();
@@ -5678,7 +5663,7 @@ void TextEdit::end_complex_operation() {
void TextEdit::_push_current_op() {
if (current_op.type == TextOperation::TYPE_NONE)
- return; // do nothing
+ return; // Nothing to do.
if (next_operation_is_complex) {
current_op.chain_forward = true;
@@ -5778,7 +5763,7 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
if (!is_wrap_enabled() && !is_hiding_enabled())
return p_line;
- // count the number of visible lines up to this line
+ // Count the number of visible lines up to this line.
double new_line_scroll_pos = 0;
int to = CLAMP(p_line, 0, text.size() - 1);
for (int i = 0; i < to; i++) {
@@ -5979,7 +5964,7 @@ void TextEdit::_update_completion_candidates() {
String s;
- //look for keywords first
+ // Look for keywords first.
bool inquote = false;
int first_quote = -1;
@@ -6004,7 +5989,7 @@ void TextEdit::_update_completion_candidates() {
bool cancel = false;
if (!inquote && first_quote == cofs - 1) {
- //no completion here
+ // No completion here.
cancel = true;
} else if (inquote && first_quote != -1) {
@@ -6042,11 +6027,12 @@ void TextEdit::_update_completion_candidates() {
bool prev_is_prefix = false;
if (cofs > 0 && completion_prefixes.has(String::chr(l[cofs - 1])))
prev_is_prefix = true;
- if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2]))) //check with one space before prefix, to allow indent
+ // Check with one space before prefix, to allow indent.
+ if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2])))
prev_is_prefix = true;
if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !prev_is_prefix))) {
- //none to complete, cancel
+ // None to complete, cancel.
_cancel_completion();
return;
}
@@ -6096,18 +6082,18 @@ void TextEdit::_update_completion_candidates() {
}
if (completion_options.size() == 0) {
- //no options to complete, cancel
+ // No options to complete, cancel.
_cancel_completion();
return;
}
if (completion_options.size() == 1 && s == completion_options[0].display) {
- // A perfect match, stop completion
+ // A perfect match, stop completion.
_cancel_completion();
return;
}
- // The top of the list is the best match
+ // The top of the list is the best match.
completion_current = completion_options[0];
completion_enabled = true;
}
@@ -6128,7 +6114,7 @@ void TextEdit::query_code_comple() {
if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1]))))
emit_signal("request_completion");
- else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) //make it work with a space too, it's good enough
+ else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) // Make it work with a space too, it's good enough.
emit_signal("request_completion");
}
@@ -6453,8 +6439,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_wrap_enabled", "enable"), &TextEdit::set_wrap_enabled);
ClassDB::bind_method(D_METHOD("is_wrap_enabled"), &TextEdit::is_wrap_enabled);
- // ClassDB::bind_method(D_METHOD("set_max_chars", "amount"), &TextEdit::set_max_chars);
- // ClassDB::bind_method(D_METHOD("get_max_char"), &TextEdit::get_max_chars);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &TextEdit::set_context_menu_enabled);
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &TextEdit::is_context_menu_enabled);
@@ -6546,7 +6530,6 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_enabled"), "set_wrap_enabled", "is_wrap_enabled");
- // ADD_PROPERTY(PropertyInfo(Variant::BOOL, "max_chars"), "set_max_chars", "get_max_chars");
ADD_GROUP("Caret", "caret_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode");
@@ -6571,7 +6554,7 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(MENU_MAX);
GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::REAL, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::REAL, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers.
}
TextEdit::TextEdit() {
@@ -6690,7 +6673,7 @@ TextEdit::TextEdit() {
context_menu_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
- readonly = true; // initialise to opposite first, so we get past the early-out in set_readonly
+ readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly.
set_readonly(false);
menu->connect("id_pressed", this, "menu_option");
first_draw = true;
@@ -6751,14 +6734,14 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
bool is_symbol = _is_symbol(str[j]);
bool is_number = _is_number(str[j]);
- // allow ABCDEF in hex notation
+ // Allow ABCDEF in hex notation.
if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) {
is_number = true;
} else {
is_hex_notation = false;
}
- // check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation
+ // Check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation.
if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
is_number = true;
is_symbol = false;
@@ -6788,7 +6771,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
if (!cri.end) {
in_region = cri.region;
}
- } else if (in_region == cri.region && !color_regions[cri.region].line_only) { //ignore otherwise
+ } else if (in_region == cri.region && !color_regions[cri.region].line_only) { // Ignore otherwise.
if (cri.end || color_regions[cri.region].eq) {
deregion = color_regions[cri.region].eq ? color_regions[cri.region].begin_key.length() : color_regions[cri.region].end_key.length();
}
@@ -6816,7 +6799,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
if (col) {
for (int k = j - 1; k >= 0; k--) {
if (str[k] == '.') {
- col = NULL; //member indexing not allowed
+ col = NULL; // Member indexing not allowed.
break;
} else if (str[k] > 32) {
break;
@@ -6838,7 +6821,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
k++;
}
- // check for space between name and bracket
+ // Check for space between name and bracket.
while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
k++;
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 6c858e9d9a..53bdb4145f 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -530,6 +530,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeSwitch>();
ClassDB::register_class<VisualShaderNodeFresnel>();
ClassDB::register_class<VisualShaderNodeExpression>();
+ ClassDB::register_class<VisualShaderNodeGlobalExpression>();
ClassDB::register_class<VisualShaderNodeIs>();
ClassDB::register_class<VisualShaderNodeCompare>();
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 8c8552ac54..985b38f913 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2870,9 +2870,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
const Vector3 &v1 = t1.value.loc;
const Vector3 &v2 = t2.value.loc;
- if (Math::is_zero_approx(v0.distance_to(v2))) {
+ if (v0 == v2) {
//0 and 2 are close, let's see if 1 is close
- if (!Math::is_zero_approx(v0.distance_to(v1))) {
+ if (v0 != v1) {
//not close, not optimizable
return false;
}
@@ -2959,9 +2959,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
const Vector3 &v1 = t1.value.scale;
const Vector3 &v2 = t2.value.scale;
- if (Math::is_zero_approx(v0.distance_to(v2))) {
+ if (v0 == v2) {
//0 and 2 are close, let's see if 1 is close
- if (!Math::is_zero_approx(v0.distance_to(v1))) {
+ if (v0 != v1) {
//not close, not optimizable
return false;
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index fb0fb4f8e3..90787780d3 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -760,6 +760,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// FileDialog
theme->set_icon("folder", "FileDialog", make_icon(icon_folder_png));
+ theme->set_color("folder", "FileDialog", Color(1, 1, 1));
theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7));
// colorPicker
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 389011c095..08ce47692c 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -612,6 +612,25 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
global_code += String() + "shader_type canvas_item;\n";
+ String global_expressions;
+ for (int i = 0, index = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
+ if (global_expression.is_valid()) {
+
+ String expr = "";
+ expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
+ expr += global_expression->generate_global(get_mode(), Type(i), -1);
+ expr = expr.replace("\n", "\n\t");
+ expr += "\n";
+ global_expressions += expr;
+ }
+ }
+ }
+
+ global_code += "\n";
+ global_code += global_expressions;
+
//make it faster to go around through shader
VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
@@ -1205,6 +1224,22 @@ void VisualShader::_update_shader() const {
static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" };
+ String global_expressions;
+ for (int i = 0, index = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
+ if (global_expression.is_valid()) {
+
+ String expr = "";
+ expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
+ expr += global_expression->generate_global(get_mode(), Type(i), -1);
+ expr = expr.replace("\n", "\n\t");
+ expr += "\n";
+ global_expressions += expr;
+ }
+ }
+ }
+
for (int i = 0; i < TYPE_MAX; i++) {
//make it faster to go around through shader
@@ -1239,6 +1274,7 @@ void VisualShader::_update_shader() const {
global_code += "\n\n";
String final_code = global_code;
final_code += global_code_per_node;
+ final_code += global_expressions;
String tcode = code;
for (int i = 0; i < TYPE_MAX; i++) {
tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]);
@@ -1249,6 +1285,10 @@ void VisualShader::_update_shader() const {
for (int i = 0; i < default_tex_params.size(); i++) {
const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param);
}
+ if (previous_code != final_code) {
+ const_cast<VisualShader *>(this)->emit_signal("changed");
+ }
+ previous_code = final_code;
}
void VisualShader::_queue_update() {
@@ -2333,6 +2373,14 @@ void VisualShaderNodeGroupBase::_apply_port_changes() {
}
}
+void VisualShaderNodeGroupBase::set_editable(bool p_enabled) {
+ editable = p_enabled;
+}
+
+bool VisualShaderNodeGroupBase::is_editable() const {
+ return editable;
+}
+
void VisualShaderNodeGroupBase::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeGroupBase::set_size);
@@ -2368,6 +2416,9 @@ void VisualShaderNodeGroupBase::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_control", "control", "index"), &VisualShaderNodeGroupBase::set_control);
ClassDB::bind_method(D_METHOD("get_control", "index"), &VisualShaderNodeGroupBase::get_control);
+
+ ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &VisualShaderNodeGroupBase::set_editable);
+ ClassDB::bind_method(D_METHOD("is_editable"), &VisualShaderNodeGroupBase::is_editable);
}
String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -2378,6 +2429,7 @@ VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() {
size = Size2(0, 0);
inputs = "";
outputs = "";
+ editable = false;
}
////////////// Expression
@@ -2504,4 +2556,19 @@ void VisualShaderNodeExpression::_bind_methods() {
VisualShaderNodeExpression::VisualShaderNodeExpression() {
expression = "";
+ set_editable(true);
+}
+
+////////////// Global Expression
+
+String VisualShaderNodeGlobalExpression::get_caption() const {
+ return "GlobalExpression";
+}
+
+String VisualShaderNodeGlobalExpression::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return expression;
+}
+
+VisualShaderNodeGlobalExpression::VisualShaderNodeGlobalExpression() {
+ set_editable(false);
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index a89e3295fc..45beb8e6ca 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -73,6 +73,7 @@ private:
} graph[TYPE_MAX];
Shader::Mode shader_mode;
+ mutable String previous_code;
Array _get_node_connections(Type p_type) const;
@@ -371,6 +372,7 @@ protected:
Vector2 size;
String inputs;
String outputs;
+ bool editable;
struct Port {
PortType type;
@@ -426,6 +428,9 @@ public:
void set_control(Control *p_control, int p_index);
Control *get_control(int p_index);
+ void set_editable(bool p_enabled);
+ bool is_editable() const;
+
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
VisualShaderNodeGroupBase();
@@ -434,10 +439,9 @@ public:
class VisualShaderNodeExpression : public VisualShaderNodeGroupBase {
GDCLASS(VisualShaderNodeExpression, VisualShaderNodeGroupBase);
-private:
+protected:
String expression;
-protected:
static void _bind_methods();
public:
@@ -453,4 +457,15 @@ public:
VisualShaderNodeExpression();
};
+class VisualShaderNodeGlobalExpression : public VisualShaderNodeExpression {
+ GDCLASS(VisualShaderNodeGlobalExpression, VisualShaderNodeExpression);
+
+public:
+ virtual String get_caption() const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+
+ VisualShaderNodeGlobalExpression();
+};
+
#endif // VISUAL_SHADER_H