summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorMariano Javier Suligoy <marianognu.easyrpg@gmail.com>2015-08-03 17:28:33 -0300
committerMariano Javier Suligoy <marianognu.easyrpg@gmail.com>2015-08-03 17:28:33 -0300
commitc88038228ae9b5c53d5d7ff3f1d99ac0adbc30eb (patch)
tree8df611ec64e5f58d32e09512bac9d1f5a662403d /scene
parentd7279ddaf2aa98ed962d84d466f21dc2f39522c9 (diff)
parentcbee679bd78c1b3317db1ea4e349f278576304a1 (diff)
Merge branch 'master' of https://github.com/okamstudio/godot
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/tile_map.cpp5
-rw-r--r--scene/2d/tile_map.h2
-rw-r--r--scene/gui/tabs.cpp115
-rw-r--r--scene/gui/tabs.h7
-rw-r--r--scene/main/node.cpp110
-rw-r--r--scene/main/node.h5
-rw-r--r--scene/main/scene_main_loop.cpp393
-rw-r--r--scene/main/scene_main_loop.h52
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
9 files changed, 679 insertions, 14 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 2fca1e67e8..17f93f816f 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -579,6 +579,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey,Quadrant>::Element *Q) {
call_deferred("_update_dirty_quadrants");
}
+void TileMap::set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
+
+ set_cell(p_pos.x,p_pos.y,p_tile,p_flip_x,p_flip_y,p_transpose);
+}
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
@@ -1106,6 +1110,7 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce);
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("set_cellv","pos","tile","flip_x","flip_y","transpose"),&TileMap::set_cellv,DEFVAL(false),DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 84ca65da4f..60534cce15 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -207,6 +207,8 @@ public:
bool is_cell_y_flipped(int p_x,int p_y) const;
bool is_cell_transposed(int p_x,int p_y) const;
+ void set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false);
+
Rect2 get_item_rect() const;
void set_collision_layer(uint32_t p_layer);
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 40a6e20c37..a849d3ae72 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -56,7 +56,14 @@ Size2 Tabs::get_minimum_size() const {
else
ms.width+=tab_bg->get_minimum_size().width;
+ if (tabs[i].right_button.is_valid()) {
+ Ref<Texture> rb=tabs[i].right_button;
+ Size2 bms = rb->get_size()+get_stylebox("button")->get_minimum_size();
+ bms.width+=get_constant("hseparation");
+ ms.width+=bms.width;
+ ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height);
+ }
}
return ms;
@@ -66,6 +73,39 @@ Size2 Tabs::get_minimum_size() const {
void Tabs::_input_event(const InputEvent& p_event) {
+ if (p_event.type==InputEvent::MOUSE_MOTION) {
+
+ Point2 pos( p_event.mouse_motion.x, p_event.mouse_motion.y );
+
+ int hover=-1;
+ for(int i=0;i<tabs.size();i++) {
+
+ if (tabs[i].rb_rect.has_point(pos)) {
+ hover=i;
+ break;
+ }
+ }
+
+ if (hover!=rb_hover) {
+ rb_hover=hover;
+ update();
+ }
+ return;
+ }
+
+ if (rb_pressing && p_event.type==InputEvent::MOUSE_BUTTON &&
+ !p_event.mouse_button.pressed &&
+ p_event.mouse_button.button_index==BUTTON_LEFT) {
+
+ if (rb_hover!=-1) {
+ //pressed
+ emit_signal("right_button_pressed",rb_hover);
+ }
+
+ rb_pressing=false;
+ update();
+ }
+
if (p_event.type==InputEvent::MOUSE_BUTTON &&
p_event.mouse_button.pressed &&
p_event.mouse_button.button_index==BUTTON_LEFT) {
@@ -76,6 +116,12 @@ void Tabs::_input_event(const InputEvent& p_event) {
int found=-1;
for(int i=0;i<tabs.size();i++) {
+ if (tabs[i].rb_rect.has_point(pos)) {
+ rb_pressing=true;
+ update();
+ return;
+ }
+
int ofs=tabs[i].ofs_cache;
int size = tabs[i].ofs_cache;
if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
@@ -100,7 +146,10 @@ void Tabs::_notification(int p_what) {
switch(p_what) {
-
+ case NOTIFICATION_MOUSE_EXIT: {
+ rb_hover=-1;
+ update();
+ } break;
case NOTIFICATION_DRAW: {
RID ci = get_canvas_item();
@@ -142,7 +191,7 @@ void Tabs::_notification(int p_what) {
Ref<Texture> icon;
if (tabs[i].icon.is_valid()) {
- Ref<Texture> icon = tabs[i].icon;
+ icon = tabs[i].icon;
if (icon.is_valid()) {
lsize+=icon->get_width();
if (s!="")
@@ -151,6 +200,16 @@ void Tabs::_notification(int p_what) {
}
}
+ if (tabs[i].right_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> rb=tabs[i].right_button;
+
+ lsize+=get_constant("hseparation");
+ lsize+=style->get_margin(MARGIN_LEFT);
+ lsize+=rb->get_width();
+ lsize+=style->get_margin(MARGIN_RIGHT);
+
+ }
Ref<StyleBox> sb;
int va;
@@ -184,7 +243,37 @@ void Tabs::_notification(int p_what) {
font->draw(ci, Point2i( w, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-font->get_height())/2+font->get_ascent() ), s, col );
- w+=slen+sb->get_margin(MARGIN_RIGHT);
+ w+=slen;
+
+ if (tabs[i].right_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> rb=tabs[i].right_button;
+
+ w+=get_constant("hseparation");
+
+ Rect2 rb_rect;
+ rb_rect.size=style->get_minimum_size()+rb->get_size();
+ rb_rect.pos.x=w;
+ rb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(rb_rect.size.y))/2;
+
+ if (rb_hover==i) {
+ if (rb_pressing)
+ get_stylebox("button_pressed")->draw(ci,rb_rect);
+ else
+ style->draw(ci,rb_rect);
+ }
+
+ w+=style->get_margin(MARGIN_LEFT);
+
+ rb->draw(ci,Point2i( w,rb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
+ w+=rb->get_width();
+ w+=style->get_margin(MARGIN_RIGHT);
+ tabs[i].rb_rect=rb_rect;
+
+
+ }
+
+ w+=sb->get_margin(MARGIN_RIGHT);
tabs[i].size_cache=w-tabs[i].ofs_cache;
@@ -252,6 +341,23 @@ Ref<Texture> Tabs::get_tab_icon(int p_tab) const{
}
+
+
+void Tabs::set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button){
+
+ ERR_FAIL_INDEX(p_tab,tabs.size());
+ tabs[p_tab].right_button=p_right_button;
+ update();
+ minimum_size_changed();
+
+}
+Ref<Texture> Tabs::get_tab_right_button(int p_tab) const{
+
+ ERR_FAIL_INDEX_V(p_tab,tabs.size(),Ref<Texture>());
+ return tabs[p_tab].right_button;
+
+}
+
void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) {
Tab t;
@@ -316,6 +422,7 @@ void Tabs::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_tab_align"),&Tabs::get_tab_align);
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
+ ADD_SIGNAL(MethodInfo("right_button_pressed",PropertyInfo(Variant::INT,"tab")));
ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") );
@@ -328,5 +435,7 @@ Tabs::Tabs() {
current=0;
tab_align=ALIGN_CENTER;
+ rb_hover=-1;
+ rb_pressing=false;
}
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 8d4d0123f8..5cb0d9e916 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -51,6 +51,8 @@ private:
Ref<Texture> icon;
int ofs_cache;
int size_cache;
+ Ref<Texture> right_button;
+ Rect2 rb_rect;
};
Vector<Tab> tabs;
@@ -58,6 +60,8 @@ private:
Control *_get_tab(int idx) const;
int _get_top_margin() const;
TabAlign tab_align;
+ int rb_hover;
+ bool rb_pressing;
protected:
@@ -75,6 +79,9 @@ public:
void set_tab_icon(int p_tab,const Ref<Texture>& p_icon);
Ref<Texture> get_tab_icon(int p_tab) const;
+ void set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button);
+ Ref<Texture> get_tab_right_button(int p_tab) const;
+
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 7e31bf8dd0..8336ce35f6 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -196,6 +196,14 @@ void Node::_propagate_enter_tree() {
}
data.blocked--;
+
+#ifdef DEBUG_ENABLED
+
+ if (ScriptDebugger::get_singleton() && data.filename!=String()) {
+ //used for live edit
+ data.tree->live_scene_edit_cache[data.filename].insert(this);
+ }
+#endif
// enter groups
}
@@ -205,6 +213,28 @@ void Node::_propagate_exit_tree() {
//block while removing children
+#ifdef DEBUG_ENABLED
+
+ if (ScriptDebugger::get_singleton() && data.filename!=String()) {
+ //used for live edit
+ Map<String,Set<Node*> >::Element *E=data.tree->live_scene_edit_cache.find(data.filename);
+ if (E) {
+ E->get().erase(this);
+ if (E->get().size()==0) {
+ data.tree->live_scene_edit_cache.erase(E);
+ }
+ }
+
+ Map<Node*,Map<ObjectID,Node*> >::Element *F=data.tree->live_edit_remove_list.find(this);
+ if (F) {
+ for (Map<ObjectID,Node*>::Element*G=F->get().front();G;G=G->next()) {
+
+ memdelete(G->get());
+ }
+ data.tree->live_edit_remove_list.erase(F);
+ }
+ }
+#endif
data.blocked++;
for (int i=data.children.size()-1;i>=0;i--) {
@@ -552,6 +582,52 @@ void Node::set_human_readable_collision_renaming(bool p_enabled) {
}
+
+String Node::validate_child_name(const String& p_name) const {
+
+ //this approach to autoset node names is human readable but very slow
+ //it's turned on while running in the editor
+
+ String basename = p_name;
+
+ if (basename==String()) {
+
+ return String();
+ }
+
+ int val=1;
+
+ for(;;) {
+
+ String attempted = val > 1 ? (basename + " " +itos(val) ) : basename;
+
+ bool found=false;
+
+ for (int i=0;i<data.children.size();i++) {
+
+ //if (data.children[i]==p_child)
+ // continue;
+ if (data.children[i]->get_name() == attempted) {
+ found=true;
+ break;
+ }
+
+ }
+
+ if (found) {
+
+ val++;
+ continue;
+ }
+
+ return attempted;
+ break;
+ }
+
+ return basename;
+
+}
+
void Node::_validate_child_name(Node *p_child) {
/* Make sure the name is unique */
@@ -1323,18 +1399,31 @@ int Node::get_position_in_parent() const {
-Node *Node::duplicate() const {
+Node *Node::duplicate(bool p_use_instancing) const {
Node *node=NULL;
- Object *obj = ObjectTypeDB::instance(get_type());
- ERR_FAIL_COND_V(!obj,NULL);
- node = obj->cast_to<Node>();
- if (!node)
- memdelete(obj);
- ERR_FAIL_COND_V(!node,NULL);
+ bool instanced=false;
+
+ if (p_use_instancing && get_filename()!=String()) {
+
+ Ref<PackedScene> res = ResourceLoader::load(get_filename());
+ ERR_FAIL_COND_V(res.is_null(),NULL);
+ node=res->instance();
+ ERR_FAIL_COND_V(!node,NULL);
+ instanced=true;
+
+ } else {
+
+ Object *obj = ObjectTypeDB::instance(get_type());
+ ERR_FAIL_COND_V(!obj,NULL);
+ node = obj->cast_to<Node>();
+ if (!node)
+ memdelete(obj);
+ ERR_FAIL_COND_V(!node,NULL);
+ }
if (get_filename()!="") { //an instance
@@ -1360,7 +1449,10 @@ Node *Node::duplicate() const {
if (get_child(i)->data.parent_owned)
continue;
- Node *dup = get_child(i)->duplicate();
+ if (instanced && get_child(i)->data.owner==this)
+ continue; //part of instance
+
+ Node *dup = get_child(i)->duplicate(p_use_instancing);
if (!dup) {
memdelete(node);
@@ -1882,7 +1974,7 @@ void Node::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_tree:SceneTree"),&Node::get_tree);
- ObjectTypeDB::bind_method(_MD("duplicate:Node"),&Node::duplicate);
+ ObjectTypeDB::bind_method(_MD("duplicate:Node","use_instancing"),&Node::duplicate,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("replace_by","node:Node","keep_data"),&Node::replace_by,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport);
diff --git a/scene/main/node.h b/scene/main/node.h
index be91c6e1bb..a6d5bfbd9f 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -255,8 +255,9 @@ public:
int get_position_in_parent() const;
- Node *duplicate() const;
+ Node *duplicate(bool p_use_instancing=false) const;
Node *duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const;
+
//Node *clone_tree() const;
// used by editors, to save what has changed only
@@ -275,6 +276,8 @@ public:
static void print_stray_nodes();
+ String validate_child_name(const String& p_name) const;
+
void queue_delete();
//shitty hacks for speed
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index 1664a9bea1..45e3d92ece 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -1044,7 +1044,371 @@ void SceneTree::add_current_scene(Node * p_current) {
current_scene=p_current;
root->add_child(p_current);
}
+#ifdef DEBUG_ENABLED
+void SceneTree::_live_edit_node_path_func(const NodePath &p_path,int p_id) {
+
+ live_edit_node_path_cache[p_id]=p_path;
+}
+
+void SceneTree::_live_edit_res_path_func(const String &p_path,int p_id) {
+
+ live_edit_resource_cache[p_id]=p_path;
+}
+
+void SceneTree::_live_edit_node_set_func(int p_id,const StringName& p_prop,const Variant& p_value) {
+
+ if (!live_edit_node_path_cache.has(p_id))
+ return;
+
+ NodePath np = live_edit_node_path_cache[p_id];
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(np))
+ continue;
+ Node *n2 = n->get_node(np);
+
+ n2->set(p_prop,p_value);
+ }
+
+}
+
+void SceneTree::_live_edit_node_set_res_func(int p_id,const StringName& p_prop,const String& p_value) {
+
+ RES r = ResourceLoader::load(p_value);
+ if (!r.is_valid())
+ return;
+ _live_edit_node_set_func(p_id,p_prop,r);
+
+}
+void SceneTree::_live_edit_node_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) {
+
+ if (!live_edit_node_path_cache.has(p_id))
+ return;
+
+ NodePath np = live_edit_node_path_cache[p_id];
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(np))
+ continue;
+ Node *n2 = n->get_node(np);
+
+ n2->call(p_method,VARIANT_ARG_PASS);
+ }
+}
+void SceneTree::_live_edit_res_set_func(int p_id,const StringName& p_prop,const Variant& p_value) {
+
+ if (!live_edit_resource_cache.has(p_id))
+ return;
+
+ String resp = live_edit_resource_cache[p_id];
+
+ if (!ResourceCache::has(resp))
+ return;
+
+ RES r = ResourceCache::get(resp);
+ if (!r.is_valid())
+ return;
+
+ r->set(p_prop,p_value);
+}
+void SceneTree::_live_edit_res_set_res_func(int p_id,const StringName& p_prop,const String& p_value) {
+
+ RES r = ResourceLoader::load(p_value);
+ if (!r.is_valid())
+ return;
+ _live_edit_res_set_func(p_id,p_prop,r);
+
+}
+void SceneTree::_live_edit_res_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) {
+
+ if (!live_edit_resource_cache.has(p_id))
+ return;
+
+ String resp = live_edit_resource_cache[p_id];
+
+ if (!ResourceCache::has(resp))
+ return;
+
+ RES r = ResourceCache::get(resp);
+ if (!r.is_valid())
+ return;
+
+ r->call(p_method,VARIANT_ARG_PASS);
+}
+
+void SceneTree::_live_edit_root_func(const NodePath& p_scene_path,const String& p_scene_from) {
+
+ live_edit_root=p_scene_path;
+ live_edit_scene=p_scene_from;
+}
+
+void SceneTree::_live_edit_create_node_func(const NodePath& p_parent,const String& p_type,const String& p_name) {
+
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_parent))
+ continue;
+ Node *n2 = n->get_node(p_parent);
+
+ Object *o = ObjectTypeDB::instance(p_type);
+ if (!o)
+ continue;
+ Node *no=o->cast_to<Node>();
+ no->set_name(p_name);
+
+ n2->add_child(no);
+ }
+}
+void SceneTree::_live_edit_instance_node_func(const NodePath& p_parent,const String& p_path,const String& p_name){
+
+ Ref<PackedScene> ps = ResourceLoader::load(p_path);
+
+ if (!ps.is_valid())
+ return;
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_parent))
+ continue;
+ Node *n2 = n->get_node(p_parent);
+
+
+
+ Node *no=ps->instance();
+ no->set_name(p_name);
+
+ n2->add_child(no);
+ }
+}
+void SceneTree::_live_edit_remove_node_func(const NodePath& p_at){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;) {
+
+ Set<Node*>::Element *N=F->next();
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *n2 = n->get_node(p_at);
+
+ memdelete(n2);
+
+ F=N;
+
+ }
+}
+void SceneTree::_live_edit_remove_and_keep_node_func(const NodePath& p_at,ObjectID p_keep_id){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+
+ for(Set<Node*>::Element *F=E->get().front();F;) {
+
+ Set<Node*>::Element *N=F->next();
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+
+ Node *n2 = n->get_node(p_at);
+
+ n2->get_parent()->remove_child(n2);
+
+ live_edit_remove_list[n][p_keep_id]=n2;
+
+ F=N;
+
+ }
+}
+void SceneTree::_live_edit_restore_node_func(ObjectID p_id,const NodePath& p_at,int p_at_pos){
+
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;) {
+
+ Set<Node*>::Element *N=F->next();
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *n2 = n->get_node(p_at);
+
+ Map<Node*,Map<ObjectID,Node*> >::Element *EN=live_edit_remove_list.find(n);
+
+ if (!EN)
+ continue;
+
+ Map<ObjectID,Node*>::Element *FN=EN->get().find(p_id);
+
+ if (!FN)
+ continue;
+ n2->add_child(FN->get());
+
+ EN->get().erase(FN);
+
+ if (EN->get().size()==0) {
+ live_edit_remove_list.erase(EN);
+ }
+
+ F=N;
+
+ }
+}
+void SceneTree::_live_edit_duplicate_node_func(const NodePath& p_at,const String& p_new_name){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *n2 = n->get_node(p_at);
+
+ Node *dup = n2->duplicate(true);
+
+ if (!dup)
+ continue;
+
+ dup->set_name(p_new_name);
+ n2->get_parent()->add_child(dup);
+
+ }
+}
+void SceneTree::_live_edit_reparent_node_func(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *nfrom = n->get_node(p_at);
+
+ if (!n->has_node(p_new_place))
+ continue;
+ Node *nto = n->get_node(p_new_place);
+
+ nfrom->get_parent()->remove_child(nfrom);
+ nfrom->set_name(p_new_name);
+
+ nto->add_child(nfrom);
+ if (p_at_pos>=0)
+ nto->move_child(nfrom,p_at_pos);
+
+ }
+}
+
+
+#endif
void SceneTree::_bind_methods() {
@@ -1169,6 +1533,35 @@ SceneTree::SceneTree() {
edited_scene_root=NULL;
#endif
+#ifdef DEBUG_ENABLED
+
+
+ live_edit_funcs.udata=this;
+ live_edit_funcs.node_path_func=_live_edit_node_path_funcs;
+ live_edit_funcs.res_path_func=_live_edit_res_path_funcs;
+ live_edit_funcs.node_set_func=_live_edit_node_set_funcs;
+ live_edit_funcs.node_set_res_func=_live_edit_node_set_res_funcs;
+ live_edit_funcs.node_call_func=_live_edit_node_call_funcs;
+ live_edit_funcs.res_set_func=_live_edit_res_set_funcs;
+ live_edit_funcs.res_set_res_func=_live_edit_res_set_res_funcs;
+ live_edit_funcs.res_call_func=_live_edit_res_call_funcs;
+ live_edit_funcs.root_func=_live_edit_root_funcs;
+
+ live_edit_funcs.tree_create_node_func=_live_edit_create_node_funcs;
+ live_edit_funcs.tree_instance_node_func=_live_edit_instance_node_funcs;
+ live_edit_funcs.tree_remove_node_func=_live_edit_remove_node_funcs;
+ live_edit_funcs.tree_remove_and_keep_node_func=_live_edit_remove_and_keep_node_funcs;
+ live_edit_funcs.tree_restore_node_func=_live_edit_restore_node_funcs;
+ live_edit_funcs.tree_duplicate_node_func=_live_edit_duplicate_node_funcs;
+ live_edit_funcs.tree_reparent_node_func=_live_edit_reparent_node_funcs;
+
+ if (ScriptDebugger::get_singleton()) {
+ ScriptDebugger::get_singleton()->set_live_edit_funcs(&live_edit_funcs);
+ }
+
+ live_edit_root=NodePath("/root");
+
+#endif
}
diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h
index e49c150fbf..1f09d9c546 100644
--- a/scene/main/scene_main_loop.h
+++ b/scene/main/scene_main_loop.h
@@ -164,6 +164,58 @@ friend class Viewport;
SelfList<Node>::List xform_change_list;
+#ifdef DEBUG_ENABLED
+
+ Map<int,NodePath> live_edit_node_path_cache;
+ Map<int,String> live_edit_resource_cache;
+
+ NodePath live_edit_root;
+ String live_edit_scene;
+
+ Map<String,Set<Node*> > live_scene_edit_cache;
+ Map<Node*,Map<ObjectID,Node*> > live_edit_remove_list;
+
+ ScriptDebugger::LiveEditFuncs live_edit_funcs;
+
+ void _live_edit_node_path_func(const NodePath &p_path,int p_id) ;
+ void _live_edit_res_path_func(const String &p_path,int p_id) ;
+
+ void _live_edit_node_set_func(int p_id,const StringName& p_prop,const Variant& p_value) ;
+ void _live_edit_node_set_res_func(int p_id,const StringName& p_prop,const String& p_value) ;
+ void _live_edit_node_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) ;
+ void _live_edit_res_set_func(int p_id,const StringName& p_prop,const Variant& p_value) ;
+ void _live_edit_res_set_res_func(int p_id,const StringName& p_prop,const String& p_value) ;
+ void _live_edit_res_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) ;
+ void _live_edit_root_func(const NodePath& p_scene_path,const String& p_scene_from) ;
+
+ void _live_edit_create_node_func(const NodePath& p_parent,const String& p_type,const String& p_name);
+ void _live_edit_instance_node_func(const NodePath& p_parent,const String& p_path,const String& p_name);
+ void _live_edit_remove_node_func(const NodePath& p_at);
+ void _live_edit_remove_and_keep_node_func(const NodePath& p_at,ObjectID p_keep_id);
+ void _live_edit_restore_node_func(ObjectID p_id,const NodePath& p_at,int p_at_pos);
+ void _live_edit_duplicate_node_func(const NodePath& p_at,const String& p_new_name);
+ void _live_edit_reparent_node_func(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos);
+
+ static void _live_edit_node_path_funcs(void *self,const NodePath &p_path,int p_id) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_path_func(p_path,p_id); }
+ static void _live_edit_res_path_funcs(void *self,const String &p_path,int p_id) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_path_func(p_path,p_id); }
+
+ static void _live_edit_node_set_funcs(void *self,int p_id,const StringName& p_prop,const Variant& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_set_func(p_id,p_prop,p_value); }
+ static void _live_edit_node_set_res_funcs(void *self,int p_id,const StringName& p_prop,const String& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_set_res_func(p_id,p_prop,p_value); }
+ static void _live_edit_node_call_funcs(void *self,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree*>(self)->_live_edit_node_call_func(p_id,p_method,VARIANT_ARG_PASS); }
+ static void _live_edit_res_set_funcs(void *self,int p_id,const StringName& p_prop,const Variant& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_set_func(p_id,p_prop,p_value); }
+ static void _live_edit_res_set_res_funcs(void *self,int p_id,const StringName& p_prop,const String& p_value) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_set_res_func(p_id,p_prop,p_value); }
+ static void _live_edit_res_call_funcs(void *self,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree*>(self)->_live_edit_res_call_func(p_id,p_method,VARIANT_ARG_PASS); }
+ static void _live_edit_root_funcs(void *self, const NodePath& p_scene_path,const String& p_scene_from) { reinterpret_cast<SceneTree*>(self)->_live_edit_root_func(p_scene_path,p_scene_from); }
+
+ static void _live_edit_create_node_funcs(void* self,const NodePath& p_parent,const String& p_type,const String& p_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_create_node_func(p_parent,p_type,p_name); }
+ static void _live_edit_instance_node_funcs(void* self,const NodePath& p_parent,const String& p_path,const String& p_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_instance_node_func(p_parent,p_path,p_name); }
+ static void _live_edit_remove_node_funcs(void* self,const NodePath& p_at) { reinterpret_cast<SceneTree*>(self)->_live_edit_remove_node_func(p_at); }
+ static void _live_edit_remove_and_keep_node_funcs(void* self,const NodePath& p_at,ObjectID p_keep_id) { reinterpret_cast<SceneTree*>(self)->_live_edit_remove_and_keep_node_func(p_at,p_keep_id); }
+ static void _live_edit_restore_node_funcs(void* self,ObjectID p_id,const NodePath& p_at,int p_at_pos) { reinterpret_cast<SceneTree*>(self)->_live_edit_restore_node_func(p_id,p_at,p_at_pos); }
+ static void _live_edit_duplicate_node_funcs(void* self,const NodePath& p_at,const String& p_new_name) { reinterpret_cast<SceneTree*>(self)->_live_edit_duplicate_node_func(p_at,p_new_name); }
+ static void _live_edit_reparent_node_funcs(void* self,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos) { reinterpret_cast<SceneTree*>(self)->_live_edit_reparent_node_func(p_at,p_new_place,p_new_name,p_at_pos); }
+
+#endif
protected:
void _notification(int p_notification);
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 58ba5fba25..819d0a5cb9 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -250,7 +250,6 @@ void make_default_theme() {
t->set_stylebox("hover","ToolButton", make_stylebox( button_normal_png,4,4,4,4) );
t->set_stylebox("disabled","ToolButton", make_empty_stylebox(4,4,4,4) );
t->set_stylebox("focus","ToolButton", focus );
-
t->set_font("font","ToolButton", default_font );
t->set_color("font_color","ToolButton", control_font_color );
@@ -678,6 +677,9 @@ void make_default_theme() {
t->set_stylebox("tab_fg","Tabs", make_stylebox( tab_current_png,4,4,4,4,16,4,16,4) );
t->set_stylebox("tab_bg","Tabs", make_stylebox( tab_behind_png,4,4,4,4,16,6,16,4) );
t->set_stylebox("panel","Tabs", make_stylebox( tab_container_bg_png,4,4,4,4) );
+ t->set_stylebox("button_pressed","Tabs", make_stylebox( button_pressed_png,4,4,4,4) );
+ t->set_stylebox("button","Tabs", make_stylebox( button_normal_png,4,4,4,4) );
+
t->set_font("font","Tabs", default_font );