summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/AnimationNodeBlendSpace2D.xml2
-rw-r--r--doc/classes/Array.xml2
-rw-r--r--doc/classes/BackBufferCopy.xml4
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/EditorInspectorPlugin.xml4
-rw-r--r--doc/classes/Image.xml11
-rw-r--r--doc/classes/PopupMenu.xml2
-rw-r--r--doc/classes/SoftBody.xml2
-rw-r--r--doc/classes/TextEdit.xml6
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp9
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp58
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h3
-rw-r--r--editor/plugins/mesh_instance_editor_plugin.cpp1
-rw-r--r--editor/plugins/script_text_editor.cpp21
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp58
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h2
-rw-r--r--modules/gdnative/gdnative_api.json98
-rw-r--r--platform/android/os_android.cpp34
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--servers/visual/shader_language.cpp6
21 files changed, 242 insertions, 88 deletions
diff --git a/doc/classes/AnimationNodeBlendSpace2D.xml b/doc/classes/AnimationNodeBlendSpace2D.xml
index c71a06d931..d8ea7fea5b 100644
--- a/doc/classes/AnimationNodeBlendSpace2D.xml
+++ b/doc/classes/AnimationNodeBlendSpace2D.xml
@@ -125,7 +125,7 @@
</methods>
<members>
<member name="auto_triangles" type="bool" setter="set_auto_triangles" getter="get_auto_triangles" default="true">
- If true, the blend space is triangulated automatically. The mesh updates every time you add or remove points with [method add_blend_point] and [method remove_blend_point].
+ If [code]true[/code], the blend space is triangulated automatically. The mesh updates every time you add or remove points with [method add_blend_point] and [method remove_blend_point].
</member>
<member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="AnimationNodeBlendSpace2D.BlendMode" default="0">
Controls the interpolation between animations. See [enum BlendMode] constants.
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index a1529f3eb3..e09c1f4b08 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -316,7 +316,7 @@
<argument index="3" name="deep" type="bool" default="False">
</argument>
<description>
- Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is true. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing.
+ Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is [code]true[/code]. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing.
</description>
</method>
<method name="sort">
diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml
index 9bb32e0444..945af0c701 100644
--- a/doc/classes/BackBufferCopy.xml
+++ b/doc/classes/BackBufferCopy.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BackBufferCopy" inherits="Node2D" category="Core" version="3.2">
<brief_description>
- Copies a region of the screen (or the whole screen) to a buffer so it can be accessed with [code]SCREEN_TEXTURE[/code] in the [code]texture()[/code] function.
+ Copies a region of the screen (or the whole screen) to a buffer so it can be accessed in your shader scripts through the [code]texture(SCREEN_TEXTURE, ...)[/code] function.
</brief_description>
<description>
- Node for back-buffering the currently-displayed screen. The region defined in the BackBufferCopy node is bufferized with the content of the screen it covers, or the entire screen according to the copy mode set. Use [code]SCREEN_TEXTURE[/code] in the [code]texture()[/code] function to access the buffer.
+ Node for back-buffering the currently-displayed screen. The region defined in the BackBufferCopy node is bufferized with the content of the screen it covers, or the entire screen according to the copy mode set. Use the [code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to access the buffer.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 05ffac803a..f5a8683a39 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -62,7 +62,7 @@
</argument>
<description>
Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. Use [code]for_text[/code] parameter to determine what text the tooltip should contain (likely the contents of [member hint_tooltip]).
- The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When null or non-Control node is returned, the default tooltip will be used instead.
+ The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When [code]null[/code] or non-Control node is returned, the default tooltip will be used instead.
[b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value.
Example of usage with custom-constructed node:
[codeblock]
diff --git a/doc/classes/EditorInspectorPlugin.xml b/doc/classes/EditorInspectorPlugin.xml
index cab5af3985..a713e06585 100644
--- a/doc/classes/EditorInspectorPlugin.xml
+++ b/doc/classes/EditorInspectorPlugin.xml
@@ -6,7 +6,7 @@
<description>
This plugins allows adding custom property editors to [EditorInspector].
Plugins are registered via [method EditorPlugin.add_inspector_plugin].
- When an object is edited, the [method can_handle] function is called and must return true if the object type is supported.
+ When an object is edited, the [method can_handle] function is called and must return [code]true[/code] if the object type is supported.
If supported, the function [method parse_begin] will be called, allowing to place custom controls at the beginning of the class.
Subsequently, the [method parse_category] and [method parse_property] are called for every category and property. They offer the ability to add custom controls to the inspector too.
Finally [method parse_end] will be called.
@@ -54,7 +54,7 @@
<argument index="0" name="object" type="Object">
</argument>
<description>
- Returns true if this object can be handled by this plugin.
+ Returns [code]true[/code] if this object can be handled by this plugin.
</description>
</method>
<method name="parse_begin" qualifiers="virtual">
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index d297bc98ae..d37ab64cb3 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -415,7 +415,7 @@
<argument index="1" name="grayscale" type="bool" default="false">
</argument>
<description>
- Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitly as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
+ Saves the image as an EXR file to [code]path[/code]. If grayscale is [code]true[/code] and the image has only one channel, it will be saved explicitly as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
</description>
</method>
<method name="save_png" qualifiers="const">
@@ -456,6 +456,15 @@
<argument index="1" name="color" type="Color">
</argument>
<description>
+ Sets the [Color] of the pixel at [code](dst.x, dst.y)[/code] if the image is locked. Note that the [code]dst[/code] values must be integers. Example:
+ [codeblock]
+ var img = Image.new()
+ img.create(img_width, img_height, false, Image.FORMAT_RGBA8)
+ img.lock()
+ img.set_pixelv(Vector2(x, y), color) # Works
+ img.unlock()
+ img.set_pixelv(Vector2(x, y), color) # Does not have an effect
+ [/codeblock]
</description>
</method>
<method name="shrink_x2">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 691aec2eb1..bdb6ca84ee 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -444,7 +444,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- Sets the type of the item at the specified index [code]idx[/code] to radio button. If false, sets the type of the item to plain text.
+ Sets the type of the item at the specified index [code]idx[/code] to radio button. If [code]false[/code], sets the type of the item to plain text.
</description>
</method>
<method name="set_item_as_separator">
diff --git a/doc/classes/SoftBody.xml b/doc/classes/SoftBody.xml
index e4a5087db5..93f02c0e01 100644
--- a/doc/classes/SoftBody.xml
+++ b/doc/classes/SoftBody.xml
@@ -78,7 +78,7 @@
</methods>
<members>
<member name="ray_pickable" type="bool" setter="set_ray_pickable" getter="is_ray_pickable" default="false">
- If true, the [SoftBody] will respond to [RayCast]s.
+ If [code]true[/code], the [SoftBody] will respond to [RayCast]s.
</member>
<member name="areaAngular_stiffness" type="float" setter="set_areaAngular_stiffness" getter="get_areaAngular_stiffness" default="0.5">
</member>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 71a949a4af..e883341107 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -94,7 +94,7 @@
</argument>
<description>
Moves the cursor at the specified [code]column[/code] index.
- If [code]adjust_viewport[/code] is set to true, the viewport will center at the cursor position after the move occurs.
+ If [code]adjust_viewport[/code] is set to [code]true[/code], the viewport will center at the cursor position after the move occurs.
</description>
</method>
<method name="cursor_set_line">
@@ -110,8 +110,8 @@
</argument>
<description>
Moves the cursor at the specified [code]line[/code] index.
- If [code]adjust_viewport[/code] is set to true, the viewport will center at the cursor position after the move occurs.
- If [code]can_be_hidden[/code] is set to true, the specified [code]line[/code] can be hidden using [method set_line_as_hidden].
+ If [code]adjust_viewport[/code] is set to [code]true[/code], the viewport will center at the cursor position after the move occurs.
+ If [code]can_be_hidden[/code] is set to [code]true[/code], the specified [code]line[/code] can be hidden using [method set_line_as_hidden].
</description>
</method>
<method name="cut">
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 1db8a870a2..7e9b6fdb82 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -809,15 +809,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "else\n";
code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
- } else if (cf_node->flow_op == SL::FLOW_OP_SWITCH) {
- code += _mktab(p_level) + "switch (" + _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
- code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
- } else if (cf_node->flow_op == SL::FLOW_OP_CASE) {
- code += _mktab(p_level) + "case " + _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n";
- code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
- } else if (cf_node->flow_op == SL::FLOW_OP_DEFAULT) {
- code += _mktab(p_level) + "default:\n";
- code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cf_node->flow_op == SL::FLOW_OP_DO) {
code += _mktab(p_level);
code += "do";
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 2d9a713cad..119c61deb1 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -70,11 +70,15 @@ class SnapDialog : public ConfirmationDialog {
SpinBox *primary_grid_steps;
SpinBox *rotation_offset;
SpinBox *rotation_step;
+ SpinBox *scale_step;
public:
SnapDialog() {
const int SPIN_BOX_GRID_RANGE = 16384;
const int SPIN_BOX_ROTATION_RANGE = 360;
+ const float SPIN_BOX_SCALE_MIN = 0.01f;
+ const float SPIN_BOX_SCALE_MAX = 100;
+
Label *label;
VBoxContainer *container;
GridContainer *child_container;
@@ -182,9 +186,27 @@ public:
rotation_step->set_suffix("deg");
rotation_step->set_h_size_flags(SIZE_EXPAND_FILL);
child_container->add_child(rotation_step);
+
+ container->add_child(memnew(HSeparator));
+
+ child_container = memnew(GridContainer);
+ child_container->set_columns(2);
+ container->add_child(child_container);
+ label = memnew(Label);
+ label->set_text(TTR("Scale Step:"));
+ child_container->add_child(label);
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ scale_step = memnew(SpinBox);
+ scale_step->set_min(SPIN_BOX_SCALE_MIN);
+ scale_step->set_max(SPIN_BOX_SCALE_MAX);
+ scale_step->set_allow_greater(true);
+ scale_step->set_h_size_flags(SIZE_EXPAND_FILL);
+ scale_step->set_step(0.01f);
+ child_container->add_child(scale_step);
}
- void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step) {
+ void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step, const float p_scale_step) {
grid_offset_x->set_value(p_grid_offset.x);
grid_offset_y->set_value(p_grid_offset.y);
grid_step_x->set_value(p_grid_step.x);
@@ -192,14 +214,16 @@ public:
primary_grid_steps->set_value(p_primary_grid_steps);
rotation_offset->set_value(p_rotation_offset * (180 / Math_PI));
rotation_step->set_value(p_rotation_step * (180 / Math_PI));
+ scale_step->set_value(p_scale_step);
}
- void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step) {
+ void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step, float &p_scale_step) {
p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
p_primary_grid_steps = int(primary_grid_steps->get_value());
p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI);
p_rotation_step = rotation_step->get_value() / (180 / Math_PI);
+ p_scale_step = scale_step->get_value();
}
};
@@ -921,7 +945,7 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite
}
void CanvasItemEditor::_snap_changed() {
- ((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step);
+ ((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
grid_step_multiplier = 0;
viewport->update();
}
@@ -1852,6 +1876,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
bool uniform = m->get_shift();
+ bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
Point2 drag_from_local = simple_xform.xform(drag_from);
Point2 drag_to_local = simple_xform.xform(drag_to);
@@ -1882,6 +1907,12 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
}
}
}
+
+ if (snap_scale && !is_ctrl) {
+ scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step;
+ scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step;
+ }
+
canvas_item->call("set_scale", scale);
return true;
}
@@ -4351,6 +4382,11 @@ void CanvasItemEditor::_popup_callback(int p_op) {
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
} break;
+ case SNAP_USE_SCALE: {
+ snap_scale = !snap_scale;
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_SCALE);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_scale);
+ } break;
case SNAP_RELATIVE: {
snap_relative = !snap_relative;
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
@@ -4363,7 +4399,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
} break;
case SNAP_CONFIGURE: {
- ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step);
+ ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
snap_dialog->popup_centered(Size2(220, 160) * EDSCALE);
} break;
case SKELETON_SHOW_BONES: {
@@ -4914,6 +4950,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["primary_grid_steps"] = primary_grid_steps;
state["snap_rotation_offset"] = snap_rotation_offset;
state["snap_rotation_step"] = snap_rotation_step;
+ state["snap_scale_step"] = snap_scale_step;
state["smart_snap_active"] = smart_snap_active;
state["grid_snap_active"] = grid_snap_active;
state["snap_node_parent"] = snap_node_parent;
@@ -4931,6 +4968,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["show_zoom_control"] = zoom_hb->is_visible();
state["show_edit_locks"] = show_edit_locks;
state["snap_rotation"] = snap_rotation;
+ state["snap_scale"] = snap_scale;
state["snap_relative"] = snap_relative;
state["snap_pixel"] = snap_pixel;
state["skeleton_show_bones"] = skeleton_show_bones;
@@ -4972,6 +5010,10 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_rotation_offset = state["snap_rotation_offset"];
}
+ if (state.has("snap_scale_step")) {
+ snap_scale_step = state["snap_scale_step"];
+ }
+
if (state.has("smart_snap_active")) {
smart_snap_active = state["smart_snap_active"];
smart_snap_button->set_pressed(smart_snap_active);
@@ -5072,6 +5114,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
}
+ if (state.has("snap_scale")) {
+ snap_scale = state["snap_scale"];
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_SCALE);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_scale);
+ }
+
if (state.has("snap_relative")) {
snap_relative = state["snap_relative"];
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
@@ -5157,6 +5205,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
grid_step_multiplier = 0;
snap_rotation_offset = 0;
snap_rotation_step = 15 / (180 / Math_PI);
+ snap_scale_step = 0.1f;
smart_snap_active = false;
grid_snap_active = false;
snap_node_parent = true;
@@ -5379,6 +5428,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->connect("id_pressed", this, "_popup_callback");
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_scale_snap", TTR("Use Scale Snap")), SNAP_USE_SCALE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping");
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 35efc14b5e..058f9a77d3 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -108,6 +108,7 @@ private:
SNAP_USE_GRID,
SNAP_USE_GUIDES,
SNAP_USE_ROTATION,
+ SNAP_USE_SCALE,
SNAP_RELATIVE,
SNAP_CONFIGURE,
SNAP_USE_PIXEL,
@@ -260,6 +261,7 @@ private:
float snap_rotation_step;
float snap_rotation_offset;
+ float snap_scale_step;
bool smart_snap_active;
bool grid_snap_active;
@@ -270,6 +272,7 @@ private:
bool snap_other_nodes;
bool snap_guides;
bool snap_rotation;
+ bool snap_scale;
bool snap_relative;
bool snap_pixel;
bool skeleton_show_bones;
diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp
index 635b934333..22df8fd8f4 100644
--- a/editor/plugins/mesh_instance_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_editor_plugin.cpp
@@ -180,6 +180,7 @@ void MeshInstanceEditor::_menu_option(int p_option) {
CollisionShape *cshape = memnew(CollisionShape);
cshape->set_shape(shapes[i]);
+ cshape->set_transform(node->get_transform());
Node *owner = node->get_owner();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 603a2365c1..f63445dab8 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -571,6 +571,7 @@ void ScriptTextEditor::_validate_script() {
String error_text = "error(" + itos(line) + "," + itos(col) + "): " + errortxt;
code_editor->set_error(error_text);
code_editor->set_error_pos(line - 1, col - 1);
+ script_is_valid = false;
} else {
code_editor->set_error("");
line = -1;
@@ -585,6 +586,7 @@ void ScriptTextEditor::_validate_script() {
functions.push_back(E->get());
}
+ script_is_valid = true;
}
_update_connected_methods();
@@ -967,7 +969,7 @@ void ScriptTextEditor::_update_connected_methods() {
text_edit->clear_info_icons();
missing_connections.clear();
- if (!script->is_valid()) {
+ if (!script_is_valid) {
return;
}
@@ -1000,10 +1002,18 @@ void ScriptTextEditor::_update_connected_methods() {
if (!ClassDB::has_method(script->get_instance_base_type(), connection.method)) {
int line = -1;
- if (script->has_method(connection.method)) {
- line = script->get_member_line(connection.method);
- text_edit->set_line_info_icon(line - 1, get_parent_control()->get_icon("Slot", "EditorIcons"), connection.method);
- methods_found.insert(connection.method);
+
+ for (int j = 0; j < functions.size(); j++) {
+ String name = functions[j].get_slice(":", 0);
+ if (name == connection.method) {
+ line = functions[j].get_slice(":", 1).to_int();
+ text_edit->set_line_info_icon(line - 1, get_parent_control()->get_icon("Slot", "EditorIcons"), connection.method);
+ methods_found.insert(connection.method);
+ break;
+ }
+ }
+
+ if (line >= 0) {
continue;
}
@@ -1728,6 +1738,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
ScriptTextEditor::ScriptTextEditor() {
theme_loaded = false;
+ script_is_valid = false;
VSplitContainer *editor_box = memnew(VSplitContainer);
add_child(editor_box);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index eba75befd4..2ba0be8feb 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -59,6 +59,7 @@ class ScriptTextEditor : public ScriptEditorBase {
RichTextLabel *warnings_panel;
Ref<Script> script;
+ bool script_is_valid;
Vector<String> functions;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 3a9e48cfdb..e96f2e55c2 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -109,11 +109,12 @@ void VisualShaderEditor::clear_custom_types() {
for (int i = 0; i < add_options.size(); i++) {
if (add_options[i].is_custom) {
add_options.remove(i);
+ i--;
}
}
}
-void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category) {
+void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_subcategory) {
ERR_FAIL_COND(!p_name.is_valid_identifier());
ERR_FAIL_COND(!p_script.is_valid());
@@ -131,9 +132,25 @@ void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script>
ao.return_type = p_return_icon_type;
ao.description = p_description;
ao.category = p_category;
- ao.sub_category = p_sub_category;
+ ao.sub_category = p_subcategory;
ao.is_custom = true;
+ bool begin = false;
+
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].is_custom) {
+ if (add_options[i].category == p_category) {
+ if (!begin) {
+ begin = true;
+ }
+ } else {
+ if (begin) {
+ add_options.insert(i, ao);
+ return;
+ }
+ }
+ }
+ }
add_options.push_back(ao);
}
@@ -184,6 +201,7 @@ void VisualShaderEditor::update_custom_nodes() {
clear_custom_types();
List<StringName> class_list;
ScriptServer::get_global_class_list(&class_list);
+ Dictionary added;
for (int i = 0; i < class_list.size(); i++) {
if (ScriptServer::get_global_class_native_base(class_list[i]) == "VisualShaderNodeCustom") {
@@ -222,14 +240,44 @@ void VisualShaderEditor::update_custom_nodes() {
category = "Custom";
}
- String sub_category = "";
+ String subcategory = "";
if (ref->has_method("_get_subcategory")) {
- sub_category = (String)ref->call("_get_subcategory");
+ subcategory = (String)ref->call("_get_subcategory");
}
- add_custom_type(name, script, description, return_icon_type, category, sub_category);
+ Dictionary dict;
+ dict["name"] = name;
+ dict["script"] = script;
+ dict["description"] = description;
+ dict["return_icon_type"] = return_icon_type;
+ dict["category"] = category;
+ dict["subcategory"] = subcategory;
+
+ String key;
+ key = category;
+ key += "/";
+ if (subcategory != "") {
+ key += subcategory;
+ key += "/";
+ }
+ key += name;
+
+ added[key] = dict;
}
}
+
+ Array keys = added.keys();
+ keys.sort();
+
+ for (int i = 0; i < keys.size(); i++) {
+
+ const Variant &key = keys.get(i);
+
+ const Dictionary &value = (Dictionary)added[key];
+
+ add_custom_type(value["name"], value["script"], value["description"], value["return_icon_type"], value["category"], value["subcategory"]);
+ }
+
_update_options_menu();
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 6f77641936..5197f8c77f 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -264,7 +264,7 @@ public:
static VisualShaderEditor *get_singleton() { return singleton; }
void clear_custom_types();
- void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category);
+ void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_subcategory);
virtual Size2 get_minimum_size() const;
void edit(VisualShader *p_visual_shader);
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 2f304ca49c..9e5295a936 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -91,6 +91,55 @@
["const godot_int", "p_step"],
["const godot_bool", "p_deep"]
]
+ },
+ {
+ "name": "godot_pool_byte_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_color_array *", "p_self"]
+ ]
}
]
},
@@ -1717,13 +1766,6 @@
]
},
{
- "name": "godot_pool_byte_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_byte_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_byte_array_destroy",
"return_type": "void",
"arguments": [
@@ -1848,13 +1890,6 @@
]
},
{
- "name": "godot_pool_int_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_int_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_int_array_destroy",
"return_type": "void",
"arguments": [
@@ -1979,13 +2014,6 @@
]
},
{
- "name": "godot_pool_real_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_real_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_real_array_destroy",
"return_type": "void",
"arguments": [
@@ -2110,13 +2138,6 @@
]
},
{
- "name": "godot_pool_string_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_string_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_string_array_destroy",
"return_type": "void",
"arguments": [
@@ -2241,13 +2262,6 @@
]
},
{
- "name": "godot_pool_vector2_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_vector2_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_vector2_array_destroy",
"return_type": "void",
"arguments": [
@@ -2372,13 +2386,6 @@
]
},
{
- "name": "godot_pool_vector3_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_vector3_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_vector3_array_destroy",
"return_type": "void",
"arguments": [
@@ -2503,13 +2510,6 @@
]
},
{
- "name": "godot_pool_color_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_pool_color_array *", "p_self"]
- ]
- },
- {
"name": "godot_pool_color_array_destroy",
"return_type": "void",
"arguments": [
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index defee8f1f1..9156181bbe 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -49,6 +49,9 @@
#include "java_godot_io_wrapper.h"
#include "java_godot_wrapper.h"
+#define PAN_GESTURE_MIN_DELTA 5 // only advertise PanGesture event with dx and dy greater than this
+#define MAGNIFY_GESTURE_MIN_FACTOR 0.1 // only advertise MagnifyGesture event with a factor difference from 1.0 greater than this
+
class AndroidLogger : public Logger {
public:
virtual void logv(const char *p_format, va_list p_list, bool p_err) {
@@ -406,6 +409,35 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ERR_FAIL_COND(touch.size() != p_points.size());
+ if (touch.size() == 1) {
+ Point2 d = (p_points[0].pos - touch.write[0].pos);
+ if (fabs(d.x) > PAN_GESTURE_MIN_DELTA || fabs(d.y) > PAN_GESTURE_MIN_DELTA) {
+ Ref<InputEventPanGesture> ev;
+ ev.instance();
+ ev->set_position(p_points[0].pos);
+ ev->set_delta(d);
+ input->parse_input_event(ev);
+ touch.write[0].pos = p_points[0].pos;
+ }
+ } else if (touch.size() == 2) {
+ Point2 v0 = touch[1].pos - touch[0].pos;
+ float l0 = (v0.x * v0.x) + (v0.y * v0.y);
+ if (l0 != 0.0) {
+ Point2 v1 = p_points[1].pos - p_points[0].pos;
+ float l1 = (v1.x * v1.x) + (v1.y * v1.y);
+ float f = (l1 / l0);
+ if (fabs(f - 1.0) > MAGNIFY_GESTURE_MIN_FACTOR) {
+ Ref<InputEventMagnifyGesture> ev;
+ ev.instance();
+ ev->set_position(p_points[0].pos + v1 / 2);
+ ev->set_factor(sqrt(f));
+ input->parse_input_event(ev);
+ touch.write[0].pos = p_points[0].pos;
+ touch.write[1].pos = p_points[1].pos;
+ }
+ }
+ }
+
for (int i = 0; i < touch.size(); i++) {
int idx = -1;
@@ -420,7 +452,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ERR_CONTINUE(idx == -1);
if (touch[i].pos == p_points[idx].pos)
- continue; //no move unncesearily
+ continue; //no unnecessary move
Ref<InputEventScreenDrag> ev;
ev.instance();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5e6e038f38..c818633f48 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3928,7 +3928,9 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
if (shift_first_line) {
text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line));
text.set_hidden(p_line + 1, text.is_hidden(p_line));
- text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line));
+ if (text.has_info_icon(p_line)) {
+ text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line));
+ }
text.set_breakpoint(p_line, false);
text.set_hidden(p_line, false);
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index a57ab92085..f791298472 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -4176,6 +4176,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
_set_tkpos(pos); //rollback
}
} else if (tk.type == TK_CF_SWITCH) {
+
+ if (VisualServer::get_singleton()->is_low_end()) {
+ _set_error("\"switch\" operator is supported only on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
+
// switch() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {