Merge pull request #76025 from YuriSizov/editor-reparentable-windows
Expose dialog parent-and-popup logic to the API
This commit is contained in:
commit
508a5bf16e
12 changed files with 242 additions and 82 deletions
|
@ -205,6 +205,43 @@
|
|||
Plays the main scene.
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_dialog">
|
||||
<return type="void" />
|
||||
<param index="0" name="dialog" type="Window" />
|
||||
<param index="1" name="rect" type="Rect2i" default="Rect2i(0, 0, 0, 0)" />
|
||||
<description>
|
||||
Pops up the [param dialog] in the editor UI with [method Window.popup_exclusive]. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method Window.set_unparent_when_invisible].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_dialog_centered">
|
||||
<return type="void" />
|
||||
<param index="0" name="dialog" type="Window" />
|
||||
<param index="1" name="minsize" type="Vector2i" default="Vector2i(0, 0)" />
|
||||
<description>
|
||||
Pops up the [param dialog] in the editor UI with [method Window.popup_exclusive_centered]. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method Window.set_unparent_when_invisible].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_dialog_centered_clamped">
|
||||
<return type="void" />
|
||||
<param index="0" name="dialog" type="Window" />
|
||||
<param index="1" name="minsize" type="Vector2i" default="Vector2i(0, 0)" />
|
||||
<param index="2" name="fallback_ratio" type="float" default="0.75" />
|
||||
<description>
|
||||
Pops up the [param dialog] in the editor UI with [method Window.popup_exclusive_centered_clamped]. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method Window.set_unparent_when_invisible].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_dialog_centered_ratio">
|
||||
<return type="void" />
|
||||
<param index="0" name="dialog" type="Window" />
|
||||
<param index="1" name="ratio" type="float" default="0.8" />
|
||||
<description>
|
||||
Pops up the [param dialog] in the editor UI with [method Window.popup_exclusive_centered_ratio]. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method Window.set_unparent_when_invisible].
|
||||
</description>
|
||||
</method>
|
||||
<method name="reload_scene_from_path">
|
||||
<return type="void" />
|
||||
<param index="0" name="scene_filepath" type="String" />
|
||||
|
|
|
@ -328,6 +328,12 @@
|
|||
If [param include_internal] is [code]false[/code], the index won't take internal children into account, i.e. first non-internal child will have index of 0 (see [code]internal[/code] parameter in [method add_child]).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_last_exclusive_window" qualifiers="const">
|
||||
<return type="Window" />
|
||||
<description>
|
||||
Returns the [Window] that contains this node, or the last exclusive child in a chain of windows starting with the one that contains this node.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_multiplayer_authority" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
|
|
|
@ -375,6 +375,52 @@
|
|||
Popups the [Window] centered inside its parent [Window] and sets its size as a [param ratio] of parent's size.
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_exclusive">
|
||||
<return type="void" />
|
||||
<param index="0" name="from_node" type="Node" />
|
||||
<param index="1" name="rect" type="Rect2i" default="Rect2i(0, 0, 0, 0)" />
|
||||
<description>
|
||||
Attempts to parent this dialog to the last exclusive window relative to [param from_node], and then calls [method Window.popup] on it. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method set_unparent_when_invisible] and [method Node.get_last_exclusive_window].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_exclusive_centered">
|
||||
<return type="void" />
|
||||
<param index="0" name="from_node" type="Node" />
|
||||
<param index="1" name="minsize" type="Vector2i" default="Vector2i(0, 0)" />
|
||||
<description>
|
||||
Attempts to parent this dialog to the last exclusive window relative to [param from_node], and then calls [method Window.popup_centered] on it. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method set_unparent_when_invisible] and [method Node.get_last_exclusive_window].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_exclusive_centered_clamped">
|
||||
<return type="void" />
|
||||
<param index="0" name="from_node" type="Node" />
|
||||
<param index="1" name="minsize" type="Vector2i" default="Vector2i(0, 0)" />
|
||||
<param index="2" name="fallback_ratio" type="float" default="0.75" />
|
||||
<description>
|
||||
Attempts to parent this dialog to the last exclusive window relative to [param from_node], and then calls [method Window.popup_centered_clamped] on it. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method set_unparent_when_invisible] and [method Node.get_last_exclusive_window].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_exclusive_centered_ratio">
|
||||
<return type="void" />
|
||||
<param index="0" name="from_node" type="Node" />
|
||||
<param index="1" name="ratio" type="float" default="0.8" />
|
||||
<description>
|
||||
Attempts to parent this dialog to the last exclusive window relative to [param from_node], and then calls [method Window.popup_centered_ratio] on it. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method set_unparent_when_invisible] and [method Node.get_last_exclusive_window].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_exclusive_on_parent">
|
||||
<return type="void" />
|
||||
<param index="0" name="from_node" type="Node" />
|
||||
<param index="1" name="parent_rect" type="Rect2i" />
|
||||
<description>
|
||||
Attempts to parent this dialog to the last exclusive window relative to [param from_node], and then calls [method Window.popup_on_parent] on it. The dialog must have no current parent, otherwise the method fails.
|
||||
See also [method set_unparent_when_invisible] and [method Node.get_last_exclusive_window].
|
||||
</description>
|
||||
</method>
|
||||
<method name="popup_on_parent">
|
||||
<return type="void" />
|
||||
<param index="0" name="parent_rect" type="Rect2i" />
|
||||
|
@ -465,6 +511,14 @@
|
|||
Sets layout direction and text writing direction. Right-to-left layouts are necessary for certain languages (e.g. Arabic and Hebrew).
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_unparent_when_invisible">
|
||||
<return type="void" />
|
||||
<param index="0" name="unparent" type="bool" />
|
||||
<description>
|
||||
If [param unparent] is [code]true[/code], the window is automatically unparented when going invisible.
|
||||
[b]Note:[/b] Make sure to keep a reference to the node, otherwise it will be orphaned. You also need to manually call [method Node.queue_free] to free the window if it's not parented.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_use_font_oversampling">
|
||||
<return type="void" />
|
||||
<param index="0" name="enable" type="bool" />
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "main/main.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/main/window.h"
|
||||
|
||||
EditorInterface *EditorInterface::singleton = nullptr;
|
||||
|
||||
|
@ -221,6 +222,22 @@ float EditorInterface::get_editor_scale() const {
|
|||
return EDSCALE;
|
||||
}
|
||||
|
||||
void EditorInterface::popup_dialog(Window *p_dialog, const Rect2i &p_screen_rect) {
|
||||
p_dialog->popup_exclusive(EditorNode::get_singleton(), p_screen_rect);
|
||||
}
|
||||
|
||||
void EditorInterface::popup_dialog_centered(Window *p_dialog, const Size2i &p_minsize) {
|
||||
p_dialog->popup_exclusive_centered(EditorNode::get_singleton(), p_minsize);
|
||||
}
|
||||
|
||||
void EditorInterface::popup_dialog_centered_ratio(Window *p_dialog, float p_ratio) {
|
||||
p_dialog->popup_exclusive_centered_ratio(EditorNode::get_singleton(), p_ratio);
|
||||
}
|
||||
|
||||
void EditorInterface::popup_dialog_centered_clamped(Window *p_dialog, const Size2i &p_size, float p_fallback_ratio) {
|
||||
p_dialog->popup_exclusive_centered_clamped(EditorNode::get_singleton(), p_size, p_fallback_ratio);
|
||||
}
|
||||
|
||||
// Editor docks.
|
||||
|
||||
FileSystemDock *EditorInterface::get_file_system_dock() const {
|
||||
|
@ -380,6 +397,11 @@ void EditorInterface::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("popup_dialog", "dialog", "rect"), &EditorInterface::popup_dialog, DEFVAL(Rect2i()));
|
||||
ClassDB::bind_method(D_METHOD("popup_dialog_centered", "dialog", "minsize"), &EditorInterface::popup_dialog_centered, DEFVAL(Size2i()));
|
||||
ClassDB::bind_method(D_METHOD("popup_dialog_centered_ratio", "dialog", "ratio"), &EditorInterface::popup_dialog_centered_ratio, DEFVAL(0.8));
|
||||
ClassDB::bind_method(D_METHOD("popup_dialog_centered_clamped", "dialog", "minsize", "fallback_ratio"), &EditorInterface::popup_dialog_centered_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distraction_free_mode"), "set_distraction_free_mode", "is_distraction_free_mode_enabled");
|
||||
|
||||
// Editor docks.
|
||||
|
|
|
@ -50,6 +50,7 @@ class Node;
|
|||
class ScriptEditor;
|
||||
class Texture2D;
|
||||
class VBoxContainer;
|
||||
class Window;
|
||||
|
||||
class EditorInterface : public Object {
|
||||
GDCLASS(EditorInterface, Object);
|
||||
|
@ -94,6 +95,11 @@ public:
|
|||
|
||||
float get_editor_scale() const;
|
||||
|
||||
void popup_dialog(Window *p_dialog, const Rect2i &p_screen_rect = Rect2i());
|
||||
void popup_dialog_centered(Window *p_dialog, const Size2i &p_minsize = Size2i());
|
||||
void popup_dialog_centered_ratio(Window *p_dialog, float p_ratio = 0.8);
|
||||
void popup_dialog_centered_clamped(Window *p_dialog, const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75);
|
||||
|
||||
// Editor docks.
|
||||
|
||||
FileSystemDock *get_file_system_dock() const;
|
||||
|
|
|
@ -160,51 +160,6 @@ static const String META_TEXT_TO_COPY = "text_to_copy";
|
|||
|
||||
static const String EDITOR_NODE_CONFIG_SECTION = "EditorNode";
|
||||
|
||||
class AcceptDialogAutoReparent : public AcceptDialog {
|
||||
GDCLASS(AcceptDialogAutoReparent, AcceptDialog);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
if (!is_visible()) {
|
||||
Node *p = get_parent();
|
||||
if (p) {
|
||||
p->remove_child(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void attach_and_popup_centered() {
|
||||
EditorNode *ed = EditorNode::get_singleton();
|
||||
if (ed && !is_inside_tree()) {
|
||||
Window *w = ed->get_window();
|
||||
while (w && w->get_exclusive_child()) {
|
||||
w = w->get_exclusive_child();
|
||||
}
|
||||
if (w && w != this) {
|
||||
w->add_child(this);
|
||||
popup_centered();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void attach_and_popup_centered_ratio(float p_ratio = 0.8) {
|
||||
EditorNode *ed = EditorNode::get_singleton();
|
||||
if (ed && !is_inside_tree()) {
|
||||
Window *w = ed->get_window();
|
||||
while (w && w->get_exclusive_child()) {
|
||||
w = w->get_exclusive_child();
|
||||
}
|
||||
if (w && w != this) {
|
||||
w->add_child(this);
|
||||
popup_centered_ratio(p_ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames) {
|
||||
ERR_FAIL_COND_MSG(p_full_paths.size() != r_filenames.size(), vformat("disambiguate_filenames requires two string vectors of same length (%d != %d).", p_full_paths.size(), r_filenames.size()));
|
||||
|
||||
|
@ -4118,7 +4073,7 @@ void EditorNode::add_io_error(const String &p_error) {
|
|||
DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id());
|
||||
singleton->load_errors->add_image(singleton->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
|
||||
singleton->load_errors->add_text(p_error + "\n");
|
||||
singleton->load_error_dialog->attach_and_popup_centered_ratio(0.5);
|
||||
EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5);
|
||||
}
|
||||
|
||||
bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
|
||||
|
@ -4459,7 +4414,7 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) {
|
|||
if (accept) {
|
||||
accept->set_ok_button_text(p_title);
|
||||
accept->set_text(p_text);
|
||||
accept->attach_and_popup_centered();
|
||||
EditorInterface::get_singleton()->popup_dialog_centered(accept);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4468,7 +4423,7 @@ void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
|
|||
if (save_accept) {
|
||||
save_accept->set_ok_button_text(p_title);
|
||||
save_accept->set_text(p_text);
|
||||
save_accept->attach_and_popup_centered();
|
||||
EditorInterface::get_singleton()->popup_dialog_centered(save_accept);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4476,7 +4431,7 @@ void EditorNode::show_warning(const String &p_text, const String &p_title) {
|
|||
if (warning) {
|
||||
warning->set_text(p_text);
|
||||
warning->set_title(p_title);
|
||||
warning->attach_and_popup_centered();
|
||||
EditorInterface::get_singleton()->popup_dialog_centered(warning);
|
||||
} else {
|
||||
WARN_PRINT(p_title + " " + p_text);
|
||||
}
|
||||
|
@ -6574,7 +6529,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
|
|||
execute_output_dialog->get_ok_button()->set_disabled(true);
|
||||
execute_outputs->clear();
|
||||
execute_outputs->set_scroll_follow(true);
|
||||
execute_output_dialog->attach_and_popup_centered_ratio();
|
||||
EditorInterface::get_singleton()->popup_dialog_centered_ratio(execute_output_dialog);
|
||||
}
|
||||
|
||||
ExecuteThreadArgs eta;
|
||||
|
@ -7188,10 +7143,11 @@ EditorNode::EditorNode() {
|
|||
prev_scene->set_position(Point2(3, 24));
|
||||
prev_scene->hide();
|
||||
|
||||
accept = memnew(AcceptDialogAutoReparent);
|
||||
accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current));
|
||||
accept = memnew(AcceptDialog);
|
||||
accept->set_unparent_when_invisible(true);
|
||||
|
||||
save_accept = memnew(AcceptDialogAutoReparent);
|
||||
save_accept = memnew(AcceptDialog);
|
||||
save_accept->set_unparent_when_invisible(true);
|
||||
save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind((int)MenuOptions::FILE_SAVE_AS_SCENE));
|
||||
|
||||
project_export = memnew(ProjectExportDialog);
|
||||
|
@ -7236,7 +7192,8 @@ EditorNode::EditorNode() {
|
|||
gui_base->add_child(fbx_importer_manager);
|
||||
#endif
|
||||
|
||||
warning = memnew(AcceptDialogAutoReparent);
|
||||
warning = memnew(AcceptDialog);
|
||||
warning->set_unparent_when_invisible(true);
|
||||
warning->add_button(TTR("Copy Text"), true, "copy");
|
||||
warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning));
|
||||
|
||||
|
@ -7909,14 +7866,16 @@ EditorNode::EditorNode() {
|
|||
set_process_shortcut_input(true);
|
||||
|
||||
load_errors = memnew(RichTextLabel);
|
||||
load_error_dialog = memnew(AcceptDialogAutoReparent);
|
||||
load_error_dialog = memnew(AcceptDialog);
|
||||
load_error_dialog->set_unparent_when_invisible(true);
|
||||
load_error_dialog->add_child(load_errors);
|
||||
load_error_dialog->set_title(TTR("Load Errors"));
|
||||
|
||||
execute_outputs = memnew(RichTextLabel);
|
||||
execute_outputs->set_selection_enabled(true);
|
||||
execute_outputs->set_context_menu_enabled(true);
|
||||
execute_output_dialog = memnew(AcceptDialogAutoReparent);
|
||||
execute_output_dialog = memnew(AcceptDialog);
|
||||
execute_output_dialog->set_unparent_when_invisible(true);
|
||||
execute_output_dialog->add_child(execute_outputs);
|
||||
execute_output_dialog->set_title("");
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ typedef void (*EditorPluginInitializeCallback)();
|
|||
typedef bool (*EditorBuildCallback)();
|
||||
|
||||
class AcceptDialog;
|
||||
class AcceptDialogAutoReparent;
|
||||
class CenterContainer;
|
||||
class CheckBox;
|
||||
class ColorPicker;
|
||||
|
@ -359,10 +358,10 @@ private:
|
|||
PluginConfigDialog *plugin_config_dialog = nullptr;
|
||||
|
||||
RichTextLabel *load_errors = nullptr;
|
||||
AcceptDialogAutoReparent *load_error_dialog = nullptr;
|
||||
AcceptDialog *load_error_dialog = nullptr;
|
||||
|
||||
RichTextLabel *execute_outputs = nullptr;
|
||||
AcceptDialogAutoReparent *execute_output_dialog = nullptr;
|
||||
AcceptDialog *execute_output_dialog = nullptr;
|
||||
|
||||
Ref<Theme> theme;
|
||||
|
||||
|
@ -377,10 +376,10 @@ private:
|
|||
ConfirmationDialog *import_confirmation = nullptr;
|
||||
ConfirmationDialog *pick_main_scene = nullptr;
|
||||
Button *select_current_scene_button = nullptr;
|
||||
AcceptDialogAutoReparent *accept = nullptr;
|
||||
AcceptDialogAutoReparent *save_accept = nullptr;
|
||||
AcceptDialog *accept = nullptr;
|
||||
AcceptDialog *save_accept = nullptr;
|
||||
EditorAbout *about = nullptr;
|
||||
AcceptDialogAutoReparent *warning = nullptr;
|
||||
AcceptDialog *warning = nullptr;
|
||||
|
||||
int overridden_default_layout = -1;
|
||||
Ref<ConfigFile> default_layout;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "core/object/message_queue.h"
|
||||
#include "core/os/os.h"
|
||||
#include "editor/editor_interface.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "main/main.h"
|
||||
|
@ -155,17 +156,7 @@ void ProgressDialog::_popup() {
|
|||
main->set_offset(SIDE_TOP, style->get_margin(SIDE_TOP));
|
||||
main->set_offset(SIDE_BOTTOM, -style->get_margin(SIDE_BOTTOM));
|
||||
|
||||
EditorNode *ed = EditorNode::get_singleton();
|
||||
if (ed && !is_inside_tree()) {
|
||||
Window *w = ed->get_window();
|
||||
while (w && w->get_exclusive_child()) {
|
||||
w = w->get_exclusive_child();
|
||||
}
|
||||
if (w && w != this) {
|
||||
w->add_child(this);
|
||||
popup_centered(ms);
|
||||
}
|
||||
}
|
||||
EditorInterface::get_singleton()->popup_dialog_centered(this, ms);
|
||||
}
|
||||
|
||||
void ProgressDialog::add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
|
||||
|
|
|
@ -1735,6 +1735,15 @@ Window *Node::get_window() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Window *Node::get_last_exclusive_window() const {
|
||||
Window *w = get_window();
|
||||
while (w && w->get_exclusive_child()) {
|
||||
w = w->get_exclusive_child();
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
bool Node::is_ancestor_of(const Node *p_node) const {
|
||||
ERR_FAIL_NULL_V(p_node, false);
|
||||
Node *p = p_node->data.parent;
|
||||
|
@ -3297,6 +3306,7 @@ void Node::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_physics_processing_internal"), &Node::is_physics_processing_internal);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
|
||||
ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);
|
||||
ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree);
|
||||
ClassDB::bind_method(D_METHOD("create_tween"), &Node::create_tween);
|
||||
|
||||
|
|
|
@ -385,6 +385,7 @@ public:
|
|||
Node *find_parent(const String &p_pattern) const;
|
||||
|
||||
Window *get_window() const;
|
||||
Window *get_last_exclusive_window() const;
|
||||
|
||||
_FORCE_INLINE_ SceneTree *get_tree() const {
|
||||
ERR_FAIL_COND_V(!data.tree, nullptr);
|
||||
|
|
|
@ -1210,12 +1210,6 @@ void Window::_notification(int p_what) {
|
|||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
emit_signal(SceneStringNames::get_singleton()->theme_changed);
|
||||
_invalidate_theme_cache();
|
||||
_update_theme_item_cache();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
if (wrap_controls) {
|
||||
// Finish any resizing immediately so it doesn't interfere on stuff overriding _ready().
|
||||
|
@ -1223,6 +1217,12 @@ void Window::_notification(int p_what) {
|
|||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
emit_signal(SceneStringNames::get_singleton()->theme_changed);
|
||||
_invalidate_theme_cache();
|
||||
_update_theme_item_cache();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
_invalidate_theme_cache();
|
||||
_update_theme_item_cache();
|
||||
|
@ -1241,6 +1241,15 @@ void Window::_notification(int p_what) {
|
|||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||
if (unparent_when_invisible && !is_visible()) {
|
||||
Node *p = get_parent();
|
||||
if (p) {
|
||||
p->remove_child(this);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
if (transient) {
|
||||
_clear_transient();
|
||||
|
@ -1656,6 +1665,48 @@ void Window::popup(const Rect2i &p_screen_rect) {
|
|||
notification(NOTIFICATION_POST_POPUP);
|
||||
}
|
||||
|
||||
bool Window::_try_parent_dialog(Node *p_from_node) {
|
||||
ERR_FAIL_NULL_V(p_from_node, false);
|
||||
ERR_FAIL_COND_V_MSG(is_inside_tree(), false, "Attempting to parent and popup a dialog that already has a parent.");
|
||||
|
||||
Window *w = p_from_node->get_last_exclusive_window();
|
||||
if (w && w != this) {
|
||||
w->add_child(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window::popup_exclusive(Node *p_from_node, const Rect2i &p_screen_rect) {
|
||||
if (_try_parent_dialog(p_from_node)) {
|
||||
popup(p_screen_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::popup_exclusive_on_parent(Node *p_from_node, const Rect2i &p_parent_rect) {
|
||||
if (_try_parent_dialog(p_from_node)) {
|
||||
popup_on_parent(p_parent_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::popup_exclusive_centered(Node *p_from_node, const Size2i &p_minsize) {
|
||||
if (_try_parent_dialog(p_from_node)) {
|
||||
popup_centered(p_minsize);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::popup_exclusive_centered_ratio(Node *p_from_node, float p_ratio) {
|
||||
if (_try_parent_dialog(p_from_node)) {
|
||||
popup_centered_ratio(p_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::popup_exclusive_centered_clamped(Node *p_from_node, const Size2i &p_size, float p_fallback_ratio) {
|
||||
if (_try_parent_dialog(p_from_node)) {
|
||||
popup_centered_clamped(p_size, p_fallback_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
Rect2i Window::fit_rect_in_parent(Rect2i p_rect, const Rect2i &p_parent_rect) const {
|
||||
ERR_READ_THREAD_GUARD_V(Rect2i());
|
||||
Size2i limit = p_parent_rect.size;
|
||||
|
@ -2318,6 +2369,10 @@ bool Window::is_clamped_to_embedder() const {
|
|||
return clamp_to_embedder;
|
||||
}
|
||||
|
||||
void Window::set_unparent_when_invisible(bool p_unparent) {
|
||||
unparent_when_invisible = p_unparent;
|
||||
}
|
||||
|
||||
void Window::set_layout_direction(Window::LayoutDirection p_direction) {
|
||||
ERR_MAIN_THREAD_GUARD;
|
||||
ERR_FAIL_INDEX((int)p_direction, 4);
|
||||
|
@ -2469,6 +2524,8 @@ void Window::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_exclusive", "exclusive"), &Window::set_exclusive);
|
||||
ClassDB::bind_method(D_METHOD("is_exclusive"), &Window::is_exclusive);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_unparent_when_invisible", "unparent"), &Window::set_unparent_when_invisible);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("can_draw"), &Window::can_draw);
|
||||
ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus);
|
||||
ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus);
|
||||
|
@ -2562,10 +2619,16 @@ void Window::_bind_methods() {
|
|||
|
||||
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_ratio", "ratio"), &Window::popup_centered_ratio, DEFVAL(0.8));
|
||||
ClassDB::bind_method(D_METHOD("popup_centered_clamped", "minsize", "fallback_ratio"), &Window::popup_centered_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("popup_exclusive", "from_node", "rect"), &Window::popup_exclusive, DEFVAL(Rect2i()));
|
||||
ClassDB::bind_method(D_METHOD("popup_exclusive_on_parent", "from_node", "parent_rect"), &Window::popup_exclusive_on_parent);
|
||||
ClassDB::bind_method(D_METHOD("popup_exclusive_centered", "from_node", "minsize"), &Window::popup_exclusive_centered, DEFVAL(Size2i()));
|
||||
ClassDB::bind_method(D_METHOD("popup_exclusive_centered_ratio", "from_node", "ratio"), &Window::popup_exclusive_centered_ratio, DEFVAL(0.8));
|
||||
ClassDB::bind_method(D_METHOD("popup_exclusive_centered_clamped", "from_node", "minsize", "fallback_ratio"), &Window::popup_exclusive_centered_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "initial_position", PROPERTY_HINT_ENUM, "Absolute,Center of Primary Screen,Center of Other Screen,Center of Screen With Mouse Pointer,Center of Screen With Keyboard Focus"), "set_initial_position", "get_initial_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position", PROPERTY_HINT_NONE, "suffix:px"), "set_position", "get_position");
|
||||
|
|
|
@ -121,6 +121,7 @@ private:
|
|||
bool updating_child_controls = false;
|
||||
bool updating_embedded_window = false;
|
||||
bool clamp_to_embedder = false;
|
||||
bool unparent_when_invisible = false;
|
||||
|
||||
LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED;
|
||||
|
||||
|
@ -138,6 +139,8 @@ private:
|
|||
void _clear_window();
|
||||
void _update_from_window();
|
||||
|
||||
bool _try_parent_dialog(Node *p_from_node);
|
||||
|
||||
Size2i max_size_used;
|
||||
|
||||
Size2i _clamp_limit_size(const Size2i &p_limit_size);
|
||||
|
@ -272,6 +275,8 @@ public:
|
|||
void set_clamp_to_embedder(bool p_enable);
|
||||
bool is_clamped_to_embedder() const;
|
||||
|
||||
void set_unparent_when_invisible(bool p_unparent);
|
||||
|
||||
bool is_in_edited_scene_root() const;
|
||||
|
||||
bool can_draw() const;
|
||||
|
@ -307,12 +312,19 @@ public:
|
|||
Window *get_exclusive_child() const { return exclusive_child; };
|
||||
Window *get_parent_visible_window() const;
|
||||
Viewport *get_parent_viewport() const;
|
||||
void popup(const Rect2i &p_rect = Rect2i());
|
||||
|
||||
void popup(const Rect2i &p_screen_rect = Rect2i());
|
||||
void popup_on_parent(const Rect2i &p_parent_rect);
|
||||
void popup_centered_ratio(float p_ratio = 0.8);
|
||||
void popup_centered(const Size2i &p_minsize = Size2i());
|
||||
void popup_centered_ratio(float p_ratio = 0.8);
|
||||
void popup_centered_clamped(const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75);
|
||||
|
||||
void popup_exclusive(Node *p_from_node, const Rect2i &p_screen_rect = Rect2i());
|
||||
void popup_exclusive_on_parent(Node *p_from_node, const Rect2i &p_parent_rect);
|
||||
void popup_exclusive_centered(Node *p_from_node, const Size2i &p_minsize = Size2i());
|
||||
void popup_exclusive_centered_ratio(Node *p_from_node, float p_ratio = 0.8);
|
||||
void popup_exclusive_centered_clamped(Node *p_from_node, const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75);
|
||||
|
||||
Rect2i fit_rect_in_parent(Rect2i p_rect, const Rect2i &p_parent_rect) const;
|
||||
Size2 get_contents_minimum_size() const;
|
||||
Size2 get_clamped_minimum_size() const;
|
||||
|
|
Loading…
Reference in a new issue