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 Apr 19, 2023
1 parent 27253f3 commit 0aac5e4
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 79 deletions.
16 changes: 16 additions & 0 deletions doc/classes/EditorInterface.xml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,22 @@
Plays the main scene.
</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>
Attempts to parent the [param dialog] to the editor UI, and then calls [method Window.popup_centered] on it. The dialog must have no current parent, otherwise the method fails.
</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>
Attempts to parent the [param dialog] to the editor UI, and then calls [method Window.popup_centered_ratio] on it. The dialog must have no current parent, otherwise the method fails.
</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 @@ -314,6 +314,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
8 changes: 8 additions & 0 deletions doc/classes/Window.xml
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,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.
</description>
</method>
<method name="set_use_font_oversampling">
<return type="void" />
<param index="0" name="enable" type="bool" />
Expand Down
30 changes: 30 additions & 0 deletions editor/editor_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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 @@ -220,6 +221,32 @@ float EditorInterface::get_editor_scale() const {
return EDSCALE;
}

bool EditorInterface::_try_parent_dialog(Window *p_dialog) {
ERR_FAIL_COND_V_MSG(p_dialog->is_inside_tree(), false, "Attempting to parent and popup a dialog that already has a parent.");

EditorNode *ed = EditorNode::get_singleton();
ERR_FAIL_NULL_V(ed, false);

Window *w = ed->get_last_exclusive_window();
if (w && w != p_dialog) {
w->add_child(p_dialog);
return true;
}
return false;
}

void EditorInterface::popup_dialog_centered(Window *p_dialog, const Size2i &p_minsize) {
if (_try_parent_dialog(p_dialog)) {
p_dialog->popup_centered(p_minsize);
}
}

void EditorInterface::popup_dialog_centered_ratio(Window *p_dialog, float p_ratio) {
if (_try_parent_dialog(p_dialog)) {
p_dialog->popup_centered_ratio(p_ratio);
}
}

// Editor docks.

FileSystemDock *EditorInterface::get_file_system_dock() const {
Expand Down Expand Up @@ -379,6 +406,9 @@ void EditorInterface::_bind_methods() {

ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);

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));

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distraction_free_mode"), "set_distraction_free_mode", "is_distraction_free_mode_enabled");

// Editor docks.
Expand Down
8 changes: 8 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 All @@ -60,6 +61,10 @@ class EditorInterface : public Object {

TypedArray<Texture2D> _make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size);

// Editor GUI.

bool _try_parent_dialog(Window *p_dialog);

protected:
static void _bind_methods();

Expand Down Expand Up @@ -94,6 +99,9 @@ class EditorInterface : public Object {

float get_editor_scale() const;

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);

// 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 @@ -153,51 +153,6 @@ EditorNode *EditorNode::singleton = nullptr;
// The metadata key used to store and retrieve the version text to copy to the clipboard.
static const String META_TEXT_TO_COPY = "text_to_copy";

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 @@ -4279,7 +4234,7 @@ void EditorNode::_load_error_notify(void *p_ud, const String &p_text) {
if (en && en->load_error_dialog) {
en->load_errors->add_image(en->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
en->load_errors->add_text(p_text + "\n");
en->load_error_dialog->attach_and_popup_centered_ratio(0.5);
EditorInterface::get_singleton()->popup_dialog_centered_ratio(en->load_error_dialog, 0.5);
}
}

Expand Down Expand Up @@ -4622,7 +4577,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 @@ -4631,15 +4586,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 @@ -6588,7 +6543,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 @@ -7199,10 +7154,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 @@ -7247,7 +7203,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 @@ -8013,14 +7970,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 @@ -43,7 +43,6 @@ typedef void (*EditorPluginInitializeCallback)();
typedef bool (*EditorBuildCallback)();

class AcceptDialog;
class AcceptDialogAutoReparent;
class CenterContainer;
class CheckBox;
class ColorPicker;
Expand Down Expand Up @@ -371,10 +370,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 @@ -389,10 +388,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
10 changes: 10 additions & 0 deletions scene/main/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,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;
Expand Down Expand Up @@ -2908,6 +2917,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);

Expand Down
1 change: 1 addition & 0 deletions scene/main/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ class Node : public Object {
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);
Expand Down
Loading

0 comments on commit 0aac5e4

Please sign in to comment.