summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/Animation.xml108
-rw-r--r--doc/classes/Node.xml11
-rw-r--r--doc/classes/RichTextLabel.xml7
-rw-r--r--doc/classes/TextEdit.xml2
-rw-r--r--editor/animation_track_editor_plugins.cpp36
-rw-r--r--editor/animation_track_editor_plugins.h4
-rw-r--r--editor/editor_help.cpp5
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--editor/icons/icon_crypto_key.svg1
-rw-r--r--editor/icons/icon_x509_certificate.svg1
-rw-r--r--editor/node_dock.cpp1
-rw-r--r--modules/gdscript/gdscript_editor.cpp9
-rw-r--r--modules/gdscript/gdscript_parser.cpp22
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp10
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp16
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java34
-rw-r--r--platform/osx/dir_access_osx.mm15
-rw-r--r--platform/windows/detect.py34
-rw-r--r--scene/2d/cpu_particles_2d.cpp141
-rw-r--r--scene/2d/cpu_particles_2d.h1
-rw-r--r--scene/2d/joints_2d.cpp6
-rw-r--r--scene/2d/touch_screen_button.cpp8
-rw-r--r--scene/3d/cpu_particles.cpp168
-rw-r--r--scene/3d/cpu_particles.h1
-rw-r--r--scene/gui/control.cpp6
-rw-r--r--scene/gui/label.cpp5
-rw-r--r--scene/gui/rich_text_label.cpp67
-rw-r--r--scene/gui/rich_text_label.h3
-rw-r--r--scene/gui/text_edit.cpp39
-rw-r--r--scene/main/node.cpp2
-rw-r--r--scene/main/scene_tree.cpp17
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/viewport.cpp1
-rw-r--r--scene/resources/animation.cpp108
34 files changed, 574 insertions, 319 deletions
diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml
index bc64cfbb19..97da8c9980 100644
--- a/doc/classes/Animation.xml
+++ b/doc/classes/Animation.xml
@@ -34,7 +34,7 @@
<method name="animation_track_get_key_animation" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -44,7 +44,7 @@
<method name="animation_track_insert_key">
<return type="int">
</return>
- <argument index="0" name="track" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -56,7 +56,7 @@
<method name="animation_track_set_key_animation">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -68,7 +68,7 @@
<method name="audio_track_get_key_end_offset" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -78,7 +78,7 @@
<method name="audio_track_get_key_start_offset" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -88,7 +88,7 @@
<method name="audio_track_get_key_stream" qualifiers="const">
<return type="Resource">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -98,7 +98,7 @@
<method name="audio_track_insert_key">
<return type="int">
</return>
- <argument index="0" name="track" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -114,7 +114,7 @@
<method name="audio_track_set_key_end_offset">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -126,7 +126,7 @@
<method name="audio_track_set_key_start_offset">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -138,7 +138,7 @@
<method name="audio_track_set_key_stream">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -150,7 +150,7 @@
<method name="bezier_track_get_key_in_handle" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -160,7 +160,7 @@
<method name="bezier_track_get_key_out_handle" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -170,7 +170,7 @@
<method name="bezier_track_get_key_value" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -180,7 +180,7 @@
<method name="bezier_track_insert_key">
<return type="int">
</return>
- <argument index="0" name="track" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -196,7 +196,7 @@
<method name="bezier_track_interpolate" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="track" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -206,7 +206,7 @@
<method name="bezier_track_set_key_in_handle">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -218,7 +218,7 @@
<method name="bezier_track_set_key_out_handle">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -230,7 +230,7 @@
<method name="bezier_track_set_key_value">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -249,7 +249,7 @@
<method name="copy_track">
<return type="void">
</return>
- <argument index="0" name="track" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="to_animation" type="Animation">
</argument>
@@ -276,7 +276,7 @@
<method name="method_track_get_key_indices" qualifiers="const">
<return type="PoolIntArray">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time_sec" type="float">
</argument>
@@ -289,7 +289,7 @@
<method name="method_track_get_name" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -300,7 +300,7 @@
<method name="method_track_get_params" qualifiers="const">
<return type="Array">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -311,7 +311,7 @@
<method name="remove_track">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Removes a track by specifying the track index.
@@ -320,7 +320,7 @@
<method name="track_find_key" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -333,7 +333,7 @@
<method name="track_get_interpolation_loop_wrap" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Returns [code]true[/code] if the track at [code]idx[/code] wraps the interpolation loop. New tracks wrap the interpolation loop by default.
@@ -342,7 +342,7 @@
<method name="track_get_interpolation_type" qualifiers="const">
<return type="int" enum="Animation.InterpolationType">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Returns the interpolation type of a given track.
@@ -351,7 +351,7 @@
<method name="track_get_key_count" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Returns the amount of keys in a given track.
@@ -360,7 +360,7 @@
<method name="track_get_key_time" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -371,7 +371,7 @@
<method name="track_get_key_transition" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -382,7 +382,7 @@
<method name="track_get_key_value" qualifiers="const">
<return type="Variant">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -393,7 +393,7 @@
<method name="track_get_path" qualifiers="const">
<return type="NodePath">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Gets the path of a track. For more information on the path format, see [method track_set_path].
@@ -402,7 +402,7 @@
<method name="track_get_type" qualifiers="const">
<return type="int" enum="Animation.TrackType">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Gets the type of a track.
@@ -411,7 +411,7 @@
<method name="track_insert_key">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -426,7 +426,7 @@
<method name="track_is_enabled" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Returns [code]true[/code] if the track at index [code]idx[/code] is enabled.
@@ -435,7 +435,7 @@
<method name="track_is_imported" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Returns [code]true[/code] if the given track is imported. Else, return [code]false[/code].
@@ -444,7 +444,7 @@
<method name="track_move_down">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Moves a track down.
@@ -453,7 +453,7 @@
<method name="track_move_to">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="to_idx" type="int">
</argument>
@@ -464,7 +464,7 @@
<method name="track_move_up">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Moves a track up.
@@ -473,7 +473,7 @@
<method name="track_remove_key">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -484,7 +484,7 @@
<method name="track_remove_key_at_position">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="position" type="float">
</argument>
@@ -495,7 +495,7 @@
<method name="track_set_enabled">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="enabled" type="bool">
</argument>
@@ -506,7 +506,7 @@
<method name="track_set_imported">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="imported" type="bool">
</argument>
@@ -517,7 +517,7 @@
<method name="track_set_interpolation_loop_wrap">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="interpolation" type="bool">
</argument>
@@ -528,7 +528,7 @@
<method name="track_set_interpolation_type">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="interpolation" type="int" enum="Animation.InterpolationType">
</argument>
@@ -539,7 +539,7 @@
<method name="track_set_key_time">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -552,7 +552,7 @@
<method name="track_set_key_transition">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key_idx" type="int">
</argument>
@@ -565,7 +565,7 @@
<method name="track_set_key_value">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="key" type="int">
</argument>
@@ -578,7 +578,7 @@
<method name="track_set_path">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="path" type="NodePath">
</argument>
@@ -590,7 +590,7 @@
<method name="track_swap">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="with_idx" type="int">
</argument>
@@ -601,7 +601,7 @@
<method name="transform_track_insert_key">
<return type="int">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time" type="float">
</argument>
@@ -618,7 +618,7 @@
<method name="transform_track_interpolate" qualifiers="const">
<return type="Array">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time_sec" type="float">
</argument>
@@ -629,7 +629,7 @@
<method name="value_track_get_key_indices" qualifiers="const">
<return type="PoolIntArray">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="time_sec" type="float">
</argument>
@@ -642,7 +642,7 @@
<method name="value_track_get_update_mode" qualifiers="const">
<return type="int" enum="Animation.UpdateMode">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<description>
Returns the update mode of a value track.
@@ -651,7 +651,7 @@
<method name="value_track_set_update_mode">
<return type="void">
</return>
- <argument index="0" name="idx" type="int">
+ <argument index="0" name="track_idx" type="int">
</argument>
<argument index="1" name="mode" type="int" enum="Animation.UpdateMode">
</argument>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index b206d4a4d2..1f685aab81 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -40,8 +40,9 @@
<return type="String">
</return>
<description>
- The string returned from this method is displayed as a warning in the "Scene Dock" if the script that overrides it is a [code]tool[/code] script.
+ The string returned from this method is displayed as a warning in the Scene Dock if the script that overrides it is a [code]tool[/code] script.
Returning an empty string produces no warning.
+ Call [method update_configuration_warning] when the warning needs to be updated for this node.
</description>
</method>
<method name="_input" qualifiers="virtual">
@@ -818,6 +819,14 @@
Sets whether this is an instance load placeholder. See [InstancePlaceholder].
</description>
</method>
+ <method name="update_configuration_warning">
+ <return type="void">
+ </return>
+ <description>
+ Updates the warning displayed for this node in the Scene Dock.
+ Use [method _get_configuration_warning] to setup the warning message to display.
+ </description>
+ </method>
</methods>
<members>
<member name="custom_multiplayer" type="MultiplayerAPI" setter="set_custom_multiplayer" getter="get_custom_multiplayer">
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index faf2ac1ff9..01c8ee4779 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -16,8 +16,13 @@
</return>
<argument index="0" name="image" type="Texture">
</argument>
+ <argument index="1" name="width" type="int" default="0">
+ </argument>
+ <argument index="2" name="height" type="int" default="0">
+ </argument>
<description>
- Adds an image's opening and closing tags to the tag stack.
+ Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image.
+ If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
</description>
</method>
<method name="add_text">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 8a114efd34..27eab85301 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -54,7 +54,7 @@
<return type="void">
</return>
<description>
- Clears all the syntax coloring information.
+ Clears all custom syntax coloring information previously added with [method add_color_region] or [method add_keyword_color].
</description>
</method>
<method name="clear_undo_history">
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 226eef9c1e..3e0b644b20 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -337,7 +337,7 @@ AnimationTrackEditAudio::AnimationTrackEditAudio() {
AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", this, "_preview_changed");
}
-/// SPRITE FRAME ///
+/// SPRITE FRAME / FRAME_COORDS ///
int AnimationTrackEditSpriteFrame::get_key_height() const {
@@ -439,14 +439,24 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
if (Object::cast_to<Sprite>(object) || Object::cast_to<Sprite3D>(object)) {
- int frame = get_animation()->track_get_key_value(get_track(), p_index);
-
texture = object->call("get_texture");
if (!texture.is_valid()) {
AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right);
return;
}
+ int hframes = object->call("get_hframes");
+ int vframes = object->call("get_vframes");
+
+ Vector2 coords;
+ if (is_coords) {
+ coords = get_animation()->track_get_key_value(get_track(), p_index);
+ } else {
+ int frame = get_animation()->track_get_key_value(get_track(), p_index);
+ coords.x = frame % hframes;
+ coords.y = frame / hframes;
+ }
+
region.size = texture->get_size();
if (bool(object->call("is_region"))) {
@@ -454,9 +464,6 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
region = Rect2(object->call("get_region_rect"));
}
- int hframes = object->call("get_hframes");
- int vframes = object->call("get_vframes");
-
if (hframes > 1) {
region.size.x /= hframes;
}
@@ -464,8 +471,8 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
region.size.y /= vframes;
}
- region.position.x += region.size.x * (frame % hframes);
- region.position.y += region.size.y * (frame / hframes);
+ region.position.x += region.size.x * coords.x;
+ region.position.y += region.size.y * coords.y;
} else if (Object::cast_to<AnimatedSprite>(object) || Object::cast_to<AnimatedSprite3D>(object)) {
@@ -532,6 +539,11 @@ void AnimationTrackEditSpriteFrame::set_node(Object *p_object) {
id = p_object->get_instance_id();
}
+void AnimationTrackEditSpriteFrame::set_as_coords() {
+
+ is_coords = true;
+}
+
/// SUB ANIMATION ///
int AnimationTrackEditSubAnim::get_key_height() const {
@@ -1297,6 +1309,14 @@ AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_value_track_edit(Obj
return sprite;
}
+ if (p_property == "frame_coords" && (p_object->is_class("Sprite") || p_object->is_class("Sprite3D"))) {
+
+ AnimationTrackEditSpriteFrame *sprite = memnew(AnimationTrackEditSpriteFrame);
+ sprite->set_as_coords();
+ sprite->set_node(p_object);
+ return sprite;
+ }
+
if (p_property == "current_animation" && (p_object->is_class("AnimationPlayer"))) {
AnimationTrackEditSubAnim *player = memnew(AnimationTrackEditSubAnim);
diff --git a/editor/animation_track_editor_plugins.h b/editor/animation_track_editor_plugins.h
index 5f0ea6196c..1013cccf72 100644
--- a/editor/animation_track_editor_plugins.h
+++ b/editor/animation_track_editor_plugins.h
@@ -81,6 +81,7 @@ class AnimationTrackEditSpriteFrame : public AnimationTrackEdit {
GDCLASS(AnimationTrackEditSpriteFrame, AnimationTrackEdit);
ObjectID id;
+ bool is_coords;
public:
virtual int get_key_height() const;
@@ -89,6 +90,9 @@ public:
virtual void draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right);
void set_node(Object *p_object);
+ void set_as_coords();
+
+ AnimationTrackEditSpriteFrame() { is_coords = false; }
};
class AnimationTrackEditSubAnim : public AnimationTrackEdit {
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 4a1e93eaad..690538f44c 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -1467,6 +1467,11 @@ void EditorHelp::_notification(int p_what) {
_update_doc();
} break;
+ case NOTIFICATION_THEME_CHANGED: {
+ if (is_visible_in_tree()) {
+ _class_desc_resized();
+ }
+ } break;
default: break;
}
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 2c3a84857a..6e2a4810cd 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -56,6 +56,7 @@
#include "editor/editor_help.h"
#include "editor/editor_properties.h"
#include "editor/editor_settings.h"
+#include "editor/editor_spin_slider.h"
#include "editor/editor_themes.h"
#include "editor/import/editor_import_collada.h"
#include "editor/import/editor_scene_importer_gltf.h"
@@ -3558,6 +3559,7 @@ void EditorNode::register_editor_types() {
ClassDB::register_class<AnimationTrackEditPlugin>();
ClassDB::register_class<ScriptCreateDialog>();
ClassDB::register_class<EditorFeatureProfile>();
+ ClassDB::register_class<EditorSpinSlider>();
// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
ClassDB::register_class<EditorScenePostImport>();
diff --git a/editor/icons/icon_crypto_key.svg b/editor/icons/icon_crypto_key.svg
new file mode 100644
index 0000000000..45b53c815d
--- /dev/null
+++ b/editor/icons/icon_crypto_key.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 4.233 4.233" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.397.34-.374.373-.375.374v.375l.188.187-1.497 1.496v.375l.374.374h.374l.187-.188.282-.092.092-.282.282-.093.093-.28.094-.28.28-.095.187-.187.187.187h.374l.375-.375.373-.373.001-.374-1.122-1.122zm.374.858a.264.264 0 1 1 .002.528.264.264 0 0 1 -.002-.528z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_x509_certificate.svg b/editor/icons/icon_x509_certificate.svg
new file mode 100644
index 0000000000..e175fa3234
--- /dev/null
+++ b/editor/icons/icon_x509_certificate.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 4.233 4.233" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.967.263-3.704.001v2.646h1.427a.993.993 0 0 1 -.022-.096.993.993 0 0 1 -.012-.099.993.993 0 0 1 -.002-.07.993.993 0 0 1 .005-.1.993.993 0 0 1 .014-.097.993.993 0 0 1 .025-.096.993.993 0 0 1 .034-.093.993.993 0 0 1 .043-.09.993.993 0 0 1 .052-.085.993.993 0 0 1 .06-.079.993.993 0 0 1 .068-.072.993.993 0 0 1 .074-.066.993.993 0 0 1 .08-.057.993.993 0 0 1 .087-.05.993.993 0 0 1 .09-.04.993.993 0 0 1 .095-.031.993.993 0 0 1 .096-.022.993.993 0 0 1 .099-.012.993.993 0 0 1 .07-.003.993.993 0 0 1 .099.006.993.993 0 0 1 .098.014.993.993 0 0 1 .096.025.993.993 0 0 1 .094.034.993.993 0 0 1 .089.043.993.993 0 0 1 .084.052.993.993 0 0 1 .08.06.993.993 0 0 1 .072.068.993.993 0 0 1 .065.074.993.993 0 0 1 .058.08.993.993 0 0 1 .05.087.993.993 0 0 1 .04.09.993.993 0 0 1 .031.095.993.993 0 0 1 .022.096.993.993 0 0 1 .012.099.993.993 0 0 1 .002.07.993.993 0 0 1 -.004.1.993.993 0 0 1 -.015.097.993.993 0 0 1 -.017.068h.365z" fill="#e0e0e0"/><g fill="#ff8484"><path d="m2.116 3.175v.793l.53-.253.529.253v-.793z"/><circle cx="2.646" cy="2.645" r=".794"/></g></svg> \ No newline at end of file
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index d6df3bd369..7ba1796600 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -129,6 +129,7 @@ NodeDock::NodeDock() {
select_a_node = memnew(Label);
select_a_node->set_text(TTR("Select a single node to edit its signals and groups."));
+ select_a_node->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
select_a_node->set_v_size_flags(SIZE_EXPAND_FILL);
select_a_node->set_valign(Label::VALIGN_CENTER);
select_a_node->set_align(Label::ALIGN_CENTER);
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 9b3bf8ad5b..1d82735328 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -1944,11 +1944,10 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
r_result.insert(option.display, option);
}
- } else {
- for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) {
- ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER);
- r_result.insert(option.display, option);
- }
+ }
+ for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) {
+ ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER);
+ r_result.insert(option.display, option);
}
}
if (!p_only_functions) {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 282bb45c3f..da6a52ff0d 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -858,11 +858,23 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (current_function) {
int arg_idx = current_function->arguments.find(identifier);
if (arg_idx != -1) {
- if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
- // Assignment is not really usage
- current_function->arguments_usage.write[arg_idx] = current_function->arguments_usage[arg_idx] - 1;
- } else {
- current_function->arguments_usage.write[arg_idx] = current_function->arguments_usage[arg_idx] + 1;
+ switch (tokenizer->get_token()) {
+ case GDScriptTokenizer::TK_OP_ASSIGN_ADD:
+ case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND:
+ case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR:
+ case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR:
+ case GDScriptTokenizer::TK_OP_ASSIGN_DIV:
+ case GDScriptTokenizer::TK_OP_ASSIGN_MOD:
+ case GDScriptTokenizer::TK_OP_ASSIGN_MUL:
+ case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT:
+ case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT:
+ case GDScriptTokenizer::TK_OP_ASSIGN_SUB:
+ case GDScriptTokenizer::TK_OP_ASSIGN: {
+ // Assignment is not really usage
+ } break;
+ default: {
+ current_function->arguments_usage.write[arg_idx] = current_function->arguments_usage[arg_idx] + 1;
+ }
}
}
}
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 8b20b0ff48..4730e9b6bc 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -849,12 +849,8 @@ void GDScriptTokenizerText::_advance() {
_make_error("Unterminated String");
return;
}
- if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
- _make_error("Malformed hex constant in string");
- return;
- }
- CharType v;
+ CharType v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -864,8 +860,8 @@ void GDScriptTokenizerText::_advance() {
v = c - 'A';
v += 10;
} else {
- ERR_PRINT("BUG");
- v = 0;
+ _make_error("Malformed hex constant in string");
+ return;
}
res <<= 4;
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index c97524a54d..804c57fc6e 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -40,11 +40,8 @@
void GridMapEditor::_node_removed(Node *p_node) {
- if (p_node == node) {
+ if (p_node == node)
node = NULL;
- hide();
- mesh_library_palette->hide();
- }
}
void GridMapEditor::_configure() {
@@ -353,7 +350,14 @@ void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const
selection.click = p_begin;
selection.current = p_end;
- _update_selection_transform();
+ if (is_visible_in_tree()) {
+ _update_selection_transform();
+ }
+
+ options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_CLEAR), !selection.active);
+ options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_CUT), !selection.active);
+ options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_DUPLICATE), !selection.active);
+ options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_FILL), !selection.active);
}
bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click) {
@@ -1465,7 +1469,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
}
}
- selection.active = false;
+ _set_selection(false);
updating = false;
accumulated_floor_delta = 0.0;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 739aa285bf..247f006a69 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -56,11 +56,14 @@ import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Messenger;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings.Secure;
import android.support.annotation.Keep;
+import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.Display;
import android.view.KeyEvent;
@@ -126,6 +129,9 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo
private boolean activityResumed;
private int mState;
+ // Used to dispatch events to the main thread.
+ private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
+
static private Intent mCurrentIntent;
@Override
@@ -187,6 +193,20 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo
Godot.singletons[Godot.singleton_count++] = this;
}
+ /**
+ * Invoked once during the Godot Android initialization process after creation of the
+ * {@link GodotView} view.
+ * <p>
+ * This method should be overridden by descendants of this class that would like to add
+ * their view/layout to the Godot view hierarchy.
+ *
+ * @return the view to be included; null if no views should be included.
+ */
+ @Nullable
+ protected View onMainCreateView(Activity activity) {
+ return null;
+ }
+
protected void onMainActivityResult(int requestCode, int resultCode, Intent data) {
}
@@ -306,6 +326,20 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo
public void run() {
GodotLib.setup(current_command_line);
setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
+
+ // The Godot Android plugins are setup on completion of GodotLib.setup
+ mainThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Include the non-null views returned in the Godot view hierarchy.
+ for (int i = 0; i < singleton_count; i++) {
+ View view = singletons[i].onMainCreateView(Godot.this);
+ if (view != null) {
+ layout.addView(view);
+ }
+ }
+ }
+ });
}
});
}
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index ada142005b..75f50aaa28 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -48,18 +48,25 @@ String DirAccessOSX::fix_unicode_name(const char *p_name) const {
}
int DirAccessOSX::get_drive_count() {
- NSArray *vols = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths];
+ NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil];
+ NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes];
+
return [vols count];
}
String DirAccessOSX::get_drive(int p_drive) {
- NSArray *vols = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths];
+ NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil];
+ NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes];
int count = [vols count];
ERR_FAIL_INDEX_V(p_drive, count, "");
- NSString *path = vols[p_drive];
- return String([path UTF8String]);
+ String volname;
+ NSString *path = [vols[p_drive] path];
+
+ volname.parse_utf8([path UTF8String]);
+
+ return volname;
}
#endif //posix_enabled
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index cc9ba720a8..f4390a9882 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -65,6 +65,8 @@ def get_opts():
BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
('msvc_version', 'MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.', None),
BoolVariable('use_mingw', 'Use the Mingw compiler, even if MSVC is installed. Only used on Windows.', False),
+ BoolVariable('use_llvm', 'Use the LLVM compiler', False),
+ BoolVariable('use_thinlto', 'Use ThinLTO', False),
]
@@ -312,17 +314,33 @@ def configure_mingw(env):
env.Append(LINKFLAGS=['-static'])
mingw_prefix = env["mingw_prefix_64"]
- env["CC"] = mingw_prefix + "gcc"
- env['AS'] = mingw_prefix + "as"
- env['CXX'] = mingw_prefix + "g++"
- env['AR'] = mingw_prefix + "gcc-ar"
- env['RANLIB'] = mingw_prefix + "gcc-ranlib"
- env['LINK'] = mingw_prefix + "g++"
+ if env['use_llvm']:
+ env["CC"] = mingw_prefix + "clang"
+ env['AS'] = mingw_prefix + "as"
+ env["CXX"] = mingw_prefix + "clang++"
+ env['AR'] = mingw_prefix + "ar"
+ env['RANLIB'] = mingw_prefix + "ranlib"
+ env["LINK"] = mingw_prefix + "clang++"
+ else:
+ env["CC"] = mingw_prefix + "gcc"
+ env['AS'] = mingw_prefix + "as"
+ env['CXX'] = mingw_prefix + "g++"
+ env['AR'] = mingw_prefix + "gcc-ar"
+ env['RANLIB'] = mingw_prefix + "gcc-ranlib"
+ env['LINK'] = mingw_prefix + "g++"
env["x86_libtheora_opt_gcc"] = True
if env['use_lto']:
- env.Append(CCFLAGS=['-flto'])
- env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
+ if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
+ env.Append(CCFLAGS=['-flto'])
+ env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
+ else:
+ if env['use_thinlto']:
+ env.Append(CCFLAGS=['-flto=thin'])
+ env.Append(LINKFLAGS=['-flto=thin'])
+ else:
+ env.Append(CCFLAGS=['-flto'])
+ env.Append(LINKFLAGS=['-flto'])
## Compile flags
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 85c423964b..9da41914d7 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -37,6 +37,9 @@
void CPUParticles2D::set_emitting(bool p_emitting) {
+ if (emitting == p_emitting)
+ return;
+
emitting = p_emitting;
if (emitting)
set_process_internal(true);
@@ -535,6 +538,74 @@ static float rand_from_seed(uint32_t &seed) {
return float(seed % uint32_t(65536)) / 65535.0;
}
+void CPUParticles2D::_update_internal() {
+
+ if (particles.size() == 0 || !is_visible_in_tree()) {
+ _set_redraw(false);
+ return;
+ }
+
+ float delta = get_process_delta_time();
+ if (emitting) {
+ inactive_time = 0;
+ } else {
+ inactive_time += delta;
+ if (inactive_time > lifetime * 1.2) {
+ set_process_internal(false);
+ _set_redraw(false);
+
+ //reset variables
+ time = 0;
+ inactive_time = 0;
+ frame_remainder = 0;
+ cycle = 0;
+ return;
+ }
+ }
+ _set_redraw(true);
+
+ if (time == 0 && pre_process_time > 0.0) {
+
+ float frame_time;
+ if (fixed_fps > 0)
+ frame_time = 1.0 / fixed_fps;
+ else
+ frame_time = 1.0 / 30.0;
+
+ float todo = pre_process_time;
+
+ while (todo >= 0) {
+ _particles_process(frame_time);
+ todo -= frame_time;
+ }
+ }
+
+ if (fixed_fps > 0) {
+ float frame_time = 1.0 / fixed_fps;
+ float decr = frame_time;
+
+ float ldelta = delta;
+ if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10
+ ldelta = 0.1;
+ } else if (ldelta <= 0.0) { //unlikely but..
+ ldelta = 0.001;
+ }
+ float todo = frame_remainder + ldelta;
+
+ while (todo >= frame_time) {
+ _particles_process(frame_time);
+ todo -= decr;
+ }
+
+ frame_remainder = todo;
+
+ } else {
+ _particles_process(delta);
+ }
+
+ _update_particle_data_buffer();
+}
+
void CPUParticles2D::_particles_process(float p_delta) {
p_delta *= speed_scale;
@@ -1000,6 +1071,10 @@ void CPUParticles2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
+ // first update before rendering to avoid one frame delay after emitting starts
+ if (emitting && (time == 0))
+ _update_internal();
+
if (!redraw)
return; // don't add to render list
@@ -1017,71 +1092,7 @@ void CPUParticles2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
-
- if (particles.size() == 0 || !is_visible_in_tree()) {
- _set_redraw(false);
- return;
- }
-
- float delta = get_process_delta_time();
- if (emitting) {
- inactive_time = 0;
- } else {
- inactive_time += delta;
- if (inactive_time > lifetime * 1.2) {
- set_process_internal(false);
- _set_redraw(false);
-
- //reset variables
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- return;
- }
- }
- _set_redraw(true);
-
- if (time == 0 && pre_process_time > 0.0) {
-
- float frame_time;
- if (fixed_fps > 0)
- frame_time = 1.0 / fixed_fps;
- else
- frame_time = 1.0 / 30.0;
-
- float todo = pre_process_time;
-
- while (todo >= 0) {
- _particles_process(frame_time);
- todo -= frame_time;
- }
- }
-
- if (fixed_fps > 0) {
- float frame_time = 1.0 / fixed_fps;
- float decr = frame_time;
-
- float ldelta = delta;
- if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10
- ldelta = 0.1;
- } else if (ldelta <= 0.0) { //unlikely but..
- ldelta = 0.001;
- }
- float todo = frame_remainder + ldelta;
-
- while (todo >= frame_time) {
- _particles_process(frame_time);
- todo -= decr;
- }
-
- frame_remainder = todo;
-
- } else {
- _particles_process(delta);
- }
-
- _update_particle_data_buffer();
+ _update_internal();
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index da668664b9..47b4568dd4 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -174,6 +174,7 @@ private:
Vector2 gravity;
+ void _update_internal();
void _particles_process(float p_delta);
void _update_particle_data_buffer();
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index 12fb18cedc..847d08b025 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -37,8 +37,8 @@
void Joint2D::_update_joint(bool p_only_free) {
if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid())
- Physics2DServer::get_singleton()->body_remove_collision_exception(ba, bb);
+ if (ba.is_valid() && bb.is_valid() && exclude_from_collision)
+ Physics2DServer::get_singleton()->joint_disable_collisions_between_bodies(joint, false);
Physics2DServer::get_singleton()->free(joint);
joint = RID();
@@ -131,6 +131,8 @@ void Joint2D::set_exclude_nodes_from_collision(bool p_enable) {
if (exclude_from_collision == p_enable)
return;
+
+ _update_joint(true);
exclude_from_collision = p_enable;
_update_joint();
}
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 9a1a759e72..cf68528388 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -325,8 +325,12 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
}
Rect2 TouchScreenButton::_edit_get_rect() const {
- if (texture.is_null())
- return CanvasItem::_edit_get_rect();
+ if (texture.is_null()) {
+ if (shape.is_valid())
+ return shape->get_rect();
+ else
+ return CanvasItem::_edit_get_rect();
+ }
return Rect2(Size2(), texture->get_size());
}
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index 93ff60bc4e..5c895ecf22 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -46,9 +46,17 @@ PoolVector<Face3> CPUParticles::get_faces(uint32_t p_usage_flags) const {
void CPUParticles::set_emitting(bool p_emitting) {
+ if (emitting == p_emitting)
+ return;
+
emitting = p_emitting;
- if (emitting)
+ if (emitting) {
set_process_internal(true);
+
+ // first update before rendering to avoid one frame delay after emitting starts
+ if (time == 0)
+ _update_internal();
+ }
}
void CPUParticles::set_amount(int p_amount) {
@@ -508,6 +516,81 @@ static float rand_from_seed(uint32_t &seed) {
return float(seed % uint32_t(65536)) / 65535.0;
}
+void CPUParticles::_update_internal() {
+
+ if (particles.size() == 0 || !is_visible_in_tree()) {
+ _set_redraw(false);
+ return;
+ }
+
+ float delta = get_process_delta_time();
+ if (emitting) {
+ inactive_time = 0;
+ } else {
+ inactive_time += delta;
+ if (inactive_time > lifetime * 1.2) {
+ set_process_internal(false);
+ _set_redraw(false);
+
+ //reset variables
+ time = 0;
+ inactive_time = 0;
+ frame_remainder = 0;
+ cycle = 0;
+ return;
+ }
+ }
+ _set_redraw(true);
+
+ bool processed = false;
+
+ if (time == 0 && pre_process_time > 0.0) {
+
+ float frame_time;
+ if (fixed_fps > 0)
+ frame_time = 1.0 / fixed_fps;
+ else
+ frame_time = 1.0 / 30.0;
+
+ float todo = pre_process_time;
+
+ while (todo >= 0) {
+ _particles_process(frame_time);
+ processed = true;
+ todo -= frame_time;
+ }
+ }
+
+ if (fixed_fps > 0) {
+ float frame_time = 1.0 / fixed_fps;
+ float decr = frame_time;
+
+ float ldelta = delta;
+ if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10
+ ldelta = 0.1;
+ } else if (ldelta <= 0.0) { //unlikely but..
+ ldelta = 0.001;
+ }
+ float todo = frame_remainder + ldelta;
+
+ while (todo >= frame_time) {
+ _particles_process(frame_time);
+ processed = true;
+ todo -= decr;
+ }
+
+ frame_remainder = todo;
+
+ } else {
+ _particles_process(delta);
+ processed = true;
+ }
+
+ if (processed) {
+ _update_particle_data_buffer();
+ }
+}
+
void CPUParticles::_particles_process(float p_delta) {
p_delta *= speed_scale;
@@ -1068,85 +1151,24 @@ void CPUParticles::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
set_process_internal(emitting);
+
+ // first update before rendering to avoid one frame delay after emitting starts
+ if (emitting && (time == 0))
+ _update_internal();
}
if (p_what == NOTIFICATION_EXIT_TREE) {
_set_redraw(false);
}
- if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
-
- if (particles.size() == 0 || !is_visible_in_tree()) {
- _set_redraw(false);
- return;
- }
-
- float delta = get_process_delta_time();
- if (emitting) {
- inactive_time = 0;
- } else {
- inactive_time += delta;
- if (inactive_time > lifetime * 1.2) {
- set_process_internal(false);
- _set_redraw(false);
-
- //reset variables
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- return;
- }
- }
- _set_redraw(true);
-
- bool processed = false;
-
- if (time == 0 && pre_process_time > 0.0) {
-
- float frame_time;
- if (fixed_fps > 0)
- frame_time = 1.0 / fixed_fps;
- else
- frame_time = 1.0 / 30.0;
-
- float todo = pre_process_time;
-
- while (todo >= 0) {
- _particles_process(frame_time);
- processed = true;
- todo -= frame_time;
- }
- }
-
- if (fixed_fps > 0) {
- float frame_time = 1.0 / fixed_fps;
- float decr = frame_time;
-
- float ldelta = delta;
- if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10
- ldelta = 0.1;
- } else if (ldelta <= 0.0) { //unlikely but..
- ldelta = 0.001;
- }
- float todo = frame_remainder + ldelta;
-
- while (todo >= frame_time) {
- _particles_process(frame_time);
- processed = true;
- todo -= decr;
- }
-
- frame_remainder = todo;
-
- } else {
- _particles_process(delta);
- processed = true;
- }
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ // first update before rendering to avoid one frame delay after emitting starts
+ if (emitting && (time == 0))
+ _update_internal();
+ }
- if (processed) {
- _update_particle_data_buffer();
- }
+ if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
+ _update_internal();
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h
index 66b37f359a..635265be7f 100644
--- a/scene/3d/cpu_particles.h
+++ b/scene/3d/cpu_particles.h
@@ -173,6 +173,7 @@ private:
Vector3 gravity;
+ void _update_internal();
void _particles_process(float p_delta);
void _update_particle_data_buffer();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index fafbcf0c55..8b4d5d4980 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2221,9 +2221,11 @@ void Control::_modal_stack_remove() {
if (!data.MI)
return;
- get_viewport()->_gui_remove_from_modal_stack(data.MI, data.modal_prev_focus_owner);
-
+ List<Control *>::Element *element = data.MI;
data.MI = NULL;
+
+ get_viewport()->_gui_remove_from_modal_stack(element, data.modal_prev_focus_owner);
+
data.modal_prev_focus_owner = 0;
}
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 510f1b18ad..4edd4b8530 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -452,6 +452,11 @@ void Label::regenerate_word_cache() {
current_word_size += char_width;
line_width += char_width;
total_char_cache++;
+
+ // allow autowrap to cut words when they exceed line width
+ if (autowrap && (current_word_size > width)) {
+ separatable = true;
+ }
}
if ((autowrap && (line_width >= width) && ((last && last->char_pos >= 0) || separatable)) || insert_newline) {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 42cb89b2d6..0ce63a7c6f 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -624,19 +624,19 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
if (p_mode == PROCESS_POINTER && r_click_char)
*r_click_char = 0;
- ENSURE_WIDTH(img->image->get_width());
+ ENSURE_WIDTH(img->size.width);
- bool visible = visible_characters < 0 || (p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->image->get_height(), img->image->get_height()));
+ bool visible = visible_characters < 0 || (p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->size.height, img->size.height));
if (visible)
line_is_blank = false;
if (p_mode == PROCESS_DRAW && visible) {
- img->image->draw(ci, p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->image->get_height()));
+ img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size));
}
p_char_count++;
- ADVANCE(img->image->get_width());
- CHECK_HEIGHT((img->image->get_height() + font->get_descent()));
+ ADVANCE(img->size.width);
+ CHECK_HEIGHT((img->size.height + font->get_descent()));
} break;
case ITEM_NEWLINE: {
@@ -859,7 +859,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
void RichTextLabel::_scroll_changed(double) {
- if (updating_scroll)
+ if (updating_scroll || !scroll_active)
return;
if (scroll_follow && vscroll->get_value() >= (vscroll->get_max() - vscroll->get_page()))
@@ -1634,7 +1634,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
}
}
-void RichTextLabel::add_image(const Ref<Texture> &p_image) {
+void RichTextLabel::add_image(const Ref<Texture> &p_image, const int p_width, const int p_height) {
if (current->type == ITEM_TABLE)
return;
@@ -1643,6 +1643,30 @@ void RichTextLabel::add_image(const Ref<Texture> &p_image) {
ItemImage *item = memnew(ItemImage);
item->image = p_image;
+
+ if (p_width > 0) {
+ // custom width
+ item->size.width = p_width;
+ if (p_height > 0) {
+ // custom height
+ item->size.height = p_height;
+ } else {
+ // calculate height to keep aspect ratio
+ item->size.height = p_image->get_height() * p_width / p_image->get_width();
+ }
+ } else {
+ if (p_height > 0) {
+ // custom height
+ item->size.height = p_height;
+ // calculate width to keep aspect ratio
+ item->size.width = p_image->get_width() * p_height / p_image->get_height();
+ } else {
+ // keep original width and height
+ item->size.height = p_image->get_height();
+ item->size.width = p_image->get_width();
+ }
+ }
+
_add_item(item, false);
}
@@ -2125,6 +2149,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
int end = p_bbcode.find("[", brk_end);
if (end == -1)
end = p_bbcode.length();
+
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
Ref<Texture> texture = ResourceLoader::load(image, "Texture");
@@ -2133,6 +2158,32 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = end;
tag_stack.push_front(tag);
+ } else if (tag.begins_with("img=")) {
+
+ int width = 0;
+ int height = 0;
+
+ String params = tag.substr(4, tag.length());
+ int sep = params.find("x");
+ if (sep == -1) {
+ width = params.to_int();
+ } else {
+ width = params.substr(0, sep).to_int();
+ height = params.substr(sep + 1, params.length()).to_int();
+ }
+
+ int end = p_bbcode.find("[", brk_end);
+ if (end == -1)
+ end = p_bbcode.length();
+
+ String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
+
+ Ref<Texture> texture = ResourceLoader::load(image, "Texture");
+ if (texture.is_valid())
+ add_image(texture, width, height);
+
+ pos = end;
+ tag_stack.push_front("img");
} else if (tag.begins_with("color=")) {
String col = tag.substr(6, tag.length());
@@ -2581,7 +2632,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
- ClassDB::bind_method(D_METHOD("add_image", "image"), &RichTextLabel::add_image);
+ ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 1c90d974e4..6cd69b9187 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -148,6 +148,7 @@ private:
struct ItemImage : public Item {
Ref<Texture> image;
+ Size2 size;
ItemImage() { type = ITEM_IMAGE; }
};
@@ -406,7 +407,7 @@ protected:
public:
String get_text();
void add_text(const String &p_text);
- void add_image(const Ref<Texture> &p_image);
+ void add_image(const Ref<Texture> &p_image, const int p_width = 0, const int p_height = 0);
void add_newline();
bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 69d076c41b..42afde9a0c 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2843,19 +2843,30 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// 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
+ // Indent once again if previous line will end with ':','{','[','(' 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;
- } else {
- ins += "\t";
- }
+ if (cursor.column > 0) {
+ char prev_char = text[cursor.line][cursor.column - 1];
+ switch (prev_char) {
+ case ':':
+ case '{':
+ case '[':
+ case '(': {
+ if (!is_line_comment(cursor.line)) {
+ if (indent_using_spaces) {
+ ins += space_indent;
+ } else {
+ ins += "\t";
+ }
- // 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);
+ // No need to move the brace below if we are not taking the text with us.
+ char closing_char = _get_right_pair_symbol(prev_char);
+ if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) {
+ brace_indent = true;
+ ins += "\n" + ins.substr(1, ins.length() - 2);
+ }
+ }
+ } break;
}
}
}
@@ -5052,15 +5063,18 @@ Map<int, TextEdit::Text::ColorRegionInfo> TextEdit::_get_line_color_region_info(
void TextEdit::clear_colors() {
keywords.clear();
+ member_keywords.clear();
color_regions.clear();
color_region_cache.clear();
syntax_highlighting_cache.clear();
text.clear_width_cache();
+ update();
}
void TextEdit::add_keyword_color(const String &p_keyword, const Color &p_color) {
keywords[p_keyword] = p_color;
+ syntax_highlighting_cache.clear();
update();
}
@@ -5077,12 +5091,14 @@ Color TextEdit::get_keyword_color(String p_keyword) const {
void TextEdit::add_color_region(const String &p_begin_key, const String &p_end_key, const Color &p_color, bool p_line_only) {
color_regions.push_back(ColorRegion(p_begin_key, p_end_key, p_color, p_line_only));
+ syntax_highlighting_cache.clear();
text.clear_width_cache();
update();
}
void TextEdit::add_member_keyword(const String &p_keyword, const Color &p_color) {
member_keywords[p_keyword] = p_color;
+ syntax_highlighting_cache.clear();
update();
}
@@ -5096,6 +5112,7 @@ Color TextEdit::get_member_color(String p_member) const {
void TextEdit::clear_member_keywords() {
member_keywords.clear();
+ syntax_highlighting_cache.clear();
update();
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 7b6c90766f..217dacfbfe 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2832,6 +2832,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("rset_unreliable", "property", "value"), &Node::rset_unreliable);
ClassDB::bind_method(D_METHOD("rset_unreliable_id", "peer_id", "property", "value"), &Node::rset_unreliable_id);
+ ClassDB::bind_method(D_METHOD("update_configuration_warning"), &Node::update_configuration_warning);
+
BIND_CONSTANT(NOTIFICATION_ENTER_TREE);
BIND_CONSTANT(NOTIFICATION_EXIT_TREE);
BIND_CONSTANT(NOTIFICATION_MOVED_IN_PARENT);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 830d314245..38ad6886b1 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -78,6 +78,17 @@ bool SceneTreeTimer::is_pause_mode_process() {
return process_pause;
}
+void SceneTreeTimer::release_connections() {
+
+ List<Connection> connections;
+ get_all_signal_connections(&connections);
+
+ for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
+ Connection const &connection = E->get();
+ disconnect(connection.signal, connection.target, connection.method);
+ }
+}
+
SceneTreeTimer::SceneTreeTimer() {
time_left = 0;
process_pause = true;
@@ -611,6 +622,12 @@ void SceneTree::finish() {
memdelete(root); //delete root
root = NULL;
}
+
+ // cleanup timers
+ for (List<Ref<SceneTreeTimer> >::Element *E = timers.front(); E; E = E->next()) {
+ E->get()->release_connections();
+ }
+ timers.clear();
}
void SceneTree::quit() {
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index d387886d61..ef847ebb5b 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -61,6 +61,8 @@ public:
void set_pause_mode_process(bool p_pause_mode_process);
bool is_pause_mode_process();
+ void release_connections();
+
SceneTreeTimer();
};
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 52ef225364..95536bbb23 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2374,7 +2374,6 @@ void Viewport::_gui_remove_from_modal_stack(List<Control *>::Element *MI, Object
List<Control *>::Element *next = MI->next();
gui.modal_stack.erase(MI);
- MI = NULL;
if (p_prev_focus_owner) {
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 985b38f913..d932545da4 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2741,77 +2741,77 @@ void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("remove_track", "idx"), &Animation::remove_track);
+ ClassDB::bind_method(D_METHOD("remove_track", "track_idx"), &Animation::remove_track);
ClassDB::bind_method(D_METHOD("get_track_count"), &Animation::get_track_count);
- ClassDB::bind_method(D_METHOD("track_get_type", "idx"), &Animation::track_get_type);
- ClassDB::bind_method(D_METHOD("track_get_path", "idx"), &Animation::track_get_path);
- ClassDB::bind_method(D_METHOD("track_set_path", "idx", "path"), &Animation::track_set_path);
+ ClassDB::bind_method(D_METHOD("track_get_type", "track_idx"), &Animation::track_get_type);
+ ClassDB::bind_method(D_METHOD("track_get_path", "track_idx"), &Animation::track_get_path);
+ ClassDB::bind_method(D_METHOD("track_set_path", "track_idx", "path"), &Animation::track_set_path);
ClassDB::bind_method(D_METHOD("find_track", "path"), &Animation::find_track);
- ClassDB::bind_method(D_METHOD("track_move_up", "idx"), &Animation::track_move_up);
- ClassDB::bind_method(D_METHOD("track_move_down", "idx"), &Animation::track_move_down);
- ClassDB::bind_method(D_METHOD("track_move_to", "idx", "to_idx"), &Animation::track_move_to);
- ClassDB::bind_method(D_METHOD("track_swap", "idx", "with_idx"), &Animation::track_swap);
+ ClassDB::bind_method(D_METHOD("track_move_up", "track_idx"), &Animation::track_move_up);
+ ClassDB::bind_method(D_METHOD("track_move_down", "track_idx"), &Animation::track_move_down);
+ ClassDB::bind_method(D_METHOD("track_move_to", "track_idx", "to_idx"), &Animation::track_move_to);
+ ClassDB::bind_method(D_METHOD("track_swap", "track_idx", "with_idx"), &Animation::track_swap);
- ClassDB::bind_method(D_METHOD("track_set_imported", "idx", "imported"), &Animation::track_set_imported);
- ClassDB::bind_method(D_METHOD("track_is_imported", "idx"), &Animation::track_is_imported);
+ ClassDB::bind_method(D_METHOD("track_set_imported", "track_idx", "imported"), &Animation::track_set_imported);
+ ClassDB::bind_method(D_METHOD("track_is_imported", "track_idx"), &Animation::track_is_imported);
- ClassDB::bind_method(D_METHOD("track_set_enabled", "idx", "enabled"), &Animation::track_set_enabled);
- ClassDB::bind_method(D_METHOD("track_is_enabled", "idx"), &Animation::track_is_enabled);
+ ClassDB::bind_method(D_METHOD("track_set_enabled", "track_idx", "enabled"), &Animation::track_set_enabled);
+ ClassDB::bind_method(D_METHOD("track_is_enabled", "track_idx"), &Animation::track_is_enabled);
- ClassDB::bind_method(D_METHOD("transform_track_insert_key", "idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key);
- ClassDB::bind_method(D_METHOD("track_insert_key", "idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1));
- ClassDB::bind_method(D_METHOD("track_remove_key", "idx", "key_idx"), &Animation::track_remove_key);
- ClassDB::bind_method(D_METHOD("track_remove_key_at_position", "idx", "position"), &Animation::track_remove_key_at_position);
- ClassDB::bind_method(D_METHOD("track_set_key_value", "idx", "key", "value"), &Animation::track_set_key_value);
- ClassDB::bind_method(D_METHOD("track_set_key_transition", "idx", "key_idx", "transition"), &Animation::track_set_key_transition);
- ClassDB::bind_method(D_METHOD("track_set_key_time", "idx", "key_idx", "time"), &Animation::track_set_key_time);
- ClassDB::bind_method(D_METHOD("track_get_key_transition", "idx", "key_idx"), &Animation::track_get_key_transition);
+ ClassDB::bind_method(D_METHOD("transform_track_insert_key", "track_idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key);
+ ClassDB::bind_method(D_METHOD("track_insert_key", "track_idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("track_remove_key", "track_idx", "key_idx"), &Animation::track_remove_key);
+ ClassDB::bind_method(D_METHOD("track_remove_key_at_position", "track_idx", "position"), &Animation::track_remove_key_at_position);
+ ClassDB::bind_method(D_METHOD("track_set_key_value", "track_idx", "key", "value"), &Animation::track_set_key_value);
+ ClassDB::bind_method(D_METHOD("track_set_key_transition", "track_idx", "key_idx", "transition"), &Animation::track_set_key_transition);
+ ClassDB::bind_method(D_METHOD("track_set_key_time", "track_idx", "key_idx", "time"), &Animation::track_set_key_time);
+ ClassDB::bind_method(D_METHOD("track_get_key_transition", "track_idx", "key_idx"), &Animation::track_get_key_transition);
- ClassDB::bind_method(D_METHOD("track_get_key_count", "idx"), &Animation::track_get_key_count);
- ClassDB::bind_method(D_METHOD("track_get_key_value", "idx", "key_idx"), &Animation::track_get_key_value);
- ClassDB::bind_method(D_METHOD("track_get_key_time", "idx", "key_idx"), &Animation::track_get_key_time);
- ClassDB::bind_method(D_METHOD("track_find_key", "idx", "time", "exact"), &Animation::track_find_key, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("track_get_key_count", "track_idx"), &Animation::track_get_key_count);
+ ClassDB::bind_method(D_METHOD("track_get_key_value", "track_idx", "key_idx"), &Animation::track_get_key_value);
+ ClassDB::bind_method(D_METHOD("track_get_key_time", "track_idx", "key_idx"), &Animation::track_get_key_time);
+ ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "exact"), &Animation::track_find_key, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "idx", "interpolation"), &Animation::track_set_interpolation_type);
- ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "idx"), &Animation::track_get_interpolation_type);
+ ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "track_idx", "interpolation"), &Animation::track_set_interpolation_type);
+ ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "track_idx"), &Animation::track_get_interpolation_type);
- ClassDB::bind_method(D_METHOD("track_set_interpolation_loop_wrap", "idx", "interpolation"), &Animation::track_set_interpolation_loop_wrap);
- ClassDB::bind_method(D_METHOD("track_get_interpolation_loop_wrap", "idx"), &Animation::track_get_interpolation_loop_wrap);
+ ClassDB::bind_method(D_METHOD("track_set_interpolation_loop_wrap", "track_idx", "interpolation"), &Animation::track_set_interpolation_loop_wrap);
+ ClassDB::bind_method(D_METHOD("track_get_interpolation_loop_wrap", "track_idx"), &Animation::track_get_interpolation_loop_wrap);
- ClassDB::bind_method(D_METHOD("transform_track_interpolate", "idx", "time_sec"), &Animation::_transform_track_interpolate);
- ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "idx", "mode"), &Animation::value_track_set_update_mode);
- ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "idx"), &Animation::value_track_get_update_mode);
+ ClassDB::bind_method(D_METHOD("transform_track_interpolate", "track_idx", "time_sec"), &Animation::_transform_track_interpolate);
+ ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "track_idx", "mode"), &Animation::value_track_set_update_mode);
+ ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode);
- ClassDB::bind_method(D_METHOD("value_track_get_key_indices", "idx", "time_sec", "delta"), &Animation::_value_track_get_key_indices);
+ ClassDB::bind_method(D_METHOD("value_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_value_track_get_key_indices);
- ClassDB::bind_method(D_METHOD("method_track_get_key_indices", "idx", "time_sec", "delta"), &Animation::_method_track_get_key_indices);
- ClassDB::bind_method(D_METHOD("method_track_get_name", "idx", "key_idx"), &Animation::method_track_get_name);
- ClassDB::bind_method(D_METHOD("method_track_get_params", "idx", "key_idx"), &Animation::method_track_get_params);
+ ClassDB::bind_method(D_METHOD("method_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_method_track_get_key_indices);
+ ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name);
+ ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params);
- ClassDB::bind_method(D_METHOD("bezier_track_insert_key", "track", "time", "value", "in_handle", "out_handle"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()));
+ ClassDB::bind_method(D_METHOD("bezier_track_insert_key", "track_idx", "time", "value", "in_handle", "out_handle"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()));
- ClassDB::bind_method(D_METHOD("bezier_track_set_key_value", "idx", "key_idx", "value"), &Animation::bezier_track_set_key_value);
- ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "idx", "key_idx", "in_handle"), &Animation::bezier_track_set_key_in_handle);
- ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "idx", "key_idx", "out_handle"), &Animation::bezier_track_set_key_out_handle);
+ ClassDB::bind_method(D_METHOD("bezier_track_set_key_value", "track_idx", "key_idx", "value"), &Animation::bezier_track_set_key_value);
+ ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "track_idx", "key_idx", "in_handle"), &Animation::bezier_track_set_key_in_handle);
+ ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "track_idx", "key_idx", "out_handle"), &Animation::bezier_track_set_key_out_handle);
- ClassDB::bind_method(D_METHOD("bezier_track_get_key_value", "idx", "key_idx"), &Animation::bezier_track_get_key_value);
- ClassDB::bind_method(D_METHOD("bezier_track_get_key_in_handle", "idx", "key_idx"), &Animation::bezier_track_get_key_in_handle);
- ClassDB::bind_method(D_METHOD("bezier_track_get_key_out_handle", "idx", "key_idx"), &Animation::bezier_track_get_key_out_handle);
+ ClassDB::bind_method(D_METHOD("bezier_track_get_key_value", "track_idx", "key_idx"), &Animation::bezier_track_get_key_value);
+ ClassDB::bind_method(D_METHOD("bezier_track_get_key_in_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_in_handle);
+ ClassDB::bind_method(D_METHOD("bezier_track_get_key_out_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_out_handle);
- ClassDB::bind_method(D_METHOD("bezier_track_interpolate", "track", "time"), &Animation::bezier_track_interpolate);
+ ClassDB::bind_method(D_METHOD("bezier_track_interpolate", "track_idx", "time"), &Animation::bezier_track_interpolate);
- ClassDB::bind_method(D_METHOD("audio_track_insert_key", "track", "time", "stream", "start_offset", "end_offset"), &Animation::audio_track_insert_key, DEFVAL(0), DEFVAL(0));
- ClassDB::bind_method(D_METHOD("audio_track_set_key_stream", "idx", "key_idx", "stream"), &Animation::audio_track_set_key_stream);
- ClassDB::bind_method(D_METHOD("audio_track_set_key_start_offset", "idx", "key_idx", "offset"), &Animation::audio_track_set_key_start_offset);
- ClassDB::bind_method(D_METHOD("audio_track_set_key_end_offset", "idx", "key_idx", "offset"), &Animation::audio_track_set_key_end_offset);
- ClassDB::bind_method(D_METHOD("audio_track_get_key_stream", "idx", "key_idx"), &Animation::audio_track_get_key_stream);
- ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "idx", "key_idx"), &Animation::audio_track_get_key_start_offset);
- ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "idx", "key_idx"), &Animation::audio_track_get_key_end_offset);
+ ClassDB::bind_method(D_METHOD("audio_track_insert_key", "track_idx", "time", "stream", "start_offset", "end_offset"), &Animation::audio_track_insert_key, DEFVAL(0), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("audio_track_set_key_stream", "track_idx", "key_idx", "stream"), &Animation::audio_track_set_key_stream);
+ ClassDB::bind_method(D_METHOD("audio_track_set_key_start_offset", "track_idx", "key_idx", "offset"), &Animation::audio_track_set_key_start_offset);
+ ClassDB::bind_method(D_METHOD("audio_track_set_key_end_offset", "track_idx", "key_idx", "offset"), &Animation::audio_track_set_key_end_offset);
+ ClassDB::bind_method(D_METHOD("audio_track_get_key_stream", "track_idx", "key_idx"), &Animation::audio_track_get_key_stream);
+ ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_start_offset);
+ ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_end_offset);
- ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track", "time", "animation"), &Animation::animation_track_insert_key);
- ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation);
- ClassDB::bind_method(D_METHOD("animation_track_get_key_animation", "idx", "key_idx"), &Animation::animation_track_get_key_animation);
+ ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track_idx", "time", "animation"), &Animation::animation_track_insert_key);
+ ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "track_idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation);
+ ClassDB::bind_method(D_METHOD("animation_track_get_key_animation", "track_idx", "key_idx"), &Animation::animation_track_get_key_animation);
ClassDB::bind_method(D_METHOD("set_length", "time_sec"), &Animation::set_length);
ClassDB::bind_method(D_METHOD("get_length"), &Animation::get_length);
@@ -2823,7 +2823,7 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step);
ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
- ClassDB::bind_method(D_METHOD("copy_track", "track", "to_animation"), &Animation::copy_track);
+ ClassDB::bind_method(D_METHOD("copy_track", "track_idx", "to_animation"), &Animation::copy_track);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");