From 918ecbe493ae0d9600d2d8bfafef560ec2e77043 Mon Sep 17 00:00:00 2001 From: Koerty Date: Sat, 21 Apr 2018 15:23:10 +0200 Subject: [PATCH] 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 --- es-core/src/components/NinePatchComponent.cpp | 108 ++++++------------ es-core/src/components/NinePatchComponent.h | 7 +- 2 files changed, 43 insertions(+), 72 deletions(-) diff --git a/es-core/src/components/NinePatchComponent.cpp b/es-core/src/components/NinePatchComponent.cpp index 994ba5838..5a2e39e11 100644 --- a/es-core/src/components/NinePatchComponent.cpp +++ b/es-core/src/components/NinePatchComponent.cpp @@ -6,7 +6,8 @@ #include "ThemeData.h" NinePatchComponent::NinePatchComponent(Window* window, const std::string& path, unsigned int edgeColor, unsigned int centerColor) : GuiComponent(window), - mEdgeColor(edgeColor), mCenterColor(centerColor), + mCornerSize(16, 16), + mEdgeColor(edgeColor), mCenterColor(centerColor), mPath(path), mVertices(NULL), mColors(NULL) { @@ -51,83 +52,44 @@ void NinePatchComponent::buildVertices() mColors = new GLubyte[6 * 9 * 4]; 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 - const Vector2f pieceCoords[9] = { - Vector2f(0, 0), - Vector2f(16, 0), - Vector2f(32, 0), - Vector2f(0, 16), - Vector2f(16, 16), - Vector2f(32, 16), - Vector2f(0, 32), - Vector2f(16, 32), - Vector2f(32, 32), - }; + float imgSizeX[3] = {mCornerSize.x(), mSize.x() - mCornerSize.x() * 2, mCornerSize.x()}; + float imgSizeY[3] = {mCornerSize.y(), mSize.y() - mCornerSize.y() * 2, mCornerSize.y()}; + float imgPosX[3] = {0, imgSizeX[0], imgSizeX[0] + imgSizeX[1]}; + float imgPosY[3] = {0, imgSizeY[0], imgSizeY[0] + imgSizeY[1]}; - const Vector2f pieceSizes = getCornerSize(); - - //corners never stretch, so we calculate a width and height for slices 1, 3, 5, and 7 - float borderWidth = mSize.x() - (pieceSizes.x() * 2); //should be pieceSizes[0] and pieceSizes[2] - //if(borderWidth < pieceSizes.x()) - // 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 + //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()}; + float texSizeY[3] = {-mCornerSize.y() / texSize.y(), -(texSize.y() - mCornerSize.y() * 2) / texSize.y(), -mCornerSize.y() / texSize.y()}; + float texPosX[3] = {0, texSizeX[0], texSizeX[0] + texSizeX[1]}; + float texPosY[3] = {1, 1 + texSizeY[0], 1 + texSizeY[0] + texSizeY[1]}; int v = 0; for(int slice = 0; slice < 9; slice++) { - Vector2f size; + int sliceX = slice % 3; + int sliceY = slice / 3; - //corners - if(slice == 0 || slice == 2 || slice == 6 || slice == 8) - size = pieceSizes; + Vector2f imgPos = Vector2f(imgPosX[sliceX], imgPosY[sliceY]); + Vector2f imgSize = Vector2f(imgSizeX[sliceX], imgSizeY[sliceY]); - //vertical borders - if(slice == 1 || slice == 7) - size = Vector2f(borderWidth, pieceSizes.y()); - - //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 + 0].pos = imgPos; + mVertices[v + 1].pos = imgPos + Vector2f(0, imgSize.y()); + mVertices[v + 2].pos = imgPos + Vector2f(imgSize.x(), 0); + mVertices[v + 3].pos = mVertices[v + 2].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 - //the y = (1 - y) is to deal with texture coordinates having a bottom left corner origin vs. verticies having a top left origin - 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()); + Vector2f texPos = Vector2f(texPosX[sliceX], texPosY[sliceY]); + Vector2f texSize = Vector2f(texSizeX[sliceX], texSizeY[sliceY]); - 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 + 5].tex = mVertices[v + 0].tex; + mVertices[v + 5].tex = texPos + texSize; v += 6; } @@ -180,9 +142,15 @@ void NinePatchComponent::onSizeChanged() 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) @@ -191,8 +159,8 @@ void NinePatchComponent::fitTo(Vector2f size, Vector3f position, Vector2f paddin position[0] -= padding.x() / 2; position[1] -= padding.y() / 2; - setSize(size + Vector2f(getCornerSize().x() * 2, getCornerSize().y() * 2)); - setPosition(-getCornerSize().x() + position.x(), -getCornerSize().y() + position.y()); + setSize(size + mCornerSize * 2); + setPosition(-mCornerSize.x() + position.x(), -mCornerSize.y() + position.y()); } void NinePatchComponent::setImagePath(const std::string& path) diff --git a/es-core/src/components/NinePatchComponent.h b/es-core/src/components/NinePatchComponent.h index 5d08ecd64..af9e3b934 100644 --- a/es-core/src/components/NinePatchComponent.h +++ b/es-core/src/components/NinePatchComponent.h @@ -37,9 +37,11 @@ public: virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; -private: - Vector2f getCornerSize() const; + 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 updateColors(); @@ -53,6 +55,7 @@ private: GLubyte* mColors; std::string mPath; + Vector2f mCornerSize; unsigned int mEdgeColor; unsigned int mCenterColor; std::shared_ptr mTexture;