mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 07:05:39 +00:00
Rewrite NinePatchComponent to handle images of all sizes
- Rewrite NinePatchComponent to handle images with a different size than 48x48 px - It's now possible to change the border sizes using setCornerSize function
This commit is contained in:
parent
4a1e9d5f11
commit
918ecbe493
|
@ -6,6 +6,7 @@
|
||||||
#include "ThemeData.h"
|
#include "ThemeData.h"
|
||||||
|
|
||||||
NinePatchComponent::NinePatchComponent(Window* window, const std::string& path, unsigned int edgeColor, unsigned int centerColor) : GuiComponent(window),
|
NinePatchComponent::NinePatchComponent(Window* window, const std::string& path, unsigned int edgeColor, unsigned int centerColor) : GuiComponent(window),
|
||||||
|
mCornerSize(16, 16),
|
||||||
mEdgeColor(edgeColor), mCenterColor(centerColor),
|
mEdgeColor(edgeColor), mCenterColor(centerColor),
|
||||||
mPath(path),
|
mPath(path),
|
||||||
mVertices(NULL), mColors(NULL)
|
mVertices(NULL), mColors(NULL)
|
||||||
|
@ -51,83 +52,44 @@ void NinePatchComponent::buildVertices()
|
||||||
mColors = new GLubyte[6 * 9 * 4];
|
mColors = new GLubyte[6 * 9 * 4];
|
||||||
updateColors();
|
updateColors();
|
||||||
|
|
||||||
const Vector2f ts = Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y());
|
const Vector2f texSize = Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y());
|
||||||
|
|
||||||
//coordinates on the image in pixels, top left origin
|
float imgSizeX[3] = {mCornerSize.x(), mSize.x() - mCornerSize.x() * 2, mCornerSize.x()};
|
||||||
const Vector2f pieceCoords[9] = {
|
float imgSizeY[3] = {mCornerSize.y(), mSize.y() - mCornerSize.y() * 2, mCornerSize.y()};
|
||||||
Vector2f(0, 0),
|
float imgPosX[3] = {0, imgSizeX[0], imgSizeX[0] + imgSizeX[1]};
|
||||||
Vector2f(16, 0),
|
float imgPosY[3] = {0, imgSizeY[0], imgSizeY[0] + imgSizeY[1]};
|
||||||
Vector2f(32, 0),
|
|
||||||
Vector2f(0, 16),
|
|
||||||
Vector2f(16, 16),
|
|
||||||
Vector2f(32, 16),
|
|
||||||
Vector2f(0, 32),
|
|
||||||
Vector2f(16, 32),
|
|
||||||
Vector2f(32, 32),
|
|
||||||
};
|
|
||||||
|
|
||||||
const Vector2f pieceSizes = getCornerSize();
|
//the "1 +" in posY and "-" in sizeY is to deal with texture coordinates having a bottom left corner origin vs. verticies having a top left origin
|
||||||
|
float texSizeX[3] = {mCornerSize.x() / texSize.x(), (texSize.x() - mCornerSize.x() * 2) / texSize.x(), mCornerSize.x() / texSize.x()};
|
||||||
//corners never stretch, so we calculate a width and height for slices 1, 3, 5, and 7
|
float texSizeY[3] = {-mCornerSize.y() / texSize.y(), -(texSize.y() - mCornerSize.y() * 2) / texSize.y(), -mCornerSize.y() / texSize.y()};
|
||||||
float borderWidth = mSize.x() - (pieceSizes.x() * 2); //should be pieceSizes[0] and pieceSizes[2]
|
float texPosX[3] = {0, texSizeX[0], texSizeX[0] + texSizeX[1]};
|
||||||
//if(borderWidth < pieceSizes.x())
|
float texPosY[3] = {1, 1 + texSizeY[0], 1 + texSizeY[0] + texSizeY[1]};
|
||||||
// borderWidth = pieceSizes.x();
|
|
||||||
|
|
||||||
float borderHeight = mSize.y() - (pieceSizes.y() * 2); //should be pieceSizes[0] and pieceSizes[6]
|
|
||||||
//if(borderHeight < pieceSizes.y())
|
|
||||||
// borderHeight = pieceSizes.y();
|
|
||||||
|
|
||||||
mVertices[0 * 6].pos = pieceCoords[0]; //top left
|
|
||||||
mVertices[1 * 6].pos = pieceCoords[1]; //top middle
|
|
||||||
mVertices[2 * 6].pos = pieceCoords[1] + Vector2f(borderWidth, 0); //top right
|
|
||||||
|
|
||||||
mVertices[3 * 6].pos = mVertices[0 * 6].pos + Vector2f(0, pieceSizes.y()); //mid left
|
|
||||||
mVertices[4 * 6].pos = mVertices[3 * 6].pos + Vector2f(pieceSizes.x(), 0); //mid middle
|
|
||||||
mVertices[5 * 6].pos = mVertices[4 * 6].pos + Vector2f(borderWidth, 0); //mid right
|
|
||||||
|
|
||||||
mVertices[6 * 6].pos = mVertices[3 * 6].pos + Vector2f(0, borderHeight); //bot left
|
|
||||||
mVertices[7 * 6].pos = mVertices[6 * 6].pos + Vector2f(pieceSizes.x(), 0); //bot middle
|
|
||||||
mVertices[8 * 6].pos = mVertices[7 * 6].pos + Vector2f(borderWidth, 0); //bot right
|
|
||||||
|
|
||||||
int v = 0;
|
int v = 0;
|
||||||
for(int slice = 0; slice < 9; slice++)
|
for(int slice = 0; slice < 9; slice++)
|
||||||
{
|
{
|
||||||
Vector2f size;
|
int sliceX = slice % 3;
|
||||||
|
int sliceY = slice / 3;
|
||||||
|
|
||||||
//corners
|
Vector2f imgPos = Vector2f(imgPosX[sliceX], imgPosY[sliceY]);
|
||||||
if(slice == 0 || slice == 2 || slice == 6 || slice == 8)
|
Vector2f imgSize = Vector2f(imgSizeX[sliceX], imgSizeY[sliceY]);
|
||||||
size = pieceSizes;
|
|
||||||
|
|
||||||
//vertical borders
|
mVertices[v + 0].pos = imgPos;
|
||||||
if(slice == 1 || slice == 7)
|
mVertices[v + 1].pos = imgPos + Vector2f(0, imgSize.y());
|
||||||
size = Vector2f(borderWidth, pieceSizes.y());
|
mVertices[v + 2].pos = imgPos + Vector2f(imgSize.x(), 0);
|
||||||
|
mVertices[v + 3].pos = mVertices[v + 2].pos;
|
||||||
//horizontal borders
|
|
||||||
if(slice == 3 || slice == 5)
|
|
||||||
size = Vector2f(pieceSizes.x(), borderHeight);
|
|
||||||
|
|
||||||
//center
|
|
||||||
if(slice == 4)
|
|
||||||
size = Vector2f(borderWidth, borderHeight);
|
|
||||||
|
|
||||||
//no resizing will be necessary
|
|
||||||
//mVertices[v + 0] is already correct
|
|
||||||
mVertices[v + 1].pos = mVertices[v + 0].pos + size;
|
|
||||||
mVertices[v + 2].pos = Vector2f(mVertices[v + 0].pos.x(), mVertices[v + 1].pos.y());
|
|
||||||
|
|
||||||
mVertices[v + 3].pos = Vector2f(mVertices[v + 1].pos.x(), mVertices[v + 0].pos.y());
|
|
||||||
mVertices[v + 4].pos = mVertices[v + 1].pos;
|
mVertices[v + 4].pos = mVertices[v + 1].pos;
|
||||||
mVertices[v + 5].pos = mVertices[v + 0].pos;
|
mVertices[v + 5].pos = imgPos + imgSize;
|
||||||
|
|
||||||
//texture coordinates
|
Vector2f texPos = Vector2f(texPosX[sliceX], texPosY[sliceY]);
|
||||||
//the y = (1 - y) is to deal with texture coordinates having a bottom left corner origin vs. verticies having a top left origin
|
Vector2f texSize = Vector2f(texSizeX[sliceX], texSizeY[sliceY]);
|
||||||
mVertices[v + 0].tex = Vector2f(pieceCoords[slice].x() / ts.x(), 1 - (pieceCoords[slice].y() / ts.y()));
|
|
||||||
mVertices[v + 1].tex = Vector2f((pieceCoords[slice].x() + pieceSizes.x()) / ts.x(), 1 - ((pieceCoords[slice].y() + pieceSizes.y()) / ts.y()));
|
|
||||||
mVertices[v + 2].tex = Vector2f(mVertices[v + 0].tex.x(), mVertices[v + 1].tex.y());
|
|
||||||
|
|
||||||
mVertices[v + 3].tex = Vector2f(mVertices[v + 1].tex.x(), mVertices[v + 0].tex.y());
|
mVertices[v + 0].tex = texPos;
|
||||||
|
mVertices[v + 1].tex = texPos + Vector2f(0, texSize.y());
|
||||||
|
mVertices[v + 2].tex = texPos + Vector2f(texSize.x(), 0);
|
||||||
|
mVertices[v + 3].tex = mVertices[v + 2].tex;
|
||||||
mVertices[v + 4].tex = mVertices[v + 1].tex;
|
mVertices[v + 4].tex = mVertices[v + 1].tex;
|
||||||
mVertices[v + 5].tex = mVertices[v + 0].tex;
|
mVertices[v + 5].tex = texPos + texSize;
|
||||||
|
|
||||||
v += 6;
|
v += 6;
|
||||||
}
|
}
|
||||||
|
@ -180,9 +142,15 @@ void NinePatchComponent::onSizeChanged()
|
||||||
buildVertices();
|
buildVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2f NinePatchComponent::getCornerSize() const
|
const Vector2f& NinePatchComponent::getCornerSize() const
|
||||||
{
|
{
|
||||||
return Vector2f(16, 16);
|
return mCornerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NinePatchComponent::setCornerSize(int sizeX, int sizeY)
|
||||||
|
{
|
||||||
|
mCornerSize = Vector2f(sizeX, sizeY);
|
||||||
|
buildVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NinePatchComponent::fitTo(Vector2f size, Vector3f position, Vector2f padding)
|
void NinePatchComponent::fitTo(Vector2f size, Vector3f position, Vector2f padding)
|
||||||
|
@ -191,8 +159,8 @@ void NinePatchComponent::fitTo(Vector2f size, Vector3f position, Vector2f paddin
|
||||||
position[0] -= padding.x() / 2;
|
position[0] -= padding.x() / 2;
|
||||||
position[1] -= padding.y() / 2;
|
position[1] -= padding.y() / 2;
|
||||||
|
|
||||||
setSize(size + Vector2f(getCornerSize().x() * 2, getCornerSize().y() * 2));
|
setSize(size + mCornerSize * 2);
|
||||||
setPosition(-getCornerSize().x() + position.x(), -getCornerSize().y() + position.y());
|
setPosition(-mCornerSize.x() + position.x(), -mCornerSize.y() + position.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NinePatchComponent::setImagePath(const std::string& path)
|
void NinePatchComponent::setImagePath(const std::string& path)
|
||||||
|
|
|
@ -37,9 +37,11 @@ public:
|
||||||
|
|
||||||
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties) override;
|
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties) override;
|
||||||
|
|
||||||
private:
|
const Vector2f& getCornerSize() const;
|
||||||
Vector2f getCornerSize() const;
|
void setCornerSize(int sizeX, int sizeY);
|
||||||
|
inline void setCornerSize(const Vector2f& size) { setCornerSize(size.x(), size.y()); }
|
||||||
|
|
||||||
|
private:
|
||||||
void buildVertices();
|
void buildVertices();
|
||||||
void updateColors();
|
void updateColors();
|
||||||
|
|
||||||
|
@ -53,6 +55,7 @@ private:
|
||||||
GLubyte* mColors;
|
GLubyte* mColors;
|
||||||
|
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
|
Vector2f mCornerSize;
|
||||||
unsigned int mEdgeColor;
|
unsigned int mEdgeColor;
|
||||||
unsigned int mCenterColor;
|
unsigned int mCenterColor;
|
||||||
std::shared_ptr<TextureResource> mTexture;
|
std::shared_ptr<TextureResource> mTexture;
|
||||||
|
|
Loading…
Reference in a new issue