summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/tests/test_gui.cpp3
-rw-r--r--core/os/memory.cpp7
-rw-r--r--core/os/memory.h17
-rw-r--r--core/reference.h3
-rw-r--r--demos/2d/space_shooter/asteroid.gd49
-rw-r--r--demos/2d/space_shooter/asteroid.scnbin0 -> 4516 bytes
-rw-r--r--demos/2d/space_shooter/bg_gradient.pngbin0 -> 1572 bytes
-rw-r--r--demos/2d/space_shooter/big_star.pngbin0 -> 275 bytes
-rw-r--r--demos/2d/space_shooter/enemy1.gd37
-rw-r--r--demos/2d/space_shooter/enemy1.pngbin0 -> 7048 bytes
-rw-r--r--demos/2d/space_shooter/enemy1.scnbin0 -> 3759 bytes
-rw-r--r--demos/2d/space_shooter/enemy2.gd56
-rw-r--r--demos/2d/space_shooter/enemy2.pngbin0 -> 5676 bytes
-rw-r--r--demos/2d/space_shooter/enemy2.scnbin0 -> 3801 bytes
-rw-r--r--demos/2d/space_shooter/enemy_shot.gd32
-rw-r--r--demos/2d/space_shooter/enemy_shot.pngbin0 -> 330 bytes
-rw-r--r--demos/2d/space_shooter/enemy_shot.scnbin0 -> 3944 bytes
-rw-r--r--demos/2d/space_shooter/engine.cfg22
-rw-r--r--demos/2d/space_shooter/explosion.scnbin0 -> 1497 bytes
-rw-r--r--demos/2d/space_shooter/fire.pngbin0 -> 357 bytes
-rw-r--r--demos/2d/space_shooter/game_state.gd24
-rw-r--r--demos/2d/space_shooter/icon.pngbin0 -> 6931 bytes
-rw-r--r--demos/2d/space_shooter/level.scnbin0 -> 9185 bytes
-rw-r--r--demos/2d/space_shooter/level_tiles.resbin0 -> 720 bytes
-rw-r--r--demos/2d/space_shooter/level_tiles.scnbin0 -> 2148 bytes
-rw-r--r--demos/2d/space_shooter/main_menu.gd20
-rw-r--r--demos/2d/space_shooter/main_menu.scnbin0 -> 2402 bytes
-rw-r--r--demos/2d/space_shooter/meteorite.pngbin0 -> 6072 bytes
-rw-r--r--demos/2d/space_shooter/parallax.scnbin0 -> 3307 bytes
-rw-r--r--demos/2d/space_shooter/rail.gd26
-rw-r--r--demos/2d/space_shooter/ship.gd88
-rw-r--r--demos/2d/space_shooter/ship.pngbin0 -> 2815 bytes
-rw-r--r--demos/2d/space_shooter/ship.scnbin0 -> 6752 bytes
-rw-r--r--demos/2d/space_shooter/shoot.pngbin0 -> 222 bytes
-rw-r--r--demos/2d/space_shooter/shot.gd47
-rw-r--r--demos/2d/space_shooter/shot.scnbin0 -> 3990 bytes
-rw-r--r--demos/2d/space_shooter/small_star.pngbin0 -> 90 bytes
-rw-r--r--demos/2d/space_shooter/sound_explode.wavbin0 -> 75832 bytes
-rw-r--r--demos/2d/space_shooter/sound_shoot.wavbin0 -> 78888 bytes
-rw-r--r--demos/2d/space_shooter/tile.pngbin0 -> 810 bytes
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp13
-rw-r--r--drivers/gles2/rasterizer_gles2.h3
-rw-r--r--main/main.cpp12
-rw-r--r--makerel.bat1
-rw-r--r--platform/x11/detect.py4
-rw-r--r--scene/2d/animated_sprite.cpp6
-rw-r--r--scene/2d/camera_2d.cpp68
-rw-r--r--scene/2d/camera_2d.h14
-rw-r--r--scene/2d/sprite.cpp10
-rw-r--r--scene/3d/area.cpp254
-rw-r--r--scene/3d/area.h38
-rw-r--r--scene/gui/control.cpp7
-rw-r--r--scene/gui/popup.cpp42
-rw-r--r--scene/gui/popup.h1
-rw-r--r--scene/gui/split_container.cpp3
-rw-r--r--scene/gui/tab_container.cpp120
-rw-r--r--scene/gui/tab_container.h11
-rw-r--r--scene/main/node.cpp2
-rw-r--r--scene/main/scene_main_loop.cpp6
-rw-r--r--scene/resources/default_theme/default_theme.cpp2
-rw-r--r--scene/resources/default_theme/tab_menu.pngbin0 -> 222 bytes
-rw-r--r--scene/resources/default_theme/tab_menu_hl.pngbin0 -> 226 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h10
-rw-r--r--servers/physics/area_pair_sw.cpp69
-rw-r--r--servers/physics/area_pair_sw.h18
-rw-r--r--servers/physics/area_sw.cpp69
-rw-r--r--servers/physics/area_sw.h37
-rw-r--r--servers/physics/physics_server_sw.cpp16
-rw-r--r--servers/physics/physics_server_sw.h3
-rw-r--r--servers/physics/space_sw.cpp15
-rw-r--r--servers/physics_server.h3
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/rasterizer_dummy.cpp2
-rw-r--r--servers/visual/rasterizer_dummy.h2
-rw-r--r--servers/visual/visual_server_raster.cpp9
-rw-r--r--tools/editor/create_dialog.cpp5
-rw-r--r--tools/editor/editor_node.cpp516
-rw-r--r--tools/editor/editor_node.h61
-rw-r--r--tools/editor/groups_editor.cpp3
-rw-r--r--tools/editor/icons/icon_back_disabled.pngbin0 -> 175 bytes
-rw-r--r--tools/editor/icons/icon_tab_menu.pngbin0 -> 251 bytes
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp46
-rw-r--r--tools/editor/property_editor.cpp1
-rw-r--r--tools/editor/reparent_dialog.cpp5
-rw-r--r--tools/editor/scene_tree_dock.cpp25
-rw-r--r--tools/editor/scene_tree_dock.h1
-rw-r--r--tools/editor/scene_tree_editor.cpp6
87 files changed, 1804 insertions, 168 deletions
diff --git a/bin/tests/test_gui.cpp b/bin/tests/test_gui.cpp
index 8822febdeb..c404623872 100644
--- a/bin/tests/test_gui.cpp
+++ b/bin/tests/test_gui.cpp
@@ -109,6 +109,9 @@ public:
frame->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
frame->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END );
frame->set_end( Point2(0,0) );
+
+ Ref<Theme> t = memnew( Theme );
+ frame->set_theme(t);
get_root()->add_child( frame );
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index 617e40e92a..1d9ac4e302 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -112,13 +112,6 @@ size_t Memory::get_dynamic_mem_usage() {
return MemoryPoolDynamic::get_singleton()->get_total_usage();
}
-void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_description) {
-
- void *failptr=0;
- ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */
-
- return p_pointer;
-}
diff --git a/core/os/memory.h b/core/os/memory.h
index 4497fcc200..0a35c93fdb 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -236,11 +236,11 @@ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_de
#endif
-_FORCE_INLINE_ void postinitialize_handler(void *) {}
+_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
template<class T>
-_FORCE_INLINE_ T *_post_initialize(T *p_obj) {
+_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
postinitialize_handler(p_obj);
return p_obj;
@@ -249,19 +249,26 @@ _FORCE_INLINE_ T *_post_initialize(T *p_obj) {
#ifdef DEBUG_MEMORY_ENABLED
#define memnew(m_class) _post_initialize(new(__FILE__":"__STR(__LINE__)", memnew type: "__STR(m_class)) m_class)
-#define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),__FILE__":"__STR(__LINE__)", type: "__STR(m_class)) m_class)
#else
#define memnew(m_class) _post_initialize(new("") m_class)
-#define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),"") m_class)
#endif
+_ALWAYS_INLINE_ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_description) {
+// void *failptr=0;
+// ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */
+
+ return p_pointer;
+}
+
+
#define memnew_allocator(m_class,m_allocator) _post_initialize(new(m_allocator::alloc) m_class)
+#define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),"") m_class)
-_FORCE_INLINE_ bool predelete_handler(void *) { return true; }
+_ALWAYS_INLINE_ bool predelete_handler(void *) { return true; }
template<class T>
void memdelete(T *p_class) {
diff --git a/core/reference.h b/core/reference.h
index 544da41044..65f31f78f3 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -294,6 +294,9 @@ public:
reference=NULL;
}
+ void instance() {
+ ref( memnew( T ));
+ }
Ref() {
diff --git a/demos/2d/space_shooter/asteroid.gd b/demos/2d/space_shooter/asteroid.gd
new file mode 100644
index 0000000000..f21b9777bb
--- /dev/null
+++ b/demos/2d/space_shooter/asteroid.gd
@@ -0,0 +1,49 @@
+
+extends Area2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+const SPEED=-200
+const Y_RANDOM=10
+
+var points=1
+
+
+var speed_y=0.0
+
+func _process(delta):
+
+ translate( Vector2(SPEED,speed_y) * delta )
+
+func _ready():
+ # Initialization here
+ speed_y=rand_range(-Y_RANDOM,Y_RANDOM)
+ pass
+
+var destroyed=false
+
+func destroy():
+ if (destroyed):
+ return
+ destroyed=true
+ get_node("anim").play("explode")
+ set_process(false)
+ get_node("sfx").play("sound_explode")
+ #accum points
+ get_node("/root/game_state").points+=1
+
+func is_enemy():
+ return not destroyed
+
+
+func _on_visibility_enter_screen():
+ set_process(true)
+ #make it spin!
+ get_node("anim").play("spin")
+
+
+func _on_visibility_exit_screen():
+ queue_free()
+ pass # replace with function body
diff --git a/demos/2d/space_shooter/asteroid.scn b/demos/2d/space_shooter/asteroid.scn
new file mode 100644
index 0000000000..b881725ea4
--- /dev/null
+++ b/demos/2d/space_shooter/asteroid.scn
Binary files differ
diff --git a/demos/2d/space_shooter/bg_gradient.png b/demos/2d/space_shooter/bg_gradient.png
new file mode 100644
index 0000000000..3e71976dc6
--- /dev/null
+++ b/demos/2d/space_shooter/bg_gradient.png
Binary files differ
diff --git a/demos/2d/space_shooter/big_star.png b/demos/2d/space_shooter/big_star.png
new file mode 100644
index 0000000000..7726a7aa12
--- /dev/null
+++ b/demos/2d/space_shooter/big_star.png
Binary files differ
diff --git a/demos/2d/space_shooter/enemy1.gd b/demos/2d/space_shooter/enemy1.gd
new file mode 100644
index 0000000000..051798742a
--- /dev/null
+++ b/demos/2d/space_shooter/enemy1.gd
@@ -0,0 +1,37 @@
+
+extends Area2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+const SPEED=-200
+
+func _process(delta):
+ get_parent().translate(Vector2(SPEED*delta,0))
+
+
+var destroyed=false
+
+func is_enemy():
+ return not destroyed
+
+
+func destroy():
+ if (destroyed):
+ return
+ destroyed=true
+ get_node("anim").play("explode")
+ set_process(false)
+ get_node("sfx").play("sound_explode")
+ #accum points
+ get_node("/root/game_state").points+=5
+
+func _on_visibility_enter_screen():
+ set_process(true)
+ get_node("anim").play("zigzag")
+ get_node("anim").seek(randf()*2.0) #make it start from any pos
+
+func _on_visibility_exit_screen():
+ queue_free()
+
diff --git a/demos/2d/space_shooter/enemy1.png b/demos/2d/space_shooter/enemy1.png
new file mode 100644
index 0000000000..242d8f0055
--- /dev/null
+++ b/demos/2d/space_shooter/enemy1.png
Binary files differ
diff --git a/demos/2d/space_shooter/enemy1.scn b/demos/2d/space_shooter/enemy1.scn
new file mode 100644
index 0000000000..14298f0a59
--- /dev/null
+++ b/demos/2d/space_shooter/enemy1.scn
Binary files differ
diff --git a/demos/2d/space_shooter/enemy2.gd b/demos/2d/space_shooter/enemy2.gd
new file mode 100644
index 0000000000..4f632a053d
--- /dev/null
+++ b/demos/2d/space_shooter/enemy2.gd
@@ -0,0 +1,56 @@
+
+extends Area2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+const SPEED=-220
+const SHOOT_INTERVAL=1
+var shoot_timeout=0
+
+func _process(delta):
+ translate( Vector2(SPEED*delta,0) )
+ shoot_timeout-=delta
+
+ if (shoot_timeout<0):
+
+ shoot_timeout=SHOOT_INTERVAL
+
+ #instance a shot
+ var shot = preload("res://enemy_shot.scn").instance()
+ #set pos as "shoot_from" Position2D node
+ shot.set_pos( get_node("shoot_from").get_global_pos() )
+ #add it to parent, so it has world coordinates
+ get_parent().add_child(shot)
+
+var destroyed=false
+
+func is_enemy():
+ return not destroyed
+
+func destroy():
+ if (destroyed):
+ return
+ destroyed=true
+ get_node("anim").play("explode")
+ set_process(false)
+ get_node("sfx").play("sound_explode")
+ #accum points
+ get_node("/root/game_state").points+=10
+
+func _ready():
+ set_fixed_process(true)
+ # Initialization here
+ pass
+
+
+
+
+func _on_visibility_enter_screen():
+ set_process(true)
+ pass # replace with function body
+
+
+func _on_visibility_exit_screen():
+ queue_free()
+ pass # replace with function body
diff --git a/demos/2d/space_shooter/enemy2.png b/demos/2d/space_shooter/enemy2.png
new file mode 100644
index 0000000000..5b63033696
--- /dev/null
+++ b/demos/2d/space_shooter/enemy2.png
Binary files differ
diff --git a/demos/2d/space_shooter/enemy2.scn b/demos/2d/space_shooter/enemy2.scn
new file mode 100644
index 0000000000..1d31f9c30e
--- /dev/null
+++ b/demos/2d/space_shooter/enemy2.scn
Binary files differ
diff --git a/demos/2d/space_shooter/enemy_shot.gd b/demos/2d/space_shooter/enemy_shot.gd
new file mode 100644
index 0000000000..238d24e4a2
--- /dev/null
+++ b/demos/2d/space_shooter/enemy_shot.gd
@@ -0,0 +1,32 @@
+
+extends Area2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+const SPEED = -800
+
+func _process(delta):
+ translate(Vector2(delta*SPEED,0))
+
+func _ready():
+ # Initialization here
+ set_process(true)
+
+
+var hit=false
+
+func is_enemy():
+ return true
+
+func _hit_something():
+ if (hit):
+ return
+ hit=true
+ set_process(false)
+ get_node("anim").play("splash")
+
+func _on_visibility_exit_screen():
+ queue_free()
+
diff --git a/demos/2d/space_shooter/enemy_shot.png b/demos/2d/space_shooter/enemy_shot.png
new file mode 100644
index 0000000000..04287211a9
--- /dev/null
+++ b/demos/2d/space_shooter/enemy_shot.png
Binary files differ
diff --git a/demos/2d/space_shooter/enemy_shot.scn b/demos/2d/space_shooter/enemy_shot.scn
new file mode 100644
index 0000000000..13f5ae89e5
--- /dev/null
+++ b/demos/2d/space_shooter/enemy_shot.scn
Binary files differ
diff --git a/demos/2d/space_shooter/engine.cfg b/demos/2d/space_shooter/engine.cfg
new file mode 100644
index 0000000000..8047cebdd3
--- /dev/null
+++ b/demos/2d/space_shooter/engine.cfg
@@ -0,0 +1,22 @@
+[application]
+
+name="Simple Shooter"
+main_scene="res://main_menu.scn"
+icon="res://icon.png"
+
+[autoload]
+
+game_state="res://game_state.gd"
+
+[display]
+
+width=1024
+height=600
+
+[input]
+
+move_up=[key(Up)]
+move_down=[key(Down)]
+move_left=[key(Left)]
+move_right=[key(Right)]
+shoot=[key(Space)]
diff --git a/demos/2d/space_shooter/explosion.scn b/demos/2d/space_shooter/explosion.scn
new file mode 100644
index 0000000000..4edcf709cb
--- /dev/null
+++ b/demos/2d/space_shooter/explosion.scn
Binary files differ
diff --git a/demos/2d/space_shooter/fire.png b/demos/2d/space_shooter/fire.png
new file mode 100644
index 0000000000..1c68c36213
--- /dev/null
+++ b/demos/2d/space_shooter/fire.png
Binary files differ
diff --git a/demos/2d/space_shooter/game_state.gd b/demos/2d/space_shooter/game_state.gd
new file mode 100644
index 0000000000..26ef086f14
--- /dev/null
+++ b/demos/2d/space_shooter/game_state.gd
@@ -0,0 +1,24 @@
+extends Node
+
+
+var points = 0
+var max_points = 0
+
+
+func _ready():
+ var f = File.new()
+ #load high score
+ if (f.open("user://highscore",File.READ)==OK):
+
+ max_points=f.get_var()
+
+
+
+func game_over():
+ if (points>max_points):
+ max_points=points
+ #save high score
+ var f = File.new()
+ f.open("user://highscore",File.WRITE)
+ f.store_var(max_points)
+ \ No newline at end of file
diff --git a/demos/2d/space_shooter/icon.png b/demos/2d/space_shooter/icon.png
new file mode 100644
index 0000000000..1df2bf5d9d
--- /dev/null
+++ b/demos/2d/space_shooter/icon.png
Binary files differ
diff --git a/demos/2d/space_shooter/level.scn b/demos/2d/space_shooter/level.scn
new file mode 100644
index 0000000000..12a679f8b6
--- /dev/null
+++ b/demos/2d/space_shooter/level.scn
Binary files differ
diff --git a/demos/2d/space_shooter/level_tiles.res b/demos/2d/space_shooter/level_tiles.res
new file mode 100644
index 0000000000..8712b8c799
--- /dev/null
+++ b/demos/2d/space_shooter/level_tiles.res
Binary files differ
diff --git a/demos/2d/space_shooter/level_tiles.scn b/demos/2d/space_shooter/level_tiles.scn
new file mode 100644
index 0000000000..3fb91d8cb3
--- /dev/null
+++ b/demos/2d/space_shooter/level_tiles.scn
Binary files differ
diff --git a/demos/2d/space_shooter/main_menu.gd b/demos/2d/space_shooter/main_menu.gd
new file mode 100644
index 0000000000..52221aba1b
--- /dev/null
+++ b/demos/2d/space_shooter/main_menu.gd
@@ -0,0 +1,20 @@
+
+extends Control
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+func _ready():
+
+ get_node("score").set_text( "HIGH SCORE: "+str( get_node("/root/game_state").max_points ) )
+ # Initialization here
+ pass
+
+
+
+
+func _on_play_pressed():
+ get_node("/root/game_state").points=0
+ get_tree().change_scene("res://level.scn")
+ pass # replace with function body
diff --git a/demos/2d/space_shooter/main_menu.scn b/demos/2d/space_shooter/main_menu.scn
new file mode 100644
index 0000000000..b87cc5d3a8
--- /dev/null
+++ b/demos/2d/space_shooter/main_menu.scn
Binary files differ
diff --git a/demos/2d/space_shooter/meteorite.png b/demos/2d/space_shooter/meteorite.png
new file mode 100644
index 0000000000..92fb4387df
--- /dev/null
+++ b/demos/2d/space_shooter/meteorite.png
Binary files differ
diff --git a/demos/2d/space_shooter/parallax.scn b/demos/2d/space_shooter/parallax.scn
new file mode 100644
index 0000000000..f67277dc01
--- /dev/null
+++ b/demos/2d/space_shooter/parallax.scn
Binary files differ
diff --git a/demos/2d/space_shooter/rail.gd b/demos/2d/space_shooter/rail.gd
new file mode 100644
index 0000000000..803a09fe84
--- /dev/null
+++ b/demos/2d/space_shooter/rail.gd
@@ -0,0 +1,26 @@
+
+extends Node2D
+
+
+const SPEED=200
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+func stop():
+ set_process(false)
+
+var offset=0
+
+
+func _process(delta):
+
+ offset+=delta*SPEED
+ set_pos(Vector2(offset,0))
+
+func _ready():
+ set_process(true)
+ # Initialization here
+
+
+
diff --git a/demos/2d/space_shooter/ship.gd b/demos/2d/space_shooter/ship.gd
new file mode 100644
index 0000000000..fa444868a4
--- /dev/null
+++ b/demos/2d/space_shooter/ship.gd
@@ -0,0 +1,88 @@
+
+extends Area2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+const SPEED = 200
+
+var screen_size
+
+var prev_shooting=false
+
+func _process(delta):
+
+ var motion = Vector2()
+ if Input.is_action_pressed("move_up"):
+ motion+=Vector2(0,-1)
+ if Input.is_action_pressed("move_down"):
+ motion+=Vector2(0,1)
+ if Input.is_action_pressed("move_left"):
+ motion+=Vector2(-1,0)
+ if Input.is_action_pressed("move_right"):
+ motion+=Vector2(1,0)
+ var shooting = Input.is_action_pressed("shoot")
+
+ var pos = get_pos()
+
+ pos+=motion*delta*SPEED
+ if (pos.x<0):
+ pos.x=0
+ if (pos.x>screen_size.x):
+ pos.x=screen_size.x
+ if (pos.y<0):
+ pos.y=0
+ if (pos.y>screen_size.y):
+ pos.y=screen_size.y
+
+ set_pos(pos)
+
+ if (shooting and not prev_shooting):
+ # just pressed
+ var shot = preload("res://shot.scn").instance()
+ #use the position3d as reference
+ shot.set_pos( get_node("shootfrom").get_global_pos() )
+ #put it two parents above, so it is not moved by us
+ get_node("../..").add_child(shot)
+ #play sound
+ get_node("sfx").play("shoot")
+
+
+ prev_shooting = shooting
+
+ #update points counter
+ get_node("../hud/score_points").set_text( str(get_node("/root/game_state").points) )
+
+func _ready():
+ # Initialization here
+ screen_size = get_viewport().get_rect().size
+ set_process(true)
+ pass
+
+var killed=false
+
+func _hit_something():
+ if (killed):
+ return
+ killed=true
+ get_node("anim").play("explode")
+ get_node("sfx").play("sound_explode")
+ get_node("../hud/game_over").show()
+ get_node("/root/game_state").game_over()
+ get_parent().stop()
+ set_process(false)
+
+
+func _on_ship_body_enter( body ):
+ _hit_something()
+
+
+func _on_ship_area_enter( area ):
+ if (area.has_method("is_enemy") and area.is_enemy()):
+ _hit_something()
+
+
+func _on_back_to_menu_pressed():
+ get_tree().change_scene("res://main_menu.scn")
+ pass # replace with function body
diff --git a/demos/2d/space_shooter/ship.png b/demos/2d/space_shooter/ship.png
new file mode 100644
index 0000000000..a36b833903
--- /dev/null
+++ b/demos/2d/space_shooter/ship.png
Binary files differ
diff --git a/demos/2d/space_shooter/ship.scn b/demos/2d/space_shooter/ship.scn
new file mode 100644
index 0000000000..82c710eda7
--- /dev/null
+++ b/demos/2d/space_shooter/ship.scn
Binary files differ
diff --git a/demos/2d/space_shooter/shoot.png b/demos/2d/space_shooter/shoot.png
new file mode 100644
index 0000000000..6e80ddab93
--- /dev/null
+++ b/demos/2d/space_shooter/shoot.png
Binary files differ
diff --git a/demos/2d/space_shooter/shot.gd b/demos/2d/space_shooter/shot.gd
new file mode 100644
index 0000000000..813587d670
--- /dev/null
+++ b/demos/2d/space_shooter/shot.gd
@@ -0,0 +1,47 @@
+
+extends Area2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+const SPEED = 800
+
+func _process(delta):
+ translate(Vector2(delta*SPEED,0))
+
+func _ready():
+ # Initialization here
+ set_process(true)
+ pass
+
+var hit=false
+
+func _hit_something():
+ if (hit):
+ return
+ hit=true
+ set_process(false)
+ get_node("anim").play("splash")
+
+func _on_visibility_exit_screen():
+ queue_free()
+ pass # replace with function body
+
+
+
+func _on_shot_area_enter( area ):
+ #hit an enemy or asteroid
+ if (area.has_method("destroy")):
+ #duck typing at it's best
+ area.destroy()
+ _hit_something()
+
+
+ pass
+
+
+func _on_shot_body_enter( body ):
+ #hit the tilemap
+ _hit_something()
+ pass # replace with function body
diff --git a/demos/2d/space_shooter/shot.scn b/demos/2d/space_shooter/shot.scn
new file mode 100644
index 0000000000..64c8c25ebe
--- /dev/null
+++ b/demos/2d/space_shooter/shot.scn
Binary files differ
diff --git a/demos/2d/space_shooter/small_star.png b/demos/2d/space_shooter/small_star.png
new file mode 100644
index 0000000000..71c3c531cd
--- /dev/null
+++ b/demos/2d/space_shooter/small_star.png
Binary files differ
diff --git a/demos/2d/space_shooter/sound_explode.wav b/demos/2d/space_shooter/sound_explode.wav
new file mode 100644
index 0000000000..229c85399c
--- /dev/null
+++ b/demos/2d/space_shooter/sound_explode.wav
Binary files differ
diff --git a/demos/2d/space_shooter/sound_shoot.wav b/demos/2d/space_shooter/sound_shoot.wav
new file mode 100644
index 0000000000..ad74f328cb
--- /dev/null
+++ b/demos/2d/space_shooter/sound_shoot.wav
Binary files differ
diff --git a/demos/2d/space_shooter/tile.png b/demos/2d/space_shooter/tile.png
new file mode 100644
index 0000000000..d8f41d16f6
--- /dev/null
+++ b/demos/2d/space_shooter/tile.png
Binary files differ
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index a588643fd9..efc92c5d9f 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -4394,7 +4394,7 @@ void RasterizerGLES2::begin_shadow_map( RID p_light_instance, int p_shadow_pass
}
-void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection) {
+void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint) {
camera_transform=p_world;
if (current_rt && current_rt_vflip) {
@@ -4402,10 +4402,11 @@ void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_
}
camera_transform_inverse=camera_transform.inverse();
camera_projection=p_projection;
- camera_plane = Plane( camera_transform.origin, camera_transform.basis.get_axis(2) );
+ camera_plane = Plane( camera_transform.origin, -camera_transform.basis.get_axis(2) );
camera_z_near=camera_projection.get_z_near();
camera_z_far=camera_projection.get_z_far();
camera_projection.get_viewport_size(camera_vp_size.x,camera_vp_size.y);
+ camera_ortho=p_ortho_hint;
}
void RasterizerGLES2::add_light( RID p_light_instance ) {
@@ -4768,8 +4769,11 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD
e->geometry_cmp=p_geometry_cmp;
e->material=m;
e->instance=p_instance;
- //e->depth=camera_plane.distance_to(p_world->origin);
- e->depth=camera_transform.origin.distance_to(p_instance->transform.origin);
+ if (camera_ortho) {
+ e->depth=camera_plane.distance_to(p_instance->transform.origin);
+ } else {
+ e->depth=camera_transform.origin.distance_to(p_instance->transform.origin);
+ }
e->owner=p_owner;
e->light_type=0;
e->additive=false;
@@ -10796,6 +10800,7 @@ void RasterizerGLES2::init() {
current_rt=NULL;
current_vd=NULL;
current_debug=VS::SCENARIO_DEBUG_DISABLED;
+ camera_ortho=false;
glGenBuffers(1,&gui_quad_buffer);
glBindBuffer(GL_ARRAY_BUFFER,gui_quad_buffer);
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index e83bd39caa..d337ecfb64 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -1052,6 +1052,7 @@ class RasterizerGLES2 : public Rasterizer {
float camera_z_near;
float camera_z_far;
Size2 camera_vp_size;
+ bool camera_ortho;
Set<String> extensions;
bool texscreen_copied;
bool texscreen_used;
@@ -1589,7 +1590,7 @@ public:
virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass );
- virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection);
+ virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint);
virtual void add_light( RID p_light_instance ); ///< all "add_light" calls happen before add_geometry calls
diff --git a/main/main.cpp b/main/main.cpp
index a00538a6ae..15f969f466 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -98,6 +98,9 @@ static int video_driver_idx=-1;
static int audio_driver_idx=-1;
static String locale;
+static bool init_maximized=false;
+static int init_screen=-1;
+
static String unescape_cmdline(const String& p_str) {
return p_str.replace("%20"," ");
@@ -384,7 +387,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
} else if (I->get()=="-e" || I->get()=="-editor") { // fonud editor
editor=true;
-
+ init_maximized=true;
} else if (I->get()=="-nowindow") { // fullscreen
OS::get_singleton()->set_no_window_mode(true);
@@ -789,6 +792,13 @@ Error Main::setup2() {
show_logo=false;
#endif
+ if (init_screen!=-1) {
+ OS::get_singleton()->set_current_screen(init_screen);
+ }
+ if (init_maximized) {
+ OS::get_singleton()->set_window_maximized(true);
+ }
+
if (show_logo) { //boot logo!
String boot_logo_path=GLOBAL_DEF("application/boot_splash",String());
bool boot_logo_scale=GLOBAL_DEF("application/boot_splash_fullsize",true);
diff --git a/makerel.bat b/makerel.bat
new file mode 100644
index 0000000000..7db76e1dd7
--- /dev/null
+++ b/makerel.bat
@@ -0,0 +1 @@
+"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" && c:\python27\scons p=windows target=debug_release tools=no
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 85714c46bb..ff85e286db 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -111,9 +111,9 @@ def configure(env):
if (env["target"]=="release"):
if (env["debug_release"]=="yes"):
- env.Append(CCFLAGS=['-g2','-fomit-frame-pointer'])
+ env.Append(CCFLAGS=['-g2'])
else:
- env.Append(CCFLAGS=['-O2','-ffast-math','-fomit-frame-pointer'])
+ env.Append(CCFLAGS=['-O3','-ffast-math'])
elif (env["target"]=="release_debug"):
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index b49426f7e2..e350a34013 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -149,11 +149,11 @@ void AnimatedSprite::_notification(int p_what) {
Size2i s;
s = texture->get_size();
- Point2i ofs=offset;
+ Point2 ofs=offset;
if (centered)
ofs-=s/2;
- Rect2i dst_rect(ofs,s);
+ Rect2 dst_rect(ofs,s);
if (hflip)
dst_rect.size.x=-dst_rect.size.x;
@@ -284,7 +284,7 @@ Rect2 AnimatedSprite::get_item_rect() const {
return Node2D::get_item_rect();
Size2i s = t->get_size();
- Point2i ofs=offset;
+ Point2 ofs=offset;
if (centered)
ofs-=s/2;
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 70b88a6611..49683da226 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -81,43 +81,47 @@ Matrix32 Camera2D::get_camera_transform() {
if (!first) {
- if (centered) {
+ if (anchor_mode==ANCHOR_MODE_DRAG_CENTER) {
- if (h_drag_enabled) {
- camera_pos.x = MIN( camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT]));
- camera_pos.x = MAX( camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * drag_margin[MARGIN_LEFT]));
- } else {
+ if (h_drag_enabled) {
+ camera_pos.x = MIN( camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT]));
+ camera_pos.x = MAX( camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * drag_margin[MARGIN_LEFT]));
+ } else {
- if (h_ofs<0) {
- camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs;
- } else {
- camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs;
- }
- }
+ if (h_ofs<0) {
+ camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs;
+ } else {
+ camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs;
+ }
+ }
+
+ if (v_drag_enabled) {
- if (v_drag_enabled) {
+ camera_pos.y = MIN( camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM]));
+ camera_pos.y = MAX( camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * drag_margin[MARGIN_TOP]));
- camera_pos.y = MIN( camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM]));
- camera_pos.y = MAX( camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * drag_margin[MARGIN_TOP]));
+ } else {
- } else {
+ if (v_ofs<0) {
+ camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs;
+ } else {
+ camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs;
+ }
+ }
- if (v_ofs<0) {
- camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs;
- } else {
- camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs;
- }
- }
+ } else if (anchor_mode==ANCHOR_MODE_FIXED_TOP_LEFT){
+ camera_pos=new_camera_pos;
}
+
if (smoothing>0.0) {
float c = smoothing*get_fixed_process_delta_time();
smoothed_camera_pos = ((new_camera_pos-smoothed_camera_pos)*c)+smoothed_camera_pos;
ret_camera_pos=smoothed_camera_pos;
-// camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing;
+ // camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing;
} else {
ret_camera_pos=smoothed_camera_pos=camera_pos;
@@ -132,7 +136,7 @@ Matrix32 Camera2D::get_camera_transform() {
}
- Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());
+ Point2 screen_offset = (anchor_mode==ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2());
float angle = get_global_transform().get_rotation();
if(rotating){
@@ -267,15 +271,15 @@ Vector2 Camera2D::get_offset() const{
return offset;
}
-void Camera2D::set_centered(bool p_centered){
+void Camera2D::set_anchor_mode(AnchorMode p_anchor_mode){
- centered=p_centered;
+ anchor_mode=p_anchor_mode;
_update_scroll();
}
-bool Camera2D::is_centered() const {
+Camera2D::AnchorMode Camera2D::get_anchor_mode() const {
- return centered;
+ return anchor_mode;
}
void Camera2D::set_rotating(bool p_rotating){
@@ -439,8 +443,8 @@ void Camera2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_offset","offset"),&Camera2D::set_offset);
ObjectTypeDB::bind_method(_MD("get_offset"),&Camera2D::get_offset);
- ObjectTypeDB::bind_method(_MD("set_centered","centered"),&Camera2D::set_centered);
- ObjectTypeDB::bind_method(_MD("is_centered"),&Camera2D::is_centered);
+ ObjectTypeDB::bind_method(_MD("set_anchor_mode","anchor_mode"),&Camera2D::set_anchor_mode);
+ ObjectTypeDB::bind_method(_MD("get_anchor_mode"),&Camera2D::get_anchor_mode);
ObjectTypeDB::bind_method(_MD("set_rotating","rotating"),&Camera2D::set_rotating);
ObjectTypeDB::bind_method(_MD("is_rotating"),&Camera2D::is_rotating);
@@ -487,7 +491,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_offset"),_SCS("get_offset"));
- ADD_PROPERTY( PropertyInfo(Variant::BOOL,"centered"),_SCS("set_centered"),_SCS("is_centered"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"anchor_mode",PROPERTY_HINT_ENUM,"Fixed TopLeft,Drag Center"),_SCS("set_anchor_mode"),_SCS("get_anchor_mode"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"rotating"),_SCS("set_rotating"),_SCS("is_rotating"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"current"),_SCS("_set_current"),_SCS("is_current"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"smoothing"),_SCS("set_follow_smoothing"),_SCS("get_follow_smoothing") );
@@ -507,6 +511,8 @@ void Camera2D::_bind_methods() {
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"drag_margin/bottom",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_drag_margin"),_SCS("get_drag_margin"),MARGIN_BOTTOM);
+ BIND_CONSTANT( ANCHOR_MODE_DRAG_CENTER );
+ BIND_CONSTANT( ANCHOR_MODE_FIXED_TOP_LEFT );
}
@@ -514,7 +520,7 @@ Camera2D::Camera2D() {
- centered=true;
+ anchor_mode=ANCHOR_MODE_DRAG_CENTER;
rotating=false;
current=false;
limit[MARGIN_LEFT]=-10000000;
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 8975a2584b..79d84f48d0 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -36,6 +36,12 @@
class Camera2D : public Node2D {
OBJ_TYPE( Camera2D, Node2D );
+public:
+
+ enum AnchorMode {
+ ANCHOR_MODE_FIXED_TOP_LEFT,
+ ANCHOR_MODE_DRAG_CENTER
+ };
protected:
Point2 camera_pos;
@@ -49,7 +55,7 @@ protected:
RID canvas;
Vector2 offset;
Vector2 zoom;
- bool centered;
+ AnchorMode anchor_mode;
bool rotating;
bool current;
float smoothing;
@@ -77,8 +83,8 @@ public:
void set_offset(const Vector2& p_offset);
Vector2 get_offset() const;
- void set_centered(bool p_centered);
- bool is_centered() const;
+ void set_anchor_mode(AnchorMode p_anchor_mode);
+ AnchorMode get_anchor_mode() const;
void set_rotating(bool p_rotating);
bool is_rotating() const;
@@ -120,4 +126,6 @@ public:
Camera2D();
};
+VARIANT_ENUM_CAST(Camera2D::AnchorMode);
+
#endif // CAMERA_2D_H
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index 067b4794b4..0485033691 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -82,7 +82,7 @@ void Sprite::_notification(int p_what) {
}
- Point2i ofs=offset;
+ Point2 ofs=offset;
if (centered)
ofs-=s/2;
@@ -265,7 +265,7 @@ Rect2 Sprite::get_item_rect() const {
s=s/Point2(hframes,vframes);
}
- Point2i ofs=offset;
+ Point2 ofs=offset;
if (centered)
ofs-=s/2;
@@ -413,11 +413,11 @@ void ViewportSprite::_notification(int p_what) {
src_rect.size=s;
- Point2i ofs=offset;
+ Point2 ofs=offset;
if (centered)
ofs-=s/2;
- Rect2i dst_rect(ofs,s);
+ Rect2 dst_rect(ofs,s);
texture->draw_rect_region(ci,dst_rect,src_rect,modulate);
} break;
@@ -505,7 +505,7 @@ Rect2 ViewportSprite::get_item_rect() const {
Size2i s;
s = texture->get_size();
- Point2i ofs=offset;
+ Point2 ofs=offset;
if (centered)
ofs-=s/2;
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 76527c72e6..a00946a07a 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -225,27 +225,56 @@ void Area::_clear_monitoring() {
}
ERR_FAIL_COND(locked);
- Map<ObjectID,BodyState> bmcopy = body_map;
- body_map.clear();
- //disconnect all monitored stuff
+ {
+ Map<ObjectID,BodyState> bmcopy = body_map;
+ body_map.clear();
+ //disconnect all monitored stuff
- for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) {
+ for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
- Node *node = obj ? obj->cast_to<Node>() : NULL;
- ERR_CONTINUE(!node);
- if (!E->get().in_tree)
- continue;
+ Object *obj = ObjectDB::get_instance(E->key());
+ Node *node = obj ? obj->cast_to<Node>() : NULL;
+ ERR_CONTINUE(!node);
+ if (!E->get().in_tree)
+ continue;
+
+ for(int i=0;i<E->get().shapes.size();i++) {
- for(int i=0;i<E->get().shapes.size();i++) {
+ emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape);
+ }
- emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape);
+ emit_signal(SceneStringNames::get_singleton()->body_exit,obj);
+
+ node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree);
+ node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree);
}
- emit_signal(SceneStringNames::get_singleton()->body_exit,obj);
+ }
+
+ {
+
+ Map<ObjectID,AreaState> bmcopy = area_map;
+ area_map.clear();
+ //disconnect all monitored stuff
+
+ for (Map<ObjectID,AreaState>::Element *E=bmcopy.front();E;E=E->next()) {
+
+ Object *obj = ObjectDB::get_instance(E->key());
+ Node *node = obj ? obj->cast_to<Node>() : NULL;
+ ERR_CONTINUE(!node);
+ if (!E->get().in_tree)
+ continue;
+
+ for(int i=0;i<E->get().shapes.size();i++) {
- node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree);
- node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree);
+ emit_signal(SceneStringNames::get_singleton()->area_exit_shape,E->key(),node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape);
+ }
+
+ emit_signal(SceneStringNames::get_singleton()->area_exit,obj);
+
+ node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree);
+ node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree);
+ }
}
}
@@ -271,10 +300,127 @@ void Area::set_enable_monitoring(bool p_enable) {
if (monitoring) {
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),this,"_body_inout");
+ PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,"_area_inout");
} else {
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),NULL,StringName());
+ PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),NULL,StringName());
_clear_monitoring();
+
+ }
+}
+
+
+void Area::_area_enter_tree(ObjectID p_id) {
+
+ Object *obj = ObjectDB::get_instance(p_id);
+ Node *node = obj ? obj->cast_to<Node>() : NULL;
+ ERR_FAIL_COND(!node);
+
+ Map<ObjectID,AreaState>::Element *E=area_map.find(p_id);
+ ERR_FAIL_COND(!E);
+ ERR_FAIL_COND(E->get().in_tree);
+
+ E->get().in_tree=true;
+ emit_signal(SceneStringNames::get_singleton()->area_enter,node);
+ for(int i=0;i<E->get().shapes.size();i++) {
+
+ emit_signal(SceneStringNames::get_singleton()->area_enter_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape);
+ }
+
+}
+
+void Area::_area_exit_tree(ObjectID p_id) {
+
+ Object *obj = ObjectDB::get_instance(p_id);
+ Node *node = obj ? obj->cast_to<Node>() : NULL;
+ ERR_FAIL_COND(!node);
+ Map<ObjectID,AreaState>::Element *E=area_map.find(p_id);
+ ERR_FAIL_COND(!E);
+ ERR_FAIL_COND(!E->get().in_tree);
+ E->get().in_tree=false;
+ emit_signal(SceneStringNames::get_singleton()->area_exit,node);
+ for(int i=0;i<E->get().shapes.size();i++) {
+
+ emit_signal(SceneStringNames::get_singleton()->area_exit_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape);
}
+
+}
+
+void Area::_area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape) {
+
+
+ bool area_in = p_status==PhysicsServer::AREA_BODY_ADDED;
+ ObjectID objid=p_instance;
+
+ Object *obj = ObjectDB::get_instance(objid);
+ Node *node = obj ? obj->cast_to<Node>() : NULL;
+
+ Map<ObjectID,AreaState>::Element *E=area_map.find(objid);
+
+ ERR_FAIL_COND(!area_in && !E);
+
+ locked=true;
+
+ if (area_in) {
+ if (!E) {
+
+ E = area_map.insert(objid,AreaState());
+ E->get().rc=0;
+ E->get().in_tree=node && node->is_inside_tree();
+ if (node) {
+ node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree,make_binds(objid));
+ node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree,make_binds(objid));
+ if (E->get().in_tree) {
+ emit_signal(SceneStringNames::get_singleton()->area_enter,node);
+
+ }
+ }
+
+ }
+ E->get().rc++;
+ if (node)
+ E->get().shapes.insert(AreaShapePair(p_area_shape,p_self_shape));
+
+
+ if (!node || E->get().in_tree) {
+ emit_signal(SceneStringNames::get_singleton()->area_enter_shape,objid,node,p_area_shape,p_self_shape);
+ }
+
+ } else {
+
+ E->get().rc--;
+
+ if (node)
+ E->get().shapes.erase(AreaShapePair(p_area_shape,p_self_shape));
+
+ bool eraseit=false;
+
+ if (E->get().rc==0) {
+
+ if (node) {
+ node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree);
+ node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree);
+ if (E->get().in_tree) {
+ emit_signal(SceneStringNames::get_singleton()->area_exit,obj);
+ }
+
+ }
+
+ eraseit=true;
+
+ }
+ if (!node || E->get().in_tree) {
+ emit_signal(SceneStringNames::get_singleton()->area_exit_shape,objid,obj,p_area_shape,p_self_shape);
+ }
+
+ if (eraseit)
+ area_map.erase(E);
+
+ }
+
+ locked=false;
+
+
}
bool Area::is_monitoring_enabled() const {
@@ -302,11 +448,76 @@ Array Area::get_overlapping_bodies() const {
return ret;
}
+void Area::set_monitorable(bool p_enable) {
+
+ if (locked) {
+ ERR_EXPLAIN("This function can't be used during the in/out signal.");
+ }
+ ERR_FAIL_COND(locked);
+
+ if (p_enable==monitorable)
+ return;
+
+ monitorable=p_enable;
+
+ PhysicsServer::get_singleton()->area_set_monitorable(get_rid(),monitorable);
+}
+
+bool Area::is_monitorable() const {
+
+ return monitorable;
+}
+
+
+Array Area::get_overlapping_areas() const {
+
+ ERR_FAIL_COND_V(!monitoring,Array());
+ Array ret;
+ ret.resize(area_map.size());
+ int idx=0;
+ for (const Map<ObjectID,AreaState>::Element *E=area_map.front();E;E=E->next()) {
+ Object *obj = ObjectDB::get_instance(E->key());
+ if (!obj) {
+ ret.resize( ret.size() -1 ); //ops
+ } else {
+ ret[idx++]=obj;
+ }
+
+ }
+
+ return ret;
+}
+
+bool Area::overlaps_area(Node* p_area) const {
+
+ ERR_FAIL_NULL_V(p_area,false);
+ const Map<ObjectID,AreaState>::Element *E=area_map.find(p_area->get_instance_ID());
+ if (!E)
+ return false;
+ return E->get().in_tree;
+
+
+
+}
+
+bool Area::overlaps_body(Node* p_body) const{
+
+ ERR_FAIL_NULL_V(p_body,false);
+ const Map<ObjectID,BodyState>::Element *E=body_map.find(p_body->get_instance_ID());
+ if (!E)
+ return false;
+ return E->get().in_tree;
+
+}
+
void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_body_enter_tree","id"),&Area::_body_enter_tree);
ObjectTypeDB::bind_method(_MD("_body_exit_tree","id"),&Area::_body_exit_tree);
+ ObjectTypeDB::bind_method(_MD("_area_enter_tree","id"),&Area::_area_enter_tree);
+ ObjectTypeDB::bind_method(_MD("_area_exit_tree","id"),&Area::_area_exit_tree);
+
ObjectTypeDB::bind_method(_MD("set_space_override_mode","enable"),&Area::set_space_override_mode);
ObjectTypeDB::bind_method(_MD("get_space_override_mode"),&Area::get_space_override_mode);
@@ -328,13 +539,21 @@ void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
+ ObjectTypeDB::bind_method(_MD("set_monitorable","enable"),&Area::set_monitorable);
+ ObjectTypeDB::bind_method(_MD("is_monitorable"),&Area::is_monitorable);
+
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area::set_enable_monitoring);
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area::is_monitoring_enabled);
ObjectTypeDB::bind_method(_MD("get_overlapping_bodies"),&Area::get_overlapping_bodies);
+ ObjectTypeDB::bind_method(_MD("get_overlapping_areas"),&Area::get_overlapping_areas);
+
+ ObjectTypeDB::bind_method(_MD("overlaps_body:PhysicsBody","body"),&Area::overlaps_body);
+ ObjectTypeDB::bind_method(_MD("overlaps_area:Area","area"),&Area::overlaps_area);
ObjectTypeDB::bind_method(_MD("_body_inout"),&Area::_body_inout);
+ ObjectTypeDB::bind_method(_MD("_area_inout"),&Area::_area_inout);
ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape")));
@@ -342,6 +561,11 @@ void Area::_bind_methods() {
ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body")));
ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body")));
+ ADD_SIGNAL( MethodInfo("area_enter_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"area_shape")));
+ ADD_SIGNAL( MethodInfo("area_exit_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"area_shape")));
+ ADD_SIGNAL( MethodInfo("area_enter",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area")));
+ ADD_SIGNAL( MethodInfo("area_exit",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area")));
+
ADD_PROPERTY( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
@@ -350,6 +574,7 @@ void Area::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
}
@@ -366,6 +591,7 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
monitoring=false;
set_ray_pickable(false);
set_enable_monitoring(true);
+ set_monitorable(true);
}
diff --git a/scene/3d/area.h b/scene/3d/area.h
index fb853092f3..fa7500c47c 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -53,6 +53,7 @@ private:
real_t density;
int priority;
bool monitoring;
+ bool monitorable;
bool locked;
@@ -84,6 +85,36 @@ private:
};
Map<ObjectID,BodyState> body_map;
+
+
+ void _area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape);
+
+ void _area_enter_tree(ObjectID p_id);
+ void _area_exit_tree(ObjectID p_id);
+
+ struct AreaShapePair {
+
+ int area_shape;
+ int self_shape;
+ bool operator<(const AreaShapePair& p_sp) const {
+ if (area_shape==p_sp.area_shape)
+ return self_shape < p_sp.self_shape;
+ else
+ return area_shape < p_sp.area_shape;
+ }
+
+ AreaShapePair() {}
+ AreaShapePair(int p_bs, int p_as) { area_shape=p_bs; self_shape=p_as; }
+ };
+
+ struct AreaState {
+
+ int rc;
+ bool in_tree;
+ VSet<AreaShapePair> shapes;
+ };
+
+ Map<ObjectID,AreaState> area_map;
void _clear_monitoring();
@@ -117,7 +148,14 @@ public:
void set_enable_monitoring(bool p_enable);
bool is_monitoring_enabled() const;
+ void set_monitorable(bool p_enable);
+ bool is_monitorable() const;
+
Array get_overlapping_bodies() const;
+ Array get_overlapping_areas() const; //function for script
+
+ bool overlaps_area(Node* p_area) const;
+ bool overlaps_body(Node* p_body) const;
Area();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 22559c238c..2367c03e99 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -548,15 +548,18 @@ void Control::_notification(int p_notification) {
Control * parent = get_parent()->cast_to<Control>();
//make children reference them theme
- if (parent && data.theme.is_null() && parent->data.theme_owner)
+
+ if (parent && data.theme.is_null() && parent->data.theme_owner) {
_propagate_theme_changed(parent->data.theme_owner);
+ }
} break;
case NOTIFICATION_UNPARENTED: {
//make children unreference the theme
- if (data.theme.is_null() && data.theme_owner)
+ if (data.theme.is_null() && data.theme_owner) {
_propagate_theme_changed(NULL);
+ }
} break;
case NOTIFICATION_MOVED_IN_PARENT: {
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index c73af74426..5ce7e2e0d3 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -84,6 +84,48 @@ void Popup::_fix_size() {
}
+void Popup::set_as_minsize() {
+
+ Size2 total_minsize;
+
+ for(int i=0;i<get_child_count();i++) {
+
+ Control *c=get_child(i)->cast_to<Control>();
+ if (!c)
+ continue;
+ if (c->is_hidden())
+ continue;
+
+ Size2 minsize = c->get_combined_minimum_size();
+
+ for(int j=0;j<2;j++) {
+
+ Margin m_beg = Margin(0+j);
+ Margin m_end = Margin(2+j);
+
+ float margin_begin = c->get_margin(m_beg);
+ float margin_end = c->get_margin(m_end);
+ AnchorType anchor_begin = c->get_anchor(m_beg);
+ AnchorType anchor_end = c->get_anchor(m_end);
+
+ if (anchor_begin == ANCHOR_BEGIN)
+ minsize[j]+=margin_begin;
+ if (anchor_end == ANCHOR_END)
+ minsize[j]+=margin_end;
+
+ }
+
+ print_line(String(c->get_type())+": "+minsize);
+
+ total_minsize.width = MAX( total_minsize.width, minsize.width );
+ total_minsize.height = MAX( total_minsize.height, minsize.height );
+ }
+
+ set_size(total_minsize);
+
+}
+
+
void Popup::popup_centered_minsize(const Size2& p_minsize) {
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index c2de6c8cf7..6c72a3c82b 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -62,6 +62,7 @@ public:
void popup_centered_ratio(float p_screen_ratio=0.75);
void popup_centered(const Size2& p_size=Size2());
void popup_centered_minsize(const Size2& p_minsize=Size2());
+ void set_as_minsize();
virtual void popup();
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index d02c833be9..d7ee7a6b86 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -345,6 +345,7 @@ void SplitContainer::_input_event(const InputEvent& p_event) {
expand_ofs=drag_ofs+((vertical?mm.y:mm.x)-drag_from);
queue_sort();
+ emit_signal("dragged",get_split_offset());
}
}
@@ -431,11 +432,13 @@ void SplitContainer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_dragger_visible","visible"),&SplitContainer::set_dragger_visible);
ObjectTypeDB::bind_method(_MD("is_dragger_visible"),&SplitContainer::is_dragger_visible);
+ ADD_SIGNAL( MethodInfo("dragged",PropertyInfo(Variant::INT,"offset")));
ADD_PROPERTY( PropertyInfo(Variant::INT,"split/offset"),_SCS("set_split_offset"),_SCS("get_split_offset"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"split/collapsed"),_SCS("set_collapsed"),_SCS("is_collapsed"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"split/dragger_visible"),_SCS("set_dragger_visible"),_SCS("is_dragger_visible"));
+
}
SplitContainer::SplitContainer(bool p_vertical) {
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 1db4998a27..3ed182c017 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -88,7 +88,22 @@ void TabContainer::_input_event(const InputEvent& p_event) {
Ref<Font> font = get_font("font");
Ref<Texture> incr = get_icon("increment");
Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture> menu = get_icon("menu");
+ Ref<Texture> menu_hl = get_icon("menu_hl");
+ if (popup && pos.x>get_size().width-menu->get_width()) {
+
+
+ emit_signal("pre_popup_pressed");
+ Vector2 pp_pos = get_global_pos();
+ pp_pos.x+=get_size().width;
+ pp_pos.x-=popup->get_size().width;
+ pp_pos.y+=menu->get_height();
+
+ popup->set_global_pos( pp_pos );
+ popup->popup();;
+ return;
+ }
pos.x-=tabs_ofs_cache;
int idx=0;
@@ -116,17 +131,17 @@ void TabContainer::_input_event(const InputEvent& p_event) {
String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name());
int tab_width=font->get_string_size(s).width;
- if (c->has_meta("_tab_icon")) {
- Ref<Texture> icon = c->get_meta("_tab_icon");
- if (icon.is_valid()) {
- tab_width+=icon->get_width();
- if (s!="")
- tab_width+=get_constant("hseparation");
+ if (c->has_meta("_tab_icon")) {
+ Ref<Texture> icon = c->get_meta("_tab_icon");
+ if (icon.is_valid()) {
+ tab_width+=icon->get_width();
+ if (s!="")
+ tab_width+=get_constant("hseparation");
- }
- }
+ }
+ }
- if (idx==current) {
+ if (idx==current) {
tab_width+=tab_fg->get_minimum_size().width;
} else {
@@ -163,7 +178,7 @@ void TabContainer::_input_event(const InputEvent& p_event) {
if (found!=-1) {
- set_current_tab(found);
+ set_current_tab(found);
}
}
@@ -194,7 +209,9 @@ void TabContainer::_notification(int p_what) {
Ref<Texture> incr = get_icon("increment");
Ref<Texture> incr_hl = get_icon("increment_hilite");
Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> decr_hl = get_icon("decrement_hilite");
+ Ref<Texture> decr_hl = get_icon("decrement_hilite");
+ Ref<Texture> menu = get_icon("menu");
+ Ref<Texture> menu_hl = get_icon("menu_hl");
Ref<Font> font = get_font("font");
Color color_fg = get_color("font_color_fg");
Color color_bg = get_color("font_color_bg");
@@ -209,6 +226,7 @@ void TabContainer::_notification(int p_what) {
Size2 top_size = Size2( size.width, top_margin );
+
int w=0;
int idx=0;
for(int i=0;i<get_child_count();i++) {
@@ -227,7 +245,7 @@ void TabContainer::_notification(int p_what) {
if (icon.is_valid()) {
w+=icon->get_width();
if (s!="")
- w+=get_constant("hseparation");
+ w+=get_constant("hseparation");
}
}
@@ -245,14 +263,18 @@ void TabContainer::_notification(int p_what) {
int ofs;
int limit=get_size().width;
+ if (popup) {
+ top_size.width-=menu->get_width();
+ limit-=menu->get_width();
+ }
- if (w<=get_size().width) {
+ if (w<=limit) {
switch(align) {
case ALIGN_LEFT: ofs = side_margin; break;
- case ALIGN_CENTER: ofs = (int(top_size.width) - w)/2; break;
- case ALIGN_RIGHT: ofs = int(top_size.width) - w - side_margin; break;
+ case ALIGN_CENTER: ofs = (int(limit) - w)/2; break;
+ case ALIGN_RIGHT: ofs = int(limit) - w - side_margin; break;
};
tab_display_ofs=0;
@@ -364,6 +386,15 @@ void TabContainer::_notification(int p_what) {
incr->draw(ci,Point2(limit+incr->get_width(),vofs),Color(1,1,1,notdone?1.0:0.5));
}
+ if (popup) {
+ int from = get_size().width-menu->get_width();
+
+ if (mouse_x_cache > from)
+ menu_hl->draw(get_canvas_item(),Size2(from,0));
+ else
+ menu->draw(get_canvas_item(),Size2(from,0));
+ }
+
panel->draw(ci, Rect2( 0, top_size.height, size.width, size.height-top_size.height));
} break;
@@ -465,6 +496,48 @@ int TabContainer::get_current_tab() const {
return current;
}
+Control* TabContainer::get_tab_control(int p_idx) const {
+
+ int idx=0;
+
+
+ for(int i=0;i<get_child_count();i++) {
+
+ Control *c = get_child(i)->cast_to<Control>();
+ if (!c)
+ continue;
+ if (c->is_set_as_toplevel())
+ continue;
+ if (idx==p_idx) {
+ return c;
+
+ }
+ idx++;
+ }
+
+ return NULL;
+}
+Control* TabContainer::get_current_tab_control() const {
+
+ int idx=0;
+
+
+ for(int i=0;i<get_child_count();i++) {
+
+ Control *c = get_child(i)->cast_to<Control>();
+ if (!c)
+ continue;
+ if (c->is_set_as_toplevel())
+ continue;
+ if (idx==current) {
+ return c;
+
+ }
+ idx++;
+ }
+
+ return NULL;
+}
void TabContainer::remove_child_notify(Node *p_child) {
@@ -635,12 +708,25 @@ Size2 TabContainer::get_minimum_size() const {
return ms;
}
+void TabContainer::set_popup(Node *p_popup) {
+ ERR_FAIL_NULL(p_popup);
+ popup=p_popup->cast_to<Popup>();
+ update();
+}
+
+Popup* TabContainer::get_popup() const {
+ return popup;
+}
+
+
void TabContainer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_input_event"),&TabContainer::_input_event);
ObjectTypeDB::bind_method(_MD("get_tab_count"),&TabContainer::get_tab_count);
ObjectTypeDB::bind_method(_MD("set_current_tab","tab_idx"),&TabContainer::set_current_tab);
ObjectTypeDB::bind_method(_MD("get_current_tab"),&TabContainer::get_current_tab);
+ ObjectTypeDB::bind_method(_MD("get_current_tab_control:Control"),&TabContainer::get_current_tab_control);
+ ObjectTypeDB::bind_method(_MD("get_tab_control:Control","idx"),&TabContainer::get_tab_control);
ObjectTypeDB::bind_method(_MD("set_tab_align","align"),&TabContainer::set_tab_align);
ObjectTypeDB::bind_method(_MD("get_tab_align"),&TabContainer::get_tab_align);
ObjectTypeDB::bind_method(_MD("set_tabs_visible","visible"),&TabContainer::set_tabs_visible);
@@ -649,10 +735,13 @@ void TabContainer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_tab_title","tab_idx"),&TabContainer::get_tab_title);
ObjectTypeDB::bind_method(_MD("set_tab_icon","tab_idx","icon:Texture"),&TabContainer::set_tab_icon);
ObjectTypeDB::bind_method(_MD("get_tab_icon:Texture","tab_idx"),&TabContainer::get_tab_icon);
+ ObjectTypeDB::bind_method(_MD("set_popup","popup:Popup"),&TabContainer::set_popup);
+ ObjectTypeDB::bind_method(_MD("get_popup:Popup"),&TabContainer::get_popup);
ObjectTypeDB::bind_method(_MD("_child_renamed_callback"),&TabContainer::_child_renamed_callback);
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
+ ADD_SIGNAL(MethodInfo("pre_popup_pressed"));
ADD_PROPERTY( PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM,"Left,Center,Right"), _SCS("set_tab_align"), _SCS("get_tab_align") );
ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") );
@@ -669,5 +758,6 @@ TabContainer::TabContainer() {
mouse_x_cache=0;
align=ALIGN_CENTER;
tabs_visible=true;
+ popup=NULL;
}
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 43314b026d..602d248b46 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -31,7 +31,7 @@
#include "scene/gui/control.h"
-
+#include "scene/gui/popup.h"
class TabContainer : public Control {
OBJ_TYPE( TabContainer, Control );
@@ -55,6 +55,8 @@ private:
TabAlign align;
Control *_get_tab(int idx) const;
int _get_top_margin() const;
+ Popup *popup;
+
protected:
@@ -85,10 +87,17 @@ public:
void set_current_tab(int p_current);
int get_current_tab() const;
+ Control* get_tab_control(int p_idx) const;
+ Control* get_current_tab_control() const;
+
virtual Size2 get_minimum_size() const;
virtual void get_translatable_strings(List<String> *p_strings) const;
+ void set_popup(Node *p_popup);
+ Popup* get_popup() const;
+
+
TabContainer();
};
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index ab530866bb..2530e3a36f 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -641,6 +641,7 @@ void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) {
p_child->data.pos=data.children.size();
data.children.push_back( p_child );
p_child->data.parent=this;
+ p_child->notification(NOTIFICATION_PARENTED);
if (data.tree) {
p_child->_set_tree(data.tree);
@@ -649,7 +650,6 @@ void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) {
/* Notify */
//recognize childs created in this node constructor
p_child->data.parent_owned=data.in_constructor;
- p_child->notification(NOTIFICATION_PARENTED);
add_child_notify(p_child);
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index 584b40337f..1664a9bea1 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -1108,6 +1108,9 @@ void SceneTree::_bind_methods() {
ADD_SIGNAL( MethodInfo("node_removed",PropertyInfo( Variant::OBJECT, "node") ) );
ADD_SIGNAL( MethodInfo("screen_resized") );
+ ADD_SIGNAL( MethodInfo("idle_frame"));
+ ADD_SIGNAL( MethodInfo("fixed_frame"));
+
BIND_CONSTANT( GROUP_CALL_DEFAULT );
BIND_CONSTANT( GROUP_CALL_REVERSE );
BIND_CONSTANT( GROUP_CALL_REALTIME );
@@ -1166,8 +1169,7 @@ SceneTree::SceneTree() {
edited_scene_root=NULL;
#endif
- ADD_SIGNAL( MethodInfo("idle_frame"));
- ADD_SIGNAL( MethodInfo("fixed_frame"));
+
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 2267cc9e2f..9a9048e3e5 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -655,6 +655,8 @@ void make_default_theme() {
t->set_icon("increment_hilite","TabContainer",make_icon( scroll_button_right_hl_png));
t->set_icon("decrement","TabContainer",make_icon( scroll_button_left_png));
t->set_icon("decrement_hilite","TabContainer",make_icon( scroll_button_left_hl_png));
+ t->set_icon("menu","TabContainer",make_icon( tab_menu_png));
+ t->set_icon("menu_hilite","TabContainer",make_icon( tab_menu_hl_png));
t->set_font("font","TabContainer", default_font );
diff --git a/scene/resources/default_theme/tab_menu.png b/scene/resources/default_theme/tab_menu.png
new file mode 100644
index 0000000000..c5659da11b
--- /dev/null
+++ b/scene/resources/default_theme/tab_menu.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_menu_hl.png b/scene/resources/default_theme/tab_menu_hl.png
new file mode 100644
index 0000000000..6f68502c07
--- /dev/null
+++ b/scene/resources/default_theme/tab_menu_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 8bd0a66271..291931a015 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -379,6 +379,16 @@ static const unsigned char tab_current_png[]={
};
+static const unsigned char tab_menu_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0xd,0x3,0x2c,0x7,0xf7,0x85,0x69,0x73,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0x54,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x92,0xb1,0xd,0xc0,0x20,0x10,0x3,0x8f,0xec,0x63,0x65,0xff,0x2d,0x40,0x1e,0xe8,0xd3,0x50,0x24,0xd1,0x83,0x48,0x97,0x2,0xb7,0xb6,0x4f,0xd6,0xeb,0x61,0xeb,0x67,0xb2,0x5d,0xbe,0x66,0x4a,0x12,0x88,0x19,0x40,0xd2,0xa3,0x73,0x24,0x99,0x6,0x64,0x90,0xe8,0x1e,0xd3,0x5,0x7d,0x45,0x3,0x74,0xf3,0x3,0xb0,0xa4,0x73,0x9,0xf0,0x82,0x30,0x2a,0xaf,0x1c,0xb5,0xda,0xae,0xfb,0xbd,0xe6,0xba,0x0,0x22,0x30,0x1e,0x2c,0xd7,0x21,0xa8,0x0,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
+static const unsigned char tab_menu_hl_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0xd,0x3,0x2c,0x15,0x4,0x3c,0x18,0x3b,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0x58,0x49,0x44,0x41,0x54,0x38,0xcb,0x63,0x60,0x18,0x5,0x83,0xc,0xbc,0x7c,0xf9,0x92,0x91,0x54,0x35,0x8c,0x58,0x14,0xfc,0xc7,0x67,0x80,0xb8,0xb8,0x38,0x8a,0x1e,0x26,0x2c,0x6a,0x2e,0x32,0x30,0x30,0x60,0x33,0xe4,0x3f,0x54,0x8e,0x1,0xaf,0xb,0xa0,0xae,0xb8,0xc8,0xc0,0xc0,0xa0,0x8b,0x24,0xff,0x9f,0x81,0x81,0xe1,0xb2,0xb8,0xb8,0xb8,0x3e,0x51,0x6,0xa0,0x19,0xc2,0x80,0x4b,0x33,0x31,0x81,0x7a,0xe1,0xe5,0xcb,0x97,0x17,0x46,0x93,0x17,0x7e,0x0,0x0,0xa,0x9a,0x1f,0x34,0xff,0x99,0xf7,0x75,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
static const unsigned char toggle_off_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0xa2,0x9d,0x7e,0x84,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x26,0x0,0x26,0x0,0x26,0x59,0xf,0xde,0x74,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x14,0x17,0x2,0x16,0xe9,0x0,0x17,0x60,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x2,0x45,0x49,0x44,0x41,0x54,0x68,0x81,0xed,0x99,0x5f,0x4f,0xd3,0x50,0x18,0x87,0x9f,0xb3,0x96,0xb5,0xcc,0x3a,0xa6,0xac,0x6d,0xa,0x91,0x84,0x5b,0x8d,0x7e,0x21,0x60,0x2c,0x5c,0x1a,0x63,0xe2,0x27,0x31,0x31,0xc6,0x4b,0x32,0xa7,0x7e,0x20,0x84,0x6b,0x6f,0xc,0x90,0x6d,0x32,0xca,0x6c,0xb0,0x24,0x75,0xc7,0x8b,0xba,0xb9,0x35,0xdd,0x84,0xec,0xe0,0x26,0xed,0x73,0xd7,0xf7,0xed,0xce,0x7b,0x7e,0xbf,0xbe,0x67,0x7f,0xde,0x41,0x4e,0x4e,0xa6,0x11,0x89,0xeb,0x12,0x50,0x1,0x2c,0x40,0x4b,0xc9,0xff,0xaf,0x48,0xe0,0x27,0x10,0x0,0x3e,0x70,0x39,0x48,0xe8,0x89,0x1b,0x2b,0xc0,0x33,0xe0,0x11,0x60,0x72,0xb7,0xc,0x8,0x81,0xaf,0xc0,0x67,0xa6,0x18,0x60,0x1,0x1b,0x4f,0x1e,0x3f,0x7d,0x6d,0x57,0xed,0x65,0x40,0x48,0x64,0xfc,0x72,0x95,0x8,0x10,0x8,0x74,0x5d,0x67,0x69,0x49,0x47,0xd3,0x92,0xdb,0x50,0x4b,0x14,0x45,0xf2,0xf8,0xe4,0xf8,0xc7,0xe1,0xd1,0xc1,0x2b,0xe0,0xcb,0x68,0x2e,0x59,0x59,0x7,0xc,0xbb,0x6a,0x97,0xce,0xba,0x67,0x4,0x41,0x80,0xec,0xf7,0x91,0x8a,0x1d,0x10,0x8,0x44,0xa1,0x80,0x51,0x2c,0x52,0x2a,0xdd,0xa3,0x58,0x2c,0x2a,0x5d,0x3f,0x89,0x69,0x9a,0x62,0x7d,0x6d,0xbd,0x74,0x78,0x74,0x60,0x90,0xd0,0x9c,0x66,0xbd,0x0,0x8,0x82,0xef,0x54,0x2a,0xf,0x70,0x6c,0x7,0xa1,0xf8,0x24,0x48,0x24,0xed,0x4e,0x1b,0xdf,0x3f,0xc7,0x30,0x4c,0xa5,0x6b,0xa7,0x11,0x86,0x21,0x96,0x65,0x41,0xca,0x91,0x4e,0xed,0x3d,0x29,0x25,0xb2,0x2f,0x71,0x1d,0x97,0x30,0xc,0x39,0x6d,0x9d,0x2a,0xdd,0x90,0xe7,0x7a,0xb8,0x8e,0xcb,0x79,0xb7,0xab,0xbc,0xbb,0x6e,0x4a,0x61,0x52,0x62,0x70,0xf6,0x55,0x8b,0x87,0xdf,0x6b,0x4a,0xe6,0x2e,0x1e,0xa6,0x18,0x90,0x15,0x32,0x6f,0xc0,0xed,0x7e,0xfe,0xcc,0x80,0x65,0x59,0xd4,0xf7,0x6a,0x63,0xb1,0xc6,0x7e,0x93,0x20,0x8,0x78,0xf1,0xf2,0xf9,0x58,0xfc,0xed,0x9b,0x77,0xa9,0xb1,0xeb,0xb0,0xb0,0x6,0xc,0xc4,0x7f,0x78,0xff,0x9,0x80,0x9d,0xdd,0x2d,0xea,0x7b,0xb5,0xa1,0xb0,0x34,0x81,0xd7,0x15,0x3d,0xca,0xc2,0x1a,0x0,0xd0,0x6c,0x7c,0xa4,0xd7,0xeb,0x1,0xb1,0x11,0x3b,0xbb,0x5b,0xc3,0xdc,0xe8,0x13,0x1f,0x8,0x4f,0x8b,0xfd,0x8d,0x85,0x36,0x60,0x1a,0xaa,0x3a,0x60,0xa1,0xdf,0x4,0x6b,0xf5,0x6d,0xca,0xe5,0x32,0xe5,0x72,0x79,0xec,0xe9,0xab,0x24,0x69,0x80,0x9,0xac,0xdc,0x4a,0xa5,0x1b,0xd2,0xd8,0x6f,0x2,0xb1,0x9,0xb5,0xfa,0xf6,0x58,0x6c,0x6,0x56,0x88,0x35,0xe,0x49,0x1e,0x81,0x10,0xb8,0x98,0xb5,0x8a,0xa,0x82,0x20,0x98,0xd8,0xd2,0x33,0xb4,0xff,0x5,0xb1,0xc6,0x21,0xb,0x7d,0x4,0xfe,0x5,0xb9,0x1,0xf3,0xde,0xc0,0xbc,0x99,0x68,0x80,0x88,0xa7,0x16,0x78,0xae,0xa7,0xbc,0xa8,0xe7,0x7a,0xc3,0xa1,0xc8,0xbc,0x49,0xfd,0x1e,0x20,0x84,0x40,0x14,0x4,0xad,0x76,0xb,0xc7,0x76,0xd8,0xdc,0xd8,0x54,0x5a,0x54,0x22,0x69,0xb5,0x5b,0x88,0x82,0x98,0xbb,0x9,0x69,0x6,0x48,0x0,0xcb,0xba,0x8f,0xef,0xfb,0xb7,0xf2,0x9b,0xfd,0xcf,0x44,0xc8,0x40,0xd3,0x34,0xa5,0x6b,0xa7,0x61,0x9a,0x26,0x51,0x14,0x41,0xca,0x70,0x2f,0x69,0x40,0x4,0x5c,0x75,0xbe,0x75,0x2e,0xed,0xaa,0xbd,0xbc,0xfa,0x70,0xf5,0x4e,0xcd,0x4,0x81,0x2b,0x62,0x8d,0xa3,0x5b,0x19,0x63,0x8d,0x6c,0x4c,0x85,0x4f,0x6,0x89,0xcc,0xff,0x2f,0x90,0x93,0x93,0x93,0x6d,0x7e,0x1,0x6b,0xe,0xc1,0xdb,0xd6,0xe0,0xc4,0xba,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index e009bd52cb..3eb96fb681 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -93,3 +93,72 @@ AreaPairSW::~AreaPairSW() {
body->remove_constraint(this);
area->remove_constraint(this);
}
+
+////////////////////////////////////////////////////
+
+
+
+bool Area2PairSW::setup(float p_step) {
+
+// bool result = area_a->test_collision_mask(area_b) && CollisionSolverSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this);
+ bool result = CollisionSolverSW::solve_static(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),NULL,this);
+
+ if (result!=colliding) {
+
+ if (result) {
+
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ area_b->add_area_to_query(area_a,shape_a,shape_b);
+
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ area_a->add_area_to_query(area_b,shape_b,shape_a);
+
+ } else {
+
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ area_b->remove_area_from_query(area_a,shape_a,shape_b);
+
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ area_a->remove_area_from_query(area_b,shape_b,shape_a);
+ }
+
+ colliding=result;
+
+ }
+
+ return false; //never do any post solving
+}
+
+void Area2PairSW::solve(float p_step) {
+
+
+}
+
+
+Area2PairSW::Area2PairSW(AreaSW *p_area_a,int p_shape_a, AreaSW *p_area_b,int p_shape_b) {
+
+
+ area_a=p_area_a;
+ area_b=p_area_b;
+ shape_a=p_shape_a;
+ shape_b=p_shape_b;
+ colliding=false;
+ area_a->add_constraint(this);
+ area_b->add_constraint(this);
+
+}
+
+Area2PairSW::~Area2PairSW() {
+
+ if (colliding) {
+
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ area_b->remove_area_from_query(area_a,shape_a,shape_b);
+
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ area_a->remove_area_from_query(area_b,shape_b,shape_a);
+ }
+
+ area_a->remove_constraint(this);
+ area_b->remove_constraint(this);
+}
diff --git a/servers/physics/area_pair_sw.h b/servers/physics/area_pair_sw.h
index 1c219a05fd..4f8087280a 100644
--- a/servers/physics/area_pair_sw.h
+++ b/servers/physics/area_pair_sw.h
@@ -49,5 +49,23 @@ public:
~AreaPairSW();
};
+
+class Area2PairSW : public ConstraintSW {
+
+ AreaSW *area_a;
+ AreaSW *area_b;
+ int shape_a;
+ int shape_b;
+ bool colliding;
+public:
+
+ bool setup(float p_step);
+ void solve(float p_step);
+
+ Area2PairSW(AreaSW *p_area_a,int p_shape_a, AreaSW *p_area_b,int p_shape_b);
+ ~Area2PairSW();
+};
+
+
#endif // AREA_PAIR__SW_H
diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp
index aa1c530221..83be80f816 100644
--- a/servers/physics/area_sw.cpp
+++ b/servers/physics/area_sw.cpp
@@ -31,6 +31,7 @@
#include "body_sw.h"
AreaSW::BodyKey::BodyKey(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; }
+AreaSW::BodyKey::BodyKey(AreaSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; }
void AreaSW::_shapes_changed() {
@@ -57,6 +58,7 @@ void AreaSW::set_space(SpaceSW *p_space) {
}
monitored_bodies.clear();
+ monitored_areas.clear();
_set_space(p_space);
}
@@ -76,11 +78,32 @@ void AreaSW::set_monitor_callback(ObjectID p_id, const StringName& p_method) {
monitor_callback_method=p_method;
monitored_bodies.clear();
+ monitored_areas.clear();
+
_shape_changed();
}
+void AreaSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method) {
+
+
+ if (p_id==area_monitor_callback_id) {
+ area_monitor_callback_method=p_method;
+ return;
+ }
+
+ _unregister_shapes();
+
+ area_monitor_callback_id=p_id;
+ area_monitor_callback_method=p_method;
+
+ monitored_bodies.clear();
+ monitored_areas.clear();
+
+ _shape_changed();
+
+}
void AreaSW::set_space_override_mode(PhysicsServer::AreaSpaceOverrideMode p_mode) {
@@ -134,6 +157,15 @@ void AreaSW::_queue_monitor_update() {
}
+void AreaSW::set_monitorable(bool p_monitorable) {
+
+ if (monitorable==p_monitorable)
+ return;
+
+ monitorable=p_monitorable;
+ _set_static(!monitorable);
+}
+
void AreaSW::call_queries() {
if (monitor_callback_id && !monitored_bodies.empty()) {
@@ -168,6 +200,41 @@ void AreaSW::call_queries() {
monitored_bodies.clear();
+ if (area_monitor_callback_id && !monitored_areas.empty()) {
+
+
+ Variant res[5];
+ Variant *resptr[5];
+ for(int i=0;i<5;i++)
+ resptr[i]=&res[i];
+
+ Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
+ if (!obj) {
+ monitored_areas.clear();
+ area_monitor_callback_id=0;
+ return;
+ }
+
+
+
+ for (Map<BodyKey,BodyState>::Element *E=monitored_areas.front();E;E=E->next()) {
+
+ if (E->get().state==0)
+ continue; //nothing happened
+
+ res[0]=E->get().state>0 ? PhysicsServer::AREA_BODY_ADDED : PhysicsServer::AREA_BODY_REMOVED;
+ res[1]=E->key().rid;
+ res[2]=E->key().instance_id;
+ res[3]=E->key().body_shape;
+ res[4]=E->key().area_shape;
+
+
+ Variant::CallError ce;
+ obj->call(area_monitor_callback_method,(const Variant**)resptr,5,ce);
+ }
+ }
+
+ monitored_areas.clear();
//get_space()->area_remove_from_monitor_query_list(&monitor_query_list);
}
@@ -185,6 +252,8 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move
priority=0;
set_ray_pickable(false);
monitor_callback_id=0;
+ area_monitor_callback_id=0;
+ monitorable=false;
}
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index a875472f6b..26d6a177db 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -49,10 +49,14 @@ class AreaSW : public CollisionObjectSW{
float point_attenuation;
float density;
int priority;
+ bool monitorable;
ObjectID monitor_callback_id;
StringName monitor_callback_method;
+ ObjectID area_monitor_callback_id;
+ StringName area_monitor_callback_method;
+
SelfList<AreaSW> monitor_query_list;
SelfList<AreaSW> moved_list;
@@ -79,6 +83,8 @@ class AreaSW : public CollisionObjectSW{
_FORCE_INLINE_ BodyKey() {}
BodyKey(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape);
+ BodyKey(AreaSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape);
+
};
struct BodyState {
@@ -90,6 +96,7 @@ class AreaSW : public CollisionObjectSW{
};
Map<BodyKey,BodyState> monitored_bodies;
+ Map<BodyKey,BodyState> monitored_areas;
//virtual void shape_changed_notify(ShapeSW *p_shape);
//virtual void shape_deleted_notify(ShapeSW *p_shape);
@@ -108,9 +115,15 @@ public:
void set_monitor_callback(ObjectID p_id, const StringName& p_method);
_FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id; }
+ void set_area_monitor_callback(ObjectID p_id, const StringName& p_method);
+ _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id; }
+
_FORCE_INLINE_ void add_body_to_query(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape);
_FORCE_INLINE_ void remove_body_from_query(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape);
+ _FORCE_INLINE_ void add_area_to_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape);
+ _FORCE_INLINE_ void remove_area_from_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape);
+
void set_param(PhysicsServer::AreaParameter p_param, const Variant& p_value);
Variant get_param(PhysicsServer::AreaParameter p_param) const;
@@ -142,8 +155,8 @@ public:
_FORCE_INLINE_ void remove_constraint( ConstraintSW* p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<ConstraintSW*>& get_constraints() const { return constraints; }
-
-
+ void set_monitorable(bool p_monitorable);
+ _FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
void set_transform(const Transform& p_transform);
@@ -172,6 +185,26 @@ void AreaSW::remove_body_from_query(BodySW *p_body, uint32_t p_body_shape,uint32
}
+void AreaSW::add_area_to_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) {
+
+
+ BodyKey bk(p_area,p_area_shape,p_self_shape);
+ monitored_areas[bk].inc();
+ if (!monitor_query_list.in_list())
+ _queue_monitor_update();
+
+
+}
+void AreaSW::remove_area_from_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) {
+
+
+ BodyKey bk(p_area,p_area_shape,p_self_shape);
+ monitored_areas[bk].dec();
+ if (!monitor_query_list.in_list())
+ _queue_monitor_update();
+}
+
+
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 03d5b7afa1..521ffae0ea 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -394,6 +394,14 @@ Transform PhysicsServerSW::area_get_transform(RID p_area) const {
return area->get_transform();
};
+void PhysicsServerSW::area_set_monitorable(RID p_area,bool p_monitorable) {
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_monitorable(p_monitorable);
+}
+
void PhysicsServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) {
AreaSW *area = area_owner.get(p_area);
@@ -423,6 +431,14 @@ bool PhysicsServerSW::area_is_ray_pickable(RID p_area) const{
}
+void PhysicsServerSW::area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) {
+
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_area_monitor_callback(p_receiver?p_receiver->get_instance_ID():0,p_method);
+}
/* BODY API */
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index de2a24a378..80007b8499 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -128,7 +128,10 @@ public:
virtual void area_set_ray_pickable(RID p_area,bool p_enable);
virtual bool area_is_ray_pickable(RID p_area) const;
+ virtual void area_set_monitorable(RID p_area,bool p_monitorable);
+
virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method);
+ virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method);
/* BODY API */
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index a7465c57b9..d329a10f04 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -503,15 +503,18 @@ void* SpaceSW::_broadphase_pair(CollisionObjectSW *A,int p_subindex_A,CollisionO
if (type_A==CollisionObjectSW::TYPE_AREA) {
-
- ERR_FAIL_COND_V(type_B!=CollisionObjectSW::TYPE_BODY,NULL);
AreaSW *area=static_cast<AreaSW*>(A);
- BodySW *body=static_cast<BodySW*>(B);
-
+ if (type_B==CollisionObjectSW::TYPE_AREA) {
- AreaPairSW *area_pair = memnew(AreaPairSW(body,p_subindex_B,area,p_subindex_A) );
+ AreaSW *area_b=static_cast<AreaSW*>(B);
+ Area2PairSW *area2_pair = memnew(Area2PairSW(area_b,p_subindex_B,area,p_subindex_A) );
+ return area2_pair;
+ } else {
- return area_pair;
+ BodySW *body=static_cast<BodySW*>(B);
+ AreaPairSW *area_pair = memnew(AreaPairSW(body,p_subindex_B,area,p_subindex_A) );
+ return area_pair;
+ }
} else {
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 05b64da804..f66ea590b8 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -339,7 +339,10 @@ public:
virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const=0;
virtual Transform area_get_transform(RID p_area) const=0;
+ virtual void area_set_monitorable(RID p_area,bool p_monitorable)=0;
+
virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0;
+ virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0;
virtual void area_set_ray_pickable(RID p_area,bool p_enable)=0;
virtual bool area_is_ray_pickable(RID p_area) const=0;
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 79365f7db6..50336e07f4 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -502,7 +502,7 @@ public:
virtual void begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug)=0;
virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass )=0;
- virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection)=0;
+ virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint)=0;
virtual void add_light( RID p_light_instance )=0; ///< all "add_light" calls happen before add_geometry calls
diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp
index 8db1cbf6e5..e32f47b3d8 100644
--- a/servers/visual/rasterizer_dummy.cpp
+++ b/servers/visual/rasterizer_dummy.cpp
@@ -1497,7 +1497,7 @@ void RasterizerDummy::begin_shadow_map( RID p_light_instance, int p_shadow_pass
}
-void RasterizerDummy::set_camera(const Transform& p_world,const CameraMatrix& p_projection) {
+void RasterizerDummy::set_camera(const Transform& p_world, const CameraMatrix& p_projection, bool p_ortho_hint) {
}
diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h
index 318cf6ff99..cc3c1724a4 100644
--- a/servers/visual/rasterizer_dummy.h
+++ b/servers/visual/rasterizer_dummy.h
@@ -679,7 +679,7 @@ public:
virtual void begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug);
virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass );
- virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection);
+ virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint);
virtual void add_light( RID p_light_instance ); ///< all "add_light" calls happen before add_geometry calls
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 52e5c21272..3fc90fd46d 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -6302,7 +6302,7 @@ void VisualServerRaster::_render_no_camera(Viewport *p_viewport,Camera *p_camera
else
environment=p_scenario->fallback_environment;
- rasterizer->set_camera(Transform(),CameraMatrix());
+ rasterizer->set_camera(Transform(),CameraMatrix(),false);
rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug);
rasterizer->set_viewport(viewport_rect);
rasterizer->end_scene();
@@ -6318,7 +6318,8 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
/* STEP 1 - SETUP CAMERA */
CameraMatrix camera_matrix;
-
+ bool ortho=false;
+
switch(p_camera->type) {
case Camera::ORTHOGONAL: {
@@ -6330,6 +6331,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
p_camera->vaspect
);
+ ortho=true;
} break;
case Camera::PERSPECTIVE: {
@@ -6341,12 +6343,13 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
p_camera->vaspect
);
+ ortho=false;
} break;
}
- rasterizer->set_camera(p_camera->transform, camera_matrix);
+ rasterizer->set_camera(p_camera->transform, camera_matrix,ortho);
Vector<Plane> planes = camera_matrix.get_projection_planes(p_camera->transform);
diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp
index f5bef2580d..c0f35a4ac2 100644
--- a/tools/editor/create_dialog.cpp
+++ b/tools/editor/create_dialog.cpp
@@ -230,6 +230,11 @@ void CreateDialog::_notification(int p_what) {
connect("confirmed",this,"_confirmed");
_update_search();
}
+ if (p_what==NOTIFICATION_EXIT_TREE) {
+
+ disconnect("confirmed",this,"_confirmed");
+
+ }
if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 688604ecfd..373c8aba73 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -54,7 +54,7 @@
#include "register_exporters.h"
#include "bind/core_bind.h"
#include "io/zip_io.h"
-
+#include "io/config_file.h"
// plugins
#include "plugins/sprite_frames_editor_plugin.h"
@@ -1377,7 +1377,7 @@ void EditorNode::_edit_current() {
object_menu->set_disabled(false);
resources_dock->add_resource(Ref<Resource>(current_res));
- top_pallete->set_current_tab(1);
+ //top_pallete->set_current_tab(1);
}
@@ -1394,7 +1394,7 @@ void EditorNode::_edit_current() {
scene_tree_dock->set_selected(current_node);
object_menu->get_popup()->clear();
- top_pallete->set_current_tab(0);
+ //top_pallete->set_current_tab(0);
}
@@ -2908,7 +2908,7 @@ Error EditorNode::load_scene(const String& p_scene) {
prev_scene->set_disabled(previous_scenes.size()==0);
opening_prev=false;
- top_pallete->set_current_tab(0); //always go to scene
+ //top_pallete->set_current_tab(0); //always go to scene
push_item(new_scene);
@@ -2981,15 +2981,15 @@ void EditorNode::_update_keying() {
void EditorNode::_close_messages() {
// left_split->set_dragger_visible(false);
- old_split_ofs = left_split->get_split_offset();
- left_split->set_split_offset(0);
+ old_split_ofs = center_split->get_split_offset();
+ center_split->set_split_offset(0);
// scene_root_parent->set_anchor_and_margin(MARGIN_BOTTOM,Control::ANCHOR_END,0);
}
void EditorNode::_show_messages() {
// left_split->set_dragger_visible(true);
- left_split->set_split_offset(old_split_ofs);
+ center_split->set_split_offset(old_split_ofs);
// scene_root_parent->set_anchor_and_margin(MARGIN_BOTTOM,Control::ANCHOR_END,log->get_margin(MARGIN_TOP));
}
@@ -3334,6 +3334,17 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("_sources_changed",&EditorNode::_sources_changed);
ObjectTypeDB::bind_method("_fs_changed",&EditorNode::_fs_changed);
+ ObjectTypeDB::bind_method("_dock_select_draw",&EditorNode::_dock_select_draw);
+ ObjectTypeDB::bind_method("_dock_select_input",&EditorNode::_dock_select_input);
+ ObjectTypeDB::bind_method("_dock_pre_popup",&EditorNode::_dock_pre_popup);
+ ObjectTypeDB::bind_method("_dock_split_dragged",&EditorNode::_dock_split_dragged);
+ ObjectTypeDB::bind_method("_save_docks",&EditorNode::_save_docks);
+ ObjectTypeDB::bind_method("_dock_popup_exit",&EditorNode::_dock_popup_exit);
+ ObjectTypeDB::bind_method("_dock_move_left",&EditorNode::_dock_move_left);
+ ObjectTypeDB::bind_method("_dock_move_right",&EditorNode::_dock_move_right);
+
+
+
ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin);
ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin);
@@ -3414,6 +3425,329 @@ void EditorNode::show_warning(const String& p_text) {
warning->popup_centered_minsize();
}
+void EditorNode::_dock_select_input(const InputEvent& p_input) {
+
+ if (p_input.type==InputEvent::MOUSE_BUTTON || p_input.type==InputEvent::MOUSE_MOTION) {
+
+ Vector2 point(p_input.mouse_motion.x,p_input.mouse_motion.y);
+
+ int nrect = -1;
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+ if (dock_select_rect[i].has_point(point)) {
+ nrect=i;
+ break;
+ }
+ }
+
+
+ if (nrect!=dock_select_rect_over) {
+ dock_select->update();
+ dock_select_rect_over=nrect;
+
+ }
+
+
+ if (nrect==-1)
+ return;
+
+ if (p_input.type==InputEvent::MOUSE_BUTTON && p_input.mouse_button.button_index==1 && p_input.mouse_button.pressed && dock_popup_selected!=nrect) {
+ Control *dock = dock_slot[dock_popup_selected]->get_current_tab_control();
+ if (dock) {
+ dock_slot[dock_popup_selected]->remove_child(dock);
+ }
+ if (dock_slot[dock_popup_selected]->get_tab_count()==0) {
+ dock_slot[dock_popup_selected]->hide();
+
+ } else {
+
+ dock_slot[dock_popup_selected]->set_current_tab(0);
+ }
+
+ print_line("performing reparent");
+ dock_slot[nrect]->add_child(dock);
+ dock_popup_selected=nrect;
+ dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count()-1);
+ dock_slot[nrect]->show();
+ dock_select->update();
+
+ VSplitContainer*splits[DOCK_SLOT_MAX/2]={
+ left_l_vsplit,
+ left_r_vsplit,
+ right_l_vsplit,
+ right_r_vsplit,
+ };
+
+ for(int i=0;i<4;i++) {
+ bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count();
+ if (in_use)
+ splits[i]->show();
+ else
+ splits[i]->hide();
+ }
+
+ _save_docks();
+ }
+ }
+}
+
+void EditorNode::_dock_popup_exit() {
+
+ dock_select_rect_over=-1;
+ dock_select->update();
+}
+
+void EditorNode::_dock_pre_popup(int p_which) {
+
+
+ dock_popup_selected=p_which;
+}
+
+void EditorNode::_dock_move_left() {
+
+ if (dock_popup_selected<0 || dock_popup_selected>=DOCK_SLOT_MAX)
+ return;
+ Control *current = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab() );
+ Control *prev = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab()-1 );
+ if (!current || !prev)
+ return;
+ dock_slot[dock_popup_selected]->move_child(current,prev->get_index());
+ dock_slot[dock_popup_selected]->set_current_tab( dock_slot[dock_popup_selected]->get_current_tab()-1 );
+ dock_select->update();
+ _save_docks();
+
+
+}
+
+void EditorNode::_dock_move_right() {
+
+ Control *current = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab() );
+ Control *next = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab()+1 );
+ if (!current || !next)
+ return;
+ dock_slot[dock_popup_selected]->move_child(next,current->get_index());
+ dock_slot[dock_popup_selected]->set_current_tab( dock_slot[dock_popup_selected]->get_current_tab()+1 );
+ dock_select->update();
+ _save_docks();
+}
+
+void EditorNode::_dock_select_draw(){
+ Size2 s = dock_select->get_size();
+ s.y/=2.0;
+ s.x/=6.0;
+
+ Color used=Color(0.6,0.6,0.6,0.8);
+ Color used_selected=Color(0.8,0.8,0.8,0.8);
+ Color tab_selected=Color(1,1,1,1);
+ Color unused=used;
+ unused.a=0.4;
+ Color unusable=unused;
+ unusable.a=0.1;
+
+ Rect2 unr(s.x*2,0,s.x*2,s.y*2);
+ unr.pos+=Vector2(2,5);
+ unr.size-=Vector2(4,7);
+
+ dock_select->draw_rect(unr,unusable);
+
+ dock_tab_move_left->set_disabled(true);
+ dock_tab_move_right->set_disabled(true);
+
+ if (dock_popup_selected!=-1 && dock_slot[dock_popup_selected]->get_tab_count()) {
+
+ dock_tab_move_left->set_disabled(dock_slot[dock_popup_selected]->get_current_tab()==0);
+ dock_tab_move_right->set_disabled(dock_slot[dock_popup_selected]->get_current_tab()>=dock_slot[dock_popup_selected]->get_tab_count()-1);
+ }
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ Vector2 ofs;
+
+ switch(i) {
+ case DOCK_SLOT_LEFT_UL: {
+
+ } break;
+ case DOCK_SLOT_LEFT_BL: {
+ ofs.y+=s.y;
+ } break;
+ case DOCK_SLOT_LEFT_UR: {
+ ofs.x+=s.x;
+ } break;
+ case DOCK_SLOT_LEFT_BR: {
+ ofs+=s;
+ } break;
+ case DOCK_SLOT_RIGHT_UL: {
+ ofs.x+=s.x*4;
+ } break;
+ case DOCK_SLOT_RIGHT_BL: {
+ ofs.x+=s.x*4;
+ ofs.y+=s.y;
+
+ } break;
+ case DOCK_SLOT_RIGHT_UR: {
+ ofs.x+=s.x*4;
+ ofs.x+=s.x;
+
+ } break;
+ case DOCK_SLOT_RIGHT_BR: {
+ ofs.x+=s.x*4;
+ ofs+=s;
+
+ } break;
+ }
+
+ Rect2 r(ofs,s);
+ dock_select_rect[i]=r;
+ r.pos+=Vector2(2,5);
+ r.size-=Vector2(4,7);
+
+
+ if (i==dock_select_rect_over) {
+ dock_select->draw_rect(r,used_selected);
+ } else if (dock_slot[i]->get_child_count()==0) {
+ dock_select->draw_rect(r,unused);
+ } else {
+
+ dock_select->draw_rect(r,used);
+ }
+
+ for(int j=0;j<MIN(3,dock_slot[i]->get_child_count());j++) {
+ int xofs = (r.size.width/3)*j;
+ Color c = used;
+ if (i==dock_popup_selected && (dock_slot[i]->get_current_tab()>3 || dock_slot[i]->get_current_tab()==j))
+ c=tab_selected;
+ dock_select->draw_rect(Rect2(2+ofs.x+xofs,ofs.y,r.size.width/3-1,3),c);
+ }
+
+ }
+}
+
+void EditorNode::_save_docks() {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+ String names;
+ for(int j=0;j<dock_slot[i]->get_tab_count();j++) {
+ String name = dock_slot[i]->get_tab_control(j)->get_name();
+ if (names!="")
+ names+=",";
+ names+=name;
+ }
+
+ if (names!="") {
+ config->set_value("docks","dock_"+itos(i+1),names);
+ }
+ }
+
+ VSplitContainer*splits[DOCK_SLOT_MAX/2]={
+ left_l_vsplit,
+ left_r_vsplit,
+ right_l_vsplit,
+ right_r_vsplit,
+ };
+
+ 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());
+ }
+ }
+
+
+ config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg"));
+
+}
+
+void EditorNode::_dock_split_dragged(int ofs) {
+
+ dock_drag_timer->start();
+}
+
+void EditorNode::_load_docks() {
+
+ Ref<ConfigFile> config;
+ config.instance();
+ Error err = config->load(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg"));
+ if (err!=OK) {
+ return; //no config
+ }
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ if (!config->has_section_key("docks","dock_"+itos(i+1)))
+ continue;
+
+ Vector<String> names = String(config->get_value("docks","dock_"+itos(i+1))).split(",");
+
+ for(int j=0;j<names.size();j++) {
+
+ String name=names[j];
+ //find it, in a horribly inefficient way
+ int atidx=-1;
+ Control *node=NULL;
+ for(int k=0;k<DOCK_SLOT_MAX;k++) {
+ if (!dock_slot[k]->has_node(name))
+ continue;
+ node=dock_slot[k]->get_node(name)->cast_to<Control>();
+ if (!node)
+ continue;
+ atidx=k;
+ break;
+ }
+ if (atidx==-1) //well, it's not anywhere
+ continue;
+
+ if (atidx==j) {
+ node->raise();
+ continue;
+ }
+
+
+ dock_slot[atidx]->remove_child(node);
+
+ if (dock_slot[atidx]->get_tab_count()==0) {
+ dock_slot[atidx]->hide();
+
+ }
+ dock_slot[i]->add_child(node);
+ dock_slot[i]->show();
+ }
+
+ }
+
+ VSplitContainer*splits[DOCK_SLOT_MAX/2]={
+ left_l_vsplit,
+ left_r_vsplit,
+ right_l_vsplit,
+ right_r_vsplit,
+ };
+
+ for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
+
+ if (!config->has_section_key("docks","dock_split_"+itos(i+1)))
+ continue;
+
+ int ofs = config->get_value("docks","dock_split_"+itos(i+1));
+ splits[i]->set_split_offset(ofs);
+ }
+
+ for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
+ bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count();
+ if (in_use)
+ splits[i]->show();
+ else
+ splits[i]->hide();
+ }
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ if (!dock_slot[i]->is_hidden() && dock_slot[i]->get_tab_count()) {
+ dock_slot[i]->set_current_tab(0);
+ }
+ }
+
+}
EditorNode::EditorNode() {
@@ -3515,18 +3849,124 @@ EditorNode::EditorNode() {
menu_hb = memnew( HBoxContainer );
main_vbox->add_child(menu_hb);
- main_split = memnew( HSplitContainer );
- main_vbox->add_child(main_split);
- main_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
+ //left
+ left_l_hsplit = memnew( HSplitContainer );
+ main_vbox->add_child(left_l_hsplit);
+
+ left_l_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
+ left_l_vsplit = memnew( VSplitContainer );
+ left_l_hsplit->add_child(left_l_vsplit);
+ dock_slot[DOCK_SLOT_LEFT_UL]=memnew( TabContainer );
+ left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UL]);
+ dock_slot[DOCK_SLOT_LEFT_BL]=memnew( TabContainer );
+ left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BL]);
+ left_l_vsplit->hide();
+ dock_slot[DOCK_SLOT_LEFT_UL]->hide();
+ dock_slot[DOCK_SLOT_LEFT_BL]->hide();
+
+ left_r_hsplit = memnew( HSplitContainer );
+ left_l_hsplit->add_child(left_r_hsplit);
+ left_r_vsplit = memnew( VSplitContainer );
+ left_r_hsplit->add_child(left_r_vsplit);
+ dock_slot[DOCK_SLOT_LEFT_UR]=memnew( TabContainer );
+ left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UR]);
+ dock_slot[DOCK_SLOT_LEFT_BR]=memnew( TabContainer );
+ left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BR]);
+ //left_r_vsplit->hide();
+ //dock_slot[DOCK_SLOT_LEFT_UR]->hide();
+ //dock_slot[DOCK_SLOT_LEFT_BR]->hide();
+
+
+ main_hsplit = memnew( HSplitContainer );
+ left_r_hsplit->add_child(main_hsplit);
+ //main_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
+ center_split = memnew( VSplitContainer );
+ main_hsplit->add_child(center_split);
+ center_split->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ center_split->set_collapsed(false);
+
+ right_hsplit = memnew( HSplitContainer );
+ main_hsplit->add_child(right_hsplit);
+
+ right_l_vsplit = memnew( VSplitContainer );
+ right_hsplit->add_child(right_l_vsplit);
+ dock_slot[DOCK_SLOT_RIGHT_UL]=memnew( TabContainer );
+ right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UL]);
+ dock_slot[DOCK_SLOT_RIGHT_BL]=memnew( TabContainer );
+ right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BL]);
+
+ right_r_vsplit = memnew( VSplitContainer );
+ right_hsplit->add_child(right_r_vsplit);
+ dock_slot[DOCK_SLOT_RIGHT_UR]=memnew( TabContainer );
+ right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UR]);
+ dock_slot[DOCK_SLOT_RIGHT_BR]=memnew( TabContainer );
+ right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BR]);
+ right_r_vsplit->hide();
+ //dock_slot[DOCK_SLOT_RIGHT_UL]->hide();
+ //dock_slot[DOCK_SLOT_RIGHT_BL]->hide();
+
+ left_l_vsplit->connect("dragged",this,"_dock_split_dragged");
+ left_r_vsplit->connect("dragged",this,"_dock_split_dragged");
+ right_l_vsplit->connect("dragged",this,"_dock_split_dragged");
+ right_r_vsplit->connect("dragged",this,"_dock_split_dragged");
+
+
+ dock_select_popoup = memnew( PopupPanel );
+ gui_base->add_child(dock_select_popoup);
+ VBoxContainer *dock_vb = memnew( VBoxContainer );
+ dock_select_popoup->add_child(dock_vb);
+
+ HBoxContainer *dock_hb = memnew( HBoxContainer);
+ dock_tab_move_left = memnew( ToolButton );
+ dock_tab_move_left->set_icon(theme->get_icon("Back","EditorIcons"));
+ dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE);
+ dock_tab_move_left->connect("pressed",this,"_dock_move_left");
+ //dock_tab_move_left->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ dock_hb->add_child(dock_tab_move_left);
+ dock_hb->add_spacer();
+ dock_tab_move_right = memnew( ToolButton );
+ dock_tab_move_right->set_icon(theme->get_icon("Forward","EditorIcons"));
+ dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE);
+ dock_tab_move_right->connect("pressed",this,"_dock_move_right");
+
+ //dock_tab_move_right->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ dock_hb->add_child(dock_tab_move_right);
+ dock_vb->add_child(dock_hb);
+
+ dock_select = memnew( Control );
+ dock_select->set_custom_minimum_size(Size2(128,64));
+ dock_select->connect("input_event",this,"_dock_select_input");
+ dock_select->connect("draw",this,"_dock_select_draw");
+ dock_select->connect("mouse_exit",this,"_dock_popup_exit");
+ dock_select->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ dock_vb->add_child(dock_select);
+
+
+ dock_select_popoup->set_child_rect(dock_vb);
+ dock_select_popoup->set_as_minsize();
+ dock_select_rect_over=-1;
+ dock_popup_selected=-1;
+ //dock_select_popoup->set_(Size2(20,20));
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+ dock_slot[i]->set_custom_minimum_size(Size2(250,250));
+ dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ dock_slot[i]->set_popup(dock_select_popoup);
+ dock_slot[i]->connect("pre_popup_pressed",this,"_dock_pre_popup",varray(i));
+
+ //dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
+ }
- left_split = memnew( VSplitContainer );
- main_split->add_child(left_split);
- left_split->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- left_split->set_collapsed(false);
+ dock_drag_timer = memnew( Timer );
+ add_child(dock_drag_timer);
+ dock_drag_timer->set_wait_time(0.5);
+ dock_drag_timer->set_one_shot(true);
+ dock_drag_timer->connect("timeout",this,"_save_docks");
top_split = memnew( VSplitContainer );
- left_split->add_child(top_split);
+ center_split->add_child(top_split);
top_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
top_split->set_collapsed(true);
@@ -3895,45 +4335,47 @@ EditorNode::EditorNode() {
- editor_hsplit = memnew( HSplitContainer );
- main_split->add_child(editor_hsplit);
- editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ //editor_hsplit = memnew( HSplitContainer );
+ //main_split->add_child(editor_hsplit);
+ //editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor_vsplit = memnew( VSplitContainer );
- editor_hsplit->add_child(editor_vsplit);
+ //editor_vsplit = memnew( VSplitContainer );
+ //editor_hsplit->add_child(editor_vsplit);
- top_pallete = memnew( TabContainer );
+ //top_pallete = memnew( TabContainer );
scene_tree_dock = memnew( SceneTreeDock(this,scene_root,editor_selection,editor_data) );
scene_tree_dock->set_name("Scene");
- top_pallete->add_child(scene_tree_dock);
+ //top_pallete->add_child(scene_tree_dock);
+ dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock);
resources_dock = memnew( ResourcesDock(this) );
resources_dock->set_name("Resources");
- top_pallete->add_child(resources_dock);
- top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ //top_pallete->add_child(resources_dock);
+ dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(resources_dock);
+ //top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- Control *editor_spacer = memnew( Control );
+ /*Control *editor_spacer = memnew( Control );
editor_spacer->set_custom_minimum_size(Size2(260,200));
editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor_vsplit->add_child( editor_spacer );
editor_spacer->add_child( top_pallete );
- top_pallete->set_area_as_parent_rect();
+ top_pallete->set_area_as_parent_rect();*/
- prop_pallete = memnew( TabContainer );
+ //prop_pallete = memnew( TabContainer );
- prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ //prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor_spacer = memnew( Control );
+ /*editor_spacer = memnew( Control );
editor_spacer->set_custom_minimum_size(Size2(260,200));
editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor_vsplit->add_child( editor_spacer );
editor_spacer->add_child( prop_pallete );
- prop_pallete->set_area_as_parent_rect();
+ prop_pallete->set_area_as_parent_rect();*/
VBoxContainer *prop_editor_base = memnew( VBoxContainer );
prop_editor_base->set_name("Inspector"); // Properties?
- prop_pallete->add_child(prop_editor_base);
+ dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(prop_editor_base);
HBoxContainer *prop_editor_hb = memnew( HBoxContainer );
prop_editor_base->add_child(prop_editor_hb);
@@ -3975,14 +4417,15 @@ EditorNode::EditorNode() {
scenes_dock = memnew( ScenesDock(this) );
scenes_dock->set_name("FileSystem");
- prop_pallete->add_child(scenes_dock);
+ dock_slot[DOCK_SLOT_LEFT_BR]->add_child(scenes_dock);
+ //prop_pallete->add_child(scenes_dock);
scenes_dock->connect("open",this,"open_request");
scenes_dock->connect("instance",this,"_instance_request");
log = memnew( EditorLog );
- left_split->add_child(log);
+ center_split->add_child(log);
log->connect("close_request",this,"_close_messages");
log->connect("show_request",this,"_show_messages");
//left_split->set_dragger_visible(false);
@@ -3998,7 +4441,7 @@ EditorNode::EditorNode() {
animation_vb->add_child(animation_editor);
- left_split->connect("resized",this,"_vp_resized");
+ center_split->connect("resized",this,"_vp_resized");
animation_editor->hide();
@@ -4403,12 +4846,15 @@ EditorNode::EditorNode() {
Node::set_human_readable_collision_renaming(true);
+
+
// Ref<ImageTexture> it = gui_base->get_icon("logo","Icons");
// OS::get_singleton()->set_icon( it->get_data() );
for(int i=0;i<_init_callbacks.size();i++)
_init_callbacks[i]();
+ _load_docks();
}
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 365dff84ee..2ef9332c84 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -94,6 +94,8 @@
typedef void (*EditorNodeInitCallback)();
+
+
class EditorNode : public Node {
OBJ_TYPE( EditorNode, Node );
@@ -168,7 +170,17 @@ class EditorNode : public Node {
OBJECT_METHOD_BASE=500
};
-
+ enum DockSlot {
+ DOCK_SLOT_LEFT_UL,
+ DOCK_SLOT_LEFT_BL,
+ DOCK_SLOT_LEFT_UR,
+ DOCK_SLOT_LEFT_BR,
+ DOCK_SLOT_RIGHT_UL,
+ DOCK_SLOT_RIGHT_BL,
+ DOCK_SLOT_RIGHT_UR,
+ DOCK_SLOT_RIGHT_BR,
+ DOCK_SLOT_MAX
+ };
Node *edited_scene; //scene being edited
@@ -179,8 +191,22 @@ class EditorNode : public Node {
Control* scene_root_parent;
Control *gui_base;
VBoxContainer *main_vbox;
- HSplitContainer *main_split;
- VSplitContainer *left_split;
+
+
+
+ HSplitContainer *left_l_hsplit;
+ VSplitContainer *left_l_vsplit;
+ HSplitContainer *left_r_hsplit;
+ VSplitContainer *left_r_vsplit;
+ HSplitContainer *main_hsplit;
+ HSplitContainer *right_hsplit;
+ VSplitContainer *right_l_vsplit;
+ VSplitContainer *right_r_vsplit;
+
+ VSplitContainer *center_split;
+
+
+
int old_split_ofs;
VSplitContainer *top_split;
HBoxContainer *bottom_hb;
@@ -190,8 +216,9 @@ class EditorNode : public Node {
TextureButton *anim_close;
Panel *menu_panel;
- HSplitContainer *editor_hsplit;
- VSplitContainer *editor_vsplit;
+
+ //HSplitContainer *editor_hsplit;
+ //VSplitContainer *editor_vsplit;
HBoxContainer *menu_hb;
Control *viewport;
MenuButton *file_menu;
@@ -249,8 +276,8 @@ class EditorNode : public Node {
String current_path;
MenuButton *update_menu;
ToolButton *sources_button;
- TabContainer *prop_pallete;
- TabContainer *top_pallete;
+ //TabContainer *prop_pallete;
+ //TabContainer *top_pallete;
String defer_load_scene;
String defer_translatable;
String defer_optimize;
@@ -277,6 +304,16 @@ class EditorNode : public Node {
ProgressDialog *progress_dialog;
BackgroundProgress *progress_hb;
+ TabContainer *dock_slot[DOCK_SLOT_MAX];
+ Rect2 dock_select_rect[DOCK_SLOT_MAX];
+ int dock_select_rect_over;
+ PopupPanel *dock_select_popoup;
+ Control *dock_select;
+ ToolButton *dock_tab_move_left;
+ ToolButton *dock_tab_move_right;
+ int dock_popup_selected;
+ Timer *dock_drag_timer;
+
String _tmp_import_path;
EditorImportExport *editor_import_export;
@@ -417,6 +454,16 @@ class EditorNode : public Node {
bool _find_scene_in_use(Node* p_node,const String& p_path) const;
+ void _dock_select_input(const InputEvent& p_input);
+ void _dock_move_left();
+ void _dock_move_right();
+ void _dock_select_draw();
+ void _dock_pre_popup(int p_which);
+ void _dock_split_dragged(int ofs);
+ void _dock_popup_exit();
+
+ void _save_docks();
+ void _load_docks();
protected:
void _notification(int p_what);
diff --git a/tools/editor/groups_editor.cpp b/tools/editor/groups_editor.cpp
index ed76f54562..2e82854014 100644
--- a/tools/editor/groups_editor.cpp
+++ b/tools/editor/groups_editor.cpp
@@ -39,6 +39,9 @@ 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");
+ }
}
void GroupsEditor::_close() {
diff --git a/tools/editor/icons/icon_back_disabled.png b/tools/editor/icons/icon_back_disabled.png
new file mode 100644
index 0000000000..31aab496e2
--- /dev/null
+++ b/tools/editor/icons/icon_back_disabled.png
Binary files differ
diff --git a/tools/editor/icons/icon_tab_menu.png b/tools/editor/icons/icon_tab_menu.png
new file mode 100644
index 0000000000..29edd02f01
--- /dev/null
+++ b/tools/editor/icons/icon_tab_menu.png
Binary files differ
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index fef5890f11..74b8202dc0 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -150,8 +150,46 @@ void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) {
_tool_select(TOOL_MOVE);
if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_E)
_tool_select(TOOL_ROTATE);
- if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_ALL && can_move_pivot)
- drag=DRAG_PIVOT;
+ if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_NONE && can_move_pivot) {
+ if (p_ev.key.mod.shift) {
+ //move drag pivot
+ drag=DRAG_PIVOT;
+ } else if (!Input::get_singleton()->is_mouse_button_pressed(0)) {
+
+ List<Node*> &selection = editor_selection->get_selected_node_list();
+
+ Vector2 mouse_pos = viewport->get_local_mouse_pos();
+ if (selection.size() && viewport->get_rect().has_point(mouse_pos)) {
+ //just in case, make it work if over viewport
+ mouse_pos=transform.affine_inverse().xform(mouse_pos);
+ mouse_pos=snap_point(mouse_pos);
+
+ undo_redo->create_action("Move Pivot");
+
+ for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
+
+ Node2D *n2d = E->get()->cast_to<Node2D>();
+
+ if (n2d && n2d->edit_has_pivot()) {
+
+ Vector2 offset = n2d->edit_get_pivot();
+ Vector2 gpos = n2d->get_global_pos();
+
+
+ undo_redo->add_do_method(n2d,"set_global_pos",mouse_pos);
+ undo_redo->add_do_method(n2d,"edit_set_pivot",offset+(gpos-mouse_pos));
+ undo_redo->add_undo_method(n2d,"set_global_pos",gpos);
+ undo_redo->add_undo_method(n2d,"edit_set_pivot",offset);
+
+ }
+
+ }
+
+ undo_redo->commit_action();
+ }
+
+ }
+ }
}
@@ -1685,7 +1723,7 @@ void CanvasItemEditor::_viewport_draw() {
viewport->draw_line(endpoints[i],endpoints[(i+1)%4],c,2);
}
- if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE)) { //kind of sucks
+ if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE)) { //kind of sucks
if (canvas_item->cast_to<Node2D>()) {
@@ -2854,7 +2892,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->add_child(select_button);
select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_SELECT));
select_button->set_pressed(true);
- select_button->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nPress 'v' to Move Pivot (while moving)");
+ select_button->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nPress 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).");
move_button = memnew( ToolButton );
move_button->set_toggle_mode(true);
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 98e0df77f7..a7636f517f 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -1915,6 +1915,7 @@ void PropertyEditor::_notification(int p_what) {
}
if (p_what==NOTIFICATION_EXIT_TREE) {
+ get_tree()->disconnect("node_removed",this,"_node_removed");
edit(NULL);
}
diff --git a/tools/editor/reparent_dialog.cpp b/tools/editor/reparent_dialog.cpp
index d35316f67f..6d0c5b867e 100644
--- a/tools/editor/reparent_dialog.cpp
+++ b/tools/editor/reparent_dialog.cpp
@@ -41,6 +41,11 @@ void ReparentDialog::_notification(int p_what) {
connect("confirmed", this,"_reparent");
}
+ if (p_what==NOTIFICATION_EXIT_TREE) {
+
+ disconnect("confirmed", this,"_reparent");
+ }
+
if (p_what==NOTIFICATION_DRAW) {
//RID ci = get_canvas_item();
diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp
index 432f60fa53..49cbebdb43 100644
--- a/tools/editor/scene_tree_dock.cpp
+++ b/tools/editor/scene_tree_dock.cpp
@@ -471,8 +471,18 @@ void SceneTreeDock::_notification(int p_what) {
switch(p_what) {
- case NOTIFICATION_ENTER_TREE: {
+ case NOTIFICATION_READY: {
+
+ if (!first_enter)
+ break;
+ first_enter=false;
+ CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>();
+ if (canvas_item_plugin) {
+ canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
+ canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
+ scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update");
+ }
static const char* button_names[TOOL_BUTTON_MAX]={
"New",
"Add",
@@ -487,19 +497,12 @@ void SceneTreeDock::_notification(int p_what) {
"Remove",
};
+
+
for(int i=0;i<TOOL_BUTTON_MAX;i++)
tool_buttons[i]->set_icon(get_icon(button_names[i],"EditorIcons"));
} break;
- case NOTIFICATION_READY: {
-
- CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>();
- if (canvas_item_plugin) {
- canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
- canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
- scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update");
- }
- } break;
}
}
@@ -1367,7 +1370,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
add_child(import_subscene_dialog);
import_subscene_dialog->connect("subscene_selected",this,"_import_subscene");
-
+ first_enter=true;
}
diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h
index 34e8a00739..4baa4ef37b 100644
--- a/tools/editor/scene_tree_dock.h
+++ b/tools/editor/scene_tree_dock.h
@@ -90,6 +90,7 @@ class SceneTreeDock : public VBoxContainer {
EditorFileDialog *file;
EditorSubScene *import_subscene_dialog;
+ bool first_enter;
void _create();
Node *scene_root;
diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp
index 94eea969fe..fd841028a2 100644
--- a/tools/editor/scene_tree_editor.cpp
+++ b/tools/editor/scene_tree_editor.cpp
@@ -498,6 +498,7 @@ void SceneTreeEditor::_notification(int p_what) {
get_tree()->disconnect("tree_changed",this,"_tree_changed");
get_tree()->disconnect("node_removed",this,"_node_removed");
+ tree->disconnect("item_collapsed",this,"_cell_collapsed");
_update_tree();
}
@@ -810,6 +811,11 @@ void SceneTreeDialog::_notification(int p_what) {
connect("confirmed", this,"_select");
}
+
+ if (p_what==NOTIFICATION_EXIT_TREE) {
+ disconnect("confirmed", this,"_select");
+
+ }
if (p_what==NOTIFICATION_DRAW) {
RID ci = get_canvas_item();