-Moved all the "root" input handling for GUI from individual Controls to Viewport.

-Should fix several reported bugs when controls don't have a common parent

This may have added new bugs, so please report if so!
This commit is contained in:
Juan Linietsky 2016-01-16 22:41:10 -03:00
parent 4081829923
commit 72fcb8a35b
10 changed files with 1156 additions and 1017 deletions

File diff suppressed because it is too large Load diff

View file

@ -124,7 +124,6 @@ private:
bool stop_mouse;
Control *parent;
Control *window;
bool modal;
bool modal_exclusive;
Ref<Theme> theme;
@ -134,11 +133,10 @@ private:
List<Control*>::Element *MI; //modal item
List<Control*>::Element *SI;
List<Control*>::Element *RI;
CanvasItem *parent_canvas_item;
Viewport *viewport;
ObjectID modal_prev_focus_owner;
NodePath focus_neighbour[4];
@ -149,66 +147,25 @@ private:
HashMap<StringName, Color, StringNameHasher > color_override;
HashMap<StringName, int, StringNameHasher > constant_override;
} data;
struct Window {
// info used when this is a window
bool key_event_accepted;
Control *mouse_focus;
int mouse_focus_button;
Control *key_focus;
Control *mouse_over;
Control *tooltip;
Panel *tooltip_popup;
Label *tooltip_label;
Point2 tooltip_pos;
Point2 last_mouse_pos;
Point2 drag_accum;
bool drag_attempted;
Variant drag_data;
Control *drag_preview;
Timer *tooltip_timer;
List<Control*> modal_stack;
unsigned int cancelled_input_ID;
Matrix32 focus_inv_xform;
bool subwindow_order_dirty;
List<Control*> subwindows;
bool disable_input;
Window();
};
Window *window;
// used internally
Control* _find_next_visible_control_at_pos(Node* p_node,const Point2& p_global,Matrix32& r_xform) const;
Control* _find_control_at_pos(CanvasItem* p_node,const Point2& p_pos,const Matrix32& p_xform,Matrix32& r_inv_xform);
void _window_sort_subwindows();
void _window_accept_event();
void _window_remove_focus();
void _window_cancel_input_ID(int p_input);
void _window_sort_modal_stack();
void _window_find_focus_neighbour(const Vector2& p_dir, Node *p_at, const Point2* p_points ,float p_min,float &r_closest_dist,Control **r_closest);
Control *_get_focus_neighbour(Margin p_margin,int p_count=0);
void _window_call_input(Control *p_control,const InputEvent& p_input);
float _get_parent_range(int p_idx) const;
float _get_range(int p_idx) const;
float _s2a(float p_val, AnchorType p_anchor,float p_range) const;
float _a2s(float p_val, AnchorType p_anchor,float p_range) const;
void _modal_stack_remove();
void _propagate_theme_changed(Control *p_owner);
void _change_notify_margins();
void _window_cancel_tooltip();
void _window_show_tooltip();
void _update_minimum_size();
void _update_scroll();
void _gui_input(const InputEvent& p_event); //used by scene main loop
void _input_text(const String& p_text);
void _resize(const Size2& p_size);
void _size_changed();
@ -217,10 +174,13 @@ private:
void _set_rotation_deg(float p_rot);
float _get_rotation_deg() const;
protected:
bool window_has_modal_stack() const;
friend class Viewport;
void _modal_stack_remove();
void _modal_set_prev_focus_owner(ObjectID p_prev);
virtual void _window_input_event(InputEvent p_event);
protected:
//virtual void _window_input_event(InputEvent p_event);
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
@ -272,8 +232,6 @@ public:
bool is_window_modal_on_top() const;
bool is_window() const;
Control *get_window() const;
Control *get_parent_control() const;

View file

@ -59,8 +59,6 @@ void Popup::_notification(int p_what) {
void Popup::_fix_size() {
Control *window = get_window();
ERR_FAIL_COND(!window);
#if 0
Point2 pos = get_pos();
@ -182,14 +180,12 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) {
void Popup::popup_centered(const Size2& p_size) {
Control *window = get_window();
ERR_FAIL_COND(!window);
Point2 window_size = get_viewport_rect().size;
emit_signal("about_to_show");
Rect2 rect;
rect.size = p_size==Size2()?get_size():p_size;
Point2 window_size = window==this ? get_parent_area_size() :window->get_size();
rect.pos = ((window_size-rect.size)/2.0).floor();
set_pos( rect.pos );
set_size( rect.size );
@ -209,13 +205,11 @@ void Popup::popup_centered(const Size2& p_size) {
void Popup::popup_centered_ratio(float p_screen_ratio) {
Control *window = get_window();
ERR_FAIL_COND(!window);
emit_signal("about_to_show");
Rect2 rect;
Point2 window_size = window==this ? get_parent_area_size() :window->get_size();
Point2 window_size = get_viewport_rect().size;
rect.size = (window_size * p_screen_ratio).floor();
rect.pos = ((window_size-rect.size)/2.0).floor();
set_pos( rect.pos );

View file

@ -330,7 +330,8 @@ void SceneTree::input_text( const String& p_text ) {
root_lock++;
call_group(GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input",p_text);
call_group(GROUP_CALL_REALTIME,"_viewports","_vp_input_text",p_text); //special one for GUI, as controls use their own process check
root_lock--;
}

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,11 @@
*/
class Camera;
class Control;
class CanvasItem;
class Panel;
class Label;
class Timer;
class Viewport;
class RenderTargetTexture : public Texture {
@ -162,6 +167,48 @@ friend class RenderTargetTexture;
Ref<RenderTargetTexture> render_target_texture;
struct GUI {
// info used when this is a window
bool key_event_accepted;
Control *mouse_focus;
int mouse_focus_button;
Control *key_focus;
Control *mouse_over;
Control *tooltip;
Panel *tooltip_popup;
Label *tooltip_label;
Point2 tooltip_pos;
Point2 last_mouse_pos;
Point2 drag_accum;
bool drag_attempted;
Variant drag_data;
Control *drag_preview;
Timer *tooltip_timer;
List<Control*> modal_stack;
unsigned int cancelled_input_ID;
Matrix32 focus_inv_xform;
bool subwindow_order_dirty;
List<Control*> subwindows;
bool roots_order_dirty;
List<Control*> roots;
GUI();
} gui;
bool disable_input;
void _gui_call_input(Control *p_control,const InputEvent& p_input);
void _gui_sort_subwindows();
void _gui_sort_roots();
void _gui_sort_modal_stack();
Control* _gui_find_control(const Point2& p_global);
Control* _gui_find_control_at_pos(CanvasItem* p_node,const Point2& p_global,const Matrix32& p_xform,Matrix32& r_inv_xform);
void _gui_input_event(InputEvent p_event);
void update_worlds();
_FORCE_INLINE_ Matrix32 _get_input_pre_xform() const;
@ -170,9 +217,47 @@ friend class RenderTargetTexture;
void _vp_exit_tree();
void _vp_input(const InputEvent& p_ev);
void _vp_input_text(const String& p_text);
void _vp_unhandled_input(const InputEvent& p_ev);
void _make_input_local(InputEvent& ev);
friend class Control;
List<Control*>::Element* _gui_add_root_control(Control* p_control);
List<Control*>::Element* _gui_add_subwindow_control(Control* p_control);
void _gui_set_subwindow_order_dirty();
void _gui_set_root_order_dirty();
void _gui_remove_modal_control(List<Control*>::Element *MI);
void _gui_remove_from_modal_stack(List<Control*>::Element *MI,ObjectID p_prev_focus_owner);
void _gui_remove_root_control(List<Control*>::Element *RI);
void _gui_remove_subwindow_control(List<Control*>::Element* SI);
void _gui_cancel_tooltip();
void _gui_show_tooltip();
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);
bool _gui_is_modal_on_top(const Control* p_control);
List<Control*>::Element* _gui_show_modal(Control* p_control);
void _gui_remove_focus();
void _gui_unfocus_control(Control *p_control);
bool _gui_control_has_focus(const Control* p_control);
void _gui_control_grab_focus(Control* p_control);
void _gui_grab_click_focus(Control *p_control);
void _gui_accept_event();
Control *_gui_get_focus_owner();
friend class Camera;
void _camera_transform_changed_notify();
void _set_camera(Camera* p_camera);
@ -254,6 +339,9 @@ public:
void input(const InputEvent& p_event);
void unhandled_input(const InputEvent& p_event);
void set_disable_input(bool p_disable);
bool is_input_disabled() const;
void set_render_target_to_screen_rect(const Rect2& p_rect);
Rect2 get_render_target_to_screen_rect() const;
@ -263,6 +351,9 @@ public:
void set_physics_object_picking(bool p_enable);
bool get_physics_object_picking();
bool gui_has_modal_stack() const;
Viewport();
~Viewport();

View file

@ -4964,8 +4964,9 @@ EditorNode::EditorNode() {
//scene_root_base->add_child(scene_root);
scene_root->set_meta("_editor_disable_input",true);
//scene_root->set_meta("_editor_disable_input",true);
VisualServer::get_singleton()->viewport_set_hide_scenario(scene_root->get_viewport(),true);
scene_root->set_disable_input(true);
scene_root->set_as_audio_listener_2d(true);
scene_root->set_size_override(true,Size2(Globals::get_singleton()->get("display/width"),Globals::get_singleton()->get("display/height")));

View file

@ -194,7 +194,7 @@ void CanvasItemEditor::_edit_set_pivot(const Vector2& mouse_pos) {
void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) {
if (!is_visible() || window_has_modal_stack())
if (!is_visible() || get_viewport()->gui_has_modal_stack())
return;
if (p_ev.key.mod.control)
// prevent to change tool mode when control key is pressed

View file

@ -3529,7 +3529,7 @@ void SpatialEditor::_instance_scene() {
void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
if (!is_visible() || window_has_modal_stack())
if (!is_visible() || get_viewport()->gui_has_modal_stack())
return;
{

View file

@ -39,12 +39,8 @@
Node *SceneTreeEditor::get_scene_node() {
ERR_FAIL_COND_V(!is_inside_tree(),NULL);
if (get_tree()->get_root()->get_child_count() && get_tree()->get_root()->get_child(0)->cast_to<EditorNode>())
return get_tree()->get_root()->get_child(0)->cast_to<EditorNode>()->get_edited_scene();
else
return get_tree()->get_root();
return NULL;
return get_tree()->get_edited_scene_root();
}