Skip to content

Commit

Permalink
Expose dialog parent-and-popup logic to the API
Browse files Browse the repository at this point in the history
  • Loading branch information
YuriSizov committed May 15, 2023
1 parent 5c653c2 commit 17f492f
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 82 deletions.
37 changes: 37 additions & 0 deletions doc/classes/EditorInterface.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
6 changes: 6 additions & 0 deletions doc/classes/Node.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
54 changes: 54 additions & 0 deletions doc/classes/Window.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down Expand Up @@ -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" />
Expand Down
22 changes: 22 additions & 0 deletions editor/editor_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions editor/editor_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Node;
class ScriptEditor;
class Texture2D;
class VBoxContainer;
class Window;

class EditorInterface : public Object {
GDCLASS(EditorInterface, Object);
Expand Down Expand Up @@ -94,6 +95,11 @@ class EditorInterface : public Object {

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;
Expand Down
71 changes: 15 additions & 56 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()));

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -4468,15 +4423,15 @@ 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);
}
}

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);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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("");

Expand Down
11 changes: 5 additions & 6 deletions editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ typedef void (*EditorPluginInitializeCallback)();
typedef bool (*EditorBuildCallback)();

class AcceptDialog;
class AcceptDialogAutoReparent;
class CenterContainer;
class CheckBox;
class ColorPicker;
Expand Down Expand Up @@ -359,10 +358,10 @@ class EditorNode : public Node {
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;

Expand All @@ -377,10 +376,10 @@ class EditorNode : public Node {
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;
Expand Down
13 changes: 2 additions & 11 deletions editor/progress_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit 17f492f

Please sign in to comment.