summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/math/geometry.cpp11
-rw-r--r--core/math/geometry.h3
-rw-r--r--core/os/input.cpp20
-rw-r--r--core/os/input.h25
-rw-r--r--core/os/os.h1
-rw-r--r--core/ring_buffer.h17
-rw-r--r--core/script_debugger_remote.cpp10
-rw-r--r--core/variant_call.cpp5
-rw-r--r--doc/classes/@GDScript.xml5
-rw-r--r--doc/classes/@GlobalScope.xml60
-rw-r--r--doc/classes/ARVRServer.xml2
-rw-r--r--doc/classes/AStar.xml2
-rw-r--r--doc/classes/BakedLightmap.xml28
-rw-r--r--doc/classes/Camera.xml3
-rw-r--r--doc/classes/Image.xml78
-rw-r--r--doc/classes/Input.xml39
-rw-r--r--doc/classes/InputEvent.xml15
-rw-r--r--doc/classes/MenuButton.xml8
-rw-r--r--doc/classes/Node2D.xml2
-rw-r--r--doc/classes/Physics2DServer.xml12
-rw-r--r--doc/classes/SceneTree.xml16
-rw-r--r--doc/classes/ScriptEditor.xml16
-rw-r--r--doc/classes/Spatial.xml46
-rw-r--r--doc/classes/StreamPeer.xml2
-rw-r--r--doc/classes/TextEdit.xml2
-rw-r--r--doc/classes/TileMap.xml2
-rw-r--r--doc/classes/TileSet.xml6
-rw-r--r--doc/classes/Tree.xml2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp4
-rw-r--r--drivers/unix/os_unix.cpp2
-rw-r--r--editor/code_editor.cpp2
-rw-r--r--editor/create_dialog.cpp29
-rw-r--r--editor/create_dialog.h3
-rw-r--r--editor/editor_about.cpp3
-rw-r--r--editor/editor_fonts.cpp17
-rw-r--r--editor/editor_log.cpp2
-rw-r--r--editor/editor_node.cpp3
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_themes.cpp11
-rw-r--r--editor/filesystem_dock.cpp14
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp18
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h4
-rw-r--r--editor/plugins/curve_editor_plugin.cpp23
-rw-r--r--editor/plugins/script_editor_plugin.cpp12
-rw-r--r--editor/plugins/script_editor_plugin.h1
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp69
-rw-r--r--editor/plugins/tile_set_editor_plugin.h1
-rw-r--r--editor/project_manager.cpp136
-rw-r--r--editor/scene_tree_dock.cpp3
-rw-r--r--editor/script_create_dialog.cpp16
-rw-r--r--editor/script_editor_debugger.cpp67
-rw-r--r--editor/script_editor_debugger.h10
-rw-r--r--main/input_default.cpp20
-rw-r--r--main/input_default.h2
-rw-r--r--main/main.cpp2
-rwxr-xr-xmisc/dist/osx_tools.app/Contents/Info.plist4
-rw-r--r--modules/gdscript/gdscript_function.cpp2
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml42
-rw-r--r--modules/gridmap/grid_map.cpp80
-rw-r--r--modules/gridmap/grid_map.h16
-rw-r--r--modules/thekla_unwrap/register_types.cpp7
-rw-r--r--modules/theora/video_stream_theora.cpp9
-rw-r--r--platform/android/SCsub2
-rw-r--r--platform/android/build.gradle.template4
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--platform/android/os_android.cpp3
-rw-r--r--platform/android/os_android.h1
-rw-r--r--platform/haiku/os_haiku.cpp4
-rw-r--r--platform/haiku/os_haiku.h1
-rw-r--r--platform/iphone/os_iphone.cpp2
-rw-r--r--platform/iphone/os_iphone.h1
-rw-r--r--platform/osx/os_osx.h3
-rw-r--r--platform/osx/os_osx.mm97
-rw-r--r--platform/server/os_server.cpp3
-rw-r--r--platform/server/os_server.h1
-rw-r--r--platform/uwp/os_uwp.cpp4
-rw-r--r--platform/uwp/os_uwp.h1
-rw-r--r--platform/windows/os_windows.cpp117
-rw-r--r--platform/windows/os_windows.h3
-rw-r--r--platform/x11/os_x11.cpp92
-rw-r--r--platform/x11/os_x11.h3
-rw-r--r--scene/2d/canvas_item.h1
-rw-r--r--scene/2d/collision_polygon_2d.cpp7
-rw-r--r--scene/2d/collision_polygon_2d.h1
-rw-r--r--scene/2d/collision_shape_2d.cpp10
-rw-r--r--scene/2d/collision_shape_2d.h1
-rw-r--r--scene/2d/line_2d.cpp26
-rw-r--r--scene/2d/line_2d.h3
-rw-r--r--scene/2d/navigation_polygon.cpp60
-rw-r--r--scene/2d/navigation_polygon.h9
-rw-r--r--scene/2d/node_2d.cpp22
-rw-r--r--scene/2d/node_2d.h6
-rw-r--r--scene/2d/path_2d.cpp54
-rw-r--r--scene/2d/path_2d.h3
-rw-r--r--scene/2d/polygon_2d.cpp7
-rw-r--r--scene/2d/polygon_2d.h1
-rw-r--r--scene/2d/sprite.cpp93
-rw-r--r--scene/2d/sprite.h3
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/3d/skeleton.cpp4
-rw-r--r--scene/animation/animation_player.cpp21
-rw-r--r--scene/animation/animation_player.h1
-rw-r--r--scene/animation/tween.cpp85
-rw-r--r--scene/gui/color_picker.cpp1
-rw-r--r--scene/gui/item_list.cpp9
-rw-r--r--scene/gui/item_list.h4
-rw-r--r--scene/gui/line_edit.cpp12
-rw-r--r--scene/gui/text_edit.cpp65
-rw-r--r--scene/gui/text_edit.h1
-rw-r--r--scene/main/scene_tree.cpp1
-rw-r--r--scene/resources/capsule_shape_2d.cpp29
-rw-r--r--scene/resources/capsule_shape_2d.h3
-rw-r--r--scene/resources/circle_shape_2d.cpp6
-rw-r--r--scene/resources/circle_shape_2d.h2
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp17
-rw-r--r--scene/resources/concave_polygon_shape_2d.h2
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp5
-rw-r--r--scene/resources/convex_polygon_shape_2d.h2
-rw-r--r--scene/resources/segment_shape_2d.cpp7
-rw-r--r--scene/resources/segment_shape_2d.h2
-rw-r--r--scene/resources/shape_2d.h2
-rw-r--r--scene/resources/shape_line_2d.cpp15
-rw-r--r--scene/resources/shape_line_2d.h2
-rw-r--r--servers/visual/visual_server_canvas.cpp8
-rw-r--r--servers/visual/visual_server_canvas.h6
-rw-r--r--servers/visual/visual_server_raster.h2
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp1
-rw-r--r--servers/visual/visual_server_wrap_mt.h3
-rw-r--r--servers/visual_server.cpp2
-rw-r--r--servers/visual_server.h2
-rw-r--r--thirdparty/thekla_atlas/godot-changes.patch154
-rw-r--r--thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp6
132 files changed, 1755 insertions, 454 deletions
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index b2145eca85..a3b48320b1 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -30,6 +30,17 @@
#include "geometry.h"
#include "print_string.h"
+bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
+
+ Vector<int> indices = Geometry::triangulate_polygon(p_polygon);
+ for (int j = 0; j + 3 <= indices.size(); j += 3) {
+ int i1 = indices[j], i2 = indices[j + 1], i3 = indices[j + 2];
+ if (Geometry::is_point_in_triangle(p_point, p_polygon[i1], p_polygon[i2], p_polygon[i3]))
+ return true;
+ }
+ return false;
+}
+
void Geometry::MeshData::optimize_vertices() {
Map<int, int> vtx_remap;
diff --git a/core/math/geometry.h b/core/math/geometry.h
index ac1a22289c..fefdd88794 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -512,6 +512,9 @@ public:
return true;
}
+
+ static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon);
+
static Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 *p_segment) {
Vector2 p = p_point - p_segment[0];
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 2795b11243..a44adde425 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -84,7 +84,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &Input::warp_mouse_position);
ClassDB::bind_method(D_METHOD("action_press", "action"), &Input::action_press);
ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release);
- ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(Vector2()));
+ ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
@@ -92,6 +92,24 @@ void Input::_bind_methods() {
BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED);
+ BIND_ENUM_CONSTANT(CURSOR_ARROW);
+ BIND_ENUM_CONSTANT(CURSOR_IBEAM);
+ BIND_ENUM_CONSTANT(CURSOR_POINTING_HAND);
+ BIND_ENUM_CONSTANT(CURSOR_CROSS);
+ BIND_ENUM_CONSTANT(CURSOR_WAIT);
+ BIND_ENUM_CONSTANT(CURSOR_BUSY);
+ BIND_ENUM_CONSTANT(CURSOR_DRAG);
+ BIND_ENUM_CONSTANT(CURSOR_CAN_DROP);
+ BIND_ENUM_CONSTANT(CURSOR_FORBIDDEN);
+ BIND_ENUM_CONSTANT(CURSOR_VSIZE);
+ BIND_ENUM_CONSTANT(CURSOR_HSIZE);
+ BIND_ENUM_CONSTANT(CURSOR_BDIAGSIZE);
+ BIND_ENUM_CONSTANT(CURSOR_FDIAGSIZE);
+ BIND_ENUM_CONSTANT(CURSOR_MOVE);
+ BIND_ENUM_CONSTANT(CURSOR_VSPLIT);
+ BIND_ENUM_CONSTANT(CURSOR_HSPLIT);
+ BIND_ENUM_CONSTANT(CURSOR_HELP);
+
ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "connected")));
}
diff --git a/core/os/input.h b/core/os/input.h
index 608484ccd0..140d11de4d 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -51,6 +51,28 @@ public:
MOUSE_MODE_CONFINED
};
+#undef CursorShape
+ enum CursorShape {
+ CURSOR_ARROW,
+ CURSOR_IBEAM,
+ CURSOR_POINTING_HAND,
+ CURSOR_CROSS,
+ CURSOR_WAIT,
+ CURSOR_BUSY,
+ CURSOR_DRAG,
+ CURSOR_CAN_DROP,
+ CURSOR_FORBIDDEN,
+ CURSOR_VSIZE,
+ CURSOR_HSIZE,
+ CURSOR_BDIAGSIZE,
+ CURSOR_FDIAGSIZE,
+ CURSOR_MOVE,
+ CURSOR_VSPLIT,
+ CURSOR_HSPLIT,
+ CURSOR_HELP,
+ CURSOR_MAX
+ };
+
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
@@ -96,7 +118,7 @@ public:
virtual bool is_emulating_touchscreen() const = 0;
- virtual void set_custom_mouse_cursor(const RES &p_cursor, const Vector2 &p_hotspot = Vector2()) = 0;
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) = 0;
virtual void set_mouse_in_window(bool p_in_window) = 0;
virtual String get_joy_button_string(int p_button) = 0;
@@ -110,5 +132,6 @@ public:
};
VARIANT_ENUM_CAST(Input::MouseMode);
+VARIANT_ENUM_CAST(Input::CursorShape);
#endif // INPUT_H
diff --git a/core/os/os.h b/core/os/os.h
index 5dc39b52d6..c9c228cfaf 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -325,6 +325,7 @@ public:
virtual int get_virtual_keyboard_height() const;
virtual void set_cursor_shape(CursorShape p_shape) = 0;
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) = 0;
virtual bool get_swap_ok_cancel() { return false; }
virtual void dump_memory_to_file(const char *p_file);
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index 4b4a7fe9cf..c8562a0570 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -40,7 +40,7 @@ class RingBuffer {
int write_pos;
int size_mask;
- inline int inc(int &p_var, int p_size) {
+ inline int inc(int &p_var, int p_size) const {
int ret = p_var;
p_var += p_size;
p_var = p_var & size_mask;
@@ -50,7 +50,7 @@ class RingBuffer {
public:
T read() {
ERR_FAIL_COND_V(space_left() < 1, T());
- return data[inc(read_pos, 1)];
+ return data.ptr()[inc(read_pos, 1)];
};
int read(T *p_buf, int p_size, bool p_advance = true) {
@@ -63,8 +63,9 @@ public:
int end = pos + to_read;
end = MIN(end, size());
int total = end - pos;
+ const T *read = data.ptr();
for (int i = 0; i < total; i++) {
- p_buf[dst++] = data[pos + i];
+ p_buf[dst++] = read[pos + i];
};
to_read -= total;
pos = 0;
@@ -75,7 +76,7 @@ public:
return p_size;
};
- int copy(T *p_buf, int p_offset, int p_size) {
+ int copy(T *p_buf, int p_offset, int p_size) const {
int left = data_left();
if ((p_offset + p_size) > left) {
@@ -101,7 +102,7 @@ public:
return p_size;
};
- int find(const T &t, int p_offset, int p_max_size) {
+ int find(const T &t, int p_offset, int p_max_size) const {
int left = data_left();
if ((p_offset + p_max_size) > left) {
@@ -164,7 +165,7 @@ public:
return p_size;
};
- inline int space_left() {
+ inline int space_left() const {
int left = read_pos - write_pos;
if (left < 0) {
return size() + left - 1;
@@ -174,11 +175,11 @@ public:
};
return left - 1;
};
- inline int data_left() {
+ inline int data_left() const {
return size() - space_left() - 1;
};
- inline int size() {
+ inline int size() const {
return data.size();
};
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index a2505cbc53..a0a55ce86e 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -129,15 +129,21 @@ static ObjectID safe_get_instance_id(const Variant &p_v) {
void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_variable) {
packet_peer_stream->put_var(p_name);
+
+ Variant var = p_variable;
+ if (p_variable.get_type() == Variant::OBJECT && !ObjectDB::instance_validate(p_variable)) {
+ var = Variant();
+ }
+
int len = 0;
- Error err = encode_variant(p_variable, NULL, len);
+ Error err = encode_variant(var, NULL, len);
if (err != OK)
ERR_PRINT("Failed to encode variant");
if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
packet_peer_stream->put_var(Variant());
} else {
- packet_peer_stream->put_var(p_variable);
+ packet_peer_stream->put_var(var);
}
}
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index a2794e7052..81e823b5db 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -101,9 +101,10 @@ struct _VariantCall {
const Variant *newargs[VARIANT_ARG_MAX];
for (int i = 0; i < p_argcount; i++)
newargs[i] = p_args[i];
- int defargcount = def_argcount;
+ // fill in any remaining parameters with defaults
+ int first_default_arg = arg_count - def_argcount;
for (int i = p_argcount; i < arg_count; i++)
- newargs[i] = &default_args[defargcount - (i - p_argcount) - 1]; //default arguments
+ newargs[i] = &default_args[i - first_default_arg];
#ifdef DEBUG_ENABLED
if (!verify_arguments(newargs, r_error))
return;
diff --git a/doc/classes/@GDScript.xml b/doc/classes/@GDScript.xml
index bee2cdf387..cd05c83347 100644
--- a/doc/classes/@GDScript.xml
+++ b/doc/classes/@GDScript.xml
@@ -535,7 +535,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Loads a resource from the filesystem located at 'path'. Note: resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path".
+ Loads a resource from the filesystem located at [code]path[/code]. Note: resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path".
[codeblock]
# load a scene called main located in the root of the project directory
var main = load("res://main.tscn")
@@ -866,9 +866,10 @@
<argument index="0" name="s" type="float">
</argument>
<description>
- Returns sign of [code]s[/code] -1 or 1.
+ Returns the sign of [code]s[/code]: -1 or 1. Returns 0 if [code]s[/code] is 0.
[codeblock]
sign(-6) # returns -1
+ sign(0) # returns 0
sign(6) # returns 1
[/codeblock]
</description>
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index de5dc18702..6e8b760966 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -93,6 +93,14 @@
<constant name="MARGIN_BOTTOM" value="3" enum="Margin">
Bottom margin, used usually for [Control] or [StyleBox] derived classes.
</constant>
+ <constant name="CORNER_TOP_LEFT" value="0" enum="Corner">
+ </constant>
+ <constant name="CORNER_TOP_RIGHT" value="1" enum="Corner">
+ </constant>
+ <constant name="CORNER_BOTTOM_RIGHT" value="2" enum="Corner">
+ </constant>
+ <constant name="CORNER_BOTTOM_LEFT" value="3" enum="Corner">
+ </constant>
<constant name="VERTICAL" value="1" enum="Orientation">
General vertical alignment, used usually for [Separator], [ScrollBar], [Slider], etc.
</constant>
@@ -1385,5 +1393,57 @@
<constant name="TYPE_MAX" value="27" enum="Variant.Type">
Marker for end of type constants.
</constant>
+ <constant name="OP_EQUAL" value="0" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_NOT_EQUAL" value="1" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_LESS" value="2" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_LESS_EQUAL" value="3" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_GREATER" value="4" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_GREATER_EQUAL" value="5" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_ADD" value="6" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_SUBTRACT" value="7" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_MULTIPLY" value="8" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_DIVIDE" value="9" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_NEGATE" value="10" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_POSITIVE" value="11" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_MODULE" value="12" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_STRING_CONCAT" value="13" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_SHIFT_LEFT" value="14" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_SHIFT_RIGHT" value="15" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_BIT_AND" value="16" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_BIT_OR" value="17" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_BIT_XOR" value="18" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_BIT_NEGATE" value="19" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_AND" value="20" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_OR" value="21" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_XOR" value="22" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_NOT" value="23" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_IN" value="24" enum="Variant.Operator">
+ </constant>
+ <constant name="OP_MAX" value="25" enum="Variant.Operator">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/ARVRServer.xml b/doc/classes/ARVRServer.xml
index ffe6c35240..7f9eedce50 100644
--- a/doc/classes/ARVRServer.xml
+++ b/doc/classes/ARVRServer.xml
@@ -14,7 +14,7 @@
<method name="center_on_hmd">
<return type="void">
</return>
- <argument index="0" name="rotation_mode" type="bool">
+ <argument index="0" name="rotation_mode" type="int" enum="ARVRServer.RotationMode">
</argument>
<argument index="1" name="keep_height" type="bool">
</argument>
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index e0e3261edf..08ac12736a 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -171,7 +171,7 @@
<method name="get_point_connections">
<return type="PoolIntArray">
</return>
- <argument index="0" name="arg0" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
Returns an array with the ids of the points that form the connect with the given point.
diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml
index b351aeac05..b23b608589 100644
--- a/doc/classes/BakedLightmap.xml
+++ b/doc/classes/BakedLightmap.xml
@@ -27,38 +27,28 @@
</method>
</methods>
<members>
- <member name="bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="BakedLightmap.BakeMode">
+ <member name="bake_cell_size" type="float" setter="set_bake_cell_size" getter="get_bake_cell_size">
</member>
- <member name="bake_quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality">
+ <member name="bake_energy" type="float" setter="set_energy" getter="get_energy">
+ </member>
+ <member name="bake_extents" type="Vector3" setter="set_extents" getter="get_extents">
</member>
- <member name="bake_subdiv" type="int" setter="set_bake_subdiv" getter="get_bake_subdiv" enum="BakedLightmap.Subdiv">
+ <member name="bake_hdr" type="bool" setter="set_hdr" getter="is_hdr">
</member>
- <member name="capture_subdiv" type="int" setter="set_capture_subdiv" getter="get_capture_subdiv" enum="BakedLightmap.Subdiv">
+ <member name="bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="BakedLightmap.BakeMode">
</member>
- <member name="energy" type="float" setter="set_energy" getter="get_energy">
+ <member name="bake_propagation" type="float" setter="set_propagation" getter="get_propagation">
</member>
- <member name="extents" type="Vector3" setter="set_extents" getter="get_extents">
+ <member name="bake_quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality">
</member>
- <member name="hdr" type="bool" setter="set_hdr" getter="is_hdr">
+ <member name="capture_cell_size" type="float" setter="set_capture_cell_size" getter="get_capture_cell_size">
</member>
<member name="image_path" type="String" setter="set_image_path" getter="get_image_path">
</member>
<member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data">
</member>
- <member name="propagation" type="float" setter="set_propagation" getter="get_propagation">
- </member>
</members>
<constants>
- <constant name="SUBDIV_128" value="0" enum="Subdiv">
- </constant>
- <constant name="SUBDIV_256" value="1" enum="Subdiv">
- </constant>
- <constant name="SUBDIV_512" value="2" enum="Subdiv">
- </constant>
- <constant name="SUBDIV_1024" value="3" enum="Subdiv">
- </constant>
- <constant name="SUBDIV_MAX" value="4" enum="Subdiv">
- </constant>
<constant name="BAKE_QUALITY_LOW" value="0" enum="BakeQuality">
</constant>
<constant name="BAKE_QUALITY_MEDIUM" value="1" enum="BakeQuality">
diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml
index 91c9ecc774..c2ae9101e1 100644
--- a/doc/classes/Camera.xml
+++ b/doc/classes/Camera.xml
@@ -150,9 +150,6 @@
<member name="v_offset" type="float" setter="set_v_offset" getter="get_v_offset">
The horizontal (Y) offset of the Camear viewport.
</member>
- <member name="vaspect" type="bool" setter="set_vaspect" getter="get_vaspect">
- A boolean representation of [member keep_aspect] in which [code]true[/code] is equivalent to [code]KEEP_WIDTH[/code].
- </member>
</members>
<constants>
<constant name="PROJECTION_PERSPECTIVE" value="0" enum="Projection">
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 54eaf6cc7a..230978950b 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -314,6 +314,22 @@
Loads an image from file [code]path[/code].
</description>
</method>
+ <method name="load_jpg_from_buffer">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="buffer" type="PoolByteArray">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="load_png_from_buffer">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="buffer" type="PoolByteArray">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="lock">
<return type="void">
</return>
@@ -430,65 +446,67 @@
</constant>
<constant name="FORMAT_RGBA5551" value="7" enum="Format">
</constant>
- <constant name="FORMAT_RF" value="8" enum="Format">
+ <constant name="FORMAT_RGB10A2" value="8" enum="Format">
+ </constant>
+ <constant name="FORMAT_RF" value="9" enum="Format">
</constant>
- <constant name="FORMAT_RGF" value="9" enum="Format">
+ <constant name="FORMAT_RGF" value="10" enum="Format">
</constant>
- <constant name="FORMAT_RGBF" value="10" enum="Format">
+ <constant name="FORMAT_RGBF" value="11" enum="Format">
</constant>
- <constant name="FORMAT_RGBAF" value="11" enum="Format">
+ <constant name="FORMAT_RGBAF" value="12" enum="Format">
</constant>
- <constant name="FORMAT_RH" value="12" enum="Format">
+ <constant name="FORMAT_RH" value="13" enum="Format">
</constant>
- <constant name="FORMAT_RGH" value="13" enum="Format">
+ <constant name="FORMAT_RGH" value="14" enum="Format">
</constant>
- <constant name="FORMAT_RGBH" value="14" enum="Format">
+ <constant name="FORMAT_RGBH" value="15" enum="Format">
</constant>
- <constant name="FORMAT_RGBAH" value="15" enum="Format">
+ <constant name="FORMAT_RGBAH" value="16" enum="Format">
</constant>
- <constant name="FORMAT_RGBE9995" value="16" enum="Format">
+ <constant name="FORMAT_RGBE9995" value="17" enum="Format">
</constant>
- <constant name="FORMAT_DXT1" value="17" enum="Format">
+ <constant name="FORMAT_DXT1" value="18" enum="Format">
</constant>
- <constant name="FORMAT_DXT3" value="18" enum="Format">
+ <constant name="FORMAT_DXT3" value="19" enum="Format">
</constant>
- <constant name="FORMAT_DXT5" value="19" enum="Format">
+ <constant name="FORMAT_DXT5" value="20" enum="Format">
</constant>
- <constant name="FORMAT_RGTC_R" value="20" enum="Format">
+ <constant name="FORMAT_RGTC_R" value="21" enum="Format">
</constant>
- <constant name="FORMAT_RGTC_RG" value="21" enum="Format">
+ <constant name="FORMAT_RGTC_RG" value="22" enum="Format">
</constant>
- <constant name="FORMAT_BPTC_RGBA" value="22" enum="Format">
+ <constant name="FORMAT_BPTC_RGBA" value="23" enum="Format">
</constant>
- <constant name="FORMAT_BPTC_RGBF" value="23" enum="Format">
+ <constant name="FORMAT_BPTC_RGBF" value="24" enum="Format">
</constant>
- <constant name="FORMAT_BPTC_RGBFU" value="24" enum="Format">
+ <constant name="FORMAT_BPTC_RGBFU" value="25" enum="Format">
</constant>
- <constant name="FORMAT_PVRTC2" value="25" enum="Format">
+ <constant name="FORMAT_PVRTC2" value="26" enum="Format">
</constant>
- <constant name="FORMAT_PVRTC2A" value="26" enum="Format">
+ <constant name="FORMAT_PVRTC2A" value="27" enum="Format">
</constant>
- <constant name="FORMAT_PVRTC4" value="27" enum="Format">
+ <constant name="FORMAT_PVRTC4" value="28" enum="Format">
</constant>
- <constant name="FORMAT_PVRTC4A" value="28" enum="Format">
+ <constant name="FORMAT_PVRTC4A" value="29" enum="Format">
</constant>
- <constant name="FORMAT_ETC" value="29" enum="Format">
+ <constant name="FORMAT_ETC" value="30" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_R11" value="30" enum="Format">
+ <constant name="FORMAT_ETC2_R11" value="31" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_R11S" value="31" enum="Format">
+ <constant name="FORMAT_ETC2_R11S" value="32" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_RG11" value="32" enum="Format">
+ <constant name="FORMAT_ETC2_RG11" value="33" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_RG11S" value="33" enum="Format">
+ <constant name="FORMAT_ETC2_RG11S" value="34" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_RGB8" value="34" enum="Format">
+ <constant name="FORMAT_ETC2_RGB8" value="35" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_RGBA8" value="35" enum="Format">
+ <constant name="FORMAT_ETC2_RGBA8" value="36" enum="Format">
</constant>
- <constant name="FORMAT_ETC2_RGB8A1" value="36" enum="Format">
+ <constant name="FORMAT_ETC2_RGB8A1" value="37" enum="Format">
</constant>
- <constant name="FORMAT_MAX" value="37" enum="Format">
+ <constant name="FORMAT_MAX" value="38" enum="Format">
</constant>
<constant name="INTERPOLATE_NEAREST" value="0" enum="Interpolation">
</constant>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 1200ac5170..79dc45fa1f 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -275,9 +275,12 @@
</return>
<argument index="0" name="image" type="Resource">
</argument>
- <argument index="1" name="hotspot" type="Vector2" default="Vector2( 0, 0 )">
+ <argument index="1" name="shape" type="int" enum="Input.CursorShape" default="0">
+ </argument>
+ <argument index="2" name="hotspot" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
+ Set a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified. See enum [code]CURSOR_*[/code] for the list of shapes.
</description>
</method>
<method name="set_mouse_mode">
@@ -347,5 +350,39 @@
</constant>
<constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode">
</constant>
+ <constant name="CURSOR_ARROW" value="0" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_IBEAM" value="1" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_POINTING_HAND" value="2" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_CROSS" value="3" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_WAIT" value="4" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_BUSY" value="5" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_DRAG" value="6" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_CAN_DROP" value="7" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_FORBIDDEN" value="8" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_VSIZE" value="9" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_HSIZE" value="10" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_BDIAGSIZE" value="11" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_FDIAGSIZE" value="12" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_MOVE" value="13" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_VSPLIT" value="14" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_HSPLIT" value="15" enum="CursorShape">
+ </constant>
+ <constant name="CURSOR_HELP" value="16" enum="CursorShape">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml
index cc31da0627..a8abe60f78 100644
--- a/doc/classes/InputEvent.xml
+++ b/doc/classes/InputEvent.xml
@@ -28,13 +28,6 @@
Returns a [String] representation of the event.
</description>
</method>
- <method name="get_id" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the event's ID.
- </description>
- </method>
<method name="is_action" qualifiers="const">
<return type="bool">
</return>
@@ -83,14 +76,6 @@
Returns [code]true[/code] if this input event is pressed. Not relevant for the event types [code]MOUSE_MOTION[/code], [code]SCREEN_DRAG[/code] or [code]NONE[/code].
</description>
</method>
- <method name="set_id">
- <return type="void">
- </return>
- <argument index="0" name="id" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="shortcut_match" qualifiers="const">
<return type="bool">
</return>
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index 22231cfdf3..af681c9456 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -18,6 +18,14 @@
Return the [PopupMenu] contained in this button.
</description>
</method>
+ <method name="set_disable_shortcuts">
+ <return type="void">
+ </return>
+ <argument index="0" name="disabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<signals>
<signal name="about_to_show">
diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml
index 81978809d7..ae2a67312e 100644
--- a/doc/classes/Node2D.xml
+++ b/doc/classes/Node2D.xml
@@ -157,7 +157,7 @@
<member name="transform" type="Transform2D" setter="set_transform" getter="get_transform">
Local [Transform2D].
</member>
- <member name="z" type="int" setter="set_z" getter="get_z">
+ <member name="z_index" type="int" setter="set_z_index" getter="get_z_index">
Z-index. Controls the order in which the nodes render. A node with a higher Z-index will display in front of others.
</member>
<member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative">
diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml
index 67f5f84a49..8bad396b84 100644
--- a/doc/classes/Physics2DServer.xml
+++ b/doc/classes/Physics2DServer.xml
@@ -216,7 +216,7 @@
<argument index="2" name="disable" type="bool">
</argument>
<description>
- Disables a given shape in this area if [code]disable is true[/code]
+ Disables a given shape in an area.
</description>
</method>
<method name="area_set_shape_transform">
@@ -638,7 +638,7 @@
<argument index="2" name="enable" type="bool">
</argument>
<description>
- Enables one way collision on body if [code]enable is true[/code].
+ Enables one way collision on body if [code]enable[/code] is [code]true[/code].
</description>
</method>
<method name="body_set_shape_disabled">
@@ -651,7 +651,7 @@
<argument index="2" name="disable" type="bool">
</argument>
<description>
- Disables shape in body if [code]disable is true[/code].
+ Disables shape in body if [code]disable[/code] is [code]true[/code].
</description>
</method>
<method name="body_set_shape_metadata">
@@ -1135,6 +1135,12 @@
<constant name="JOINT_DAMPED_SPRING" value="2" enum="JointType">
Constant to create damped spring joints.
</constant>
+ <constant name="JOINT_PARAM_BIAS" value="0" enum="JointParam">
+ </constant>
+ <constant name="JOINT_PARAM_MAX_BIAS" value="1" enum="JointParam">
+ </constant>
+ <constant name="JOINT_PARAM_MAX_FORCE" value="2" enum="JointParam">
+ </constant>
<constant name="DAMPED_STRING_REST_LENGTH" value="0" enum="DampedStringParam">
Set the resting length of the spring joint. The joint will always try to go to back this length when pulled apart.
</constant>
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index a78fe03cab..3a4b843b06 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -302,6 +302,14 @@
<description>
</description>
</method>
+ <method name="set_quit_on_go_back">
+ <return type="void">
+ </return>
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_refuse_new_network_connections">
<return type="void">
</return>
@@ -402,13 +410,13 @@
</signal>
</signals>
<constants>
- <constant name="GROUP_CALL_DEFAULT" value="0" enum="CallGroupFlags">
+ <constant name="GROUP_CALL_DEFAULT" value="0" enum="GroupCallFlags">
</constant>
- <constant name="GROUP_CALL_REVERSE" value="1" enum="CallGroupFlags">
+ <constant name="GROUP_CALL_REVERSE" value="1" enum="GroupCallFlags">
</constant>
- <constant name="GROUP_CALL_REALTIME" value="2" enum="CallGroupFlags">
+ <constant name="GROUP_CALL_REALTIME" value="2" enum="GroupCallFlags">
</constant>
- <constant name="GROUP_CALL_UNIQUE" value="4" enum="CallGroupFlags">
+ <constant name="GROUP_CALL_UNIQUE" value="4" enum="GroupCallFlags">
</constant>
<constant name="STRETCH_MODE_DISABLED" value="0" enum="StretchMode">
</constant>
diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml
index 81b0b3d0c3..1e1a8d516e 100644
--- a/doc/classes/ScriptEditor.xml
+++ b/doc/classes/ScriptEditor.xml
@@ -12,11 +12,11 @@
<method name="can_drop_data_fw" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="arg0" type="Vector2">
+ <argument index="0" name="point" type="Vector2">
</argument>
- <argument index="1" name="arg1" type="Variant">
+ <argument index="1" name="data" type="Variant">
</argument>
- <argument index="2" name="arg2" type="Control">
+ <argument index="2" name="from" type="Control">
</argument>
<description>
</description>
@@ -24,11 +24,11 @@
<method name="drop_data_fw">
<return type="void">
</return>
- <argument index="0" name="arg0" type="Vector2">
+ <argument index="0" name="point" type="Vector2">
</argument>
- <argument index="1" name="arg1" type="Variant">
+ <argument index="1" name="data" type="Variant">
</argument>
- <argument index="2" name="arg2" type="Control">
+ <argument index="2" name="from" type="Control">
</argument>
<description>
</description>
@@ -43,9 +43,9 @@
<method name="get_drag_data_fw">
<return type="Variant">
</return>
- <argument index="0" name="arg0" type="Vector2">
+ <argument index="0" name="point" type="Vector2">
</argument>
- <argument index="1" name="arg1" type="Control">
+ <argument index="1" name="from" type="Control">
</argument>
<description>
</description>
diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml
index 7940e4065e..d0addcf9f9 100644
--- a/doc/classes/Spatial.xml
+++ b/doc/classes/Spatial.xml
@@ -34,7 +34,7 @@
Returns the current [World] resource this Spatial node is registered to.
</description>
</method>
- <method name="rotate_object_local">
+ <method name="global_rotate">
<return type="void">
</return>
<argument index="0" name="axis" type="Vector3">
@@ -42,27 +42,15 @@
<argument index="1" name="angle" type="float">
</argument>
<description>
- Rotates the local transformation around axis, a unit [Vector3], by specified angle in radians. The rotation axis is in object-local coordinate system.
+ Rotates the global (world) transformation around axis, a unit [Vector3], by specified angle in radians. The rotation axis is in global coordinate system.
</description>
</method>
- <method name="scale_object_local">
+ <method name="global_scale">
<return type="void">
</return>
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
- Scales the local transformation by given 3D scale factors in object-local coordinate system.
- </description>
- </method>
- <method name="global_rotate">
- <return type="void">
- </return>
- <argument index="0" name="axis" type="Vector3">
- </argument>
- <argument index="1" name="angle" type="float">
- </argument>
- <description>
- Rotates the global (world) transformation around axis, a unit [Vector3], by specified angle in radians. The rotation axis is in global coordinate system.
</description>
</method>
<method name="global_translate">
@@ -151,6 +139,17 @@
Rotates the local transformation around axis, a unit [Vector3], by specified angle in radians.
</description>
</method>
+ <method name="rotate_object_local">
+ <return type="void">
+ </return>
+ <argument index="0" name="axis" type="Vector3">
+ </argument>
+ <argument index="1" name="angle" type="float">
+ </argument>
+ <description>
+ Rotates the local transformation around axis, a unit [Vector3], by specified angle in radians. The rotation axis is in object-local coordinate system.
+ </description>
+ </method>
<method name="rotate_x">
<return type="void">
</return>
@@ -178,6 +177,15 @@
Rotates the local transformation around the Z axis by angle in radians.
</description>
</method>
+ <method name="scale_object_local">
+ <return type="void">
+ </return>
+ <argument index="0" name="scale" type="Vector3">
+ </argument>
+ <description>
+ Scales the local transformation by given 3D scale factors in object-local coordinate system.
+ </description>
+ </method>
<method name="set_as_toplevel">
<return type="void">
</return>
@@ -264,6 +272,14 @@
Changes the node's position by given offset [Vector3].
</description>
</method>
+ <method name="translate_object_local">
+ <return type="void">
+ </return>
+ <argument index="0" name="offset" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="update_gizmo">
<return type="void">
</return>
diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml
index d757b6f2d8..8ecd9e5816 100644
--- a/doc/classes/StreamPeer.xml
+++ b/doc/classes/StreamPeer.xml
@@ -105,7 +105,7 @@
<return type="int">
</return>
<description>
- Get an unsigned 16 bit value from the stream.
+ Get an unsigned 64 bit value from the stream.
</description>
</method>
<method name="get_u8">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index ab722a24c3..f4d80c46b4 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -213,7 +213,7 @@
<method name="is_line_hidden" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="arg0" type="int">
+ <argument index="0" name="line" type="int">
</argument>
<description>
</description>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index a09f6b6dc3..daba0a0fc1 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -185,7 +185,7 @@
<method name="update_bitmask_area">
<return type="void">
</return>
- <argument index="0" name="arg0" type="Vector2">
+ <argument index="0" name="position" type="Vector2">
</argument>
<description>
Applies autotiling rules to the cell (and its adjacent cells) referenced by its grid-based X and Y coordinates.
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index 3dbf172c5a..716f89eab6 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -39,7 +39,7 @@
<method name="autotile_get_bitmask_mode" qualifiers="const">
<return type="int" enum="TileSet.BitmaskMode">
</return>
- <argument index="0" name="arg0" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
</description>
@@ -47,9 +47,9 @@
<method name="autotile_set_bitmask_mode">
<return type="void">
</return>
- <argument index="0" name="mode" type="int">
+ <argument index="0" name="id" type="int">
</argument>
- <argument index="1" name="arg1" type="int" enum="TileSet.BitmaskMode">
+ <argument index="1" name="mode" type="int" enum="TileSet.BitmaskMode">
</argument>
<description>
</description>
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 11bd3b3b86..e26082c47e 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -41,6 +41,8 @@
</return>
<argument index="0" name="parent" type="Object" default="null">
</argument>
+ <argument index="1" name="idx" type="int" default="-1">
+ </argument>
<description>
Create an item in the tree and add it as the last child of [code]parent[/code]. If parent is not given, it will be added as the root's last child, or it'll the be the root itself if the tree is empty.
</description>
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 5ce544ecfb..d35d624589 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -6943,6 +6943,10 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
glDeleteTextures(1, &cls->distance);
canvas_light_shadow_owner.free(p_rid);
memdelete(cls);
+ } else if (particles_owner.owns(p_rid)) {
+ Particles *particles = particles_owner.get(p_rid);
+ particles_owner.free(p_rid);
+ memdelete(particles);
} else {
return false;
}
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index cc4d060c02..fa8094f31a 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -298,7 +298,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
args.push_back(0);
#ifdef __FreeBSD__
- if (p_path.find("/")) {
+ if (p_path.find("/") != -1) {
// exec name contains path so use it
execv(p_path.utf8().get_data(), &args[0]);
} else {
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 256fe302d7..4b59656903 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1251,7 +1251,7 @@ CodeTextEditor::CodeTextEditor() {
error = memnew(Label);
status_bar->add_child(error);
- error->set_clip_text(true); //do not change, or else very long errors can push the whole container to the right
+ error->set_autowrap(true);
error->set_valign(Label::VALIGN_CENTER);
error->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
error->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index a601c8cd2b..96c3a27ea7 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -37,7 +37,7 @@
#include "print_string.h"
#include "scene/gui/box_container.h"
-void CreateDialog::popup_create(bool p_dontclear) {
+void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {
recent->clear();
@@ -89,11 +89,12 @@ void CreateDialog::popup_create(bool p_dontclear) {
popup_centered_ratio();
}
- if (p_dontclear)
+ if (p_dont_clear) {
search_box->select_all();
- else {
+ } else {
search_box->clear();
}
+
search_box->grab_focus();
_update_search();
@@ -104,8 +105,19 @@ void CreateDialog::popup_create(bool p_dontclear) {
if (enable_rl) {
search_options->add_constant_override("draw_relationship_lines", 1);
search_options->add_color_override("relationship_line_color", rl_color);
- } else
+ } else {
search_options->add_constant_override("draw_relationship_lines", 0);
+ }
+
+ is_replace_mode = p_replace_mode;
+
+ if (p_replace_mode) {
+ set_title(vformat(TTR("Change %s Type"), base_type));
+ get_ok()->set_text(TTR("Change"));
+ } else {
+ set_title(vformat(TTR("Create New %s"), base_type));
+ get_ok()->set_text(TTR("Create"));
+ }
}
void CreateDialog::_text_changed(const String &p_newtext) {
@@ -369,7 +381,11 @@ void CreateDialog::_notification(int p_what) {
void CreateDialog::set_base_type(const String &p_base) {
base_type = p_base;
- set_title(vformat(TTR("Create New %s"), p_base));
+ if (is_replace_mode)
+ set_title(vformat(TTR("Change %s Type"), p_base));
+ else
+ set_title(vformat(TTR("Create New %s"), p_base));
+
_update_search();
}
@@ -624,6 +640,8 @@ void CreateDialog::_bind_methods() {
CreateDialog::CreateDialog() {
+ is_replace_mode = false;
+
ClassDB::get_class_list(&type_list);
type_list.sort_custom<StringName::AlphCompare>();
@@ -678,7 +696,6 @@ CreateDialog::CreateDialog() {
search_box->connect("gui_input", this, "_sbox_input");
search_options = memnew(Tree);
vbc->add_margin_child(TTR("Matches:"), search_options, true);
- get_ok()->set_text(TTR("Create"));
get_ok()->set_disabled(true);
register_text_enter(search_box);
set_hide_on_ok(false);
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index 56ba7f8a3e..ed23fb4ae8 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -52,6 +52,7 @@ class CreateDialog : public ConfirmationDialog {
Button *favorite;
LineEdit *search_box;
Tree *search_options;
+ bool is_replace_mode;
String base_type;
String preferred_search_result_type;
EditorHelpBit *help_bit;
@@ -97,7 +98,7 @@ public:
void set_preferred_search_result_type(const String &p_preferred_type);
String get_preferred_search_result_type();
- void popup_create(bool p_dontclear);
+ void popup_create(bool p_dont_clear, bool p_replace_mode = false);
CreateDialog();
};
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 1d6d933924..7fa4776141 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -131,7 +131,8 @@ EditorAbout::EditorAbout() {
Label *about_text = memnew(Label);
about_text->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
- about_text->set_text(VERSION_FULL_NAME + hash + String::utf8("\n\xc2\xa9 2007-2018 Juan Linietsky, Ariel Manzur.\n\xc2\xa9 2014-2017 ") +
+ about_text->set_text(VERSION_FULL_NAME + hash +
+ String::utf8("\n\xc2\xa9 2007-2018 Juan Linietsky, Ariel Manzur.\n\xc2\xa9 2014-2018 ") +
TTR("Godot Engine contributors") + "\n");
hbc->add_child(about_text);
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index f2882561aa..c50995fc2b 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -77,12 +77,27 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p
Ref<DynamicFont> m_name; \
m_name.instance(); \
m_name->set_size(m_size); \
- m_name->set_font_data(DefaultFont); \
+ if (CustomFont.is_valid()) { \
+ m_name->set_font_data(CustomFont); \
+ m_name->add_fallback(DefaultFont); \
+ } else { \
+ m_name->set_font_data(DefaultFont); \
+ } \
m_name->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); \
m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); \
MAKE_FALLBACKS(m_name);
void editor_register_fonts(Ref<Theme> p_theme) {
+ /* Custom font */
+
+ String custom_font = EditorSettings::get_singleton()->get("interface/editor/custom_font");
+ Ref<DynamicFontData> CustomFont;
+ if (custom_font.length() > 0) {
+ CustomFont.instance();
+ CustomFont->set_font_path(custom_font);
+ CustomFont->set_force_autohinter(true); //just looks better..i think?
+ }
+
/* Droid Sans */
Ref<DynamicFontData> DefaultFont;
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index cf19af7ef6..1b885adf37 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "editor_log.h"
+#include "core/os/keyboard.h"
#include "editor_node.h"
#include "scene/gui/center_container.h"
#include "scene/resources/dynamic_font.h"
@@ -154,6 +155,7 @@ EditorLog::EditorLog() {
clearbutton = memnew(Button);
hb->add_child(clearbutton);
clearbutton->set_text(TTR("Clear"));
+ clearbutton->set_shortcut(ED_SHORTCUT("editor/clear_output", TTR("Clear Output"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K));
clearbutton->connect("pressed", this, "_clear_request");
log = memnew(RichTextLabel);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index bd37e7d0be..b52161813d 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4419,10 +4419,11 @@ void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_current_path());
DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Vector<String> just_copy = String("ttf,otf").split(",");
for (int i = 0; i < p_files.size(); i++) {
String from = p_files[i];
- if (!ResourceFormatImporter::get_singleton()->can_be_imported(from)) {
+ if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) != -1)) {
continue;
}
String to = to_path.plus_file(from.get_file());
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 5a16ec7eab..dc82a02f46 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -277,7 +277,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/source_font_size", 14);
hints["interface/editor/source_font_size"] = PropertyInfo(Variant::INT, "interface/editor/source_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/custom_font", "");
- hints["interface/editor/custom_font"] = PropertyInfo(Variant::STRING, "interface/editor/custom_font", PROPERTY_HINT_GLOBAL_FILE, "*.font,*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/editor/custom_font"] = PropertyInfo(Variant::STRING, "interface/editor/custom_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/dim_editor_on_dialog_popup", true);
_initial_set("interface/editor/dim_amount", 0.6f);
hints["interface/editor/dim_amount"] = PropertyInfo(Variant::REAL, "interface/editor/dim_amount", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 3644893663..b19d015455 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1135,16 +1135,5 @@ Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) {
theme = create_editor_theme(p_theme);
}
- String global_font = EditorSettings::get_singleton()->get("interface/editor/custom_font");
- if (global_font != "") {
- Ref<Font> fnt = ResourceLoader::load(global_font);
- if (fnt.is_valid()) {
- if (!theme.is_valid()) {
- theme.instance();
- }
- theme->set_default_theme_font(fnt);
- }
- }
-
return theme;
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 949455ff98..b18cd6b747 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -819,7 +819,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
print_line("Duplicating " + old_path + " -> " + new_path);
- Error err = da->copy(old_path, new_path);
+ Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path);
if (err == OK) {
//Move/Rename any corresponding import settings too
if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
@@ -980,10 +980,12 @@ void FileSystemDock::_duplicate_operation_confirm() {
return;
}
- String old_path = to_duplicate.path.ends_with("/") ? to_duplicate.path.substr(0, to_duplicate.path.length() - 1) : to_rename.path;
- String new_path = old_path.get_base_dir().plus_file(new_name);
- if (old_path == new_path) {
- return;
+ String new_path;
+ String base_dir = to_duplicate.path.get_base_dir();
+ if (to_duplicate.is_file) {
+ new_path = base_dir.plus_file(new_name);
+ } else {
+ new_path = base_dir.substr(0, base_dir.find_last("/")) + "/" + new_name;
}
//Present a more user friendly warning for name conflict
@@ -995,7 +997,7 @@ void FileSystemDock::_duplicate_operation_confirm() {
}
memdelete(da);
- _try_duplicate_item(to_duplicate, new_name);
+ _try_duplicate_item(to_duplicate, new_path);
//Rescan everything
print_line("call rescan!");
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 53b52c5f1b..a52c914096 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -612,6 +612,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
if (Object::cast_to<Viewport>(p_node))
return;
+ const real_t grab_distance = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
@@ -630,14 +631,17 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !Object::cast_to<CanvasLayer>(c)) {
Rect2 rect = c->_edit_get_rect();
- Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos);
+ Transform2D to_local = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse();
+ Point2 local_pos = to_local.xform(p_pos);
+ const real_t local_grab_distance = (to_local.xform(p_pos + Vector2(grab_distance, 0)) - local_pos).length();
+ Rect2 local_pos_rect = Rect2(local_pos, Vector2(0, 0)).grow(local_grab_distance);
- if (rect.has_point(local_pos)) {
+ if (rect.intersects(local_pos_rect) && c->_edit_is_selected_on_click(local_pos, local_grab_distance)) {
Node2D *node = Object::cast_to<Node2D>(c);
_SelectResult res;
res.item = c;
- res.z = node ? node->get_z() : 0;
+ res.z_index = node ? node->get_z_index() : 0;
res.has_z = node;
r_items.push_back(res);
}
@@ -3464,7 +3468,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree())
continue;
if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
@@ -3482,7 +3486,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree())
continue;
if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
@@ -3502,7 +3506,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree())
continue;
if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
@@ -3520,7 +3524,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree())
continue;
if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index f14f1a92a6..0866fe77aa 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -252,10 +252,10 @@ class CanvasItemEditor : public VBoxContainer {
struct _SelectResult {
CanvasItem *item;
- float z;
+ float z_index;
bool has_z;
_FORCE_INLINE_ bool operator<(const _SelectResult &p_rr) const {
- return has_z && p_rr.has_z ? p_rr.z < z : p_rr.has_z;
+ return has_z && p_rr.has_z ? p_rr.z_index < z_index : p_rr.has_z;
}
};
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index c865ddd4b0..3be68f21af 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -347,7 +347,8 @@ void CurveEditor::open_context_menu(Vector2 pos) {
_context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LINEAR), is_linear);
} else {
- _context_menu->add_separator();
+ if (_selected_point > 0 || _selected_point + 1 < _curve_ref->get_point_count())
+ _context_menu->add_separator();
if (_selected_point > 0) {
_context_menu->add_check_item(TTR("Left linear"), CONTEXT_LEFT_LINEAR);
@@ -367,6 +368,7 @@ void CurveEditor::open_context_menu(Vector2 pos) {
_context_menu->add_submenu_item(TTR("Load preset"), _presets_menu->get_name());
+ _context_menu->set_size(Size2(0, 0));
_context_menu->popup();
}
@@ -566,7 +568,6 @@ static void plot_curve_accurate(const Curve &curve, float step, T plot_func) {
Vector2 prev_pos = a;
float len = b.x - a.x;
- //float step = 4.f / view_size.x;
for (float x = step; x < len; x += step) {
pos.x = a.x + x;
@@ -694,24 +695,6 @@ void CurveEditor::_draw() {
CanvasItemPlotCurve plot_func(*this, line_color, edge_line_color);
plot_curve_accurate(curve, 4.f / view_size.x, plot_func);
- /*// TEST draw baked curve
- {
- Vector2 pos = Vector2(0, curve.interpolate_baked(0));
- Vector2 prev_pos = pos;
-
- float len = 1.0;
- float step = 4.f / view_size.x;
-
- for(float x = step; x < len; x += step) {
- pos.x = x;
- pos.y = curve.interpolate_baked(x);
- draw_line(get_point_view_pos(prev_pos), get_point_view_pos(pos), Color(0,1,0));
- prev_pos = pos;
- }
-
- draw_line(get_point_view_pos(prev_pos), get_point_view_pos(Vector2(1, curve.interpolate_baked(1))), Color(0,1,0));
- }//*/
-
// Draw points
draw_set_transform_matrix(Transform2D());
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 73fd64f8db..bc29c92d7f 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1027,6 +1027,15 @@ void ScriptEditor::_menu_option(int p_option) {
case FILE_COPY_PATH: {
_copy_script_path();
} break;
+ case SHOW_IN_FILE_SYSTEM: {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(tab_container->get_current_tab()));
+ Ref<Script> script = se->get_edited_script();
+ FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock();
+ file_system_dock->navigate_to_path(script->get_path());
+ // Ensure that the FileSystem dock is visible.
+ TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control();
+ tab_container->set_current_tab(file_system_dock->get_position_in_parent());
+ } break;
case CLOSE_DOCS: {
_close_docs_tab();
} break;
@@ -2164,7 +2173,7 @@ void ScriptEditor::_make_script_list_context_menu() {
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/copy_path"), FILE_COPY_PATH);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
-
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/show_in_file_system"), SHOW_IN_FILE_SYSTEM);
Ref<Script> scr = se->get_edited_script();
if (!scr.is_null() && scr->is_tool()) {
context_menu->add_separator();
@@ -2613,6 +2622,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy_path", TTR("Copy Script Path")), FILE_COPY_PATH);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show In File System")), SHOW_IN_FILE_SYSTEM);
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Prev"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV);
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 3305147442..d90cf7b912 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -137,6 +137,7 @@ class ScriptEditor : public PanelContainer {
CLOSE_ALL,
CLOSE_OTHER_TABS,
TOGGLE_SCRIPTS_PANEL,
+ SHOW_IN_FILE_SYSTEM,
FILE_COPY_PATH,
FILE_TOOL_RELOAD,
FILE_TOOL_RELOAD_SOFT,
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index da507db5da..eccb11ba12 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -333,7 +333,7 @@ AutotileEditor::AutotileEditor(EditorNode *p_editor) {
autotile_list = memnew(ItemList);
autotile_list->set_v_size_flags(SIZE_EXPAND_FILL);
autotile_list->set_h_size_flags(SIZE_EXPAND_FILL);
- autotile_list->set_custom_minimum_size(Size2(02, 200));
+ autotile_list->set_custom_minimum_size(Size2(10, 200));
autotile_list->connect("item_selected", this, "_on_autotile_selected");
split->add_child(autotile_list);
@@ -531,7 +531,7 @@ AutotileEditor::AutotileEditor(EditorNode *p_editor) {
main_vb->add_child(toolbar);
- ScrollContainer *scroll = memnew(ScrollContainer);
+ scroll = memnew(ScrollContainer);
main_vb->add_child(scroll);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -619,6 +619,7 @@ void AutotileEditor::_on_edit_mode_changed(int p_edit_mode) {
tool_containers[TOOLBAR_BITMASK]->hide();
tool_containers[TOOLBAR_SHAPE]->show();
tools[TOOL_SELECT]->set_tooltip(TTR("Select current edited sub-tile."));
+ current_shape = PoolVector2Array();
spin_priority->hide();
} break;
default: {
@@ -1061,20 +1062,43 @@ void AutotileEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
} else {
int t_id = get_current_tile();
if (t_id >= 0) {
- Vector<TileSet::ShapeData> sd = tile_set->tile_get_shapes(t_id);
- for (int i = 0; i < sd.size(); i++) {
- if (sd[i].autotile_coord == edited_shape_coord) {
- Ref<ConvexPolygonShape2D> shape = sd[i].shape;
+ if (edit_mode == EDITMODE_COLLISION) {
+ Vector<TileSet::ShapeData> sd = tile_set->tile_get_shapes(t_id);
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].autotile_coord == edited_shape_coord) {
+ Ref<ConvexPolygonShape2D> shape = sd[i].shape;
+
+ if (!shape.is_null()) {
+ sd.remove(i);
+ tile_set->tile_set_shapes(get_current_tile(), sd);
+ edited_collision_shape = Ref<Shape2D>();
+ workspace->update();
+ }
+ break;
+ }
+ }
+ } else if (edit_mode == EDITMODE_OCCLUSION) {
+ Map<Vector2, Ref<OccluderPolygon2D> > map = tile_set->autotile_get_light_oclusion_map(t_id);
+ for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = map.front(); E; E = E->next()) {
+ if (E->key() == edited_shape_coord) {
+ tile_set->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+ break;
+ }
+ }
- if (!shape.is_null()) {
- sd.remove(i);
- tile_set->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape = Ref<Shape2D>();
- current_shape.resize(0);
- workspace->update();
+ edited_occlusion_shape = Ref<OccluderPolygon2D>();
+ workspace->update();
+ } else if (edit_mode == EDITMODE_NAVIGATION) {
+ Map<Vector2, Ref<NavigationPolygon> > map = tile_set->autotile_get_navigation_map(t_id);
+ for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) {
+ if (E->key() == edited_shape_coord) {
+ tile_set->autotile_set_navigation_polygon(t_id, Ref<NavigationPolygon>(), edited_shape_coord);
+ break;
}
- break;
}
+
+ edited_navigation_shape = Ref<NavigationPolygon>();
+ workspace->update();
}
}
@@ -1095,6 +1119,16 @@ void AutotileEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
} break;
}
+
+ //Drag Middle Mouse
+ if (mm.is_valid()) {
+ if (mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
+
+ Vector2 dragged(mm->get_relative().x, mm->get_relative().y);
+ scroll->set_h_scroll(scroll->get_h_scroll() - dragged.x * workspace->get_scale().x);
+ scroll->set_v_scroll(scroll->get_v_scroll() - dragged.y * workspace->get_scale().x);
+ }
+ }
}
}
@@ -1453,11 +1487,20 @@ void AutotileEditor::close_shape(const Vector2 &shape_anchor) {
Ref<ConvexPolygonShape2D> shape = memnew(ConvexPolygonShape2D);
Vector<Vector2> segments;
+ float p_total = 0;
for (int i = 0; i < current_shape.size(); i++) {
segments.push_back(current_shape[i] - shape_anchor);
+
+ if (i != current_shape.size() - 1)
+ p_total += ((current_shape[i + 1].x - current_shape[i].x) * (-current_shape[i + 1].y + (-current_shape[i].y)));
+ else
+ p_total += ((current_shape[0].x - current_shape[i].x) * (-current_shape[0].y + (-current_shape[i].y)));
}
+ if (p_total < 0)
+ segments.invert();
+
shape->set_points(segments);
tile_set->tile_add_shape(get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 7d9558d4e7..0f66f04cb1 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -86,6 +86,7 @@ class AutotileEditor : public Control {
int current_item_index;
Sprite *preview;
+ ScrollContainer *scroll;
Control *workspace_container;
Control *workspace;
Button *tool_editmode[EDITMODE_MAX];
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 0411656857..eb5cec2a2e 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -89,33 +89,50 @@ private:
String created_folder_path;
void set_message(const String &p_msg, MessageType p_type = MESSAGE_SUCCESS) {
+
msg->set_text(p_msg);
- if (p_msg == "") {
- status_btn->set_icon(get_icon("StatusSuccess", "EditorIcons"));
- return;
- }
- msg->hide();
+ Ref<Texture> current_icon = status_btn->get_icon();
+
switch (p_type) {
- case MESSAGE_ERROR:
+
+ case MESSAGE_ERROR: {
+
msg->add_color_override("font_color", get_color("error_color", "Editor"));
- status_btn->set_icon(get_icon("StatusError", "EditorIcons"));
- msg->show();
- break;
- case MESSAGE_WARNING:
+ Ref<Texture> new_icon = get_icon("StatusError", "EditorIcons");
+ if (current_icon != new_icon) {
+
+ status_btn->set_icon(new_icon);
+ msg->show();
+ }
+ } break;
+ case MESSAGE_WARNING: {
+
msg->add_color_override("font_color", get_color("warning_color", "Editor"));
- status_btn->set_icon(get_icon("StatusWarning", "EditorIcons"));
- break;
- case MESSAGE_SUCCESS:
+ Ref<Texture> new_icon = get_icon("StatusWarning", "EditorIcons");
+ if (current_icon != new_icon) {
+
+ status_btn->set_icon(new_icon);
+ if (current_icon != get_icon("StatusSuccess", "EditorIcons"))
+ msg->hide();
+ }
+ } break;
+ case MESSAGE_SUCCESS: {
+
msg->add_color_override("font_color", get_color("success_color", "Editor"));
- status_btn->set_icon(get_icon("StatusSuccess", "EditorIcons"));
- break;
+ Ref<Texture> new_icon = get_icon("StatusSuccess", "EditorIcons");
+ if (current_icon != new_icon) {
+
+ status_btn->set_icon(new_icon);
+ msg->hide();
+ }
+ } break;
}
+
+ set_size(Size2(500, 0) * EDSCALE);
}
String _test_path() {
- set_message(" ");
- get_ok()->set_disabled(true);
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String valid_path;
if (d->change_dir(project_path->get_text()) == OK) {
@@ -127,6 +144,7 @@ private:
if (valid_path == "") {
set_message(TTR("The path does not exist."), MESSAGE_ERROR);
memdelete(d);
+ get_ok()->set_disabled(true);
return "";
}
@@ -136,6 +154,7 @@ private:
set_message(TTR("Please choose a 'project.godot' file."), MESSAGE_ERROR);
memdelete(d);
+ get_ok()->set_disabled(true);
return "";
}
@@ -155,19 +174,22 @@ private:
d->list_dir_end();
if (!is_empty) {
+
set_message(TTR("Your project will be created in a non empty folder (you might want to create a new folder)."), MESSAGE_WARNING);
+ memdelete(d);
+ get_ok()->set_disabled(false);
+ return valid_path;
}
- } else {
-
- if (d->file_exists("project.godot")) {
+ } else if (d->file_exists("project.godot")) {
- set_message(TTR("Please choose a folder that does not contain a 'project.godot' file."), MESSAGE_ERROR);
- memdelete(d);
- return "";
- }
+ set_message(TTR("Please choose a folder that does not contain a 'project.godot' file."), MESSAGE_ERROR);
+ memdelete(d);
+ get_ok()->set_disabled(true);
+ return "";
}
+ set_message(TTR("That's a BINGO!"));
memdelete(d);
get_ok()->set_disabled(false);
return valid_path;
@@ -213,7 +235,6 @@ private:
}
String sp = p.simplify_path();
project_path->set_text(sp);
- set_message(" "); // just so it does not disappear
get_ok()->call_deferred("grab_focus");
}
@@ -242,21 +263,32 @@ private:
void _create_folder() {
- if (project_name->get_text() == "" || created_folder_path != "") {
+ if (project_name->get_text() == "" || created_folder_path != "")
return;
- }
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (d->change_dir(project_path->get_text()) == OK) {
+
if (!d->dir_exists(project_name->get_text())) {
+
if (d->make_dir(project_name->get_text()) == OK) {
+
d->change_dir(project_name->get_text());
project_path->set_text(d->get_current_dir());
created_folder_path = d->get_current_dir();
create_dir->set_disabled(true);
+ } else {
+
+ dialog_error->set_text(TTR("Couldn't create folder."));
+ dialog_error->popup_centered_minsize();
}
+ } else {
+
+ dialog_error->set_text(TTR("There is already a folder in this path with the specified name."));
+ dialog_error->popup_centered_minsize();
}
}
+
memdelete(d);
}
@@ -337,6 +369,7 @@ private:
if (!pkg) {
dialog_error->set_text(TTR("Error opening package file, not in zip format."));
+ dialog_error->popup_centered_minsize();
return;
}
@@ -448,7 +481,10 @@ private:
}
void _toggle_message() {
+
msg->set_visible(!msg->is_visible());
+ if (!msg->is_visible())
+ set_size(Size2(500, 0) * EDSCALE);
}
void cancel_pressed() {
@@ -457,6 +493,15 @@ private:
project_path->clear();
project_name->clear();
+
+ if (status_btn->get_icon() == get_icon("StatusError", "EditorIcons"))
+ msg->show();
+ }
+
+ void _notification(int p_what) {
+
+ if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST)
+ _remove_created_folder();
}
protected:
@@ -558,7 +603,7 @@ public:
_test_path();
}
- popup_centered(Size2(500, 125) * EDSCALE);
+ popup_centered(Size2(500, 0) * EDSCALE);
}
ProjectDialog() {
@@ -610,7 +655,6 @@ public:
pphb->add_child(browse);
msg = memnew(Label);
- msg->set_text(TTR("That's a BINGO!"));
msg->set_align(Label::ALIGN_CENTER);
msg->hide();
vb->add_child(msg);
@@ -652,19 +696,20 @@ struct ProjectItem {
void ProjectManager::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
-
- Engine::get_singleton()->set_editor_hint(false);
-
- } else if (p_what == NOTIFICATION_READY) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
- if (scroll_childs->get_child_count() == 0) {
- open_templates->popup_centered_minsize();
- }
+ Engine::get_singleton()->set_editor_hint(false);
+ } break;
+ case NOTIFICATION_READY: {
- } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (scroll_childs->get_child_count() == 0)
+ open_templates->popup_centered_minsize();
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
- set_process_unhandled_input(is_visible_in_tree());
+ set_process_unhandled_input(is_visible_in_tree());
+ } break;
}
}
@@ -1214,7 +1259,6 @@ void ProjectManager::_run_project_confirm() {
Error err = OS::get_singleton()->execute(exec, args, false, &pid);
ERR_FAIL_COND(err);
}
- //get_scene()->quit(); do not quit
}
void ProjectManager::_run_project() {
@@ -1556,9 +1600,6 @@ ProjectManager::ProjectManager() {
scroll_childs->set_h_size_flags(SIZE_EXPAND_FILL);
scroll->add_child(scroll_childs);
- //HBoxContainer *hb = memnew( HBoxContainer );
- //vb->add_child(hb);
-
Button *open = memnew(Button);
open->set_text(TTR("Edit"));
tree_vb->add_child(open);
@@ -1663,7 +1704,7 @@ ProjectManager::ProjectManager() {
cancel->connect("pressed", this, "_exit_dialog");
vb->add_child(cc);
- //
+ //////////////////////////////////////////////////////////////
language_restart_ask = memnew(ConfirmationDialog);
language_restart_ask->get_ok()->set_text(TTR("Restart Now"));
@@ -1772,12 +1813,9 @@ void ProjectListFilter::_filter_option_selected(int p_idx) {
}
void ProjectListFilter::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- clear_search_button->set_icon(get_icon("Close", "EditorIcons"));
- } break;
- }
+ if (p_what == NOTIFICATION_ENTER_TREE)
+ clear_search_button->set_icon(get_icon("Close", "EditorIcons"));
}
void ProjectListFilter::_bind_methods() {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 7e8a6fcb6d..e7da78a35c 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -307,7 +307,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_REPLACE: {
- create_dialog->popup_create(false);
+ create_dialog->popup_create(false, true);
} break;
case TOOL_ATTACH_SCRIPT: {
@@ -417,7 +417,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (editor_selection->is_selected(edited_scene)) {
current_option = -1;
- //accept->get_cancel()->hide();
accept->get_ok()->set_text(TTR("I see.."));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index ad6ea2180f..96863a59d2 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -232,7 +232,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
String path = file_path->get_text();
String extension = "";
if (path != "") {
- if (path.find(".") >= 0) {
+ if (path.find(".") != -1) {
extension = path.get_extension();
}
@@ -359,16 +359,14 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
return;
}
- if (p.find("/") || p.find("\\")) {
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- if (d->change_dir(p.get_base_dir()) != OK) {
- _msg_path_valid(false, TTR("Invalid base path"));
- memdelete(d);
- _update_dialog();
- return;
- }
+ DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (d->change_dir(p.get_base_dir()) != OK) {
+ _msg_path_valid(false, TTR("Invalid base path"));
memdelete(d);
+ _update_dialog();
+ return;
}
+ memdelete(d);
/* Does file already exist */
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 4fe7bef9f7..f1a5aa4654 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -1686,6 +1686,45 @@ void ScriptEditorDebugger::_clear_remote_objects() {
remote_objects.clear();
}
+void ScriptEditorDebugger::_clear_errors_list() {
+
+ error_list->clear();
+ error_count = 0;
+ _notification(NOTIFICATION_PROCESS);
+}
+
+// Right click on specific file(s) or folder(s).
+void ScriptEditorDebugger::_error_list_item_rmb_selected(int p_item, const Vector2 &p_pos) {
+
+ item_menu->clear();
+ item_menu->set_size(Size2(1, 1));
+
+ // Allow specific actions only on one item.
+ bool single_item_selected = error_list->get_selected_items().size() == 1;
+
+ if (single_item_selected) {
+ item_menu->add_icon_item(get_icon("CopyNodePath", "EditorIcons"), TTR("Copy Error"), ITEM_MENU_COPY_ERROR);
+ }
+
+ if (item_menu->get_item_count() > 0) {
+ item_menu->set_position(error_list->get_global_position() + p_pos);
+ item_menu->popup();
+ }
+}
+
+void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) {
+
+ switch (p_option) {
+
+ case ITEM_MENU_COPY_ERROR: {
+ String title = error_list->get_item_text(error_list->get_current());
+ String desc = error_list->get_item_tooltip(error_list->get_current());
+
+ OS::get_singleton()->set_clipboard(title + "\n----------\n" + desc);
+ } break;
+ }
+}
+
void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected);
@@ -1705,6 +1744,10 @@ void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_error_stack_selected"), &ScriptEditorDebugger::_error_stack_selected);
ClassDB::bind_method(D_METHOD("_profiler_activate"), &ScriptEditorDebugger::_profiler_activate);
ClassDB::bind_method(D_METHOD("_profiler_seeked"), &ScriptEditorDebugger::_profiler_seeked);
+ ClassDB::bind_method(D_METHOD("_clear_errors_list"), &ScriptEditorDebugger::_clear_errors_list);
+
+ ClassDB::bind_method(D_METHOD("_error_list_item_rmb_selected"), &ScriptEditorDebugger::_error_list_item_rmb_selected);
+ ClassDB::bind_method(D_METHOD("_item_menu_id_pressed"), &ScriptEditorDebugger::_item_menu_id_pressed);
ClassDB::bind_method(D_METHOD("_paused"), &ScriptEditorDebugger::_paused);
@@ -1829,9 +1872,31 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
error_split = memnew(HSplitContainer);
VBoxContainer *errvb = memnew(VBoxContainer);
+ HBoxContainer *errhb = memnew(HBoxContainer);
errvb->set_h_size_flags(SIZE_EXPAND_FILL);
+ Label *velb = memnew(Label(TTR("Errors:")));
+ velb->set_h_size_flags(SIZE_EXPAND_FILL);
+ errhb->add_child(velb);
+
+ clearbutton = memnew(Button);
+ clearbutton->set_text(TTR("Clear"));
+ clearbutton->connect("pressed", this, "_clear_errors_list");
+ errhb->add_child(clearbutton);
+ errvb->add_child(errhb);
+
error_list = memnew(ItemList);
- errvb->add_margin_child(TTR("Errors:"), error_list, true);
+ error_list->set_v_size_flags(SIZE_EXPAND_FILL);
+ error_list->set_h_size_flags(SIZE_EXPAND_FILL);
+ error_list->connect("item_rmb_selected", this, "_error_list_item_rmb_selected");
+ error_list->set_allow_rmb_select(true);
+ error_list->set_autoscroll_to_bottom(true);
+
+ item_menu = memnew(PopupMenu);
+ item_menu->connect("id_pressed", this, "_item_menu_id_pressed");
+ error_list->add_child(item_menu);
+
+ errvb->add_child(error_list);
+
error_split->add_child(errvb);
errvb = memnew(VBoxContainer);
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index e380a56b18..7f8348d82f 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -62,6 +62,10 @@ class ScriptEditorDebugger : public Control {
MESSAGE_SUCCESS,
};
+ enum ItemMenu {
+ ITEM_MENU_COPY_ERROR,
+ };
+
AcceptDialog *msgdialog;
Button *debugger_button;
@@ -85,6 +89,8 @@ class ScriptEditorDebugger : public Control {
ItemList *error_list;
ItemList *error_stack;
Tree *inspect_scene_tree;
+ Button *clearbutton;
+ PopupMenu *item_menu;
int error_count;
int last_error_count;
@@ -175,6 +181,10 @@ class ScriptEditorDebugger : public Control {
void _set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj);
void _clear_remote_objects();
+ void _clear_errors_list();
+
+ void _error_list_item_rmb_selected(int p_item, const Vector2 &p_pos);
+ void _item_menu_id_pressed(int p_option);
protected:
void _notification(int p_what);
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 5026b8bb39..c3454d86f3 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -497,26 +497,16 @@ bool InputDefault::is_emulating_touchscreen() const {
return emulate_touch;
}
-void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, const Vector2 &p_hotspot) {
- /* no longer supported, leaving this for reference to anyone who might want to implement hardware cursors
+void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ if (Engine::get_singleton()->is_editor_hint())
+ return;
+
if (custom_cursor == p_cursor)
return;
custom_cursor = p_cursor;
- if (p_cursor.is_null()) {
- set_mouse_mode(MOUSE_MODE_VISIBLE);
- //removed, please insist us to implement hardare cursors
- //VisualServer::get_singleton()->cursor_set_visible(false);
- } else {
- Ref<AtlasTexture> atex = custom_cursor;
- Rect2 region = atex.is_valid() ? atex->get_region() : Rect2();
- set_mouse_mode(MOUSE_MODE_HIDDEN);
- VisualServer::get_singleton()->cursor_set_visible(true);
- VisualServer::get_singleton()->cursor_set_texture(custom_cursor->get_rid(), p_hotspot, 0, region);
- VisualServer::get_singleton()->cursor_set_pos(get_mouse_position());
- }
- */
+ OS::get_singleton()->set_custom_mouse_cursor(p_cursor, (OS::CursorShape)p_shape, p_hotspot);
}
void InputDefault::set_mouse_in_window(bool p_in_window) {
diff --git a/main/input_default.h b/main/input_default.h
index 62ba0b0c32..3d9a809325 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -225,7 +225,7 @@ public:
void set_emulate_touch(bool p_emulate);
virtual bool is_emulating_touchscreen() const;
- virtual void set_custom_mouse_cursor(const RES &p_cursor, const Vector2 &p_hotspot = Vector2());
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
virtual void set_mouse_in_window(bool p_in_window);
void parse_mapping(String p_mapping);
diff --git a/main/main.cpp b/main/main.cpp
index 5936a323d4..ac68fe1296 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1107,7 +1107,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
if (cursor.is_valid()) {
//print_line("loaded ok");
Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
- Input::get_singleton()->set_custom_mouse_cursor(cursor, hotspot);
+ Input::get_singleton()->set_custom_mouse_cursor(cursor, Input::CURSOR_ARROW, hotspot);
}
}
#ifdef TOOLS_ENABLED
diff --git a/misc/dist/osx_tools.app/Contents/Info.plist b/misc/dist/osx_tools.app/Contents/Info.plist
index 2a4914ec75..895eda14db 100755
--- a/misc/dist/osx_tools.app/Contents/Info.plist
+++ b/misc/dist/osx_tools.app/Contents/Info.plist
@@ -9,7 +9,7 @@
<key>CFBundleName</key>
<string>Godot</string>
<key>CFBundleGetInfoString</key>
- <string>(c) 2007-2018 Juan Linietsky, Ariel Manzur./string>
+ <string>(c) 2007-2018 Juan Linietsky, Ariel Manzur.</string>
<key>CFBundleIconFile</key>
<string>Godot.icns</string>
<key>CFBundleIdentifier</key>
@@ -25,7 +25,7 @@
<key>CFBundleVersion</key>
<string>3.0-dev</string>
<key>NSHumanReadableCopyright</key>
- <string>© 2007-2018 Juan Linietsky, Ariel Manzur./string>
+ <string>© 2007-2018 Juan Linietsky, Ariel Manzur.</string>
<key>LSMinimumSystemVersion</key>
<string>10.9.0</string>
<key>LSMinimumSystemVersionByArchitecture</key>
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index d97f355400..3023b489e5 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -605,7 +605,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
if (src->has_method(*index)) {
- err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "'). Did you mean '." + index->operator String() + "()' ?";
+ err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "'). Did you mean '." + index->operator String() + "()' or funcref(obj, \"" + index->operator String() + "\") ?";
} else {
err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "').";
}
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index e9bb90631d..c30c6d77b9 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -95,6 +95,22 @@
Returns whether or not grid items are centered on the Z axis.
</description>
</method>
+ <method name="get_collision_layer_bit" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_collision_mask_bit" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_meshes">
<return type="Array">
</return>
@@ -222,6 +238,26 @@
<description>
</description>
</method>
+ <method name="set_collision_layer_bit">
+ <return type="void">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <argument index="1" name="value" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_collision_mask_bit">
+ <return type="void">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <argument index="1" name="value" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_octant_size">
<return type="void">
</return>
@@ -249,6 +285,12 @@
</description>
</method>
</methods>
+ <members>
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer">
+ </member>
+ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
+ </member>
+ </members>
<constants>
<constant name="INVALID_CELL_ITEM" value="-1">
Invalid cell item that can be used in [method set_cell_item] to clear cells (or represent an empty cell in [method get_cell_item]).
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index bd37118847..9a03bc410a 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -198,6 +198,58 @@ void GridMap::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
}
+void GridMap::set_collision_layer(uint32_t p_layer) {
+
+ collision_layer = p_layer;
+ _reset_physic_bodies_collision_filters();
+}
+
+uint32_t GridMap::get_collision_layer() const {
+
+ return collision_layer;
+}
+
+void GridMap::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask = p_mask;
+ _reset_physic_bodies_collision_filters();
+}
+
+uint32_t GridMap::get_collision_mask() const {
+
+ return collision_mask;
+}
+
+void GridMap::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask |= 1 << p_bit;
+ else
+ mask &= ~(1 << p_bit);
+ set_collision_mask(mask);
+}
+
+bool GridMap::get_collision_mask_bit(int p_bit) const {
+
+ return get_collision_mask() & (1 << p_bit);
+}
+
+void GridMap::set_collision_layer_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_layer();
+ if (p_value)
+ mask |= 1 << p_bit;
+ else
+ mask &= ~(1 << p_bit);
+ set_collision_layer(mask);
+}
+
+bool GridMap::get_collision_layer_bit(int p_bit) const {
+
+ return get_collision_layer() & (1 << p_bit);
+}
+
void GridMap::set_theme(const Ref<MeshLibrary> &p_theme) {
if (!theme.is_null())
@@ -311,6 +363,8 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
g->dirty = true;
g->static_body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
PhysicsServer::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
+ PhysicsServer::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
+ PhysicsServer::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_debugging_collisions_hint()) {
@@ -575,6 +629,13 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
return false;
}
+void GridMap::_reset_physic_bodies_collision_filters() {
+ for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
+ PhysicsServer::get_singleton()->body_set_collision_layer(E->get()->static_body, collision_layer);
+ PhysicsServer::get_singleton()->body_set_collision_mask(E->get()->static_body, collision_mask);
+ }
+}
+
void GridMap::_octant_enter_world(const OctantKey &p_key) {
ERR_FAIL_COND(!octant_map.has(p_key));
@@ -815,6 +876,18 @@ void GridMap::_update_octants_callback() {
void GridMap::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &GridMap::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &GridMap::get_collision_layer);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &GridMap::set_collision_mask);
+ ClassDB::bind_method(D_METHOD("get_collision_mask"), &GridMap::get_collision_mask);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &GridMap::set_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &GridMap::get_collision_mask_bit);
+
+ ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &GridMap::set_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &GridMap::get_collision_layer_bit);
+
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &GridMap::set_theme);
ClassDB::bind_method(D_METHOD("get_theme"), &GridMap::get_theme);
@@ -855,6 +928,10 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_baked_meshes"), &GridMap::clear_baked_meshes);
ClassDB::bind_method(D_METHOD("make_baked_meshes", "gen_lightmap_uv", "lightmap_uv_texel_size"), &GridMap::make_baked_meshes, DEFVAL(false), DEFVAL(0.1));
+ ADD_GROUP("Collision", "collision_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+
BIND_CONSTANT(INVALID_CELL_ITEM);
}
@@ -1067,6 +1144,9 @@ RID GridMap::get_bake_mesh_instance(int p_idx) {
GridMap::GridMap() {
+ collision_layer = 1;
+ collision_mask = 1;
+
cell_size = Vector3(2, 2, 2);
octant_size = 8;
awaiting_update = false;
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index 18a9551edf..7b97fe3183 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -136,6 +136,9 @@ class GridMap : public Spatial {
OctantKey() { key = 0; }
};
+ uint32_t collision_layer;
+ uint32_t collision_mask;
+
Transform last_transform;
bool _in_tree;
@@ -173,6 +176,7 @@ class GridMap : public Spatial {
return Vector3(p_key.x, p_key.y, p_key.z) * cell_size * octant_size;
}
+ void _reset_physic_bodies_collision_filters();
void _octant_enter_world(const OctantKey &p_key);
void _octant_exit_world(const OctantKey &p_key);
bool _octant_update(const OctantKey &p_key);
@@ -210,6 +214,18 @@ public:
INVALID_CELL_ITEM = -1
};
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
+
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_collision_layer_bit(int p_bit, bool p_value);
+ bool get_collision_layer_bit(int p_bit) const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
void set_theme(const Ref<MeshLibrary> &p_theme);
Ref<MeshLibrary> get_theme() const;
diff --git a/modules/thekla_unwrap/register_types.cpp b/modules/thekla_unwrap/register_types.cpp
index 2dc9217e48..eb11325dde 100644
--- a/modules/thekla_unwrap/register_types.cpp
+++ b/modules/thekla_unwrap/register_types.cpp
@@ -28,7 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
+#include "error_macros.h"
#include "thirdparty/thekla_atlas/thekla/thekla_atlas.h"
+
#include <stdio.h>
#include <stdlib.h>
extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y);
@@ -74,6 +76,11 @@ bool thekla_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
delete[] input_mesh.face_array;
delete[] input_mesh.vertex_array;
+ if (output == NULL) {
+ ERR_PRINT("could not generate atlas output mesh");
+ return false;
+ }
+
if (err != Thekla::Atlas_Error_Success) {
printf("error with atlas\n");
} else {
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 5702134791..2ff3fb6d7a 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -309,9 +309,6 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
/* and now we have it all. initialize decoders */
if (theora_p) {
td = th_decode_alloc(&ti, ts);
- printf("Ogg logical stream %lx is Theora %dx%d %.02f fps",
- to.serialno, ti.pic_width, ti.pic_height,
- (double)ti.fps_numerator / ti.fps_denominator);
px_fmt = ti.pixel_fmt;
switch (ti.pixel_fmt) {
case TH_PF_420: printf(" 4:2:0 video\n"); break;
@@ -322,9 +319,6 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
printf(" video\n (UNKNOWN Chroma sampling!)\n");
break;
}
- if (ti.pic_width != ti.frame_width || ti.pic_height != ti.frame_height)
- printf(" Frame content is %dx%d with offset (%d,%d).\n",
- ti.frame_width, ti.frame_height, ti.pic_x, ti.pic_y);
th_decode_ctl(td, TH_DECCTL_GET_PPLEVEL_MAX, &pp_level_max,
sizeof(pp_level_max));
pp_level = 0;
@@ -351,10 +345,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
if (vorbis_p) {
vorbis_synthesis_init(&vd, &vi);
vorbis_block_init(&vd, &vb);
- fprintf(stderr, "Ogg logical stream %lx is Vorbis %d channel %ld Hz audio.\n",
- vo.serialno, vi.channels, vi.rate);
//_setup(vi.channels, vi.rate);
-
} else {
/* tear down the partial vorbis setup */
vorbis_info_clear(&vi);
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 0cd91276ef..d2285a82dd 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -104,7 +104,7 @@ gradle_asset_dirs_text = ""
gradle_default_config_text = ""
minSdk = 18
-targetSdk = 23
+targetSdk = 27
for x in env.android_default_config:
if x.startswith("minSdkVersion") and int(x.split(" ")[-1]) < minSdk:
diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template
index 4a44d1c5f9..13b4d3b6c7 100644
--- a/platform/android/build.gradle.template
+++ b/platform/android/build.gradle.template
@@ -31,8 +31,8 @@ android {
disable 'MissingTranslation'
}
- compileSdkVersion 26
- buildToolsVersion "26.0.1"
+ compileSdkVersion 27
+ buildToolsVersion "27.0.3"
useLibrary 'org.apache.http.legacy'
packagingOptions {
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index ee6901c9d7..fe37fa74a9 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index dd23a81977..97e81874c9 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -248,6 +248,9 @@ void OS_Android::set_cursor_shape(CursorShape p_shape) {
//android really really really has no mouse.. how amazing..
}
+void OS_Android::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+}
+
void OS_Android::main_loop_begin() {
if (main_loop)
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 744dce7ff1..adfd88b59b 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -182,6 +182,7 @@ public:
virtual bool can_draw() const;
virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
void main_loop_begin();
bool main_loop_iterate();
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 3324b33e95..65a220f8ca 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -200,6 +200,10 @@ void OS_Haiku::set_cursor_shape(CursorShape p_shape) {
//ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED");
}
+void OS_Haiku::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ // TODO
+}
+
int OS_Haiku::get_screen_count() const {
// TODO: implement get_screen_count()
return 1;
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index b4d0add04b..6d69c1997f 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -87,6 +87,7 @@ public:
virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
virtual int get_screen_count() const;
virtual int get_current_screen() const;
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index dcb7b8b1f4..507d4f22db 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -490,6 +490,8 @@ String OSIPhone::get_user_data_dir() const {
return data_dir;
};
+void OSIPhone::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot){};
+
String OSIPhone::get_name() {
return "iOS";
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 7e310e3a03..8e701a7fab 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -173,6 +173,7 @@ public:
virtual int get_virtual_keyboard_height() const;
virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
virtual Size2 get_window_size() const;
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index a24bf6c0bc..0411b4e72b 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -41,6 +41,7 @@
#include "servers/visual/rasterizer.h"
#include "servers/visual/visual_server_wrap_mt.h"
#include "servers/visual_server.h"
+#include <AppKit/NSCursor.h>
#include <ApplicationServices/ApplicationServices.h>
#undef CursorShape
@@ -86,6 +87,7 @@ public:
id context;
CursorShape cursor_shape;
+ NSCursor *cursors[CURSOR_MAX] = { NULL };
MouseMode mouse_mode;
String title;
@@ -137,6 +139,7 @@ public:
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 0cd02663da..99c5995d7a 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -577,8 +577,11 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
return;
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
- if (OS_OSX::singleton->input)
+ if (OS_OSX::singleton->input) {
OS_OSX::singleton->input->set_mouse_in_window(true);
+ OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX;
+ OS_OSX::singleton->set_cursor_shape(OS::CURSOR_ARROW);
+ }
}
- (void)magnifyWithEvent:(NSEvent *)event {
@@ -1240,30 +1243,84 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
if (cursor_shape == p_shape)
return;
- switch (p_shape) {
- case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break;
- case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break;
- case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break;
- case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break;
- case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break;
- case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break;
- case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break;
- case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break;
- case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break;
- case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break;
- case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break;
- case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break;
- case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break;
- case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break;
- case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_HELP: [[NSCursor arrowCursor] set]; break;
- default: {};
+ if (cursors[p_shape] != NULL) {
+ [cursors[p_shape] set];
+ } else {
+ switch (p_shape) {
+ case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break;
+ case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break;
+ case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break;
+ case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break;
+ case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break;
+ case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break;
+ case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break;
+ case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break;
+ case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break;
+ case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break;
+ case CURSOR_HELP: [[NSCursor arrowCursor] set]; break;
+ default: {};
+ }
}
cursor_shape = p_shape;
}
+void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ if (p_cursor.is_valid()) {
+ Ref<Texture> texture = p_cursor;
+ Ref<Image> image = texture->get_data();
+
+ int image_size = 32 * 32;
+
+ ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+
+ NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
+ initWithBitmapDataPlanes:NULL
+ pixelsWide:image->get_width()
+ pixelsHigh:image->get_height()
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:image->get_width() * 4
+ bitsPerPixel:32] autorelease];
+
+ ERR_FAIL_COND(imgrep == nil);
+ uint8_t *pixels = [imgrep bitmapData];
+
+ int len = image->get_width() * image->get_height();
+ PoolVector<uint8_t> data = image->get_data();
+ PoolVector<uint8_t>::Read r = data.read();
+
+ /* Premultiply the alpha channel */
+ for (int i = 0; i < len; i++) {
+ uint8_t alpha = r[i * 4 + 3];
+ pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
+ pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
+ pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
+ pixels[i * 4 + 3] = alpha;
+ }
+
+ NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(image->get_width(), image->get_height())] autorelease];
+ [nsimage addRepresentation:imgrep];
+
+ NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)];
+
+ cursors[p_shape] = cursor;
+
+ if (p_shape == CURSOR_ARROW) {
+ [cursor set];
+ }
+ }
+}
+
void OS_OSX::set_mouse_show(bool p_show) {
}
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index c34567aaab..13264ed46e 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -179,6 +179,9 @@ void OS_Server::move_window_to_foreground() {
void OS_Server::set_cursor_shape(CursorShape p_shape) {
}
+void OS_Server::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+}
+
OS::PowerState OS_Server::get_power_state() {
return power_manager->get_power_state();
}
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index c58c48500e..7b7d4a38a8 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -75,6 +75,7 @@ public:
virtual String get_name();
virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab);
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index ceccfb281c..603a918cca 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -651,6 +651,10 @@ void OSUWP::set_cursor_shape(CursorShape p_shape) {
cursor_shape = p_shape;
}
+void OSUWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ // TODO
+}
+
Error OSUWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) {
return FAILED;
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 7c2371b097..976eda1fe1 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -218,6 +218,7 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 8edc2c5cff..e3af82b629 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1844,10 +1844,125 @@ void OS_Windows::set_cursor_shape(CursorShape p_shape) {
IDC_HELP
};
- SetCursor(LoadCursor(hInstance, win_cursors[p_shape]));
+ if (cursors[p_shape] != NULL) {
+ SetCursor(cursors[p_shape]);
+ } else {
+ SetCursor(LoadCursor(hInstance, win_cursors[p_shape]));
+ }
cursor_shape = p_shape;
}
+void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ if (p_cursor.is_valid()) {
+ Ref<Texture> texture = p_cursor;
+ Ref<Image> image = texture->get_data();
+
+ UINT image_size = 32 * 32;
+ UINT size = sizeof(UINT) * image_size;
+
+ ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+
+ // Create the BITMAP with alpha channel
+ COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size);
+
+ image->lock();
+ for (UINT index = 0; index < image_size; index++) {
+ int column_index = floor(index / 32);
+ int row_index = index % 32;
+
+ Color pcColor = image->get_pixel(row_index, column_index);
+ *(buffer + index) = image->get_pixel(row_index, column_index).to_argb32();
+ }
+ image->unlock();
+
+ // Using 4 channels, so 4 * 8 bits
+ HBITMAP bitmap = CreateBitmap(32, 32, 1, 4 * 8, buffer);
+ COLORREF clrTransparent = -1;
+
+ // Create the AND and XOR masks for the bitmap
+ HBITMAP hAndMask = NULL;
+ HBITMAP hXorMask = NULL;
+
+ GetMaskBitmaps(bitmap, clrTransparent, hAndMask, hXorMask);
+
+ if (NULL == hAndMask || NULL == hXorMask) {
+ return;
+ }
+
+ // Finally, create the icon
+ ICONINFO iconinfo = { 0 };
+ iconinfo.fIcon = FALSE;
+ iconinfo.xHotspot = p_hotspot.x;
+ iconinfo.yHotspot = p_hotspot.y;
+ iconinfo.hbmMask = hAndMask;
+ iconinfo.hbmColor = hXorMask;
+
+ cursors[p_shape] = CreateIconIndirect(&iconinfo);
+
+ if (p_shape == CURSOR_ARROW) {
+ SetCursor(cursors[p_shape]);
+ }
+
+ if (hAndMask != NULL) {
+ DeleteObject(hAndMask);
+ }
+
+ if (hXorMask != NULL) {
+ DeleteObject(hXorMask);
+ }
+ }
+}
+
+void OS_Windows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap) {
+
+ // Get the system display DC
+ HDC hDC = GetDC(NULL);
+
+ // Create helper DC
+ HDC hMainDC = CreateCompatibleDC(hDC);
+ HDC hAndMaskDC = CreateCompatibleDC(hDC);
+ HDC hXorMaskDC = CreateCompatibleDC(hDC);
+
+ // Get the dimensions of the source bitmap
+ BITMAP bm;
+ GetObject(hSourceBitmap, sizeof(BITMAP), &bm);
+
+ // Create the mask bitmaps
+ hAndMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // color
+ hXorMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // color
+
+ // Release the system display DC
+ ReleaseDC(NULL, hDC);
+
+ // Select the bitmaps to helper DC
+ HBITMAP hOldMainBitmap = (HBITMAP)SelectObject(hMainDC, hSourceBitmap);
+ HBITMAP hOldAndMaskBitmap = (HBITMAP)SelectObject(hAndMaskDC, hAndMaskBitmap);
+ HBITMAP hOldXorMaskBitmap = (HBITMAP)SelectObject(hXorMaskDC, hXorMaskBitmap);
+
+ // Assign the monochrome AND mask bitmap pixels so that a pixels of the source bitmap
+ // with 'clrTransparent' will be white pixels of the monochrome bitmap
+ SetBkColor(hMainDC, clrTransparent);
+ BitBlt(hAndMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hMainDC, 0, 0, SRCCOPY);
+
+ // Assign the color XOR mask bitmap pixels so that a pixels of the source bitmap
+ // with 'clrTransparent' will be black and rest the pixels same as corresponding
+ // pixels of the source bitmap
+ SetBkColor(hXorMaskDC, RGB(0, 0, 0));
+ SetTextColor(hXorMaskDC, RGB(255, 255, 255));
+ BitBlt(hXorMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hAndMaskDC, 0, 0, SRCCOPY);
+ BitBlt(hXorMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hMainDC, 0, 0, SRCAND);
+
+ // Deselect bitmaps from the helper DC
+ SelectObject(hMainDC, hOldMainBitmap);
+ SelectObject(hAndMaskDC, hOldAndMaskBitmap);
+ SelectObject(hXorMaskDC, hOldXorMaskBitmap);
+
+ // Delete the helper DC
+ DeleteDC(hXorMaskDC);
+ DeleteDC(hAndMaskDC);
+ DeleteDC(hMainDC);
+}
+
Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) {
if (p_blocking && r_pipe) {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index d709fb3fe5..9d254ccf27 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -113,6 +113,7 @@ class OS_Windows : public OS {
bool window_has_focus;
uint32_t last_button_state;
+ HCURSOR cursors[CURSOR_MAX] = { NULL };
CursorShape cursor_shape;
InputDefault *input;
@@ -244,6 +245,8 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
+ void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap);
void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 240d6638a9..e9920b18a4 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1050,13 +1050,59 @@ void OS_X11::set_window_maximized(bool p_enabled) {
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- while (p_enabled && !is_window_maximized()) {
- // Wait for effective resizing (so the GLX context is too).
+ if (is_window_maximize_allowed()) {
+ while (p_enabled && !is_window_maximized()) {
+ // Wait for effective resizing (so the GLX context is too).
+ }
}
maximized = p_enabled;
}
+bool OS_X11::is_window_maximize_allowed() {
+ Atom property = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False);
+ Atom type;
+ int format;
+ unsigned long len;
+ unsigned long remaining;
+ unsigned char *data = NULL;
+
+ int result = XGetWindowProperty(
+ x11_display,
+ x11_window,
+ property,
+ 0,
+ 1024,
+ False,
+ XA_ATOM,
+ &type,
+ &format,
+ &len,
+ &remaining,
+ &data);
+
+ if (result == Success) {
+ Atom *atoms = (Atom *)data;
+ Atom wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False);
+ Atom wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_VERT", False);
+ bool found_wm_act_max_horz = false;
+ bool found_wm_act_max_vert = false;
+
+ for (unsigned int i = 0; i < len; i++) {
+ if (atoms[i] == wm_act_max_horz)
+ found_wm_act_max_horz = true;
+ if (atoms[i] == wm_act_max_vert)
+ found_wm_act_max_vert = true;
+
+ if (found_wm_act_max_horz || found_wm_act_max_vert)
+ return true;
+ }
+ XFree(atoms);
+ }
+
+ return false;
+}
+
bool OS_X11::is_window_maximized() const {
// Using EWMH -- Extended Window Manager Hints
Atom property = XInternAtom(x11_display, "_NET_WM_STATE", False);
@@ -2205,6 +2251,48 @@ void OS_X11::set_cursor_shape(CursorShape p_shape) {
current_cursor = p_shape;
}
+void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ if (p_cursor.is_valid()) {
+ Ref<Texture> texture = p_cursor;
+ Ref<Image> image = texture->get_data();
+
+ ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+
+ // Create the cursor structure
+ XcursorImage *cursor_image = XcursorImageCreate(texture->get_width(), texture->get_height());
+ XcursorUInt image_size = 32 * 32;
+ XcursorDim size = sizeof(XcursorPixel) * image_size;
+
+ cursor_image->version = 1;
+ cursor_image->size = size;
+ cursor_image->xhot = p_hotspot.x;
+ cursor_image->yhot = p_hotspot.y;
+
+ // allocate memory to contain the whole file
+ cursor_image->pixels = (XcursorPixel *)malloc(size);
+
+ image->lock();
+
+ for (XcursorPixel index = 0; index < image_size; index++) {
+ int column_index = floor(index / 32);
+ int row_index = index % 32;
+
+ *(cursor_image->pixels + index) = image->get_pixel(row_index, column_index).to_argb32();
+ }
+
+ image->unlock();
+
+ ERR_FAIL_COND(cursor_image->pixels == NULL);
+
+ // Save it for a further usage
+ cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image);
+
+ if (p_shape == CURSOR_ARROW) {
+ XDefineCursor(x11_display, x11_window, cursors[p_shape]);
+ }
+ }
+}
+
void OS_X11::release_rendering_thread() {
context_gl->release_current();
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 59b9c8caa8..04243a9b36 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -200,10 +200,13 @@ protected:
void _window_changed(XEvent *xevent);
+ bool is_window_maximize_allowed();
+
public:
virtual String get_name();
virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index e994ebb5aa..1db9e4902a 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -229,6 +229,7 @@ public:
// Used to resize/move/select the node
virtual void _edit_set_rect(const Rect2 &p_rect){};
virtual Rect2 _edit_get_rect() const { return Rect2(-32, -32, 64, 64); };
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return true; }
Rect2 _edit_get_item_and_children_rect() const;
virtual bool _edit_use_rect() const { return false; };
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index eaa650b140..8c6b25f296 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -131,7 +131,7 @@ void CollisionPolygon2D::_notification(int p_what) {
/*if (Engine::get_singleton()->is_editor_hint()) {
//display above all else
set_z_as_relative(false);
- set_z(VS::CANVAS_ITEM_Z_MAX - 1);
+ set_z_index(VS::CANVAS_ITEM_Z_MAX - 1);
}*/
} break;
@@ -248,6 +248,11 @@ Rect2 CollisionPolygon2D::_edit_get_rect() const {
return aabb;
}
+bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return Geometry::is_point_in_polygon(p_point, Variant(polygon));
+}
+
String CollisionPolygon2D::get_configuration_warning() const {
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index 4c8b55a9ee..fa7e5e1046 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -70,6 +70,7 @@ public:
Vector<Point2> get_polygon() const;
virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
virtual String get_configuration_warning() const;
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 1cadbe83d0..1956e23421 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -64,7 +64,7 @@ void CollisionShape2D::_notification(int p_what) {
/*if (Engine::get_singleton()->is_editor_hint()) {
//display above all else
set_z_as_relative(false);
- set_z(VS::CANVAS_ITEM_Z_MAX - 1);
+ set_z_index(VS::CANVAS_ITEM_Z_MAX - 1);
}*/
} break;
@@ -163,6 +163,14 @@ Rect2 CollisionShape2D::_edit_get_rect() const {
return rect;
}
+bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ if (!shape.is_valid())
+ return false;
+
+ return shape->_edit_is_selected_on_click(p_point, p_tolerance);
+}
+
String CollisionShape2D::get_configuration_warning() const {
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h
index 833d9ae5cb..921066c5c8 100644
--- a/scene/2d/collision_shape_2d.h
+++ b/scene/2d/collision_shape_2d.h
@@ -52,6 +52,7 @@ protected:
public:
virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
void set_shape(const Ref<Shape2D> &p_shape);
Ref<Shape2D> get_shape() const;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index f108df140f..abc80216d4 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -48,6 +48,32 @@ Line2D::Line2D() :
_round_precision = 8;
}
+Rect2 Line2D::_edit_get_rect() const {
+
+ if (_points.size() == 0)
+ return Rect2(0, 0, 0, 0);
+ Vector2 d = Vector2(_width, _width);
+ Rect2 aabb = Rect2(_points[0] - d, 2 * d);
+ for (int i = 1; i < _points.size(); i++) {
+ aabb.expand_to(_points[i] - d);
+ aabb.expand_to(_points[i] + d);
+ }
+ return aabb;
+}
+
+bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ const real_t d = _width / 2 + p_tolerance;
+ PoolVector<Vector2>::Read points = _points.read();
+ for (int i = 0; i < _points.size() - 1; i++) {
+ Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]);
+ if (p.distance_to(p_point) <= d)
+ return true;
+ }
+
+ return false;
+}
+
void Line2D::set_points(const PoolVector<Vector2> &p_points) {
_points = p_points;
update();
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index 123728ab39..54a4683dc7 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -57,6 +57,9 @@ public:
Line2D();
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_points(const PoolVector<Vector2> &p_points);
PoolVector<Vector2> get_points() const;
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 9c297db52b..dde41dbf3f 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -35,9 +35,50 @@
#include "thirdparty/misc/triangulator.h"
+Rect2 NavigationPolygon::_edit_get_rect() const {
+
+ if (rect_cache_dirty) {
+ item_rect = Rect2();
+ bool first = true;
+
+ for (int i = 0; i < outlines.size(); i++) {
+ const PoolVector<Vector2> &outline = outlines[i];
+ const int outline_size = outline.size();
+ if (outline_size < 3)
+ continue;
+ PoolVector<Vector2>::Read p = outline.read();
+ for (int j = 0; j < outline_size; j++) {
+ if (first) {
+ item_rect = Rect2(p[j], Vector2(0, 0));
+ first = false;
+ } else {
+ item_rect.expand_to(p[j]);
+ }
+ }
+ }
+
+ rect_cache_dirty = false;
+ }
+ return item_rect;
+}
+
+bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ for (int i = 0; i < outlines.size(); i++) {
+ const PoolVector<Vector2> &outline = outlines[i];
+ const int outline_size = outline.size();
+ if (outline_size < 3)
+ continue;
+ if (Geometry::is_point_in_polygon(p_point, Variant(outline)))
+ return true;
+ }
+ return false;
+}
+
void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) {
vertices = p_vertices;
+ rect_cache_dirty = true;
}
PoolVector<Vector2> NavigationPolygon::get_vertices() const {
@@ -70,6 +111,7 @@ void NavigationPolygon::_set_outlines(const Array &p_array) {
for (int i = 0; i < p_array.size(); i++) {
outlines[i] = p_array[i];
}
+ rect_cache_dirty = true;
}
Array NavigationPolygon::_get_outlines() const {
@@ -93,6 +135,7 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
void NavigationPolygon::add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index) {
outlines.insert(p_index, p_outline);
+ rect_cache_dirty = true;
}
int NavigationPolygon::get_polygon_count() const {
@@ -112,6 +155,7 @@ void NavigationPolygon::clear_polygons() {
void NavigationPolygon::add_outline(const PoolVector<Vector2> &p_outline) {
outlines.push_back(p_outline);
+ rect_cache_dirty = true;
}
int NavigationPolygon::get_outline_count() const {
@@ -122,12 +166,14 @@ int NavigationPolygon::get_outline_count() const {
void NavigationPolygon::set_outline(int p_idx, const PoolVector<Vector2> &p_outline) {
ERR_FAIL_INDEX(p_idx, outlines.size());
outlines[p_idx] = p_outline;
+ rect_cache_dirty = true;
}
void NavigationPolygon::remove_outline(int p_idx) {
ERR_FAIL_INDEX(p_idx, outlines.size());
outlines.remove(p_idx);
+ rect_cache_dirty = true;
}
PoolVector<Vector2> NavigationPolygon::get_outline(int p_idx) const {
@@ -138,6 +184,7 @@ PoolVector<Vector2> NavigationPolygon::get_outline(int p_idx) const {
void NavigationPolygon::clear_outlines() {
outlines.clear();
+ rect_cache_dirty = true;
}
void NavigationPolygon::make_polygons_from_outlines() {
@@ -269,7 +316,8 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_outlines", "_get_outlines");
}
-NavigationPolygon::NavigationPolygon() {
+NavigationPolygon::NavigationPolygon() :
+ rect_cache_dirty(true) {
}
void NavigationPolygonInstance::set_enabled(bool p_enabled) {
@@ -311,6 +359,16 @@ bool NavigationPolygonInstance::is_enabled() const {
/////////////////////////////
+Rect2 NavigationPolygonInstance::_edit_get_rect() const {
+
+ return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2();
+}
+
+bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false;
+}
+
void NavigationPolygonInstance::_notification(int p_what) {
switch (p_what) {
diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h
index febdcf2ca6..7b5220f92d 100644
--- a/scene/2d/navigation_polygon.h
+++ b/scene/2d/navigation_polygon.h
@@ -43,6 +43,9 @@ class NavigationPolygon : public Resource {
Vector<Polygon> polygons;
Vector<PoolVector<Vector2> > outlines;
+ mutable Rect2 item_rect;
+ mutable bool rect_cache_dirty;
+
protected:
static void _bind_methods();
@@ -53,6 +56,9 @@ protected:
Array _get_outlines() const;
public:
+ Rect2 _edit_get_rect() const;
+ bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_vertices(const PoolVector<Vector2> &p_vertices);
PoolVector<Vector2> get_vertices() const;
@@ -93,6 +99,9 @@ protected:
static void _bind_methods();
public:
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_enabled(bool p_enabled);
bool is_enabled() const;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 2a305512af..e133f86ef7 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -329,13 +329,13 @@ void Node2D::set_global_transform(const Transform2D &p_transform) {
set_transform(p_transform);
}
-void Node2D::set_z(int p_z) {
+void Node2D::set_z_index(int p_z) {
ERR_FAIL_COND(p_z < VS::CANVAS_ITEM_Z_MIN);
ERR_FAIL_COND(p_z > VS::CANVAS_ITEM_Z_MAX);
- z = p_z;
- VS::get_singleton()->canvas_item_set_z(get_canvas_item(), z);
- _change_notify("z");
+ z_index = p_z;
+ VS::get_singleton()->canvas_item_set_z_index(get_canvas_item(), z_index);
+ _change_notify("z_index");
}
void Node2D::set_z_as_relative(bool p_enabled) {
@@ -351,9 +351,9 @@ bool Node2D::is_z_relative() const {
return z_relative;
}
-int Node2D::get_z() const {
+int Node2D::get_z_index() const {
- return z;
+ return z_index;
}
Transform2D Node2D::get_relative_transform_to_parent(const Node *p_parent) const {
@@ -427,8 +427,8 @@ void Node2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node2D::to_local);
ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node2D::to_global);
- ClassDB::bind_method(D_METHOD("set_z", "z"), &Node2D::set_z);
- ClassDB::bind_method(D_METHOD("get_z"), &Node2D::get_z);
+ ClassDB::bind_method(D_METHOD("set_z_index", "z_index"), &Node2D::set_z_index);
+ ClassDB::bind_method(D_METHOD("get_z_index"), &Node2D::get_z_index);
ClassDB::bind_method(D_METHOD("set_z_as_relative", "enable"), &Node2D::set_z_as_relative);
ClassDB::bind_method(D_METHOD("is_z_relative"), &Node2D::is_z_relative);
@@ -448,8 +448,8 @@ void Node2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_scale", PROPERTY_HINT_NONE, "", 0), "set_global_scale", "get_global_scale");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform");
- ADD_GROUP("Z", "");
- ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "z", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z", "get_z");
+ ADD_GROUP("Z Index", "");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index");
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative");
}
@@ -458,6 +458,6 @@ Node2D::Node2D() {
angle = 0;
_scale = Vector2(1, 1);
_xform_dirty = false;
- z = 0;
+ z_index = 0;
z_relative = true;
}
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index 7d2e5aa00c..321021a748 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -39,7 +39,7 @@ class Node2D : public CanvasItem {
Point2 pos;
float angle;
Size2 _scale;
- int z;
+ int z_index;
bool z_relative;
Transform2D _mat;
@@ -96,8 +96,8 @@ public:
void set_global_rotation_degrees(float p_degrees);
void set_global_scale(const Size2 &p_scale);
- void set_z(int p_z);
- int get_z() const;
+ void set_z_index(int p_z);
+ int get_z_index() const;
void look_at(const Vector2 &p_pos);
float get_angle_to(const Vector2 &p_pos) const;
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 06bd55858c..d2a307a9ed 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -32,6 +32,51 @@
#include "engine.h"
#include "scene/scene_string_names.h"
+#ifdef TOOLS_ENABLED
+#include "editor/editor_scale.h"
+#endif
+
+Rect2 Path2D::_edit_get_rect() const {
+
+ if (curve->get_point_count() == 0)
+ return Rect2(0, 0, 0, 0);
+
+ Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0));
+
+ for (int i = 0; i < curve->get_point_count(); i++) {
+
+ for (int j = 0; j <= 8; j++) {
+
+ real_t frac = j / 8.0;
+ Vector2 p = curve->interpolate(i, frac);
+ aabb.expand_to(p);
+ }
+ }
+
+ return aabb;
+}
+
+bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ for (int i = 0; i < curve->get_point_count(); i++) {
+ Vector2 s[2];
+ s[0] = curve->get_point_position(i);
+
+ for (int j = 1; j <= 8; j++) {
+ real_t frac = j / 8.0;
+ s[1] = curve->interpolate(i, frac);
+
+ Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s);
+ if (p.distance_to(p_point) <= p_tolerance)
+ return true;
+
+ s[0] = s[1];
+ }
+ }
+
+ return false;
+}
+
void Path2D::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW && curve.is_valid()) {
@@ -41,6 +86,13 @@ void Path2D::_notification(int p_what) {
return;
}
+#if TOOLS_ENABLED
+ const float line_width = 2 * EDSCALE;
+#else
+ const float line_width = 2;
+#endif
+ const Color color = Color(0.5, 0.6, 1.0, 0.7);
+
for (int i = 0; i < curve->get_point_count(); i++) {
Vector2 prev_p = curve->get_point_position(i);
@@ -49,7 +101,7 @@ void Path2D::_notification(int p_what) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, Color(0.5, 0.6, 1.0, 0.7), 2);
+ draw_line(prev_p, p, color, line_width);
prev_p = p;
}
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index ebfa77d605..7f53821c7e 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -46,6 +46,9 @@ protected:
static void _bind_methods();
public:
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_curve(const Ref<Curve2D> &p_curve);
Ref<Curve2D> get_curve() const;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index a2f49d938b..f9951cdd08 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "polygon_2d.h"
+#include "core/math/geometry.h"
Rect2 Polygon2D::_edit_get_rect() const {
@@ -42,13 +43,17 @@ Rect2 Polygon2D::_edit_get_rect() const {
else
item_rect.expand_to(pos);
}
- item_rect = item_rect.grow(20);
rect_cache_dirty = false;
}
return item_rect;
}
+bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return Geometry::is_point_in_polygon(p_point, Variant(polygon));
+}
+
void Polygon2D::_edit_set_pivot(const Point2 &p_pivot) {
set_offset(p_pivot);
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index a23e223e6e..5014cbc6e9 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -104,6 +104,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
Polygon2D();
};
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index c4a7e5aebd..68df95c042 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -47,6 +47,40 @@ bool Sprite::_edit_use_pivot() const {
return true;
}
+void Sprite::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const {
+
+ Size2 s;
+ r_filter_clip = false;
+
+ if (region) {
+
+ s = region_rect.size;
+ r_src_rect = region_rect;
+ r_filter_clip = region_filter_clip;
+ } else {
+ s = Size2(texture->get_size());
+ s = s / Size2(hframes, vframes);
+
+ r_src_rect.size = s;
+ r_src_rect.position.x += float(frame % hframes) * s.x;
+ r_src_rect.position.y += float(frame / hframes) * s.y;
+ }
+
+ Point2 ofs = offset;
+ if (centered)
+ ofs -= s / 2;
+ if (Engine::get_singleton()->get_use_pixel_snap()) {
+ ofs = ofs.floor();
+ }
+
+ r_dst_rect = Rect2(ofs, s);
+
+ if (hflip)
+ r_dst_rect.size.x = -r_dst_rect.size.x;
+ if (vflip)
+ r_dst_rect.size.y = -r_dst_rect.size.y;
+}
+
void Sprite::_notification(int p_what) {
switch (p_what) {
@@ -63,38 +97,9 @@ void Sprite::_notification(int p_what) {
break;
*/
- Size2 s;
- Rect2 src_rect;
- bool filter_clip = false;
-
- if (region) {
-
- s = region_rect.size;
- src_rect = region_rect;
- filter_clip = region_filter_clip;
- } else {
- s = Size2(texture->get_size());
- s = s / Size2(hframes, vframes);
-
- src_rect.size = s;
- src_rect.position.x += float(frame % hframes) * s.x;
- src_rect.position.y += float(frame / hframes) * s.y;
- }
-
- Point2 ofs = offset;
- if (centered)
- ofs -= s / 2;
- if (Engine::get_singleton()->get_use_pixel_snap()) {
- ofs = ofs.floor();
- }
-
- Rect2 dst_rect(ofs, s);
-
- if (hflip)
- dst_rect.size.x = -dst_rect.size.x;
- if (vflip)
- dst_rect.size.y = -dst_rect.size.y;
-
+ Rect2 src_rect, dst_rect;
+ bool filter_clip;
+ _get_rects(src_rect, dst_rect, filter_clip);
texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, filter_clip);
} break;
@@ -257,6 +262,30 @@ int Sprite::get_hframes() const {
return hframes;
}
+bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ if (texture.is_null())
+ return false;
+
+ Rect2 src_rect, dst_rect;
+ bool filter_clip;
+ _get_rects(src_rect, dst_rect, filter_clip);
+
+ if (!dst_rect.has_point(p_point))
+ return false;
+
+ Vector2 q = ((p_point - dst_rect.position) / dst_rect.size) * src_rect.size + src_rect.position;
+
+ Ref<Image> image = texture->get_data();
+ ERR_FAIL_COND_V(image.is_null(), false);
+
+ image->lock();
+ const Color c = image->get_pixel((int)q.x, (int)q.y);
+ image->unlock();
+
+ return c.a > 0.01;
+}
+
Rect2 Sprite::_edit_get_rect() const {
if (texture.is_null())
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index c437f6d404..7d9b2cf457 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -54,6 +54,8 @@ class Sprite : public Node2D {
int vframes;
int hframes;
+ void _get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const;
+
protected:
void _notification(int p_what);
@@ -65,6 +67,7 @@ public:
virtual void _edit_set_pivot(const Point2 &p_pivot);
virtual Point2 _edit_get_pivot() const;
virtual bool _edit_use_pivot() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
virtual Rect2 _edit_get_rect() const;
void set_texture(const Ref<Texture> &p_texture);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 73fce4be75..8bd5676bc7 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -336,7 +336,7 @@ void TileMap::_update_dirty_quadrants() {
debug_canvas_item = vs->canvas_item_create();
vs->canvas_item_set_parent(debug_canvas_item, canvas_item);
vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item, false);
- vs->canvas_item_set_z(debug_canvas_item, VS::CANVAS_ITEM_Z_MAX - 1);
+ vs->canvas_item_set_z_index(debug_canvas_item, VS::CANVAS_ITEM_Z_MAX - 1);
q.canvas_items.push_back(debug_canvas_item);
prev_debug_canvas_item = debug_canvas_item;
}
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index ef60a2151d..aaa378bb68 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -160,14 +160,14 @@ void Skeleton::_notification(int p_what) {
//if moved, just update transforms
VisualServer *vs = VisualServer::get_singleton();
- Bone *bonesptr = &bones[0];
+ const Bone *bonesptr = bones.ptr();
int len = bones.size();
Transform global_transform = get_global_transform();
Transform global_transform_inverse = global_transform.affine_inverse();
for (int i = 0; i < len; i++) {
- Bone &b = bonesptr[i];
+ const Bone &b = bonesptr[i];
vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse));
}
} break;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 6463180d9e..bac95c6cca 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -547,12 +547,14 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) {
//playback finished
- end_notify = true;
+ end_reached = true;
+ end_notify = cd.pos < len; // Notify only if not already at the end
}
if (backwards && cd.pos >= 0 && next_pos == 0 /*&& playback.blend.empty()*/) {
//playback finished
- end_notify = true;
+ end_reached = true;
+ end_notify = cd.pos > 0; // Notify only if not already at the beginning
}
}
@@ -679,24 +681,26 @@ void AnimationPlayer::_animation_process(float p_delta) {
if (playback.current.from) {
+ end_reached = false;
end_notify = false;
_animation_process2(p_delta);
_animation_update_transforms();
- if (end_notify) {
+ if (end_reached) {
if (queued.size()) {
String old = playback.assigned;
play(queued.front()->get());
String new_name = playback.assigned;
queued.pop_front();
- end_notify = false;
- emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
+ if (end_notify)
+ emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
} else {
//stop();
playing = false;
_set_process(false);
- end_notify = false;
- emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
+ if (end_notify)
+ emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
}
+ end_reached = false;
}
} else {
@@ -954,7 +958,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
c.current.speed_scale = p_custom_scale;
c.assigned = p_name;
- if (!end_notify)
+ if (!end_reached)
queued.clear();
_set_process(true); // always process when starting an animation
playing = true;
@@ -1348,6 +1352,7 @@ AnimationPlayer::AnimationPlayer() {
cache_update_size = 0;
cache_update_prop_size = 0;
speed_scale = 1;
+ end_reached = false;
end_notify = false;
animation_process_mode = ANIMATION_PROCESS_IDLE;
processing = false;
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 57c658e054..40a7252528 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -205,6 +205,7 @@ private:
List<StringName> queued;
+ bool end_reached;
bool end_notify;
String autoplay;
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 2f30337cb8..1711fbffee 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -561,57 +561,50 @@ void Tween::_tween_process(float p_delta) {
data.finish = true;
}
- switch (data.type) {
- case INTER_PROPERTY:
- case INTER_METHOD: {
- Variant result = _run_equation(data);
- emit_signal("tween_step", object, NodePath(Vector<StringName>(), data.key, false), data.elapsed, result);
- _apply_tween_value(data, result);
- if (data.finish)
- _apply_tween_value(data, data.final_val);
- } break;
-
- case INTER_CALLBACK:
- if (data.finish) {
- if (data.call_deferred) {
-
- switch (data.args) {
- case 0:
- object->call_deferred(data.key[0]);
- break;
- case 1:
- object->call_deferred(data.key[0], data.arg[0]);
- break;
- case 2:
- object->call_deferred(data.key[0], data.arg[0], data.arg[1]);
- break;
- case 3:
- object->call_deferred(data.key[0], data.arg[0], data.arg[1], data.arg[2]);
- break;
- case 4:
- object->call_deferred(data.key[0], data.arg[0], data.arg[1], data.arg[2], data.arg[3]);
- break;
- case 5:
- object->call_deferred(data.key[0], data.arg[0], data.arg[1], data.arg[2], data.arg[3], data.arg[4]);
- break;
- }
- } else {
- Variant::CallError error;
- Variant *arg[5] = {
- &data.arg[0],
- &data.arg[1],
- &data.arg[2],
- &data.arg[3],
- &data.arg[4],
- };
- object->call(data.key[0], (const Variant **)arg, data.args, error);
+ if (data.type == INTER_CALLBACK) {
+ if (data.finish) {
+ if (data.call_deferred) {
+
+ switch (data.args) {
+ case 0:
+ object->call_deferred(data.key[0]);
+ break;
+ case 1:
+ object->call_deferred(data.key[0], data.arg[0]);
+ break;
+ case 2:
+ object->call_deferred(data.key[0], data.arg[0], data.arg[1]);
+ break;
+ case 3:
+ object->call_deferred(data.key[0], data.arg[0], data.arg[1], data.arg[2]);
+ break;
+ case 4:
+ object->call_deferred(data.key[0], data.arg[0], data.arg[1], data.arg[2], data.arg[3]);
+ break;
+ case 5:
+ object->call_deferred(data.key[0], data.arg[0], data.arg[1], data.arg[2], data.arg[3], data.arg[4]);
+ break;
}
+ } else {
+ Variant::CallError error;
+ Variant *arg[5] = {
+ &data.arg[0],
+ &data.arg[1],
+ &data.arg[2],
+ &data.arg[3],
+ &data.arg[4],
+ };
+ object->call(data.key[0], (const Variant **)arg, data.args, error);
}
- break;
- default: {}
+ }
+ } else {
+ Variant result = _run_equation(data);
+ emit_signal("tween_step", object, NodePath(Vector<StringName>(), data.key, false), data.elapsed, result);
+ _apply_tween_value(data, result);
}
if (data.finish) {
+ _apply_tween_value(data, data.final_val);
emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
// not repeat mode, remove completed action
if (!repeat)
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 95298f5a18..63478886c6 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -209,6 +209,7 @@ Color ColorPicker::get_pick_color() const {
}
void ColorPicker::add_preset(const Color &p_color) {
+
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
} else {
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index b1c862d1d1..5a4a0b2106 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -930,6 +930,9 @@ void ItemList::_notification(int p_what) {
scroll_bar->hide();
} else {
scroll_bar->show();
+
+ if (do_autoscroll_to_bottom)
+ scroll_bar->set_value(max);
}
break;
}
@@ -1313,6 +1316,11 @@ Size2 ItemList::get_minimum_size() const {
return Size2();
}
+void ItemList::set_autoscroll_to_bottom(const bool p_enable) {
+
+ do_autoscroll_to_bottom = p_enable;
+}
+
void ItemList::set_auto_height(bool p_enable) {
auto_height = p_enable;
@@ -1466,6 +1474,7 @@ ItemList::ItemList() {
ensure_selected_visible = false;
defer_select_single = -1;
allow_rmb_select = false;
+ do_autoscroll_to_bottom = false;
icon_scale = 1.0f;
set_clip_contents(true);
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index df751d8b9d..e56d5e5224 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -107,6 +107,8 @@ private:
real_t icon_scale;
+ bool do_autoscroll_to_bottom;
+
Array _get_items() const;
void _set_items(const Array &p_items);
@@ -212,6 +214,8 @@ public:
Size2 get_minimum_size() const;
+ void set_autoscroll_to_bottom(const bool p_enable);
+
VScrollBar *get_v_scroll() { return scroll_bar; }
ItemList();
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 34abb1fbcc..dff7722a9e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -368,6 +368,18 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
shift_selection_check_post(k->get_shift());
} break;
+ case KEY_UP: {
+
+ shift_selection_check_pre(k->get_shift());
+ set_cursor_position(0);
+ shift_selection_check_post(k->get_shift());
+ } break;
+ case KEY_DOWN: {
+
+ shift_selection_check_pre(k->get_shift());
+ set_cursor_position(text.length());
+ shift_selection_check_post(k->get_shift());
+ } break;
case KEY_DELETE: {
if (!editable)
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index dde274e55e..87043c65eb 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1498,7 +1498,7 @@ void TextEdit::_notification(int p_what) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect());
if (raised_from_completion) {
- VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1);
+ VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1);
}
} break;
@@ -1512,7 +1512,7 @@ void TextEdit::_notification(int p_what) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard();
if (raised_from_completion) {
- VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0);
+ VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0);
}
} break;
}
@@ -2733,6 +2733,8 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_scroll_lines_down();
break;
}
+
+ {
#else
if (k->get_command() && k->get_alt()) {
_scroll_lines_down();
@@ -2741,9 +2743,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (k->get_command())
cursor_set_line(text.size() - 1, true, false);
- else
+ else {
#endif
- cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
+ if (!is_last_visible_line(cursor.line)) {
+ cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
+ } else {
+ cursor_set_line(text.size() - 1);
+ cursor_set_column(get_line(cursor.line).length(), true);
+ }
+ }
if (k->get_shift())
_post_shift_selection();
@@ -3139,6 +3147,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
void TextEdit::_scroll_up(real_t p_delta) {
+ if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(-p_delta))
+ scrolling = false;
+
if (scrolling) {
target_v_scroll = (target_v_scroll - p_delta);
} else {
@@ -3149,8 +3160,12 @@ void TextEdit::_scroll_up(real_t p_delta) {
if (target_v_scroll <= 0) {
target_v_scroll = 0;
}
- scrolling = true;
- set_physics_process(true);
+ if (Math::abs(target_v_scroll - v_scroll->get_value()) < 1.0) {
+ v_scroll->set_value(target_v_scroll);
+ } else {
+ scrolling = true;
+ set_physics_process(true);
+ }
} else {
v_scroll->set_value(target_v_scroll);
}
@@ -3158,6 +3173,9 @@ void TextEdit::_scroll_up(real_t p_delta) {
void TextEdit::_scroll_down(real_t p_delta) {
+ if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(p_delta))
+ scrolling = false;
+
if (scrolling) {
target_v_scroll = (target_v_scroll + p_delta);
} else {
@@ -3174,8 +3192,13 @@ void TextEdit::_scroll_down(real_t p_delta) {
if (target_v_scroll > max_v_scroll) {
target_v_scroll = max_v_scroll;
}
- scrolling = true;
- set_physics_process(true);
+
+ if (Math::abs(target_v_scroll - v_scroll->get_value()) < 1.0) {
+ v_scroll->set_value(target_v_scroll);
+ } else {
+ scrolling = true;
+ set_physics_process(true);
+ }
} else {
v_scroll->set_value(target_v_scroll);
}
@@ -4592,6 +4615,24 @@ int TextEdit::num_lines_from(int p_line_from, int unhidden_amount) const {
return num_total;
}
+bool TextEdit::is_last_visible_line(int p_line) const {
+
+ ERR_FAIL_INDEX_V(p_line, text.size(), false);
+
+ if (p_line == text.size() - 1)
+ return true;
+
+ if (!is_hiding_enabled())
+ return false;
+
+ for (int i = p_line + 1; i < text.size(); i++) {
+ if (!is_line_hidden(i))
+ return false;
+ }
+
+ return true;
+}
+
int TextEdit::get_indent_level(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
@@ -5021,7 +5062,7 @@ void TextEdit::_confirm_completion() {
void TextEdit::_cancel_code_hint() {
- VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0);
+ VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0);
raised_from_completion = false;
completion_hint = "";
update();
@@ -5029,7 +5070,7 @@ void TextEdit::_cancel_code_hint() {
void TextEdit::_cancel_completion() {
- VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0);
+ VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0);
raised_from_completion = false;
if (!completion_active)
return;
@@ -5204,7 +5245,7 @@ void TextEdit::query_code_comple() {
void TextEdit::set_code_hint(const String &p_hint) {
- VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1);
+ VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1);
raised_from_completion = true;
completion_hint = p_hint;
completion_hint_offset = -0xFFFF;
@@ -5213,7 +5254,7 @@ void TextEdit::set_code_hint(const String &p_hint) {
void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) {
- VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1);
+ VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1);
raised_from_completion = true;
completion_strings = p_strings;
completion_active = true;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 320bb6d9fd..ccd7ba8278 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -433,6 +433,7 @@ public:
void fold_all_lines();
void unhide_all_lines();
int num_lines_from(int p_line_from, int unhidden_amount) const;
+ bool is_last_visible_line(int p_line) const;
bool can_fold(int p_line) const;
bool is_folded(int p_line) const;
void fold_line(int p_line);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 07f93fa52b..632d912e43 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -2126,6 +2126,7 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_group", "name"), &SceneTree::has_group);
ClassDB::bind_method(D_METHOD("set_auto_accept_quit", "enabled"), &SceneTree::set_auto_accept_quit);
+ ClassDB::bind_method(D_METHOD("set_quit_on_go_back", "enabled"), &SceneTree::set_quit_on_go_back);
ClassDB::bind_method(D_METHOD("set_debug_collisions_hint", "enable"), &SceneTree::set_debug_collisions_hint);
ClassDB::bind_method(D_METHOD("is_debugging_collisions_hint"), &SceneTree::is_debugging_collisions_hint);
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 7b2dbf8e8c..2722ff7207 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -32,6 +32,25 @@
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
+Vector<Vector2> CapsuleShape2D::_get_points() const {
+
+ Vector<Vector2> points;
+ for (int i = 0; i < 24; i++) {
+ Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);
+
+ points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
+ if (i == 6 || i == 18)
+ points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
+ }
+
+ return points;
+}
+
+bool CapsuleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return Geometry::is_point_in_polygon(p_point, _get_points());
+}
+
void CapsuleShape2D::_update_shape() {
Physics2DServer::get_singleton()->shape_set_data(get_rid(), Vector2(radius, height));
@@ -62,15 +81,7 @@ real_t CapsuleShape2D::get_height() const {
void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
- Vector<Vector2> points;
- for (int i = 0; i < 24; i++) {
- Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);
-
- points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
- if (i == 6 || i == 18)
- points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
- }
-
+ Vector<Vector2> points = _get_points();
Vector<Color> col;
col.push_back(p_color);
VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h
index 7ce6a4ed63..784f2c02c8 100644
--- a/scene/resources/capsule_shape_2d.h
+++ b/scene/resources/capsule_shape_2d.h
@@ -39,11 +39,14 @@ class CapsuleShape2D : public Shape2D {
real_t radius;
void _update_shape();
+ Vector<Vector2> _get_points() const;
protected:
static void _bind_methods();
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_height(real_t p_height);
real_t get_height() const;
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index d9d0ddbe8f..669b1d8e7d 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -31,6 +31,12 @@
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
+
+bool CircleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return p_point.length() < get_radius() + p_tolerance;
+}
+
void CircleShape2D::_update_shape() {
Physics2DServer::get_singleton()->shape_set_data(get_rid(), radius);
diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h
index f14f8f6776..3668521a55 100644
--- a/scene/resources/circle_shape_2d.h
+++ b/scene/resources/circle_shape_2d.h
@@ -42,6 +42,8 @@ protected:
static void _bind_methods();
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_radius(real_t p_radius);
real_t get_radius() const;
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index 19985d4acf..69765796f6 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -32,6 +32,23 @@
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
+bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ PoolVector<Vector2> s = get_segments();
+ int len = s.size();
+ if (len == 0 || (len % 2) == 1)
+ return false;
+
+ PoolVector<Vector2>::Read r = s.read();
+ for (int i = 0; i < len; i += 2) {
+ Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, &r[i]);
+ if (p_point.distance_to(closest) < p_tolerance)
+ return true;
+ }
+
+ return false;
+}
+
void ConcavePolygonShape2D::set_segments(const PoolVector<Vector2> &p_segments) {
Physics2DServer::get_singleton()->shape_set_data(get_rid(), p_segments);
diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h
index 4a5defe72c..7ca14d4d66 100644
--- a/scene/resources/concave_polygon_shape_2d.h
+++ b/scene/resources/concave_polygon_shape_2d.h
@@ -39,6 +39,8 @@ protected:
static void _bind_methods();
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_segments(const PoolVector<Vector2> &p_segments);
PoolVector<Vector2> get_segments() const;
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 98ef2ca7c6..0402a70898 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -33,6 +33,11 @@
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
+bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return Geometry::is_point_in_polygon(p_point, points);
+}
+
void ConvexPolygonShape2D::_update_shape() {
Physics2DServer::get_singleton()->shape_set_data(get_rid(), points);
diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h
index f492b7651b..320cf94a5e 100644
--- a/scene/resources/convex_polygon_shape_2d.h
+++ b/scene/resources/convex_polygon_shape_2d.h
@@ -42,6 +42,8 @@ protected:
static void _bind_methods();
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_point_cloud(const Vector<Vector2> &p_points);
void set_points(const Vector<Vector2> &p_points);
Vector<Vector2> get_points() const;
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 4682ef5cb3..346599b25a 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -32,6 +32,13 @@
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
+bool SegmentShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ Vector2 l[2] = { a, b };
+ Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, l);
+ return p_point.distance_to(closest) < p_tolerance;
+}
+
void SegmentShape2D::_update_shape() {
Rect2 r;
diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h
index 1285ae4f82..39a71f61d5 100644
--- a/scene/resources/segment_shape_2d.h
+++ b/scene/resources/segment_shape_2d.h
@@ -44,6 +44,8 @@ protected:
static void _bind_methods();
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_a(const Vector2 &p_a);
void set_b(const Vector2 &p_b);
diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h
index 5c2c24ed74..877a159aee 100644
--- a/scene/resources/shape_2d.h
+++ b/scene/resources/shape_2d.h
@@ -44,6 +44,8 @@ protected:
Shape2D(const RID &p_rid);
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return true; }
+
void set_custom_solver_bias(real_t p_bias);
real_t get_custom_solver_bias() const;
diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/shape_line_2d.cpp
index c6cc3659f6..9548d35370 100644
--- a/scene/resources/shape_line_2d.cpp
+++ b/scene/resources/shape_line_2d.cpp
@@ -30,6 +30,21 @@
#include "shape_line_2d.h"
#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"
+
+bool LineShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ Vector2 point = get_d() * get_normal();
+ Vector2 l[2][2] = { { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 }, { point, point + get_normal() * 30 } };
+
+ for (int i = 0; i < 2; i++) {
+ Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, l[i]);
+ if (p_point.distance_to(closest) < p_tolerance)
+ return true;
+ }
+
+ return false;
+}
+
void LineShape2D::_update_shape() {
Array arr;
diff --git a/scene/resources/shape_line_2d.h b/scene/resources/shape_line_2d.h
index 747500b0ac..fe6f2d675e 100644
--- a/scene/resources/shape_line_2d.h
+++ b/scene/resources/shape_line_2d.h
@@ -44,6 +44,8 @@ protected:
static void _bind_methods();
public:
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+
void set_normal(const Vector2 &p_normal);
void set_d(real_t p_d);
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 60530e48e2..b163402a07 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -102,9 +102,9 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
}
if (ci->z_relative)
- p_z = CLAMP(p_z + ci->z, VS::CANVAS_ITEM_Z_MIN, VS::CANVAS_ITEM_Z_MAX);
+ p_z = CLAMP(p_z + ci->z_index, VS::CANVAS_ITEM_Z_MIN, VS::CANVAS_ITEM_Z_MAX);
else
- p_z = ci->z;
+ p_z = ci->z_index;
for (int i = 0; i < child_item_count; i++) {
@@ -805,14 +805,14 @@ void VisualServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_e
canvas_item->sort_y = p_enable;
}
-void VisualServerCanvas::canvas_item_set_z(RID p_item, int p_z) {
+void VisualServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
ERR_FAIL_COND(p_z < VS::CANVAS_ITEM_Z_MIN || p_z > VS::CANVAS_ITEM_Z_MAX);
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- canvas_item->z = p_z;
+ canvas_item->z_index = p_z;
}
void VisualServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index b86dd0316c..320fc2fb0b 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -39,7 +39,7 @@ public:
RID parent; // canvas it belongs to
List<Item *>::Element *E;
- int z;
+ int z_index;
bool z_relative;
bool sort_y;
Color modulate;
@@ -53,7 +53,7 @@ public:
Item() {
children_order_dirty = true;
E = NULL;
- z = 0;
+ z_index = 0;
modulate = Color(1, 1, 1, 1);
self_modulate = Color(1, 1, 1, 1);
sort_y = false;
@@ -187,7 +187,7 @@ public:
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
- void canvas_item_set_z(RID p_item, int p_z);
+ void canvas_item_set_z_index(RID p_item, int p_z);
void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable);
void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 95d7269d7a..864ae81140 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -586,7 +586,7 @@ public:
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
BIND2(canvas_item_add_clip_ignore, RID, bool)
BIND2(canvas_item_set_sort_children_by_y, RID, bool)
- BIND2(canvas_item_set_z, RID, int)
+ BIND2(canvas_item_set_z_index, RID, int)
BIND2(canvas_item_set_z_as_relative_to_parent, RID, bool)
BIND3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index a8422b805e..67b83b7618 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -6,6 +6,7 @@
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 4062f91438..276e445f4d 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -6,6 +6,7 @@
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -503,7 +504,7 @@ public:
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
FUNC2(canvas_item_add_clip_ignore, RID, bool)
FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
- FUNC2(canvas_item_set_z, RID, int)
+ FUNC2(canvas_item_set_z_index, RID, int)
FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index b4949b6093..bf6d425fb9 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1611,7 +1611,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &VisualServer::canvas_item_add_set_transform);
ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &VisualServer::canvas_item_add_clip_ignore);
ClassDB::bind_method(D_METHOD("canvas_item_set_sort_children_by_y", "item", "enabled"), &VisualServer::canvas_item_set_sort_children_by_y);
- ClassDB::bind_method(D_METHOD("canvas_item_set_z", "item", "z"), &VisualServer::canvas_item_set_z);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_z_index", "item", "z_index"), &VisualServer::canvas_item_set_z_index);
ClassDB::bind_method(D_METHOD("canvas_item_set_z_as_relative_to_parent", "item", "enabled"), &VisualServer::canvas_item_set_z_as_relative_to_parent);
ClassDB::bind_method(D_METHOD("canvas_item_set_copy_to_backbuffer", "item", "enabled", "rect"), &VisualServer::canvas_item_set_copy_to_backbuffer);
ClassDB::bind_method(D_METHOD("canvas_item_clear", "item"), &VisualServer::canvas_item_clear);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index e1def0b713..eb2c56cd3a 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -847,7 +847,7 @@ public:
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0;
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) = 0;
- virtual void canvas_item_set_z(RID p_item, int p_z) = 0;
+ virtual void canvas_item_set_z_index(RID p_item, int p_z) = 0;
virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) = 0;
virtual void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) = 0;
diff --git a/thirdparty/thekla_atlas/godot-changes.patch b/thirdparty/thekla_atlas/godot-changes.patch
new file mode 100644
index 0000000000..0e56403336
--- /dev/null
+++ b/thirdparty/thekla_atlas/godot-changes.patch
@@ -0,0 +1,154 @@
+diff --git a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp
+index 5ce452c..11e635d 100644
+--- a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp
++++ b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp
+@@ -142,9 +142,11 @@ AtlasPacker::AtlasPacker(Atlas * atlas) : m_atlas(atlas), m_bitmap(256, 256)
+ {
+ m_width = 0;
+ m_height = 0;
+-
+- m_debug_bitmap.allocate(256, 256);
+- m_debug_bitmap.fill(Color32(0,0,0,0));
++
++ // -- GODOT start --
++ //m_debug_bitmap.allocate(256, 256);
++ //m_debug_bitmap.fill(Color32(0,0,0,0));
++ // -- GODOT end --
+ }
+
+ AtlasPacker::~AtlasPacker()
+@@ -465,7 +467,11 @@ void AtlasPacker::packCharts(int quality, float texelsPerUnit, bool blockAligned
+ nvDebug("origin: %f %f\n", origin.x, origin.y);
+ nvDebug("majorAxis: %f %f\n", majorAxis.x, majorAxis.y);
+ nvDebug("minorAxis: %f %f\n", minorAxis.x, minorAxis.y);
+- nvDebugBreak();
++ // -- GODOT start --
++ //nvDebugBreak();
++ m_atlas->setFailed();
++ return;
++ // -- GODOT end --
+ }
+ //nvCheck(tmp.x >= 0 && tmp.y >= 0);
+
+@@ -597,8 +603,10 @@ void AtlasPacker::packCharts(int quality, float texelsPerUnit, bool blockAligned
+ m_bitmap.clearAll();
+ if (approximateExtent > m_bitmap.width()) {
+ m_bitmap.resize(approximateExtent, approximateExtent, false);
+- m_debug_bitmap.resize(approximateExtent, approximateExtent);
+- m_debug_bitmap.fill(Color32(0,0,0,0));
++ // -- GODOT start --
++ //m_debug_bitmap.resize(approximateExtent, approximateExtent);
++ //m_debug_bitmap.fill(Color32(0,0,0,0));
++ // -- GODOT end --
+ }
+
+
+@@ -680,20 +688,24 @@ void AtlasPacker::packCharts(int quality, float texelsPerUnit, bool blockAligned
+ {
+ //nvDebug("Resize bitmap (%d, %d).\n", nextPowerOfTwo(w), nextPowerOfTwo(h));
+ m_bitmap.resize(nextPowerOfTwo(U32(w)), nextPowerOfTwo(U32(h)), false);
+- m_debug_bitmap.resize(nextPowerOfTwo(U32(w)), nextPowerOfTwo(U32(h)));
++ // -- GODOT start --
++ //m_debug_bitmap.resize(nextPowerOfTwo(U32(w)), nextPowerOfTwo(U32(h)));
++ // -- GODOT end --
+ }
+
+ //nvDebug("Add chart at (%d, %d).\n", best_x, best_y);
+
+ addChart(&chart_bitmap, w, h, best_x, best_y, best_r, /*debugOutput=*/NULL);
+
++ // -- GODOT start --
+ // IC: Output chart again to debug bitmap.
+- if (chart->isVertexMapped()) {
++ /*if (chart->isVertexMapped()) {
+ addChart(&chart_bitmap, w, h, best_x, best_y, best_r, &m_debug_bitmap);
+ }
+ else {
+ addChart(chart, w, h, best_x, best_y, best_r, &m_debug_bitmap);
+- }
++ }*/
++ // -- GODOT end --
+
+ //float best_angle = 2 * PI * best_r;
+
+@@ -842,8 +854,10 @@ void AtlasPacker::packCharts(int quality, float texelsPerUnit, bool blockAligned
+ nvCheck(isAligned(m_width, 4));
+ nvCheck(isAligned(m_height, 4));
+
+- m_debug_bitmap.resize(m_width, m_height);
+- m_debug_bitmap.setFormat(Image::Format_ARGB);
++ // -- GODOT start --
++ //m_debug_bitmap.resize(m_width, m_height);
++ //m_debug_bitmap.setFormat(Image::Format_ARGB);
++ // -- GODOT end --
+
+ #if DEBUG_OUTPUT
+ //outputDebugBitmap("debug_packer_final.tga", m_bitmap, w, h);
+diff --git a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.h b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.h
+index 2d305f3..845dbfb 100644
+--- a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.h
++++ b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.h
+@@ -48,7 +48,9 @@ namespace nv
+
+ Atlas * m_atlas;
+ BitMap m_bitmap;
+- Image m_debug_bitmap;
++ // -- GODOT start --
++ //Image m_debug_bitmap;
++ // -- GODOT end --
+ RadixSort m_radix;
+
+ uint m_width;
+diff --git a/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp b/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp
+index d6f0acc..de1953d 100644
+--- a/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp
++++ b/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp
+@@ -2,6 +2,9 @@
+ #include "thekla_atlas.h"
+
+ #include <cfloat>
++// -- GODOT start --
++#include <stdio.h>
++// -- GODOT end --
+
+ #include "nvmesh/halfedge/Edge.h"
+ #include "nvmesh/halfedge/Mesh.h"
+@@ -112,6 +115,8 @@ static Atlas_Output_Mesh * mesh_atlas_to_output(const HalfEdge::Mesh * mesh, con
+ output->index_count = face_count * 3;
+ output->index_array = new int[face_count * 3];
+
++ // -- GODOT start --
++ int face_ofs = 0;
+ // Set face indices.
+ for (int f = 0; f < face_count; f++) {
+ uint c = charts->faceChartAt(f);
+@@ -121,14 +126,26 @@ static Atlas_Output_Mesh * mesh_atlas_to_output(const HalfEdge::Mesh * mesh, con
+ const Chart * chart = charts->chartAt(c);
+ nvDebugCheck(chart->faceAt(i) == f);
+
++ if (i >= chart->chartMesh()->faceCount()) {
++ printf("WARNING: Faces may be missing in the final vertex, which could not be packed\n");
++ continue;
++ }
++
+ const HalfEdge::Face * face = chart->chartMesh()->faceAt(i);
+ const HalfEdge::Edge * edge = face->edge;
+
+- output->index_array[3*f+0] = vertexOffset + edge->vertex->id;
+- output->index_array[3*f+1] = vertexOffset + edge->next->vertex->id;
+- output->index_array[3*f+2] = vertexOffset + edge->next->next->vertex->id;
++ //output->index_array[3*f+0] = vertexOffset + edge->vertex->id;
++ //output->index_array[3*f+1] = vertexOffset + edge->next->vertex->id;
++ //output->index_array[3*f+2] = vertexOffset + edge->next->next->vertex->id;
++ output->index_array[3 * face_ofs + 0] = vertexOffset + edge->vertex->id;
++ output->index_array[3 * face_ofs + 1] = vertexOffset + edge->next->vertex->id;
++ output->index_array[3 * face_ofs + 2] = vertexOffset + edge->next->next->vertex->id;
++ face_ofs++;
+ }
+
++ output->index_count = face_ofs * 3;
++ // -- GODOT end --
++
+ *error = Atlas_Error_Success;
+ output->atlas_width = w;
+ output->atlas_height = h;
diff --git a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp
index fd37b8c59c..11e635db17 100644
--- a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp
+++ b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp
@@ -467,7 +467,11 @@ void AtlasPacker::packCharts(int quality, float texelsPerUnit, bool blockAligned
nvDebug("origin: %f %f\n", origin.x, origin.y);
nvDebug("majorAxis: %f %f\n", majorAxis.x, majorAxis.y);
nvDebug("minorAxis: %f %f\n", minorAxis.x, minorAxis.y);
- nvDebugBreak();
+ // -- GODOT start --
+ //nvDebugBreak();
+ m_atlas->setFailed();
+ return;
+ // -- GODOT end --
}
//nvCheck(tmp.x >= 0 && tmp.y >= 0);