summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/node_2d.cpp8
-rw-r--r--scene/2d/node_2d.h1
-rw-r--r--scene/3d/node_3d.cpp8
-rw-r--r--scene/3d/node_3d.h1
-rw-r--r--scene/gui/control.cpp8
-rw-r--r--scene/gui/control.h1
-rw-r--r--scene/main/node.cpp13
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/viewport.cpp1
-rw-r--r--scene/main/window.cpp40
-rw-r--r--scene/main/window.h12
11 files changed, 90 insertions, 4 deletions
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 0b7cdafdef..1c0efe773f 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -133,6 +133,14 @@ void Node2D::_update_transform() {
_notify_transform();
}
+void Node2D::reparent(Node *p_parent, bool p_keep_global_transform) {
+ Transform2D temp = get_global_transform();
+ Node::reparent(p_parent);
+ if (p_keep_global_transform) {
+ set_global_transform(temp);
+ }
+}
+
void Node2D::set_position(const Point2 &p_pos) {
if (_xform_dirty) {
const_cast<Node2D *>(this)->_update_xform_values();
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index e332745da5..119e23cd98 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -70,6 +70,7 @@ public:
virtual void _edit_set_rect(const Rect2 &p_edit_rect) override;
#endif
+ virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override;
void set_position(const Point2 &p_pos);
void set_rotation(real_t p_radians);
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index a0382b73dc..66e8831d15 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -623,6 +623,14 @@ void Node3D::set_disable_gizmos(bool p_enabled) {
#endif
}
+void Node3D::reparent(Node *p_parent, bool p_keep_global_transform) {
+ Transform3D temp = get_global_transform();
+ Node::reparent(p_parent);
+ if (p_keep_global_transform) {
+ set_global_transform(temp);
+ }
+}
+
void Node3D::set_disable_scale(bool p_enabled) {
data.disable_scale = p_enabled;
}
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index 0901ab331b..98bcab5fd4 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -206,6 +206,7 @@ public:
virtual void set_transform_gizmo_visible(bool p_enabled) { data.transform_gizmo_visible = p_enabled; };
virtual bool is_transform_gizmo_visible() const { return data.transform_gizmo_visible; };
#endif
+ virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override;
void set_disable_gizmos(bool p_enabled);
void update_gizmos();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 64d1d38abb..7daeb6eab6 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -186,6 +186,14 @@ Size2 Control::_edit_get_minimum_size() const {
}
#endif
+void Control::reparent(Node *p_parent, bool p_keep_global_transform) {
+ Transform2D temp = get_global_transform();
+ Node::reparent(p_parent);
+ if (p_keep_global_transform) {
+ set_global_position(temp.get_origin());
+ }
+}
+
// Editor integration.
void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 288de7c9e7..a11f7da00f 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -387,6 +387,7 @@ public:
virtual Size2 _edit_get_minimum_size() const override;
#endif
+ virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override;
// Editor integration.
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 8f173e4c0d..3544ec4c83 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1439,6 +1439,18 @@ TypedArray<Node> Node::find_children(const String &p_pattern, const String &p_ty
return ret;
}
+void Node::reparent(Node *p_parent, bool p_keep_global_transform) {
+ ERR_FAIL_NULL(p_parent);
+ ERR_FAIL_NULL_MSG(data.parent, "Node needs a parent to be reparented.");
+
+ if (p_parent == data.parent) {
+ return;
+ }
+
+ data.parent->remove_child(this);
+ p_parent->add_child(this);
+}
+
Node *Node::get_parent() const {
return data.parent;
}
@@ -2784,6 +2796,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name);
ClassDB::bind_method(D_METHOD("add_child", "node", "force_readable_name", "internal"), &Node::add_child, DEFVAL(false), DEFVAL(0));
ClassDB::bind_method(D_METHOD("remove_child", "node"), &Node::remove_child);
+ ClassDB::bind_method(D_METHOD("reparent", "new_parent", "keep_global_transform"), &Node::reparent, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_child_count", "include_internal"), &Node::get_child_count, DEFVAL(false)); // Note that the default value bound for include_internal is false, while the method is declared with true. This is because internal nodes are irrelevant for GDSCript.
ClassDB::bind_method(D_METHOD("get_children", "include_internal"), &Node::_get_children, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_child", "idx", "include_internal"), &Node::get_child, DEFVAL(false));
diff --git a/scene/main/node.h b/scene/main/node.h
index 611f48c400..398465c3cd 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -317,6 +317,7 @@ public:
bool has_node_and_resource(const NodePath &p_path) const;
Node *get_node_and_resource(const NodePath &p_path, Ref<Resource> &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const;
+ virtual void reparent(Node *p_parent, bool p_keep_global_transform = true);
Node *get_parent() const;
Node *find_parent(const String &p_pattern) const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 46d8c7df89..1287f69bef 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1298,7 +1298,6 @@ void Viewport::_gui_show_tooltip() {
r.position.y = vr.position.y;
}
- gui.tooltip_popup->set_current_screen(window->get_current_screen());
gui.tooltip_popup->set_position(r.position);
gui.tooltip_popup->set_size(r.size);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index d3fcf29927..c5dbfffd7b 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -223,6 +223,14 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Window::_validate_property(PropertyInfo &p_property) const {
+ if (p_property.name == "position" && initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
+
+ if (p_property.name == "current_screen" && initial_position != WINDOW_INITIAL_POSITION_CENTER_SCREEN) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
+
if (p_property.name == "theme_type_variation") {
List<StringName> names;
@@ -275,6 +283,15 @@ String Window::get_title() const {
return title;
}
+void Window::set_initial_position(Window::WindowInitialPosition p_initial_position) {
+ initial_position = p_initial_position;
+ notify_property_list_changed();
+}
+
+Window::WindowInitialPosition Window::get_initial_position() const {
+ return initial_position;
+}
+
void Window::set_current_screen(int p_screen) {
current_screen = p_screen;
if (window_id == DisplayServer::INVALID_WINDOW_ID) {
@@ -462,7 +479,13 @@ void Window::_make_window() {
}
DisplayServer::VSyncMode vsync_mode = DisplayServer::get_singleton()->window_get_vsync_mode(DisplayServer::MAIN_WINDOW_ID);
- window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, Rect2i(position, size), current_screen);
+ Rect2i window_rect;
+ if (initial_position == WINDOW_INITIAL_POSITION_ABSOLUTE) {
+ window_rect = Rect2i(position, size);
+ } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_SCREEN) {
+ window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(current_screen) + (DisplayServer::get_singleton()->screen_get_size(current_screen) - size) / 2, size);
+ }
+ window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, window_rect);
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
DisplayServer::get_singleton()->window_set_max_size(Size2i(), window_id);
DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id);
@@ -2068,6 +2091,9 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
+ ClassDB::bind_method(D_METHOD("set_initial_position", "initial_position"), &Window::set_initial_position);
+ ClassDB::bind_method(D_METHOD("get_initial_position"), &Window::get_initial_position);
+
ClassDB::bind_method(D_METHOD("set_current_screen", "index"), &Window::set_current_screen);
ClassDB::bind_method(D_METHOD("get_current_screen"), &Window::get_current_screen);
@@ -2204,11 +2230,18 @@ void Window::_bind_methods() {
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_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "initial_position", PROPERTY_HINT_ENUM, "Absolute,Screen Center"), "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");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
+
+ // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum.
+ String screen_hints = "Primary Monitor:-2,Main Window Monitor:-1";
+ for (int i = 0; i < 64; i++) {
+ screen_hints += ",Monitor " + itos(i + 1) + ":" + itos(i);
+ }
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen", PROPERTY_HINT_ENUM, screen_hints), "set_current_screen", "get_current_screen");
ADD_GROUP("Flags", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
@@ -2285,6 +2318,9 @@ void Window::_bind_methods() {
BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LOCALE);
BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LTR);
BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_RTL);
+
+ BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_ABSOLUTE);
+ BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_SCREEN);
}
Window::Window() {
diff --git a/scene/main/window.h b/scene/main/window.h
index 9a16a24e57..97f8450628 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -87,11 +87,16 @@ public:
DEFAULT_WINDOW_SIZE = 100,
};
+ enum WindowInitialPosition {
+ WINDOW_INITIAL_POSITION_ABSOLUTE,
+ WINDOW_INITIAL_POSITION_CENTER_SCREEN,
+ };
+
private:
DisplayServer::WindowID window_id = DisplayServer::INVALID_WINDOW_ID;
String title;
- mutable int current_screen = 0;
+ mutable int current_screen = DisplayServer::SCREEN_PRIMARY;
mutable Vector2i position;
mutable Size2i size = Size2i(DEFAULT_WINDOW_SIZE, DEFAULT_WINDOW_SIZE);
mutable Size2i min_size;
@@ -100,6 +105,7 @@ private:
mutable bool flags[FLAG_MAX] = {};
bool visible = true;
bool focused = false;
+ WindowInitialPosition initial_position = WINDOW_INITIAL_POSITION_ABSOLUTE;
bool use_font_oversampling = false;
bool transient = false;
@@ -201,6 +207,9 @@ public:
void set_title(const String &p_title);
String get_title() const;
+ void set_initial_position(WindowInitialPosition p_initial_position);
+ WindowInitialPosition get_initial_position() const;
+
void set_current_screen(int p_screen);
int get_current_screen() const;
@@ -369,5 +378,6 @@ VARIANT_ENUM_CAST(Window::Flags);
VARIANT_ENUM_CAST(Window::ContentScaleMode);
VARIANT_ENUM_CAST(Window::ContentScaleAspect);
VARIANT_ENUM_CAST(Window::LayoutDirection);
+VARIANT_ENUM_CAST(Window::WindowInitialPosition);
#endif // WINDOW_H