diff options
Diffstat (limited to 'scene/main/window.cpp')
-rw-r--r-- | scene/main/window.cpp | 100 |
1 files changed, 93 insertions, 7 deletions
diff --git a/scene/main/window.cpp b/scene/main/window.cpp index d0658c489d..1af279d94c 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -670,18 +670,29 @@ void Window::_propagate_window_notification(Node *p_node, int p_notification) { void Window::_event_callback(DisplayServer::WindowEvent p_event) { switch (p_event) { case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: { - _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER); Window *root = get_tree()->get_root(); - DEV_ASSERT(!root->gui.windowmanager_window_over); // Entering a window while a window is hovered should never happen. + if (root->gui.windowmanager_window_over) { +#ifdef DEV_ENABLED + WARN_PRINT_ONCE("Entering a window while a window is hovered should never happen in DisplayServer."); +#endif // DEV_ENABLED + root->gui.windowmanager_window_over->_event_callback(DisplayServer::WINDOW_EVENT_MOUSE_EXIT); + } + _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER); root->gui.windowmanager_window_over = this; - notification(NOTIFICATION_VP_MOUSE_ENTER); + mouse_in_window = true; if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) { DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape } } break; case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: { Window *root = get_tree()->get_root(); - DEV_ASSERT(root->gui.windowmanager_window_over); // Exiting a window, while no window is hovered should never happen. + if (!root->gui.windowmanager_window_over) { +#ifdef DEV_ENABLED + WARN_PRINT_ONCE("Exiting a window while no window is hovered should never happen in DisplayServer."); +#endif // DEV_ENABLED + return; + } + mouse_in_window = false; root->gui.windowmanager_window_over->_mouse_leave_viewport(); root->gui.windowmanager_window_over = nullptr; _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT); @@ -991,6 +1002,17 @@ void Window::_update_viewport_size() { float font_oversampling = 1.0; window_transform = Transform2D(); + if (content_scale_stretch == Window::CONTENT_SCALE_STRETCH_INTEGER) { + // We always want to make sure that the content scale factor is a whole + // number, else there will be pixel wobble no matter what. + content_scale_factor = Math::floor(content_scale_factor); + + // A content scale factor of zero is pretty useless. + if (content_scale_factor < 1) { + content_scale_factor = 1; + } + } + if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) { font_oversampling = content_scale_factor; final_size = size; @@ -1044,13 +1066,26 @@ void Window::_update_viewport_size() { screen_size = screen_size.floor(); viewport_size = viewport_size.floor(); + if (content_scale_stretch == Window::CONTENT_SCALE_STRETCH_INTEGER) { + Size2i screen_scale = (screen_size / viewport_size).floor(); + int scale_factor = MIN(screen_scale.x, screen_scale.y); + + if (scale_factor < 1) { + scale_factor = 1; + } + + screen_size = viewport_size * scale_factor; + } + Size2 margin; Size2 offset; - if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.x < video_mode.x) { + if (screen_size.x < video_mode.x) { margin.x = Math::round((video_mode.x - screen_size.x) / 2.0); offset.x = Math::round(margin.x * viewport_size.y / screen_size.y); - } else if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.y < video_mode.y) { + } + + if (screen_size.y < video_mode.y) { margin.y = Math::round((video_mode.y - screen_size.y) / 2.0); offset.y = Math::round(margin.y * viewport_size.x / screen_size.x); } @@ -1327,6 +1362,15 @@ Window::ContentScaleAspect Window::get_content_scale_aspect() const { return content_scale_aspect; } +void Window::set_content_scale_stretch(ContentScaleStretch p_stretch) { + content_scale_stretch = p_stretch; + _update_viewport_size(); +} + +Window::ContentScaleStretch Window::get_content_scale_stretch() const { + return content_scale_stretch; +} + void Window::set_content_scale_factor(real_t p_factor) { ERR_MAIN_THREAD_GUARD; ERR_FAIL_COND(p_factor <= 0); @@ -2509,6 +2553,41 @@ bool Window::is_attached_in_viewport() const { return get_embedder(); } +void Window::_update_mouse_over(Vector2 p_pos) { + if (!mouse_in_window) { + if (is_embedded()) { + mouse_in_window = true; + _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER); + } else { + // Prevent update based on delayed InputEvents from DisplayServer. + return; + } + } + + bool new_in = get_visible_rect().has_point(p_pos); + if (new_in == gui.mouse_in_viewport) { + if (new_in) { + Viewport::_update_mouse_over(p_pos); + } + return; + } + + if (new_in) { + notification(NOTIFICATION_VP_MOUSE_ENTER); + Viewport::_update_mouse_over(p_pos); + } else { + Viewport::_mouse_leave_viewport(); + } +} + +void Window::_mouse_leave_viewport() { + Viewport::_mouse_leave_viewport(); + if (is_embedded()) { + mouse_in_window = false; + _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT); + } +} + void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title); ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title); @@ -2583,6 +2662,9 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_content_scale_aspect", "aspect"), &Window::set_content_scale_aspect); ClassDB::bind_method(D_METHOD("get_content_scale_aspect"), &Window::get_content_scale_aspect); + ClassDB::bind_method(D_METHOD("set_content_scale_stretch", "stretch"), &Window::set_content_scale_stretch); + ClassDB::bind_method(D_METHOD("get_content_scale_stretch"), &Window::get_content_scale_stretch); + ClassDB::bind_method(D_METHOD("set_content_scale_factor", "factor"), &Window::set_content_scale_factor); ClassDB::bind_method(D_METHOD("get_content_scale_factor"), &Window::get_content_scale_factor); @@ -2701,7 +2783,8 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor"), "set_content_scale_factor", "get_content_scale_factor"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_stretch", PROPERTY_HINT_ENUM, "Fractional,Integer"), "set_content_scale_stretch", "get_content_scale_stretch"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor", PROPERTY_HINT_RANGE, "0.5,8.0,0.01"), "set_content_scale_factor", "get_content_scale_factor"); ADD_GROUP("Localization", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating"); @@ -2753,6 +2836,9 @@ void Window::_bind_methods() { BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP_HEIGHT); BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_EXPAND); + BIND_ENUM_CONSTANT(CONTENT_SCALE_STRETCH_FRACTIONAL); + BIND_ENUM_CONSTANT(CONTENT_SCALE_STRETCH_INTEGER); + BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_INHERITED); BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LOCALE); BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LTR); |