diff options
Diffstat (limited to 'scene')
| -rw-r--r-- | scene/gui/control.cpp | 24 | ||||
| -rw-r--r-- | scene/gui/control.h | 2 | ||||
| -rw-r--r-- | scene/main/node.cpp | 9 | ||||
| -rw-r--r-- | scene/main/viewport.cpp | 76 | ||||
| -rw-r--r-- | scene/main/viewport.h | 7 |
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); |