Merge pull request #63925 from YeldhamDev/window_fixes

This commit is contained in:
Rémi Verschelde 2022-08-08 10:34:08 +02:00 committed by GitHub
commit a8a4982de2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 15 deletions

View File

@ -344,9 +344,11 @@
</member>
<member name="max_size" type="Vector2i" setter="set_max_size" getter="get_max_size" default="Vector2i(0, 0)">
If non-zero, the [Window] can't be resized to be bigger than this size.
[b]Note:[/b] This property will be ignored if the value is lower than [member min_size].
</member>
<member name="min_size" type="Vector2i" setter="set_min_size" getter="get_min_size" default="Vector2i(0, 0)">
If non-zero, the [Window] can't be resized to be smaller than this size.
[b]Note:[/b] This property will be ignored in favor of [method get_contents_minimum_size] if [member wrap_controls] is enabled and if its size is bigger.
</member>
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Window.Mode" default="0">
Set's the window's current mode.
@ -388,7 +390,7 @@
If [code]true[/code], the window is visible.
</member>
<member name="wrap_controls" type="bool" setter="set_wrap_controls" getter="is_wrapping_controls" default="false">
If [code]true[/code], the window's size will automatically update when a child node is added or removed.
If [code]true[/code], the window's size will automatically update when a child node is added or removed, ignoring [member min_size] if the new size is bigger.
If [code]false[/code], you need to call [method child_controls_changed] manually.
</member>
</members>

View File

@ -2498,17 +2498,20 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (gui.subwindow_drag == SUB_WINDOW_DRAG_RESIZE) {
Vector2i diff = mm->get_position() - gui.subwindow_drag_from;
Size2i min_size = gui.subwindow_focused->get_min_size();
Size2i min_size_adjusted = min_size;
if (gui.subwindow_focused->is_wrapping_controls()) {
Size2i cms = gui.subwindow_focused->get_contents_minimum_size();
min_size.x = MAX(cms.x, min_size.x);
min_size.y = MAX(cms.y, min_size.y);
min_size_adjusted.x = MAX(cms.x, min_size.x);
min_size_adjusted.y = MAX(cms.y, min_size.y);
}
min_size.x = MAX(min_size.x, 1);
min_size.y = MAX(min_size.y, 1);
min_size_adjusted.x = MAX(min_size_adjusted.x, 1);
min_size_adjusted.y = MAX(min_size_adjusted.y, 1);
Rect2i r = gui.subwindow_resize_from_rect;
Size2i limit = r.size - min_size;
Size2i limit = r.size - min_size_adjusted;
switch (gui.subwindow_resize_mode) {
case SUB_WINDOW_RESIZE_TOP_LEFT: {
@ -2563,6 +2566,19 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
}
Size2i max_size = gui.subwindow_focused->get_max_size();
if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) {
max_size.x = MAX(max_size.x, 1);
max_size.y = MAX(max_size.y, 1);
if (r.size.x > max_size.x) {
r.size.x = max_size.x;
}
if (r.size.y > max_size.y) {
r.size.y = max_size.y;
}
}
gui.subwindow_focused->_rect_changed_callback(r);
}
@ -2600,7 +2616,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
Ref<Texture2D> close_icon = sw.window->get_theme_icon(SNAME("close"));
Rect2 close_rect;
close_rect.position = Vector2(r.position.x + r.size.x - close_v_ofs, r.position.y - close_h_ofs);
close_rect.position = Vector2(r.position.x + r.size.x - close_h_ofs, r.position.y - close_v_ofs);
close_rect.size = close_icon->get_size();
if (gui.subwindow_focused != sw.window) {

View File

@ -242,8 +242,8 @@ void Window::_make_window() {
window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, Rect2i(position, size));
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id);
DisplayServer::get_singleton()->window_set_max_size(max_size, window_id);
DisplayServer::get_singleton()->window_set_min_size(min_size, window_id);
DisplayServer::get_singleton()->window_set_max_size(Size2i(), window_id);
DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id);
String tr_title = atr(title);
#ifdef DEBUG_ENABLED
if (window_id == DisplayServer::MAIN_WINDOW_ID) {
@ -596,20 +596,43 @@ void Window::_update_window_size() {
size.x = MAX(size_limit.x, size.x);
size.y = MAX(size_limit.y, size.y);
if (max_size.x > 0 && max_size.x > min_size.x && size.x > max_size.x) {
size.x = max_size.x;
}
bool reset_min_first = false;
if (max_size.y > 0 && max_size.y > min_size.y && size.y > max_size.y) {
size.y = max_size.y;
bool max_size_valid = false;
if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) {
max_size_valid = true;
if (size.x > max_size.x) {
size.x = max_size.x;
}
if (size_limit.x > max_size.x) {
size_limit.x = max_size.x;
reset_min_first = true;
}
if (size.y > max_size.y) {
size.y = max_size.y;
}
if (size_limit.y > max_size.y) {
size_limit.y = max_size.y;
reset_min_first = true;
}
}
if (embedder) {
size.x = MAX(size.x, 1);
size.y = MAX(size.y, 1);
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
if (reset_min_first && wrap_controls) {
// Avoid an error if setting max_size to a value between min_size and the previous size_limit.
DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id);
}
DisplayServer::get_singleton()->window_set_size(size, window_id);
DisplayServer::get_singleton()->window_set_max_size(max_size_valid ? max_size : Size2i(), window_id);
DisplayServer::get_singleton()->window_set_min_size(size_limit, window_id);
DisplayServer::get_singleton()->window_set_max_size(max_size, window_id);
}
//update the viewport
@ -953,6 +976,8 @@ void Window::set_wrap_controls(bool p_enable) {
wrap_controls = p_enable;
if (wrap_controls) {
child_controls_changed();
} else {
_update_window_size();
}
}