The TextureButton's bitmask takes into account the stretch mode selected
When the stretch is tile the mask gets applied to each tile.
This commit is contained in:
parent
a1c08b7109
commit
9927b70efb
2 changed files with 61 additions and 10 deletions
|
@ -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)
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue