Browse Source

Add node configuration warnings for nested clipping and CanvasGroups

Many subclasses of CanvasItem had to have their `get_configuration_warnings` methods updated so they would display the warning as well

Make clip children warning update whenever clip_children_mode is modified

Update scene/main/canvas_item.h

Co-authored-by: A Thousand Ships <[email protected]>

Add warning if ancestor of clipping CanvasItem is CanvasGroup

Add warnings for CanvasGroup when ancestors are CanvasGroups or clip children
Malcolm Anderson 8 tháng trước cách đây
mục cha
commit
60a9c8e2ea

+ 32 - 0
scene/2d/canvas_group.cpp

@@ -64,6 +64,38 @@ bool CanvasGroup::is_using_mipmaps() const {
 	return use_mipmaps;
 	return use_mipmaps;
 }
 }
 
 
+PackedStringArray CanvasGroup::get_configuration_warnings() const {
+	PackedStringArray warnings = Node2D::get_configuration_warnings();
+
+	if (is_inside_tree()) {
+		bool warned_about_ancestor_clipping = false;
+		bool warned_about_canvasgroup_ancestor = false;
+		Node *n = get_parent();
+		while (n) {
+			CanvasItem *as_canvas_item = Object::cast_to<CanvasItem>(n);
+			if (!warned_about_ancestor_clipping && as_canvas_item && as_canvas_item->get_clip_children_mode() != CLIP_CHILDREN_DISABLED) {
+				warnings.push_back(vformat(RTR("Ancestor \"%s\" clips its children, so this CanvasGroup will not function properly."), as_canvas_item->get_name()));
+				warned_about_ancestor_clipping = true;
+			}
+
+			CanvasGroup *as_canvas_group = Object::cast_to<CanvasGroup>(n);
+			if (!warned_about_canvasgroup_ancestor && as_canvas_group) {
+				warnings.push_back(vformat(RTR("Ancestor \"%s\" is a CanvasGroup, so this CanvasGroup will not function properly."), as_canvas_group->get_name()));
+				warned_about_canvasgroup_ancestor = true;
+			}
+
+			// Only break out early once both warnings have been triggered, so
+			// that the user is aware of both possible reasons for clipping not working.
+			if (warned_about_ancestor_clipping && warned_about_canvasgroup_ancestor) {
+				break;
+			}
+			n = n->get_parent();
+		}
+	}
+
+	return warnings;
+}
+
 void CanvasGroup::_bind_methods() {
 void CanvasGroup::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_fit_margin", "fit_margin"), &CanvasGroup::set_fit_margin);
 	ClassDB::bind_method(D_METHOD("set_fit_margin", "fit_margin"), &CanvasGroup::set_fit_margin);
 	ClassDB::bind_method(D_METHOD("get_fit_margin"), &CanvasGroup::get_fit_margin);
 	ClassDB::bind_method(D_METHOD("get_fit_margin"), &CanvasGroup::get_fit_margin);

+ 2 - 0
scene/2d/canvas_group.h

@@ -51,6 +51,8 @@ public:
 	void set_use_mipmaps(bool p_use_mipmaps);
 	void set_use_mipmaps(bool p_use_mipmaps);
 	bool is_using_mipmaps() const;
 	bool is_using_mipmaps() const;
 
 
+	virtual PackedStringArray get_configuration_warnings() const override;
+
 	CanvasGroup();
 	CanvasGroup();
 	~CanvasGroup();
 	~CanvasGroup();
 };
 };

+ 34 - 0
scene/main/canvas_item.cpp

@@ -1245,6 +1245,38 @@ void CanvasItem::_validate_property(PropertyInfo &p_property) const {
 	}
 	}
 }
 }
 
 
+PackedStringArray CanvasItem::get_configuration_warnings() const {
+	PackedStringArray warnings = Node::get_configuration_warnings();
+
+	if (clip_children_mode != CLIP_CHILDREN_DISABLED && is_inside_tree()) {
+		bool warned_about_ancestor_clipping = false;
+		bool warned_about_canvasgroup_ancestor = false;
+		Node *n = get_parent();
+		while (n) {
+			CanvasItem *as_canvas_item = Object::cast_to<CanvasItem>(n);
+			if (!warned_about_ancestor_clipping && as_canvas_item && as_canvas_item->clip_children_mode != CLIP_CHILDREN_DISABLED) {
+				warnings.push_back(vformat(RTR("Ancestor \"%s\" clips its children, so this node will not be able to clip its children."), as_canvas_item->get_name()));
+				warned_about_ancestor_clipping = true;
+			}
+
+			CanvasGroup *as_canvas_group = Object::cast_to<CanvasGroup>(n);
+			if (!warned_about_canvasgroup_ancestor && as_canvas_group) {
+				warnings.push_back(vformat(RTR("Ancestor \"%s\" is a CanvasGroup, so this node will not be able to clip its children."), as_canvas_group->get_name()));
+				warned_about_canvasgroup_ancestor = true;
+			}
+
+			// Only break out early once both warnings have been triggered, so
+			// that the user is aware of both possible reasons for clipping not working.
+			if (warned_about_ancestor_clipping && warned_about_canvasgroup_ancestor) {
+				break;
+			}
+			n = n->get_parent();
+		}
+	}
+
+	return warnings;
+}
+
 void CanvasItem::_bind_methods() {
 void CanvasItem::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_top_level_raise_self"), &CanvasItem::_top_level_raise_self);
 	ClassDB::bind_method(D_METHOD("_top_level_raise_self"), &CanvasItem::_top_level_raise_self);
 
 
@@ -1646,6 +1678,8 @@ void CanvasItem::set_clip_children_mode(ClipChildrenMode p_clip_mode) {
 	}
 	}
 	clip_children_mode = p_clip_mode;
 	clip_children_mode = p_clip_mode;
 
 
+	update_configuration_warnings();
+
 	if (Object::cast_to<CanvasGroup>(this) != nullptr) {
 	if (Object::cast_to<CanvasGroup>(this) != nullptr) {
 		//avoid accidental bugs, make this not work on CanvasGroup
 		//avoid accidental bugs, make this not work on CanvasGroup
 		return;
 		return;

+ 2 - 0
scene/main/canvas_item.h

@@ -398,6 +398,8 @@ public:
 	int get_canvas_layer() const;
 	int get_canvas_layer() const;
 	CanvasLayer *get_canvas_layer_node() const;
 	CanvasLayer *get_canvas_layer_node() const;
 
 
+	virtual PackedStringArray get_configuration_warnings() const override;
+
 	CanvasItem();
 	CanvasItem();
 	~CanvasItem();
 	~CanvasItem();
 };
 };