Browse Source

Prohibit inconsistent size state for SubViewport

Prohibit size changes of SubViewports with parent SubViewportContainers that have stretch mode enabled.
Markus Sauermann 2 years ago
parent
commit
decbda68d7

+ 1 - 0
doc/classes/SubViewport.xml

@@ -26,6 +26,7 @@
 		</member>
 		<member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(512, 512)">
 			The width and height of the sub-viewport. Must be set to a value greater than or equal to 2 pixels on both dimensions. Otherwise, nothing will be displayed.
+			[b]Note:[/b] If the parent node is a [SubViewportContainer] and its [member SubViewportContainer.stretch] is [code]true[/code], the viewport size cannot be changed manually.
 		</member>
 		<member name="size_2d_override" type="Vector2i" setter="set_size_2d_override" getter="get_size_2d_override" default="Vector2i(0, 0)">
 			The 2D size override of the sub-viewport. If either the width or height is [code]0[/code], the override is disabled.

+ 1 - 0
doc/classes/SubViewportContainer.xml

@@ -13,6 +13,7 @@
 	<members>
 		<member name="stretch" type="bool" setter="set_stretch" getter="is_stretch_enabled" default="false">
 			If [code]true[/code], the sub-viewport will be automatically resized to the control's size.
+			[b]Note:[/b] If [code]true[/code], this will prohibit changing [member SubViewport.size] of its children manually.
 		</member>
 		<member name="stretch_shrink" type="int" setter="set_stretch_shrink" getter="get_stretch_shrink" default="1">
 			Divides the sub-viewport's effective resolution by this value while preserving its scale. This can be used to speed up rendering.

+ 2 - 2
scene/gui/subviewport_container.cpp

@@ -85,7 +85,7 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) {
 			continue;
 		}
 
-		c->set_size(get_size() / shrink);
+		c->set_size_force(get_size() / shrink);
 	}
 
 	queue_redraw();
@@ -116,7 +116,7 @@ void SubViewportContainer::_notification(int p_what) {
 					continue;
 				}
 
-				c->set_size(get_size() / shrink);
+				c->set_size_force(get_size() / shrink);
 			}
 		} break;
 

+ 18 - 1
scene/main/viewport.cpp

@@ -4080,9 +4080,26 @@ Viewport::~Viewport() {
 /////////////////////////////////
 
 void SubViewport::set_size(const Size2i &p_size) {
-	_set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
+	_internal_set_size(p_size);
+}
 
+void SubViewport::set_size_force(const Size2i &p_size) {
+	// Use only for setting the size from the parent SubViewportContainer with enabled stretch mode.
+	// Don't expose function to scripting.
+	_internal_set_size(p_size, true);
+}
+
+void SubViewport::_internal_set_size(const Size2i &p_size, bool p_force) {
 	SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
+	if (!p_force && c && c->is_stretch_enabled()) {
+#ifdef DEBUG_ENABLED
+		WARN_PRINT("Can't change the size of a `SubViewport` with a `SubViewportContainer` parent that has `stretch` enabled. Set `SubViewportContainer.stretch` to `false` to allow changing the size manually.");
+#endif // DEBUG_ENABLED
+		return;
+	}
+
+	_set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
+
 	if (c) {
 		c->update_minimum_size();
 	}

+ 3 - 0
scene/main/viewport.h

@@ -743,6 +743,8 @@ private:
 	ClearMode clear_mode = CLEAR_MODE_ALWAYS;
 	bool size_2d_override_stretch = false;
 
+	void _internal_set_size(const Size2i &p_size, bool p_force = false);
+
 protected:
 	static void _bind_methods();
 	virtual DisplayServer::WindowID get_window_id() const override;
@@ -752,6 +754,7 @@ protected:
 public:
 	void set_size(const Size2i &p_size);
 	Size2i get_size() const;
+	void set_size_force(const Size2i &p_size);
 
 	void set_size_2d_override(const Size2i &p_size);
 	Size2i get_size_2d_override() const;