summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/2d/area_input/engine.cfg1
-rw-r--r--demos/2d/area_input/icon.pngbin0 -> 1684 bytes
-rw-r--r--demos/2d/dynamic_collision_shapes/engine.cfg1
-rw-r--r--demos/2d/dynamic_collision_shapes/icon.pngbin0 -> 844 bytes
-rw-r--r--demos/2d/fog_of_war/engine.cfg2
-rw-r--r--demos/2d/hdr/engine.cfg1
-rw-r--r--demos/2d/hdr/icon.pngbin0 -> 2670 bytes
-rw-r--r--demos/2d/isometric_light/engine.cfg1
-rw-r--r--demos/2d/isometric_light/icon.pngbin0 -> 3638 bytes
-rw-r--r--demos/2d/light_mask/engine.cfg1
-rw-r--r--demos/2d/light_mask/icon.pngbin0 -> 3344 bytes
-rw-r--r--demos/2d/lights_shadows/engine.cfg1
-rw-r--r--demos/2d/lights_shadows/icon.pngbin0 -> 2733 bytes
-rw-r--r--demos/2d/navpoly/engine.cfg1
-rw-r--r--demos/2d/navpoly/icon.pngbin0 -> 2420 bytes
-rw-r--r--demos/2d/normalmaps/engine.cfg1
-rw-r--r--demos/2d/normalmaps/icon.pngbin0 -> 4876 bytes
-rw-r--r--demos/2d/polygon_path_finder_demo/engine.cfg2
-rw-r--r--demos/2d/screen_space_shaders/engine.cfg1
-rw-r--r--demos/2d/screen_space_shaders/icon.pngbin0 -> 3341 bytes
-rw-r--r--demos/2d/sdf_font/engine.cfg1
-rw-r--r--demos/2d/sdf_font/icon.pngbin0 -> 1534 bytes
-rw-r--r--demos/2d/splash/engine.cfg1
-rw-r--r--demos/2d/splash/icon.pngbin0 -> 3408 bytes
-rw-r--r--demos/2d/sprite_shaders/engine.cfg1
-rw-r--r--demos/2d/sprite_shaders/icon.pngbin0 -> 3934 bytes
-rw-r--r--demos/3d/navmesh/icon.pngbin0 -> 2803 bytes
-rw-r--r--demos/3d/sat_test/engine.cfg1
-rw-r--r--demos/3d/sat_test/icon.pngbin0 -> 2699 bytes
-rw-r--r--demos/gui/input_mapping/engine.cfg1
-rw-r--r--demos/gui/rich_text_bbcode/engine.cfg1
-rw-r--r--demos/gui/rich_text_bbcode/icon.pngbin0 -> 2293 bytes
-rw-r--r--demos/misc/instancing/engine.cfg1
-rw-r--r--demos/misc/instancing/icon.pngbin0 -> 2185 bytes
-rw-r--r--demos/misc/regex/regex.gd18
-rw-r--r--demos/misc/regex/regex.scnbin1772 -> 1793 bytes
-rw-r--r--demos/misc/tween/engine.cfg2
-rw-r--r--demos/misc/window_management/engine.cfg2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp17
-rw-r--r--drivers/gles2/rasterizer_gles2.h2
-rw-r--r--drivers/nrex/README.md57
-rw-r--r--drivers/nrex/nrex.cpp790
-rw-r--r--drivers/nrex/nrex.hpp10
-rw-r--r--drivers/nrex/regex.cpp10
-rw-r--r--drivers/nrex/regex.h2
-rw-r--r--modules/gdscript/gd_parser.h1
-rw-r--r--scene/2d/tile_map.cpp5
-rw-r--r--scene/gui/button_group.cpp2
-rw-r--r--scene/gui/button_group.h6
-rw-r--r--scene/gui/tabs.cpp2
-rw-r--r--scene/gui/texture_progress.cpp7
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/material.cpp6
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/rasterizer_dummy.h4
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp60
-rw-r--r--tools/editor/plugins/mesh_editor_plugin.cpp15
-rw-r--r--tools/editor/plugins/multimesh_editor_plugin.cpp20
-rw-r--r--tools/editor/plugins/multimesh_editor_plugin.h8
-rw-r--r--tools/editor/plugins/shader_graph_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp42
-rw-r--r--tools/editor/plugins/theme_editor_plugin.cpp38
-rw-r--r--tools/editor/project_manager.cpp33
64 files changed, 849 insertions, 339 deletions
diff --git a/demos/2d/area_input/engine.cfg b/demos/2d/area_input/engine.cfg
index 3227e9278f..8fa2e15beb 100644
--- a/demos/2d/area_input/engine.cfg
+++ b/demos/2d/area_input/engine.cfg
@@ -2,3 +2,4 @@
name="Area 2D Input Events"
main_scene="res://input.scn"
+icon="res://icon.png"
diff --git a/demos/2d/area_input/icon.png b/demos/2d/area_input/icon.png
new file mode 100644
index 0000000000..d9bb881693
--- /dev/null
+++ b/demos/2d/area_input/icon.png
Binary files differ
diff --git a/demos/2d/dynamic_collision_shapes/engine.cfg b/demos/2d/dynamic_collision_shapes/engine.cfg
index 536b75f2f2..76a074f346 100644
--- a/demos/2d/dynamic_collision_shapes/engine.cfg
+++ b/demos/2d/dynamic_collision_shapes/engine.cfg
@@ -2,3 +2,4 @@
name="Run-Time CollisionShape"
main_scene="res://dynamic_colobjs.scn"
+icon="res://icon.png"
diff --git a/demos/2d/dynamic_collision_shapes/icon.png b/demos/2d/dynamic_collision_shapes/icon.png
new file mode 100644
index 0000000000..ac01d401ba
--- /dev/null
+++ b/demos/2d/dynamic_collision_shapes/icon.png
Binary files differ
diff --git a/demos/2d/fog_of_war/engine.cfg b/demos/2d/fog_of_war/engine.cfg
index 5c4307b5bc..1f56851c58 100644
--- a/demos/2d/fog_of_war/engine.cfg
+++ b/demos/2d/fog_of_war/engine.cfg
@@ -2,7 +2,7 @@
name="Fog of War"
main_scene="res://fog.scn"
-icon="icon.png"
+icon="res://icon.png"
[input]
diff --git a/demos/2d/hdr/engine.cfg b/demos/2d/hdr/engine.cfg
index 3d8b4222d5..ab53a022f0 100644
--- a/demos/2d/hdr/engine.cfg
+++ b/demos/2d/hdr/engine.cfg
@@ -2,6 +2,7 @@
name="HDR for 2D"
main_scene="res://beach_cave.scn"
+icon="res://icon.png"
[display]
diff --git a/demos/2d/hdr/icon.png b/demos/2d/hdr/icon.png
new file mode 100644
index 0000000000..2df0ec38e9
--- /dev/null
+++ b/demos/2d/hdr/icon.png
Binary files differ
diff --git a/demos/2d/isometric_light/engine.cfg b/demos/2d/isometric_light/engine.cfg
index 08393f1724..a5b053aa95 100644
--- a/demos/2d/isometric_light/engine.cfg
+++ b/demos/2d/isometric_light/engine.cfg
@@ -2,6 +2,7 @@
name="Isometric 2D + Lighting"
main_scene="res://map.scn"
+icon="res://icon.png"
[input]
diff --git a/demos/2d/isometric_light/icon.png b/demos/2d/isometric_light/icon.png
new file mode 100644
index 0000000000..3de9749729
--- /dev/null
+++ b/demos/2d/isometric_light/icon.png
Binary files differ
diff --git a/demos/2d/light_mask/engine.cfg b/demos/2d/light_mask/engine.cfg
index 8b0ae6f61d..39608669ab 100644
--- a/demos/2d/light_mask/engine.cfg
+++ b/demos/2d/light_mask/engine.cfg
@@ -2,6 +2,7 @@
name="Using Lights As Mask"
main_scene="res://lightmask.scn"
+icon="res://icon.png"
[rasterizer]
diff --git a/demos/2d/light_mask/icon.png b/demos/2d/light_mask/icon.png
new file mode 100644
index 0000000000..c12b045e62
--- /dev/null
+++ b/demos/2d/light_mask/icon.png
Binary files differ
diff --git a/demos/2d/lights_shadows/engine.cfg b/demos/2d/lights_shadows/engine.cfg
index 771288c209..80142633d3 100644
--- a/demos/2d/lights_shadows/engine.cfg
+++ b/demos/2d/lights_shadows/engine.cfg
@@ -2,6 +2,7 @@
name="2D Lighting"
main_scene="res://light_shadows.scn"
+icon="res://icon.png"
[display]
diff --git a/demos/2d/lights_shadows/icon.png b/demos/2d/lights_shadows/icon.png
new file mode 100644
index 0000000000..c7f9e13bae
--- /dev/null
+++ b/demos/2d/lights_shadows/icon.png
Binary files differ
diff --git a/demos/2d/navpoly/engine.cfg b/demos/2d/navpoly/engine.cfg
index 40515dd3d2..b750419915 100644
--- a/demos/2d/navpoly/engine.cfg
+++ b/demos/2d/navpoly/engine.cfg
@@ -2,6 +2,7 @@
name="Navigation Polygon (2D)"
main_scene="res://navigation.scn"
+icon="res://icon.png"
[display]
diff --git a/demos/2d/navpoly/icon.png b/demos/2d/navpoly/icon.png
new file mode 100644
index 0000000000..df7fb43633
--- /dev/null
+++ b/demos/2d/navpoly/icon.png
Binary files differ
diff --git a/demos/2d/normalmaps/engine.cfg b/demos/2d/normalmaps/engine.cfg
index f0002dc2b8..4f9f4f67f0 100644
--- a/demos/2d/normalmaps/engine.cfg
+++ b/demos/2d/normalmaps/engine.cfg
@@ -2,6 +2,7 @@
name="2D Normal Mapping"
main_scene="res://normalmap.scn"
+icon="res://icon.png"
[display]
diff --git a/demos/2d/normalmaps/icon.png b/demos/2d/normalmaps/icon.png
new file mode 100644
index 0000000000..4e5d835005
--- /dev/null
+++ b/demos/2d/normalmaps/icon.png
Binary files differ
diff --git a/demos/2d/polygon_path_finder_demo/engine.cfg b/demos/2d/polygon_path_finder_demo/engine.cfg
index 41c4adf701..de5593c417 100644
--- a/demos/2d/polygon_path_finder_demo/engine.cfg
+++ b/demos/2d/polygon_path_finder_demo/engine.cfg
@@ -2,4 +2,4 @@
name="polygon_path_finder_demo"
main_scene="res://new_scene_poly_with_holes.scn"
-icon="icon.png"
+icon="res://icon.png"
diff --git a/demos/2d/screen_space_shaders/engine.cfg b/demos/2d/screen_space_shaders/engine.cfg
index 527e2f8f0a..383ca7bf11 100644
--- a/demos/2d/screen_space_shaders/engine.cfg
+++ b/demos/2d/screen_space_shaders/engine.cfg
@@ -2,6 +2,7 @@
name="Screen-Space Shaders"
main_scene="res://screen_shaders.scn"
+icon="res://icon.png"
[display]
diff --git a/demos/2d/screen_space_shaders/icon.png b/demos/2d/screen_space_shaders/icon.png
new file mode 100644
index 0000000000..65247f9ae7
--- /dev/null
+++ b/demos/2d/screen_space_shaders/icon.png
Binary files differ
diff --git a/demos/2d/sdf_font/engine.cfg b/demos/2d/sdf_font/engine.cfg
index bdf26ce741..bf983041fa 100644
--- a/demos/2d/sdf_font/engine.cfg
+++ b/demos/2d/sdf_font/engine.cfg
@@ -2,3 +2,4 @@
name="Signed Distance Field Font"
main_scene="res://sdf.scn"
+icon="res://icon.png"
diff --git a/demos/2d/sdf_font/icon.png b/demos/2d/sdf_font/icon.png
new file mode 100644
index 0000000000..be9fefa8b0
--- /dev/null
+++ b/demos/2d/sdf_font/icon.png
Binary files differ
diff --git a/demos/2d/splash/engine.cfg b/demos/2d/splash/engine.cfg
index cb50c7b1be..e461426305 100644
--- a/demos/2d/splash/engine.cfg
+++ b/demos/2d/splash/engine.cfg
@@ -2,6 +2,7 @@
name="Splash Screen"
main_scene="res://splash.xml"
+icon="res://icon.png"
[display]
diff --git a/demos/2d/splash/icon.png b/demos/2d/splash/icon.png
new file mode 100644
index 0000000000..88620eb35b
--- /dev/null
+++ b/demos/2d/splash/icon.png
Binary files differ
diff --git a/demos/2d/sprite_shaders/engine.cfg b/demos/2d/sprite_shaders/engine.cfg
index 09f9a59566..17bdada188 100644
--- a/demos/2d/sprite_shaders/engine.cfg
+++ b/demos/2d/sprite_shaders/engine.cfg
@@ -2,3 +2,4 @@
name="2D Shaders for Sprites"
main_scene="res://sprite_shaders.scn"
+icon="res://icon.png"
diff --git a/demos/2d/sprite_shaders/icon.png b/demos/2d/sprite_shaders/icon.png
new file mode 100644
index 0000000000..b044b31f93
--- /dev/null
+++ b/demos/2d/sprite_shaders/icon.png
Binary files differ
diff --git a/demos/3d/navmesh/icon.png b/demos/3d/navmesh/icon.png
new file mode 100644
index 0000000000..5b354f931c
--- /dev/null
+++ b/demos/3d/navmesh/icon.png
Binary files differ
diff --git a/demos/3d/sat_test/engine.cfg b/demos/3d/sat_test/engine.cfg
index cc215c83e8..82c688635d 100644
--- a/demos/3d/sat_test/engine.cfg
+++ b/demos/3d/sat_test/engine.cfg
@@ -2,3 +2,4 @@
name="SAT Collision Test"
main_scene="res://sat_test.xml"
+icon="res://icon.png"
diff --git a/demos/3d/sat_test/icon.png b/demos/3d/sat_test/icon.png
new file mode 100644
index 0000000000..b89c5a7467
--- /dev/null
+++ b/demos/3d/sat_test/icon.png
Binary files differ
diff --git a/demos/gui/input_mapping/engine.cfg b/demos/gui/input_mapping/engine.cfg
index 959c0ac7d5..6470ec6cd8 100644
--- a/demos/gui/input_mapping/engine.cfg
+++ b/demos/gui/input_mapping/engine.cfg
@@ -2,7 +2,6 @@
name="Input Mapping GUI"
main_scene="res://controls.scn"
-icon="icon.png"
[display]
diff --git a/demos/gui/rich_text_bbcode/engine.cfg b/demos/gui/rich_text_bbcode/engine.cfg
index e0ea296f6d..5f68b6a0e6 100644
--- a/demos/gui/rich_text_bbcode/engine.cfg
+++ b/demos/gui/rich_text_bbcode/engine.cfg
@@ -2,3 +2,4 @@
name="Rich Text Label (BBCode)"
main_scene="res://rich_text_bbcode.scn"
+icon="res://icon.png"
diff --git a/demos/gui/rich_text_bbcode/icon.png b/demos/gui/rich_text_bbcode/icon.png
new file mode 100644
index 0000000000..78358ba71b
--- /dev/null
+++ b/demos/gui/rich_text_bbcode/icon.png
Binary files differ
diff --git a/demos/misc/instancing/engine.cfg b/demos/misc/instancing/engine.cfg
index 52a28a3fce..76b0c97721 100644
--- a/demos/misc/instancing/engine.cfg
+++ b/demos/misc/instancing/engine.cfg
@@ -2,6 +2,7 @@
name="Scene Instancing Demo"
main_scene="res://container.scn"
+icon="res://icon.png"
[physics_2d]
diff --git a/demos/misc/instancing/icon.png b/demos/misc/instancing/icon.png
new file mode 100644
index 0000000000..7a6de677c5
--- /dev/null
+++ b/demos/misc/instancing/icon.png
Binary files differ
diff --git a/demos/misc/regex/regex.gd b/demos/misc/regex/regex.gd
index e648c18093..409b4cab05 100644
--- a/demos/misc/regex/regex.gd
+++ b/demos/misc/regex/regex.gd
@@ -2,21 +2,23 @@ extends VBoxContainer
var regex = RegEx.new()
-func update_expression():
- regex.compile(get_node("Expression").get_text())
+func update_expression(text):
+ regex.compile(text)
update_text()
func update_text():
var text = get_node("Text").get_text()
- regex.find(text)
var list = get_node("List")
for child in list.get_children():
child.queue_free()
- for res in regex.get_captures():
- var label = Label.new()
- label.set_text(res)
- list.add_child(label)
+ if regex.is_valid():
+ regex.find(text)
+ for res in regex.get_captures():
+ var label = Label.new()
+ label.set_text(res)
+ list.add_child(label)
func _ready():
get_node("Text").set_text("They asked me \"What's going on \\\"in the manor\\\"?\"")
- update_expression()
+ update_expression(get_node("Expression").get_text())
+
diff --git a/demos/misc/regex/regex.scn b/demos/misc/regex/regex.scn
index 2b62d6b82a..1f46521d0d 100644
--- a/demos/misc/regex/regex.scn
+++ b/demos/misc/regex/regex.scn
Binary files differ
diff --git a/demos/misc/tween/engine.cfg b/demos/misc/tween/engine.cfg
index f97e540dbd..3d3d639964 100644
--- a/demos/misc/tween/engine.cfg
+++ b/demos/misc/tween/engine.cfg
@@ -2,7 +2,7 @@
name="Tween Demo"
main_scene="res://main.xml"
-icon="icon.png"
+icon="res://icon.png"
target_fps=60
[display]
diff --git a/demos/misc/window_management/engine.cfg b/demos/misc/window_management/engine.cfg
index 0a34231673..911d3fd4a1 100644
--- a/demos/misc/window_management/engine.cfg
+++ b/demos/misc/window_management/engine.cfg
@@ -2,7 +2,7 @@
name="Window Management"
main_scene="res://window_management.scn"
-icon="icon.png"
+icon="res://icon.png"
[display]
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index d84ee5a758..9bcce156cd 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -4075,6 +4075,8 @@ void RasterizerGLES2::render_target_set_size(RID p_render_target,int p_width,int
glDeleteTextures(1,&rt->color);
rt->fbo=0;
+ rt->depth=0;
+ rt->color=0;
rt->width=0;
rt->height=0;
rt->texture_ptr->tex_id=0;
@@ -4094,12 +4096,14 @@ void RasterizerGLES2::render_target_set_size(RID p_render_target,int p_width,int
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
//depth
- glGenRenderbuffers(1, &rt->depth);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
+ if (!low_memory_2d) {
+ glGenRenderbuffers(1, &rt->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
- glRenderbufferStorage(GL_RENDERBUFFER, use_depth24?_DEPTH_COMPONENT24_OES:GL_DEPTH_COMPONENT16, rt->width,rt->height);
+ glRenderbufferStorage(GL_RENDERBUFFER, use_depth24?_DEPTH_COMPONENT24_OES:GL_DEPTH_COMPONENT16, rt->width,rt->height);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+ }
//color
glGenTextures(1, &rt->color);
@@ -10293,7 +10297,11 @@ void RasterizerGLES2::_update_framebuffer() {
framebuffer.fbo=0;
}
+#ifdef TOOLS_ENABLED
framebuffer.active=use_fbo;
+#else
+ framebuffer.active=use_fbo && !low_memory_2d;
+#endif
framebuffer.width=dwidth;
framebuffer.height=dheight;
framebuffer.scale=scale;
@@ -11203,6 +11211,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo
use_fp16_fb=bool(GLOBAL_DEF("rasterizer/fp16_framebuffer",true));
use_shadow_mapping=true;
use_fast_texture_filter=!bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true));
+ low_memory_2d=bool(GLOBAL_DEF("rasterizer/low_memory_2d_mode",false));
skel_default.resize(1024*4);
for(int i=0;i<1024/3;i++) {
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 4b512cc3a9..d6d9593da8 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -105,7 +105,7 @@ class RasterizerGLES2 : public Rasterizer {
float anisotropic_level;
bool use_half_float;
-
+ bool low_memory_2d;
Vector<float> skel_default;
diff --git a/drivers/nrex/README.md b/drivers/nrex/README.md
index f150a5d76f..951b301c1e 100644
--- a/drivers/nrex/README.md
+++ b/drivers/nrex/README.md
@@ -18,47 +18,42 @@ More details about its use is documented in `nrex.hpp`
Currently supported features:
* Capturing `()` and non-capturing `(?:)` groups
- * Any character `.`
+ * Any character `.` (includes newlines)
* Shorthand caracter classes `\w\W\s\S\d\D`
- * User-defined character classes such as `[A-Za-z]`
+ * POSIX character classes such as `[[:alnum:]]`
+ * Bracket expressions such as `[A-Za-z]`
* Simple quantifiers `?`, `*` and `+`
* Range quantifiers `{0,1}`
* Lazy (non-greedy) quantifiers `*?`
* Begining `^` and end `$` anchors
+ * Word boundaries `\b`
* Alternation `|`
- * Backreferences `\1` to `\99`
-
-To do list:
+ * ASCII `\xFF` code points
* 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`)
## License
Copyright (c) 2015, Zher Huei Lee
All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would
+ be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
diff --git a/drivers/nrex/nrex.cpp b/drivers/nrex/nrex.cpp
index 696d46240e..104e07f887 100644
--- a/drivers/nrex/nrex.cpp
+++ b/drivers/nrex/nrex.cpp
@@ -29,11 +29,13 @@
#include <wctype.h>
#include <wchar.h>
#define NREX_ISALPHANUM iswalnum
+#define NREX_ISSPACE iswspace
#define NREX_STRLEN wcslen
#else
#include <ctype.h>
#include <string.h>
#define NREX_ISALPHANUM isalnum
+#define NREX_ISSPACE isspace
#define NREX_STRLEN strlen
#endif
@@ -116,34 +118,72 @@ class nrex_array
}
};
-static nrex_char nrex_unescape(nrex_char repr)
+static int nrex_parse_hex(nrex_char c)
{
- switch (repr)
+ if ('0' <= c && c <= '9')
+ {
+ return int(c - '0');
+ }
+ else if ('a' <= c && c <= 'f')
+ {
+ return int(c - 'a') + 10;
+ }
+ else if ('A' <= c && c <= 'F')
{
- case '^': return '^';
- case '$': return '$';
- case '(': return '(';
- case ')': return ')';
- case '\\': return '\\';
- case '.': return '.';
- case '+': return '+';
- case '*': return '*';
- case '?': return '?';
- case '-': return '-';
- case 'a': return '\a';
- case 'e': return '\e';
- case 'f': return '\f';
- case 'n': return '\n';
- case 'r': return '\r';
- case 't': return '\t';
- case 'v': return '\v';
+ return int(c - 'A') + 10;
}
- return 0;
+ return -1;
+}
+
+static nrex_char nrex_unescape(const nrex_char*& c)
+{
+ switch (c[1])
+ {
+ case '0': ++c; return '\0';
+ case 'a': ++c; return '\a';
+ case 'e': ++c; return '\e';
+ case 'f': ++c; return '\f';
+ case 'n': ++c; return '\n';
+ case 'r': ++c; return '\r';
+ case 't': ++c; return '\t';
+ case 'v': ++c; return '\v';
+ case 'b': ++c; return '\b';
+ case 'x':
+ {
+ int point = 0;
+ for (int i = 2; i <= 3; ++i)
+ {
+ int res = nrex_parse_hex(c[i]);
+ if (res == -1)
+ {
+ return '\0';
+ }
+ point = (point << 4) + res;
+ }
+ c = &c[3];
+ return nrex_char(point);
+ }
+ case 'u':
+ {
+ int point = 0;
+ for (int i = 2; i <= 5; ++i)
+ {
+ int res = nrex_parse_hex(c[i]);
+ if (res == -1)
+ {
+ return '\0';
+ }
+ point = (point << 4) + res;
+ }
+ c = &c[5];
+ return nrex_char(point);
+ }
+ }
+ return (++c)[0];
}
struct nrex_search
{
- public:
const nrex_char* str;
nrex_result* captures;
int end;
@@ -168,12 +208,14 @@ struct nrex_node
nrex_node* previous;
nrex_node* parent;
bool quantifiable;
+ int length;
nrex_node(bool quantify = false)
: next(NULL)
, previous(NULL)
, parent(NULL)
, quantifiable(quantify)
+ , length(-1)
{
}
@@ -206,21 +248,57 @@ struct nrex_node
}
return pos;
}
+
+ void increment_length(int amount, bool subtract = false)
+ {
+ if (amount >= 0 && length >= 0)
+ {
+ if (!subtract)
+ {
+ length += amount;
+ }
+ else
+ {
+ length -= amount;
+ }
+ }
+ else
+ {
+ length = -1;
+ }
+ if (parent)
+ {
+ parent->increment_length(amount, subtract);
+ }
+ }
};
struct nrex_node_group : public nrex_node
{
- int capturing;
+ static const int NonCapture = -1;
+ static const int Bracket = -2;
+ static const int LookAhead = -3;
+ static const int LookBehind = -4;
+
+ int mode;
bool negate;
nrex_array<nrex_node*> childset;
nrex_node* back;
- nrex_node_group(int capturing)
+ nrex_node_group(int mode)
: nrex_node(true)
- , capturing(capturing)
+ , mode(mode)
, negate(false)
, back(NULL)
{
+ if (mode != Bracket)
+ {
+ length = 0;
+ }
+ else
+ {
+ length = 1;
+ }
}
virtual ~nrex_node_group()
@@ -234,14 +312,19 @@ struct nrex_node_group : public nrex_node
int test(nrex_search* s, int pos) const
{
- if (capturing >= 0)
+ if (mode >= 0)
{
- s->captures[capturing].start = pos;
+ s->captures[mode].start = pos;
}
for (unsigned int i = 0; i < childset.size(); ++i)
{
s->complete = false;
- int res = childset[i]->test(s, pos);
+ int offset = 0;
+ if (mode == LookBehind)
+ {
+ offset = length;
+ }
+ int res = childset[i]->test(s, pos - offset);
if (s->complete)
{
return res;
@@ -256,12 +339,20 @@ struct nrex_node_group : public nrex_node
{
return -1;
}
+ if (i + 1 < childset.size())
+ {
+ continue;
+ }
}
if (res >= 0)
{
- if (capturing >= 0)
+ if (mode >= 0)
{
- s->captures[capturing].length = res - pos;
+ s->captures[mode].length = res - pos;
+ }
+ else if (mode == LookAhead || mode == LookBehind)
+ {
+ res = pos;
}
return next ? next->test(s, res) : res;
}
@@ -271,15 +362,19 @@ struct nrex_node_group : public nrex_node
virtual int test_parent(nrex_search* s, int pos) const
{
- if (capturing >= 0)
+ if (mode >= 0)
{
- s->captures[capturing].length = pos - s->captures[capturing].start;
+ s->captures[mode].length = pos - s->captures[mode].start;
}
return nrex_node::test_parent(s, pos);
}
void add_childset()
{
+ if (childset.size() > 0 && mode != Bracket)
+ {
+ length = -1;
+ }
back = NULL;
}
@@ -287,7 +382,7 @@ struct nrex_node_group : public nrex_node
{
node->parent = this;
node->previous = back;
- if (back)
+ if (back && mode != Bracket)
{
back->next = node;
}
@@ -295,6 +390,10 @@ struct nrex_node_group : public nrex_node
{
childset.push(node);
}
+ if (mode != Bracket)
+ {
+ increment_length(node->length);
+ }
back = node;
}
@@ -310,10 +409,32 @@ struct nrex_node_group : public nrex_node
{
childset.pop();
}
+ if (mode != Bracket)
+ {
+ increment_length(old->length, true);
+ }
back = old->previous;
add_child(node);
return old;
}
+
+ void pop_back()
+ {
+ if (back)
+ {
+ nrex_node* old = back;
+ if (!old->previous)
+ {
+ childset.pop();
+ }
+ if (mode != Bracket)
+ {
+ increment_length(old->length, true);
+ }
+ back = old->previous;
+ NREX_DELETE(old);
+ }
+ }
};
struct nrex_node_char : public nrex_node
@@ -324,6 +445,7 @@ struct nrex_node_char : public nrex_node
: nrex_node(true)
, ch(c)
{
+ length = 1;
}
int test(nrex_search* s, int pos) const
@@ -346,6 +468,7 @@ struct nrex_node_range : public nrex_node
, start(s)
, end(e)
{
+ length = 1;
}
int test(nrex_search* s, int pos) const
@@ -363,20 +486,219 @@ struct nrex_node_range : public nrex_node
}
};
-static bool nrex_is_whitespace(nrex_char repr)
+enum nrex_class_type
{
- switch (repr)
+ nrex_class_none,
+ nrex_class_alnum,
+ nrex_class_alpha,
+ nrex_class_blank,
+ nrex_class_cntrl,
+ nrex_class_digit,
+ nrex_class_graph,
+ nrex_class_lower,
+ nrex_class_print,
+ nrex_class_punct,
+ nrex_class_space,
+ nrex_class_upper,
+ nrex_class_xdigit,
+ nrex_class_word
+};
+
+static bool nrex_compare_class(const nrex_char** pos, const char* text)
+{
+ unsigned int i = 0;
+ for (i = 0; text[i] != '\0'; ++i)
{
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- case '\f':
- return true;
+ if ((*pos)[i] != text[i])
+ {
+ return false;
+ }
}
- return false;
+ if ((*pos)[i++] != ':' || (*pos)[i] != ']')
+ {
+ return false;
+ }
+ *pos = &(*pos)[i];
+ return true;
}
+#define NREX_COMPARE_CLASS(POS, NAME) if (nrex_compare_class(POS, #NAME)) return nrex_class_ ## NAME
+
+static nrex_class_type nrex_parse_class(const nrex_char** pos)
+{
+ NREX_COMPARE_CLASS(pos, alnum);
+ NREX_COMPARE_CLASS(pos, alpha);
+ NREX_COMPARE_CLASS(pos, blank);
+ NREX_COMPARE_CLASS(pos, cntrl);
+ NREX_COMPARE_CLASS(pos, digit);
+ NREX_COMPARE_CLASS(pos, graph);
+ NREX_COMPARE_CLASS(pos, lower);
+ NREX_COMPARE_CLASS(pos, print);
+ NREX_COMPARE_CLASS(pos, punct);
+ NREX_COMPARE_CLASS(pos, space);
+ NREX_COMPARE_CLASS(pos, upper);
+ NREX_COMPARE_CLASS(pos, xdigit);
+ NREX_COMPARE_CLASS(pos, word);
+ return nrex_class_none;
+}
+
+struct nrex_node_class : public nrex_node
+{
+ nrex_class_type type;
+
+ nrex_node_class(nrex_class_type t)
+ : nrex_node(true)
+ , type(t)
+ {
+ length = 1;
+ }
+
+ int test(nrex_search* s, int pos) const
+ {
+ if (s->end == pos)
+ {
+ return -1;
+ }
+ if (!test_class(s->at(pos)))
+ {
+ return -1;
+ }
+ return next ? next->test(s, pos + 1) : pos + 1;
+ }
+
+ bool test_class(nrex_char c) const
+ {
+ if ((0 <= c && c <= 0x1F) || c == 0x7F)
+ {
+ if (type == nrex_class_cntrl)
+ {
+ return true;
+ }
+ }
+ else if (c < 0x7F)
+ {
+ if (type == nrex_class_print)
+ {
+ return true;
+ }
+ else if (type == nrex_class_graph && c != ' ')
+ {
+ return true;
+ }
+ else if ('0' <= c && c <= '9')
+ {
+ switch (type)
+ {
+ case nrex_class_alnum:
+ case nrex_class_digit:
+ case nrex_class_xdigit:
+ case nrex_class_word:
+ return true;
+ default:
+ break;
+ }
+ }
+ else if ('A' <= c && c <= 'Z')
+ {
+ switch (type)
+ {
+ case nrex_class_alnum:
+ case nrex_class_alpha:
+ case nrex_class_upper:
+ case nrex_class_word:
+ return true;
+ case nrex_class_xdigit:
+ if (c <= 'F')
+ {
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+ else if ('a' <= c && c <= 'z')
+ {
+ switch (type)
+ {
+ case nrex_class_alnum:
+ case nrex_class_alpha:
+ case nrex_class_lower:
+ case nrex_class_word:
+ return true;
+ case nrex_class_xdigit:
+ if (c <= 'f')
+ {
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ if (type == nrex_class_blank)
+ {
+ return true;
+ }
+ case '\r':
+ case '\n':
+ case '\f':
+ if (type == nrex_class_space)
+ {
+ return true;
+ }
+ break;
+ case '_':
+ if (type == nrex_class_word)
+ {
+ return true;
+ }
+ case ']':
+ case '[':
+ case '!':
+ case '"':
+ case '#':
+ case '$':
+ case '%':
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case '.':
+ case '/':
+ case ':':
+ case ';':
+ case '<':
+ case '=':
+ case '>':
+ case '?':
+ case '@':
+ case '\\':
+ case '^':
+ case '`':
+ case '{':
+ case '|':
+ case '}':
+ case '~':
+ case '-':
+ if (type == nrex_class_punct)
+ {
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+ }
+};
+
static bool nrex_is_shorthand(nrex_char repr)
{
switch (repr)
@@ -400,6 +722,7 @@ struct nrex_node_shorthand : public nrex_node
: nrex_node(true)
, repr(c)
{
+ length = 1;
}
int test(nrex_search* s, int pos) const
@@ -435,7 +758,7 @@ struct nrex_node_shorthand : public nrex_node
case 'S':
invert = true;
case 's':
- if (nrex_is_whitespace(c))
+ if (NREX_ISSPACE(c))
{
found = true;
}
@@ -469,10 +792,10 @@ struct nrex_node_quantifier : public nrex_node
bool greedy;
nrex_node* child;
- nrex_node_quantifier()
+ nrex_node_quantifier(int min, int max)
: nrex_node()
- , min(0)
- , max(0)
+ , min(min)
+ , max(max)
, greedy(true)
, child(NULL)
{
@@ -488,17 +811,49 @@ struct nrex_node_quantifier : public nrex_node
int test(nrex_search* s, int pos) const
{
- nrex_array<int> backtrack;
- backtrack.push(pos);
- while (backtrack.top() <= s->end)
+ return test_step(s, pos, 1);
+ }
+
+ int test_step(nrex_search* s, int pos, int level) const
+ {
+ if (max == 0)
{
- if (max >= 1 && backtrack.size() > (unsigned int)max)
+ return pos;
+ }
+ if ((max >= 1 && level > max) || pos > s->end)
+ {
+ return -1;
+ }
+ if (!greedy && level > min)
+ {
+ int res = pos;
+ if (next)
{
- break;
+ res = next->test(s, res);
+ }
+ if (s->complete)
+ {
+ return res;
}
- if (!greedy && (unsigned int)min < backtrack.size())
+ if (res >= 0 && parent->test_parent(s, res) >= 0)
+ {
+ return res;
+ }
+ }
+ int res = child->test(s, pos);
+ if (s->complete)
+ {
+ return res;
+ }
+ if (res >= 0)
+ {
+ int res_step = test_step(s, res, level + 1);
+ if (res_step >= 0)
+ {
+ return res_step;
+ }
+ else if (greedy && level >= min)
{
- int res = backtrack.top();
if (next)
{
res = next->test(s, res);
@@ -512,33 +867,6 @@ struct nrex_node_quantifier : public nrex_node
return res;
}
}
- int res = child->test(s, backtrack.top());
- if (s->complete)
- {
- return res;
- }
- if (res < 0 || res == backtrack.top())
- {
- break;
- }
- backtrack.push(res);
- }
- while (greedy && (unsigned int) min < backtrack.size())
- {
- int res = backtrack.top();
- if (next)
- {
- res = next->test(s, res);
- }
- if (res >= 0 && parent->test_parent(s, res) >= 0)
- {
- return res;
- }
- if (s->complete)
- {
- return res;
- }
- backtrack.pop();
}
return -1;
}
@@ -552,6 +880,7 @@ struct nrex_node_anchor : public nrex_node
: nrex_node()
, end(end)
{
+ length = 0;
}
int test(nrex_search* s, int pos) const
@@ -568,6 +897,45 @@ struct nrex_node_anchor : public nrex_node
}
};
+struct nrex_node_word_boundary : public nrex_node
+{
+ bool inverse;
+
+ nrex_node_word_boundary(bool inverse)
+ : nrex_node()
+ , inverse(inverse)
+ {
+ length = 0;
+ }
+
+ int test(nrex_search* s, int pos) const
+ {
+ bool left = false;
+ bool right = false;
+ if (pos != 0)
+ {
+ nrex_char c = s->at(pos - 1);
+ if (c == '_' || NREX_ISALPHANUM(c))
+ {
+ left = true;
+ }
+ }
+ if (pos != s->end)
+ {
+ nrex_char c = s->at(pos);
+ if (c == '_' || NREX_ISALPHANUM(c))
+ {
+ right = true;
+ }
+ }
+ if ((left != right) == inverse)
+ {
+ return -1;
+ }
+ return next ? next->test(s, pos) : pos;
+ }
+};
+
struct nrex_node_backreference : public nrex_node
{
int ref;
@@ -576,6 +944,7 @@ struct nrex_node_backreference : public nrex_node
: nrex_node(true)
, ref(ref)
{
+ length = -1;
}
int test(nrex_search* s, int pos) const
@@ -596,6 +965,18 @@ struct nrex_node_backreference : public nrex_node
}
};
+bool nrex_has_lookbehind(nrex_array<nrex_node_group*>& stack)
+{
+ for (unsigned int i = 0; i < stack.size(); i++)
+ {
+ if (stack[i]->mode == nrex_node_group::LookBehind)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
nrex::nrex()
: _capturing(0)
, _root(NULL)
@@ -630,7 +1011,7 @@ int nrex::capture_size() const
return _capturing + 1;
}
-bool nrex::compile(const nrex_char* pattern)
+bool nrex::compile(const nrex_char* pattern, bool extended)
{
reset();
nrex_node_group* root = NREX_NEW(nrex_node_group(_capturing));
@@ -647,16 +1028,32 @@ bool nrex::compile(const nrex_char* pattern)
if (c[2] == ':')
{
c = &c[2];
- nrex_node_group* group = NREX_NEW(nrex_node_group(-1));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::NonCapture));
+ stack.top()->add_child(group);
+ stack.push(group);
+ }
+ else if (c[2] == '!' || c[2] == '=')
+ {
+ c = &c[2];
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::LookAhead));
+ group->negate = (c[0] == '!');
+ stack.top()->add_child(group);
+ stack.push(group);
+ }
+ else if (c[2] == '<' && (c[3] == '!' || c[3] == '='))
+ {
+ c = &c[3];
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::LookBehind));
+ group->negate = (c[0] == '!');
stack.top()->add_child(group);
stack.push(group);
}
else
{
- NREX_COMPILE_ERROR("unrecognised qualifier for parenthesis");
+ NREX_COMPILE_ERROR("unrecognised qualifier for group");
}
}
- else if (_capturing < 99)
+ else if ((!extended && _capturing < 9) || (extended && _capturing < 99))
{
nrex_node_group* group = NREX_NEW(nrex_node_group(++_capturing));
stack.top()->add_child(group);
@@ -664,7 +1061,7 @@ bool nrex::compile(const nrex_char* pattern)
}
else
{
- nrex_node_group* group = NREX_NEW(nrex_node_group(-1));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::NonCapture));
stack.top()->add_child(group);
stack.push(group);
}
@@ -682,152 +1079,233 @@ bool nrex::compile(const nrex_char* pattern)
}
else if (c[0] == '[')
{
- nrex_node_group* group = NREX_NEW(nrex_node_group(-1));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::Bracket));
stack.top()->add_child(group);
if (c[1] == '^')
{
group->negate = true;
++c;
}
+ bool first_child = true;
+ nrex_char previous_child;
+ bool previous_child_single = false;
while (true)
{
group->add_childset();
++c;
if (c[0] == '\0')
{
- NREX_COMPILE_ERROR("unclosed character class '[]'");
+ NREX_COMPILE_ERROR("unclosed bracket expression '['");
}
- if (c[0] == ']')
+ if (c[0] == '[' && c[1] == ':')
+ {
+ const nrex_char* d = &c[2];
+ nrex_class_type cls = nrex_parse_class(&d);
+ if (cls != nrex_class_none)
+ {
+ c = d;
+ group->add_child(NREX_NEW(nrex_node_class(cls)));
+ previous_child_single = false;
+ }
+ else
+ {
+ group->add_child(NREX_NEW(nrex_node_char('[')));
+ previous_child = '[';
+ previous_child_single = true;
+ }
+ }
+ else if (c[0] == ']' && !first_child)
{
break;
}
else if (c[0] == '\\')
{
- nrex_char unescaped = nrex_unescape(c[1]);
- if (unescaped)
- {
- group->add_child(NREX_NEW(nrex_node_char(unescaped)));
- ++c;
- }
- else if (nrex_is_shorthand(c[1]))
+ if (nrex_is_shorthand(c[1]))
{
group->add_child(NREX_NEW(nrex_node_shorthand(c[1])));
++c;
+ previous_child_single = false;
}
else
{
- NREX_COMPILE_ERROR("escape token not recognised");
+ const nrex_char* d = c;
+ nrex_char unescaped = nrex_unescape(d);
+ if (c == d)
+ {
+ NREX_COMPILE_ERROR("invalid escape token");
+ }
+ group->add_child(NREX_NEW(nrex_node_char(unescaped)));
+ c = d;
+ previous_child = unescaped;
+ previous_child_single = true;
}
}
- else
+ else if (previous_child_single && c[0] == '-')
{
- if (c[1] == '-' && c[2] != '\0')
+ bool is_range = false;
+ nrex_char next;
+ if (c[1] != '\0' && c[1] != ']')
{
- bool range = false;
- if ('A' <= c[0] && c[0] <= 'Z' && 'A' <= c[2] && c[2] <= 'Z')
+ if (c[1] == '\\')
{
- range = true;
+ const nrex_char* d = ++c;
+ next = nrex_unescape(d);
+ if (c == d)
+ {
+ NREX_COMPILE_ERROR("invalid escape token in range");
+ }
}
- if ('a' <= c[0] && c[0] <= 'z' && 'a' <= c[2] && c[2] <= 'z')
- {
- range = true;
- }
- if ('0' <= c[0] && c[0] <= '9' && '0' <= c[2] && c[2] <= '9')
+ else
{
- range = true;
+ next = c[1];
+ ++c;
}
- if (range)
+ is_range = true;
+ }
+ if (is_range)
+ {
+ if (next < previous_child)
{
- group->add_child(NREX_NEW(nrex_node_range(c[0], c[2])));
- c = &c[2];
- continue;
+ NREX_COMPILE_ERROR("text range out of order");
}
+ group->pop_back();
+ group->add_child(NREX_NEW(nrex_node_range(previous_child, next)));
+ previous_child_single = false;
+ }
+ else
+ {
+ group->add_child(NREX_NEW(nrex_node_char(c[0])));
+ previous_child = c[0];
+ previous_child_single = true;
}
+ }
+ else
+ {
group->add_child(NREX_NEW(nrex_node_char(c[0])));
+ previous_child = c[0];
+ previous_child_single = true;
}
-
+ first_child = false;
}
}
else if (nrex_is_quantifier(c[0]))
{
- nrex_node_quantifier* quant = NREX_NEW(nrex_node_quantifier);
- quant->child = stack.top()->swap_back(quant);
- if (quant->child == NULL || !quant->child->quantifiable)
+ 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");
}
- quant->child->previous = NULL;
- quant->child->next = NULL;
- quant->child->parent = quant;
+ int min = 0;
+ int max = -1;
+ bool valid_quantifier = true;
if (c[0] == '?')
{
- quant->min = 0;
- quant->max = 1;
+ min = 0;
+ max = 1;
}
else if (c[0] == '+')
{
- quant->min = 1;
- quant->max = -1;
+ min = 1;
+ max = -1;
}
else if (c[0] == '*')
{
- quant->min = 0;
- quant->max = -1;
+ min = 0;
+ max = -1;
}
else if (c[0] == '{')
{
bool max_set = false;
- quant->min = 0;
- quant->max = -1;
+ const nrex_char* d = c;
while (true)
{
- ++c;
- if (c[0] == '\0')
+ ++d;
+ if (d[0] == '\0')
{
- NREX_COMPILE_ERROR("unclosed range quantifier '{}'");
+ valid_quantifier = false;
+ break;
}
- else if (c[0] == '}')
+ else if (d[0] == '}')
{
break;
}
- else if (c[0] == ',')
+ else if (d[0] == ',')
{
max_set = true;
continue;
}
- else if (c[0] < '0' || '9' < c[0])
+ else if (d[0] < '0' || '9' < d[0])
{
- NREX_COMPILE_ERROR("expected numeric digits, ',' or '}'");
+ valid_quantifier = false;
+ break;
}
if (max_set)
{
- if (quant->max < 0)
+ if (max < 0)
{
- quant->max = int(c[0] - '0');
+ max = int(d[0] - '0');
}
else
{
- quant->max = quant->max * 10 + int(c[0] - '0');
+ max = max * 10 + int(d[0] - '0');
}
}
else
{
- quant->min = quant->min * 10 + int(c[0] - '0');
+ min = min * 10 + int(d[0] - '0');
}
}
if (!max_set)
{
- quant->max = quant->min;
+ max = min;
+ }
+ if (valid_quantifier)
+ {
+ c = d;
}
}
- if (c[1] == '?')
+ if (valid_quantifier)
{
- quant->greedy = false;
- ++c;
+ nrex_node_quantifier* quant = NREX_NEW(nrex_node_quantifier(min, max));
+ if (min == max)
+ {
+ if (stack.top()->back->length >= 0)
+ {
+ quant->length = max * stack.top()->back->length;
+ }
+ }
+ else
+ {
+ if (nrex_has_lookbehind(stack))
+ {
+ NREX_COMPILE_ERROR("variable length quantifiers inside lookbehind not supported");
+ }
+ }
+ quant->child = stack.top()->swap_back(quant);
+ quant->child->previous = NULL;
+ quant->child->next = NULL;
+ quant->child->parent = quant;
+ if (c[1] == '?')
+ {
+ quant->greedy = false;
+ ++c;
+ }
+ }
+ else
+ {
+ stack.top()->add_child(NREX_NEW(nrex_node_char(c[0])));
}
}
else if (c[0] == '|')
{
+ if (nrex_has_lookbehind(stack))
+ {
+ NREX_COMPILE_ERROR("alternations inside lookbehind not supported");
+ }
stack.top()->add_childset();
}
else if (c[0] == '^' || c[0] == '$')
@@ -840,13 +1318,7 @@ bool nrex::compile(const nrex_char* pattern)
}
else if (c[0] == '\\')
{
- nrex_char unescaped = nrex_unescape(c[1]);
- if (unescaped)
- {
- stack.top()->add_child(NREX_NEW(nrex_node_char(unescaped)));
- ++c;
- }
- else if (nrex_is_shorthand(c[1]))
+ if (nrex_is_shorthand(c[1]))
{
stack.top()->add_child(NREX_NEW(nrex_node_shorthand(c[1])));
++c;
@@ -854,7 +1326,7 @@ bool nrex::compile(const nrex_char* pattern)
else if ('1' <= c[1] && c[1] <= '9')
{
int ref = 0;
- if ('0' <= c[2] && c[2] <= '9')
+ if (extended && '0' <= c[2] && c[2] <= '9')
{
ref = int(c[1] - '0') * 10 + int(c[2] - '0');
c = &c[2];
@@ -868,11 +1340,27 @@ bool nrex::compile(const nrex_char* pattern)
{
NREX_COMPILE_ERROR("backreference to non-existent capture");
}
+ if (nrex_has_lookbehind(stack))
+ {
+ NREX_COMPILE_ERROR("backreferences inside lookbehind not supported");
+ }
stack.top()->add_child(NREX_NEW(nrex_node_backreference(ref)));
}
+ else if (c[1] == 'b' || c[1] == 'B')
+ {
+ stack.top()->add_child(NREX_NEW(nrex_node_word_boundary(c[1] == 'B')));
+ ++c;
+ }
else
{
- NREX_COMPILE_ERROR("escape token not recognised");
+ const nrex_char* d = c;
+ nrex_char unescaped = nrex_unescape(d);
+ if (c == d)
+ {
+ NREX_COMPILE_ERROR("invalid escape token");
+ }
+ stack.top()->add_child(NREX_NEW(nrex_node_char(unescaped)));
+ c = d;
}
}
else
@@ -880,6 +1368,10 @@ bool nrex::compile(const nrex_char* pattern)
stack.top()->add_child(NREX_NEW(nrex_node_char(c[0])));
}
}
+ if (stack.size() > 1)
+ {
+ NREX_COMPILE_ERROR("unclosed group '('");
+ }
return true;
}
diff --git a/drivers/nrex/nrex.hpp b/drivers/nrex/nrex.hpp
index 2a6aa08e1d..e26a61c39a 100644
--- a/drivers/nrex/nrex.hpp
+++ b/drivers/nrex/nrex.hpp
@@ -79,7 +79,8 @@ 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 100.
+ * always capped at 10 or 100, depending on the extend option given in
+ * nrex::compile() (default 10).
*
* \return The number of captures
*/
@@ -95,10 +96,13 @@ class nrex
* runtime error nrex_compile_error if it encounters a problem when
* parsing the pattern.
*
- * \param The regex 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.
* \return True if the pattern was succesfully compiled
*/
- bool compile(const nrex_char* pattern);
+ bool compile(const nrex_char* pattern, bool extended = false);
/*!
* \brief Uses the pattern to search through the provided string
diff --git a/drivers/nrex/regex.cpp b/drivers/nrex/regex.cpp
index 0a813c3490..246384b10a 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"),&RegEx::compile);
+ ObjectTypeDB::bind_method(_MD("compile","pattern", "expanded"),&RegEx::compile, DEFVAL(true));
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);
@@ -54,7 +54,9 @@ bool RegEx::is_valid() const {
};
int RegEx::get_capture_count() const {
-
+
+ ERR_FAIL_COND_V( !exp.valid(), 0 );
+
return exp.capture_size();
}
@@ -66,11 +68,11 @@ String RegEx::get_capture(int capture) const {
}
-Error RegEx::compile(const String& p_pattern) {
+Error RegEx::compile(const String& p_pattern, bool expanded) {
clear();
- exp.compile(p_pattern.c_str());
+ exp.compile(p_pattern.c_str(), expanded);
ERR_FAIL_COND_V( !exp.valid(), FAILED );
diff --git a/drivers/nrex/regex.h b/drivers/nrex/regex.h
index 0626029705..be52da8149 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);
+ Error compile(const String& p_pattern, bool expanded = false);
int find(const String& p_text, int p_start = 0, int p_end = -1) const;
RegEx();
diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h
index 134279b6d8..04f3dff3de 100644
--- a/modules/gdscript/gd_parser.h
+++ b/modules/gdscript/gd_parser.h
@@ -276,7 +276,6 @@ public:
};
struct NewLineNode : public Node {
- int line;
NewLineNode() { type=TYPE_NEWLINE; }
};
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 418ee192b2..167b637bdc 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1031,13 +1031,12 @@ Vector2 TileMap::world_to_map(const Vector2& p_pos) const{
switch(half_offset) {
case HALF_OFFSET_X: {
- if (int(ret.y)&1) {
-
+ if ( ret.y > 0 ? int(ret.y)&1 : (int(ret.y)-1)&1 ) {
ret.x-=0.5;
}
} break;
case HALF_OFFSET_Y: {
- if (int(ret.x)&1) {
+ if ( ret.x > 0 ? int(ret.x)&1 : (int(ret.x)-1)&1) {
ret.y-=0.5;
}
} break;
diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp
index 8d1fa80b84..c92d7f2696 100644
--- a/scene/gui/button_group.cpp
+++ b/scene/gui/button_group.cpp
@@ -155,6 +155,6 @@ void ButtonGroup::_bind_methods() {
}
-ButtonGroup::ButtonGroup()
+ButtonGroup::ButtonGroup() : BoxContainer(true)
{
}
diff --git a/scene/gui/button_group.h b/scene/gui/button_group.h
index 24edf94994..74e847e937 100644
--- a/scene/gui/button_group.h
+++ b/scene/gui/button_group.h
@@ -29,14 +29,14 @@
#ifndef BUTTON_GROUP_H
#define BUTTON_GROUP_H
-#include "scene/gui/control.h"
+#include "scene/gui/box_container.h"
class BaseButton;
-class ButtonGroup : public Control {
+class ButtonGroup : public BoxContainer {
- OBJ_TYPE(ButtonGroup,Control);
+ OBJ_TYPE(ButtonGroup,BoxContainer);
Set<BaseButton*> buttons;
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 8e448dfb2b..47a55e0716 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -102,11 +102,13 @@ void Tabs::_input_event(const InputEvent& p_event) {
// test hovering right button and close button
if (tabs[i].rb_rect.has_point(pos)) {
rb_hover=i;
+ cb_hover=-1;
hover_buttons = i;
break;
}
else if (tabs[i].cb_rect.has_point(pos)) {
cb_hover=i;
+ rb_hover=-1;
hover_buttons = i;
break;
}
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index 0d549108fa..c8930add6e 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -233,11 +233,7 @@ float TextureProgress::get_radial_initial_angle()
void TextureProgress::set_fill_degrees(float p_angle)
{
- while(p_angle>360)
- p_angle-=360;
- while (p_angle<0)
- p_angle+=360;
- rad_max_degrees=p_angle;
+ rad_max_degrees=CLAMP(p_angle,0,360);
update();
}
@@ -302,4 +298,5 @@ TextureProgress::TextureProgress()
{
mode=FILL_LEFT_TO_RIGHT;
rad_center_off=Point2();
+ rad_max_degrees=360;
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 8c640b1b1b..a82fc2a5e7 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -322,6 +322,10 @@ void make_default_theme() {
t->set_constant("hseparation","MenuButton", 3 );
+ // ButtonGroup
+
+ t->set_stylebox("panel","ButtonGroup", memnew( StyleBoxEmpty ));
+
// CheckBox
Ref<StyleBox> cbx_empty = memnew( StyleBoxEmpty );
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index bbb2a386f3..55bb4e9073 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -406,7 +406,6 @@ void FixedMaterial::_bind_methods() {
BIND_CONSTANT( PARAM_SHADE_PARAM );
BIND_CONSTANT( PARAM_MAX );
-
BIND_CONSTANT( TEXCOORD_SPHERE );
BIND_CONSTANT( TEXCOORD_UV );
BIND_CONSTANT( TEXCOORD_UV_TRANSFORM );
@@ -417,6 +416,11 @@ void FixedMaterial::_bind_methods() {
BIND_CONSTANT( FLAG_USE_POINT_SIZE );
BIND_CONSTANT( FLAG_DISCARD_ALPHA );
+ BIND_CONSTANT( LIGHT_SHADER_LAMBERT );
+ BIND_CONSTANT( LIGHT_SHADER_WRAP );
+ BIND_CONSTANT( LIGHT_SHADER_VELVET );
+ BIND_CONSTANT( LIGHT_SHADER_TOON );
+
}
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index e22b3c3a6c..aca301e0a8 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -693,7 +693,7 @@ public:
Rect2 rect;
RID texture;
float margin[4];
- float draw_center;
+ bool draw_center;
Color color;
CommandStyle() { draw_center=true; type = TYPE_STYLE; }
};
diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h
index f582fbd8ee..2c503249fe 100644
--- a/servers/visual/rasterizer_dummy.h
+++ b/servers/visual/rasterizer_dummy.h
@@ -162,10 +162,6 @@ class RasterizerDummy : public Rasterizer {
uint32_t format;
uint32_t morph_format;
- RID material;
- bool material_owned;
-
-
Surface() {
packed=false;
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index f8c484e886..65565aae85 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -1279,6 +1279,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
add_child(file);
name_dialog = memnew( ConfirmationDialog );
+ name_dialog->set_title("Create New Animation");
name_dialog->set_hide_on_ok(false);
add_child(name_dialog);
name = memnew( LineEdit );
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index d318f6f6fa..b03eed77b1 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -41,9 +41,9 @@
class SnapDialog : public ConfirmationDialog {
OBJ_TYPE(SnapDialog,ConfirmationDialog);
-
-protected:
- friend class CanvasItemEditor;
+
+friend class CanvasItemEditor;
+
SpinBox *grid_offset_x;
SpinBox *grid_offset_y;
SpinBox *grid_step_x;
@@ -58,63 +58,75 @@ public:
Label *label;
VBoxContainer *container;
GridContainer *child_container;
-
+
set_title("Configure Snap");
get_ok()->set_text("Close");
- container = memnew(VBoxContainer);
+
+ container = memnew( VBoxContainer );
add_child(container);
-
- child_container = memnew(GridContainer);
+ set_child_rect(container);
+
+ child_container = memnew( GridContainer );
child_container->set_columns(3);
container->add_child(child_container);
-
- label = memnew(Label);
+
+ label = memnew( Label );
label->set_text("Grid Offset:");
child_container->add_child(label);
- grid_offset_x=memnew(SpinBox);
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ grid_offset_x = memnew( SpinBox );
grid_offset_x->set_min(-SPIN_BOX_GRID_RANGE);
grid_offset_x->set_max(SPIN_BOX_GRID_RANGE);
grid_offset_x->set_suffix("px");
child_container->add_child(grid_offset_x);
- grid_offset_y=memnew(SpinBox);
+
+ grid_offset_y = memnew( SpinBox );
grid_offset_y->set_min(-SPIN_BOX_GRID_RANGE);
grid_offset_y->set_max(SPIN_BOX_GRID_RANGE);
grid_offset_y->set_suffix("px");
child_container->add_child(grid_offset_y);
- label = memnew(Label);
+ label = memnew( Label );
label->set_text("Grid Step:");
child_container->add_child(label);
- grid_step_x=memnew(SpinBox);
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ grid_step_x = memnew( SpinBox );
grid_step_x->set_min(-SPIN_BOX_GRID_RANGE);
grid_step_x->set_max(SPIN_BOX_GRID_RANGE);
grid_step_x->set_suffix("px");
child_container->add_child(grid_step_x);
- grid_step_y=memnew(SpinBox);
+
+ grid_step_y = memnew( SpinBox );
grid_step_y->set_min(-SPIN_BOX_GRID_RANGE);
grid_step_y->set_max(SPIN_BOX_GRID_RANGE);
grid_step_y->set_suffix("px");
child_container->add_child(grid_step_y);
-
- container->add_child(memnew(HSeparator));
- child_container = memnew(GridContainer);
+ container->add_child( memnew( HSeparator ) );
+
+ child_container = memnew( GridContainer );
child_container->set_columns(2);
container->add_child(child_container);
- label = memnew(Label);
+ label = memnew( Label );
label->set_text("Rotation Offset:");
child_container->add_child(label);
- rotation_offset=memnew(SpinBox);
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ rotation_offset = memnew( SpinBox );
rotation_offset->set_min(-SPIN_BOX_ROTATION_RANGE);
rotation_offset->set_max(SPIN_BOX_ROTATION_RANGE);
rotation_offset->set_suffix("deg");
child_container->add_child(rotation_offset);
-
- label = memnew(Label);
+
+ label = memnew( Label );
label->set_text("Rotation Step:");
child_container->add_child(label);
- rotation_step=memnew(SpinBox);
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ rotation_step = memnew( SpinBox );
rotation_step->set_min(-SPIN_BOX_ROTATION_RANGE);
rotation_step->set_max(SPIN_BOX_ROTATION_RANGE);
rotation_step->set_suffix("deg");
@@ -2278,7 +2290,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case SNAP_CONFIGURE: {
((SnapDialog *)snap_dialog)->set_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step);
- snap_dialog->popup_centered(Size2(200,160));
+ snap_dialog->popup_centered(Size2(220,160));
} break;
case ZOOM_IN: {
zoom=zoom*(1.0/0.5);
@@ -3173,7 +3185,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->add_item("Paste Pose",ANIM_PASTE_POSE);
p->add_item("Clear Pose",ANIM_CLEAR_POSE,KEY_MASK_SHIFT|KEY_K);
- snap_dialog = memnew(SnapDialog);
+ snap_dialog = memnew( SnapDialog );
snap_dialog->connect("confirmed",this,"_snap_changed");
add_child(snap_dialog);
diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp
index 13d4c8db5a..cea774f94b 100644
--- a/tools/editor/plugins/mesh_editor_plugin.cpp
+++ b/tools/editor/plugins/mesh_editor_plugin.cpp
@@ -160,7 +160,7 @@ void MeshInstanceEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_OUTLINE_MESH: {
- outline_dialog->popup_centered_minsize();
+ outline_dialog->popup_centered(Vector2(200, 90));
} break;
}
@@ -212,7 +212,6 @@ MeshInstanceEditor::MeshInstanceEditor() {
options = memnew( MenuButton );
- //add_child(options);
SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text("Mesh");
@@ -231,14 +230,20 @@ MeshInstanceEditor::MeshInstanceEditor() {
options->get_popup()->connect("item_pressed", this,"_menu_option");
outline_dialog = memnew( ConfirmationDialog );
- outline_dialog->set_title("Outline Size: ");
+ outline_dialog->set_title("Create Outline Mesh");
+ outline_dialog->get_ok()->set_text("Create");
+
+ VBoxContainer *outline_dialog_vbc = memnew( VBoxContainer );
+ outline_dialog->add_child(outline_dialog_vbc);
+ outline_dialog->set_child_rect(outline_dialog_vbc);
+
outline_size = memnew( SpinBox );
outline_size->set_min(0.001);
outline_size->set_max(1024);
outline_size->set_step(0.001);
outline_size->set_val(0.05);
- outline_dialog->add_child(outline_size);
- outline_dialog->set_child_rect(outline_size);
+ outline_dialog_vbc->add_margin_child("Outline Size:",outline_size);
+
add_child(outline_dialog);
outline_dialog->connect("confirmed",this,"_create_outline_mesh");
diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/tools/editor/plugins/multimesh_editor_plugin.cpp
index 3c88b1d3a8..a5c823f8bd 100644
--- a/tools/editor/plugins/multimesh_editor_plugin.cpp
+++ b/tools/editor/plugins/multimesh_editor_plugin.cpp
@@ -289,7 +289,7 @@ void MultiMeshEditor::_menu_option(int p_option) {
_last_pp_node=node;
}
- populate_dialog->popup_centered(Size2(250,395));
+ populate_dialog->popup_centered(Size2(250,380));
} break;
}
@@ -325,10 +325,8 @@ MultiMeshEditor::MultiMeshEditor() {
options = memnew( MenuButton );
- //add_child(options);
SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
- options->set_area_as_parent_rect();
-
+
options->set_text("MultiMesh");
options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MultiMeshInstance","EditorIcons"));
@@ -373,12 +371,12 @@ MultiMeshEditor::MultiMeshEditor() {
populate_axis->select(2);
vbc->add_margin_child("Mesh Up Axis:",populate_axis);
- populate_rotate_random = memnew( HScrollBar );
+ populate_rotate_random = memnew( HSlider );
populate_rotate_random->set_max(1);
populate_rotate_random->set_step(0.01);
vbc->add_margin_child("Random Rotation:",populate_rotate_random);
- populate_tilt_random = memnew( HScrollBar );
+ populate_tilt_random = memnew( HSlider );
populate_tilt_random->set_max(1);
populate_tilt_random->set_step(0.01);
vbc->add_margin_child("Random Tilt:",populate_tilt_random);
@@ -416,8 +414,7 @@ MultiMeshEditor::MultiMeshEditor() {
std->connect("selected",this,"_browsed");
_last_pp_node=NULL;
- //options->set_anchor(MARGIN_LEFT,Control::ANCHOR_END);
- //options->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
+
err_dialog = memnew( AcceptDialog );
add_child(err_dialog);
}
@@ -451,13 +448,6 @@ MultiMeshEditorPlugin::MultiMeshEditorPlugin(EditorNode *p_node) {
multimesh_editor = memnew( MultiMeshEditor );
editor->get_viewport()->add_child(multimesh_editor);
-// multimesh_editor->set_anchor(MARGIN_LEFT,Control::ANCHOR_END);
-// multimesh_editor->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
- multimesh_editor->set_margin(MARGIN_LEFT,253);
- multimesh_editor->set_margin(MARGIN_RIGHT,310);
- multimesh_editor->set_margin(MARGIN_TOP,0);
- multimesh_editor->set_margin(MARGIN_BOTTOM,10);
-
multimesh_editor->options->hide();
}
diff --git a/tools/editor/plugins/multimesh_editor_plugin.h b/tools/editor/plugins/multimesh_editor_plugin.h
index 4f0c0d008b..edc3dfd55f 100644
--- a/tools/editor/plugins/multimesh_editor_plugin.h
+++ b/tools/editor/plugins/multimesh_editor_plugin.h
@@ -42,10 +42,10 @@ class MultiMeshEditor : public Control {
OBJ_TYPE(MultiMeshEditor, Control );
- friend class MultiMeshEditorPlugin;
+friend class MultiMeshEditorPlugin;
AcceptDialog *err_dialog;
- MenuButton * options;
+ MenuButton * options;
MultiMeshInstance *_last_pp_node;
bool browsing_source;
@@ -59,8 +59,8 @@ class MultiMeshEditor : public Control {
ConfirmationDialog *populate_dialog;
OptionButton *populate_axis;
- HScrollBar *populate_rotate_random;
- HScrollBar *populate_tilt_random;
+ HSlider *populate_rotate_random;
+ HSlider *populate_tilt_random;
SpinBox *populate_scale_random;
SpinBox *populate_scale;
SpinBox *populate_amount;
diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp
index 684e7e32ef..3a7dc26466 100644
--- a/tools/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp
@@ -2542,7 +2542,7 @@ void ShaderGraphView::_notification(int p_what) {
void ShaderGraphView::add_node(int p_type, const Vector2 &location) {
- if ((p_type==ShaderGraph::NODE_INPUT||p_type==ShaderGraph::NODE_INPUT) && graph->node_count(type, p_type)>0)
+ if (p_type==ShaderGraph::NODE_INPUT && graph->node_count(type, p_type)>0)
return;
List<int> existing;
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index 3ab9339265..f3458a768a 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -2725,7 +2725,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_TRANSFORM_CONFIGURE_SNAP: {
- snap_dialog->popup_centered(Size2(200,160));
+ snap_dialog->popup_centered(Size2(200,180));
} break;
case MENU_TRANSFORM_LOCAL_COORDS: {
@@ -3793,46 +3793,24 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
snap_dialog = memnew( ConfirmationDialog );
snap_dialog->set_title("Snap Settings");
add_child(snap_dialog);
- Label *l = memnew(Label);
- l->set_text("Translate Snap:");
- l->set_pos(Point2(5,5));
- snap_dialog->add_child(l);
+
+ VBoxContainer *snap_dialog_vbc = memnew( VBoxContainer );
+ snap_dialog->add_child(snap_dialog_vbc);
+ snap_dialog->set_child_rect(snap_dialog_vbc);
snap_translate = memnew( LineEdit );
- snap_translate->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- snap_translate->set_begin( Point2(15,22) );
- snap_translate->set_end( Point2(15,35) );
snap_translate->set_text("1");
- snap_dialog->add_child(snap_translate);
-
- l = memnew(Label);
- l->set_text("Rotate Snap (deg.):");
- l->set_pos(Point2(5,45));
- snap_dialog->add_child(l);
+ snap_dialog_vbc->add_margin_child("Translate Snap:",snap_translate);
snap_rotate = memnew( LineEdit );
- snap_rotate->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- snap_rotate->set_begin( Point2(15,62) );
- snap_rotate->set_end( Point2(15,75) );
snap_rotate->set_text("5");
- snap_dialog->add_child(snap_rotate);
-
-
- l = memnew(Label);
- l->set_text("Scale Snap (%):");
- l->set_pos(Point2(5,85));
- snap_dialog->add_child(l);
+ snap_dialog_vbc->add_margin_child("Rotate Snap (deg.):",snap_rotate);
snap_scale = memnew( LineEdit );
- snap_scale->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- snap_scale->set_begin( Point2(15,102) );
- snap_scale->set_end( Point2(15,115) );
snap_scale->set_text("5");
- snap_dialog->add_child(snap_scale);
+ snap_dialog_vbc->add_margin_child("Scale Snap (%):",snap_scale);
- //snap_dialog->get_cancel()->hide();
-
- /* SNAP DIALOG */
+ /* SETTINGS DIALOG */
settings_dialog = memnew( ConfirmationDialog );
settings_dialog->set_title("Viewport Settings");
@@ -3906,7 +3884,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
xform_dialog = memnew( ConfirmationDialog );
xform_dialog->set_title("Transform Change");
add_child(xform_dialog);
- l = memnew(Label);
+ Label *l = memnew(Label);
l->set_text("Translate:");
l->set_pos(Point2(5,5));
xform_dialog->add_child(l);
diff --git a/tools/editor/plugins/theme_editor_plugin.cpp b/tools/editor/plugins/theme_editor_plugin.cpp
index 55e8f164d6..63ba57bfc0 100644
--- a/tools/editor/plugins/theme_editor_plugin.cpp
+++ b/tools/editor/plugins/theme_editor_plugin.cpp
@@ -568,26 +568,24 @@ ThemeEditor::ThemeEditor() {
CheckButton *cb = memnew( CheckButton );
cb->set_text("CheckButton");
first_vb->add_child(cb );
- CheckBox *cbx = memnew( CheckBox );
- cbx->set_text("CheckBox");
- first_vb->add_child(cbx );
-
- /* TODO: This is not working properly, controls are overlapping*/
- /*
- ButtonGroup *bg = memnew( ButtonGroup );
- bg->set_v_size_flags(SIZE_EXPAND_FILL);
- VBoxContainer *gbvb = memnew( VBoxContainer );
- gbvb->set_v_size_flags(SIZE_EXPAND_FILL);
- CheckBox *rbx1 = memnew( CheckBox );
- rbx1->set_text("CheckBox Radio1");
- rbx1->set_pressed(true);
- gbvb->add_child(rbx1);
- CheckBox *rbx2 = memnew( CheckBox );
- rbx2->set_text("CheckBox Radio2");
- gbvb->add_child(rbx2);
- bg->add_child(gbvb);
- first_vb->add_child(bg);
- */
+ CheckBox *cbx = memnew( CheckBox );
+ cbx->set_text("CheckBox");
+ first_vb->add_child(cbx );
+
+
+ ButtonGroup *bg = memnew( ButtonGroup );
+ bg->set_v_size_flags(SIZE_EXPAND_FILL);
+ VBoxContainer *gbvb = memnew( VBoxContainer );
+ gbvb->set_v_size_flags(SIZE_EXPAND_FILL);
+ CheckBox *rbx1 = memnew( CheckBox );
+ rbx1->set_text("CheckBox Radio1");
+ rbx1->set_pressed(true);
+ gbvb->add_child(rbx1);
+ CheckBox *rbx2 = memnew( CheckBox );
+ rbx2->set_text("CheckBox Radio2");
+ gbvb->add_child(rbx2);
+ bg->add_child(gbvb);
+ first_vb->add_child(bg);
MenuButton* test_menu_button = memnew( MenuButton );
test_menu_button->set_text("MenuButton");
diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp
index 9f47291433..bc1af52858 100644
--- a/tools/editor/project_manager.cpp
+++ b/tools/editor/project_manager.cpp
@@ -193,7 +193,7 @@ class NewProjectDialog : public ConfirmationDialog {
f->store_line("\n");
f->store_line("[application]");
f->store_line("name=\""+project_name->get_text()+"\"");
- f->store_line("icon=\"icon.png\"");
+ f->store_line("icon=\"res://icon.png\"");
memdelete(f);
@@ -480,20 +480,25 @@ void ProjectManager::_load_recent_projects() {
bool favorite = (_name.begins_with("favorite_projects/"))?true:false;
uint64_t last_modified = 0;
- if (FileAccess::exists(conf))
+ if (FileAccess::exists(conf)) {
last_modified = FileAccess::get_modified_time(conf);
- String fscache = path.plus_file(".fscache");
- if (FileAccess::exists(fscache)) {
- uint64_t cache_modified = FileAccess::get_modified_time(fscache);
- if ( cache_modified > last_modified )
- last_modified = cache_modified;
- }
- ProjectItem item(project, path, conf, last_modified, favorite);
- if (favorite)
- favorite_projects.push_back(item);
- else
- projects.push_back(item);
+ String fscache = path.plus_file(".fscache");
+ if (FileAccess::exists(fscache)) {
+ uint64_t cache_modified = FileAccess::get_modified_time(fscache);
+ if ( cache_modified > last_modified )
+ last_modified = cache_modified;
+ }
+
+ ProjectItem item(project, path, conf, last_modified, favorite);
+ if (favorite)
+ favorite_projects.push_back(item);
+ else
+ projects.push_back(item);
+ } else {
+ //project doesn't exist on disk but it's in the XML settings file
+ EditorSettings::get_singleton()->erase(_name); //remove it
+ }
}
projects.sort();
@@ -601,6 +606,8 @@ void ProjectManager::_load_recent_projects() {
erase_btn->set_disabled(selected_list.size()<1);
open_btn->set_disabled(selected_list.size()<1);
run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main==""));
+
+ EditorSettings::get_singleton()->save();
}
void ProjectManager::_open_project_confirm() {