summaryrefslogtreecommitdiff
path: root/scene/main/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main/window.cpp')
-rw-r--r--scene/main/window.cpp172
1 files changed, 124 insertions, 48 deletions
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index a9be8a1eff..d697a1a5dd 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,8 +32,9 @@
#include "core/debugger/engine_debugger.h"
#include "core/os/keyboard.h"
+#include "core/string/translation.h"
#include "scene/gui/control.h"
-#include "scene/resources/dynamic_font.h"
+#include "scene/resources/font.h"
#include "scene/scene_string_names.h"
void Window::set_title(const String &p_title) {
@@ -246,7 +247,10 @@ void Window::_make_window() {
}
}
+ _update_window_callbacks();
+
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
+ DisplayServer::get_singleton()->show_window(window_id);
}
void Window::_update_from_window() {
@@ -309,6 +313,7 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
emit_signal("mouse_entered");
+ DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape
} break;
case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
@@ -316,13 +321,13 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
} break;
case DisplayServer::WINDOW_EVENT_FOCUS_IN: {
focused = true;
- _propagate_window_notification(this, NOTIFICATION_WM_FOCUS_IN);
+ _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_IN);
emit_signal("focus_entered");
} break;
case DisplayServer::WINDOW_EVENT_FOCUS_OUT: {
focused = false;
- _propagate_window_notification(this, NOTIFICATION_WM_FOCUS_OUT);
+ _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_OUT);
emit_signal("focus_exited");
} break;
case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: {
@@ -337,6 +342,7 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
emit_signal("go_back_requested");
} break;
case DisplayServer::WINDOW_EVENT_DPI_CHANGE: {
+ _update_viewport_size();
_propagate_window_notification(this, NOTIFICATION_WM_DPI_CHANGE);
emit_signal("dpi_changed");
} break;
@@ -376,7 +382,6 @@ void Window::set_visible(bool p_visible) {
}
if (p_visible && window_id == DisplayServer::INVALID_WINDOW_ID) {
_make_window();
- _update_window_callbacks();
}
} else {
if (visible) {
@@ -398,6 +403,18 @@ void Window::set_visible(bool p_visible) {
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible);
+
+ //update transient exclusive
+ if (transient_parent) {
+ if (exclusive && visible) {
+ ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child.");
+ transient_parent->exclusive_child = this;
+ } else {
+ if (transient_parent->exclusive_child == this) {
+ transient_parent->exclusive_child = nullptr;
+ }
+ }
+ }
}
void Window::_clear_transient() {
@@ -512,11 +529,11 @@ 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 && max_size.x > size.x) {
+ if (max_size.x > 0 && max_size.x > min_size.x && size.x > max_size.x) {
size.x = max_size.x;
}
- if (max_size.y > 0 && max_size.y > min_size.y && max_size.y > size.y) {
+ if (max_size.y > 0 && max_size.y > min_size.y && size.y > max_size.y) {
size.y = max_size.y;
}
@@ -612,26 +629,25 @@ void Window::_update_viewport_size() {
// Already handled above
//_update_font_oversampling(1.0);
} break;
- case CONTENT_SCALE_MODE_OBJECTS: {
+ case CONTENT_SCALE_MODE_CANVAS_ITEMS: {
final_size = screen_size;
final_size_override = viewport_size;
attach_to_screen_rect = Rect2(margin, screen_size);
font_oversampling = screen_size.x / viewport_size.x;
+
+ Size2 scale = Vector2(screen_size) / Vector2(final_size_override);
+ stretch_transform.scale(scale);
+
} break;
- case CONTENT_SCALE_MODE_PIXELS: {
+ case CONTENT_SCALE_MODE_VIEWPORT: {
final_size = viewport_size;
attach_to_screen_rect = Rect2(margin, screen_size);
} break;
}
-
- Size2 scale = size / (Vector2(final_size) + margin * 2);
- stretch_transform.scale(scale);
- stretch_transform.elements[2] = margin * scale;
}
bool allocate = is_inside_tree() && visible && (window_id != DisplayServer::INVALID_WINDOW_ID || embedder != nullptr);
-
_set_size(final_size, final_size_override, attach_to_screen_rect, stretch_transform, allocate);
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
@@ -644,9 +660,8 @@ void Window::_update_viewport_size() {
if (!use_font_oversampling) {
font_oversampling = 1.0;
}
- if (DynamicFontAtSize::font_oversampling != font_oversampling) {
- DynamicFontAtSize::font_oversampling = font_oversampling;
- DynamicFont::update_oversampling();
+ if (TS->font_get_oversampling() != font_oversampling) {
+ TS->font_set_oversampling(font_oversampling);
}
}
@@ -724,7 +739,6 @@ void Window::_notification(int p_what) {
//create
if (visible) {
_make_window();
- _update_window_callbacks();
}
}
}
@@ -812,6 +826,9 @@ bool Window::is_using_font_oversampling() const {
}
DisplayServer::WindowID Window::get_window_id() const {
+ if (embedder) {
+ return parent->get_window_id();
+ }
return window_id;
}
@@ -862,11 +879,11 @@ void Window::child_controls_changed() {
call_deferred("_update_child_controls");
}
-void Window::_window_input(const Ref<InputEvent> &p_ev) {
- if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) {
- return; //avoid joy input on editor
- }
+bool Window::_can_consume_input_events() const {
+ return exclusive_child == nullptr;
+}
+void Window::_window_input(const Ref<InputEvent> &p_ev) {
if (EngineDebugger::is_active()) {
//quit from game window using F8
Ref<InputEventKey> k = p_ev;
@@ -876,12 +893,20 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
}
if (exclusive_child != nullptr) {
- exclusive_child->grab_focus();
+ Window *focus_target = exclusive_child;
+ focus_target->grab_focus();
+ while (focus_target->exclusive_child != nullptr) {
+ focus_target = focus_target->exclusive_child;
+ focus_target->grab_focus();
+ }
- return; //has an exclusive child, can't get events until child is closed
+ if (!is_embedding_subwindows()) { //not embedding, no need for event
+ return;
+ }
}
emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
+
input(p_ev);
if (!is_input_handled()) {
unhandled_input(p_ev);
@@ -957,7 +982,7 @@ void Window::popup_centered_clamped(const Size2i &p_size, float p_fallback_ratio
Rect2i popup_rect;
popup_rect.size = Vector2i(MIN(size_ratio.x, p_size.x), MIN(size_ratio.y, p_size.y));
- popup_rect.position = (parent_rect.size - popup_rect.size) / 2;
+ popup_rect.position = parent_rect.position + (parent_rect.size - popup_rect.size) / 2;
popup(popup_rect);
}
@@ -983,7 +1008,7 @@ void Window::popup_centered(const Size2i &p_minsize) {
} else {
popup_rect.size = p_minsize;
}
- popup_rect.position = (parent_rect.size - popup_rect.size) / 2;
+ popup_rect.position = parent_rect.position + (parent_rect.size - popup_rect.size) / 2;
popup(popup_rect);
}
@@ -1005,7 +1030,7 @@ void Window::popup_centered_ratio(float p_ratio) {
Rect2i popup_rect;
popup_rect.size = parent_rect.size * p_ratio;
- popup_rect.position = (parent_rect.size - popup_rect.size) / 2;
+ popup_rect.position = parent_rect.position + (parent_rect.size - popup_rect.size) / 2;
popup(popup_rect);
}
@@ -1013,6 +1038,9 @@ void Window::popup_centered_ratio(float p_ratio) {
void Window::popup(const Rect2i &p_screen_rect) {
emit_signal("about_to_popup");
+ // Update window size to calculate the actual window size based on contents minimum size and minimum size.
+ _update_window_size();
+
if (p_screen_rect != Rect2i()) {
set_position(p_screen_rect.position);
set_size(p_screen_rect.size);
@@ -1141,11 +1169,6 @@ Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName
return Control::get_icons(theme_owner, theme_owner_window, p_name, type);
}
-Ref<Shader> Window::get_theme_shader(const StringName &p_name, const StringName &p_type) const {
- StringName type = p_type ? p_type : get_class_name();
- return Control::get_shaders(theme_owner, theme_owner_window, p_name, type);
-}
-
Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_styleboxs(theme_owner, theme_owner_window, p_name, type);
@@ -1156,6 +1179,11 @@ Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_t
return Control::get_fonts(theme_owner, theme_owner_window, p_name, type);
}
+int Window::get_theme_font_size(const StringName &p_name, const StringName &p_type) const {
+ StringName type = p_type ? p_type : get_class_name();
+ return Control::get_font_sizes(theme_owner, theme_owner_window, p_name, type);
+}
+
Color Window::get_theme_color(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_colors(theme_owner, theme_owner_window, p_name, type);
@@ -1171,11 +1199,6 @@ bool Window::has_theme_icon(const StringName &p_name, const StringName &p_type)
return Control::has_icons(theme_owner, theme_owner_window, p_name, type);
}
-bool Window::has_theme_shader(const StringName &p_name, const StringName &p_type) const {
- StringName type = p_type ? p_type : get_class_name();
- return Control::has_shaders(theme_owner, theme_owner_window, p_name, type);
-}
-
bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_styleboxs(theme_owner, theme_owner_window, p_name, type);
@@ -1186,6 +1209,11 @@ bool Window::has_theme_font(const StringName &p_name, const StringName &p_type)
return Control::has_fonts(theme_owner, theme_owner_window, p_name, type);
}
+bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_type) const {
+ StringName type = p_type ? p_type : get_class_name();
+ return Control::has_font_sizes(theme_owner, theme_owner_window, p_name, type);
+}
+
bool Window::has_theme_color(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_colors(theme_owner, theme_owner_window, p_name, type);
@@ -1232,6 +1260,48 @@ Rect2i Window::get_parent_rect() const {
}
}
+void Window::set_clamp_to_embedder(bool p_enable) {
+ clamp_to_embedder = p_enable;
+}
+
+bool Window::is_clamped_to_embedder() const {
+ return clamp_to_embedder;
+}
+
+void Window::set_layout_direction(Window::LayoutDirection p_direction) {
+ ERR_FAIL_INDEX((int)p_direction, 4);
+
+ layout_dir = p_direction;
+ propagate_notification(Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED);
+}
+
+Window::LayoutDirection Window::get_layout_direction() const {
+ return layout_dir;
+}
+
+bool Window::is_layout_rtl() const {
+ if (layout_dir == LAYOUT_DIRECTION_INHERITED) {
+ Window *parent = Object::cast_to<Window>(get_parent());
+ if (parent) {
+ return parent->is_layout_rtl();
+ } else {
+ if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
+ return true;
+ }
+ String locale = TranslationServer::get_singleton()->get_tool_locale();
+ return TS->is_locale_right_to_left(locale);
+ }
+ } else if (layout_dir == LAYOUT_DIRECTION_LOCALE) {
+ if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
+ return true;
+ }
+ String locale = TranslationServer::get_singleton()->get_tool_locale();
+ return TS->is_locale_right_to_left(locale);
+ } else {
+ return (layout_dir == LAYOUT_DIRECTION_RTL);
+ }
+}
+
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);
@@ -1281,8 +1351,8 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus);
ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus);
- ClassDB::bind_method(D_METHOD("set_ime_active"), &Window::set_ime_active);
- ClassDB::bind_method(D_METHOD("set_ime_position"), &Window::set_ime_position);
+ ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &Window::set_ime_active);
+ ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &Window::set_ime_position);
ClassDB::bind_method(D_METHOD("is_embedded"), &Window::is_embedded);
@@ -1310,15 +1380,21 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "type"), &Window::get_theme_icon, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "type"), &Window::get_theme_stylebox, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_font", "name", "type"), &Window::get_theme_font, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "type"), &Window::get_theme_font_size, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_color", "name", "type"), &Window::get_theme_color, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "type"), &Window::get_theme_constant, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "type"), &Window::has_theme_icon, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "type"), &Window::has_theme_stylebox, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_font", "name", "type"), &Window::has_theme_font, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "type"), &Window::has_theme_font_size, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_color", "name", "type"), &Window::has_theme_color, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "type"), &Window::has_theme_constant, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Window::set_layout_direction);
+ ClassDB::bind_method(D_METHOD("get_layout_direction"), &Window::get_layout_direction);
+ ClassDB::bind_method(D_METHOD("is_layout_rtl"), &Window::is_layout_rtl);
+
ClassDB::bind_method(D_METHOD("popup", "rect"), &Window::popup, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("popup_on_parent", "parent_rect"), &Window::popup_on_parent);
ClassDB::bind_method(D_METHOD("popup_centered_ratio", "ratio"), &Window::popup_centered_ratio, DEFVAL(0.8));
@@ -1345,7 +1421,7 @@ void Window::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "max_size"), "set_max_size", "get_max_size");
ADD_GROUP("Content Scale", "content_scale_");
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,Object,Pixels"), "set_content_scale_mode", "get_content_scale_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,CanvasItems,Viewport"), "set_content_scale_mode", "get_content_scale_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,KeepWidth,KeepHeight,Expand"), "set_content_scale_aspect", "get_content_scale_aspect");
ADD_GROUP("Theme", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
@@ -1376,22 +1452,22 @@ void Window::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED);
- BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_OBJECTS);
- BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_PIXELS);
+ BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_CANVAS_ITEMS);
+ BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_VIEWPORT);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_IGNORE);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP_WIDTH);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP_HEIGHT);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_EXPAND);
+
+ BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_INHERITED);
+ BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LOCALE);
+ BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LTR);
+ BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_RTL);
}
Window::Window() {
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = false;
- }
- content_scale_mode = CONTENT_SCALE_MODE_DISABLED;
- content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE;
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
}