summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--SConstruct1
-rw-r--r--core/error_macros.h5
-rw-r--r--core/io/aes256.cpp170
-rw-r--r--core/io/resource_format_binary.cpp2
-rw-r--r--core/object.cpp27
-rw-r--r--core/object.h2
-rw-r--r--core/object_type_db.cpp39
-rw-r--r--core/object_type_db.h4
-rw-r--r--core/os/os.h1
-rw-r--r--core/ring_buffer.h6
-rw-r--r--core/script_language.cpp14
-rw-r--r--core/script_language.h3
-rw-r--r--core/ustring.cpp22
-rw-r--r--core/variant.h2
-rw-r--r--core/variant_call.cpp11
-rw-r--r--core/vector.h38
-rw-r--r--demos/gui/input_mapping/controls.scnbin2686 -> 2852 bytes
-rw-r--r--demos/viewport/gui_in_3d/gui.scnbin2270 -> 3267 bytes
-rw-r--r--doc/base/classes.xml25
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp69
-rw-r--r--drivers/gles2/shaders/canvas.glsl23
-rw-r--r--drivers/nrex/README.md4
-rw-r--r--drivers/nrex/nrex.cpp101
-rw-r--r--drivers/nrex/nrex.hpp41
-rw-r--r--drivers/nrex/regex.cpp6
-rw-r--r--drivers/nrex/regex.h2
-rw-r--r--drivers/theora/video_stream_theora.cpp117
-rw-r--r--drivers/theora/video_stream_theora.h32
-rw-r--r--drivers/unix/SCsub8
-rw-r--r--drivers/unix/os_unix.cpp8
-rw-r--r--drivers/unix/os_unix.h3
-rw-r--r--drivers/webp/dec/alpha.c2
-rw-r--r--drivers/webp/dec/decode_vp8.h2
-rw-r--r--drivers/webp/dec/webp.c2
-rw-r--r--drivers/webp/demux/anim_decode.c6
-rw-r--r--drivers/webp/demux/demux.c8
-rw-r--r--drivers/webp/dsp/dsp.h4
-rw-r--r--drivers/webp/dsp/lossless.h4
-rw-r--r--drivers/webp/enc/alpha.c2
-rw-r--r--drivers/webp/enc/backward_references.h4
-rw-r--r--drivers/webp/enc/config.c2
-rw-r--r--drivers/webp/enc/delta_palettization.c2
-rw-r--r--drivers/webp/enc/delta_palettization.h2
-rw-r--r--drivers/webp/enc/frame.c2
-rw-r--r--drivers/webp/enc/histogram.c2
-rw-r--r--drivers/webp/enc/histogram.h4
-rw-r--r--drivers/webp/enc/syntax.c4
-rw-r--r--drivers/webp/enc/vp8enci.h2
-rw-r--r--drivers/webp/enc/vp8l.c2
-rw-r--r--drivers/webp/enc/vp8li.h4
-rw-r--r--drivers/webp/mux/anim_encode.c8
-rw-r--r--drivers/webp/mux/muxi.h2
-rw-r--r--drivers/webp/utils/bit_reader.c2
-rw-r--r--drivers/webp/utils/bit_reader.h2
-rw-r--r--drivers/webp/utils/bit_reader_inl.h2
-rw-r--r--drivers/webp/utils/bit_writer.h2
-rw-r--r--drivers/webp/utils/color_cache.h2
-rw-r--r--drivers/webp/utils/endian_inl.h4
-rw-r--r--drivers/webp/utils/filters.h2
-rw-r--r--drivers/webp/utils/huffman.c2
-rw-r--r--drivers/webp/utils/huffman.h4
-rw-r--r--drivers/webp/utils/huffman_encode.c2
-rw-r--r--drivers/webp/utils/huffman_encode.h2
-rw-r--r--drivers/webp/utils/quant_levels.h2
-rw-r--r--drivers/webp/utils/quant_levels_dec.h2
-rw-r--r--drivers/webp/utils/random.h2
-rw-r--r--drivers/webp/utils/rescaler.h2
-rw-r--r--drivers/webp/utils/thread.h4
-rw-r--r--drivers/webp/utils/utils.c4
-rw-r--r--drivers/webp/utils/utils.h2
-rw-r--r--modules/gdscript/gd_script.cpp20
-rw-r--r--modules/gdscript/gd_script.h2
-rw-r--r--modules/gdscript/gd_tokenizer.cpp6
-rw-r--r--platform/android/export/export.cpp29
-rw-r--r--platform/bb10/export/export.cpp18
-rw-r--r--platform/javascript/export/export.cpp27
-rw-r--r--platform/osx/export/export.cpp23
-rw-r--r--platform/windows/detect.py1
-rw-r--r--platform/x11/detect.py7
-rw-r--r--platform/x11/os_x11.cpp5
-rw-r--r--platform/x11/platform_config.h2
-rw-r--r--scene/2d/canvas_item.cpp10
-rw-r--r--scene/2d/canvas_item.h1
-rw-r--r--scene/2d/joints_2d.cpp35
-rw-r--r--scene/2d/joints_2d.h5
-rw-r--r--scene/2d/light_2d.cpp3
-rw-r--r--scene/2d/light_2d.h1
-rw-r--r--scene/3d/physics_body.cpp15
-rw-r--r--scene/3d/physics_body.h2
-rw-r--r--scene/3d/physics_joint.cpp31
-rw-r--r--scene/3d/physics_joint.h4
-rw-r--r--scene/3d/spatial.cpp10
-rw-r--r--scene/3d/spatial.h1
-rw-r--r--scene/animation/animation_player.cpp87
-rw-r--r--scene/animation/animation_player.h2
-rw-r--r--scene/gui/file_dialog.cpp11
-rw-r--r--scene/gui/file_dialog.h3
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/main/node.cpp23
-rw-r--r--scene/main/node.h4
-rw-r--r--servers/physics/body_sw.cpp22
-rw-r--r--servers/physics/body_sw.h2
-rw-r--r--servers/physics/space_sw.cpp16
-rw-r--r--servers/physics_2d/body_2d_sw.cpp25
-rw-r--r--servers/physics_2d/body_2d_sw.h2
-rw-r--r--servers/visual/rasterizer.h7
-rw-r--r--servers/visual/shader_language.cpp14
-rw-r--r--servers/visual/visual_server_raster.cpp44
-rw-r--r--servers/visual/visual_server_raster.h4
-rw-r--r--servers/visual_server.h1
-rw-r--r--tools/editor/animation_editor.cpp171
-rw-r--r--tools/editor/animation_editor.h8
-rw-r--r--tools/editor/editor_file_dialog.cpp23
-rw-r--r--tools/editor/editor_file_dialog.h1
-rw-r--r--tools/editor/editor_import_export.cpp75
-rw-r--r--tools/editor/editor_import_export.h2
-rw-r--r--tools/editor/editor_layout_dialog.cpp59
-rw-r--r--tools/editor/editor_layout_dialog.h53
-rw-r--r--tools/editor/editor_node.cpp213
-rw-r--r--tools/editor/editor_node.h16
-rw-r--r--tools/editor/editor_settings.h1
-rw-r--r--tools/editor/groups_editor.cpp165
-rw-r--r--tools/editor/groups_editor.h36
-rw-r--r--tools/editor/icons/icon_key_invalid.pngbin0 -> 239 bytes
-rw-r--r--tools/editor/icons/icon_key_invalid_hover.pngbin0 -> 239 bytes
-rw-r--r--tools/editor/io_plugins/editor_font_import_plugin.cpp4
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp7
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.h4
-rw-r--r--tools/editor/plugins/item_list_editor_plugin.cpp365
-rw-r--r--tools/editor/plugins/item_list_editor_plugin.h138
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp4
-rw-r--r--tools/editor/project_settings.cpp29
-rw-r--r--tools/editor/property_editor.cpp14
-rw-r--r--tools/editor/property_editor.h4
135 files changed, 2029 insertions, 791 deletions
diff --git a/.gitignore b/.gitignore
index f24d91a7ee..d947306558 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ core/method_bind.inc
core/method_bind_ext.inc
core/script_encryption_key.cpp
core/global_defaults.cpp
+drivers/unix/os_unix_global_settings_path.cpp
tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h
tools/editor/editor_icons.cpp
diff --git a/SConstruct b/SConstruct
index f16f4f6d65..95ad0010a2 100644
--- a/SConstruct
+++ b/SConstruct
@@ -127,6 +127,7 @@ opts.Add("CXX", "Compiler");
opts.Add("CCFLAGS", "Custom flags for the C++ compiler");
opts.Add("CFLAGS", "Custom flags for the C compiler");
opts.Add("LINKFLAGS", "Custom flags for the linker");
+opts.Add('unix_global_settings_path', 'unix-specific path to system-wide settings. Currently only used by templates.','')
opts.Add('disable_3d', 'Disable 3D nodes for smaller executable (yes/no)', "no")
opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no")
opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no')
diff --git a/core/error_macros.h b/core/error_macros.h
index 76da88287b..cc88686301 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -207,6 +207,11 @@ extern bool _err_error_exists;
_err_error_exists=false;\
} \
+#define ERR_PRINTS(m_string) \
+ { \
+ _err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data()); \
+ _err_error_exists=false;\
+ } \
/** Print a warning string.
*/
diff --git a/core/io/aes256.cpp b/core/io/aes256.cpp
index e7f465dcc6..cfdac0214d 100644
--- a/core/io/aes256.cpp
+++ b/core/io/aes256.cpp
@@ -1,8 +1,8 @@
-/*
+/*
* Byte-oriented AES-256 implementation.
-* All lookup tables replaced with 'on the fly' calculations.
+* All lookup tables replaced with 'on the fly' calculations.
*
-* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
+* Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com
* Other contributors: Hal Finney
*
* Permission to use, copy, modify, and distribute this software for any
@@ -19,13 +19,33 @@
*/
#include "aes256.h"
-#define F(x) (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b))
#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
-// #define BACK_TO_TABLES
+#define BACK_TO_TABLES
+
+static uint8_t rj_xtime(uint8_t);
+static void aes_subBytes(uint8_t *);
+static void aes_subBytes_inv(uint8_t *);
+static void aes_addRoundKey(uint8_t *, uint8_t *);
+static void aes_addRoundKey_cpy(uint8_t *, uint8_t *, uint8_t *);
+static void aes_shiftRows(uint8_t *);
+static void aes_shiftRows_inv(uint8_t *);
+static void aes_mixColumns(uint8_t *);
+static void aes_mixColumns_inv(uint8_t *);
+static void aes_expandEncKey(uint8_t *, uint8_t *);
+static void aes_expandDecKey(uint8_t *, uint8_t *);
+#ifndef BACK_TO_TABLES
+static uint8_t gf_alog(uint8_t);
+static uint8_t gf_log(uint8_t);
+static uint8_t gf_mulinv(uint8_t);
+static uint8_t rj_sbox(uint8_t);
+static uint8_t rj_sbox_inv(uint8_t);
+#endif
+
#ifdef BACK_TO_TABLES
-const uint8_t sbox[256] = {
+static const uint8_t sbox[256] =
+{
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
@@ -59,7 +79,8 @@ const uint8_t sbox[256] = {
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
-const uint8_t sboxinv[256] = {
+static const uint8_t sboxinv[256] =
+{
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
@@ -100,55 +121,62 @@ const uint8_t sboxinv[256] = {
#else /* tableless subroutines */
/* -------------------------------------------------------------------------- */
-uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
+static uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
{
- uint8_t atb = 1, z;
+ uint8_t y = 1, i;
- while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;}
+ for (i = 0; i < x; i++) y ^= rj_xtime(y);
- return atb;
+ return y;
} /* gf_alog */
/* -------------------------------------------------------------------------- */
-uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
+static uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
{
- uint8_t atb = 1, i = 0, z;
+ uint8_t y, i = 0;
- do {
- if (atb == x) break;
- z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;
- } while (++i > 0);
+ if (x)
+ for (i = 1, y = 1; i > 0; i++ )
+ {
+ y ^= rj_xtime(y);
+ if (y == x) break;
+ }
return i;
} /* gf_log */
/* -------------------------------------------------------------------------- */
-uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
+static uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
{
return (x) ? gf_alog(255 - gf_log(x)) : 0;
} /* gf_mulinv */
/* -------------------------------------------------------------------------- */
-uint8_t rj_sbox(uint8_t x)
+static uint8_t rj_sbox(uint8_t x)
{
uint8_t y, sb;
sb = y = gf_mulinv(x);
- y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;
- y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;
+ y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
+ y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
+ y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
+ y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
return (sb ^ 0x63);
} /* rj_sbox */
/* -------------------------------------------------------------------------- */
-uint8_t rj_sbox_inv(uint8_t x)
+static uint8_t rj_sbox_inv(uint8_t x)
{
uint8_t y, sb;
y = x ^ 0x63;
- sb = y = (y<<1)|(y>>7);
- y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y;
+ sb = y = (uint8_t)(y << 1) | (y >> 7);
+ y = (uint8_t)(y << 2) | (y >> 6);
+ sb ^= y;
+ y = (uint8_t)(y << 3) | (y >> 5);
+ sb ^= y;
return gf_mulinv(sb);
} /* rj_sbox_inv */
@@ -156,13 +184,14 @@ uint8_t rj_sbox_inv(uint8_t x)
#endif
/* -------------------------------------------------------------------------- */
-uint8_t rj_xtime(uint8_t x)
+static uint8_t rj_xtime(uint8_t x)
{
- return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);
+ uint8_t y = (uint8_t)(x << 1);
+ return (x & 0x80) ? (y ^ 0x1b) : y;
} /* rj_xtime */
/* -------------------------------------------------------------------------- */
-void aes_subBytes(uint8_t *buf)
+static void aes_subBytes(uint8_t *buf)
{
register uint8_t i = 16;
@@ -170,7 +199,7 @@ void aes_subBytes(uint8_t *buf)
} /* aes_subBytes */
/* -------------------------------------------------------------------------- */
-void aes_subBytes_inv(uint8_t *buf)
+static void aes_subBytes_inv(uint8_t *buf)
{
register uint8_t i = 16;
@@ -178,7 +207,7 @@ void aes_subBytes_inv(uint8_t *buf)
} /* aes_subBytes_inv */
/* -------------------------------------------------------------------------- */
-void aes_addRoundKey(uint8_t *buf, uint8_t *key)
+static void aes_addRoundKey(uint8_t *buf, uint8_t *key)
{
register uint8_t i = 16;
@@ -186,49 +215,54 @@ void aes_addRoundKey(uint8_t *buf, uint8_t *key)
} /* aes_addRoundKey */
/* -------------------------------------------------------------------------- */
-void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
+static void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
{
register uint8_t i = 16;
- while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i];
+ while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];
} /* aes_addRoundKey_cpy */
/* -------------------------------------------------------------------------- */
-void aes_shiftRows(uint8_t *buf)
+static void aes_shiftRows(uint8_t *buf)
{
register uint8_t i, j; /* to make it potentially parallelable :) */
- i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i;
- i = buf[10]; buf[10] = buf[2]; buf[2] = i;
- j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j;
- j = buf[14]; buf[14] = buf[6]; buf[6] = j;
+ i = buf[1], buf[1] = buf[5], buf[5] = buf[9], buf[9] = buf[13], buf[13] = i;
+ i = buf[10], buf[10] = buf[2], buf[2] = i;
+ j = buf[3], buf[3] = buf[15], buf[15] = buf[11], buf[11] = buf[7], buf[7] = j;
+ j = buf[14], buf[14] = buf[6], buf[6] = j;
} /* aes_shiftRows */
/* -------------------------------------------------------------------------- */
-void aes_shiftRows_inv(uint8_t *buf)
+static void aes_shiftRows_inv(uint8_t *buf)
{
register uint8_t i, j; /* same as above :) */
- i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i;
- i = buf[2]; buf[2] = buf[10]; buf[10] = i;
- j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j;
- j = buf[6]; buf[6] = buf[14]; buf[14] = j;
+ i = buf[1], buf[1] = buf[13], buf[13] = buf[9], buf[9] = buf[5], buf[5] = i;
+ i = buf[2], buf[2] = buf[10], buf[10] = i;
+ j = buf[3], buf[3] = buf[7], buf[7] = buf[11], buf[11] = buf[15], buf[15] = j;
+ j = buf[6], buf[6] = buf[14], buf[14] = j;
} /* aes_shiftRows_inv */
/* -------------------------------------------------------------------------- */
-void aes_mixColumns(uint8_t *buf)
+static void aes_mixColumns(uint8_t *buf)
{
register uint8_t i, a, b, c, d, e;
for (i = 0; i < 16; i += 4)
{
- a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];
+ a = buf[i];
+ b = buf[i + 1];
+ c = buf[i + 2];
+ d = buf[i + 3];
e = a ^ b ^ c ^ d;
- buf[i] ^= e ^ rj_xtime(a^b); buf[i+1] ^= e ^ rj_xtime(b^c);
- buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a);
+ buf[i] ^= e ^ rj_xtime(a ^ b);
+ buf[i + 1] ^= e ^ rj_xtime(b ^ c);
+ buf[i + 2] ^= e ^ rj_xtime(c ^ d);
+ buf[i + 3] ^= e ^ rj_xtime(d ^ a);
}
} /* aes_mixColumns */
@@ -239,17 +273,23 @@ void aes_mixColumns_inv(uint8_t *buf)
for (i = 0; i < 16; i += 4)
{
- a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];
+ a = buf[i];
+ b = buf[i + 1];
+ c = buf[i + 2];
+ d = buf[i + 3];
e = a ^ b ^ c ^ d;
z = rj_xtime(e);
- x = e ^ rj_xtime(rj_xtime(z^a^c)); y = e ^ rj_xtime(rj_xtime(z^b^d));
- buf[i] ^= x ^ rj_xtime(a^b); buf[i+1] ^= y ^ rj_xtime(b^c);
- buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a);
+ x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
+ y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
+ buf[i] ^= x ^ rj_xtime(a ^ b);
+ buf[i + 1] ^= y ^ rj_xtime(b ^ c);
+ buf[i + 2] ^= x ^ rj_xtime(c ^ d);
+ buf[i + 3] ^= y ^ rj_xtime(d ^ a);
}
} /* aes_mixColumns_inv */
/* -------------------------------------------------------------------------- */
-void aes_expandEncKey(uint8_t *k, uint8_t *rc)
+static void aes_expandEncKey(uint8_t *k, uint8_t *rc)
{
register uint8_t i;
@@ -257,35 +297,35 @@ void aes_expandEncKey(uint8_t *k, uint8_t *rc)
k[1] ^= rj_sbox(k[30]);
k[2] ^= rj_sbox(k[31]);
k[3] ^= rj_sbox(k[28]);
- *rc = F( *rc);
+ *rc = rj_xtime( *rc);
- for(i = 4; i < 16; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
+ for(i = 4; i < 16; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
+ k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
k[16] ^= rj_sbox(k[12]);
k[17] ^= rj_sbox(k[13]);
k[18] ^= rj_sbox(k[14]);
k[19] ^= rj_sbox(k[15]);
- for(i = 20; i < 32; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
+ for(i = 20; i < 32; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
+ k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
} /* aes_expandEncKey */
/* -------------------------------------------------------------------------- */
-void aes_expandDecKey(uint8_t *k, uint8_t *rc)
+void aes_expandDecKey(uint8_t *k, uint8_t *rc)
{
uint8_t i;
- for(i = 28; i > 16; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
+ for(i = 28; i > 16; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
+ k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
k[16] ^= rj_sbox(k[12]);
k[17] ^= rj_sbox(k[13]);
k[18] ^= rj_sbox(k[14]);
k[19] ^= rj_sbox(k[15]);
- for(i = 12; i > 0; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
+ for(i = 12; i > 0; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
+ k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
*rc = FD(*rc);
k[0] ^= rj_sbox(k[29]) ^ (*rc);
@@ -302,7 +342,7 @@ void aes256_init(aes256_context *ctx, uint8_t *k)
register uint8_t i;
for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
- for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon);
+ for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon);
} /* aes256_init */
/* -------------------------------------------------------------------------- */
@@ -310,7 +350,7 @@ void aes256_done(aes256_context *ctx)
{
register uint8_t i;
- for (i = 0; i < sizeof(ctx->key); i++)
+ for (i = 0; i < sizeof(ctx->key); i++)
ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
} /* aes256_done */
@@ -330,7 +370,7 @@ void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
}
aes_subBytes(buf);
aes_shiftRows(buf);
- aes_expandEncKey(ctx->key, &rcon);
+ aes_expandEncKey(ctx->key, &rcon);
aes_addRoundKey(buf, ctx->key);
} /* aes256_encrypt */
@@ -345,7 +385,7 @@ void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
for (i = 14, rcon = 0x80; --i;)
{
- if( ( i & 1 ) )
+ if( ( i & 1 ) )
{
aes_expandDecKey(ctx->key, &rcon);
aes_addRoundKey(buf, &ctx->key[16]);
@@ -355,5 +395,5 @@ void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
aes_shiftRows_inv(buf);
aes_subBytes_inv(buf);
}
- aes_addRoundKey( buf, ctx->key);
+ aes_addRoundKey( buf, ctx->key);
} /* aes256_decrypt */
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 1a0552e8d1..4cd3cd595f 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -905,7 +905,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
error=ERR_FILE_UNRECOGNIZED;
ERR_EXPLAIN("Unrecognized binary resource file: "+local_path);
- ERR_FAIL_V();
+ ERR_FAIL();
}
bool big_endian = f->get_32();
diff --git a/core/object.cpp b/core/object.cpp
index 3a4c06e7e7..96f0c86832 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -314,6 +314,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
_edited=true;
#endif
+
if (script_instance) {
if (script_instance->set(p_name,p_value)) {
@@ -326,9 +327,9 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
//try built-in setgetter
{
- if (ObjectTypeDB::set_property(this,p_name,p_value)) {
- if (r_valid)
- *r_valid=true;
+ if (ObjectTypeDB::set_property(this,p_name,p_value,r_valid)) {
+ //if (r_valid)
+ // *r_valid=true;
return;
}
}
@@ -1694,6 +1695,26 @@ void Object::get_translatable_strings(List<String> *p_strings) const {
}
+Variant::Type Object::get_static_property_type(const StringName& p_property, bool *r_valid) const {
+
+ bool valid;
+ Variant::Type t = ObjectTypeDB::get_property_type(get_type_name(),p_property,&valid);
+ if (valid) {
+ if (r_valid)
+ *r_valid=true;
+ return t;
+ }
+
+ if (get_script_instance()) {
+ return get_script_instance()->get_property_type(p_property,r_valid);
+ }
+ if (r_valid)
+ *r_valid=false;
+
+ return Variant::NIL;
+
+}
+
bool Object::is_queued_for_deletion() const {
return _is_queued_for_deletion;
}
diff --git a/core/object.h b/core/object.h
index 981a83958c..5b6361796f 100644
--- a/core/object.h
+++ b/core/object.h
@@ -606,6 +606,8 @@ public:
void set_block_signals(bool p_block);
bool is_blocking_signals() const;
+ Variant::Type get_static_property_type(const StringName& p_property,bool *r_valid=NULL) const;
+
virtual void get_translatable_strings(List<String> *p_strings) const;
virtual void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp
index a64b3d2715..f8ba0a9b15 100644
--- a/core/object_type_db.cpp
+++ b/core/object_type_db.cpp
@@ -612,6 +612,7 @@ void ObjectTypeDB::add_property(StringName p_type,const PropertyInfo& p_pinfo, c
psg._setptr=mb_set;
psg._getptr=mb_get;
psg.index=p_index;
+ psg.type=p_pinfo.type;
type->property_setget[p_pinfo.name]=psg;
@@ -634,7 +635,7 @@ void ObjectTypeDB::get_property_list(StringName p_type,List<PropertyInfo> *p_lis
}
}
-bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value) {
+bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value,bool *r_valid) {
TypeInfo *type=types.getptr(p_object->get_type_name());
@@ -643,13 +644,17 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
- if (!psg->setter)
+ if (!psg->setter) {
+ if (r_valid)
+ *r_valid=false;
return true; //return true but do nothing
+ }
+
+ Variant::CallError ce;
if (psg->index>=0) {
Variant index=psg->index;
const Variant* arg[2]={&index,&p_value};
- Variant::CallError ce;
// p_object->call(psg->setter,arg,2,ce);
if (psg->_setptr) {
psg->_setptr->call(p_object,arg,2,ce);
@@ -660,13 +665,16 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c
} else {
const Variant* arg[1]={&p_value};
- Variant::CallError ce;
if (psg->_setptr) {
psg->_setptr->call(p_object,arg,1,ce);
} else {
p_object->call(psg->setter,arg,1,ce);
}
}
+
+ if (r_valid)
+ *r_valid=ce.error==Variant::CallError::CALL_OK;
+
return true;
}
@@ -718,6 +726,29 @@ bool ObjectTypeDB::get_property(Object* p_object,const StringName& p_property, V
return false;
}
+Variant::Type ObjectTypeDB::get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid) {
+
+ TypeInfo *type=types.getptr(p_type);
+ TypeInfo *check=type;
+ while(check) {
+ const PropertySetGet *psg = check->property_setget.getptr(p_property);
+ if (psg) {
+
+ if (r_is_valid)
+ *r_is_valid=true;
+
+ return psg->type;
+ }
+
+ check=check->inherits_ptr;
+ }
+ if (r_is_valid)
+ *r_is_valid=false;
+
+ return Variant::NIL;
+
+}
+
void ObjectTypeDB::set_method_flags(StringName p_type,StringName p_method,int p_flags) {
diff --git a/core/object_type_db.h b/core/object_type_db.h
index bfa0f921e5..319e3ec02c 100644
--- a/core/object_type_db.h
+++ b/core/object_type_db.h
@@ -117,6 +117,7 @@ class ObjectTypeDB {
StringName getter;
MethodBind *_setptr;
MethodBind *_getptr;
+ Variant::Type type;
};
struct TypeInfo {
@@ -456,8 +457,9 @@ public:
static void add_property(StringName p_type,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index=-1);
static void get_property_list(StringName p_type,List<PropertyInfo> *p_list,bool p_no_inheritance=false);
- static bool set_property(Object* p_object,const StringName& p_property, const Variant& p_value);
+ static bool set_property(Object* p_object, const StringName& p_property, const Variant& p_value, bool *r_valid=NULL);
static bool get_property(Object* p_object,const StringName& p_property, Variant& r_value);
+ static Variant::Type get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid=NULL);
diff --git a/core/os/os.h b/core/os/os.h
index e5338b4a02..e908177df7 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -184,6 +184,7 @@ public:
virtual void set_low_processor_usage_mode(bool p_enabled);
virtual bool is_in_low_processor_usage_mode() const;
+ virtual String get_installed_templates_path() const { return ""; };
virtual String get_executable_path() const;
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL)=0;
virtual Error kill(const ProcessID& p_pid)=0;
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index 3cf9cf9064..5cbd261ec8 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -155,6 +155,12 @@ public:
inline int size() {
return data.size();
};
+
+ inline void clear() {
+ read_pos = 0;
+ write_pos = 0;
+
+ }
void resize(int p_power) {
int old_size = size();
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 35c50b1022..b7a0f579f4 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -267,6 +267,20 @@ void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properti
}
}
+Variant::Type PlaceHolderScriptInstance::get_property_type(const StringName& p_name,bool *r_is_valid) const {
+
+ if (values.has(p_name)) {
+ if (r_is_valid)
+ *r_is_valid=true;
+ return values[p_name].get_type();
+ }
+ if (r_is_valid)
+ *r_is_valid=false;
+
+ return Variant::NIL;
+}
+
+
void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties,const Map<StringName,Variant>& p_values) {
diff --git a/core/script_language.h b/core/script_language.h
index 5a0f673b94..9660f141c7 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -82,6 +82,7 @@ public:
virtual StringName get_instance_base_type() const=0; // this may not work in all scripts, will return empty if so
virtual ScriptInstance* instance_create(Object *p_this)=0;
virtual bool instance_has(const Object *p_this) const=0;
+
virtual bool has_source_code() const=0;
virtual String get_source_code() const=0;
@@ -109,6 +110,7 @@ public:
virtual bool set(const StringName& p_name, const Variant& p_value)=0;
virtual bool get(const StringName& p_name, Variant &r_ret) const=0;
virtual void get_property_list(List<PropertyInfo> *p_properties) const=0;
+ virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const=0;
virtual void get_method_list(List<MethodInfo> *p_list) const=0;
virtual bool has_method(const StringName& p_method) const=0;
@@ -208,6 +210,7 @@ public:
virtual bool set(const StringName& p_name, const Variant& p_value);
virtual bool get(const StringName& p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const;
virtual void get_method_list(List<MethodInfo> *p_list) const {}
virtual bool has_method(const StringName& p_method) const { return false; }
diff --git a/core/ustring.cpp b/core/ustring.cpp
index f3c89a7908..bf2494e9b5 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -897,17 +897,8 @@ String String::num(double p_num,int p_decimals) {
}
char buf[256];
-#if defined(__GNUC__)
-#ifdef MINGW_ENABLED
- //snprintf is inexplicably broken in mingw
- //sprintf(buf,fmt,p_num);
- _snprintf(buf,256,fmt,p_num);
-#else
+#if defined(__GNUC__) || defined(_MSC_VER)
snprintf(buf,256,fmt,p_num);
-#endif
-
-#elif defined(_MSC_VER)
- _snprintf(buf,256,fmt,p_num);
#else
sprintf(buf,fmt,p_num);
#endif
@@ -1178,10 +1169,7 @@ String String::num_scientific(double p_num) {
char buf[256];
-#if defined(_MSC_VER) || defined(MINGW_ENABLED)
-
- _snprintf(buf,256,"%lg",p_num);
-#elif defined(__GNUC__)
+#if defined(__GNUC__) || defined(_MSC_VER)
snprintf(buf,256,"%lg",p_num);
#else
sprintf(buf,"%.16lg",p_num);
@@ -3096,7 +3084,11 @@ String String::http_escape() const {
res += ord;
} else {
char h_Val[3];
- snprintf(h_Val, 3, "%.2X", ord);
+#if defined(__GNUC__) || defined(_MSC_VER)
+ snprintf(h_Val, 3, "%.2X", ord);
+#else
+ sprintf(h_Val, "%.2X", ord);
+#endif
res += "%";
res += h_Val;
}
diff --git a/core/variant.h b/core/variant.h
index 8fd9662c36..e75a2b1c92 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -390,7 +390,7 @@ public:
Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error);
Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant());
- static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error);
+ static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error,bool p_strict=true);
void get_method_list(List<MethodInfo> *p_list) const;
bool has_method(const StringName& p_method) const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 48c38f05f9..2d10cf4d44 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -858,6 +858,11 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
r_ret=Transform(p_args[0]->operator Matrix3(),p_args[1]->operator Vector3());
}
+ static void Image_init1(Variant& r_ret, const Variant** p_args) {
+
+ r_ret=Image(*p_args[0],*p_args[1],*p_args[2],Image::Format(p_args[3]->operator int()));
+ }
+
static void add_constructor(VariantConstructFunc p_func,const Variant::Type p_type,
const String& p_name1="", const Variant::Type p_type1=Variant::NIL,
const String& p_name2="", const Variant::Type p_type2=Variant::NIL,
@@ -959,7 +964,7 @@ Variant Variant::call(const StringName& p_method,const Variant** p_args,int p_ar
#define VCALL(m_type,m_method) _VariantCall::_call_##m_type##_##m_method
-Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int p_argcount,CallError &r_error) {
+Variant Variant::construct(const Variant::Type p_type, const Variant** p_args, int p_argcount, CallError &r_error, bool p_strict) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_INDEX_V(p_type,VARIANT_MAX,Variant());
@@ -1035,7 +1040,7 @@ Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int
} else if (p_argcount==1 && p_args[0]->type==p_type) {
return *p_args[0]; //copy construct
- } else if (p_argcount==1 && Variant::can_convert(p_args[0]->type,p_type)) {
+ } else if (p_argcount==1 && (!p_strict || Variant::can_convert(p_args[0]->type,p_type))) {
//near match construct
switch(p_type) {
@@ -1583,6 +1588,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
_VariantCall::add_constructor(_VariantCall::Transform_init1,Variant::TRANSFORM,"x_axis",Variant::VECTOR3,"y_axis",Variant::VECTOR3,"z_axis",Variant::VECTOR3,"origin",Variant::VECTOR3);
_VariantCall::add_constructor(_VariantCall::Transform_init2,Variant::TRANSFORM,"basis",Variant::MATRIX3,"origin",Variant::VECTOR3);
+ _VariantCall::add_constructor(_VariantCall::Image_init1,Variant::IMAGE,"width",Variant::INT,"height",Variant::INT,"mipmaps",Variant::BOOL,"format",Variant::INT);
+
/* REGISTER CONSTANTS */
_VariantCall::constant_data[Variant::VECTOR3].value["AXIS_X"]=Vector3::AXIS_X;
diff --git a/core/vector.h b/core/vector.h
index d103400622..78dff5eadb 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -42,7 +42,7 @@
template<class T>
class Vector {
- mutable void* _ptr;
+ mutable T* _ptr;
// internal helpers
@@ -51,21 +51,21 @@ class Vector {
if (!_ptr)
return NULL;
- return reinterpret_cast<SafeRefCount*>(_ptr);
+ return reinterpret_cast<SafeRefCount*>((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount));
}
_FORCE_INLINE_ int* _get_size() const {
if (!_ptr)
return NULL;
- return reinterpret_cast<int*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount));
+ return reinterpret_cast<int*>((uint8_t*)_ptr-sizeof(int));
}
_FORCE_INLINE_ T* _get_data() const {
if (!_ptr)
return NULL;
- return reinterpret_cast<T*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount)+sizeof(int));
+ return reinterpret_cast<T*>(_ptr);
}
@@ -88,11 +88,11 @@ public:
_FORCE_INLINE_ void clear() { resize(0); }
_FORCE_INLINE_ int size() const {
-
- if (!_ptr)
- return 0;
+ int* size = _get_size();
+ if (size)
+ return *size;
else
- return *reinterpret_cast<int*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount));
+ return 0;
}
_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
Error resize(int p_size);
@@ -174,7 +174,7 @@ void Vector<T>::_unref(void *p_data) {
if (!p_data)
return;
- SafeRefCount *src = reinterpret_cast<SafeRefCount*>(p_data);
+ SafeRefCount *src = reinterpret_cast<SafeRefCount*>((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
if (!src->unref())
return; // still in use
@@ -189,7 +189,7 @@ void Vector<T>::_unref(void *p_data) {
}
// free mem
- memfree(p_data);
+ memfree((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
}
@@ -201,7 +201,8 @@ void Vector<T>::_copy_on_write() {
if (_get_refcount()->get() > 1 ) {
/* in use by more than me */
- SafeRefCount *src_new=(SafeRefCount *)memalloc(_get_alloc_size(*_get_size()));
+ void* mem_new = memalloc(_get_alloc_size(*_get_size()));
+ SafeRefCount *src_new=(SafeRefCount *)mem_new;
src_new->init();
int * _size = (int*)(src_new+1);
*_size=*_get_size();
@@ -215,7 +216,7 @@ void Vector<T>::_copy_on_write() {
}
_unref(_ptr);
- _ptr=src_new;
+ _ptr=_data;
}
}
@@ -260,16 +261,17 @@ Error Vector<T>::resize(int p_size) {
if (size()==0) {
// alloc from scratch
- _ptr = (T*)memalloc(_get_alloc_size(p_size));
- ERR_FAIL_COND_V( !_ptr ,ERR_OUT_OF_MEMORY);
+ void* ptr=memalloc(_get_alloc_size(p_size));
+ ERR_FAIL_COND_V( !ptr ,ERR_OUT_OF_MEMORY);
+ _ptr=(T*)((uint8_t*)ptr+sizeof(int)+sizeof(SafeRefCount));
_get_refcount()->init(); // init refcount
*_get_size()=0; // init size (currently, none)
} else {
- void *_ptrnew = (T*)memrealloc(_ptr,_get_alloc_size(p_size));
+ void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
- _ptr=_ptrnew;
+ _ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
}
// construct the newly created elements
@@ -291,10 +293,10 @@ Error Vector<T>::resize(int p_size) {
t->~T();
}
- void *_ptrnew = (T*)memrealloc(_ptr,_get_alloc_size(p_size));
+ void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
- _ptr=_ptrnew;
+ _ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
*_get_size()=p_size;
diff --git a/demos/gui/input_mapping/controls.scn b/demos/gui/input_mapping/controls.scn
index 276712ba22..03567fb691 100644
--- a/demos/gui/input_mapping/controls.scn
+++ b/demos/gui/input_mapping/controls.scn
Binary files differ
diff --git a/demos/viewport/gui_in_3d/gui.scn b/demos/viewport/gui_in_3d/gui.scn
index 4d665226b7..5e8c04754e 100644
--- a/demos/viewport/gui_in_3d/gui.scn
+++ b/demos/viewport/gui_in_3d/gui.scn
Binary files differ
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index fd5df945ba..39b3791e84 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -13147,6 +13147,21 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
+ <method name="Image">
+ <return type="Image">
+ </return>
+ <argument index="0" name="width" type="int">
+ </argument>
+ <argument index="1" name="height" type="int">
+ </argument>
+ <argument index="2" name="mipmaps" type="bool">
+ </argument>
+ <argument index="3" name="format" type="int">
+ </argument>
+ <description>
+ Create an empty image of a specific size and format.
+ </description>
+ </method>
</methods>
<constants>
<constant name="COMPRESS_BC" value="0">
@@ -15038,14 +15053,13 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
- <method name="can_move_to">
+ <method name="can_teleport_to">
<return type="bool">
</return>
<argument index="0" name="position" type="Vector3">
</argument>
- <argument index="1" name="arg1" type="bool">
- </argument>
<description>
+ Returns whether the KinematicBody can be teleported to the destination given as an argument, checking all collision shapes of the body against potential colliders at the destination.
</description>
</method>
<method name="is_colliding" qualifiers="const">
@@ -26945,7 +26959,7 @@ This method controls whether the position between two cached points is interpola
Lazy (non-greedy) quantifiers [code]*?[/code]
Begining [code]^[/code] and end [code]$[/code] anchors
Alternation [code]|[/code]
- Backreferences [code]\1[/code] to [code]\9[/code]
+ Backreferences [code]\1[/code] and [code]\g{1}[/code]
POSIX character classes [code][[:alnum:]][/code]
Lookahead [code](?=)[/code], [code](?!)[/code] and lookbehind [code](?&lt;=)[/code], [code](?&lt;!)[/code]
ASCII [code]\xFF[/code] and Unicode [code]\uFFFF[/code] code points (in a style similar to Python)
@@ -26957,9 +26971,10 @@ This method controls whether the position between two cached points is interpola
</return>
<argument index="0" name="pattern" type="String">
</argument>
- <argument index="1" name="expanded" type="bool" default="true">
+ <argument index="1" name="capture" type="int" default="9">
</argument>
<description>
+ Compiles and assign the regular expression pattern to use. The limit on the number of capturing groups can be specified or made unlimited if negative.
</description>
</method>
<method name="find" qualifiers="const">
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index c6d8d9e9bf..83b71fd5ff 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -9169,10 +9169,23 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem
//glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
//current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
- int x = current_clip->final_clip_rect.pos.x;
- int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
- int w = current_clip->final_clip_rect.size.x;
- int h = current_clip->final_clip_rect.size.y;
+ int x;
+ int y;
+ int w;
+ int h;
+
+ if (current_rt) {
+ x = current_clip->final_clip_rect.pos.x;
+ y = current_clip->final_clip_rect.pos.y;
+ w = current_clip->final_clip_rect.size.x;
+ h = current_clip->final_clip_rect.size.y;
+ }
+ else {
+ x = current_clip->final_clip_rect.pos.x;
+ y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
+ w = current_clip->final_clip_rect.size.x;
+ h = current_clip->final_clip_rect.size.y;
+ }
glScissor(x,y,w,h);
@@ -9362,10 +9375,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
*/
- int x = current_clip->final_clip_rect.pos.x;
- int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
- int w = current_clip->final_clip_rect.size.x;
- int h = current_clip->final_clip_rect.size.y;
+ int x;
+ int y;
+ int w;
+ int h;
+
+ if (current_rt) {
+ x = current_clip->final_clip_rect.pos.x;
+ y = current_clip->final_clip_rect.pos.y;
+ w = current_clip->final_clip_rect.size.x;
+ h = current_clip->final_clip_rect.size.y;
+ }
+ else {
+ x = current_clip->final_clip_rect.pos.x;
+ y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
+ w = current_clip->final_clip_rect.size.x;
+ h = current_clip->final_clip_rect.size.y;
+ }
glScissor(x,y,w,h);
@@ -9514,7 +9540,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
canvas_opacity = ci->final_opacity;
- if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT)))
+ if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT) && !ci->light_masked ))
_canvas_item_render_commands<false>(ci,current_clip,reclip);
if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && !unshaded) {
@@ -9546,7 +9572,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
} break;
- case VS::CANVAS_LIGHT_MODE_MIX: {
+ case VS::CANVAS_LIGHT_MODE_MIX:
+ case VS::CANVAS_LIGHT_MODE_MASK: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -9594,6 +9621,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,Color(light->color.r*light->energy,light->color.g*light->energy,light->color.b*light->energy,light->color.a));
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height);
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse());
+ canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_OUTSIDE_ALPHA,light->mode==VS::CANVAS_LIGHT_MODE_MASK?1.0:0.0);
if (has_shadow) {
@@ -9667,10 +9695,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
//glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
//current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
- int x = current_clip->final_clip_rect.pos.x;
- int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
- int w = current_clip->final_clip_rect.size.x;
- int h = current_clip->final_clip_rect.size.y;
+ int x;
+ int y;
+ int w;
+ int h;
+
+ if (current_rt) {
+ x = current_clip->final_clip_rect.pos.x;
+ y = current_clip->final_clip_rect.pos.y;
+ w = current_clip->final_clip_rect.size.x;
+ h = current_clip->final_clip_rect.size.y;
+ }
+ else {
+ x = current_clip->final_clip_rect.pos.x;
+ y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
+ w = current_clip->final_clip_rect.size.x;
+ h = current_clip->final_clip_rect.size.y;
+ }
glScissor(x,y,w,h);
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index e297b328cd..259e82d704 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -155,6 +155,7 @@ uniform vec4 light_color;
uniform vec4 light_shadow_color;
uniform float light_height;
varying vec4 light_uv_interp;
+uniform float light_outside_alpha;
#if defined(NORMAL_USED)
varying vec4 local_rot;
@@ -247,22 +248,27 @@ FRAGMENT_SHADER_CODE
vec4 shadow_color=vec4(0.0,0.0,0.0,0.0);
#endif
+ if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) {
+ color.a*=light_outside_alpha; //invisible
+
+ } else {
+
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
-{
- vec4 light_out=light*color;
+ {
+ vec4 light_out=light*color;
LIGHT_SHADER_CODE
- color=light_out;
-}
+ color=light_out;
+ }
#else
#if defined(NORMAL_USED)
- vec3 light_normal = normalize(vec3(light_vec,-light_height));
- light*=max(dot(-light_normal,normal),0.0);
+ vec3 light_normal = normalize(vec3(light_vec,-light_height));
+ light*=max(dot(-light_normal,normal),0.0);
#endif
- color*=light;
+ color*=light;
/*
#ifdef USE_NORMAL
color.xy=local_rot.xy;//normal.xy;
@@ -273,9 +279,6 @@ LIGHT_SHADER_CODE
//light shader code
#endif
- if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) {
- color.a=0.0; //invisible
- } else {
#ifdef USE_SHADOWS
diff --git a/drivers/nrex/README.md b/drivers/nrex/README.md
index 951b301c1e..9ff67992dc 100644
--- a/drivers/nrex/README.md
+++ b/drivers/nrex/README.md
@@ -1,5 +1,7 @@
# NREX: Node RegEx
+Version 0.1
+
Small node-based regular expression library. It only does text pattern
matchhing, not replacement. To use add the files `nrex.hpp`, `nrex.cpp`
and `nrex_config.h` to your project and follow the example:
@@ -32,7 +34,7 @@ Currently supported features:
* Unicode `\uFFFF` code points
* Positive `(?=)` and negative `(?!)` lookahead
* Positive `(?<=)` and negative `(?<!)` lookbehind (fixed length and no alternations)
- * Backreferences `\1` to `\9` (with option to expand to `\99`)
+ * Backreferences `\1` and `\g{1}` (limited by default to 9 - can be unlimited)
## License
diff --git a/drivers/nrex/nrex.cpp b/drivers/nrex/nrex.cpp
index 104e07f887..1eb9ec38c8 100644
--- a/drivers/nrex/nrex.cpp
+++ b/drivers/nrex/nrex.cpp
@@ -1,4 +1,5 @@
// NREX: Node RegEx
+// Version 0.1
//
// Copyright (c) 2015, Zher Huei Lee
// All rights reserved.
@@ -299,6 +300,10 @@ struct nrex_node_group : public nrex_node
{
length = 1;
}
+ if (mode == LookAhead || mode == LookBehind)
+ {
+ quantifiable = false;
+ }
}
virtual ~nrex_node_group()
@@ -322,6 +327,10 @@ struct nrex_node_group : public nrex_node
int offset = 0;
if (mode == LookBehind)
{
+ if (pos < length)
+ {
+ return -1;
+ }
offset = length;
}
int res = childset[i]->test(s, pos - offset);
@@ -450,7 +459,7 @@ struct nrex_node_char : public nrex_node
int test(nrex_search* s, int pos) const
{
- if (s->end == pos || s->at(pos) != ch)
+ if (s->end <= pos || 0 > pos || s->at(pos) != ch)
{
return -1;
}
@@ -473,7 +482,7 @@ struct nrex_node_range : public nrex_node
int test(nrex_search* s, int pos) const
{
- if (s->end == pos)
+ if (s->end <= pos || 0 > pos)
{
return -1;
}
@@ -555,7 +564,7 @@ struct nrex_node_class : public nrex_node
int test(nrex_search* s, int pos) const
{
- if (s->end == pos)
+ if (s->end <= pos || 0 > pos)
{
return -1;
}
@@ -727,7 +736,7 @@ struct nrex_node_shorthand : public nrex_node
int test(nrex_search* s, int pos) const
{
- if (s->end == pos)
+ if (s->end <= pos || 0 > pos)
{
return -1;
}
@@ -811,16 +820,12 @@ struct nrex_node_quantifier : public nrex_node
int test(nrex_search* s, int pos) const
{
- return test_step(s, pos, 1);
+ return test_step(s, pos, 0, pos);
}
- int test_step(nrex_search* s, int pos, int level) const
+ int test_step(nrex_search* s, int pos, int level, int start) const
{
- if (max == 0)
- {
- return pos;
- }
- if ((max >= 1 && level > max) || pos > s->end)
+ if (pos > s->end)
{
return -1;
}
@@ -840,14 +845,26 @@ struct nrex_node_quantifier : public nrex_node
return res;
}
}
- int res = child->test(s, pos);
- if (s->complete)
+ if (max >= 0 && level > max)
{
- return res;
+ return -1;
+ }
+ if (level > 1 && level > min + 1 && pos == start)
+ {
+ return -1;
+ }
+ int res = pos;
+ if (level >= 1)
+ {
+ res = child->test(s, pos);
+ if (s->complete)
+ {
+ return res;
+ }
}
if (res >= 0)
{
- int res_step = test_step(s, res, level + 1);
+ int res_step = test_step(s, res, level + 1, start);
if (res_step >= 0)
{
return res_step;
@@ -983,6 +1000,13 @@ nrex::nrex()
{
}
+nrex::nrex(const nrex_char* pattern, int captures)
+ : _capturing(0)
+ , _root(NULL)
+{
+ compile(pattern, captures);
+}
+
nrex::~nrex()
{
if (_root)
@@ -1008,10 +1032,14 @@ void nrex::reset()
int nrex::capture_size() const
{
- return _capturing + 1;
+ if (_root)
+ {
+ return _capturing + 1;
+ }
+ return 0;
}
-bool nrex::compile(const nrex_char* pattern, bool extended)
+bool nrex::compile(const nrex_char* pattern, int captures)
{
reset();
nrex_node_group* root = NREX_NEW(nrex_node_group(_capturing));
@@ -1053,7 +1081,7 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
NREX_COMPILE_ERROR("unrecognised qualifier for group");
}
}
- else if ((!extended && _capturing < 9) || (extended && _capturing < 99))
+ else if (captures >= 0 && _capturing < captures)
{
nrex_node_group* group = NREX_NEW(nrex_node_group(++_capturing));
stack.top()->add_child(group);
@@ -1190,15 +1218,6 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
}
else if (nrex_is_quantifier(c[0]))
{
- if (stack.top()->back == NULL || !stack.top()->back->quantifiable)
- {
- if (c[0] == '{')
- {
- stack.top()->add_child(NREX_NEW(nrex_node_char('{')));
- continue;
- }
- NREX_COMPILE_ERROR("element not quantifiable");
- }
int min = 0;
int max = -1;
bool valid_quantifier = true;
@@ -1270,6 +1289,10 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
}
if (valid_quantifier)
{
+ if (stack.top()->back == NULL || !stack.top()->back->quantifiable)
+ {
+ NREX_COMPILE_ERROR("element not quantifiable");
+ }
nrex_node_quantifier* quant = NREX_NEW(nrex_node_quantifier(min, max));
if (min == max)
{
@@ -1323,20 +1346,26 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
stack.top()->add_child(NREX_NEW(nrex_node_shorthand(c[1])));
++c;
}
- else if ('1' <= c[1] && c[1] <= '9')
+ else if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{'))
{
int ref = 0;
- if (extended && '0' <= c[2] && c[2] <= '9')
+ bool unclosed = false;
+ if (c[1] == 'g')
{
- ref = int(c[1] - '0') * 10 + int(c[2] - '0');
+ unclosed = true;
c = &c[2];
}
- else
+ while ('0' <= c[1] && c[1] <= '9')
{
- ref = int(c[1] - '0');
+ ref = ref * 10 + int(c[1] - '0');
++c;
}
- if (ref > _capturing)
+ if (c[1] == '}')
+ {
+ unclosed = false;
+ ++c;
+ }
+ if (ref > _capturing || ref <= 0 || unclosed)
{
NREX_COMPILE_ERROR("backreference to non-existent capture");
}
@@ -1377,6 +1406,10 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
bool nrex::match(const nrex_char* str, nrex_result* captures, int offset, int end) const
{
+ if (!_root)
+ {
+ return false;
+ }
nrex_search s(str, captures);
if (end >= offset)
{
@@ -1386,7 +1419,7 @@ bool nrex::match(const nrex_char* str, nrex_result* captures, int offset, int en
{
s.end = NREX_STRLEN(str);
}
- for (int i = offset; i < s.end; ++i)
+ for (int i = offset; i <= s.end; ++i)
{
for (int c = 0; c <= _capturing; ++c)
{
diff --git a/drivers/nrex/nrex.hpp b/drivers/nrex/nrex.hpp
index e26a61c39a..44e950c517 100644
--- a/drivers/nrex/nrex.hpp
+++ b/drivers/nrex/nrex.hpp
@@ -1,4 +1,5 @@
// NREX: Node RegEx
+// Version 0.1
//
// Copyright (c) 2015, Zher Huei Lee
// All rights reserved.
@@ -59,7 +60,32 @@ class nrex
int _capturing;
nrex_node* _root;
public:
+
+ /*!
+ * \brief Initialises an empty regex container
+ */
nrex();
+
+ /*!
+ * \brief Initialises and compiles the regex pattern
+ *
+ * This calls nrex::compile() with the same arguments. To check whether
+ * the compilation was successfull, use nrex::valid().
+ *
+ * If the NREX_THROW_ERROR was defined it would automatically throw a
+ * runtime error nrex_compile_error if it encounters a problem when
+ * parsing the pattern.
+ *
+ * \param pattern The regex pattern
+ * \param captures The maximum number of capture groups to allow. Any
+ * extra would be converted to non-capturing groups.
+ * If negative, no limit would be imposed. Defaults
+ * to 9.
+ *
+ * \see nrex::compile()
+ */
+ nrex(const nrex_char* pattern, int captures = 9);
+
~nrex();
/*!
@@ -78,9 +104,9 @@ class nrex
*
* This is used to provide the array size of the captures needed for
* nrex::match() to work. The size is actually the number of capture
- * groups + one for the matching of the entire pattern. The result is
- * always capped at 10 or 100, depending on the extend option given in
- * nrex::compile() (default 10).
+ * groups + one for the matching of the entire pattern. This can be
+ * capped using the extra argument given in nrex::compile()
+ * (default 10).
*
* \return The number of captures
*/
@@ -97,12 +123,13 @@ class nrex
* parsing the pattern.
*
* \param pattern The regex pattern
- * \param extended If true, raises the limit on number of capture
- * groups and back-references to 99. Otherwise limited
- * to 9. Defaults to false.
+ * \param captures The maximum number of capture groups to allow. Any
+ * extra would be converted to non-capturing groups.
+ * If negative, no limit would be imposed. Defaults
+ * to 9.
* \return True if the pattern was succesfully compiled
*/
- bool compile(const nrex_char* pattern, bool extended = false);
+ bool compile(const nrex_char* pattern, int captures = 9);
/*!
* \brief Uses the pattern to search through the provided string
diff --git a/drivers/nrex/regex.cpp b/drivers/nrex/regex.cpp
index 246384b10a..e8578221a9 100644
--- a/drivers/nrex/regex.cpp
+++ b/drivers/nrex/regex.cpp
@@ -15,7 +15,7 @@
void RegEx::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("compile","pattern", "expanded"),&RegEx::compile, DEFVAL(true));
+ ObjectTypeDB::bind_method(_MD("compile","pattern", "capture"),&RegEx::compile, DEFVAL(9));
ObjectTypeDB::bind_method(_MD("find","text","start","end"),&RegEx::find, DEFVAL(0), DEFVAL(-1));
ObjectTypeDB::bind_method(_MD("clear"),&RegEx::clear);
ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid);
@@ -68,11 +68,11 @@ String RegEx::get_capture(int capture) const {
}
-Error RegEx::compile(const String& p_pattern, bool expanded) {
+Error RegEx::compile(const String& p_pattern, int capture) {
clear();
- exp.compile(p_pattern.c_str(), expanded);
+ exp.compile(p_pattern.c_str(), capture);
ERR_FAIL_COND_V( !exp.valid(), FAILED );
diff --git a/drivers/nrex/regex.h b/drivers/nrex/regex.h
index be52da8149..76aab2aea6 100644
--- a/drivers/nrex/regex.h
+++ b/drivers/nrex/regex.h
@@ -36,7 +36,7 @@ public:
bool is_valid() const;
int get_capture_count() const;
String get_capture(int capture) const;
- Error compile(const String& p_pattern, bool expanded = false);
+ Error compile(const String& p_pattern, int capture = 9);
int find(const String& p_text, int p_start = 0, int p_end = -1) const;
RegEx();
diff --git a/drivers/theora/video_stream_theora.cpp b/drivers/theora/video_stream_theora.cpp
index f301bd7515..fe248bc911 100644
--- a/drivers/theora/video_stream_theora.cpp
+++ b/drivers/theora/video_stream_theora.cpp
@@ -7,11 +7,34 @@
int VideoStreamPlaybackTheora:: buffer_data() {
- char *buffer=ogg_sync_buffer(&oy,4096);
- int bytes=file->get_buffer((uint8_t*)buffer, 4096);
- ogg_sync_wrote(&oy,bytes);
- return(bytes);
+ char *buffer=ogg_sync_buffer(&oy,4096);
+
+#ifdef THEORA_USE_THREAD_STREAMING
+
+ int read;
+
+ do {
+ thread_sem->post();
+ read = MIN(ring_buffer.data_left(),4096);
+ if (read) {
+ ring_buffer.read((uint8_t*)buffer,read);
+ ogg_sync_wrote(&oy,read);
+ } else {
+ OS::get_singleton()->delay_usec(100);
+ }
+
+ } while(read==0);
+
+ return read;
+
+#else
+
+ int bytes=file->get_buffer((uint8_t*)buffer, 4096);
+ ogg_sync_wrote(&oy,bytes);
+ return(bytes);
+
+#endif
}
int VideoStreamPlaybackTheora::queue_page(ogg_page *page){
@@ -200,6 +223,14 @@ void VideoStreamPlaybackTheora::clear() {
}
ogg_sync_clear(&oy);
+#ifdef THEORA_USE_THREAD_STREAMING
+ thread_exit=true;
+ thread_sem->post(); //just in case
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+ thread=NULL;
+ ring_buffer.clear();
+#endif
//file_name = "";
theora_p = 0;
@@ -217,6 +248,7 @@ void VideoStreamPlaybackTheora::clear() {
void VideoStreamPlaybackTheora::set_file(const String& p_file) {
+ ERR_FAIL_COND(playing);
ogg_packet op;
th_setup_info *ts = NULL;
@@ -227,7 +259,17 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
file = FileAccess::open(p_file, FileAccess::READ);
ERR_FAIL_COND(!file);
+#ifdef THEORA_USE_THREAD_STREAMING
+ thread_exit=false;
+ thread_eof=false;
+ //pre-fill buffer
+ int to_read = ring_buffer.space_left();
+ int read = file->get_buffer(read_buffer.ptr(),to_read);
+ ring_buffer.write(read_buffer.ptr(),read);
+ thread=Thread::create(_streaming_thread,this);
+
+#endif
ogg_sync_init(&oy);
@@ -369,6 +411,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
th_decode_ctl(td,TH_DECCTL_GET_PPLEVEL_MAX,&pp_level_max,
sizeof(pp_level_max));
pp_level=pp_level_max;
+ pp_level=0;
th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
pp_inc=0;
@@ -415,6 +458,8 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
buffering=true;
time=0;
audio_frames_wrote=0;
+
+
};
float VideoStreamPlaybackTheora::get_time() const {
@@ -436,13 +481,16 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
return;
};
+#ifdef THEORA_USE_THREAD_STREAMING
+ thread_sem->post();
+#endif
+
//double ctime =AudioServer::get_singleton()->get_mix_time();
//print_line("play "+rtos(p_delta));
time+=p_delta;
if (videobuf_time>get_time()) {
-
return; //no new frames need to be produced
}
@@ -573,21 +621,22 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
if(videobuf_time>=get_time()) {
frame_done=true;
- print_line("frame!");
} else{
/*If we are too slow, reduce the pp level.*/
pp_inc=pp_level>0?-1:0;
- print_line("skip!");
}
}
} else {
- print_line("no packet..");
+
break;
}
}
-
+#ifdef THEORA_USE_THREAD_STREAMING
+ if (file && thread_eof && ring_buffer.data_left()==0) {
+#else
if (file && /*!videobuf_ready && */ file->eof_reached()) {
+#endif
printf("video done, stopping\n");
stop();
return;
@@ -633,6 +682,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
else if(tdiff<ti.fps_denominator*0.05/ti.fps_numerator){
pp_inc=pp_level>0?-1:0;
}
+
}
video_write();
@@ -644,15 +694,21 @@ void VideoStreamPlaybackTheora::play() {
if (!playing)
time=0;
+ else {
+ stop();
+ }
+
playing = true;
delay_compensation=Globals::get_singleton()->get("audio/video_delay_compensation_ms");
delay_compensation/=1000.0;
+
};
void VideoStreamPlaybackTheora::stop() {
if (playing) {
+
clear();
set_file(file_name); //reset
}
@@ -730,7 +786,33 @@ int VideoStreamPlaybackTheora::get_mix_rate() const{
return vi.rate;
}
+#ifdef THEORA_USE_THREAD_STREAMING
+
+
+void VideoStreamPlaybackTheora::_streaming_thread(void *ud) {
+
+ VideoStreamPlaybackTheora *vs=(VideoStreamPlaybackTheora*)ud;
+
+ while(!vs->thread_exit) {
+
+ //just fill back the buffer
+ if (!vs->thread_eof) {
+
+ int to_read = vs->ring_buffer.space_left();
+ if (to_read) {
+ int read = vs->file->get_buffer(vs->read_buffer.ptr(),to_read);
+ vs->ring_buffer.write(vs->read_buffer.ptr(),read);
+ vs->thread_eof=vs->file->eof_reached();
+ }
+
+
+ }
+
+ vs->thread_sem->wait();
+ }
+}
+#endif
VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
@@ -749,14 +831,31 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
audio_track=0;
delay_compensation=0;
audio_frames_wrote=0;
+
+#ifdef THEORA_USE_THREAD_STREAMING
+ int rb_power = nearest_shift(RB_SIZE_KB*1024);
+ ring_buffer.resize(rb_power);
+ read_buffer.resize(RB_SIZE_KB*1024);
+ thread_sem=Semaphore::create();
+ thread=NULL;
+ thread_exit=false;
+ thread_eof=false;
+
+#endif
};
VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {
+#ifdef THEORA_USE_THREAD_STREAMING
+
+ memdelete(thread_sem);
+#endif
clear();
if (file)
memdelete(file);
+
+
};
diff --git a/drivers/theora/video_stream_theora.h b/drivers/theora/video_stream_theora.h
index 5540f050f9..c15ef31cfc 100644
--- a/drivers/theora/video_stream_theora.h
+++ b/drivers/theora/video_stream_theora.h
@@ -6,9 +6,13 @@
#include "theora/theoradec.h"
#include "vorbis/codec.h"
#include "os/file_access.h"
-
+#include "ring_buffer.h"
#include "io/resource_loader.h"
#include "scene/resources/video_stream.h"
+#include "os/thread.h"
+#include "os/semaphore.h"
+
+//#define THEORA_USE_THREAD_STREAMING
class VideoStreamPlaybackTheora : public VideoStreamPlayback {
@@ -66,7 +70,25 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
AudioMixCallback mix_callback;
void* mix_udata;
- int audio_track;
+#ifdef THEORA_USE_THREAD_STREAMING
+
+ enum {
+ RB_SIZE_KB=1024
+ };
+
+ RingBuffer<uint8_t> ring_buffer;
+ Vector<uint8_t> read_buffer;
+ bool thread_eof;
+ Semaphore *thread_sem;
+ Thread *thread;
+ volatile bool thread_exit;
+
+ static void _streaming_thread(void *ud);
+
+#endif
+
+
+ int audio_track;
protected:
@@ -116,20 +138,20 @@ class VideoStreamTheora : public VideoStream {
OBJ_TYPE(VideoStreamTheora,VideoStream);
String file;
- int audio_track;
+ int audio_track;
public:
Ref<VideoStreamPlayback> instance_playback() {
Ref<VideoStreamPlaybackTheora> pb = memnew( VideoStreamPlaybackTheora );
- pb->set_audio_track(audio_track);
+ pb->set_audio_track(audio_track);
pb->set_file(file);
return pb;
}
void set_file(const String& p_file) { file=p_file; }
- void set_audio_track(int p_track) { audio_track=p_track; }
+ void set_audio_track(int p_track) { audio_track=p_track; }
VideoStreamTheora() { audio_track=0; }
diff --git a/drivers/unix/SCsub b/drivers/unix/SCsub
index 9fbb467baa..e8b3cadfc7 100644
--- a/drivers/unix/SCsub
+++ b/drivers/unix/SCsub
@@ -1,5 +1,13 @@
Import('env')
+ed_gl_set='#include "os_unix.h"\n'
+ed_gl_set+='String OS_Unix::get_global_settings_path() const {\n'
+ed_gl_set+='\treturn "' + env["unix_global_settings_path"]+'";\n'
+ed_gl_set+='}\n'
+f = open("os_unix_global_settings_path.cpp","wb")
+f.write(ed_gl_set)
+f.close()
+
env.add_source_files(env.drivers_sources,"*.cpp")
Export('env')
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index fd8c26f6d9..94a7b03f45 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -477,6 +477,14 @@ String OS_Unix::get_data_dir() const {
}
+String OS_Unix::get_installed_templates_path() const {
+ String p=get_global_settings_path();
+ if (p!="")
+ return p+"/templates/";
+ else
+ return "";
+}
+
String OS_Unix::get_executable_path() const {
#ifdef __linux__
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 2ee6102164..9ac18c9055 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -64,6 +64,8 @@ protected:
String stdin_buf;
+ String get_global_settings_path() const;
+
public:
@@ -111,6 +113,7 @@ public:
virtual void debug_break();
+ virtual String get_installed_templates_path() const;
virtual String get_executable_path() const;
virtual String get_data_dir() const;
diff --git a/drivers/webp/dec/alpha.c b/drivers/webp/dec/alpha.c
index 52216fc4d6..1d029b0e6a 100644
--- a/drivers/webp/dec/alpha.c
+++ b/drivers/webp/dec/alpha.c
@@ -18,7 +18,7 @@
#include "../dsp/dsp.h"
#include "../utils/quant_levels_dec.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
//------------------------------------------------------------------------------
// ALPHDecoder object.
diff --git a/drivers/webp/dec/decode_vp8.h b/drivers/webp/dec/decode_vp8.h
index b9337bbec0..2bf1bdbbf5 100644
--- a/drivers/webp/dec/decode_vp8.h
+++ b/drivers/webp/dec/decode_vp8.h
@@ -14,7 +14,7 @@
#ifndef WEBP_WEBP_DECODE_VP8_H_
#define WEBP_WEBP_DECODE_VP8_H_
-#include "../webp/decode.h"
+#include "webp/decode.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/dec/webp.c b/drivers/webp/dec/webp.c
index 952178fa89..93a113a48d 100644
--- a/drivers/webp/dec/webp.c
+++ b/drivers/webp/dec/webp.c
@@ -17,7 +17,7 @@
#include "./vp8li.h"
#include "./webpi.h"
#include "../utils/utils.h"
-#include "../webp/mux_types.h" // ALPHA_FLAG
+#include "webp/mux_types.h" // ALPHA_FLAG
//------------------------------------------------------------------------------
// RIFF layout is:
diff --git a/drivers/webp/demux/anim_decode.c b/drivers/webp/demux/anim_decode.c
index adf84cd193..c81cedfba0 100644
--- a/drivers/webp/demux/anim_decode.c
+++ b/drivers/webp/demux/anim_decode.c
@@ -11,15 +11,15 @@
//
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include <assert.h>
#include <string.h>
#include "../utils/utils.h"
-#include "../webp/decode.h"
-#include "../webp/demux.h"
+#include "webp/decode.h"
+#include "webp/demux.h"
#define NUM_CHANNELS 4
diff --git a/drivers/webp/demux/demux.c b/drivers/webp/demux/demux.c
index e8e5418efe..3717e21165 100644
--- a/drivers/webp/demux/demux.c
+++ b/drivers/webp/demux/demux.c
@@ -11,7 +11,7 @@
//
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include <assert.h>
@@ -19,9 +19,9 @@
#include <string.h>
#include "../utils/utils.h"
-#include "../webp/decode.h" // WebPGetFeatures
-#include "../webp/demux.h"
-#include "../webp/format_constants.h"
+#include "webp/decode.h" // WebPGetFeatures
+#include "webp/demux.h"
+#include "webp/format_constants.h"
#define DMUX_MAJ_VERSION 0
#define DMUX_MIN_VERSION 2
diff --git a/drivers/webp/dsp/dsp.h b/drivers/webp/dsp/dsp.h
index 8395df40e4..4613d9c3ff 100644
--- a/drivers/webp/dsp/dsp.h
+++ b/drivers/webp/dsp/dsp.h
@@ -15,10 +15,10 @@
#define WEBP_DSP_DSP_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/dsp/lossless.h b/drivers/webp/dsp/lossless.h
index ee6771333f..149c6a01d3 100644
--- a/drivers/webp/dsp/lossless.h
+++ b/drivers/webp/dsp/lossless.h
@@ -15,8 +15,8 @@
#ifndef WEBP_DSP_LOSSLESS_H_
#define WEBP_DSP_LOSSLESS_H_
-#include "../webp/types.h"
-#include "../webp/decode.h"
+#include "webp/types.h"
+#include "webp/decode.h"
#include "../enc/histogram.h"
#include "../utils/utils.h"
diff --git a/drivers/webp/enc/alpha.c b/drivers/webp/enc/alpha.c
index fad6346e43..1842b36401 100644
--- a/drivers/webp/enc/alpha.c
+++ b/drivers/webp/enc/alpha.c
@@ -19,7 +19,7 @@
#include "../utils/filters.h"
#include "../utils/quant_levels.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
// -----------------------------------------------------------------------------
// Encodes the given alpha data via specified compression method 'method'.
diff --git a/drivers/webp/enc/backward_references.h b/drivers/webp/enc/backward_references.h
index daa084d846..e410b06f7d 100644
--- a/drivers/webp/enc/backward_references.h
+++ b/drivers/webp/enc/backward_references.h
@@ -15,8 +15,8 @@
#include <assert.h>
#include <stdlib.h>
-#include "../webp/types.h"
-#include "../webp/format_constants.h"
+#include "webp/types.h"
+#include "webp/format_constants.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/enc/config.c b/drivers/webp/enc/config.c
index f9f7961d58..8fd2276cb5 100644
--- a/drivers/webp/enc/config.c
+++ b/drivers/webp/enc/config.c
@@ -11,7 +11,7 @@
//
// Author: Skal (pascal.massimino@gmail.com)
-#include "../webp/encode.h"
+#include "webp/encode.h"
//------------------------------------------------------------------------------
// WebPConfig
diff --git a/drivers/webp/enc/delta_palettization.c b/drivers/webp/enc/delta_palettization.c
index 062e588d79..8bd3a3d233 100644
--- a/drivers/webp/enc/delta_palettization.c
+++ b/drivers/webp/enc/delta_palettization.c
@@ -13,7 +13,7 @@
#include "./delta_palettization.h"
#ifdef WEBP_EXPERIMENTAL_FEATURES
-#include "../webp/types.h"
+#include "webp/types.h"
#include "../dsp/lossless.h"
#define MK_COL(r, g, b) (((r) << 16) + ((g) << 8) + (b))
diff --git a/drivers/webp/enc/delta_palettization.h b/drivers/webp/enc/delta_palettization.h
index e41c0c5ab5..54195d452c 100644
--- a/drivers/webp/enc/delta_palettization.h
+++ b/drivers/webp/enc/delta_palettization.h
@@ -13,7 +13,7 @@
#ifndef WEBP_ENC_DELTA_PALETTIZATION_H_
#define WEBP_ENC_DELTA_PALETTIZATION_H_
-#include "../webp/encode.h"
+#include "webp/encode.h"
#include "../enc/vp8li.h"
// Replaces enc->argb_[] input by a palettizable approximation of it,
diff --git a/drivers/webp/enc/frame.c b/drivers/webp/enc/frame.c
index 5b7a40b9ad..65a98ada4d 100644
--- a/drivers/webp/enc/frame.c
+++ b/drivers/webp/enc/frame.c
@@ -17,7 +17,7 @@
#include "./cost.h"
#include "./vp8enci.h"
#include "../dsp/dsp.h"
-#include "../webp/format_constants.h" // RIFF constants
+#include "webp/format_constants.h" // RIFF constants
#define SEGMENT_VISU 0
#define DEBUG_SEARCH 0 // useful to track search convergence
diff --git a/drivers/webp/enc/histogram.c b/drivers/webp/enc/histogram.c
index 62c320d809..68c27fb1db 100644
--- a/drivers/webp/enc/histogram.c
+++ b/drivers/webp/enc/histogram.c
@@ -10,7 +10,7 @@
// Author: Jyrki Alakuijala (jyrki@google.com)
//
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include <math.h>
diff --git a/drivers/webp/enc/histogram.h b/drivers/webp/enc/histogram.h
index adb16c01ca..72f045793a 100644
--- a/drivers/webp/enc/histogram.h
+++ b/drivers/webp/enc/histogram.h
@@ -17,8 +17,8 @@
#include <string.h>
#include "./backward_references.h"
-#include "../webp/format_constants.h"
-#include "../webp/types.h"
+#include "webp/format_constants.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/enc/syntax.c b/drivers/webp/enc/syntax.c
index a0e79ef404..2b65f15ca1 100644
--- a/drivers/webp/enc/syntax.c
+++ b/drivers/webp/enc/syntax.c
@@ -14,8 +14,8 @@
#include <assert.h>
#include "../utils/utils.h"
-#include "../webp/format_constants.h" // RIFF constants
-#include "../webp/mux_types.h" // ALPHA_FLAG
+#include "webp/format_constants.h" // RIFF constants
+#include "webp/mux_types.h" // ALPHA_FLAG
#include "./vp8enci.h"
//------------------------------------------------------------------------------
diff --git a/drivers/webp/enc/vp8enci.h b/drivers/webp/enc/vp8enci.h
index 1a7ebe5703..0cb2ccc353 100644
--- a/drivers/webp/enc/vp8enci.h
+++ b/drivers/webp/enc/vp8enci.h
@@ -20,7 +20,7 @@
#include "../utils/bit_writer.h"
#include "../utils/thread.h"
#include "../utils/utils.h"
-#include "../webp/encode.h"
+#include "webp/encode.h"
#ifdef WEBP_EXPERIMENTAL_FEATURES
#include "./vp8li.h"
diff --git a/drivers/webp/enc/vp8l.c b/drivers/webp/enc/vp8l.c
index 047c9032ac..284995e830 100644
--- a/drivers/webp/enc/vp8l.c
+++ b/drivers/webp/enc/vp8l.c
@@ -22,7 +22,7 @@
#include "../utils/bit_writer.h"
#include "../utils/huffman_encode.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
#include "./delta_palettization.h"
diff --git a/drivers/webp/enc/vp8li.h b/drivers/webp/enc/vp8li.h
index 6b6db127db..4543c3b260 100644
--- a/drivers/webp/enc/vp8li.h
+++ b/drivers/webp/enc/vp8li.h
@@ -17,8 +17,8 @@
#include "./backward_references.h"
#include "./histogram.h"
#include "../utils/bit_writer.h"
-#include "../webp/encode.h"
-#include "../webp/format_constants.h"
+#include "webp/encode.h"
+#include "webp/format_constants.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/mux/anim_encode.c b/drivers/webp/mux/anim_encode.c
index fa86eaac94..bb7c0f50b9 100644
--- a/drivers/webp/mux/anim_encode.c
+++ b/drivers/webp/mux/anim_encode.c
@@ -15,10 +15,10 @@
#include <stdio.h>
#include "../utils/utils.h"
-#include "../webp/decode.h"
-#include "../webp/encode.h"
-#include "../webp/format_constants.h"
-#include "../webp/mux.h"
+#include "webp/decode.h"
+#include "webp/encode.h"
+#include "webp/format_constants.h"
+#include "webp/mux.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
diff --git a/drivers/webp/mux/muxi.h b/drivers/webp/mux/muxi.h
index 718b2f5d58..8bd5291661 100644
--- a/drivers/webp/mux/muxi.h
+++ b/drivers/webp/mux/muxi.h
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include "../dec/vp8i.h"
#include "../dec/vp8li.h"
-#include "../webp/mux.h"
+#include "webp/mux.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/bit_reader.c b/drivers/webp/utils/bit_reader.c
index cd265321bb..5081d5cd4d 100644
--- a/drivers/webp/utils/bit_reader.c
+++ b/drivers/webp/utils/bit_reader.c
@@ -12,7 +12,7 @@
// Author: Skal (pascal.massimino@gmail.com)
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include "./bit_reader_inl.h"
diff --git a/drivers/webp/utils/bit_reader.h b/drivers/webp/utils/bit_reader.h
index 0fc62d33b7..7e09653ebc 100644
--- a/drivers/webp/utils/bit_reader.h
+++ b/drivers/webp/utils/bit_reader.h
@@ -19,7 +19,7 @@
#ifdef _MSC_VER
#include <stdlib.h> // _byteswap_ulong
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/bit_reader_inl.h b/drivers/webp/utils/bit_reader_inl.h
index 37215702d4..20ce5f3cc7 100644
--- a/drivers/webp/utils/bit_reader_inl.h
+++ b/drivers/webp/utils/bit_reader_inl.h
@@ -17,7 +17,7 @@
#define WEBP_UTILS_BIT_READER_INL_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#ifdef WEBP_FORCE_ALIGNED
diff --git a/drivers/webp/utils/bit_writer.h b/drivers/webp/utils/bit_writer.h
index ef360d1dc6..867a5ee055 100644
--- a/drivers/webp/utils/bit_writer.h
+++ b/drivers/webp/utils/bit_writer.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_BIT_WRITER_H_
#define WEBP_UTILS_BIT_WRITER_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/color_cache.h b/drivers/webp/utils/color_cache.h
index a9a9f64270..34299e4c4e 100644
--- a/drivers/webp/utils/color_cache.h
+++ b/drivers/webp/utils/color_cache.h
@@ -15,7 +15,7 @@
#ifndef WEBP_UTILS_COLOR_CACHE_H_
#define WEBP_UTILS_COLOR_CACHE_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/endian_inl.h b/drivers/webp/utils/endian_inl.h
index e11260ff7d..253b7be8ee 100644
--- a/drivers/webp/utils/endian_inl.h
+++ b/drivers/webp/utils/endian_inl.h
@@ -13,11 +13,11 @@
#define WEBP_UTILS_ENDIAN_INL_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include "../dsp/dsp.h"
-#include "../webp/types.h"
+#include "webp/types.h"
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
#if !defined(WORDS_BIGENDIAN) && \
diff --git a/drivers/webp/utils/filters.h b/drivers/webp/utils/filters.h
index 088b132fc5..4aba3fd3b7 100644
--- a/drivers/webp/utils/filters.h
+++ b/drivers/webp/utils/filters.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_FILTERS_H_
#define WEBP_UTILS_FILTERS_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#include "../dsp/dsp.h"
#ifdef __cplusplus
diff --git a/drivers/webp/utils/huffman.c b/drivers/webp/utils/huffman.c
index d57376aa6b..e6f482a6a8 100644
--- a/drivers/webp/utils/huffman.c
+++ b/drivers/webp/utils/huffman.c
@@ -16,7 +16,7 @@
#include <string.h>
#include "./huffman.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
// Huffman data read via DecodeImageStream is represented in two (red and green)
// bytes.
diff --git a/drivers/webp/utils/huffman.h b/drivers/webp/utils/huffman.h
index c6dd6aaa45..a8cc0da1c3 100644
--- a/drivers/webp/utils/huffman.h
+++ b/drivers/webp/utils/huffman.h
@@ -15,8 +15,8 @@
#define WEBP_UTILS_HUFFMAN_H_
#include <assert.h>
-#include "../webp/format_constants.h"
-#include "../webp/types.h"
+#include "webp/format_constants.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/huffman_encode.c b/drivers/webp/utils/huffman_encode.c
index 6421c2beed..d7aad6f56d 100644
--- a/drivers/webp/utils/huffman_encode.c
+++ b/drivers/webp/utils/huffman_encode.c
@@ -16,7 +16,7 @@
#include <string.h>
#include "./huffman_encode.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
// -----------------------------------------------------------------------------
// Util function to optimize the symbol map for RLE coding
diff --git a/drivers/webp/utils/huffman_encode.h b/drivers/webp/utils/huffman_encode.h
index a157165148..93610066f3 100644
--- a/drivers/webp/utils/huffman_encode.h
+++ b/drivers/webp/utils/huffman_encode.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
#define WEBP_UTILS_HUFFMAN_ENCODE_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/quant_levels.h b/drivers/webp/utils/quant_levels.h
index 1cb5a32cae..3916b977ab 100644
--- a/drivers/webp/utils/quant_levels.h
+++ b/drivers/webp/utils/quant_levels.h
@@ -16,7 +16,7 @@
#include <stdlib.h>
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/quant_levels_dec.h b/drivers/webp/utils/quant_levels_dec.h
index 9aab068076..29c7e6e205 100644
--- a/drivers/webp/utils/quant_levels_dec.h
+++ b/drivers/webp/utils/quant_levels_dec.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_
#define WEBP_UTILS_QUANT_LEVELS_DEC_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/random.h b/drivers/webp/utils/random.h
index c392a615ca..745f3e2e87 100644
--- a/drivers/webp/utils/random.h
+++ b/drivers/webp/utils/random.h
@@ -15,7 +15,7 @@
#define WEBP_UTILS_RANDOM_H_
#include <assert.h>
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/rescaler.h b/drivers/webp/utils/rescaler.h
index 98b01a76d0..868467b4d7 100644
--- a/drivers/webp/utils/rescaler.h
+++ b/drivers/webp/utils/rescaler.h
@@ -18,7 +18,7 @@
extern "C" {
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#define WEBP_RESCALER_RFIX 32 // fixed-point precision for multiplies
#define WEBP_RESCALER_ONE (1ull << WEBP_RESCALER_RFIX)
diff --git a/drivers/webp/utils/thread.h b/drivers/webp/utils/thread.h
index 8408311855..6008bb7c01 100644
--- a/drivers/webp/utils/thread.h
+++ b/drivers/webp/utils/thread.h
@@ -15,10 +15,10 @@
#define WEBP_UTILS_THREAD_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/utils.c b/drivers/webp/utils/utils.c
index d8e30930af..35aeae6ab8 100644
--- a/drivers/webp/utils/utils.c
+++ b/drivers/webp/utils/utils.c
@@ -13,8 +13,8 @@
#include <stdlib.h>
#include <string.h> // for memcpy()
-#include "../webp/decode.h"
-#include "../webp/encode.h"
+#include "webp/decode.h"
+#include "webp/encode.h"
#include "./utils.h"
// If PRINT_MEM_INFO is defined, extra info (like total memory used, number of
diff --git a/drivers/webp/utils/utils.h b/drivers/webp/utils/utils.h
index fcdb7e139b..d0e1cb250a 100644
--- a/drivers/webp/utils/utils.h
+++ b/drivers/webp/utils/utils.h
@@ -17,7 +17,7 @@
#include <assert.h>
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 8746f92c9e..c3cc779bce 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -2274,6 +2274,26 @@ bool GDInstance::get(const StringName& p_name, Variant &r_ret) const {
return false;
}
+
+Variant::Type GDInstance::get_property_type(const StringName& p_name,bool *r_is_valid) const {
+
+
+ const GDScript *sptr=script.ptr();
+ while(sptr) {
+
+ if (sptr->member_info.has(p_name)) {
+ if (r_is_valid)
+ *r_is_valid=true;
+ return sptr->member_info[p_name].type;
+ }
+ sptr = sptr->_base;
+ }
+
+ if (r_is_valid)
+ *r_is_valid=false;
+ return Variant::NIL;
+}
+
void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const {
// exported members, not doen yet!
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 850ffec05f..3d16b59065 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -373,6 +373,8 @@ public:
virtual bool set(const StringName& p_name, const Variant& p_value);
virtual bool get(const StringName& p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const;
+
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName& p_method) const;
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index b591ed3b4b..e445701669 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -774,20 +774,15 @@ void GDTokenizerText::_advance() {
{Variant::INT,"int"},
{Variant::REAL,"float"},
{Variant::STRING,"String"},
- {Variant::VECTOR2,"vec2"},
{Variant::VECTOR2,"Vector2"},
{Variant::RECT2,"Rect2"},
{Variant::MATRIX32,"Matrix32"},
- {Variant::MATRIX32,"mat32"},
- {Variant::VECTOR3,"vec3"},
{Variant::VECTOR3,"Vector3"},
{Variant::_AABB,"AABB"},
{Variant::_AABB,"Rect3"},
{Variant::PLANE,"Plane"},
{Variant::QUAT,"Quat"},
- {Variant::MATRIX3,"mat3"},
{Variant::MATRIX3,"Matrix3"},
- {Variant::TRANSFORM,"trn"},
{Variant::TRANSFORM,"Transform"},
{Variant::COLOR,"Color"},
{Variant::IMAGE,"Image"},
@@ -795,7 +790,6 @@ void GDTokenizerText::_advance() {
{Variant::OBJECT,"Object"},
{Variant::INPUT_EVENT,"InputEvent"},
{Variant::NODE_PATH,"NodePath"},
- {Variant::DICTIONARY,"dict"},
{Variant::DICTIONARY,"Dictionary"},
{Variant::ARRAY,"Array"},
{Variant::RAW_ARRAY,"RawArray"},
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 1deeb3457a..7d550f4fa0 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1020,18 +1020,24 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
EditorProgress ep("export","Exporting for Android",104);
- String apk_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
-
- if (p_debug) {
-
- src_apk=custom_debug_package!=""?custom_debug_package:apk_path+"android_debug.apk";
- } else {
-
- src_apk=custom_release_package!=""?custom_release_package:apk_path+"android_release.apk";
+ if (p_debug)
+ src_apk=custom_debug_package;
+ else
+ src_apk=custom_release_package;
+ if (src_apk=="") {
+ String err;
+ if (p_debug) {
+ src_apk=find_export_template("android_debug.apk", &err);
+ } else {
+ src_apk=find_export_template("android_release.apk", &err);
+ }
+ if (src_apk=="") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
}
-
FileAccess *src_f=NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -1659,10 +1665,7 @@ bool EditorExportPlatformAndroid::can_export(String *r_error) const {
err+="Debug Keystore not configured in editor settings.\n";
}
-
- String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
-
- if (!FileAccess::exists(exe_path+"android_debug.apk") || !FileAccess::exists(exe_path+"android_release.apk")) {
+ if (!exists_export_template("android_debug.apk") || !exists_export_template("android_release.apk")) {
valid=false;
err+="No export templates found.\nDownload and install export templates.\n";
}
diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp
index 434aaff414..2acd920f31 100644
--- a/platform/bb10/export/export.cpp
+++ b/platform/bb10/export/export.cpp
@@ -275,10 +275,16 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
EditorProgress ep("export","Exporting for BlackBerry 10",104);
- String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
-
- String src_template=custom_package!=""?custom_package:template_path.plus_file("bb10.zip");
-
+ String src_template=custom_package;
+
+ if (src_template=="") {
+ String err;
+ src_template = find_export_template("bb10.zip", &err);
+ if (src_template=="") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
+ }
FileAccess *src_f=NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -733,9 +739,7 @@ bool EditorExportPlatformBB10::can_export(String *r_error) const {
err+="Blackberry host tools not configured in editor settings.\n";
}
- String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
-
- if (!FileAccess::exists(exe_path+"bb10.zip")) {
+ if (!exists_export_template("bb10.zip")) {
valid=false;
err+="No export template found.\nDownload and install export templates.\n";
}
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 9e2595f4a1..acbcbb4652 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -205,18 +205,24 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool
EditorProgress ep("export","Exporting for javascript",104);
- String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
-
- if (p_debug) {
-
- src_template=custom_debug_package!=""?custom_debug_package:template_path+"javascript_debug.zip";
- } else {
-
- src_template=custom_release_package!=""?custom_release_package:template_path+"javascript_release.zip";
+ if (p_debug)
+ src_template=custom_debug_package;
+ else
+ src_template=custom_release_package;
+ if (src_template=="") {
+ String err;
+ if (p_debug) {
+ src_template=find_export_template("javascript_debug.zip", &err);
+ } else {
+ src_template=find_export_template("javascript_release.zip", &err);
+ }
+ if (src_template=="") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
}
-
FileAccess *src_f=NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -337,9 +343,8 @@ bool EditorExportPlatformJavaScript::can_export(String *r_error) const {
bool valid=true;
String err;
- String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
- if (!FileAccess::exists(exe_path+"javascript_debug.zip") || !FileAccess::exists(exe_path+"javascript_release.zip")) {
+ if (!exists_export_template("javascript_debug.zip") || !exists_export_template("javascript_release.zip")) {
valid=false;
err+="No export templates found.\nDownload and install export templates.\n";
}
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 79ee91bc61..0bece6ec76 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -251,15 +251,19 @@ Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug
EditorProgress ep("export","Exporting for OSX",104);
- String pkg_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/osx.zip";
-
- if (p_debug) {
-
- src_pkg=custom_debug_package!=""?custom_debug_package:pkg_path;
- } else {
-
- src_pkg=custom_release_package!=""?custom_release_package:pkg_path;
+ if (p_debug)
+ src_pkg=custom_debug_package;
+ else
+ src_pkg=custom_release_package;
+
+ if (src_pkg=="") {
+ String err;
+ src_pkg=find_export_template("osx.zip", &err);
+ if (src_pkg=="") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
}
@@ -464,9 +468,8 @@ bool EditorExportPlatformOSX::can_export(String *r_error) const {
bool valid=true;
String err;
- String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
- if (!FileAccess::exists(exe_path+"osx.zip")) {
+ if (!exists_export_template("osx.zip")) {
valid=false;
err+="No export templates found.\nDownload and install export templates.\n";
}
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 4ec4b054db..3193a2acbb 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -170,7 +170,6 @@ def get_flags():
return [
('freetype','builtin'), #use builtin freetype
('openssl','builtin'), #use builtin openssl
- ('theora','no'),
]
def build_res_file( target, source, env ):
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index d996587864..0f6e640b03 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -1,6 +1,7 @@
import os
import sys
+import platform
def is_active():
@@ -147,7 +148,9 @@ def configure(env):
env.Append(CPPFLAGS=['-DOPENGL_ENABLED','-DGLEW_ENABLED'])
- env.Append(CPPFLAGS=["-DALSA_ENABLED"])
+ if platform.system() == 'Linux':
+ env.Append(CPPFLAGS=["-DALSA_ENABLED"])
+ env.Append(LIBS=['asound'])
if (env["pulseaudio"]=="yes"):
if not os.system("pkg-config --exists libpulse-simple"):
@@ -158,7 +161,7 @@ def configure(env):
print("PulseAudio development libraries not found, disabling driver")
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL'])
- env.Append(LIBS=['GL', 'GLU', 'pthread','asound','z']) #TODO detect linux/BSD!
+ env.Append(LIBS=['GL', 'GLU', 'pthread', 'z'])
#env.Append(CPPFLAGS=['-DMPC_FIXED_POINT'])
#host compiler is default..
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 74ebad748a..4f1b475d06 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -32,6 +32,7 @@
#include "key_mapping_x11.h"
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "print_string.h"
#include "servers/physics/physics_server_sw.h"
#include "errno.h"
@@ -1672,7 +1673,7 @@ void OS_X11::close_joystick(int p_id) {
};
void OS_X11::probe_joystick(int p_id) {
- #ifndef __FreeBSD__
+ #if !defined(__FreeBSD__) && !defined(__OpenBSD__)
if (p_id == -1) {
@@ -1727,7 +1728,7 @@ void OS_X11::move_window_to_foreground() {
}
void OS_X11::process_joysticks() {
- #ifndef __FreeBSD__
+ #if !defined(__FreeBSD__) && !defined(__OpenBSD__)
int bytes;
js_event events[32];
InputEvent ievent;
diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h
index c01d0aa380..1556b56058 100644
--- a/platform/x11/platform_config.h
+++ b/platform/x11/platform_config.h
@@ -29,7 +29,7 @@
#ifdef __linux__
#include <alloca.h>
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
#include <stdlib.h>
#endif
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 357aaa225b..abd532c156 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -309,6 +309,15 @@ void CanvasItem::hide() {
_change_notify("visibility/visible");
}
+void CanvasItem::set_hidden(bool p_hidden) {
+
+ if (hidden == p_hidden) {
+ return;
+ }
+
+ _set_visible_(!p_hidden);
+}
+
Variant CanvasItem::edit_get_state() const {
@@ -1043,6 +1052,7 @@ void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_hidden"),&CanvasItem::is_hidden);
ObjectTypeDB::bind_method(_MD("show"),&CanvasItem::show);
ObjectTypeDB::bind_method(_MD("hide"),&CanvasItem::hide);
+ ObjectTypeDB::bind_method(_MD("set_hidden","hidden"),&CanvasItem::set_hidden);
ObjectTypeDB::bind_method(_MD("update"),&CanvasItem::update);
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 4885256c64..667fedc956 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -190,6 +190,7 @@ public:
bool is_hidden() const;
void show();
void hide();
+ void set_hidden(bool p_hidden);
void update();
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index 1df936535f..adb2904a0a 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -111,6 +111,19 @@ real_t Joint2D::get_bias() const{
return bias;
}
+void Joint2D::set_exclude_nodes_from_collision(bool p_enable) {
+
+ if (exclude_from_collision==p_enable)
+ return;
+ exclude_from_collision=p_enable;
+ _update_joint();
+}
+
+bool Joint2D::get_exclude_nodes_from_collision() const{
+
+ return exclude_from_collision;
+}
+
void Joint2D::_bind_methods() {
@@ -124,9 +137,14 @@ void Joint2D::_bind_methods() {
ObjectTypeDB::bind_method( _MD("set_bias","bias"), &Joint2D::set_bias );
ObjectTypeDB::bind_method( _MD("get_bias"), &Joint2D::get_bias );
+ ObjectTypeDB::bind_method( _MD("set_exclude_nodes_from_collision","enable"), &Joint2D::set_exclude_nodes_from_collision );
+ ObjectTypeDB::bind_method( _MD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision );
+
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.001"), _SCS("set_bias"),_SCS("get_bias") );
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "collision/exclude_nodes"), _SCS("set_exclude_nodes_from_collision"),_SCS("get_exclude_nodes_from_collision") );
+
}
@@ -135,6 +153,7 @@ void Joint2D::_bind_methods() {
Joint2D::Joint2D() {
bias=0;
+ exclude_from_collision=true;
}
///////////////////////////////////////////////////////////////////////////////
@@ -173,7 +192,10 @@ RID PinJoint2D::_configure_joint() {
SWAP(body_a,body_b);
} else if (body_b) {
//add a collision exception between both
- Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+ if (get_exclude_nodes_from_collision())
+ Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+ else
+ Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(),body_b->get_rid());
}
RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness);
@@ -245,7 +267,11 @@ RID GrooveJoint2D::_configure_joint(){
if (!body_a || !body_b)
return RID();
- Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+
+ if (get_exclude_nodes_from_collision())
+ Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+ else
+ Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(),body_b->get_rid());
Matrix32 gt = get_global_transform();
Vector2 groove_A1 = gt.get_origin();
@@ -338,7 +364,10 @@ RID DampedSpringJoint2D::_configure_joint(){
if (!body_a || !body_b)
return RID();
- Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+ if (get_exclude_nodes_from_collision())
+ Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
+ else
+ Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(),body_b->get_rid());
Matrix32 gt = get_global_transform();
Vector2 anchor_A = gt.get_origin();
diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h
index 908e3a158e..d468f3a6b5 100644
--- a/scene/2d/joints_2d.h
+++ b/scene/2d/joints_2d.h
@@ -42,6 +42,8 @@ class Joint2D : public Node2D {
NodePath b;
real_t bias;
+ bool exclude_from_collision;
+
protected:
@@ -62,6 +64,9 @@ public:
void set_bias(real_t p_bias);
real_t get_bias() const;
+ void set_exclude_nodes_from_collision(bool p_enable);
+ bool get_exclude_nodes_from_collision() const;
+
RID get_joint() const { return joint; }
Joint2D();
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 852a6fb46b..a2112c7d37 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -333,7 +333,7 @@ void Light2D::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::REAL,"scale",PROPERTY_HINT_RANGE,"0.01,4096,0.01"),_SCS("set_texture_scale"),_SCS("get_texture_scale"));
ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"energy"),_SCS("set_energy"),_SCS("get_energy"));
- ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Add,Sub,Mix"),_SCS("set_mode"),_SCS("get_mode"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Add,Sub,Mix,Mask"),_SCS("set_mode"),_SCS("get_mode"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"range/height"),_SCS("set_height"),_SCS("get_height"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max"));
@@ -349,6 +349,7 @@ void Light2D::_bind_methods() {
BIND_CONSTANT( MODE_ADD );
BIND_CONSTANT( MODE_SUB );
BIND_CONSTANT( MODE_MIX );
+ BIND_CONSTANT( MODE_MASK );
}
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index bf61868bac..0828d9ac33 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -11,6 +11,7 @@ public:
MODE_ADD,
MODE_SUB,
MODE_MIX,
+ MODE_MASK,
};
private:
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index d61859a3d0..de50484a1e 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1073,7 +1073,7 @@ Vector3 KinematicBody::move_to(const Vector3& p_position) {
return move(p_position-get_global_transform().origin);
}
-bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) {
+bool KinematicBody::can_teleport_to(const Vector3& p_position) {
ERR_FAIL_COND_V(!is_inside_tree(),false);
PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space());
@@ -1089,25 +1089,18 @@ bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) {
if (collide_character)
mask|=PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
- Vector3 motion = p_position-get_global_transform().origin;
Transform xform=get_global_transform();
-
- if (true || p_discrete) {
-
- xform.origin+=motion;
- motion=Vector3();
- }
+ xform.origin=p_position;
Set<RID> exclude;
exclude.insert(get_rid());
- //fill exclude list..
for(int i=0;i<get_shape_count();i++) {
if (is_shape_set_as_trigger(i))
continue;
- bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,0,exclude,get_layer_mask(),mask);
+ bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,1,exclude,get_layer_mask(),mask);
if (col)
return false;
}
@@ -1205,7 +1198,7 @@ void KinematicBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody::move);
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody::move_to);
- ObjectTypeDB::bind_method(_MD("can_move_to","position"),&KinematicBody::can_move_to);
+ ObjectTypeDB::bind_method(_MD("can_teleport_to","position"),&KinematicBody::can_teleport_to);
ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody::is_colliding);
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 66490ba925..0e63b77118 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -304,7 +304,7 @@ public:
Vector3 move(const Vector3& p_motion);
Vector3 move_to(const Vector3& p_position);
- bool can_move_to(const Vector3& p_position,bool p_discrete=false);
+ bool can_teleport_to(const Vector3& p_position);
bool is_colliding() const;
Vector3 get_collision_pos() const;
Vector3 get_collision_normal() const;
diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp
index 0cc72b28e5..f4facb7c3f 100644
--- a/scene/3d/physics_joint.cpp
+++ b/scene/3d/physics_joint.cpp
@@ -34,8 +34,15 @@ void Joint::_update_joint(bool p_only_free) {
if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid())
- PhysicsServer::get_singleton()->body_remove_collision_exception(ba,bb);
+ if (ba.is_valid() && bb.is_valid()) {
+
+ if (exclude_from_collision)
+ PhysicsServer::get_singleton()->body_add_collision_exception(ba,bb);
+ else
+ PhysicsServer::get_singleton()->body_remove_collision_exception(ba,bb);
+
+ }
+
PhysicsServer::get_singleton()->free(joint);
joint=RID();
ba=RID();
@@ -144,6 +151,19 @@ void Joint::_notification(int p_what) {
}
+void Joint::set_exclude_nodes_from_collision(bool p_enable) {
+
+ if (exclude_from_collision==p_enable)
+ return;
+ exclude_from_collision=p_enable;
+ _update_joint();
+}
+
+bool Joint::get_exclude_nodes_from_collision() const{
+
+ return exclude_from_collision;
+}
+
void Joint::_bind_methods() {
@@ -156,10 +176,16 @@ void Joint::_bind_methods() {
ObjectTypeDB::bind_method( _MD("set_solver_priority","priority"), &Joint::set_solver_priority );
ObjectTypeDB::bind_method( _MD("get_solver_priority"), &Joint::get_solver_priority );
+ ObjectTypeDB::bind_method( _MD("set_exclude_nodes_from_collision","enable"), &Joint::set_exclude_nodes_from_collision );
+ ObjectTypeDB::bind_method( _MD("get_exclude_nodes_from_collision"), &Joint::get_exclude_nodes_from_collision );
+
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
ADD_PROPERTY( PropertyInfo( Variant::INT, "solver/priority",PROPERTY_HINT_RANGE,"1,8,1"), _SCS("set_solver_priority"),_SCS("get_solver_priority") );
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "collision/exclude_nodes"), _SCS("set_exclude_nodes_from_collision"),_SCS("get_exclude_nodes_from_collision") );
+
+
}
@@ -167,6 +193,7 @@ void Joint::_bind_methods() {
Joint::Joint() {
+ exclude_from_collision=true;
solver_priority=1;
}
diff --git a/scene/3d/physics_joint.h b/scene/3d/physics_joint.h
index a5f4ea4bdb..3f5a0e91a6 100644
--- a/scene/3d/physics_joint.h
+++ b/scene/3d/physics_joint.h
@@ -45,6 +45,7 @@ class Joint : public Spatial {
NodePath b;
int solver_priority;
+ bool exclude_from_collision;
protected:
@@ -67,6 +68,9 @@ public:
void set_solver_priority(int p_priority);
int get_solver_priority() const;
+ void set_exclude_nodes_from_collision(bool p_enable);
+ bool get_exclude_nodes_from_collision() const;
+
RID get_joint() const { return joint; }
Joint();
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index a65f68ed2c..7d48420a83 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -594,6 +594,15 @@ bool Spatial::is_hidden() const{
return !data.visible;
}
+void Spatial::set_hidden(bool p_hidden) {
+
+ if (data.visible != p_hidden) {
+ return;
+ }
+
+ _set_visible_(!p_hidden);
+}
+
void Spatial::_set_visible_(bool p_visible) {
if (p_visible)
@@ -742,6 +751,7 @@ void Spatial::_bind_methods() {
ObjectTypeDB::bind_method(_MD("hide"), &Spatial::hide);
ObjectTypeDB::bind_method(_MD("is_visible"), &Spatial::is_visible);
ObjectTypeDB::bind_method(_MD("is_hidden"), &Spatial::is_hidden);
+ ObjectTypeDB::bind_method(_MD("set_hidden","hidden"), &Spatial::set_hidden);
ObjectTypeDB::bind_method(_MD("_set_visible_"), &Spatial::_set_visible_);
ObjectTypeDB::bind_method(_MD("_is_visible_"), &Spatial::_is_visible_);
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index 7fa6099d7a..b1e3a82868 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -191,6 +191,7 @@ public:
void hide();
bool is_visible() const;
bool is_hidden() const;
+ void set_hidden(bool p_hidden);
#ifdef TOOLS_ENABLED
void set_import_transform(const Transform& p_transform) ;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index c2ea1c8bb6..b040e59d16 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -268,6 +268,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
TrackNodeCacheKey key;
key.id=id;
key.bone_idx=bone_idx;
+
if (node_cache_map.has(key)) {
@@ -278,6 +279,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
node_cache_map[key]=TrackNodeCache();
p_anim->node_cache[i]=&node_cache_map[key];
+ p_anim->node_cache[i]->path=a->track_get_path(i);
p_anim->node_cache[i]->node=child;
p_anim->node_cache[i]->resource=resource;
p_anim->node_cache[i]->node_2d=child->cast_to<Node2D>();
@@ -320,6 +322,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
pa.prop=property;
pa.object=resource.is_valid()?(Object*)resource.ptr():(Object*)child;
pa.special=SP_NONE;
+ pa.owner=p_anim->node_cache[i];
if (false && p_anim->node_cache[i]->node_2d) {
if (pa.prop==SceneStringNames::get_singleton()->transform_pos)
@@ -410,7 +413,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
TrackNodeCache::PropertyAnim *pa = &E->get();
- if (a->value_track_is_continuous(i) || p_delta==0) {
+ if (a->value_track_is_continuous(i) || p_delta==0) { //delta == 0 means seek
Variant value=a->value_track_interpolate(i,p_time);
@@ -436,10 +439,42 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
Variant value=a->track_get_key_value(i,F->get());
switch(pa->special) {
- case SP_NONE: pa->object->set(pa->prop,value); break; //you are not speshul
- case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(value); break;
- case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value)); break;
- case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(value); break;
+ case SP_NONE: {
+ bool valid;
+ pa->object->set(pa->prop,value,&valid); //you are not speshul
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ ERR_PRINTS("Failed setting track value '"+String(pa->owner->path)+"'. Check if property exists or the type of key is valid");
+ }
+#endif
+
+ } break;
+ case SP_NODE2D_POS: {
+#ifdef DEBUG_ENABLED
+ if (value.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Position key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+ static_cast<Node2D*>(pa->object)->set_pos(value);
+ } break;
+ case SP_NODE2D_ROT: {
+#ifdef DEBUG_ENABLED
+ if (value.is_num()) {
+ ERR_PRINTS("Rotation key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not numerical");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value));
+ } break;
+ case SP_NODE2D_SCALE: {
+#ifdef DEBUG_ENABLED
+ if (value.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Scale key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_scale(value);
+ } break;
}
}
@@ -607,13 +642,53 @@ void AnimationPlayer::_animation_update_transforms() {
ERR_CONTINUE( pa->accum_pass!=accum_pass );
#if 1
- switch(pa->special) {
+/* switch(pa->special) {
case SP_NONE: pa->object->set(pa->prop,pa->value_accum); break; //you are not speshul
case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum); break;
case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum)); break;
case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum); break;
+ }*/
+
+ switch(pa->special) {
+
+ case SP_NONE: {
+ bool valid;
+ pa->object->set(pa->prop,pa->value_accum,&valid); //you are not speshul
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ ERR_PRINTS("Failed setting key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"'. Check if property exists or the type of key is right for the property");
+ }
+#endif
+
+ } break;
+ case SP_NODE2D_POS: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Position key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+ static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum);
+ } break;
+ case SP_NODE2D_ROT: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.is_num()) {
+ ERR_PRINTS("Rotation key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not numerical");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum));
+ } break;
+ case SP_NODE2D_SCALE: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Scale key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum);
+ } break;
}
#else
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 1e3c37c4d6..18cedee796 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -68,6 +68,7 @@ private:
struct TrackNodeCache {
+ NodePath path;
uint32_t id;
RES resource;
Node *node;
@@ -84,6 +85,7 @@ private:
struct PropertyAnim {
+ TrackNodeCache *owner;
SpecialProperty special; //small optimization
StringName prop;
Object *object;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 8e428fd71c..22e3a81e52 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -46,6 +46,11 @@ VBoxContainer *FileDialog::get_vbox() {
}
void FileDialog::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_ENTER_TREE) {
+
+ refresh->set_icon(get_icon("Reload","EditorIcons"));
+ }
if (p_what==NOTIFICATION_DRAW) {
@@ -618,7 +623,7 @@ void FileDialog::_update_drives() {
}
}
-bool FileDialog::default_show_hidden_files=true;
+bool FileDialog::default_show_hidden_files=false;
void FileDialog::_bind_methods() {
@@ -700,6 +705,10 @@ FileDialog::FileDialog() {
pathhb->add_child(dir);
dir->set_h_size_flags(SIZE_EXPAND_FILL);
+ refresh = memnew( ToolButton );
+ refresh->connect("pressed",this,"_update_file_list");
+ pathhb->add_child(refresh);
+
drives = memnew( OptionButton );
pathhb->add_child(drives);
drives->connect("item_selected",this,"_select_drive");
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index ec42c7744a..370088b215 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -34,6 +34,7 @@
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
#include "scene/gui/dialogs.h"
+#include "scene/gui/tool_button.h"
#include "os/dir_access.h"
#include "box_container.h"
/**
@@ -86,6 +87,8 @@ private:
OptionButton *filter;
DirAccess *dir_access;
ConfirmationDialog *confirm_save;
+
+ ToolButton *refresh;
Vector<String> filters;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 18de8ed568..10ba20a833 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -568,7 +568,7 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
int char_w = 0;
if (font != NULL) {
- int char_w = font->get_char_size(text[ofs]).width;
+ char_w = font->get_char_size(text[ofs]).width;
}
pixel_ofs+=char_w;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 97c36ff71b..a832162994 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -628,11 +628,11 @@ String Node::validate_child_name(const String& p_name) const {
}
-void Node::_validate_child_name(Node *p_child) {
+void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
/* Make sure the name is unique */
- if (node_hrcr) {
+ if (node_hrcr || p_force_human_readable) {
//this approach to autoset node names is human readable but very slow
//it's turned on while running in the editor
@@ -700,11 +700,7 @@ void Node::_validate_child_name(Node *p_child) {
if (!unique) {
node_hrcr_count.ref();
-#ifdef DEBUG_ENABLED
- String name = "@"+String(p_child->get_type_name())+itos(node_hrcr_count.get());
-#else
- String name = "@"+itos(node_hrcr_count.get());
-#endif
+ String name = "@"+String(p_child->get_name())+"@"+itos(node_hrcr_count.get());
p_child->data.name=name;
}
}
@@ -732,24 +728,27 @@ void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) {
}
-void Node::add_child(Node *p_child) {
+void Node::add_child(Node *p_child, bool p_legible_unique_name) {
ERR_FAIL_NULL(p_child);
/* Fail if node has a parent */
- ERR_EXPLAIN("Can't add child "+p_child->get_name()+" to itself.")
- ERR_FAIL_COND( p_child==this ); // adding to itself!
+ if (p_child==this) {
+ ERR_EXPLAIN("Can't add child "+p_child->get_name()+" to itself.")
+ ERR_FAIL_COND( p_child==this ); // adding to itself!
+ }
ERR_EXPLAIN("Can't add child, already has a parent");
ERR_FAIL_COND( p_child->data.parent );
ERR_EXPLAIN("Can't add child while a notification is happening");
ERR_FAIL_COND( data.blocked > 0 );
/* Validate name */
- _validate_child_name(p_child);
+ _validate_child_name(p_child,p_legible_unique_name);
_add_child_nocheck(p_child,p_child->data.name);
}
+
void Node::_propagate_validate_owner() {
if (data.owner) {
@@ -1984,7 +1983,7 @@ void Node::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_name","name"),&Node::set_name);
ObjectTypeDB::bind_method(_MD("get_name"),&Node::get_name);
- ObjectTypeDB::bind_method(_MD("add_child","node:Node"),&Node::add_child);
+ ObjectTypeDB::bind_method(_MD("add_child","node:Node","legible_unique_name"),&Node::add_child,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("remove_child","node:Node"),&Node::remove_child);
//ObjectTypeDB::bind_method(_MD("remove_and_delete_child","node:Node"),&Node::remove_and_delete_child);
ObjectTypeDB::bind_method(_MD("get_child_count"),&Node::get_child_count);
diff --git a/scene/main/node.h b/scene/main/node.h
index 87fa4dd6ca..196c4a06eb 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -122,7 +122,7 @@ private:
- void _validate_child_name(Node *p_name);
+ void _validate_child_name(Node *p_name, bool p_force_human_readable=false);
void _propagate_reverse_notification(int p_notification);
void _propagate_deferred_notification(int p_notification, bool p_reverse);
@@ -187,7 +187,7 @@ public:
StringName get_name() const;
void set_name(const String& p_name);
- void add_child(Node *p_child);
+ void add_child(Node *p_child,bool p_legible_unique_name=false);
void remove_child(Node *p_child);
int get_child_count() const;
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 8edbaf0b89..c66e73b430 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -382,7 +382,7 @@ void BodySW::set_space(SpaceSW *p_space){
}
-void BodySW::_compute_area_gravity(const AreaSW *p_area) {
+void BodySW::_compute_area_gravity_and_dampenings(const AreaSW *p_area) {
if (p_area->is_gravity_point()) {
if(p_area->get_gravity_distance_scale() > 0) {
@@ -394,6 +394,9 @@ void BodySW::_compute_area_gravity(const AreaSW *p_area) {
} else {
gravity += p_area->get_gravity_vector() * p_area->get_gravity();
}
+
+ area_linear_damp += p_area->get_linear_damp();
+ area_angular_damp += p_area->get_angular_damp();
}
void BodySW::integrate_forces(real_t p_step) {
@@ -409,13 +412,15 @@ void BodySW::integrate_forces(real_t p_step) {
int ac = areas.size();
bool replace = false;
- gravity=Vector3(0,0,0);
+ gravity = Vector3(0,0,0);
+ area_linear_damp = 0;
+ area_angular_damp = 0;
if (ac) {
areas.sort();
const AreaCMP *aa = &areas[0];
damp_area = aa[ac-1].area;
for(int i=ac-1;i>=0;i--) {
- _compute_area_gravity(aa[i].area);
+ _compute_area_gravity_and_dampenings(aa[i].area);
if (aa[i].area->get_space_override_mode() == PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE) {
replace = true;
break;
@@ -424,20 +429,21 @@ void BodySW::integrate_forces(real_t p_step) {
}
if( !replace ) {
- _compute_area_gravity(def_area);
+ _compute_area_gravity_and_dampenings(def_area);
}
gravity*=gravity_scale;
+ // If less than 0, override dampenings with that of the Body
if (angular_damp>=0)
area_angular_damp=angular_damp;
- else
- area_angular_damp=damp_area->get_angular_damp();
+ //else
+ // area_angular_damp=damp_area->get_angular_damp();
if (linear_damp>=0)
area_linear_damp=linear_damp;
- else
- area_linear_damp=damp_area->get_linear_damp();
+ //else
+ // area_linear_damp=damp_area->get_linear_damp();
Vector3 motion;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index 66d814bfd1..4c4c7818c5 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -130,7 +130,7 @@ class BodySW : public CollisionObjectSW {
BodySW *island_next;
BodySW *island_list_next;
- _FORCE_INLINE_ void _compute_area_gravity(const AreaSW *p_area);
+ _FORCE_INLINE_ void _compute_area_gravity_and_dampenings(const AreaSW *p_area);
_FORCE_INLINE_ void _update_inertia_tensor();
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index ba1c737530..778d20d3f1 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -175,13 +175,15 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transfo
if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0))
continue;
- r_results[cc].collider_id=col_obj->get_instance_id();
- if (r_results[cc].collider_id!=0)
- r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
- else
- r_results[cc].collider=NULL;
- r_results[cc].rid=col_obj->get_self();
- r_results[cc].shape=shape_idx;
+ if (r_results) {
+ r_results[cc].collider_id=col_obj->get_instance_id();
+ if (r_results[cc].collider_id!=0)
+ r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
+ else
+ r_results[cc].collider=NULL;
+ r_results[cc].rid=col_obj->get_self();
+ r_results[cc].shape=shape_idx;
+ }
cc++;
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 3afbbe5455..d0c5cbc77b 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -380,7 +380,7 @@ void Body2DSW::set_space(Space2DSW *p_space){
}
-void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) {
+void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
if (p_area->is_gravity_point()) {
if(p_area->get_gravity_distance_scale() > 0) {
@@ -393,6 +393,8 @@ void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) {
gravity += p_area->get_gravity_vector() * p_area->get_gravity();
}
+ area_linear_damp += p_area->get_linear_damp();
+ area_angular_damp += p_area->get_angular_damp();
}
void Body2DSW::integrate_forces(real_t p_step) {
@@ -406,13 +408,15 @@ void Body2DSW::integrate_forces(real_t p_step) {
int ac = areas.size();
bool replace = false;
- gravity=Vector2(0,0);
+ gravity = Vector2(0,0);
+ area_angular_damp = 0;
+ area_linear_damp = 0;
if (ac) {
areas.sort();
const AreaCMP *aa = &areas[0];
damp_area = aa[ac-1].area;
for(int i=ac-1;i>=0;i--) {
- _compute_area_gravity(aa[i].area);
+ _compute_area_gravity_and_dampenings(aa[i].area);
if (aa[i].area->get_space_override_mode() == Physics2DServer::AREA_SPACE_OVERRIDE_REPLACE) {
replace = true;
break;
@@ -420,19 +424,20 @@ void Body2DSW::integrate_forces(real_t p_step) {
}
}
if( !replace ) {
- _compute_area_gravity(def_area);
+ _compute_area_gravity_and_dampenings(def_area);
}
gravity*=gravity_scale;
+ // If less than 0, override dampenings with that of the Body2D
if (angular_damp>=0)
- area_angular_damp=angular_damp;
- else
- area_angular_damp=damp_area->get_angular_damp();
+ area_angular_damp = angular_damp;
+ //else
+ // area_angular_damp=damp_area->get_angular_damp();
if (linear_damp>=0)
- area_linear_damp=linear_damp;
- else
- area_linear_damp=damp_area->get_linear_damp();
+ area_linear_damp = linear_damp;
+ //else
+ // area_linear_damp=damp_area->get_linear_damp();
Vector2 motion;
bool do_motion=false;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 2fbfcaca60..8418c5dcd7 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -132,7 +132,7 @@ class Body2DSW : public CollisionObject2DSW {
Body2DSW *island_next;
Body2DSW *island_list_next;
- _FORCE_INLINE_ void _compute_area_gravity(const Area2DSW *p_area);
+ _FORCE_INLINE_ void _compute_area_gravity_and_dampenings(const Area2DSW *p_area);
friend class Physics2DDirectBodyStateSW; // i give up, too many functions to expose
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 50407f1b0f..d94067961f 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -610,6 +610,7 @@ public:
CanvasLight *shadows_next_ptr;
CanvasLight *filter_next_ptr;
CanvasLight *next_ptr;
+ CanvasLight *mask_next_ptr;
CanvasLight() {
enabled=true;
@@ -627,6 +628,7 @@ public:
mode=VS::CANVAS_LIGHT_MODE_ADD;
texture_cache=NULL;
next_ptr=NULL;
+ mask_next_ptr=NULL;
filter_next_ptr=NULL;
shadow_buffer_size=2048;
shadow_esm_mult=80;
@@ -792,6 +794,7 @@ public:
CanvasItem* material_owner;
ViewportRender *vp_render;
bool distance_field;
+ bool light_masked;
Rect2 global_rect_cache;
@@ -918,8 +921,8 @@ public:
return rect;
}
- void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; material_owner=NULL;}
- CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; }
+ void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; material_owner=NULL; light_masked=false; }
+ CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; light_masked=false; }
virtual ~CanvasItem() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); }
};
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 68a60e26f5..0e10c7dfe4 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -2341,19 +2341,27 @@ Error ShaderLanguage::parse_flow_if(Parser& parser,Node *p_parent,Node **r_state
parser.advance();
+ if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
+ parser.set_error("Expected statement block after 'if()'");
+ return ERR_PARSE_ERROR;
+ }
+
Node *substatement=NULL;
err = parse_statement(parser,cf,&substatement);
if (err)
return err;
-
cf->statements.push_back(substatement);
-
-
if (parser.get_token_type()==TK_CF_ELSE) {
parser.advance();
+
+ if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
+ parser.set_error("Expected statement block after 'else'");
+ return ERR_PARSE_ERROR;
+ }
+
substatement=NULL;
err = parse_statement(parser,cf,&substatement);
if (err)
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index a94d4f64c7..79911121f5 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -6777,6 +6777,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void
}
+
void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_material_owner) {
CanvasItem *ci = p_canvas_item;
@@ -6878,6 +6879,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
ci->final_opacity=opacity * ci->self_opacity;
ci->global_rect_cache=global_rect;
ci->global_rect_cache.pos-=p_clip_rect.pos;
+ ci->light_masked=false;
int zidx = p_z-CANVAS_ITEM_Z_MIN;
@@ -6905,7 +6907,34 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
}
-void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights) {
+void VisualServerRaster::_light_mask_canvas_items(int p_z,Rasterizer::CanvasItem *p_canvas_item,Rasterizer::CanvasLight *p_masked_lights) {
+
+ if (!p_masked_lights)
+ return;
+
+ Rasterizer::CanvasItem *ci=p_canvas_item;
+
+ while(ci) {
+
+ Rasterizer::CanvasLight *light=p_masked_lights;
+ while(light) {
+
+ if (ci->light_mask&light->item_mask && p_z>=light->z_min && p_z<=light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache,light->rect_cache)) {
+ ci->light_masked=true;
+ }
+
+ light=light->mask_next_ptr;
+ }
+
+ ci=ci->next;
+ }
+
+
+
+
+}
+
+void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights,Rasterizer::CanvasLight *p_masked_lights) {
rasterizer->canvas_begin();
@@ -6938,6 +6967,11 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans
for(int i=0;i<z_range;i++) {
if (!z_list[i])
continue;
+
+ if (p_masked_lights) {
+ _light_mask_canvas_items(CANVAS_ITEM_Z_MIN+i,z_list[i],p_masked_lights);
+ }
+
rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_canvas->modulate,p_lights);
}
} else {
@@ -7072,6 +7106,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height);
Rasterizer::CanvasLight *lights=NULL;
Rasterizer::CanvasLight *lights_with_shadow=NULL;
+ Rasterizer::CanvasLight *lights_with_mask=NULL;
Rect2 shadow_rect;
int light_count=0;
@@ -7119,9 +7154,14 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
cl->radius_cache=cl->rect_cache.size.length();
}
+ if (cl->mode==CANVAS_LIGHT_MODE_MASK) {
+ cl->mask_next_ptr=lights_with_mask;
+ lights_with_mask=cl;
+ }
light_count++;
}
+
}
}
@@ -7190,7 +7230,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
ptr=ptr->filter_next_ptr;
}
- _render_canvas( E->get()->canvas,xform,canvas_lights );
+ _render_canvas( E->get()->canvas,xform,canvas_lights,lights_with_mask );
i++;
if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index b6a5ca6308..e0127faf41 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -633,7 +633,9 @@ class VisualServerRaster : public VisualServer {
static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect);
void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights);
void _render_canvas_item(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, float p_opacity, int p_z, Rasterizer::CanvasItem **z_list, Rasterizer::CanvasItem **z_last_list, CanvasItem *p_canvas_clip, CanvasItem *p_material_owner);
- void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights);
+ void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights, Rasterizer::CanvasLight *p_masked_lights);
+ void _light_mask_canvas_items(int p_z,Rasterizer::CanvasItem *p_canvas_item,Rasterizer::CanvasLight *p_masked_lights);
+
Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 96c3e15cde..c5100b8d30 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -1041,6 +1041,7 @@ public:
CANVAS_LIGHT_MODE_ADD,
CANVAS_LIGHT_MODE_SUB,
CANVAS_LIGHT_MODE_MIX,
+ CANVAS_LIGHT_MODE_MASK,
};
virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode)=0;
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index ace6fda696..b8aa5874d1 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -34,6 +34,7 @@
#include "pair.h"
#include "scene/gui/separator.h"
#include "editor_node.h"
+#include "tools/editor/plugins/animation_player_editor_plugin.h"
/* Missing to fix:
*Set
@@ -903,6 +904,23 @@ void AnimationKeyEditor::_menu_track(int p_type) {
optimize_dialog->popup_centered(Size2(250,180));
} break;
+ case TRACK_MENU_CLEAN_UP: {
+
+ cleanup_dialog->popup_centered_minsize(Size2(300,0));
+ } break;
+ case TRACK_MENU_CLEAN_UP_CONFIRM: {
+
+ if (cleanup_all->is_pressed()) {
+ List<StringName> names;
+ AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names);
+ for (List<StringName>::Element *E=names.front();E;E=E->next()) {
+ _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E->get()));
+ }
+ } else {
+ _cleanup_animation(animation);
+
+ }
+ } break;
case CURVE_SET_LINEAR: {
curve_edit->force_transition(1.0);
@@ -933,6 +951,57 @@ void AnimationKeyEditor::_menu_track(int p_type) {
}
+void AnimationKeyEditor::_cleanup_animation(Ref<Animation> p_animation) {
+
+
+ for(int i=0;i<p_animation->get_track_count();i++) {
+
+ bool prop_exists=false;
+ Variant::Type valid_type=Variant::NIL;
+ Object *obj=NULL;
+
+ RES res;
+ Node *node = root->get_node_and_resource(p_animation->track_get_path(i),res);
+
+ if (res.is_valid()) {
+ obj=res.ptr();
+ } else if (node) {
+ obj=node;
+ }
+
+ if (obj && p_animation->track_get_type(i)==Animation::TYPE_VALUE) {
+ valid_type=obj->get_static_property_type(p_animation->track_get_path(i).get_property(),&prop_exists);
+ }
+
+ if (!obj && cleanup_tracks->is_pressed()) {
+
+ p_animation->remove_track(i);
+ i--;
+ continue;
+ }
+
+ if (!prop_exists || p_animation->track_get_type(i)!=Animation::TYPE_VALUE || cleanup_keys->is_pressed()==false)
+ continue;
+
+ for(int j=0;j<p_animation->track_get_key_count(i);j++) {
+
+ Variant v = p_animation->track_get_key_value(i,j);
+
+ if (!Variant::can_convert(v.get_type(),valid_type)) {
+ p_animation->track_remove_key(i,j);
+ j--;
+ }
+ }
+
+ if (p_animation->track_get_key_count(i)==0 && cleanup_tracks->is_pressed()) {
+ p_animation->remove_track(i);
+ i--;
+ }
+ }
+
+ undo_redo->clear_history();
+ _update_paths();
+}
void AnimationKeyEditor::_animation_optimize() {
@@ -1042,6 +1111,7 @@ void AnimationKeyEditor::_track_editor_draw() {
timecolor = Color::html("ff4a414f");
Color hover_color = Color(1,1,1,0.05);
Color select_color = Color(1,1,1,0.1);
+ Color invalid_path_color = Color(1,0.6,0.4,0.5);
Color track_select_color =Color::html("ffbd8e8e");
Ref<Texture> remove_icon = get_icon("Remove","EditorIcons");
@@ -1068,6 +1138,9 @@ void AnimationKeyEditor::_track_editor_draw() {
get_icon("KeyCall","EditorIcons")
};
+ Ref<Texture> invalid_icon = get_icon("KeyInvalid","EditorIcons");
+ Ref<Texture> invalid_icon_hover = get_icon("KeyInvalidHover","EditorIcons");
+
Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons");
Ref<Texture> type_hover=get_icon("KeyHover","EditorIcons");
@@ -1254,6 +1327,23 @@ void AnimationKeyEditor::_track_editor_draw() {
break;
int y = h+i*h+sep;
+ bool prop_exists=false;
+ Variant::Type valid_type=Variant::NIL;
+ Object *obj=NULL;
+
+ RES res;
+ Node *node = root->get_node_and_resource(animation->track_get_path(idx),res);
+
+ if (res.is_valid()) {
+ obj=res.ptr();
+ } else if (node) {
+ obj=node;
+ }
+
+ if (obj && animation->track_get_type(idx)==Animation::TYPE_VALUE) {
+ valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists);
+ }
+
if (/*mouse_over.over!=MouseOver::OVER_NONE &&*/ idx==mouse_over.track) {
Color sepc=hover_color;
@@ -1274,6 +1364,8 @@ void AnimationKeyEditor::_track_editor_draw() {
ncol=track_select_color;
te->draw_string(font,Point2(ofs+Point2(type_icon[0]->get_width()+sep,y+font->get_ascent()+(sep/2))).floor(),np,ncol,name_limit-(type_icon[0]->get_width()+sep)-5);
+ if (!obj)
+ te->draw_line(ofs+Point2(0,y+h/2),ofs+Point2(name_limit,y+h/2),invalid_path_color);
te->draw_line(ofs+Point2(0,y+h),ofs+Point2(size.width,y+h),sepcolor);
@@ -1339,6 +1431,8 @@ void AnimationKeyEditor::_track_editor_draw() {
int kc=animation->track_get_key_count(idx);
bool first=true;
+
+
for(int i=0;i<kc;i++) {
@@ -1386,7 +1480,21 @@ void AnimationKeyEditor::_track_editor_draw() {
}
- te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor());
+ if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) {
+ te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor());
+ }
+
+ if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) {
+ if (tex==type_hover)
+ te->draw_texture(invalid_icon_hover,ofs+Point2(x,y+key_vofs).floor());
+ else
+ te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor());
+ } else {
+
+ te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor());
+ }
+
+
first=false;
}
@@ -2555,6 +2663,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
String text;
text="time: "+rtos(animation->track_get_key_time(idx,mouse_over.over_key))+"\n";
+
+
switch(animation->track_get_type(idx)) {
case Animation::TYPE_TRANSFORM: {
@@ -2569,8 +2679,33 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
} break;
case Animation::TYPE_VALUE: {
- Variant v = animation->track_get_key_value(idx,mouse_over.over_key);
- text+="value: "+String(v)+"\n";
+ Variant v = animation->track_get_key_value(idx,mouse_over.over_key);;
+ //text+="value: "+String(v)+"\n";
+
+ bool prop_exists=false;
+ Variant::Type valid_type=Variant::NIL;
+ Object *obj=NULL;
+
+ RES res;
+ Node *node = root->get_node_and_resource(animation->track_get_path(idx),res);
+
+ if (res.is_valid()) {
+ obj=res.ptr();
+ } else if (node) {
+ obj=node;
+ }
+
+ if (obj) {
+ valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists);
+ }
+
+ text+="type: "+Variant::get_type_name(v.get_type())+"\n";
+ if (prop_exists && !Variant::can_convert(v.get_type(),valid_type)) {
+ text+="value: "+String(v)+" (Invalid, expected type: "+Variant::get_type_name(valid_type)+")\n";
+ } else {
+ text+="value: "+String(v)+"\n";
+ }
+
} break;
case Animation::TYPE_METHOD: {
@@ -2593,6 +2728,9 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
} break;
}
text+="easing: "+rtos(animation->track_get_key_transition(idx,mouse_over.over_key));
+
+
+
track_editor->set_tooltip(text);
return;
@@ -2703,6 +2841,7 @@ void AnimationKeyEditor::_notification(int p_what) {
//menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions");
//menu_track->get_popup()->add_separator();
menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE);
+ menu_track->get_popup()->add_item("Clean-Up Animation",TRACK_MENU_CLEAN_UP);
curve_linear->set_icon(get_icon("CurveLinear","EditorIcons"));
curve_in->set_icon(get_icon("CurveIn","EditorIcons"));
@@ -3862,6 +4001,32 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
add_child(call_select);
call_select->set_title("Call Functions in Which Node?");
+ cleanup_dialog = memnew( ConfirmationDialog );
+ add_child(cleanup_dialog);
+ VBoxContainer *cleanup_vb = memnew( VBoxContainer );
+ cleanup_dialog->add_child(cleanup_vb);
+ cleanup_dialog->set_child_rect(cleanup_vb);
+ cleanup_keys = memnew( CheckButton );
+ cleanup_keys->set_text("Remove invalid keys");
+ cleanup_keys->set_pressed(true);
+ cleanup_vb->add_child(cleanup_keys);
+
+ cleanup_tracks = memnew( CheckButton );
+ cleanup_tracks->set_text("Remove unresolved and empty tracks");
+ cleanup_tracks->set_pressed(true);
+ cleanup_vb->add_child(cleanup_tracks);
+
+ cleanup_all = memnew( CheckButton );
+ cleanup_all->set_text("Clean-Up all animations");
+ cleanup_vb->add_child(cleanup_all);
+
+ cleanup_dialog->set_title("Clean up Animation(s) (NO UNDO!)");
+ cleanup_dialog->get_ok()->set_text("Clean-Up");
+
+ cleanup_dialog->connect("confirmed",this,"_menu_track",varray(TRACK_MENU_CLEAN_UP_CONFIRM));
+
+
+
}
AnimationKeyEditor::~AnimationKeyEditor() {
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 629377d78e..743242fe94 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -89,6 +89,8 @@ class AnimationKeyEditor : public VBoxContainer {
TRACK_MENU_NEXT_STEP,
TRACK_MENU_PREV_STEP,
TRACK_MENU_OPTIMIZE,
+ TRACK_MENU_CLEAN_UP,
+ TRACK_MENU_CLEAN_UP_CONFIRM,
CURVE_SET_LINEAR,
CURVE_SET_IN,
CURVE_SET_OUT,
@@ -190,6 +192,11 @@ class AnimationKeyEditor : public VBoxContainer {
SpinBox *optimize_angular_error;
SpinBox *optimize_max_angle;
+ ConfirmationDialog *cleanup_dialog;
+ CheckButton *cleanup_keys;
+ CheckButton *cleanup_tracks;
+ CheckButton *cleanup_all;
+
SpinBox *step;
MenuButton *menu_add_track;
@@ -284,6 +291,7 @@ class AnimationKeyEditor : public VBoxContainer {
void _animation_changed();
void _animation_optimize();
+ void _cleanup_animation(Ref<Animation> p_animation);
void _scroll_changed(double);
diff --git a/tools/editor/editor_file_dialog.cpp b/tools/editor/editor_file_dialog.cpp
index c62347d129..104539c308 100644
--- a/tools/editor/editor_file_dialog.cpp
+++ b/tools/editor/editor_file_dialog.cpp
@@ -27,14 +27,14 @@ void EditorFileDialog::_notification(int p_what) {
dir_prev->set_icon(get_icon("ArrowLeft","EditorIcons"));
dir_next->set_icon(get_icon("ArrowRight","EditorIcons"));
dir_up->set_icon(get_icon("ArrowUp","EditorIcons"));
+ refresh->set_icon(get_icon("Reload","EditorIcons"));
favorite->set_icon(get_icon("Favorites","EditorIcons"));
fav_up->set_icon(get_icon("MoveUp","EditorIcons"));
fav_down->set_icon(get_icon("MoveDown","EditorIcons"));
fav_rm->set_icon(get_icon("RemoveSmall","EditorIcons"));
- }
- if (p_what==NOTIFICATION_PROCESS) {
+ } else if (p_what==NOTIFICATION_PROCESS) {
if (preview_waiting) {
preview_wheel_timeout-=get_process_delta_time();
@@ -47,12 +47,17 @@ void EditorFileDialog::_notification(int p_what) {
preview_wheel_timeout=0.1;
}
}
- }
-
- if (p_what==NOTIFICATION_DRAW) {
+ } else if (p_what==NOTIFICATION_DRAW) {
//RID ci = get_canvas_item();
//get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
+ } else if (p_what==EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+
+ bool show_hidden = EditorSettings::get_singleton()->get("file_dialog/show_hidden_files");
+
+ if (show_hidden != show_hidden_files) {
+ set_show_hidden_files(show_hidden);
+ }
}
}
@@ -1012,7 +1017,7 @@ void EditorFileDialog::_go_forward(){
}
-bool EditorFileDialog::default_show_hidden_files=true;
+bool EditorFileDialog::default_show_hidden_files=false;
void EditorFileDialog::set_display_mode(DisplayMode p_mode) {
@@ -1141,7 +1146,7 @@ void EditorFileDialog::_save_to_recent() {
EditorFileDialog::EditorFileDialog() {
- show_hidden_files=true;
+ show_hidden_files=default_show_hidden_files;
display_mode=DISPLAY_THUMBNAILS;
local_history_pos=0;
@@ -1170,6 +1175,10 @@ EditorFileDialog::EditorFileDialog() {
pathhb->add_child(dir);
dir->set_h_size_flags(SIZE_EXPAND_FILL);
+ refresh = memnew( ToolButton );
+ refresh->connect("pressed",this,"_update_file_list");
+ pathhb->add_child(refresh);
+
favorite = memnew( ToolButton );
favorite->set_toggle_mode(true);
favorite->connect("toggled",this,"_favorite_toggled");
diff --git a/tools/editor/editor_file_dialog.h b/tools/editor/editor_file_dialog.h
index 6cfd970516..eb38c3c02f 100644
--- a/tools/editor/editor_file_dialog.h
+++ b/tools/editor/editor_file_dialog.h
@@ -108,6 +108,7 @@ private:
ToolButton *mode_list;
+ ToolButton *refresh;
ToolButton *favorite;
ToolButton *fav_up;
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index a4906c1b3a..cd455406b7 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -399,6 +399,40 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
}
+String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
+ String user_file = EditorSettings::get_singleton()->get_settings_path()
+ +"/templates/"+template_file_name;
+ String system_file=OS::get_singleton()->get_installed_templates_path();
+ bool has_system_path=(system_file!="");
+ system_file+=template_file_name;
+
+ // Prefer user file
+ if (FileAccess::exists(user_file)) {
+ return user_file;
+ }
+
+ // Now check system file
+ if (has_system_path) {
+ if (FileAccess::exists(system_file)) {
+ return system_file;
+ }
+ }
+
+ // Not found
+ if (err) {
+ *err+="No export template found at \""+user_file+"\"";
+ if (has_system_path)
+ *err+="\n or \""+system_file+"\".";
+ else
+ *err+=".";
+ }
+ return "";
+}
+
+bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const {
+ return find_export_template(template_file_name,err)!="";
+}
+
///////////////////////////////////////
@@ -1131,19 +1165,32 @@ Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug,
ep.step("Setting Up..",0);
- String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
- if (use64) {
- if (p_debug)
- exe_path=custom_debug_binary!=""?custom_debug_binary:exe_path+debug_binary64;
- else
- exe_path=custom_release_binary!=""?custom_release_binary:exe_path+release_binary64;
- } else {
+ String exe_path="";
- if (p_debug)
- exe_path=custom_debug_binary!=""?custom_debug_binary:exe_path+debug_binary32;
- else
- exe_path=custom_release_binary!=""?custom_release_binary:exe_path+release_binary32;
+ if (p_debug)
+ exe_path=custom_debug_binary;
+ else
+ exe_path=custom_release_binary;
+ if (exe_path=="") {
+ String fname;
+ if (use64) {
+ if (p_debug)
+ fname=debug_binary64;
+ else
+ fname=release_binary64;
+ } else {
+ if (p_debug)
+ fname=debug_binary32;
+ else
+ fname=release_binary32;
+ }
+ String err="";
+ exe_path=find_export_template(fname,&err);
+ if (exe_path=="") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_CANT_READ;
+ }
}
FileAccess *src_exe=FileAccess::open(exe_path,FileAccess::READ);
@@ -1207,14 +1254,12 @@ bool EditorExportPlatformPC::can_export(String *r_error) const {
String err;
bool valid=true;
- String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
-
- if (use64 && (!FileAccess::exists(exe_path+debug_binary64) || !FileAccess::exists(exe_path+release_binary64))) {
+ if (use64 && (!exists_export_template(debug_binary64)) || !exists_export_template(release_binary64)) {
valid=false;
err="No 64 bits export templates found.\nDownload and install export templates.\n";
}
- if (!use64 && (!FileAccess::exists(exe_path+debug_binary32) || !FileAccess::exists(exe_path+release_binary32))) {
+ if (!use64 && (!exists_export_template(debug_binary32) || !exists_export_template(release_binary32))) {
valid=false;
err="No 32 bits export templates found.\nDownload and install export templates.\n";
}
diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h
index e3ef3a592c..93086f7ad4 100644
--- a/tools/editor/editor_import_export.h
+++ b/tools/editor/editor_import_export.h
@@ -86,6 +86,8 @@ protected:
Vector<uint8_t> get_exported_file_default(String& p_fname) const;
virtual Vector<uint8_t> get_exported_file(String& p_fname) const;
virtual Vector<StringName> get_dependencies(bool p_bundles) const;
+ virtual String find_export_template(String template_file_name, String *err=NULL) const;
+ virtual bool exists_export_template(String template_file_name, String *err=NULL) const;
struct TempData {
diff --git a/tools/editor/editor_layout_dialog.cpp b/tools/editor/editor_layout_dialog.cpp
new file mode 100644
index 0000000000..e37f263c0c
--- /dev/null
+++ b/tools/editor/editor_layout_dialog.cpp
@@ -0,0 +1,59 @@
+/*************************************************************************/
+/* editor_node.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "editor_layout_dialog.h"
+#include "object_type_db.h"
+
+void EditorLayoutDialog::clear_layout_name() {
+
+ layout_name->clear();
+}
+
+void EditorLayoutDialog::ok_pressed() {
+
+ if (layout_name->get_text()!="") {
+ emit_signal("layout_selected", layout_name->get_text());
+ }
+}
+
+void EditorLayoutDialog::_bind_methods() {
+
+ ADD_SIGNAL(MethodInfo("layout_selected",PropertyInfo( Variant::STRING,"layout_name")));
+}
+
+EditorLayoutDialog::EditorLayoutDialog()
+{
+
+ layout_name = memnew( LineEdit );
+ layout_name->set_margin(MARGIN_TOP,5);
+ layout_name->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5);
+ layout_name->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5);
+ add_child(layout_name);
+ move_child(layout_name, get_label()->get_index()+1);
+}
diff --git a/tools/editor/editor_layout_dialog.h b/tools/editor/editor_layout_dialog.h
new file mode 100644
index 0000000000..7e3b9e3d8a
--- /dev/null
+++ b/tools/editor/editor_layout_dialog.h
@@ -0,0 +1,53 @@
+/*************************************************************************/
+/* editor_layout_dialog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef EDITOR_LAYOUT_DIALOG_H
+#define EDITOR_LAYOUT_DIALOG_H
+
+#include "scene/gui/dialogs.h"
+#include "scene/gui/line_edit.h"
+
+class EditorLayoutDialog : public ConfirmationDialog {
+
+ OBJ_TYPE( EditorLayoutDialog, ConfirmationDialog );
+
+ LineEdit *layout_name;
+
+protected:
+
+ static void _bind_methods();
+ virtual void ok_pressed();
+
+public:
+ void clear_layout_name();
+
+ EditorLayoutDialog();
+};
+
+#endif // EDITOR_LAYOUT_DIALOG_H
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 9ad517e57a..4afb98bdd4 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -543,7 +543,6 @@ void EditorNode::save_resource_as(const Ref<Resource>& p_resource) {
}
-
void EditorNode::_menu_option(int p_option) {
_menu_option_confirm(p_option,false);
@@ -1410,6 +1409,69 @@ void EditorNode::_dialog_action(String p_file) {
save_resource_in_path(current_res,p_file);
} break;
+ case SETTINGS_LAYOUT_SAVE: {
+
+ if (p_file.empty())
+ return;
+
+ if (p_file=="Default") {
+ confirm_error->set_text("Cannot overwrite default layout!");
+ confirm_error->popup_centered_minsize();
+ return;
+ }
+
+ Ref<ConfigFile> config;
+ config.instance();
+ Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
+ if (err!=OK && err!=ERR_FILE_NOT_FOUND) {
+ return; //no config
+ }
+
+ _save_docks_to_config(config, p_file);
+
+ config->save(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
+
+ layout_dialog->hide();
+ _update_layouts_menu();
+
+ } break;
+ case SETTINGS_LAYOUT_DELETE: {
+
+ if (p_file.empty())
+ return;
+
+ if (p_file=="Default") {
+ confirm_error->set_text("Cannot delete default layout!");
+ confirm_error->popup_centered_minsize();
+ return;
+ }
+
+ Ref<ConfigFile> config;
+ config.instance();
+ Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
+ if (err!=OK) {
+ return; //no config
+ }
+
+ if (!config->has_section(p_file)) {
+ confirm_error->set_text("Layout name not found!");
+ confirm_error->popup_centered_minsize();
+ return;
+ }
+
+ // erase
+ List<String> keys;
+ config->get_section_keys(p_file, &keys);
+ for (List<String>::Element *E=keys.front();E;E=E->next()) {
+ config->set_value(p_file, E->get(), Variant());
+ }
+
+ config->save(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
+
+ layout_dialog->hide();
+ _update_layouts_menu();
+
+ } break;
default: { //save scene?
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
@@ -2042,7 +2104,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
return;
};
// fallthrough to save_as
- } break;
+ };
case FILE_SAVE_AS_SCENE: {
Node *scene = editor_data.get_edited_scene_root();
@@ -4033,6 +4095,9 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("_dock_move_left",&EditorNode::_dock_move_left);
ObjectTypeDB::bind_method("_dock_move_right",&EditorNode::_dock_move_right);
+ ObjectTypeDB::bind_method("_layout_menu_option",&EditorNode::_layout_menu_option);
+ ObjectTypeDB::bind_method("_layout_dialog_action",&EditorNode::_dialog_action);
+
ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene);
ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version);
ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed);
@@ -4327,6 +4392,15 @@ void EditorNode::_save_docks() {
Ref<ConfigFile> config;
config.instance();
+ _save_docks_to_config(config, "docks");
+ editor_data.get_plugin_window_layout(config);
+
+ config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg"));
+
+}
+
+void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section) {
+
for(int i=0;i<DOCK_SLOT_MAX;i++) {
String names;
for(int j=0;j<dock_slot[i]->get_tab_count();j++) {
@@ -4337,7 +4411,7 @@ void EditorNode::_save_docks() {
}
if (names!="") {
- config->set_value("docks","dock_"+itos(i+1),names);
+ p_layout->set_value(p_section,"dock_"+itos(i+1),names);
}
}
@@ -4351,7 +4425,7 @@ void EditorNode::_save_docks() {
for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
if (splits[i]->is_visible()) {
- config->set_value("docks","dock_split_"+itos(i+1),splits[i]->get_split_offset());
+ p_layout->set_value(p_section,"dock_split_"+itos(i+1),splits[i]->get_split_offset());
}
}
@@ -4365,13 +4439,9 @@ void EditorNode::_save_docks() {
for(int i=0;i<4;i++) {
- config->set_value("docks","dock_hsplit_"+itos(i+1),h_splits[i]->get_split_offset());
+ p_layout->set_value(p_section,"dock_hsplit_"+itos(i+1),h_splits[i]->get_split_offset());
}
- editor_data.get_plugin_window_layout(config);
-
- config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg"));
-
}
void EditorNode::save_layout() {
@@ -4393,12 +4463,19 @@ void EditorNode::_load_docks() {
return; //no config
}
+ _load_docks_from_config(config, "docks");
+ editor_data.set_plugin_window_layout(config);
+
+}
+
+void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section) {
+
for(int i=0;i<DOCK_SLOT_MAX;i++) {
- if (!config->has_section_key("docks","dock_"+itos(i+1)))
+ if (!p_layout->has_section_key(p_section,"dock_"+itos(i+1)))
continue;
- Vector<String> names = String(config->get_value("docks","dock_"+itos(i+1))).split(",");
+ Vector<String> names = String(p_layout->get_value(p_section,"dock_"+itos(i+1))).split(",");
for(int j=0;j<names.size();j++) {
@@ -4418,7 +4495,7 @@ void EditorNode::_load_docks() {
if (atidx==-1) //well, it's not anywhere
continue;
- if (atidx==j) {
+ if (atidx==i) {
node->raise();
continue;
}
@@ -4433,7 +4510,6 @@ void EditorNode::_load_docks() {
dock_slot[i]->add_child(node);
dock_slot[i]->show();
}
-
}
VSplitContainer*splits[DOCK_SLOT_MAX/2]={
@@ -4445,14 +4521,14 @@ void EditorNode::_load_docks() {
for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
- if (!config->has_section_key("docks","dock_split_"+itos(i+1)))
+ if (!p_layout->has_section_key(p_section,"dock_split_"+itos(i+1)))
continue;
- int ofs = config->get_value("docks","dock_split_"+itos(i+1));
+ int ofs = p_layout->get_value(p_section,"dock_split_"+itos(i+1));
splits[i]->set_split_offset(ofs);
}
- HSplitContainer *h_splits[4]={
+ HSplitContainer*h_splits[4]={
left_l_hsplit,
left_r_hsplit,
main_hsplit,
@@ -4460,9 +4536,9 @@ void EditorNode::_load_docks() {
};
for(int i=0;i<4;i++) {
- if (!config->has_section_key("docks","dock_hsplit_"+itos(i+1)))
+ if (!p_layout->has_section_key(p_section,"dock_hsplit_"+itos(i+1)))
continue;
- int ofs = config->get_value("docks","dock_hsplit_"+itos(i+1));
+ int ofs = p_layout->get_value(p_section,"dock_hsplit_"+itos(i+1));
h_splits[i]->set_split_offset(ofs);
}
@@ -4480,8 +4556,78 @@ void EditorNode::_load_docks() {
dock_slot[i]->set_current_tab(0);
}
}
+}
- editor_data.set_plugin_window_layout(config);
+
+void EditorNode::_update_layouts_menu() {
+
+ editor_layouts->clear();
+ editor_layouts->set_size(Vector2());
+ editor_layouts->add_item("Save Layout", SETTINGS_LAYOUT_SAVE);
+ editor_layouts->add_item("Delete Layout", SETTINGS_LAYOUT_DELETE);
+ editor_layouts->add_separator();
+ editor_layouts->add_item("Default", SETTINGS_LAYOUT_DEFAULT);
+
+ Ref<ConfigFile> config;
+ config.instance();
+ Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
+ if (err!=OK) {
+ return; //no config
+ }
+
+ List<String> layouts;
+ config.ptr()->get_sections(&layouts);
+
+ for (List<String>::Element *E=layouts.front();E;E=E->next()) {
+
+ String layout=E->get();
+
+ if (layout!="Default")
+ editor_layouts->add_item(layout);
+ }
+
+}
+
+void EditorNode::_layout_menu_option(int p_id) {
+
+ switch (p_id) {
+
+ case SETTINGS_LAYOUT_SAVE: {
+
+ current_option=p_id;
+ layout_dialog->clear_layout_name();
+ layout_dialog->set_title("Save Layout");
+ layout_dialog->get_ok()->set_text("Save");
+ layout_dialog->popup_centered();
+ } break;
+ case SETTINGS_LAYOUT_DELETE: {
+
+ current_option=p_id;
+ layout_dialog->clear_layout_name();
+ layout_dialog->set_title("Delete Layout");
+ layout_dialog->get_ok()->set_text("Delete");
+ layout_dialog->popup_centered();
+ } break;
+ case SETTINGS_LAYOUT_DEFAULT: {
+
+ _load_docks_from_config(default_theme, "docks");
+ _save_docks();
+ } break;
+ default: {
+
+ Ref<ConfigFile> config;
+ config.instance();
+ Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
+ if (err!=OK) {
+ return; //no config
+ }
+
+ int idx=editor_layouts->get_item_index(p_id);
+ _load_docks_from_config(config, editor_layouts->get_item_text(idx));
+ _save_docks();
+
+ }
+ }
}
@@ -4594,6 +4740,7 @@ EditorNode::EditorNode() {
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"));
+ EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"));
ResourceLoader::set_error_notify_func(this,_load_error_notify);
ResourceLoader::set_dependency_error_notify_func(this,_dependency_error_report);
@@ -5236,17 +5383,29 @@ EditorNode::EditorNode() {
right_menu_hb->add_child( settings_menu );
p=settings_menu->get_popup();
-
//p->add_item("Export Settings",SETTINGS_EXPORT_PREFERENCES);
p->add_item("Editor Settings",SETTINGS_PREFERENCES);
//p->add_item("Optimization Presets",SETTINGS_OPTIMIZED_PRESETS);
p->add_separator();
+ editor_layouts = memnew( PopupMenu );
+ editor_layouts->set_name("Layouts");
+ p->add_child(editor_layouts);
+ editor_layouts->connect("item_pressed",this,"_layout_menu_option");
+ p->add_submenu_item("Editor Layout", "Layouts");
+ p->add_separator();
p->add_check_item("Show Animation",SETTINGS_SHOW_ANIMATION,KEY_MASK_CMD+KEY_N);
p->add_separator();
p->add_item("Install Export Templates",SETTINGS_LOAD_EXPORT_TEMPLATES);
p->add_separator();
p->add_item("About",SETTINGS_ABOUT);
+ layout_dialog = memnew( EditorLayoutDialog );
+ gui_base->add_child(layout_dialog);
+ layout_dialog->set_hide_on_ok(false);
+ layout_dialog->set_size(Size2(175, 70));
+ confirm_error = memnew( AcceptDialog );
+ layout_dialog->add_child(confirm_error);
+ layout_dialog->connect("layout_selected", this,"_layout_dialog_action");
sources_button = memnew( ToolButton );
right_menu_hb->add_child(sources_button);
@@ -5433,7 +5592,19 @@ EditorNode::EditorNode() {
scenes_dock->connect("open",this,"open_request");
scenes_dock->connect("instance",this,"_instance_request");
+ const String docks_section = "docks";
+
+ default_theme.instance();
+ default_theme->set_value(docks_section, "dock_3", "Scene");
+ default_theme->set_value(docks_section, "dock_4", "FileSystem");
+ default_theme->set_value(docks_section, "dock_5", "Inspector");
+
+ for(int i=0;i<DOCK_SLOT_MAX/2;i++)
+ default_theme->set_value(docks_section, "dock_hsplit_"+itos(i+1), 0);
+ for(int i=0;i<DOCK_SLOT_MAX/2;i++)
+ default_theme->set_value(docks_section, "dock_split_"+itos(i+1), 0);
+ _update_layouts_menu();
log = memnew( EditorLog );
center_split->add_child(log);
@@ -5742,7 +5913,7 @@ EditorNode::EditorNode() {
resource_preview->add_preview_generator( Ref<EditorMeshPreviewPlugin>( memnew(EditorMeshPreviewPlugin )));
circle_step_msec=OS::get_singleton()->get_ticks_msec();
- circle_step_frame=OS::get_singleton()->get_frames_drawn();;
+ circle_step_frame=OS::get_singleton()->get_frames_drawn();
circle_step=0;
_rebuild_import_menu();
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 5cc9d9eaa2..bd25f27c59 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -76,6 +76,7 @@
#include "editor_reimport_dialog.h"
#include "import_settings.h"
#include "tools/editor/editor_plugin.h"
+#include "tools/editor/editor_layout_dialog.h"
#include "fileserver/editor_file_server.h"
#include "editor_resource_preview.h"
@@ -167,6 +168,9 @@ class EditorNode : public Node {
SETTINGS_EXPORT_PREFERENCES,
SETTINGS_PREFERENCES,
SETTINGS_OPTIMIZED_PRESETS,
+ SETTINGS_LAYOUT_SAVE,
+ SETTINGS_LAYOUT_DELETE,
+ SETTINGS_LAYOUT_DEFAULT,
SETTINGS_SHOW_ANIMATION,
SETTINGS_LOAD_EXPORT_TEMPLATES,
SETTINGS_HELP,
@@ -284,6 +288,11 @@ class EditorNode : public Node {
AcceptDialog *about;
AcceptDialog *warning;
+ Ref<ConfigFile> default_theme;
+ PopupMenu *editor_layouts;
+ EditorLayoutDialog *layout_dialog;
+ AcceptDialog *confirm_error;
+
//OptimizedPresetsDialog *optimized_presets;
EditorSettingsDialog *settings_config_dialog;
RunSettingsDialog *run_settings_dialog;
@@ -523,13 +532,18 @@ class EditorNode : public Node {
void _save_docks();
void _load_docks();
+ void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section);
+ void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section);
+
+ void _update_layouts_menu();
+ void _layout_menu_option(int p_idx);
void _toggle_search_bar(bool p_pressed);
void _clear_search_box();
protected:
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
enum EditorTable {
diff --git a/tools/editor/editor_settings.h b/tools/editor/editor_settings.h
index 4ba940cd1c..bdfa5160d6 100644
--- a/tools/editor/editor_settings.h
+++ b/tools/editor/editor_settings.h
@@ -107,6 +107,7 @@ public:
static EditorSettings *get_singleton();
void erase(String p_var);
String get_settings_path() const;
+ String get_global_settings_path() const;
String get_project_settings_path() const;
const Map<String,Plugin>& get_plugins() const { return plugins; }
diff --git a/tools/editor/groups_editor.cpp b/tools/editor/groups_editor.cpp
index 2e82854014..bb5e93da34 100644
--- a/tools/editor/groups_editor.cpp
+++ b/tools/editor/groups_editor.cpp
@@ -27,151 +27,130 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "groups_editor.h"
-#include "scene/gui/box_container.h"
+#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
+void GroupsEditor::_add_group(const String& p_group) {
-#include "print_string.h"
+ if (!node)
+ return;
-void GroupsEditor::_notification(int p_what) {
-
- if (p_what==NOTIFICATION_ENTER_TREE) {
- connect("confirmed", this,"_close");
- }
- if (p_what==NOTIFICATION_EXIT_TREE) {
- disconnect("confirmed", this,"_close");
- }
-}
+ String name = group_name->get_text();
+ if (name.strip_edges()=="")
+ return;
-void GroupsEditor::_close() {
-
- hide();
-
-}
-void GroupsEditor::_add() {
-
- if (!node)
+ if (node->is_in_group(name))
return;
-
- undo_redo->create_action("Add To Group");
- undo_redo->add_do_method(node,"add_to_group",group_name->get_text(),true);
- undo_redo->add_undo_method(node,"remove_from_group",group_name->get_text());
+ undo_redo->create_action("Add to Group");
+
+ undo_redo->add_do_method(node,"add_to_group",name,true);
undo_redo->add_do_method(this,"update_tree");
+ undo_redo->add_undo_method(node,"remove_from_group",name,get_text());
undo_redo->add_undo_method(this,"update_tree");
undo_redo->commit_action();
}
+void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) {
-void GroupsEditor::_remove() {
-
- if (!tree->get_selected())
- return;
if (!node)
return;
- TreeItem *sel = tree->get_selected();
- if (!sel)
+ TreeItem *ti = p_item->cast_to<TreeItem>();
+ if (!ti)
return;
-
- node->remove_from_group( sel->get_text(0) );
- update_tree();
+
+ String name = ti->get_text(0);
+
+ undo_redo->create_action("Remove from Group");
+
+ undo_redo->add_do_method(node,"remove_from_group",name);
+ undo_redo->add_do_method(this,"update_tree");
+ undo_redo->add_undo_method(node,"add_to_group",name,true);
+ undo_redo->add_undo_method(this,"update_tree");
+
+ undo_redo->commit_action();
}
+struct _GroupInfoComparator {
+
+ bool operator()(const Node::GroupInfo& p_a, const Node::GroupInfo& p_b) const {
+ return p_a.name.operator String() < p_b.name.operator String();
+ }
+};
+
void GroupsEditor::update_tree() {
-
tree->clear();
-
+
if (!node)
return;
-
- List<GroupInfo> groups;
+
+ List<Node::GroupInfo> groups;
node->get_groups(&groups);
-
+ groups.sort_custom<_GroupInfoComparator>();
+
TreeItem *root=tree->create_item();
-
+
for(List<GroupInfo>::Element *E=groups.front();E;E=E->next()) {
-
- if (!E->get().persistent)
+
+ Node::GroupInfo gi = E->get();
+ if (!gi.persistent)
continue;
+
TreeItem *item=tree->create_item(root);
- item->set_text(0, E->get().name);
-
+ item->set_text(0, gi.name);
+ item->add_button(0, get_icon("Remove", "EditorIcons"), 0);
}
-
}
void GroupsEditor::set_current(Node* p_node) {
-
+
node=p_node;
update_tree();
-
}
void GroupsEditor::_bind_methods() {
-
- ObjectTypeDB::bind_method("_add",&GroupsEditor::_add);
- ObjectTypeDB::bind_method("_close",&GroupsEditor::_close);
- ObjectTypeDB::bind_method("_remove",&GroupsEditor::_remove);
+
+ ObjectTypeDB::bind_method("_add_group",&GroupsEditor::_add_group);
+ ObjectTypeDB::bind_method("_remove_group",&GroupsEditor::_remove_group);
ObjectTypeDB::bind_method("update_tree",&GroupsEditor::update_tree);
}
GroupsEditor::GroupsEditor() {
+ node=NULL;
+
set_title("Group Editor");
-
- Label * label = memnew( Label );
- label->set_pos( Point2( 8,11) );
- label->set_text("Groups:");
-
- add_child(label);
-
- group_name = memnew(LineEdit);
- group_name->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- group_name->set_begin( Point2( 15,28) );
- group_name->set_end( Point2( 94,48 ) );
-
- add_child(group_name);
-
- tree = memnew( Tree );
- tree->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
- tree->set_begin( Point2( 15,52) );
- tree->set_end( Point2( 94,42 ) );
- tree->set_hide_root(true);
- add_child(tree);
-
+
+ VBoxContainer *vbc = memnew( VBoxContainer );
+ add_child(vbc);
+ set_child_rect(vbc);
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ vbc->add_margin_child("Group", hbc);
+
+ group_name = memnew( LineEdit );
+ group_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ hbc->add_child(group_name);
+ group_name->connect("text_entered",this,"_add_group");
+
add = memnew( Button );
- add->set_anchor( MARGIN_LEFT, ANCHOR_END );
- add->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- add->set_begin( Point2( 90, 28 ) );
- add->set_end( Point2( 15, 48 ) );
add->set_text("Add");
-
- add_child(add);
-
- remove = memnew( Button );
- remove->set_anchor( MARGIN_LEFT, ANCHOR_END );
- remove->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- remove->set_begin( Point2( 90, 52 ) );
- remove->set_end( Point2( 15, 72 ) );
- remove->set_text("Remove");
-
- add_child(remove);
+ hbc->add_child(add);
+ add->connect("pressed", this,"_add_group", varray(String()));
- get_ok()->set_text("Close");
-
- add->connect("pressed", this,"_add");
- remove->connect("pressed", this,"_remove");
+ tree = memnew( Tree );
+ tree->set_hide_root(true);
+ tree->set_v_size_flags(SIZE_EXPAND_FILL);
+ vbc->add_margin_child("Node Group(s)", tree, true);
+ tree->connect("button_pressed",this,"_remove_group");
-
- node=NULL;
+ get_ok()->set_text("Close");
}
-
GroupsEditor::~GroupsEditor()
{
}
diff --git a/tools/editor/groups_editor.h b/tools/editor/groups_editor.h
index 09883a150f..3a9cc77727 100644
--- a/tools/editor/groups_editor.h
+++ b/tools/editor/groups_editor.h
@@ -29,42 +29,42 @@
#ifndef GROUPS_EDITOR_H
#define GROUPS_EDITOR_H
-
#include "scene/gui/dialogs.h"
#include "scene/gui/button.h"
#include "scene/gui/tree.h"
#include "scene/gui/line_edit.h"
#include "undo_redo.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-class GroupsEditor : public ConfirmationDialog {
-
- OBJ_TYPE( GroupsEditor, ConfirmationDialog );
-
+
+class GroupsEditor : public AcceptDialog {
+
+ OBJ_TYPE(GroupsEditor,AcceptDialog);
+
+ Node *node;
+
LineEdit *group_name;
- Tree *tree;
Button *add;
- Button *remove;
- Node *node;
+ Tree *tree;
+
UndoRedo *undo_redo;
-
+
void update_tree();
- void _add();
- void _remove();
+ void _add_group(const String& p_group="");
+ void _remove_group(Object *p_item, int p_column, int p_id);
void _close();
-
protected:
-
- void _notification(int p_what);
- static void _bind_methods();
+
+ static void _bind_methods();
public:
-
+
void set_undo_redo(UndoRedo *p_undoredo) { undo_redo=p_undoredo; }
void set_current(Node* p_node);
-
+
GroupsEditor();
~GroupsEditor();
-
};
+
#endif
diff --git a/tools/editor/icons/icon_key_invalid.png b/tools/editor/icons/icon_key_invalid.png
new file mode 100644
index 0000000000..e8e6c87180
--- /dev/null
+++ b/tools/editor/icons/icon_key_invalid.png
Binary files differ
diff --git a/tools/editor/icons/icon_key_invalid_hover.png b/tools/editor/icons/icon_key_invalid_hover.png
new file mode 100644
index 0000000000..6f0396d96a
--- /dev/null
+++ b/tools/editor/icons/icon_key_invalid_hover.png
Binary files differ
diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp
index 10a3877529..5ba0669f1d 100644
--- a/tools/editor/io_plugins/editor_font_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp
@@ -520,6 +520,10 @@ class EditorFontImportDialog : public ConfirmationDialog {
return;
}
+ if (dest->get_line_edit()->get_text().get_file()==".fnt") {
+ dest->get_line_edit()->set_text(dest->get_line_edit()->get_text().get_base_dir() + "/" + source->get_line_edit()->get_text().get_file().basename() + ".fnt" );
+ }
+
Ref<ResourceImportMetadata> rimd = get_rimd();
if (rimd.is_null()) {
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 6542fc8b4a..dc2c241d2f 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -1250,8 +1250,15 @@ void AnimationPlayerEditor::_bind_methods() {
}
+AnimationPlayerEditor *AnimationPlayerEditor::singleton=NULL;
+
+AnimationPlayer *AnimationPlayerEditor::get_player() const {
+
+ return player;
+}
AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
editor=p_editor;
+ singleton=this;
updating=false;
diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h
index ac4d1ab6ba..839df3ddcc 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.h
+++ b/tools/editor/plugins/animation_player_editor_plugin.h
@@ -162,6 +162,7 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_tool_menu(int p_option);
void _animation_save_menu(int p_option);
+
AnimationPlayerEditor();
protected:
@@ -171,6 +172,9 @@ protected:
static void _bind_methods();
public:
+ AnimationPlayer *get_player() const;
+ static AnimationPlayerEditor *singleton;
+
Dictionary get_state() const;
void set_state(const Dictionary& p_state);
diff --git a/tools/editor/plugins/item_list_editor_plugin.cpp b/tools/editor/plugins/item_list_editor_plugin.cpp
index fa261edea3..9c53c73afd 100644
--- a/tools/editor/plugins/item_list_editor_plugin.cpp
+++ b/tools/editor/plugins/item_list_editor_plugin.cpp
@@ -30,7 +30,6 @@
#include "io/resource_loader.h"
-
bool ItemListPlugin::_set(const StringName& p_name, const Variant& p_value) {
String name = p_name;
@@ -45,12 +44,10 @@ bool ItemListPlugin::_set(const StringName& p_name, const Variant& p_value) {
set_item_checkable(idx,p_value);
else if (what=="checked")
set_item_checked(idx,p_value);
- else if (what=="enabled")
- set_item_enabled(idx,p_value);
- else if (what=="accel")
- set_item_accel(idx,p_value);
else if (what=="id")
set_item_id(idx,p_value);
+ else if (what=="enabled")
+ set_item_enabled(idx,p_value);
else if (what=="separator")
set_item_separator(idx,p_value);
else
@@ -60,6 +57,7 @@ bool ItemListPlugin::_set(const StringName& p_name, const Variant& p_value) {
}
bool ItemListPlugin::_get(const StringName& p_name,Variant &r_ret) const {
+
String name = p_name;
int idx = name.get_slice("/",0).to_int();
String what=name.get_slice("/",1);
@@ -72,12 +70,10 @@ bool ItemListPlugin::_get(const StringName& p_name,Variant &r_ret) const {
r_ret=is_item_checkable(idx);
else if (what=="checked")
r_ret=is_item_checked(idx);
- else if (what=="enabled")
- r_ret=is_item_enabled(idx);
- else if (what=="accel")
- r_ret=get_item_accel(idx);
else if (what=="id")
r_ret=get_item_id(idx);
+ else if (what=="enabled")
+ r_ret=is_item_enabled(idx);
else if (what=="separator")
r_ret=is_item_separator(idx);
else
@@ -93,66 +89,119 @@ void ItemListPlugin::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo(Variant::STRING,base+"text") );
p_list->push_back( PropertyInfo(Variant::OBJECT,base+"icon",PROPERTY_HINT_RESOURCE_TYPE,"Texture") );
- if (get_flags()&FLAG_CHECKABLE) {
+ int flags = get_flags();
+
+ if (flags&FLAG_CHECKABLE) {
p_list->push_back( PropertyInfo(Variant::BOOL,base+"checkable") );
p_list->push_back( PropertyInfo(Variant::BOOL,base+"checked") );
-
}
- if (get_flags()&FLAG_ENABLE) {
+ if (flags&FLAG_ID)
+ p_list->push_back( PropertyInfo(Variant::INT,base+"id",PROPERTY_HINT_RANGE,"-1,4096") );
+
+ if (flags&FLAG_ENABLE)
p_list->push_back( PropertyInfo(Variant::BOOL,base+"enabled") );
- }
- if (get_flags()&FLAG_ACCEL) {
+ if (flags&FLAG_SEPARATOR)
+ p_list->push_back( PropertyInfo(Variant::BOOL,base+"separator") );
+ }
+}
- p_list->push_back( PropertyInfo(Variant::INT,base+"accel",PROPERTY_HINT_KEY_ACCEL) );
+///////////////////////////////////////////////////////////////
+///////////////////////// PLUGINS /////////////////////////////
+///////////////////////////////////////////////////////////////
- }
- if (get_flags()&FLAG_ID) {
+void ItemListOptionButtonPlugin::set_object(Object *p_object) {
- p_list->push_back( PropertyInfo(Variant::INT,base+"id",PROPERTY_HINT_RANGE,"-1,4096") );
+ ob = p_object->cast_to<OptionButton>();
+}
- }
- if (get_flags()&FLAG_SEPARATOR) {
+bool ItemListOptionButtonPlugin::handles(Object *p_object) const {
- p_list->push_back( PropertyInfo(Variant::BOOL,base+"separator") );
+ return p_object->is_type("OptionButton");
+}
- }
- }
+int ItemListOptionButtonPlugin::get_flags() const {
+
+ return FLAG_ICON|FLAG_ID|FLAG_ENABLE;
}
-void ItemListEditor::_node_removed(Node *p_node) {
+void ItemListOptionButtonPlugin::add_item() {
- if(p_node==item_list) {
- item_list=NULL;
- hide();
- dialog->hide();
- }
+ ob->add_item( "Item "+itos(ob->get_item_count()));
+ _change_notify();
+}
+int ItemListOptionButtonPlugin::get_item_count() const {
+ return ob->get_item_count();
}
-void ItemListEditor::_delete_pressed() {
+void ItemListOptionButtonPlugin::erase(int p_idx) {
- String p = prop_editor->get_selected_path();
+ ob->remove_item(p_idx);
+ _change_notify();
+}
- if (p.find("/")!=-1) {
+ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() {
- if (selected_idx<0 || selected_idx>=item_plugins.size())
- return;
+ ob=NULL;
+}
- item_plugins[selected_idx]->erase(p.get_slice("/",0).to_int());;
- }
+///////////////////////////////////////////////////////////////
+
+void ItemListPopupMenuPlugin::set_object(Object *p_object) {
+ if (p_object->is_type("MenuButton"))
+ pp = p_object->cast_to<MenuButton>()->get_popup();
+ else
+ pp = p_object->cast_to<PopupMenu>();
}
-void ItemListEditor::_add_pressed() {
+bool ItemListPopupMenuPlugin::handles(Object *p_object) const {
- if (selected_idx<0 || selected_idx>=item_plugins.size())
- return;
+ return p_object->is_type("PopupMenu") || p_object->is_type("MenuButton");
+}
- item_plugins[selected_idx]->add_item();
+int ItemListPopupMenuPlugin::get_flags() const {
+
+ return FLAG_ICON|FLAG_CHECKABLE|FLAG_ID|FLAG_ENABLE|FLAG_SEPARATOR;
+}
+
+void ItemListPopupMenuPlugin::add_item() {
+
+ pp->add_item( "Item "+itos(pp->get_item_count()));
+ _change_notify();
+}
+
+int ItemListPopupMenuPlugin::get_item_count() const {
+
+ return pp->get_item_count();
+}
+
+void ItemListPopupMenuPlugin::erase(int p_idx) {
+
+ pp->remove_item(p_idx);
+ _change_notify();
+}
+
+ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() {
+
+ pp=NULL;
+}
+
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+
+void ItemListEditor::_node_removed(Node *p_node) {
+
+ if(p_node==item_list) {
+ item_list=NULL;
+ hide();
+ dialog->hide();
+ }
}
void ItemListEditor::_notification(int p_notification) {
@@ -160,57 +209,73 @@ void ItemListEditor::_notification(int p_notification) {
if (p_notification==NOTIFICATION_ENTER_TREE) {
add_button->set_icon(get_icon("Add","EditorIcons"));
- del_button->set_icon(get_icon("Del","EditorIcons"));
+ del_button->set_icon(get_icon("Remove","EditorIcons"));
}
}
+void ItemListEditor::_add_pressed() {
-void ItemListEditor::_menu_option(int p_option) {
+ if (selected_idx==-1)
+ return;
+ item_plugins[selected_idx]->add_item();
+}
- switch(p_option) {
+void ItemListEditor::_delete_pressed() {
- case MENU_EDIT_ITEMS: {
+ TreeItem *ti = tree->get_selected();
- dialog->popup_centered_ratio();
- } break;
- }
+ if (!ti)
+ return;
+
+ if (ti->get_parent()!=tree->get_root())
+ return;
+
+ int idx = ti->get_text(0).to_int();
+
+ if (selected_idx==-1)
+ return;
+
+ item_plugins[selected_idx]->erase(idx);
}
+void ItemListEditor::_edit_items() {
+
+ dialog->popup_centered(Vector2(300, 400));
+}
void ItemListEditor::edit(Node *p_item_list) {
item_list=p_item_list;
+ if (!item_list) {
+ selected_idx=-1;
+ property_editor->edit(NULL);
+ return;
+ }
+
for(int i=0;i<item_plugins.size();i++) {
if (item_plugins[i]->handles(p_item_list)) {
item_plugins[i]->set_object(p_item_list);
- prop_editor->edit(item_plugins[i]);
+ property_editor->edit(item_plugins[i]);
+
+ if (has_icon(item_list->get_type(), "EditorIcons"))
+ toolbar_button->set_icon(get_icon(item_list->get_type(), "EditorIcons"));
+ else
+ toolbar_button->set_icon(Ref<Texture>());
+
selected_idx=i;
return;
}
}
selected_idx=-1;
-
- prop_editor->edit(NULL);
-
-}
-
-
-void ItemListEditor::_bind_methods() {
-
- ObjectTypeDB::bind_method("_menu_option",&ItemListEditor::_menu_option);
- ObjectTypeDB::bind_method("_add_button",&ItemListEditor::_add_pressed);
- ObjectTypeDB::bind_method("_delete_button",&ItemListEditor::_delete_pressed);
-
- //ObjectTypeDB::bind_method("_populate",&ItemListEditor::_populate);
-
+ property_editor->edit(NULL);
}
bool ItemListEditor::handles(Object *p_object) const {
- return false;
+
for(int i=0;i<item_plugins.size();i++) {
if (item_plugins[i]->handles(p_object)) {
return true;
@@ -218,57 +283,65 @@ bool ItemListEditor::handles(Object *p_object) const {
}
return false;
+}
+void ItemListEditor::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_edit_items",&ItemListEditor::_edit_items);
+ ObjectTypeDB::bind_method("_add_button",&ItemListEditor::_add_pressed);
+ ObjectTypeDB::bind_method("_delete_button",&ItemListEditor::_delete_pressed);
}
+
ItemListEditor::ItemListEditor() {
selected_idx=-1;
- options = memnew( MenuButton );
- add_child(options);
- options->set_area_as_parent_rect();
- options->set_text("Items");
- options->get_popup()->add_item("Edit Items",MENU_EDIT_ITEMS);
- //options->get_popup()->add_item("Clear",MENU_CLEAR);
+ add_child( memnew( VSeparator ) );
- options->get_popup()->connect("item_pressed", this,"_menu_option");
+ toolbar_button = memnew( ToolButton );
+ toolbar_button->set_text("Items");
+ add_child(toolbar_button);
+ toolbar_button->connect("pressed",this,"_edit_items");
dialog = memnew( AcceptDialog );
+ dialog->set_title("Item List Editor");
add_child( dialog );
-
+ VBoxContainer *vbc = memnew( VBoxContainer );
+ dialog->add_child(vbc);
+ dialog->set_child_rect(vbc);
HBoxContainer *hbc = memnew( HBoxContainer );
-
- dialog->add_child(hbc);
- dialog->set_child_rect(hbc);
-
- prop_editor = memnew( PropertyEditor );
-
- hbc->add_child(prop_editor);
- prop_editor->set_h_size_flags(SIZE_EXPAND_FILL);
-
- VBoxContainer *vbc = memnew( VBoxContainer );
- hbc->add_child(vbc);
+ hbc->set_h_size_flags(SIZE_EXPAND_FILL);
+ vbc->add_child(hbc);
add_button = memnew( Button );
- //add_button->set_text("Add");
+ add_button->set_text("Add");
+ hbc->add_child(add_button);
add_button->connect("pressed",this,"_add_button");
- vbc->add_child(add_button);
+
+ hbc->add_spacer();
del_button = memnew( Button );
- //del_button->set_text("Del");
+ del_button->set_text("Delete");
+ hbc->add_child(del_button);
del_button->connect("pressed",this,"_delete_button");
- vbc->add_child(del_button);
- dialog->set_title("Item List");
- prop_editor->hide_top_label();
+ property_editor = memnew( PropertyEditor );
+ property_editor->hide_top_label();
+ property_editor->set_subsection_selectable(true);
+ vbc->add_child(property_editor);
+ property_editor->set_v_size_flags(SIZE_EXPAND_FILL);
+ tree = property_editor->get_scene_tree();
+}
+ItemListEditor::~ItemListEditor() {
+ for(int i=0;i<item_plugins.size();i++)
+ memdelete( item_plugins[i] );
}
-
void ItemListEditorPlugin::edit(Object *p_object) {
item_list_editor->edit(p_object->cast_to<Node>());
@@ -288,127 +361,19 @@ void ItemListEditorPlugin::make_visible(bool p_visible) {
item_list_editor->hide();
item_list_editor->edit(NULL);
}
-
-}
-
-
-ItemListEditor::~ItemListEditor() {
-
- for(int i=0;i<item_plugins.size();i++)
- memdelete( item_plugins[i] );
}
-///////////////////////// PLUGINS /////////////////////////////
-///////////////////////// PLUGINS /////////////////////////////
-///////////////////////// PLUGINS /////////////////////////////
-///////////////////////// PLUGINS /////////////////////////////
-///////////////////////// PLUGINS /////////////////////////////
-
-
-class ItemListOptionButtonPlugin : public ItemListPlugin {
-
- OBJ_TYPE(ItemListOptionButtonPlugin,ItemListPlugin);
-
- OptionButton *ob;
-public:
-
- virtual void set_object(Object *p_object) { ob = p_object->cast_to<OptionButton>(); }
-
- virtual bool handles(Object *p_object) const { return p_object->cast_to<OptionButton>()!=NULL; }
-
- virtual int get_flags() const { return FLAG_ICON|FLAG_ID|FLAG_ENABLE; }
-
- virtual void set_item_text(int p_idx,const String& p_text){ ob->set_item_text(p_idx,p_text);}
- virtual void set_item_icon(int p_idx,const Ref<Texture>& p_tex){ ob->set_item_icon(p_idx,p_tex);}
- virtual void set_item_enabled(int p_idx,int p_enabled){ ob->set_item_disabled(p_idx,!p_enabled);}
- virtual void set_item_id(int p_idx,int p_id){ ob->set_item_ID(p_idx,p_id);}
-
-
- virtual String get_item_text(int p_idx) const{ return ob->get_item_text(p_idx); };
- virtual Ref<Texture> get_item_icon(int p_idx) const{ return ob->get_item_icon(p_idx); };
- virtual bool is_item_enabled(int p_idx) const{ return !ob->is_item_disabled(p_idx); };
- virtual int get_item_id(int p_idx) const{ return ob->get_item_ID(p_idx); };
-
- virtual void add_item() { ob->add_item( "New Item "+itos(ob->get_item_count())); _change_notify();}
- virtual int get_item_count() const { return ob->get_item_count(); }
- virtual void erase(int p_idx) { ob->remove_item(p_idx); _change_notify();}
-
-
- ItemListOptionButtonPlugin() { ob=NULL; }
-};
-
-class ItemListPopupMenuPlugin : public ItemListPlugin {
-
- OBJ_TYPE(ItemListPopupMenuPlugin,ItemListPlugin);
-
- PopupMenu *pp;
-public:
-
- virtual void set_object(Object *p_object) {
- if (p_object->cast_to<MenuButton>())
- pp = p_object->cast_to<MenuButton>()->get_popup();
- else
- pp = p_object->cast_to<PopupMenu>();
- }
-
- virtual bool handles(Object *p_object) const { return p_object->cast_to<PopupMenu>()!=NULL || p_object->cast_to<MenuButton>()!=NULL; }
-
- virtual int get_flags() const { return FLAG_ICON|FLAG_ID|FLAG_ENABLE|FLAG_CHECKABLE|FLAG_SEPARATOR|FLAG_ACCEL; }
-
- virtual void set_item_text(int p_idx,const String& p_text){ pp->set_item_text(p_idx,p_text); }
- virtual void set_item_icon(int p_idx,const Ref<Texture>& p_tex){ pp->set_item_icon(p_idx,p_tex);}
- virtual void set_item_checkable(int p_idx,bool p_check){ pp->set_item_as_checkable(p_idx,p_check);}
- virtual void set_item_checked(int p_idx,bool p_checked){ pp->set_item_checked(p_idx,p_checked);}
- virtual void set_item_accel(int p_idx,int p_accel){ pp->set_item_accelerator(p_idx,p_accel);}
- virtual void set_item_enabled(int p_idx,int p_enabled){ pp->set_item_disabled(p_idx,!p_enabled);}
- virtual void set_item_id(int p_idx,int p_id){ pp->set_item_ID(p_idx,p_idx);}
- virtual void set_item_separator(int p_idx,bool p_separator){ pp->set_item_as_separator(p_idx,p_separator);}
-
-
- virtual String get_item_text(int p_idx) const{ return pp->get_item_text(p_idx); };
- virtual Ref<Texture> get_item_icon(int p_idx) const{ return pp->get_item_icon(p_idx); };
- virtual bool is_item_checkable(int p_idx) const{ return pp->is_item_checkable(p_idx); };
- virtual bool is_item_checked(int p_idx) const{ return pp->is_item_checked(p_idx); };
- virtual int get_item_accel(int p_idx) const{ return pp->get_item_accelerator(p_idx); };
- virtual bool is_item_enabled(int p_idx) const{ return !pp->is_item_disabled(p_idx); };
- virtual int get_item_id(int p_idx) const{ return pp->get_item_ID(p_idx); };
- virtual bool is_item_separator(int p_idx) const{ return pp->is_item_separator(p_idx); };
-
-
-
- virtual void add_item() { pp->add_item( "New Item "+itos(pp->get_item_count())); _change_notify();}
- virtual int get_item_count() const { return pp->get_item_count(); }
- virtual void erase(int p_idx) { pp->remove_item(p_idx); _change_notify();}
-
-
- ItemListPopupMenuPlugin() { pp=NULL; }
-};
-
-
-
-
-
-
ItemListEditorPlugin::ItemListEditorPlugin(EditorNode *p_node) {
editor=p_node;
item_list_editor = memnew( ItemListEditor );
- editor->get_viewport()->add_child(item_list_editor);
-
-// item_list_editor->set_anchor(MARGIN_LEFT,Control::ANCHOR_END);
-// item_list_editor->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
- item_list_editor->set_margin(MARGIN_LEFT,180);
- item_list_editor->set_margin(MARGIN_RIGHT,230);
- item_list_editor->set_margin(MARGIN_TOP,0);
- item_list_editor->set_margin(MARGIN_BOTTOM,10);
-
+ CanvasItemEditor::get_singleton()->add_control_to_menu_panel(item_list_editor);
item_list_editor->hide();
- item_list_editor->add_plugin( memnew( ItemListOptionButtonPlugin) );
- item_list_editor->add_plugin( memnew( ItemListPopupMenuPlugin) );
+ item_list_editor->add_plugin( memnew( ItemListOptionButtonPlugin ) );
+ item_list_editor->add_plugin( memnew( ItemListPopupMenuPlugin ) );
}
-
ItemListEditorPlugin::~ItemListEditorPlugin()
{
}
diff --git a/tools/editor/plugins/item_list_editor_plugin.h b/tools/editor/plugins/item_list_editor_plugin.h
index 351dbb800d..b40a2c22f8 100644
--- a/tools/editor/plugins/item_list_editor_plugin.h
+++ b/tools/editor/plugins/item_list_editor_plugin.h
@@ -31,10 +31,11 @@
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
+#include "canvas_item_editor_plugin.h"
+
#include "scene/gui/option_button.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/popup_menu.h"
-#include "scene/gui/spin_box.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -51,43 +52,42 @@ protected:
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
public:
enum Flags {
FLAG_ICON=1,
FLAG_CHECKABLE=2,
- FLAG_ACCEL=4,
- FLAG_ID=8,
- FLAG_ENABLE=16,
- FLAG_SEPARATOR=32
+ FLAG_ID=4,
+ FLAG_ENABLE=8,
+ FLAG_SEPARATOR=16
};
virtual void set_object(Object *p_object)=0;
-
virtual bool handles(Object *p_object) const=0;
virtual int get_flags() const=0;
- virtual void set_item_text(int p_idx,const String& p_text){}
- virtual void set_item_icon(int p_idx,const Ref<Texture>& p_tex){}
- virtual void set_item_checkable(int p_idx,bool p_check){}
- virtual void set_item_checked(int p_idx,bool p_checked){}
- virtual void set_item_accel(int p_idx,int p_accel){}
- virtual void set_item_enabled(int p_idx,int p_enabled){}
- virtual void set_item_id(int p_idx,int p_id){}
- virtual void set_item_separator(int p_idx,bool p_separator){}
-
-
+ virtual void set_item_text(int p_idx, const String& p_text) {}
virtual String get_item_text(int p_idx) const{ return ""; };
+
+ virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) {}
virtual Ref<Texture> get_item_icon(int p_idx) const{ return Ref<Texture>(); };
+
+ virtual void set_item_checkable(int p_idx, bool p_check) {}
virtual bool is_item_checkable(int p_idx) const{ return false; };
+
+ virtual void set_item_checked(int p_idx, bool p_checked) {}
virtual bool is_item_checked(int p_idx) const{ return false; };
- virtual int get_item_accel(int p_idx) const{ return 0; };
+
+ virtual void set_item_enabled(int p_idx, int p_enabled) {}
virtual bool is_item_enabled(int p_idx) const{ return false; };
+
+ virtual void set_item_id(int p_idx, int p_id) {}
virtual int get_item_id(int p_idx) const{ return -1; };
- virtual bool is_item_separator(int p_idx) const{ return false; };
+
+ virtual void set_item_separator(int p_idx, bool p_separator) {}
+ virtual bool is_item_separator(int p_idx) const { return false; };
virtual void add_item()=0;
virtual int get_item_count() const=0;
@@ -96,41 +96,107 @@ public:
ItemListPlugin() {}
};
-class ItemListEditor : public Control {
+///////////////////////////////////////////////////////////////
- OBJ_TYPE(ItemListEditor, Control );
+class ItemListOptionButtonPlugin : public ItemListPlugin {
- Node *item_list;
+ OBJ_TYPE(ItemListOptionButtonPlugin,ItemListPlugin);
- enum {
+ OptionButton *ob;
+public:
- MENU_EDIT_ITEMS,
- MENU_CLEAR
- };
+ virtual void set_object(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual int get_flags() const;
- AcceptDialog *dialog;
+ virtual void set_item_text(int p_idx, const String& p_text) { ob->set_item_text(p_idx,p_text); }
+ virtual String get_item_text(int p_idx) const { return ob->get_item_text(p_idx); }
- PropertyEditor *prop_editor;
+ virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { ob->set_item_icon(p_idx, p_tex); }
+ virtual Ref<Texture> get_item_icon(int p_idx) const { return ob->get_item_icon(p_idx); }
- MenuButton * options;
- int selected_idx;
+ virtual void set_item_enabled(int p_idx, int p_enabled) { ob->set_item_disabled(p_idx, !p_enabled); }
+ virtual bool is_item_enabled(int p_idx) const { return !ob->is_item_disabled(p_idx); }
+
+ virtual void set_item_id(int p_idx, int p_id) { ob->set_item_ID(p_idx,p_id); }
+ virtual int get_item_id(int p_idx) const { return ob->get_item_ID(p_idx); }
+
+ virtual void add_item();
+ virtual int get_item_count() const;
+ virtual void erase(int p_idx);
+
+ ItemListOptionButtonPlugin();
+};
+
+class ItemListPopupMenuPlugin : public ItemListPlugin {
+
+ OBJ_TYPE(ItemListPopupMenuPlugin,ItemListPlugin);
+
+ PopupMenu *pp;
+public:
+
+ virtual void set_object(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual int get_flags() const;
+ virtual void set_item_text(int p_idx, const String& p_text) { pp->set_item_text(p_idx,p_text); }
+ virtual String get_item_text(int p_idx) const { return pp->get_item_text(p_idx); }
+
+ virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { pp->set_item_icon(p_idx,p_tex); }
+ virtual Ref<Texture> get_item_icon(int p_idx) const { return pp->get_item_icon(p_idx); }
+
+ virtual void set_item_checkable(int p_idx, bool p_check) { pp->set_item_as_checkable(p_idx,p_check); }
+ virtual bool is_item_checkable(int p_idx) const { return pp->is_item_checkable(p_idx); }
+
+ virtual void set_item_checked(int p_idx, bool p_checked) { pp->set_item_checked(p_idx,p_checked); }
+ virtual bool is_item_checked(int p_idx) const { return pp->is_item_checked(p_idx); }
+
+ virtual void set_item_enabled(int p_idx, int p_enabled) { pp->set_item_disabled(p_idx,!p_enabled); }
+ virtual bool is_item_enabled(int p_idx) const { return !pp->is_item_disabled(p_idx); }
+
+ virtual void set_item_id(int p_idx, int p_id) { pp->set_item_ID(p_idx,p_idx); }
+ virtual int get_item_id(int p_idx) const { return pp->get_item_ID(p_idx); }
+
+ virtual void set_item_separator(int p_idx, bool p_separator) { pp->set_item_as_separator(p_idx,p_separator); }
+ virtual bool is_item_separator(int p_idx) const { return pp->is_item_separator(p_idx); }
+
+ virtual void add_item();
+ virtual int get_item_count() const;
+ virtual void erase(int p_idx);
+
+ ItemListPopupMenuPlugin();
+};
+
+///////////////////////////////////////////////////////////////
+
+class ItemListEditor : public HBoxContainer {
+
+ OBJ_TYPE(ItemListEditor,HBoxContainer);
+
+ Node *item_list;
+
+ ToolButton *toolbar_button;
+
+ AcceptDialog *dialog;
+ PropertyEditor *property_editor;
+ Tree *tree;
Button *add_button;
Button *del_button;
-
-// FileDialog *emission_file_dialog;
- void _menu_option(int);
+ int selected_idx;
Vector<ItemListPlugin*> item_plugins;
- void _node_removed(Node *p_node);
+ void _edit_items();
+
void _add_pressed();
void _delete_pressed();
+
+ void _node_removed(Node *p_node);
+
protected:
void _notification(int p_notification);
-
static void _bind_methods();
public:
@@ -143,7 +209,7 @@ public:
class ItemListEditorPlugin : public EditorPlugin {
- OBJ_TYPE( ItemListEditorPlugin, EditorPlugin );
+ OBJ_TYPE(ItemListEditorPlugin,EditorPlugin);
ItemListEditor *item_list_editor;
EditorNode *editor;
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 956e7a98a2..4e394f9e3f 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -1137,12 +1137,14 @@ void ScriptEditor::_menu_option(int p_option) {
return;
int line = tx->cursor_get_line();
int next_line = line + 1;
+ int column = tx->cursor_get_column();
- if (line == tx->get_line_count() - 1 || next_line >= tx->get_line_count())
+ if (line >= tx->get_line_count() - 1)
tx->set_line(line, tx->get_line(line) + "\n");
String line_clone = tx->get_line(line);
tx->insert_at(line_clone, next_line);
+ tx->cursor_set_column(column);
tx->update();
} break;
diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp
index 2fd8b37753..a2419895eb 100644
--- a/tools/editor/project_settings.cpp
+++ b/tools/editor/project_settings.cpp
@@ -722,6 +722,10 @@ void ProjectSettings::_translation_file_open() {
void ProjectSettings::_autoload_file_callback(const String& p_path) {
autoload_add_path->set_text(p_path);
+ if (autoload_add_name->get_text().strip_edges()==String()) {
+
+ autoload_add_name->set_text( p_path.get_file().basename() );
+ }
//_translation_add(p_translation);
}
@@ -769,6 +773,9 @@ void ProjectSettings::_autoload_add() {
undo_redo->add_undo_method(this,"_settings_changed");
undo_redo->commit_action();
+ autoload_add_path->set_text("");
+ autoload_add_name->set_text("");
+
//autoload_file_open->popup_centered_ratio();
}
@@ -1589,11 +1596,6 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
HBoxContainer *ahb = memnew( HBoxContainer);
avb->add_child(ahb);
- VBoxContainer *avb_name = memnew( VBoxContainer );
- avb_name->set_h_size_flags(SIZE_EXPAND_FILL);
- autoload_add_name = memnew(LineEdit);
- avb_name->add_margin_child("Node Name:",autoload_add_name);
- ahb->add_child(avb_name);
VBoxContainer *avb_path = memnew( VBoxContainer );
avb_path->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1604,13 +1606,24 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
Button *browseaa = memnew( Button("..") );
ahb_path->add_child(browseaa);
browseaa->connect("pressed",this,"_autoload_file_open");
- Button *addaa = memnew( Button("Add") );
- ahb_path->add_child(addaa);
- addaa->connect("pressed",this,"_autoload_add");
avb_path->add_margin_child("Path:",ahb_path);
ahb->add_child(avb_path);
+ VBoxContainer *avb_name = memnew( VBoxContainer );
+ avb_name->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ HBoxContainer *ahb_name = memnew( HBoxContainer );
+ autoload_add_name = memnew(LineEdit);
+ autoload_add_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ ahb_name->add_child(autoload_add_name);
+ avb_name->add_margin_child("Node Name:",ahb_name);
+ Button *addaa = memnew( Button("Add") );
+ ahb_name->add_child(addaa);
+ addaa->connect("pressed",this,"_autoload_add");
+
+ ahb->add_child(avb_name);
+
autoload_list = memnew( Tree );
autoload_list->set_v_size_flags(SIZE_EXPAND_FILL);
avb->add_margin_child("List:",autoload_list,true);
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 0fe3dee2ea..7ab09f0487 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -2207,9 +2207,9 @@ TreeItem *PropertyEditor::get_parent_node(String p_path,HashMap<String,TreeItem*
}
item->set_editable(0,false);
- item->set_selectable(0,false);
+ item->set_selectable(0,subsection_selectable);
item->set_editable(1,false);
- item->set_selectable(1,false);
+ item->set_selectable(1,subsection_selectable);
if (item->get_parent()==root) {
@@ -3511,7 +3511,15 @@ void PropertyEditor::register_text_enter(Node* p_line_edit) {
if (search_box)
search_box->connect("text_changed",this,"_filter_changed");
+}
+void PropertyEditor::set_subsection_selectable(bool p_selectable) {
+
+ if (p_selectable==subsection_selectable)
+ return;
+
+ subsection_selectable=p_selectable;
+ update_tree();
}
PropertyEditor::PropertyEditor() {
@@ -3573,8 +3581,8 @@ PropertyEditor::PropertyEditor() {
show_categories=false;
refresh_countdown=0;
use_doc_hints=false;
-
use_filter=false;
+ subsection_selectable=false;
}
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index 5fb8386b1b..f004616c08 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -163,8 +163,8 @@ class PropertyEditor : public Control {
bool show_categories;
float refresh_countdown;
bool use_doc_hints;
-
bool use_filter;
+ bool subsection_selectable;
HashMap<String,String> pending;
String selected_property;
@@ -239,6 +239,8 @@ public:
void set_use_filter(bool p_use);
void register_text_enter(Node *p_line_edit);
+ void set_subsection_selectable(bool p_selectable);
+
PropertyEditor();
~PropertyEditor();