diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 03e37e9d9fb..fb6262eff81 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -28,40 +28,35 @@ /*************************************************************************/ #include "texture_button.h" - Size2 TextureButton::get_minimum_size() const { - Size2 rscale; - if (normal.is_null()) { - if (pressed.is_null()) { - if (hover.is_null()) - if (click_mask.is_null()) - rscale= Size2(); + Size2 rscale = Control::get_minimum_size(); + + if (!expand) { + if (normal.is_null()) { + if (pressed.is_null()) { + if (hover.is_null()) + if (click_mask.is_null()) + rscale= Size2(); + else + rscale= click_mask->get_size(); else - rscale= click_mask->get_size(); - else - rscale= hover->get_size(); + rscale= hover->get_size(); + } else + rscale=pressed->get_size(); + } else - rscale=pressed->get_size(); + rscale= normal->get_size(); + } - } else - rscale= normal->get_size(); - - return rscale*scale.abs(); + return rscale.abs(); } - bool TextureButton::has_point(const Point2& p_point) const { - if (scale[0] == 0 || scale[1] == 0) { - return false; - } - - Point2 ppos = p_point/scale.abs(); - if (click_mask.is_valid()) { - Point2i p =ppos; + Point2i p =p_point; if (p.x<0 || p.x>=click_mask->get_size().width || p.y<0 || p.y>=click_mask->get_size().height) return false; @@ -119,17 +114,67 @@ void TextureButton::_notification(int p_what) { } if (texdraw.is_valid()) { - Rect2 drect(Point2(),texdraw->get_size()*scale); - draw_texture_rect(texdraw,drect,false); + Point2 ofs; + Size2 size = texdraw->get_size(); + Rect2 tex_regin = Rect2(Point2(), texdraw->get_size()); + bool tile = false; + if (expand) { + switch (stretch_mode) { + case StretchMode::STRETCH_KEEP: + size = texdraw->get_size(); + break; + case StretchMode::STRETCH_SCALE_ON_EXPAND: + case StretchMode::STRETCH_SCALE: + size = get_size(); + break; + case StretchMode::STRETCH_TILE: + size = get_size(); + tile = true; + break; + case StretchMode::STRETCH_KEEP_CENTERED: + ofs = (get_size() - texdraw->get_size())/2; + size = texdraw->get_size(); + break; + case StretchMode::STRETCH_KEEP_ASPECT_CENTERED: + case StretchMode::STRETCH_KEEP_ASPECT: { + Size2 _size=get_size(); + float tex_width = texdraw->get_width() * _size.height / texdraw->get_height(); + float tex_height = _size.height; + if (tex_width > _size.width) { + tex_width = _size.width; + tex_height = texdraw->get_height() * tex_width / texdraw->get_width(); + } + + if (stretch_mode==StretchMode::STRETCH_KEEP_ASPECT_CENTERED) { + ofs.x = (_size.width - tex_width)/2; + ofs.y = (_size.height - tex_height)/2; + } + size.width = tex_width; + size.height = tex_height; + } break; + case StretchMode::STRETCH_KEEP_ASPECT_COVERED:{ + size = get_size(); + Size2 tex_size = texdraw->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; + tex_regin = Rect2(ofs, size/scale); + } break; + } + } + if (tile) + draw_texture_rect(texdraw,Rect2(ofs,size),tile); + else + draw_texture_rect_region(texdraw, Rect2(ofs, size), tex_regin); } if (has_focus() && focused.is_valid()) { - Rect2 drect(Point2(),focused->get_size()*scale); + Rect2 drect(Point2(), get_size()); draw_texture_rect(focused,drect,false); }; - } break; } } @@ -142,7 +187,8 @@ void TextureButton::_bind_methods() { ClassDB::bind_method(_MD("set_disabled_texture","texture:Texture"),&TextureButton::set_disabled_texture); ClassDB::bind_method(_MD("set_focused_texture","texture:Texture"),&TextureButton::set_focused_texture); ClassDB::bind_method(_MD("set_click_mask","mask:BitMap"),&TextureButton::set_click_mask); - ClassDB::bind_method(_MD("set_texture_scale","scale"),&TextureButton::set_texture_scale); + ClassDB::bind_method(_MD("set_expand","p_expand"),&TextureButton::set_expand); + ClassDB::bind_method(_MD("set_stretch_mode","p_mode"),&TextureButton::set_stretch_mode); ClassDB::bind_method(_MD("get_normal_texture:Texture"),&TextureButton::get_normal_texture); ClassDB::bind_method(_MD("get_pressed_texture:Texture"),&TextureButton::get_pressed_texture); @@ -150,7 +196,8 @@ void TextureButton::_bind_methods() { ClassDB::bind_method(_MD("get_disabled_texture:Texture"),&TextureButton::get_disabled_texture); ClassDB::bind_method(_MD("get_focused_texture:Texture"),&TextureButton::get_focused_texture); ClassDB::bind_method(_MD("get_click_mask:BitMap"),&TextureButton::get_click_mask); - ClassDB::bind_method(_MD("get_texture_scale"),&TextureButton::get_texture_scale); + ClassDB::bind_method(_MD("get_expand"),&TextureButton::get_expand); + ClassDB::bind_method(_MD("get_stretch_mode"),&TextureButton::get_stretch_mode); ADD_GROUP("Textures","texture_"); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"texture_normal",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_normal_texture"), _SCS("get_normal_texture")); @@ -159,7 +206,25 @@ void TextureButton::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"texture_disabled",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_disabled_texture"), _SCS("get_disabled_texture")); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"texture_focused",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_focused_texture"), _SCS("get_focused_texture")); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"texture_click_mask",PROPERTY_HINT_RESOURCE_TYPE,"BitMap"), _SCS("set_click_mask"), _SCS("get_click_mask")) ; - ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2,"texture_scale",PROPERTY_HINT_RANGE,"0.01,1024,0.01"), _SCS("set_texture_scale"), _SCS("get_texture_scale")); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL,"expand",PROPERTY_HINT_RESOURCE_TYPE,"bool"), _SCS("set_expand"), _SCS("get_expand")) ; + ADD_PROPERTYNO(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"), _SCS("set_stretch_mode"), _SCS("get_stretch_mode")); + + const int STRETCH_SCALE_ON_EXPAND = StretchMode::STRETCH_SCALE_ON_EXPAND; + const int STRETCH_SCALE = StretchMode::STRETCH_SCALE; + const int STRETCH_TILE = StretchMode::STRETCH_TILE; + const int STRETCH_KEEP = StretchMode::STRETCH_KEEP; + const int STRETCH_KEEP_CENTERED = StretchMode::STRETCH_KEEP_CENTERED; + const int STRETCH_KEEP_ASPECT = StretchMode::STRETCH_KEEP_ASPECT; + const int STRETCH_KEEP_ASPECT_CENTERED = StretchMode::STRETCH_KEEP_ASPECT_CENTERED; + const int STRETCH_KEEP_ASPECT_COVERED = StretchMode::STRETCH_KEEP_ASPECT_COVERED; + BIND_CONSTANT(STRETCH_SCALE_ON_EXPAND); + BIND_CONSTANT(STRETCH_SCALE); + BIND_CONSTANT(STRETCH_TILE); + BIND_CONSTANT(STRETCH_KEEP); + BIND_CONSTANT(STRETCH_KEEP_CENTERED); + BIND_CONSTANT(STRETCH_KEEP_ASPECT); + BIND_CONSTANT(STRETCH_KEEP_ASPECT_CENTERED); + BIND_CONSTANT(STRETCH_KEEP_ASPECT_COVERED); } @@ -227,19 +292,26 @@ void TextureButton::set_focused_texture(const Ref& p_focused) { focused = p_focused; }; -void TextureButton::set_texture_scale(Size2 p_scale) { +bool TextureButton::get_expand() const { + return expand; +} - scale=p_scale; +void TextureButton::set_expand(bool p_expand) { + expand = p_expand; minimum_size_changed(); update(); } -Size2 TextureButton::get_texture_scale() const{ +void TextureButton::set_stretch_mode(TextureButton::StretchMode p_mode) { + stretch_mode = p_mode; + update(); +} - return scale; +TextureButton::StretchMode TextureButton::get_stretch_mode() const { + return stretch_mode; } TextureButton::TextureButton() { - scale=Size2(1.0, 1.0); - + expand = false; + stretch_mode = StretchMode::STRETCH_SCALE_ON_EXPAND; } diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index ef4d4d5b5b8..e1d1079cebe 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -31,22 +31,28 @@ #include "scene/gui/base_button.h" #include "scene/resources/bit_mask.h" +#include "scene/gui/texture_rect.h" class TextureButton : public BaseButton { GDCLASS( TextureButton, BaseButton ); +public: + typedef TextureRect::StretchMode StretchMode; + +private: Ref normal; Ref pressed; Ref hover; Ref disabled; Ref focused; Ref click_mask; - Size2 scale; + bool expand; + StretchMode stretch_mode; protected: - virtual bool has_point(const Point2& p_point) const; virtual Size2 get_minimum_size() const; + virtual bool has_point(const Point2& p_point) const; void _notification(int p_what); static void _bind_methods(); @@ -66,8 +72,11 @@ public: Ref get_focused_texture() const; Ref get_click_mask() const; - void set_texture_scale(Size2 p_scale); - Size2 get_texture_scale() const; + bool get_expand() const; + void set_expand(bool p_expand); + + void set_stretch_mode(StretchMode stretch_mode); + StretchMode get_stretch_mode() const; TextureButton(); }; diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index 6a4b59c5ecb..74240fe98e6 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -79,7 +79,15 @@ void TextureRect::_notification(int p_what) { draw_texture_rect(texture,Rect2(ofs_x,ofs_y,tex_width,tex_height)); } break; - + case STRETCH_KEEP_ASPECT_COVERED: { + Size2 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)); + } break; } } @@ -104,7 +112,7 @@ void TextureRect::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"),_SCS("get_texture") ); ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") ); - ADD_PROPERTYNO( PropertyInfo( Variant::INT, "stretch_mode",PROPERTY_HINT_ENUM,"Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered"), _SCS("set_stretch_mode"),_SCS("get_stretch_mode") ); + ADD_PROPERTYNO( 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"), _SCS("set_stretch_mode"),_SCS("get_stretch_mode") ); BIND_CONSTANT( STRETCH_SCALE_ON_EXPAND ); BIND_CONSTANT( STRETCH_SCALE ); @@ -113,7 +121,7 @@ void TextureRect::_bind_methods() { BIND_CONSTANT( STRETCH_KEEP_CENTERED ); BIND_CONSTANT( STRETCH_KEEP_ASPECT ); BIND_CONSTANT( STRETCH_KEEP_ASPECT_CENTERED ); - + BIND_CONSTANT( STRETCH_KEEP_ASPECT_COVERED ); } diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index e95d7427597..0d724589090 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -45,7 +45,7 @@ public: STRETCH_KEEP_CENTERED, STRETCH_KEEP_ASPECT, STRETCH_KEEP_ASPECT_CENTERED, - + STRETCH_KEEP_ASPECT_COVERED, }; private: bool expand;