1/**************************************************************************/
2/* window.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef WINDOW_H
32#define WINDOW_H
33
34#include "scene/main/viewport.h"
35#include "scene/resources/theme.h"
36
37class Control;
38class Font;
39class Shortcut;
40class StyleBox;
41class ThemeOwner;
42class ThemeContext;
43
44class Window : public Viewport {
45 GDCLASS(Window, Viewport);
46
47public:
48 // Keep synced with enum hint for `mode` property.
49 enum Mode {
50 MODE_WINDOWED = DisplayServer::WINDOW_MODE_WINDOWED,
51 MODE_MINIMIZED = DisplayServer::WINDOW_MODE_MINIMIZED,
52 MODE_MAXIMIZED = DisplayServer::WINDOW_MODE_MAXIMIZED,
53 MODE_FULLSCREEN = DisplayServer::WINDOW_MODE_FULLSCREEN,
54 MODE_EXCLUSIVE_FULLSCREEN = DisplayServer::WINDOW_MODE_EXCLUSIVE_FULLSCREEN,
55 };
56
57 enum Flags {
58 FLAG_RESIZE_DISABLED = DisplayServer::WINDOW_FLAG_RESIZE_DISABLED,
59 FLAG_BORDERLESS = DisplayServer::WINDOW_FLAG_BORDERLESS,
60 FLAG_ALWAYS_ON_TOP = DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP,
61 FLAG_TRANSPARENT = DisplayServer::WINDOW_FLAG_TRANSPARENT,
62 FLAG_NO_FOCUS = DisplayServer::WINDOW_FLAG_NO_FOCUS,
63 FLAG_POPUP = DisplayServer::WINDOW_FLAG_POPUP,
64 FLAG_EXTEND_TO_TITLE = DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE,
65 FLAG_MOUSE_PASSTHROUGH = DisplayServer::WINDOW_FLAG_MOUSE_PASSTHROUGH,
66 FLAG_MAX = DisplayServer::WINDOW_FLAG_MAX,
67 };
68
69 enum ContentScaleMode {
70 CONTENT_SCALE_MODE_DISABLED,
71 CONTENT_SCALE_MODE_CANVAS_ITEMS,
72 CONTENT_SCALE_MODE_VIEWPORT,
73 };
74
75 enum ContentScaleAspect {
76 CONTENT_SCALE_ASPECT_IGNORE,
77 CONTENT_SCALE_ASPECT_KEEP,
78 CONTENT_SCALE_ASPECT_KEEP_WIDTH,
79 CONTENT_SCALE_ASPECT_KEEP_HEIGHT,
80 CONTENT_SCALE_ASPECT_EXPAND,
81 };
82
83 enum ContentScaleStretch {
84 CONTENT_SCALE_STRETCH_FRACTIONAL,
85 CONTENT_SCALE_STRETCH_INTEGER,
86 };
87
88 enum LayoutDirection {
89 LAYOUT_DIRECTION_INHERITED,
90 LAYOUT_DIRECTION_LOCALE,
91 LAYOUT_DIRECTION_LTR,
92 LAYOUT_DIRECTION_RTL
93 };
94
95 enum {
96 DEFAULT_WINDOW_SIZE = 100,
97 };
98
99 // Keep synced with enum hint for `initial_position` property.
100 enum WindowInitialPosition {
101 WINDOW_INITIAL_POSITION_ABSOLUTE,
102 WINDOW_INITIAL_POSITION_CENTER_PRIMARY_SCREEN,
103 WINDOW_INITIAL_POSITION_CENTER_MAIN_WINDOW_SCREEN,
104 WINDOW_INITIAL_POSITION_CENTER_OTHER_SCREEN,
105 WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_MOUSE_FOCUS,
106 WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_KEYBOARD_FOCUS,
107 };
108
109private:
110 DisplayServer::WindowID window_id = DisplayServer::INVALID_WINDOW_ID;
111 bool initialized = false;
112
113 String title;
114 mutable int current_screen = 0;
115 mutable Vector2i position;
116 mutable Size2i size = Size2i(DEFAULT_WINDOW_SIZE, DEFAULT_WINDOW_SIZE);
117 mutable Size2i min_size;
118 mutable Size2i max_size;
119 mutable Vector<Vector2> mpath;
120 mutable Mode mode = MODE_WINDOWED;
121 mutable bool flags[FLAG_MAX] = {};
122 bool visible = true;
123 bool focused = false;
124 WindowInitialPosition initial_position = WINDOW_INITIAL_POSITION_ABSOLUTE;
125
126 bool use_font_oversampling = false;
127 bool transient = false;
128 bool exclusive = false;
129 bool wrap_controls = false;
130 bool updating_child_controls = false;
131 bool updating_embedded_window = false;
132 bool clamp_to_embedder = false;
133 bool unparent_when_invisible = false;
134
135 LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED;
136
137 bool auto_translate = true;
138
139 void _update_child_controls();
140 void _update_embedded_window();
141
142 Size2i content_scale_size;
143 ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED;
144 ContentScaleAspect content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE;
145 ContentScaleStretch content_scale_stretch = CONTENT_SCALE_STRETCH_FRACTIONAL;
146 real_t content_scale_factor = 1.0;
147
148 void _make_window();
149 void _clear_window();
150 void _update_from_window();
151
152 bool _try_parent_dialog(Node *p_from_node);
153
154 Size2i max_size_used;
155
156 Size2i _clamp_limit_size(const Size2i &p_limit_size);
157 Size2i _clamp_window_size(const Size2i &p_size);
158 void _validate_limit_size();
159 void _update_viewport_size();
160 void _update_window_size();
161
162 void _propagate_window_notification(Node *p_node, int p_notification);
163
164 void _update_window_callbacks();
165
166 void _clear_transient();
167 void _make_transient();
168 Window *transient_parent = nullptr;
169 Window *exclusive_child = nullptr;
170 HashSet<Window *> transient_children;
171
172 ThemeOwner *theme_owner = nullptr;
173 Ref<Theme> theme;
174 StringName theme_type_variation;
175
176 bool bulk_theme_override = false;
177 Theme::ThemeIconMap theme_icon_override;
178 Theme::ThemeStyleMap theme_style_override;
179 Theme::ThemeFontMap theme_font_override;
180 Theme::ThemeFontSizeMap theme_font_size_override;
181 Theme::ThemeColorMap theme_color_override;
182 Theme::ThemeConstantMap theme_constant_override;
183
184 mutable HashMap<StringName, Theme::ThemeIconMap> theme_icon_cache;
185 mutable HashMap<StringName, Theme::ThemeStyleMap> theme_style_cache;
186 mutable HashMap<StringName, Theme::ThemeFontMap> theme_font_cache;
187 mutable HashMap<StringName, Theme::ThemeFontSizeMap> theme_font_size_cache;
188 mutable HashMap<StringName, Theme::ThemeColorMap> theme_color_cache;
189 mutable HashMap<StringName, Theme::ThemeConstantMap> theme_constant_cache;
190
191 void _theme_changed();
192 void _notify_theme_override_changed();
193 void _invalidate_theme_cache();
194
195 struct ThemeCache {
196 Ref<StyleBox> embedded_border;
197 Ref<StyleBox> embedded_unfocused_border;
198
199 Ref<Font> title_font;
200 int title_font_size = 0;
201 Color title_color;
202 int title_height = 0;
203 Color title_outline_modulate;
204 int title_outline_size = 0;
205
206 Ref<Texture2D> close;
207 Ref<Texture2D> close_pressed;
208 int close_h_offset = 0;
209 int close_v_offset = 0;
210
211 int resize_margin = 0;
212 } theme_cache;
213
214 Viewport *embedder = nullptr;
215
216 Transform2D window_transform;
217
218 friend class Viewport; //friend back, can call the methods below
219
220 void _window_input(const Ref<InputEvent> &p_ev);
221 void _window_input_text(const String &p_text);
222 void _window_drop_files(const Vector<String> &p_files);
223 void _rect_changed_callback(const Rect2i &p_callback);
224 void _event_callback(DisplayServer::WindowEvent p_event);
225 virtual bool _can_consume_input_events() const override;
226
227 bool mouse_in_window = false;
228 void _update_mouse_over(Vector2 p_pos) override;
229 void _mouse_leave_viewport() override;
230
231 Ref<Shortcut> debugger_stop_shortcut;
232
233protected:
234 virtual Rect2i _popup_adjust_rect() const { return Rect2i(); }
235 virtual void _post_popup() {}
236
237 virtual void _update_theme_item_cache();
238
239 void _notification(int p_what);
240 static void _bind_methods();
241
242 bool _set(const StringName &p_name, const Variant &p_value);
243 bool _get(const StringName &p_name, Variant &r_ret) const;
244 void _get_property_list(List<PropertyInfo> *p_list) const;
245 void _validate_property(PropertyInfo &p_property) const;
246
247 virtual void add_child_notify(Node *p_child) override;
248 virtual void remove_child_notify(Node *p_child) override;
249
250 GDVIRTUAL0RC(Vector2, _get_contents_minimum_size)
251
252public:
253 enum {
254 NOTIFICATION_VISIBILITY_CHANGED = 30,
255 NOTIFICATION_POST_POPUP = 31,
256 NOTIFICATION_THEME_CHANGED = 32
257 };
258
259 void set_title(const String &p_title);
260 String get_title() const;
261
262 void set_initial_position(WindowInitialPosition p_initial_position);
263 WindowInitialPosition get_initial_position() const;
264
265 void set_current_screen(int p_screen);
266 int get_current_screen() const;
267
268 void set_position(const Point2i &p_position);
269 Point2i get_position() const;
270 void move_to_center();
271
272 void set_size(const Size2i &p_size);
273 Size2i get_size() const;
274 void reset_size();
275
276 Point2i get_position_with_decorations() const;
277 Size2i get_size_with_decorations() const;
278
279 void set_max_size(const Size2i &p_max_size);
280 Size2i get_max_size() const;
281
282 void set_min_size(const Size2i &p_min_size);
283 Size2i get_min_size() const;
284
285 void set_mode(Mode p_mode);
286 Mode get_mode() const;
287
288 void set_flag(Flags p_flag, bool p_enabled);
289 bool get_flag(Flags p_flag) const;
290
291 bool is_maximize_allowed() const;
292
293 void request_attention();
294 void move_to_foreground();
295
296 void set_visible(bool p_visible);
297 bool is_visible() const;
298
299 void update_mouse_cursor_state() override;
300
301 void show();
302 void hide();
303
304 void set_transient(bool p_transient);
305 bool is_transient() const;
306
307 void set_exclusive(bool p_exclusive);
308 bool is_exclusive() const;
309
310 void set_clamp_to_embedder(bool p_enable);
311 bool is_clamped_to_embedder() const;
312
313 void set_unparent_when_invisible(bool p_unparent);
314
315 bool is_in_edited_scene_root() const;
316
317 bool can_draw() const;
318
319 void set_ime_active(bool p_active);
320 void set_ime_position(const Point2i &p_pos);
321
322 bool is_embedded() const;
323 Viewport *get_embedder() const;
324
325 void set_content_scale_size(const Size2i &p_size);
326 Size2i get_content_scale_size() const;
327
328 void set_content_scale_mode(ContentScaleMode p_mode);
329 ContentScaleMode get_content_scale_mode() const;
330
331 void set_content_scale_aspect(ContentScaleAspect p_aspect);
332 ContentScaleAspect get_content_scale_aspect() const;
333
334 void set_content_scale_stretch(ContentScaleStretch p_stretch);
335 ContentScaleStretch get_content_scale_stretch() const;
336
337 void set_content_scale_factor(real_t p_factor);
338 real_t get_content_scale_factor() const;
339
340 void set_use_font_oversampling(bool p_oversampling);
341 bool is_using_font_oversampling() const;
342
343 void set_mouse_passthrough_polygon(const Vector<Vector2> &p_region);
344 Vector<Vector2> get_mouse_passthrough_polygon() const;
345
346 void set_wrap_controls(bool p_enable);
347 bool is_wrapping_controls() const;
348 void child_controls_changed();
349
350 Window *get_exclusive_child() const { return exclusive_child; };
351 Window *get_parent_visible_window() const;
352 Viewport *get_parent_viewport() const;
353
354 virtual void popup(const Rect2i &p_screen_rect = Rect2i());
355 void popup_on_parent(const Rect2i &p_parent_rect);
356 void popup_centered(const Size2i &p_minsize = Size2i());
357 void popup_centered_ratio(float p_ratio = 0.8);
358 void popup_centered_clamped(const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75);
359
360 void popup_exclusive(Node *p_from_node, const Rect2i &p_screen_rect = Rect2i());
361 void popup_exclusive_on_parent(Node *p_from_node, const Rect2i &p_parent_rect);
362 void popup_exclusive_centered(Node *p_from_node, const Size2i &p_minsize = Size2i());
363 void popup_exclusive_centered_ratio(Node *p_from_node, float p_ratio = 0.8);
364 void popup_exclusive_centered_clamped(Node *p_from_node, const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75);
365
366 Rect2i fit_rect_in_parent(Rect2i p_rect, const Rect2i &p_parent_rect) const;
367 Size2 get_contents_minimum_size() const;
368 Size2 get_clamped_minimum_size() const;
369
370 void grab_focus();
371 bool has_focus() const;
372
373 void set_layout_direction(LayoutDirection p_direction);
374 LayoutDirection get_layout_direction() const;
375 bool is_layout_rtl() const;
376
377 void set_auto_translate(bool p_enable);
378 bool is_auto_translating() const;
379 _FORCE_INLINE_ String atr(const String p_string) const { return is_auto_translating() ? tr(p_string) : p_string; };
380
381 Rect2i get_usable_parent_rect() const;
382
383 // Theming.
384
385 void set_theme_owner_node(Node *p_node);
386 Node *get_theme_owner_node() const;
387 bool has_theme_owner_node() const;
388
389 void set_theme_context(ThemeContext *p_context, bool p_propagate = true);
390
391 void set_theme(const Ref<Theme> &p_theme);
392 Ref<Theme> get_theme() const;
393
394 void set_theme_type_variation(const StringName &p_theme_type);
395 StringName get_theme_type_variation() const;
396
397 void begin_bulk_theme_override();
398 void end_bulk_theme_override();
399
400 void add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon);
401 void add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style);
402 void add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font);
403 void add_theme_font_size_override(const StringName &p_name, int p_font_size);
404 void add_theme_color_override(const StringName &p_name, const Color &p_color);
405 void add_theme_constant_override(const StringName &p_name, int p_constant);
406
407 void remove_theme_icon_override(const StringName &p_name);
408 void remove_theme_style_override(const StringName &p_name);
409 void remove_theme_font_override(const StringName &p_name);
410 void remove_theme_font_size_override(const StringName &p_name);
411 void remove_theme_color_override(const StringName &p_name);
412 void remove_theme_constant_override(const StringName &p_name);
413
414 Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
415 Ref<StyleBox> get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
416 Ref<Font> get_theme_font(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
417 int get_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
418 Color get_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
419 int get_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
420 Variant get_theme_item(Theme::DataType p_data_type, const StringName &p_name, const StringName &p_theme_type = StringName()) const;
421#ifdef TOOLS_ENABLED
422 Ref<Texture2D> get_editor_theme_icon(const StringName &p_name) const;
423#endif
424
425 bool has_theme_icon_override(const StringName &p_name) const;
426 bool has_theme_stylebox_override(const StringName &p_name) const;
427 bool has_theme_font_override(const StringName &p_name) const;
428 bool has_theme_font_size_override(const StringName &p_name) const;
429 bool has_theme_color_override(const StringName &p_name) const;
430 bool has_theme_constant_override(const StringName &p_name) const;
431
432 bool has_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
433 bool has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
434 bool has_theme_font(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
435 bool has_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
436 bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
437 bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
438
439 float get_theme_default_base_scale() const;
440 Ref<Font> get_theme_default_font() const;
441 int get_theme_default_font_size() const;
442
443 //
444
445 virtual Transform2D get_final_transform() const override;
446 virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const override;
447 virtual Transform2D get_popup_base_transform() const override;
448 virtual bool is_directly_attached_to_screen() const override;
449 virtual bool is_attached_in_viewport() const override;
450
451 Rect2i get_parent_rect() const;
452 virtual DisplayServer::WindowID get_window_id() const override;
453
454 virtual Size2 _get_contents_minimum_size() const;
455
456 Window();
457 ~Window();
458};
459
460VARIANT_ENUM_CAST(Window::Mode);
461VARIANT_ENUM_CAST(Window::Flags);
462VARIANT_ENUM_CAST(Window::ContentScaleMode);
463VARIANT_ENUM_CAST(Window::ContentScaleAspect);
464VARIANT_ENUM_CAST(Window::ContentScaleStretch);
465VARIANT_ENUM_CAST(Window::LayoutDirection);
466VARIANT_ENUM_CAST(Window::WindowInitialPosition);
467
468#endif // WINDOW_H
469