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">
|
||||
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">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue