Viewport emit mouse_enter/exit even when dragging Control

This commit is contained in:
Jérémy Zurcher 2021-11-03 15:56:04 +01:00
parent a05aefb74b
commit f8cef3afeb
3 changed files with 42 additions and 1 deletions

View file

@ -218,6 +218,9 @@
<member name="gui_disable_input" type="bool" setter="set_disable_input" getter="is_input_disabled" default="false">
If [code]true[/code], the viewport will not receive input events.
</member>
<member name="gui_force_mouse_events" type="bool" setter="set_force_mouse_events" getter="is_mouse_events_forced" default="false">
If [code]true[/code], the viewport will emit mouse_entered and mouse_exited signals even when dragging a [Control].
</member>
<member name="gui_snap_controls_to_pixels" type="bool" setter="set_snap_controls_to_pixels" getter="is_snap_controls_to_pixels_enabled" default="true">
If [code]true[/code], the GUI controls on the viewport will lay pixel perfectly.
</member>

View file

@ -187,6 +187,7 @@ Viewport::GUI::GUI() {
mouse_focus_mask = 0;
key_focus = nullptr;
mouse_over = nullptr;
unfocused_mouse_over = nullptr;
tooltip_control = nullptr;
tooltip_popup = nullptr;
@ -1911,6 +1912,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.mouse_focus = _gui_find_control(pos);
gui.last_mouse_focus = gui.mouse_focus;
gui.unfocused_mouse_over = gui.mouse_focus;
if (!gui.mouse_focus) {
gui.mouse_focus_mask = 0;
@ -2131,10 +2133,18 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
// These sections of code are reused in the mb.is_valid() case further up
// for the purpose of notifying controls about potential changes in focus
// when the mousebutton is released.
Control *_over = nullptr;
if (force_mouse_events) {
_over = _gui_find_control(mpos);
}
if (gui.mouse_focus) {
over = gui.mouse_focus;
} else {
over = _gui_find_control(mpos);
if (force_mouse_events) {
over = _over;
} else {
over = _gui_find_control(mpos);
}
}
if (gui.drag_data.get_type() == Variant::NIL && over && !gui.modal_stack.empty()) {
@ -2187,6 +2197,16 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.mouse_over = over;
if (force_mouse_events && gui.mouse_focus && _over != gui.unfocused_mouse_over) {
if (gui.unfocused_mouse_over) {
_gui_call_notification(gui.unfocused_mouse_over, Control::NOTIFICATION_MOUSE_EXIT);
}
if (_over) {
_gui_call_notification(_over, Control::NOTIFICATION_MOUSE_ENTER);
}
gui.unfocused_mouse_over = _over;
}
Control *drag_preview = _gui_get_drag_preview();
if (drag_preview) {
drag_preview->set_position(mpos);
@ -2921,6 +2941,14 @@ bool Viewport::is_input_disabled() const {
return disable_input;
}
void Viewport::set_force_mouse_events(bool p_disable) {
force_mouse_events = p_disable;
}
bool Viewport::is_mouse_events_forced() const {
return force_mouse_events;
}
void Viewport::set_disable_3d(bool p_disable) {
disable_3d = p_disable;
VS::get_singleton()->viewport_set_disable_3d(viewport, p_disable);
@ -3203,6 +3231,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);
ClassDB::bind_method(D_METHOD("set_force_mouse_events", "disable"), &Viewport::set_force_mouse_events);
ClassDB::bind_method(D_METHOD("is_mouse_events_forced"), &Viewport::is_mouse_events_forced);
ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d);
ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled);
@ -3265,6 +3296,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking");
ADD_GROUP("GUI", "gui_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_force_mouse_events"), "set_force_mouse_events", "is_mouse_events_forced");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled");
ADD_GROUP("Shadow Atlas", "shadow_atlas_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size");
@ -3386,6 +3418,7 @@ Viewport::Viewport() {
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
disable_input = false;
force_mouse_events = false;
disable_3d = false;
keep_3d_linear = false;

View file

@ -299,6 +299,7 @@ private:
int mouse_focus_mask;
Control *key_focus;
Control *mouse_over;
Control *unfocused_mouse_over;
Control *tooltip_control;
Control *tooltip_popup;
Label *tooltip_label;
@ -325,6 +326,7 @@ private:
} gui;
bool disable_input;
bool force_mouse_events;
void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input);
void _gui_call_notification(Control *p_control, int p_what);
@ -528,6 +530,9 @@ public:
void set_disable_input(bool p_disable);
bool is_input_disabled() const;
void set_force_mouse_events(bool p_disable);
bool is_mouse_events_forced() const;
void set_disable_3d(bool p_disable);
bool is_3d_disabled() const;