-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:
parent
4081829923
commit
72fcb8a35b
10 changed files with 1156 additions and 1017 deletions
File diff suppressed because it is too large
Load diff
|
@ -124,7 +124,6 @@ private:
|
||||||
bool stop_mouse;
|
bool stop_mouse;
|
||||||
|
|
||||||
Control *parent;
|
Control *parent;
|
||||||
Control *window;
|
|
||||||
bool modal;
|
bool modal;
|
||||||
bool modal_exclusive;
|
bool modal_exclusive;
|
||||||
Ref<Theme> theme;
|
Ref<Theme> theme;
|
||||||
|
@ -134,11 +133,10 @@ private:
|
||||||
|
|
||||||
List<Control*>::Element *MI; //modal item
|
List<Control*>::Element *MI; //modal item
|
||||||
List<Control*>::Element *SI;
|
List<Control*>::Element *SI;
|
||||||
|
List<Control*>::Element *RI;
|
||||||
|
|
||||||
CanvasItem *parent_canvas_item;
|
CanvasItem *parent_canvas_item;
|
||||||
|
|
||||||
Viewport *viewport;
|
|
||||||
|
|
||||||
ObjectID modal_prev_focus_owner;
|
ObjectID modal_prev_focus_owner;
|
||||||
|
|
||||||
NodePath focus_neighbour[4];
|
NodePath focus_neighbour[4];
|
||||||
|
@ -149,66 +147,25 @@ private:
|
||||||
HashMap<StringName, Color, StringNameHasher > color_override;
|
HashMap<StringName, Color, StringNameHasher > color_override;
|
||||||
HashMap<StringName, int, StringNameHasher > constant_override;
|
HashMap<StringName, int, StringNameHasher > constant_override;
|
||||||
} data;
|
} 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
|
// 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);
|
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);
|
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);
|
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_parent_range(int p_idx) const;
|
||||||
float _get_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 _s2a(float p_val, AnchorType p_anchor,float p_range) const;
|
||||||
float _a2s(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 _propagate_theme_changed(Control *p_owner);
|
||||||
|
|
||||||
void _change_notify_margins();
|
void _change_notify_margins();
|
||||||
void _window_cancel_tooltip();
|
|
||||||
void _window_show_tooltip();
|
|
||||||
void _update_minimum_size();
|
void _update_minimum_size();
|
||||||
|
|
||||||
void _update_scroll();
|
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 _resize(const Size2& p_size);
|
||||||
|
|
||||||
void _size_changed();
|
void _size_changed();
|
||||||
|
@ -217,10 +174,13 @@ private:
|
||||||
void _set_rotation_deg(float p_rot);
|
void _set_rotation_deg(float p_rot);
|
||||||
float _get_rotation_deg() const;
|
float _get_rotation_deg() const;
|
||||||
|
|
||||||
protected:
|
friend class Viewport;
|
||||||
bool window_has_modal_stack() const;
|
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 _set(const StringName& p_name, const Variant& p_value);
|
||||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
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_modal_on_top() const;
|
||||||
|
|
||||||
bool is_window() const;
|
|
||||||
Control *get_window() const;
|
|
||||||
Control *get_parent_control() const;
|
Control *get_parent_control() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,6 @@ void Popup::_notification(int p_what) {
|
||||||
|
|
||||||
void Popup::_fix_size() {
|
void Popup::_fix_size() {
|
||||||
|
|
||||||
Control *window = get_window();
|
|
||||||
ERR_FAIL_COND(!window);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
Point2 pos = get_pos();
|
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) {
|
void Popup::popup_centered(const Size2& p_size) {
|
||||||
|
|
||||||
Control *window = get_window();
|
Point2 window_size = get_viewport_rect().size;
|
||||||
ERR_FAIL_COND(!window);
|
|
||||||
|
|
||||||
|
|
||||||
emit_signal("about_to_show");
|
emit_signal("about_to_show");
|
||||||
Rect2 rect;
|
Rect2 rect;
|
||||||
rect.size = p_size==Size2()?get_size():p_size;
|
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();
|
rect.pos = ((window_size-rect.size)/2.0).floor();
|
||||||
set_pos( rect.pos );
|
set_pos( rect.pos );
|
||||||
set_size( rect.size );
|
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) {
|
void Popup::popup_centered_ratio(float p_screen_ratio) {
|
||||||
|
|
||||||
|
|
||||||
Control *window = get_window();
|
|
||||||
ERR_FAIL_COND(!window);
|
|
||||||
|
|
||||||
emit_signal("about_to_show");
|
emit_signal("about_to_show");
|
||||||
|
|
||||||
Rect2 rect;
|
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.size = (window_size * p_screen_ratio).floor();
|
||||||
rect.pos = ((window_size-rect.size)/2.0).floor();
|
rect.pos = ((window_size-rect.size)/2.0).floor();
|
||||||
set_pos( rect.pos );
|
set_pos( rect.pos );
|
||||||
|
|
|
@ -330,7 +330,8 @@ void SceneTree::input_text( const String& p_text ) {
|
||||||
|
|
||||||
root_lock++;
|
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--;
|
root_lock--;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -39,6 +39,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Camera;
|
class Camera;
|
||||||
|
class Control;
|
||||||
|
class CanvasItem;
|
||||||
|
class Panel;
|
||||||
|
class Label;
|
||||||
|
class Timer;
|
||||||
class Viewport;
|
class Viewport;
|
||||||
|
|
||||||
class RenderTargetTexture : public Texture {
|
class RenderTargetTexture : public Texture {
|
||||||
|
@ -162,6 +167,48 @@ friend class RenderTargetTexture;
|
||||||
Ref<RenderTargetTexture> render_target_texture;
|
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();
|
void update_worlds();
|
||||||
|
|
||||||
_FORCE_INLINE_ Matrix32 _get_input_pre_xform() const;
|
_FORCE_INLINE_ Matrix32 _get_input_pre_xform() const;
|
||||||
|
@ -170,9 +217,47 @@ friend class RenderTargetTexture;
|
||||||
void _vp_exit_tree();
|
void _vp_exit_tree();
|
||||||
|
|
||||||
void _vp_input(const InputEvent& p_ev);
|
void _vp_input(const InputEvent& p_ev);
|
||||||
|
void _vp_input_text(const String& p_text);
|
||||||
void _vp_unhandled_input(const InputEvent& p_ev);
|
void _vp_unhandled_input(const InputEvent& p_ev);
|
||||||
void _make_input_local(InputEvent& 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;
|
friend class Camera;
|
||||||
void _camera_transform_changed_notify();
|
void _camera_transform_changed_notify();
|
||||||
void _set_camera(Camera* p_camera);
|
void _set_camera(Camera* p_camera);
|
||||||
|
@ -254,6 +339,9 @@ public:
|
||||||
void input(const InputEvent& p_event);
|
void input(const InputEvent& p_event);
|
||||||
void unhandled_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);
|
void set_render_target_to_screen_rect(const Rect2& p_rect);
|
||||||
Rect2 get_render_target_to_screen_rect() const;
|
Rect2 get_render_target_to_screen_rect() const;
|
||||||
|
|
||||||
|
@ -263,6 +351,9 @@ public:
|
||||||
void set_physics_object_picking(bool p_enable);
|
void set_physics_object_picking(bool p_enable);
|
||||||
bool get_physics_object_picking();
|
bool get_physics_object_picking();
|
||||||
|
|
||||||
|
bool gui_has_modal_stack() const;
|
||||||
|
|
||||||
|
|
||||||
Viewport();
|
Viewport();
|
||||||
~Viewport();
|
~Viewport();
|
||||||
|
|
||||||
|
|
|
@ -4964,8 +4964,9 @@ EditorNode::EditorNode() {
|
||||||
|
|
||||||
|
|
||||||
//scene_root_base->add_child(scene_root);
|
//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);
|
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_as_audio_listener_2d(true);
|
||||||
scene_root->set_size_override(true,Size2(Globals::get_singleton()->get("display/width"),Globals::get_singleton()->get("display/height")));
|
scene_root->set_size_override(true,Size2(Globals::get_singleton()->get("display/width"),Globals::get_singleton()->get("display/height")));
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ void CanvasItemEditor::_edit_set_pivot(const Vector2& mouse_pos) {
|
||||||
|
|
||||||
void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) {
|
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;
|
return;
|
||||||
if (p_ev.key.mod.control)
|
if (p_ev.key.mod.control)
|
||||||
// prevent to change tool mode when control key is pressed
|
// prevent to change tool mode when control key is pressed
|
||||||
|
|
|
@ -3529,7 +3529,7 @@ void SpatialEditor::_instance_scene() {
|
||||||
|
|
||||||
void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
|
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;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,12 +39,8 @@
|
||||||
Node *SceneTreeEditor::get_scene_node() {
|
Node *SceneTreeEditor::get_scene_node() {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!is_inside_tree(),NULL);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue