summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/control.cpp24
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/main/node.cpp9
-rw-r--r--scene/main/viewport.cpp76
-rw-r--r--scene/main/viewport.h7
5 files changed, 89 insertions, 29 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 90c72989bd..8f6a0b4d53 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -606,14 +606,14 @@ void Control::force_drag(const Variant& p_data,Control *p_control) {
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND(p_data.get_type()==Variant::NIL);
- get_viewport()->_gui_force_drag(p_data,p_control);
+ get_viewport()->_gui_force_drag(this,p_data,p_control);
}
void Control::set_drag_preview(Control *p_control) {
ERR_FAIL_COND(!is_inside_tree());
- get_viewport()->_gui_set_drag_preview(p_control);
+ get_viewport()->_gui_set_drag_preview(this,p_control);
}
@@ -2046,6 +2046,26 @@ Vector2 Control::get_scale() const{
return data.scale;
}
+Control *Control::get_root_parent_control() const {
+
+ const CanvasItem *ci=this;
+ const Control *root=this;
+
+ while(ci) {
+
+ const Control *c = ci->cast_to<Control>();
+ if (c) {
+ root=c;
+
+ if (c->data.RI || c->data.MI || c->is_toplevel_control())
+ break;
+ }
+
+ ci=ci->get_parent_item();
+ }
+
+ return const_cast<Control*>(root);
+}
void Control::_bind_methods() {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index ab777a6a6c..a16d88a6df 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -360,6 +360,8 @@ public:
virtual bool is_text_field() const;
+ Control *get_root_parent_control() const;
+
Control();
~Control();
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 0780a4bdaf..191e3ec04c 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1510,6 +1510,15 @@ Node *Node::duplicate(bool p_use_instancing) const {
node->set_name(get_name());
+ List<GroupInfo> gi;
+ get_groups(&gi);
+ for (List<GroupInfo>::Element *E=gi.front();E;E=E->next()) {
+
+ node->add_to_group(E->get().name, E->get().persistent);
+ }
+
+ _duplicate_signals(this, node);
+
for(int i=0;i<get_child_count();i++) {
if (get_child(i)->data.parent_owned)
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 032fdab6bd..5e8868c326 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -162,11 +162,10 @@ void Viewport::_update_rect() {
if (!is_inside_tree())
return;
- Node *parent = get_parent();
- if (!render_target && parent && parent->cast_to<Control>()) {
+ if (!render_target && parent_control) {
- Control *c = parent->cast_to<Control>();
+ Control *c = parent_control;
rect.pos=Point2();
rect.size=c->get_size();
@@ -175,6 +174,7 @@ void Viewport::_update_rect() {
VisualServer::ViewportRect vr;
vr.x=rect.pos.x;
vr.y=rect.pos.y;
+
if (render_target) {
vr.x=0;
vr.y=0;
@@ -206,11 +206,10 @@ void Viewport::_parent_draw() {
void Viewport::_parent_visibility_changed() {
- Node *parent = get_parent();
- if (parent && parent->cast_to<Control>()) {
+ if (parent_control) {
- Control *c = parent->cast_to<Control>();
+ Control *c = parent_control;
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,c->is_visible());
_update_listener();
@@ -223,11 +222,9 @@ void Viewport::_parent_visibility_changed() {
void Viewport::_vp_enter_tree() {
- Node *parent = get_parent();
- //none?
- if (parent && parent->cast_to<Control>()) {
+ if (parent_control) {
- Control *cparent=parent->cast_to<Control>();
+ Control *cparent=parent_control;
RID parent_ci = cparent->get_canvas_item();
ERR_FAIL_COND(!parent_ci.is_valid());
canvas_item = VisualServer::get_singleton()->canvas_item_create();
@@ -235,8 +232,8 @@ void Viewport::_vp_enter_tree() {
VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent_ci);
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,false);
VisualServer::get_singleton()->canvas_item_attach_viewport(canvas_item,viewport);
- parent->connect("resized",this,"_parent_resized");
- parent->connect("visibility_changed",this,"_parent_visibility_changed");
+ parent_control->connect("resized",this,"_parent_resized");
+ parent_control->connect("visibility_changed",this,"_parent_visibility_changed");
} else if (!parent){
VisualServer::get_singleton()->viewport_attach_to_screen(viewport,0);
@@ -248,15 +245,14 @@ void Viewport::_vp_enter_tree() {
void Viewport::_vp_exit_tree() {
- Node *parent = get_parent();
- if (parent && parent->cast_to<Control>()) {
+ if (parent_control) {
- parent->disconnect("resized",this,"_parent_resized");
+ parent_control->disconnect("resized",this,"_parent_resized");
}
- if (parent && parent->cast_to<Control>()) {
+ if (parent_control) {
- parent->disconnect("visibility_changed",this,"_parent_visibility_changed");
+ parent_control->disconnect("visibility_changed",this,"_parent_visibility_changed");
}
if (canvas_item.is_valid()) {
@@ -328,6 +324,12 @@ void Viewport::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
+ if (get_parent()) {
+ Node *parent=get_parent();
+ if (parent) {
+ parent_control=parent->cast_to<Control>();
+ }
+ }
if (!render_target)
_vp_enter_tree();
@@ -423,6 +425,7 @@ void Viewport::_notification(int p_what) {
}
remove_from_group("_viewports");
+ parent_control=NULL;
} break;
case NOTIFICATION_FIXED_PROCESS: {
@@ -1276,6 +1279,15 @@ void Viewport::_vp_input(const InputEvent& p_ev) {
if (disable_input)
return;
+#ifdef TOOLS_ENABLED
+ if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
+ return;
+ }
+#endif
+
+ if (parent_control && !parent_control->is_visible())
+ return;
+
if (render_target && to_screen_rect==Rect2())
return; //if render target, can't get input events
@@ -1291,6 +1303,17 @@ void Viewport::_vp_input(const InputEvent& p_ev) {
void Viewport::_vp_unhandled_input(const InputEvent& p_ev) {
+ if (disable_input)
+ return;
+
+#ifdef TOOLS_ENABLED
+ if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
+ return;
+ }
+#endif
+
+ if (parent_control && !parent_control->is_visible())
+ return;
if (render_target && to_screen_rect==Rect2())
return; //if render target, can't get input events
@@ -1437,7 +1460,7 @@ Control* Viewport::_gui_find_control(const Point2& p_global) {
Matrix32 xform;
CanvasItem *pci = sw->get_parent_item();
if (pci)
- xform=pci->get_global_transform();
+ xform=pci->get_global_transform_with_canvas();
Control *ret = _gui_find_control_at_pos(sw,p_global,xform,gui.focus_inv_xform);
@@ -1454,7 +1477,7 @@ Control* Viewport::_gui_find_control(const Point2& p_global) {
Matrix32 xform;
CanvasItem *pci = sw->get_parent_item();
if (pci)
- xform=pci->get_global_transform();
+ xform=pci->get_global_transform_with_canvas();
Control *ret = _gui_find_control_at_pos(sw,p_global,xform,gui.focus_inv_xform);
@@ -1557,7 +1580,6 @@ void Viewport::_gui_input_event(InputEvent p_event) {
Vector2 pos = top->get_global_transform_with_canvas().affine_inverse().xform(mpos);
if (!top->has_point(pos)) {
- print_line("NO POINT");
if (top->data.modal_exclusive) {
//cancel event, sorry, modal exclusive EATS UP ALL
//get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
@@ -1795,7 +1817,6 @@ void Viewport::_gui_input_event(InputEvent p_event) {
Control::CursorShape cursor_shape = over->get_cursor_shape(pos);
-
OS::get_singleton()->set_cursor_shape( (OS::CursorShape)cursor_shape );
@@ -1958,17 +1979,17 @@ void Viewport::_gui_remove_from_modal_stack(List<Control*>::Element *MI,ObjectID
}
}
-void Viewport::_gui_force_drag(const Variant& p_data,Control *p_control) {
+void Viewport::_gui_force_drag(Control *p_base, const Variant& p_data, Control *p_control) {
gui.drag_data=p_data;
gui.mouse_focus=NULL;
if (p_control) {
- _gui_set_drag_preview(p_control);
+ _gui_set_drag_preview(p_base,p_control);
}
}
-void Viewport::_gui_set_drag_preview(Control *p_control) {
+void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
ERR_FAIL_NULL(p_control);
ERR_FAIL_COND( !((Object*)p_control)->cast_to<Control>());
@@ -1980,7 +2001,7 @@ void Viewport::_gui_set_drag_preview(Control *p_control) {
}
p_control->set_as_toplevel(true);
p_control->set_pos(gui.last_mouse_pos);
- add_child(p_control); //add as child of viewport
+ p_base->get_root_parent_control()->add_child(p_control); //add as child of viewport
p_control->raise();
if (gui.drag_preview) {
memdelete( gui.drag_preview );
@@ -2149,6 +2170,8 @@ void Viewport::_gui_grab_click_focus(Control *p_control) {
void Viewport::input(const InputEvent& p_event) {
ERR_FAIL_COND(!is_inside_tree());
+
+
get_tree()->_call_input_pause(input_group,"_input",p_event);
_gui_input_event(p_event);
//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check
@@ -2158,6 +2181,7 @@ void Viewport::unhandled_input(const InputEvent& p_event) {
ERR_FAIL_COND(!is_inside_tree());
+
get_tree()->_call_input_pause(unhandled_input_group,"_unhandled_input",p_event);
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
if (!get_tree()->input_handled && p_event.type==InputEvent::KEY) {
@@ -2449,6 +2473,8 @@ Viewport::Viewport() {
gui.drag_attempted=false;
gui.drag_preview=NULL;
+ parent_control=NULL;
+
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 97ceb8de4b..89e053d607 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -87,6 +87,9 @@ public:
private:
friend class RenderTargetTexture;
+
+
+ Control *parent_control;
Viewport *parent;
Camera *camera;
@@ -243,8 +246,8 @@ friend class Control;
void _gui_remove_control(Control *p_control);
void _gui_hid_control(Control *p_control);
- void _gui_force_drag(const Variant& p_data,Control *p_control);
- void _gui_set_drag_preview(Control *p_control);
+ void _gui_force_drag(Control *p_base,const Variant& p_data,Control *p_control);
+ void _gui_set_drag_preview(Control *p_base,Control *p_control);
bool _gui_is_modal_on_top(const Control* p_control);
List<Control*>::Element* _gui_show_modal(Control* p_control);