summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scene/gui/texture_button.cpp65
-rw-r--r--scene/gui/texture_button.h4
2 files changed, 60 insertions, 9 deletions
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index 07c9894611..6bd3b26280 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "texture_button.h"
+#include "core/typedefs.h"
+#include <stdlib.h>
Size2 TextureButton::get_minimum_size() const {
@@ -58,10 +60,50 @@ bool TextureButton::has_point(const Point2 &p_point) const {
if (click_mask.is_valid()) {
- 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)
+ Point2 point = p_point;
+ Rect2 rect = Rect2();
+ Size2 mask_size = click_mask->get_size();
+
+ if (_tile) {
+ // if the stretch mode is tile we offset the point to keep it inside the mask size
+ rect.size = mask_size;
+ if (_position_rect.has_point(point)) {
+ int cols = (int)Math::ceil(_position_rect.size.x / mask_size.x);
+ int rows = (int)Math::ceil(_position_rect.size.y / mask_size.y);
+ int col = (int)(point.x / mask_size.x) % cols;
+ int row = (int)(point.y / mask_size.y) % rows;
+ point.x -= mask_size.x * col;
+ point.y -= mask_size.y * row;
+ }
+ } else {
+ // we need to transform the point from our scaled / translated image back to our mask image
+ Point2 ofs = _position_rect.position;
+ Size2 scale = mask_size / _position_rect.size;
+
+ switch (stretch_mode) {
+ case STRETCH_KEEP_ASPECT_COVERED: {
+ // if the stretch mode is aspect covered the image uses a texture region so we need to take that into account
+ float min = MIN(scale.x, scale.y);
+ scale.x = min;
+ scale.y = min;
+ ofs -= _texture_region.position / min;
+ } break;
+ }
+
+ // offset and scale the new point position to adjust it to the bitmask size
+ point -= ofs;
+ point *= scale;
+
+ // finally, we need to check if the point is inside a rectangle with a position >= 0,0 and a size <= mask_size
+ rect.position = Point2(MAX(0, _texture_region.position.x), MAX(0, _texture_region.position.y));
+ rect.size = Size2(MIN(mask_size.x, _texture_region.size.x), MIN(mask_size.y, _texture_region.size.y));
+ }
+
+ if (!rect.has_point(point)) {
return false;
+ }
+ Point2i p = point;
return click_mask->get_bit(p);
}
@@ -118,8 +160,8 @@ void TextureButton::_notification(int p_what) {
if (texdraw.is_valid()) {
Point2 ofs;
Size2 size = texdraw->get_size();
- Rect2 tex_regin = Rect2(Point2(), texdraw->get_size());
- bool tile = false;
+ _texture_region = Rect2(Point2(), texdraw->get_size());
+ _tile = false;
if (expand) {
switch (stretch_mode) {
case STRETCH_KEEP:
@@ -130,7 +172,7 @@ void TextureButton::_notification(int p_what) {
break;
case STRETCH_TILE:
size = get_size();
- tile = true;
+ _tile = true;
break;
case STRETCH_KEEP_CENTERED:
ofs = (get_size() - texdraw->get_size()) / 2;
@@ -161,14 +203,15 @@ void TextureButton::_notification(int p_what) {
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);
+ _texture_region = Rect2(ofs, size / scale);
} break;
}
}
- if (tile)
- draw_texture_rect(texdraw, Rect2(ofs, size), tile);
+ _position_rect = Rect2(ofs, size);
+ if (_tile)
+ draw_texture_rect(texdraw, _position_rect, _tile);
else
- draw_texture_rect_region(texdraw, Rect2(ofs, size), tex_regin);
+ draw_texture_rect_region(texdraw, _position_rect, _texture_region);
}
if (has_focus() && focused.is_valid()) {
@@ -299,4 +342,8 @@ TextureButton::StretchMode TextureButton::get_stretch_mode() const {
TextureButton::TextureButton() {
expand = false;
stretch_mode = STRETCH_SCALE;
+
+ _texture_region = Rect2();
+ _position_rect = Rect2();
+ _tile = false;
}
diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h
index 1cf4b66413..d42df390e8 100644
--- a/scene/gui/texture_button.h
+++ b/scene/gui/texture_button.h
@@ -58,6 +58,10 @@ private:
bool expand;
StretchMode stretch_mode;
+ Rect2 _texture_region;
+ Rect2 _position_rect;
+ bool _tile;
+
protected:
virtual Size2 get_minimum_size() const;
virtual bool has_point(const Point2 &p_point) const;