2014-06-20 01:30:09 +00:00
|
|
|
#include "components/ImageComponent.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
|
|
|
|
#include "resources/TextureResource.h"
|
2014-06-20 01:30:09 +00:00
|
|
|
#include "Log.h"
|
2018-01-23 00:31:18 +00:00
|
|
|
#include "Settings.h"
|
2014-06-20 01:30:09 +00:00
|
|
|
#include "ThemeData.h"
|
2012-08-02 01:43:55 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2i ImageComponent::getTextureSize() const
|
2013-06-21 16:49:29 +00:00
|
|
|
{
|
|
|
|
if(mTexture)
|
|
|
|
return mTexture->getSize();
|
|
|
|
else
|
2017-10-28 20:24:35 +00:00
|
|
|
return Vector2i::Zero();
|
2013-08-06 13:15:20 +00:00
|
|
|
}
|
|
|
|
|
2018-04-12 09:00:47 +00:00
|
|
|
Vector2f ImageComponent::getSize() const
|
|
|
|
{
|
|
|
|
return GuiComponent::getSize() * (mBottomRightCrop - mTopLeftCrop);
|
|
|
|
}
|
|
|
|
|
2017-01-22 23:28:06 +00:00
|
|
|
ImageComponent::ImageComponent(Window* window, bool forceLoad, bool dynamic) : GuiComponent(window),
|
2018-04-12 09:00:47 +00:00
|
|
|
mTargetIsMax(false), mTargetIsMin(false), mFlipX(false), mFlipY(false), mTargetSize(0, 0), mColorShift(0xFFFFFFFF),
|
2019-07-04 01:10:17 +00:00
|
|
|
mColorShiftEnd(0xFFFFFFFF), mColorGradientHorizontal(true), mForceLoad(forceLoad), mDynamic(dynamic),
|
|
|
|
mFadeOpacity(0), mFading(false), mRotateByTargetSize(false), mTopLeftCrop(0.0f, 0.0f), mBottomRightCrop(1.0f, 1.0f)
|
2012-08-02 01:43:55 +00:00
|
|
|
{
|
2014-04-12 01:48:13 +00:00
|
|
|
updateColors();
|
2012-08-02 01:43:55 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
ImageComponent::~ImageComponent()
|
2012-08-02 01:43:55 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-06-21 16:49:29 +00:00
|
|
|
void ImageComponent::resize()
|
2012-08-09 21:19:07 +00:00
|
|
|
{
|
2013-06-21 16:49:29 +00:00
|
|
|
if(!mTexture)
|
2012-08-29 18:53:53 +00:00
|
|
|
return;
|
2012-08-29 19:22:05 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
const Vector2f textureSize = mTexture->getSourceImageSize();
|
|
|
|
if(textureSize == Vector2f::Zero())
|
2014-05-26 22:52:55 +00:00
|
|
|
return;
|
2012-08-29 21:52:25 +00:00
|
|
|
|
2014-01-19 18:23:01 +00:00
|
|
|
if(mTexture->isTiled())
|
2014-01-10 23:45:47 +00:00
|
|
|
{
|
|
|
|
mSize = mTargetSize;
|
|
|
|
}else{
|
2014-05-23 21:51:56 +00:00
|
|
|
// SVG rasterization is determined by height (see SVGResource.cpp), and rasterization is done in terms of pixels
|
|
|
|
// if rounding is off enough in the rasterization step (for images with extreme aspect ratios), it can cause cutoff when the aspect ratio breaks
|
2019-08-25 15:23:02 +00:00
|
|
|
// so, we always make sure the resultant height is an integer to make sure cutoff doesn't happen, and scale width from that
|
2014-05-23 21:51:56 +00:00
|
|
|
// (you'll see this scattered throughout the function)
|
|
|
|
// this is probably not the best way, so if you're familiar with this problem and have a better solution, please make a pull request!
|
|
|
|
|
2014-01-10 23:45:47 +00:00
|
|
|
if(mTargetIsMax)
|
2013-06-02 21:05:29 +00:00
|
|
|
{
|
2014-01-10 23:45:47 +00:00
|
|
|
mSize = textureSize;
|
2012-08-29 21:52:25 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f resizeScale((mTargetSize.x() / mSize.x()), (mTargetSize.y() / mSize.y()));
|
2018-06-04 17:55:14 +00:00
|
|
|
|
2014-01-10 23:45:47 +00:00
|
|
|
if(resizeScale.x() < resizeScale.y())
|
|
|
|
{
|
2018-06-04 17:55:14 +00:00
|
|
|
mSize[0] *= resizeScale.x(); // this will be mTargetSize.x(). We can't exceed it, nor be lower than it.
|
|
|
|
// we need to make sure we're not creating an image larger than max size
|
|
|
|
mSize[1] = Math::min(Math::round(mSize[1] *= resizeScale.x()), mTargetSize.y());
|
2014-01-10 23:45:47 +00:00
|
|
|
}else{
|
2018-06-09 17:38:18 +00:00
|
|
|
mSize[1] = Math::round(mSize[1] * resizeScale.y()); // this will be mTargetSize.y(). We can't exceed it.
|
2019-08-25 15:23:02 +00:00
|
|
|
|
2018-06-04 17:55:14 +00:00
|
|
|
// for SVG rasterization, always calculate width from rounded height (see comment above)
|
|
|
|
// we need to make sure we're not creating an image larger than max size
|
|
|
|
mSize[0] = Math::min((mSize[1] / textureSize.y()) * textureSize.x(), mTargetSize.x());
|
2014-01-10 23:45:47 +00:00
|
|
|
}
|
2018-04-12 09:00:47 +00:00
|
|
|
}else if(mTargetIsMin)
|
|
|
|
{
|
|
|
|
mSize = textureSize;
|
|
|
|
|
|
|
|
Vector2f resizeScale((mTargetSize.x() / mSize.x()), (mTargetSize.y() / mSize.y()));
|
|
|
|
|
|
|
|
if(resizeScale.x() > resizeScale.y())
|
|
|
|
{
|
|
|
|
mSize[0] *= resizeScale.x();
|
|
|
|
mSize[1] *= resizeScale.x();
|
|
|
|
|
|
|
|
float cropPercent = (mSize.y() - mTargetSize.y()) / (mSize.y() * 2);
|
|
|
|
crop(0, cropPercent, 0, cropPercent);
|
|
|
|
}else{
|
|
|
|
mSize[0] *= resizeScale.y();
|
|
|
|
mSize[1] *= resizeScale.y();
|
|
|
|
|
|
|
|
float cropPercent = (mSize.x() - mTargetSize.x()) / (mSize.x() * 2);
|
|
|
|
crop(cropPercent, 0, cropPercent, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// for SVG rasterization, always calculate width from rounded height (see comment above)
|
2018-06-04 17:55:14 +00:00
|
|
|
// we need to make sure we're not creating an image smaller than min size
|
|
|
|
mSize[1] = Math::max(Math::round(mSize[1]), mTargetSize.y());
|
|
|
|
mSize[0] = Math::max((mSize[1] / textureSize.y()) * textureSize.x(), mTargetSize.x());
|
2018-04-12 09:00:47 +00:00
|
|
|
|
2014-01-10 23:45:47 +00:00
|
|
|
}else{
|
|
|
|
// if both components are set, we just stretch
|
|
|
|
// if no components are set, we don't resize at all
|
2017-10-28 20:24:35 +00:00
|
|
|
mSize = mTargetSize == Vector2f::Zero() ? textureSize : mTargetSize;
|
2014-01-10 23:45:47 +00:00
|
|
|
|
|
|
|
// if only one component is set, we resize in a way that maintains aspect ratio
|
2014-05-23 21:51:56 +00:00
|
|
|
// for SVG rasterization, we always calculate width from rounded height (see comment above)
|
2014-01-10 23:45:47 +00:00
|
|
|
if(!mTargetSize.x() && mTargetSize.y())
|
|
|
|
{
|
2017-11-13 22:16:38 +00:00
|
|
|
mSize[1] = Math::round(mTargetSize.y());
|
2014-05-23 21:51:56 +00:00
|
|
|
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
|
2014-01-10 23:45:47 +00:00
|
|
|
}else if(mTargetSize.x() && !mTargetSize.y())
|
|
|
|
{
|
2017-11-13 22:16:38 +00:00
|
|
|
mSize[1] = Math::round((mTargetSize.x() / textureSize.x()) * textureSize.y());
|
2014-05-23 21:51:56 +00:00
|
|
|
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
|
2014-01-10 23:45:47 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-29 21:52:25 +00:00
|
|
|
}
|
2018-06-09 17:38:18 +00:00
|
|
|
|
|
|
|
mSize[0] = Math::round(mSize.x());
|
|
|
|
mSize[1] = Math::round(mSize.y());
|
2017-01-22 23:28:06 +00:00
|
|
|
// mSize.y() should already be rounded
|
2018-06-09 17:38:18 +00:00
|
|
|
mTexture->rasterizeAt((size_t)mSize.x(), (size_t)mSize.y());
|
2014-04-12 01:48:13 +00:00
|
|
|
|
|
|
|
onSizeChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::onSizeChanged()
|
|
|
|
{
|
|
|
|
updateVertices();
|
2012-08-13 18:32:53 +00:00
|
|
|
}
|
|
|
|
|
2017-10-01 03:17:58 +00:00
|
|
|
void ImageComponent::setDefaultImage(std::string path)
|
|
|
|
{
|
|
|
|
mDefaultPath = path;
|
|
|
|
}
|
|
|
|
|
2014-01-19 18:23:01 +00:00
|
|
|
void ImageComponent::setImage(std::string path, bool tile)
|
2012-08-09 21:19:07 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
if(path.empty() || !ResourceManager::getInstance()->fileExists(path))
|
2017-10-01 03:17:58 +00:00
|
|
|
{
|
|
|
|
if(mDefaultPath.empty() || !ResourceManager::getInstance()->fileExists(mDefaultPath))
|
|
|
|
mTexture.reset();
|
|
|
|
else
|
|
|
|
mTexture = TextureResource::get(mDefaultPath, tile, mForceLoad, mDynamic);
|
|
|
|
} else {
|
2017-01-22 23:28:06 +00:00
|
|
|
mTexture = TextureResource::get(path, tile, mForceLoad, mDynamic);
|
2017-10-01 03:17:58 +00:00
|
|
|
}
|
2012-08-02 01:43:55 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
resize();
|
|
|
|
}
|
|
|
|
|
2014-01-19 18:23:01 +00:00
|
|
|
void ImageComponent::setImage(const char* path, size_t length, bool tile)
|
2013-09-20 23:55:05 +00:00
|
|
|
{
|
|
|
|
mTexture.reset();
|
|
|
|
|
2014-01-19 18:23:01 +00:00
|
|
|
mTexture = TextureResource::get("", tile);
|
2013-09-20 23:55:05 +00:00
|
|
|
mTexture->initFromMemory(path, length);
|
2019-08-25 15:23:02 +00:00
|
|
|
|
2013-09-20 23:55:05 +00:00
|
|
|
resize();
|
|
|
|
}
|
|
|
|
|
2014-01-19 18:23:01 +00:00
|
|
|
void ImageComponent::setImage(const std::shared_ptr<TextureResource>& texture)
|
2012-08-13 18:32:53 +00:00
|
|
|
{
|
2014-01-19 18:23:01 +00:00
|
|
|
mTexture = texture;
|
|
|
|
resize();
|
2012-08-13 18:32:53 +00:00
|
|
|
}
|
|
|
|
|
2014-01-10 23:45:47 +00:00
|
|
|
void ImageComponent::setResize(float width, float height)
|
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
mTargetSize = Vector2f(width, height);
|
2014-01-10 23:45:47 +00:00
|
|
|
mTargetIsMax = false;
|
2018-04-12 09:00:47 +00:00
|
|
|
mTargetIsMin = false;
|
2013-06-02 22:33:49 +00:00
|
|
|
resize();
|
2012-08-13 18:32:53 +00:00
|
|
|
}
|
|
|
|
|
2014-01-10 23:45:47 +00:00
|
|
|
void ImageComponent::setMaxSize(float width, float height)
|
2012-10-05 20:04:12 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
mTargetSize = Vector2f(width, height);
|
2014-01-10 23:45:47 +00:00
|
|
|
mTargetIsMax = true;
|
2018-04-12 09:00:47 +00:00
|
|
|
mTargetIsMin = false;
|
|
|
|
resize();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::setMinSize(float width, float height)
|
|
|
|
{
|
|
|
|
mTargetSize = Vector2f(width, height);
|
|
|
|
mTargetIsMax = false;
|
|
|
|
mTargetIsMin = true;
|
2012-10-05 20:04:12 +00:00
|
|
|
resize();
|
|
|
|
}
|
|
|
|
|
2018-01-23 00:34:30 +00:00
|
|
|
Vector2f ImageComponent::getRotationSize() const
|
|
|
|
{
|
|
|
|
return mRotateByTargetSize ? mTargetSize : mSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::setRotateByTargetSize(bool rotate)
|
|
|
|
{
|
|
|
|
mRotateByTargetSize = rotate;
|
|
|
|
}
|
|
|
|
|
2018-04-12 09:00:47 +00:00
|
|
|
void ImageComponent::cropLeft(float percent)
|
|
|
|
{
|
|
|
|
assert(percent >= 0.0f && percent <= 1.0f);
|
|
|
|
mTopLeftCrop.x() = percent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::cropTop(float percent)
|
|
|
|
{
|
|
|
|
assert(percent >= 0.0f && percent <= 1.0f);
|
|
|
|
mTopLeftCrop.y() = percent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::cropRight(float percent)
|
|
|
|
{
|
|
|
|
assert(percent >= 0.0f && percent <= 1.0f);
|
|
|
|
mBottomRightCrop.x() = 1.0f - percent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::cropBot(float percent)
|
|
|
|
{
|
|
|
|
assert(percent >= 0.0f && percent <= 1.0f);
|
|
|
|
mBottomRightCrop.y() = 1.0f - percent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::crop(float left, float top, float right, float bot)
|
|
|
|
{
|
|
|
|
cropLeft(left);
|
|
|
|
cropTop(top);
|
|
|
|
cropRight(right);
|
|
|
|
cropBot(bot);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::uncrop()
|
|
|
|
{
|
|
|
|
crop(0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
void ImageComponent::setFlipX(bool flip)
|
2012-10-07 22:25:51 +00:00
|
|
|
{
|
|
|
|
mFlipX = flip;
|
2014-04-12 01:48:13 +00:00
|
|
|
updateVertices();
|
2012-10-07 22:25:51 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
void ImageComponent::setFlipY(bool flip)
|
2012-10-07 22:25:51 +00:00
|
|
|
{
|
|
|
|
mFlipY = flip;
|
2014-04-12 01:48:13 +00:00
|
|
|
updateVertices();
|
2012-10-07 22:25:51 +00:00
|
|
|
}
|
|
|
|
|
2013-08-07 22:40:27 +00:00
|
|
|
void ImageComponent::setColorShift(unsigned int color)
|
|
|
|
{
|
|
|
|
mColorShift = color;
|
2019-08-31 13:06:23 +00:00
|
|
|
mColorShiftEnd = color;
|
2014-04-12 01:48:13 +00:00
|
|
|
updateColors();
|
2013-08-07 22:40:27 +00:00
|
|
|
}
|
|
|
|
|
2019-07-04 01:10:17 +00:00
|
|
|
void ImageComponent::setColorShiftEnd(unsigned int color)
|
|
|
|
{
|
|
|
|
mColorShiftEnd = color;
|
|
|
|
updateColors();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageComponent::setColorGradientHorizontal(bool horizontal)
|
|
|
|
{
|
|
|
|
mColorGradientHorizontal = horizontal;
|
|
|
|
updateColors();
|
|
|
|
}
|
|
|
|
|
2014-04-12 01:48:13 +00:00
|
|
|
void ImageComponent::setOpacity(unsigned char opacity)
|
2012-08-02 01:43:55 +00:00
|
|
|
{
|
2014-04-12 01:48:13 +00:00
|
|
|
mOpacity = opacity;
|
|
|
|
updateColors();
|
2012-08-29 21:52:25 +00:00
|
|
|
}
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2014-04-12 01:48:13 +00:00
|
|
|
void ImageComponent::updateVertices()
|
2012-08-29 21:52:25 +00:00
|
|
|
{
|
2014-04-12 01:48:13 +00:00
|
|
|
if(!mTexture || !mTexture->isInitialized())
|
|
|
|
return;
|
|
|
|
|
2014-03-29 23:03:38 +00:00
|
|
|
// we go through this mess to make sure everything is properly rounded
|
|
|
|
// if we just round vertices at the end, edge cases occur near sizes of 0.5
|
2019-08-31 13:06:23 +00:00
|
|
|
const Vector2f topLeft = { mSize * mTopLeftCrop };
|
|
|
|
const Vector2f bottomRight = { mSize * mBottomRightCrop };
|
|
|
|
const float px = mTexture->isTiled() ? mSize.x() / getTextureSize().x() : 1.0f;
|
|
|
|
const float py = mTexture->isTiled() ? mSize.y() / getTextureSize().y() : 1.0f;
|
|
|
|
|
|
|
|
mVertices[0] = { { topLeft.x(), topLeft.y() }, { mTopLeftCrop.x(), py - mTopLeftCrop.y() }, 0 };
|
|
|
|
mVertices[1] = { { topLeft.x(), bottomRight.y() }, { mTopLeftCrop.x(), 1.0f - mBottomRightCrop.y() }, 0 };
|
|
|
|
mVertices[2] = { { bottomRight.x(), topLeft.y() }, { mBottomRightCrop.x() * px, py - mTopLeftCrop.y() }, 0 };
|
|
|
|
mVertices[3] = { { bottomRight.x(), bottomRight.y() }, { mBottomRightCrop.x() * px, 1.0f - mBottomRightCrop.y() }, 0 };
|
|
|
|
|
|
|
|
updateColors();
|
2012-10-07 22:25:51 +00:00
|
|
|
|
2019-08-31 16:19:43 +00:00
|
|
|
// round vertices
|
|
|
|
for(int i = 0; i < 4; ++i)
|
|
|
|
mVertices[i].pos.round();
|
|
|
|
|
2012-10-07 22:25:51 +00:00
|
|
|
if(mFlipX)
|
|
|
|
{
|
2019-08-31 16:19:43 +00:00
|
|
|
for(int i = 0; i < 4; ++i)
|
2018-04-12 09:00:47 +00:00
|
|
|
mVertices[i].tex[0] = px - mVertices[i].tex[0];
|
2012-10-07 22:25:51 +00:00
|
|
|
}
|
2019-08-31 16:19:43 +00:00
|
|
|
|
2012-10-07 22:25:51 +00:00
|
|
|
if(mFlipY)
|
|
|
|
{
|
2019-08-31 16:19:43 +00:00
|
|
|
for(int i = 0; i < 4; ++i)
|
2018-04-12 09:00:47 +00:00
|
|
|
mVertices[i].tex[1] = py - mVertices[i].tex[1];
|
2012-10-07 22:25:51 +00:00
|
|
|
}
|
2012-09-07 21:44:07 +00:00
|
|
|
}
|
|
|
|
|
2014-04-12 01:48:13 +00:00
|
|
|
void ImageComponent::updateColors()
|
2012-09-07 21:44:07 +00:00
|
|
|
{
|
2019-08-31 13:06:23 +00:00
|
|
|
const float opacity = (mOpacity * (mFading ? mFadeOpacity / 255.0 : 1.0)) / 255.0;
|
|
|
|
const unsigned int color = Renderer::convertColor(mColorShift & 0xFFFFFF00 | (unsigned char)((mColorShift & 0xFF) * opacity));
|
|
|
|
const unsigned int colorEnd = Renderer::convertColor(mColorShiftEnd & 0xFFFFFF00 | (unsigned char)((mColorShiftEnd & 0xFF) * opacity));
|
2019-08-08 20:16:11 +00:00
|
|
|
|
2019-07-04 01:10:17 +00:00
|
|
|
mVertices[0].col = color;
|
|
|
|
mVertices[1].col = mColorGradientHorizontal ? colorEnd : color;
|
2019-08-31 13:06:23 +00:00
|
|
|
mVertices[2].col = mColorGradientHorizontal ? color : colorEnd;
|
2019-07-04 01:10:17 +00:00
|
|
|
mVertices[3].col = colorEnd;
|
2014-04-12 01:48:13 +00:00
|
|
|
}
|
2013-06-21 16:49:29 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
void ImageComponent::render(const Transform4x4f& parentTrans)
|
2014-04-12 01:48:13 +00:00
|
|
|
{
|
2019-07-22 03:13:48 +00:00
|
|
|
if (!isVisible())
|
|
|
|
return;
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Transform4x4f trans = parentTrans * getTransform();
|
2014-04-12 01:48:13 +00:00
|
|
|
Renderer::setMatrix(trans);
|
2017-07-17 03:10:29 +00:00
|
|
|
|
2014-04-12 01:48:13 +00:00
|
|
|
if(mTexture && mOpacity > 0)
|
|
|
|
{
|
2018-01-23 00:31:18 +00:00
|
|
|
if(Settings::getInstance()->getBool("DebugImage")) {
|
|
|
|
Vector2f targetSizePos = (mTargetSize - mSize) * mOrigin * -1;
|
2019-07-04 01:10:17 +00:00
|
|
|
Renderer::drawRect(targetSizePos.x(), targetSizePos.y(), mTargetSize.x(), mTargetSize.y(), 0xFF000033, 0xFF000033);
|
|
|
|
Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), 0x00000033, 0x00000033);
|
2018-01-23 00:31:18 +00:00
|
|
|
}
|
2014-04-12 01:48:13 +00:00
|
|
|
if(mTexture->isInitialized())
|
|
|
|
{
|
|
|
|
// actually draw the image
|
2017-01-22 23:28:06 +00:00
|
|
|
// The bind() function returns false if the texture is not currently loaded. A blank
|
|
|
|
// texture is bound in this case but we want to handle a fade so it doesn't just 'jump' in
|
|
|
|
// when it finally loads
|
|
|
|
fadeIn(mTexture->bind());
|
2019-08-08 20:16:11 +00:00
|
|
|
Renderer::drawTriangleStrips(&mVertices[0], 4);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2014-04-12 01:48:13 +00:00
|
|
|
}else{
|
|
|
|
LOG(LogError) << "Image texture is not initialized!";
|
|
|
|
mTexture.reset();
|
|
|
|
}
|
|
|
|
}
|
2012-10-17 17:15:58 +00:00
|
|
|
|
2014-04-12 01:48:13 +00:00
|
|
|
GuiComponent::renderChildren(trans);
|
2012-08-02 01:43:55 +00:00
|
|
|
}
|
2012-09-04 16:45:16 +00:00
|
|
|
|
2017-01-22 23:28:06 +00:00
|
|
|
void ImageComponent::fadeIn(bool textureLoaded)
|
|
|
|
{
|
|
|
|
if (!mForceLoad)
|
|
|
|
{
|
|
|
|
if (!textureLoaded)
|
|
|
|
{
|
|
|
|
// Start the fade if this is the first time we've encountered the unloaded texture
|
|
|
|
if (!mFading)
|
|
|
|
{
|
|
|
|
// Start with a zero opacity and flag it as fading
|
|
|
|
mFadeOpacity = 0;
|
|
|
|
mFading = true;
|
|
|
|
updateColors();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (mFading)
|
|
|
|
{
|
|
|
|
// The texture is loaded and we need to fade it in. The fade is based on the frame rate
|
|
|
|
// and is 1/4 second if running at 60 frames per second although the actual value is not
|
|
|
|
// that important
|
|
|
|
int opacity = mFadeOpacity + 255 / 15;
|
|
|
|
// See if we've finished fading
|
|
|
|
if (opacity >= 255)
|
|
|
|
{
|
|
|
|
mFadeOpacity = 255;
|
|
|
|
mFading = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mFadeOpacity = (unsigned char)opacity;
|
|
|
|
}
|
|
|
|
updateColors();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
bool ImageComponent::hasImage()
|
2012-10-10 13:51:48 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
return (bool)mTexture;
|
2012-10-10 13:51:48 +00:00
|
|
|
}
|
2013-04-08 16:52:40 +00:00
|
|
|
|
2014-01-01 05:39:22 +00:00
|
|
|
void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties)
|
|
|
|
{
|
|
|
|
using namespace ThemeFlags;
|
|
|
|
|
2019-08-31 01:57:32 +00:00
|
|
|
GuiComponent::applyTheme(theme, view, element, (properties ^ SIZE) | ((properties & (SIZE | POSITION)) ? ORIGIN : 0));
|
|
|
|
|
2014-01-01 05:39:22 +00:00
|
|
|
const ThemeData::ThemeElement* elem = theme->getElement(view, element, "image");
|
|
|
|
if(!elem)
|
|
|
|
return;
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f scale = getParent() ? getParent()->getSize() : Vector2f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
2019-08-25 15:23:02 +00:00
|
|
|
|
2014-01-10 23:45:47 +00:00
|
|
|
if(properties & ThemeFlags::SIZE)
|
|
|
|
{
|
|
|
|
if(elem->has("size"))
|
2017-10-28 20:24:35 +00:00
|
|
|
setResize(elem->get<Vector2f>("size") * scale);
|
2014-01-10 23:45:47 +00:00
|
|
|
else if(elem->has("maxSize"))
|
2017-10-28 20:24:35 +00:00
|
|
|
setMaxSize(elem->get<Vector2f>("maxSize") * scale);
|
2018-04-12 09:00:47 +00:00
|
|
|
else if(elem->has("minSize"))
|
|
|
|
setMinSize(elem->get<Vector2f>("minSize") * scale);
|
2014-01-10 23:45:47 +00:00
|
|
|
}
|
2014-01-01 05:39:22 +00:00
|
|
|
|
2019-08-31 01:57:32 +00:00
|
|
|
if(elem->has("default"))
|
2017-10-01 03:17:58 +00:00
|
|
|
setDefaultImage(elem->get<std::string>("default"));
|
|
|
|
|
2014-01-01 05:39:22 +00:00
|
|
|
if(properties & PATH && elem->has("path"))
|
2014-01-19 18:23:01 +00:00
|
|
|
{
|
|
|
|
bool tile = (elem->has("tile") && elem->get<bool>("tile"));
|
|
|
|
setImage(elem->get<std::string>("path"), tile);
|
|
|
|
}
|
2014-01-23 21:30:32 +00:00
|
|
|
|
2019-07-04 01:10:17 +00:00
|
|
|
if(properties & COLOR)
|
|
|
|
{
|
|
|
|
if(elem->has("color"))
|
|
|
|
setColorShift(elem->get<unsigned int>("color"));
|
|
|
|
|
|
|
|
if (elem->has("colorEnd"))
|
|
|
|
setColorShiftEnd(elem->get<unsigned int>("colorEnd"));
|
|
|
|
|
|
|
|
if (elem->has("gradientType"))
|
|
|
|
setColorGradientHorizontal(!(elem->get<std::string>("gradientType").compare("horizontal")));
|
|
|
|
}
|
2014-01-01 05:39:22 +00:00
|
|
|
}
|
2014-05-16 21:21:33 +00:00
|
|
|
|
|
|
|
std::vector<HelpPrompt> ImageComponent::getHelpPrompts()
|
|
|
|
{
|
|
|
|
std::vector<HelpPrompt> ret;
|
|
|
|
ret.push_back(HelpPrompt("a", "select"));
|
|
|
|
return ret;
|
|
|
|
}
|