2013-12-01 01:04:46 +00:00
|
|
|
#pragma once
|
2017-10-31 17:12:50 +00:00
|
|
|
#ifndef ES_CORE_COMPONENTS_IMAGE_GRID_COMPONENT_H
|
|
|
|
#define ES_CORE_COMPONENTS_IMAGE_GRID_COMPONENT_H
|
2013-12-01 01:04:46 +00:00
|
|
|
|
2014-06-20 01:30:09 +00:00
|
|
|
#include "components/IList.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "resources/TextureResource.h"
|
2013-12-01 01:04:46 +00:00
|
|
|
|
2014-02-08 03:45:28 +00:00
|
|
|
struct ImageGridData
|
|
|
|
{
|
|
|
|
std::shared_ptr<TextureResource> texture;
|
|
|
|
};
|
|
|
|
|
2013-12-01 01:04:46 +00:00
|
|
|
template<typename T>
|
2014-02-13 23:10:28 +00:00
|
|
|
class ImageGridComponent : public IList<ImageGridData, T>
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2014-02-17 17:40:31 +00:00
|
|
|
protected:
|
|
|
|
using IList<ImageGridData, T>::mEntries;
|
|
|
|
using IList<ImageGridData, T>::listUpdate;
|
|
|
|
using IList<ImageGridData, T>::listInput;
|
|
|
|
using IList<ImageGridData, T>::listRenderTitleOverlay;
|
|
|
|
using IList<ImageGridData, T>::getTransform;
|
|
|
|
using IList<ImageGridData, T>::mSize;
|
|
|
|
using IList<ImageGridData, T>::mCursor;
|
|
|
|
using IList<ImageGridData, T>::Entry;
|
|
|
|
using IList<ImageGridData, T>::mWindow;
|
|
|
|
|
2013-12-01 01:04:46 +00:00
|
|
|
public:
|
2014-02-17 17:40:31 +00:00
|
|
|
using IList<ImageGridData, T>::size;
|
|
|
|
using IList<ImageGridData, T>::isScrolling;
|
|
|
|
using IList<ImageGridData, T>::stopScrolling;
|
|
|
|
|
2013-12-01 01:04:46 +00:00
|
|
|
ImageGridComponent(Window* window);
|
|
|
|
|
2014-02-08 03:45:28 +00:00
|
|
|
void add(const std::string& name, const std::string& imagePath, const T& obj);
|
|
|
|
|
2013-12-01 01:04:46 +00:00
|
|
|
void onSizeChanged() override;
|
|
|
|
|
|
|
|
bool input(InputConfig* config, Input input) override;
|
|
|
|
void update(int deltaTime) override;
|
2017-10-28 20:24:35 +00:00
|
|
|
void render(const Transform4x4f& parentTrans) override;
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
private:
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f getSquareSize(std::shared_ptr<TextureResource> tex = nullptr) const
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f aspect(1, 1);
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
if(tex)
|
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
const Vector2i& texSize = tex->getSize();
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
if(texSize.x() > texSize.y())
|
|
|
|
aspect[0] = (float)texSize.x() / texSize.y();
|
|
|
|
else
|
|
|
|
aspect[1] = (float)texSize.y() / texSize.x();
|
|
|
|
}
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
return Vector2f(156 * aspect.x(), 156 * aspect.y());
|
2013-12-01 01:04:46 +00:00
|
|
|
};
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f getMaxSquareSize() const
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f squareSize(32, 32);
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
// calc biggest square size
|
2017-11-11 14:56:22 +00:00
|
|
|
for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f chkSize = getSquareSize(it->data.texture);
|
2013-12-01 01:04:46 +00:00
|
|
|
if(chkSize.x() > squareSize.x())
|
|
|
|
squareSize[0] = chkSize[0];
|
|
|
|
if(chkSize.y() > squareSize.y())
|
|
|
|
squareSize[1] = chkSize[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
return squareSize;
|
|
|
|
};
|
|
|
|
|
2018-03-23 09:25:33 +00:00
|
|
|
Vector2i getGridDimension() const
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f squareSize = getMaxSquareSize();
|
2018-03-23 09:25:33 +00:00
|
|
|
Vector2i gridDimension((int)(mSize.x() / (squareSize.x() + getPadding().x())), (int)(mSize.y() / (squareSize.y() + getPadding().y())));
|
|
|
|
return gridDimension;
|
2013-12-01 01:04:46 +00:00
|
|
|
};
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f getPadding() const { return Vector2f(24, 24); }
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
void buildImages();
|
|
|
|
void updateImages();
|
|
|
|
|
2014-02-08 03:45:28 +00:00
|
|
|
virtual void onCursorChanged(const CursorState& state);
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
bool mEntriesDirty;
|
|
|
|
|
|
|
|
std::vector<ImageComponent> mImages;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
2014-02-17 17:40:31 +00:00
|
|
|
ImageGridComponent<T>::ImageGridComponent(Window* window) : IList<ImageGridData, T>(window)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
|
|
|
mEntriesDirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
2014-02-08 03:45:28 +00:00
|
|
|
void ImageGridComponent<T>::add(const std::string& name, const std::string& imagePath, const T& obj)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2014-02-17 17:40:31 +00:00
|
|
|
typename IList<ImageGridData, T>::Entry entry;
|
2014-02-08 03:45:28 +00:00
|
|
|
entry.name = name;
|
|
|
|
entry.object = obj;
|
|
|
|
entry.data.texture = ResourceManager::getInstance()->fileExists(imagePath) ? TextureResource::get(imagePath) : TextureResource::get(":/button.png");
|
|
|
|
static_cast<IList< ImageGridData, T >*>(this)->add(entry);
|
2013-12-01 01:04:46 +00:00
|
|
|
mEntriesDirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
bool ImageGridComponent<T>::input(InputConfig* config, Input input)
|
|
|
|
{
|
|
|
|
if(input.value != 0)
|
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2i dir = Vector2i::Zero();
|
2013-12-01 01:04:46 +00:00
|
|
|
if(config->isMappedTo("up", input))
|
|
|
|
dir[1] = -1;
|
|
|
|
else if(config->isMappedTo("down", input))
|
|
|
|
dir[1] = 1;
|
|
|
|
else if(config->isMappedTo("left", input))
|
|
|
|
dir[0] = -1;
|
|
|
|
else if(config->isMappedTo("right", input))
|
|
|
|
dir[0] = 1;
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
if(dir != Vector2i::Zero())
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2018-03-23 09:25:33 +00:00
|
|
|
listInput(dir.x() + dir.y() * getGridDimension().x());
|
2013-12-01 01:04:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
if(config->isMappedTo("up", input) || config->isMappedTo("down", input) || config->isMappedTo("left", input) || config->isMappedTo("right", input))
|
|
|
|
{
|
2014-02-08 02:15:48 +00:00
|
|
|
stopScrolling();
|
2013-12-01 01:04:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return GuiComponent::input(config, input);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void ImageGridComponent<T>::update(int deltaTime)
|
|
|
|
{
|
2014-02-08 02:15:48 +00:00
|
|
|
listUpdate(deltaTime);
|
2013-12-01 01:04:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
2017-10-28 20:24:35 +00:00
|
|
|
void ImageGridComponent<T>::render(const Transform4x4f& parentTrans)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Transform4x4f trans = getTransform() * parentTrans;
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
if(mEntriesDirty)
|
|
|
|
{
|
|
|
|
buildImages();
|
|
|
|
updateImages();
|
|
|
|
mEntriesDirty = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto it = mImages.begin(); it != mImages.end(); it++)
|
|
|
|
{
|
|
|
|
it->render(trans);
|
|
|
|
}
|
|
|
|
|
2014-02-17 17:40:31 +00:00
|
|
|
GuiComponent::renderChildren(trans);
|
2013-12-01 01:04:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
2017-11-17 14:58:52 +00:00
|
|
|
void ImageGridComponent<T>::onCursorChanged(const CursorState& /*state*/)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
|
|
|
updateImages();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void ImageGridComponent<T>::onSizeChanged()
|
|
|
|
{
|
|
|
|
buildImages();
|
|
|
|
updateImages();
|
|
|
|
}
|
|
|
|
|
|
|
|
// create and position imagecomponents (mImages)
|
|
|
|
template<typename T>
|
|
|
|
void ImageGridComponent<T>::buildImages()
|
|
|
|
{
|
|
|
|
mImages.clear();
|
|
|
|
|
2018-03-23 09:25:33 +00:00
|
|
|
Vector2i gridDimension = getGridDimension();
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f squareSize = getMaxSquareSize();
|
|
|
|
Vector2f padding = getPadding();
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
// attempt to center within our size
|
2018-03-23 09:25:33 +00:00
|
|
|
Vector2f totalSize(gridDimension.x() * (squareSize.x() + padding.x()), gridDimension.y() * (squareSize.y() + padding.y()));
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f offset(mSize.x() - totalSize.x(), mSize.y() - totalSize.y());
|
2013-12-01 01:04:46 +00:00
|
|
|
offset /= 2;
|
|
|
|
|
2018-03-23 09:25:33 +00:00
|
|
|
for(int y = 0; y < gridDimension.y(); y++)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
2018-03-23 09:25:33 +00:00
|
|
|
for(int x = 0; x < gridDimension.x(); x++)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
|
|
|
mImages.push_back(ImageComponent(mWindow));
|
2018-03-23 09:25:33 +00:00
|
|
|
ImageComponent& image = mImages.at(y * gridDimension.x() + x);
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
image.setPosition((squareSize.x() + padding.x()) * (x + 0.5f) + offset.x(), (squareSize.y() + padding.y()) * (y + 0.5f) + offset.y());
|
|
|
|
image.setOrigin(0.5f, 0.5f);
|
2014-01-10 23:45:47 +00:00
|
|
|
image.setResize(squareSize.x(), squareSize.y());
|
2013-12-01 01:04:46 +00:00
|
|
|
image.setImage("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void ImageGridComponent<T>::updateImages()
|
|
|
|
{
|
|
|
|
if(mImages.empty())
|
|
|
|
buildImages();
|
|
|
|
|
2018-03-23 09:25:33 +00:00
|
|
|
Vector2i gridDimension = getGridDimension();
|
2013-12-01 01:04:46 +00:00
|
|
|
|
2018-03-23 09:25:33 +00:00
|
|
|
int cursorRow = mCursor / gridDimension.x();
|
2013-12-01 01:04:46 +00:00
|
|
|
|
2018-03-23 09:25:33 +00:00
|
|
|
int start = (cursorRow - (gridDimension.y() / 2)) * gridDimension.x();
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
//if we're at the end put the row as close as we can and no higher
|
2018-03-23 09:25:33 +00:00
|
|
|
if(start + (gridDimension.x() * gridDimension.y()) >= (int)mEntries.size())
|
|
|
|
start = gridDimension.x() * ((int)mEntries.size()/gridDimension.x() - gridDimension.y() + 1);
|
2013-12-01 01:04:46 +00:00
|
|
|
|
|
|
|
if(start < 0)
|
|
|
|
start = 0;
|
|
|
|
|
|
|
|
unsigned int i = (unsigned int)start;
|
|
|
|
for(unsigned int img = 0; img < mImages.size(); img++)
|
|
|
|
{
|
|
|
|
ImageComponent& image = mImages.at(img);
|
2014-02-08 03:45:28 +00:00
|
|
|
if(i >= (unsigned int)size())
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
|
|
|
image.setImage("");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f squareSize = getSquareSize(mEntries.at(i).data.texture);
|
2017-10-28 20:07:31 +00:00
|
|
|
if(i == (unsigned int)mCursor)
|
2013-12-01 01:04:46 +00:00
|
|
|
{
|
|
|
|
image.setColorShift(0xFFFFFFFF);
|
2014-01-10 23:45:47 +00:00
|
|
|
image.setResize(squareSize.x() + getPadding().x() * 0.95f, squareSize.y() + getPadding().y() * 0.95f);
|
2013-12-01 01:04:46 +00:00
|
|
|
}else{
|
|
|
|
image.setColorShift(0xAAAAAABB);
|
2014-01-10 23:45:47 +00:00
|
|
|
image.setResize(squareSize.x(), squareSize.y());
|
2013-12-01 01:04:46 +00:00
|
|
|
}
|
|
|
|
|
2014-02-08 03:45:28 +00:00
|
|
|
image.setImage(mEntries.at(i).data.texture);
|
2013-12-01 01:04:46 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
2017-10-31 17:12:50 +00:00
|
|
|
|
|
|
|
#endif // ES_CORE_COMPONENTS_IMAGE_GRID_COMPONENT_H
|