From b3080bc2f4d7bc5c15b3a0ff7b67690c4677577e Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 19 Mar 2020 23:32:09 -0300 Subject: Popups have also been converted to windows Controls using the old modal API have been replaced to use popups. --- scene/main/viewport.cpp | 28 ++++++++++++++++++++++++++-- scene/main/viewport.h | 4 ++++ scene/main/window.cpp | 35 +++++++++++++++++++++++++++++++++-- scene/main/window.h | 11 +++++++---- 4 files changed, 70 insertions(+), 8 deletions(-) (limited to 'scene/main') diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 0dcb013c37..b809dc4d3a 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -191,6 +191,7 @@ Viewport::GUI::GUI() { dragging = false; mouse_focus = NULL; + forced_mouse_focus = false; mouse_click_grabber = NULL; mouse_focus_mask = 0; key_focus = NULL; @@ -595,6 +596,7 @@ void Viewport::_notification(int p_what) { if (!has_mouse_event) { Ref mm; mm.instance(); + mm->set_device(InputEvent::DEVICE_ID_INTERNAL); mm->set_global_position(physics_last_mousepos); mm->set_position(physics_last_mousepos); @@ -847,8 +849,7 @@ void Viewport::_notification(int p_what) { _drop_physics_mouseover(); - if (gui.mouse_focus) { - //if mouse is being pressed, send a release event + if (gui.mouse_focus && !gui.forced_mouse_focus) { _drop_mouse_focus(); } } break; @@ -1107,7 +1108,9 @@ void Viewport::_camera_set(Camera *p_camera) { if (camera) { camera->notification(Camera::NOTIFICATION_LOST_CURRENT); } + camera = p_camera; + if (!camera_override) { if (camera) VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera()); @@ -1984,6 +1987,7 @@ void Viewport::_gui_input_event(Ref p_event) { //disable mouse focus if needed before calling input, this makes popups on mouse press event work better, as the release will never be received otherwise if (gui.mouse_focus_mask == 0) { gui.mouse_focus = NULL; + gui.forced_mouse_focus = false; } if (mouse_focus && mouse_focus->can_process()) { @@ -2029,6 +2033,7 @@ void Viewport::_gui_input_event(Ref p_event) { if (gui.drag_data.get_type() != Variant::NIL) { gui.mouse_focus = NULL; + gui.forced_mouse_focus = false; gui.mouse_focus_mask = 0; break; } else { @@ -2427,6 +2432,7 @@ void Viewport::_gui_remove_control(Control *p_control) { if (gui.mouse_focus == p_control) { gui.mouse_focus = NULL; + gui.forced_mouse_focus = false; gui.mouse_focus_mask = 0; } if (gui.last_mouse_focus == p_control) { @@ -2481,6 +2487,7 @@ void Viewport::_drop_mouse_focus() { Control *c = gui.mouse_focus; int mask = gui.mouse_focus_mask; gui.mouse_focus = NULL; + gui.forced_mouse_focus = false; gui.mouse_focus_mask = 0; for (int i = 0; i < 3; i++) { @@ -3234,6 +3241,22 @@ bool Viewport::is_embedding_subwindows() const { return gui.embed_subwindows_hint; } +void Viewport::pass_mouse_focus_to(Viewport *p_viewport, Control *p_control) { + ERR_FAIL_NULL(p_viewport); + ERR_FAIL_NULL(p_control); + + if (gui.mouse_focus) { + p_viewport->gui.mouse_focus = p_control; + p_viewport->gui.mouse_focus_mask = gui.mouse_focus_mask; + p_viewport->gui.key_focus = p_control; + p_viewport->gui.forced_mouse_focus = true; + + gui.mouse_focus = nullptr; + gui.forced_mouse_focus = false; + gui.mouse_focus_mask = 0; + } +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d); @@ -3465,6 +3488,7 @@ Viewport::Viewport() { gui.canvas_sort_index = 0; gui.roots_order_dirty = false; gui.mouse_focus = NULL; + gui.forced_mouse_focus = false; gui.last_mouse_focus = NULL; gui.subwindow_focused = nullptr; gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 08dd505161..5065ebef1a 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -302,6 +302,7 @@ private: struct GUI { // info used when this is a window + bool forced_mouse_focus; //used for menu buttons bool key_event_accepted; Control *mouse_focus; Control *last_mouse_focus; @@ -555,6 +556,9 @@ public: bool is_embedding_subwindows() const; Viewport *get_parent_viewport() const; + + void pass_mouse_focus_to(Viewport *p_viewport, Control *p_control); + Viewport(); ~Viewport(); }; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 4ea00a4187..4b5710e8a4 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -35,6 +35,7 @@ #include "scene/gui/control.h" #include "scene/resources/dynamic_font.h" #include "scene/scene_string_names.h" + void Window::set_title(const String &p_title) { title = p_title; @@ -207,8 +208,8 @@ void Window::set_ime_position(const Point2i &p_pos) { bool Window::is_embedded() const { ERR_FAIL_COND_V(!is_inside_tree(), false); - Viewport *parent_vp = get_parent_viewport(); - return parent_vp && parent_vp->is_embedding_subwindows(); + + return _get_embedder() != nullptr; } void Window::_make_window() { @@ -1027,6 +1028,12 @@ void Window::popup(const Rect2 &p_screen_rect) { set_size(p_screen_rect.size); } + Rect2i adjust = _popup_adjust_rect(); + if (adjust != Rect2i()) { + set_position(adjust.position); + set_size(adjust.size); + } + set_transient(true); set_visible(true); _post_popup(); @@ -1049,6 +1056,24 @@ bool Window::has_focus() const { return focused; } +Rect2i Window::get_usable_parent_rect() const { + ERR_FAIL_COND_V(!is_inside_tree(), Rect2()); + Rect2i parent; + if (is_embedded()) { + parent = _get_embedder()->get_visible_rect(); + print_line("using embedded " + parent); + } else { + + const Window *w = is_visible() ? this : get_parent_visible_window(); + //find a parent that can contain us + ERR_FAIL_COND_V(!w, Rect2()); + + parent = DisplayServer::get_singleton()->screen_get_usable_rect(DisplayServer::get_singleton()->window_get_current_screen(w->get_window_id())); + print_line("using windowid " + parent); + } + return parent; +} + void Window::add_child_notify(Node *p_child) { Control *child_c = Object::cast_to(p_child); @@ -1292,6 +1317,12 @@ void Window::_bind_methods() { 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("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)); + ClassDB::bind_method(D_METHOD("popup_centered", "minsize"), &Window::popup_centered, DEFVAL(Size2i())); + ClassDB::bind_method(D_METHOD("popup_centered_clamped", "minsize", "fallback_ratio"), &Window::popup_centered, DEFVAL(Size2i()), DEFVAL(0.75)); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size"); diff --git a/scene/main/window.h b/scene/main/window.h index 04c077a550..77bbfec8d8 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -108,8 +108,6 @@ private: void _propagate_window_notification(Node *p_node, int p_notification); - virtual DisplayServer::WindowID get_window_id() const; - void _update_window_callbacks(); void _clear_transient(); @@ -123,8 +121,6 @@ private: Control *theme_owner = nullptr; Window *theme_owner_window = nullptr; - Viewport *_get_embedder() const; - Viewport *embedder = nullptr; friend class Viewport; //friend back, can call the methods below @@ -136,6 +132,10 @@ private: void _event_callback(DisplayServer::WindowEvent p_event); protected: + Viewport *_get_embedder() const; + + virtual Rect2i _popup_adjust_rect() const { return Rect2i(); } + virtual void _post_popup() {} virtual Size2 _get_contents_minimum_size() const; static void _bind_methods(); @@ -234,6 +234,8 @@ public: void grab_focus(); bool has_focus() const; + Rect2i get_usable_parent_rect() const; + Ref get_theme_icon(const StringName &p_name, const StringName &p_type = StringName()) const; Ref get_theme_shader(const StringName &p_name, const StringName &p_type = StringName()) const; Ref get_theme_stylebox(const StringName &p_name, const StringName &p_type = StringName()) const; @@ -249,6 +251,7 @@ public: bool has_theme_constant(const StringName &p_name, const StringName &p_type = StringName()) const; Rect2i get_parent_rect() const; + virtual DisplayServer::WindowID get_window_id() const; Window(); ~Window(); -- cgit v1.2.3