mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	Add ability to flip TextureRect horizontally or vertically
This commit is contained in:
		
							parent
							
								
									869887641f
								
							
						
					
					
						commit
						8b84638322
					
				
					 4 changed files with 74 additions and 21 deletions
				
			
		|  | @ -22,6 +22,12 @@ | ||||||
| 		<member name="texture" type="Texture" setter="set_texture" getter="get_texture"> | 		<member name="texture" type="Texture" setter="set_texture" getter="get_texture"> | ||||||
| 			The node's [Texture] resource. | 			The node's [Texture] resource. | ||||||
| 		</member> | 		</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> | 	</members> | ||||||
| 	<constants> | 	<constants> | ||||||
| 		<constant name="STRETCH_SCALE_ON_EXPAND" value="0" enum="StretchMode"> | 		<constant name="STRETCH_SCALE_ON_EXPAND" value="0" enum="StretchMode"> | ||||||
|  |  | ||||||
|  | @ -38,30 +38,32 @@ void TextureRect::_notification(int p_what) { | ||||||
| 		if (texture.is_null()) | 		if (texture.is_null()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
|  | 		Size2 size; | ||||||
|  | 		Point2 offset; | ||||||
|  | 		Rect2 region; | ||||||
|  | 		bool tile = false; | ||||||
|  | 
 | ||||||
| 		switch (stretch_mode) { | 		switch (stretch_mode) { | ||||||
| 			case STRETCH_SCALE_ON_EXPAND: { | 			case STRETCH_SCALE_ON_EXPAND: { | ||||||
| 				Size2 s = expand ? get_size() : texture->get_size(); | 				size = expand ? get_size() : texture->get_size(); | ||||||
| 				draw_texture_rect(texture, Rect2(Point2(), s), false); |  | ||||||
| 			} break; | 			} break; | ||||||
| 			case STRETCH_SCALE: { | 			case STRETCH_SCALE: { | ||||||
| 				draw_texture_rect(texture, Rect2(Point2(), get_size()), false); | 				size = get_size(); | ||||||
| 			} break; | 			} break; | ||||||
| 			case STRETCH_TILE: { | 			case STRETCH_TILE: { | ||||||
| 				draw_texture_rect(texture, Rect2(Point2(), get_size()), true); | 				size = get_size(); | ||||||
|  | 				tile = true; | ||||||
| 			} break; | 			} break; | ||||||
| 			case STRETCH_KEEP: { | 			case STRETCH_KEEP: { | ||||||
| 				draw_texture_rect(texture, Rect2(Point2(), texture->get_size()), false); | 				size = texture->get_size(); | ||||||
| 
 |  | ||||||
| 			} break; | 			} break; | ||||||
| 			case STRETCH_KEEP_CENTERED: { | 			case STRETCH_KEEP_CENTERED: { | ||||||
| 
 | 				offset = (get_size() - texture->get_size()) / 2; | ||||||
| 				Vector2 ofs = (get_size() - texture->get_size()) / 2; | 				size = texture->get_size(); | ||||||
| 				draw_texture_rect(texture, Rect2(ofs, texture->get_size()), false); |  | ||||||
| 			} break; | 			} break; | ||||||
| 			case STRETCH_KEEP_ASPECT_CENTERED: | 			case STRETCH_KEEP_ASPECT_CENTERED: | ||||||
| 			case STRETCH_KEEP_ASPECT: { | 			case STRETCH_KEEP_ASPECT: { | ||||||
| 
 | 				size = get_size(); | ||||||
| 				Size2 size = get_size(); |  | ||||||
| 				int tex_width = texture->get_width() * size.height / texture->get_height(); | 				int tex_width = texture->get_width() * size.height / texture->get_height(); | ||||||
| 				int tex_height = size.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(); | 					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) { | 				if (stretch_mode == STRETCH_KEEP_ASPECT_CENTERED) { | ||||||
| 					ofs_x += (size.width - tex_width) / 2; | 					offset.x += (size.width - tex_width) / 2; | ||||||
| 					ofs_y += (size.height - tex_height) / 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; | 			} break; | ||||||
| 			case STRETCH_KEEP_ASPECT_COVERED: { | 			case STRETCH_KEEP_ASPECT_COVERED: { | ||||||
| 				Size2 size = get_size(); | 				size = get_size(); | ||||||
|  | 
 | ||||||
| 				Size2 tex_size = texture->get_size(); | 				Size2 tex_size = texture->get_size(); | ||||||
| 				Size2 scaleSize(size.width / tex_size.width, size.height / tex_size.height); | 				Size2 scaleSize(size.width / tex_size.width, size.height / tex_size.height); | ||||||
| 				float scale = scaleSize.width > scaleSize.height ? scaleSize.width : scaleSize.height; | 				float scale = scaleSize.width > scaleSize.height ? scaleSize.width : scaleSize.height; | ||||||
| 				Size2 scaledTexSize = tex_size * scale; | 				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; | 			} 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("get_texture"), &TextureRect::get_texture); | ||||||
| 	ClassDB::bind_method(D_METHOD("set_expand", "enable"), &TextureRect::set_expand); | 	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("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("set_stretch_mode", "stretch_mode"), &TextureRect::set_stretch_mode); | ||||||
| 	ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_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::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::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::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_ON_EXPAND); | ||||||
| 	BIND_ENUM_CONSTANT(STRETCH_SCALE); | 	BIND_ENUM_CONSTANT(STRETCH_SCALE); | ||||||
|  | @ -161,9 +178,31 @@ TextureRect::StretchMode TextureRect::get_stretch_mode() const { | ||||||
| 	return stretch_mode; | 	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() { | TextureRect::TextureRect() { | ||||||
| 
 | 
 | ||||||
| 	expand = false; | 	expand = false; | ||||||
|  | 	hflip = false; | ||||||
|  | 	vflip = false; | ||||||
| 	set_mouse_filter(MOUSE_FILTER_PASS); | 	set_mouse_filter(MOUSE_FILTER_PASS); | ||||||
| 	stretch_mode = STRETCH_SCALE_ON_EXPAND; | 	stretch_mode = STRETCH_SCALE_ON_EXPAND; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -53,6 +53,8 @@ public: | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	bool expand; | 	bool expand; | ||||||
|  | 	bool hflip; | ||||||
|  | 	bool vflip; | ||||||
| 	Ref<Texture> texture; | 	Ref<Texture> texture; | ||||||
| 	StretchMode stretch_mode; | 	StretchMode stretch_mode; | ||||||
| 
 | 
 | ||||||
|  | @ -71,6 +73,12 @@ public: | ||||||
| 	void set_stretch_mode(StretchMode p_mode); | 	void set_stretch_mode(StretchMode p_mode); | ||||||
| 	StretchMode get_stretch_mode() const; | 	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(); | ||||||
| 	~TextureRect(); | 	~TextureRect(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -616,7 +616,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p | ||||||
| 	if (p_tile) { | 	if (p_tile) { | ||||||
| 		rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE; | 		rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE; | ||||||
| 		rect->flags |= RasterizerCanvas::CANVAS_RECT_REGION; | 		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) { | 	if (p_rect.size.x < 0) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 PouleyKetchoupp
						PouleyKetchoupp