Просмотр исходного кода

Add ability to flip TextureRect horizontally or vertically

PouleyKetchoupp 6 лет назад
Родитель
Сommit
8b84638322

+ 6 - 0
doc/classes/TextureRect.xml

@@ -22,6 +22,12 @@
 		<member name="texture" type="Texture" setter="set_texture" getter="get_texture">
 			The node's [Texture] resource.
 		</member>
+		<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h">
+			If [code]true[/code], texture is flipped horizontally. Default value: [code]false[/code].
+		</member>
+		<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v">
+			If [code]true[/code], texture is flipped vertically. Default value: [code]false[/code].
+		</member>
 	</members>
 	<constants>
 		<constant name="STRETCH_SCALE_ON_EXPAND" value="0" enum="StretchMode">

+ 59 - 20
scene/gui/texture_rect.cpp

@@ -38,30 +38,32 @@ void TextureRect::_notification(int p_what) {
 		if (texture.is_null())
 			return;
 
+		Size2 size;
+		Point2 offset;
+		Rect2 region;
+		bool tile = false;
+
 		switch (stretch_mode) {
 			case STRETCH_SCALE_ON_EXPAND: {
-				Size2 s = expand ? get_size() : texture->get_size();
-				draw_texture_rect(texture, Rect2(Point2(), s), false);
+				size = expand ? get_size() : texture->get_size();
 			} break;
 			case STRETCH_SCALE: {
-				draw_texture_rect(texture, Rect2(Point2(), get_size()), false);
+				size = get_size();
 			} break;
 			case STRETCH_TILE: {
-				draw_texture_rect(texture, Rect2(Point2(), get_size()), true);
+				size = get_size();
+				tile = true;
 			} break;
 			case STRETCH_KEEP: {
-				draw_texture_rect(texture, Rect2(Point2(), texture->get_size()), false);
-
+				size = texture->get_size();
 			} break;
 			case STRETCH_KEEP_CENTERED: {
-
-				Vector2 ofs = (get_size() - texture->get_size()) / 2;
-				draw_texture_rect(texture, Rect2(ofs, texture->get_size()), false);
+				offset = (get_size() - texture->get_size()) / 2;
+				size = texture->get_size();
 			} break;
 			case STRETCH_KEEP_ASPECT_CENTERED:
 			case STRETCH_KEEP_ASPECT: {
-
-				Size2 size = get_size();
+				size = get_size();
 				int tex_width = texture->get_width() * size.height / texture->get_height();
 				int tex_height = size.height;
 
@@ -70,26 +72,35 @@ void TextureRect::_notification(int p_what) {
 					tex_height = texture->get_height() * tex_width / texture->get_width();
 				}
 
-				int ofs_x = 0;
-				int ofs_y = 0;
-
 				if (stretch_mode == STRETCH_KEEP_ASPECT_CENTERED) {
-					ofs_x += (size.width - tex_width) / 2;
-					ofs_y += (size.height - tex_height) / 2;
+					offset.x += (size.width - tex_width) / 2;
+					offset.y += (size.height - tex_height) / 2;
 				}
 
-				draw_texture_rect(texture, Rect2(ofs_x, ofs_y, tex_width, tex_height));
+				size.width = tex_width;
+				size.height = tex_height;
 			} break;
 			case STRETCH_KEEP_ASPECT_COVERED: {
-				Size2 size = get_size();
+				size = get_size();
+
 				Size2 tex_size = texture->get_size();
 				Size2 scaleSize(size.width / tex_size.width, size.height / tex_size.height);
 				float scale = scaleSize.width > scaleSize.height ? scaleSize.width : scaleSize.height;
 				Size2 scaledTexSize = tex_size * scale;
-				Point2 ofs = ((scaledTexSize - size) / scale).abs() / 2.0f;
-				draw_texture_rect_region(texture, Rect2(Point2(), size), Rect2(ofs, size / scale));
+
+				region.position = ((scaledTexSize - size) / scale).abs() / 2.0f;
+				region.size = size / scale;
 			} break;
 		}
+
+		size.width *= hflip ? -1.0f : 1.0f;
+		size.height *= vflip ? -1.0f : 1.0f;
+
+		if (region.no_area()) {
+			draw_texture_rect(texture, Rect2(offset, size), tile);
+		} else {
+			draw_texture_rect_region(texture, Rect2(offset, size), region);
+		}
 	}
 }
 
@@ -106,12 +117,18 @@ void TextureRect::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_texture"), &TextureRect::get_texture);
 	ClassDB::bind_method(D_METHOD("set_expand", "enable"), &TextureRect::set_expand);
 	ClassDB::bind_method(D_METHOD("has_expand"), &TextureRect::has_expand);
+	ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureRect::set_flip_h);
+	ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureRect::is_flipped_h);
+	ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureRect::set_flip_v);
+	ClassDB::bind_method(D_METHOD("is_flipped_v"), &TextureRect::is_flipped_v);
 	ClassDB::bind_method(D_METHOD("set_stretch_mode", "stretch_mode"), &TextureRect::set_stretch_mode);
 	ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode);
 
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v");
 
 	BIND_ENUM_CONSTANT(STRETCH_SCALE_ON_EXPAND);
 	BIND_ENUM_CONSTANT(STRETCH_SCALE);
@@ -161,9 +178,31 @@ TextureRect::StretchMode TextureRect::get_stretch_mode() const {
 	return stretch_mode;
 }
 
+void TextureRect::set_flip_h(bool p_flip) {
+
+	hflip = p_flip;
+	update();
+}
+bool TextureRect::is_flipped_h() const {
+
+	return hflip;
+}
+
+void TextureRect::set_flip_v(bool p_flip) {
+
+	vflip = p_flip;
+	update();
+}
+bool TextureRect::is_flipped_v() const {
+
+	return vflip;
+}
+
 TextureRect::TextureRect() {
 
 	expand = false;
+	hflip = false;
+	vflip = false;
 	set_mouse_filter(MOUSE_FILTER_PASS);
 	stretch_mode = STRETCH_SCALE_ON_EXPAND;
 }

+ 8 - 0
scene/gui/texture_rect.h

@@ -53,6 +53,8 @@ public:
 
 private:
 	bool expand;
+	bool hflip;
+	bool vflip;
 	Ref<Texture> texture;
 	StretchMode stretch_mode;
 
@@ -71,6 +73,12 @@ public:
 	void set_stretch_mode(StretchMode p_mode);
 	StretchMode get_stretch_mode() const;
 
+	void set_flip_h(bool p_flip);
+	bool is_flipped_h() const;
+
+	void set_flip_v(bool p_flip);
+	bool is_flipped_v() const;
+
 	TextureRect();
 	~TextureRect();
 };

+ 1 - 1
servers/visual/visual_server_canvas.cpp

@@ -616,7 +616,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
 	if (p_tile) {
 		rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE;
 		rect->flags |= RasterizerCanvas::CANVAS_RECT_REGION;
-		rect->source = Rect2(0, 0, p_rect.size.width, p_rect.size.height);
+		rect->source = Rect2(0, 0, fabsf(p_rect.size.width), fabsf(p_rect.size.height));
 	}
 
 	if (p_rect.size.x < 0) {