Added Size and getSize() to GuiComponent.

Added setClipRect and clearClipRect to Renderer.
TextListComponent finally has a marquee. :)
This commit is contained in:
Aloshi 2013-06-02 17:33:49 -05:00
parent 826624481a
commit 7faf9fca53
11 changed files with 126 additions and 45 deletions

View file

@ -92,6 +92,11 @@ void GuiComponent::setOffset(int x, int y)
mOffset.y = y;
}
Vector2u GuiComponent::getSize()
{
return mSize;
}
//Children stuff.
void GuiComponent::addChild(GuiComponent* cmp)
{

View file

@ -20,7 +20,7 @@ public:
virtual void update(int deltaTime);
//Called when it's time to render. Translates the OpenGL matrix, calls onRender() (which renders children), then un-translates the OpenGL matrix.
//You probably don't need to override this, but instead want the protected method onRender.
//You probably don't need to override this, and should use the protected method onRender.
virtual void render();
//Called when the Renderer initializes. Passes to children.
@ -34,6 +34,8 @@ public:
void setOffset(Vector2i offset);
void setOffset(int x, int y);
Vector2u getSize();
void setParent(GuiComponent* parent);
GuiComponent* getParent();
@ -50,6 +52,7 @@ protected:
Window* mWindow;
GuiComponent* mParent;
Vector2i mOffset;
Vector2u mSize;
std::vector<GuiComponent*> mChildren;
};

View file

@ -35,6 +35,10 @@ namespace Renderer
void translatef(float x, float y);
void translate(Vector2i offset);
void setClipRect(int x, int y, unsigned int w, unsigned int h);
void setClipRect(Vector2i offset, Vector2u size);
void clearClipRect();
void drawRect(int x, int y, int w, int h, unsigned int color);
void drawText(std::string text, int x, int y, unsigned int color, Font* font);
void drawCenteredText(std::string text, int xOffset, int y, unsigned int color, Font* font);

View file

@ -36,6 +36,22 @@ namespace Renderer {
translatef((float)offset.x, (float)offset.y);
}
void setClipRect(int x, int y, unsigned int w, unsigned int h)
{
glScissor(x, y, w, h);
glEnable(GL_SCISSOR_TEST);
}
void setClipRect(Vector2i offset, Vector2u size)
{
setClipRect(offset.x, offset.y, size.x, size.y);
}
void clearClipRect()
{
glDisable(GL_SCISSOR_TEST);
}
void drawRect(int x, int y, int w, int h, unsigned int color)
{
#ifdef USE_OPENGL_ES

View file

@ -92,6 +92,7 @@ bool operator !=(const Vector2<T>& left, const Vector2<T>& right)
}
typedef Vector2<int> Vector2i;
typedef Vector2<unsigned int> Vector2u;
typedef Vector2<float> Vector2f;
#endif

View file

@ -5,8 +5,7 @@ GuiBox::GuiBox(Window* window, int offsetX, int offsetY, unsigned int width, uns
{
setOffset(Vector2i(offsetX, offsetY));
mWidth = width;
mHeight = height;
mSize = Vector2u(width, height);
}
void GuiBox::setData(GuiBoxData data)
@ -23,7 +22,7 @@ void GuiBox::setHorizontalImage(std::string path, bool tiled)
mHorizontalImage.setOrigin(0, 0);
mHorizontalImage.setImage(path);
mHorizontalImage.setResize(mHorizontalImage.getHeight(), mHeight, true);
mHorizontalImage.setResize(getHorizontalBorderWidth(), mSize.y, true);
}
void GuiBox::setVerticalImage(std::string path, bool tiled)
@ -32,15 +31,15 @@ void GuiBox::setVerticalImage(std::string path, bool tiled)
mVerticalImage.setOrigin(0, 0);
mVerticalImage.setImage(path);
mVerticalImage.setResize(mWidth, mVerticalImage.getHeight(), true);
mVerticalImage.setResize(mSize.x, getVerticalBorderWidth(), true);
}
void GuiBox::setBackgroundImage(std::string path, bool tiled)
{
mBackgroundImage.setOrigin(0, 0);
mBackgroundImage.setResize(mWidth, mHeight, true);
mBackgroundImage.setResize(mSize.x, mSize.y, true);
mBackgroundImage.setTiling(tiled);
mBackgroundImage.setOffset(getOffset());
mBackgroundImage.setOffset(0, 0);
mBackgroundImage.setImage(path);
}
@ -53,51 +52,53 @@ void GuiBox::setCornerImage(std::string path)
mCornerImage.setImage(path);
}
void GuiBox::render()
void GuiBox::onRender()
{
mBackgroundImage.render();
//left border
mHorizontalImage.setOffset(getOffset().x - getHorizontalBorderWidth(), getOffset().y);
mHorizontalImage.setOffset(-getHorizontalBorderWidth(), 0);
mHorizontalImage.setFlipX(false);
mHorizontalImage.render();
//right border
mHorizontalImage.setOffset(getOffset().x + mWidth, getOffset().y);
mHorizontalImage.setOffset(mSize.x, 0);
mHorizontalImage.setFlipX(true);
mHorizontalImage.render();
//top border
mVerticalImage.setOffset(getOffset().x, getOffset().y - getVerticalBorderWidth());
mVerticalImage.setOffset(0, -getVerticalBorderWidth());
mVerticalImage.setFlipY(false);
mVerticalImage.render();
//bottom border
mVerticalImage.setOffset(getOffset().x, getOffset().y + mHeight);
mVerticalImage.setOffset(0, mSize.y);
mVerticalImage.setFlipY(true);
mVerticalImage.render();
//corner top left
mCornerImage.setOffset(getOffset().x - getHorizontalBorderWidth(), getOffset().y - getVerticalBorderWidth());
mCornerImage.setOffset(-getHorizontalBorderWidth(), -getVerticalBorderWidth());
mCornerImage.setFlipX(false);
mCornerImage.setFlipY(false);
mCornerImage.render();
//top right
mCornerImage.setOffset(getOffset().x + mWidth, mCornerImage.getOffset().y);
mCornerImage.setOffset(mSize.x, mCornerImage.getOffset().y);
mCornerImage.setFlipX(true);
mCornerImage.render();
//bottom right
mCornerImage.setOffset(mCornerImage.getOffset().x, getOffset().y + mHeight);
mCornerImage.setOffset(mCornerImage.getOffset().x, mSize.y);
mCornerImage.setFlipY(true);
mCornerImage.render();
//bottom left
mCornerImage.setOffset(getOffset().x - getHorizontalBorderWidth(), mCornerImage.getOffset().y);
mCornerImage.setOffset(-getHorizontalBorderWidth(), mCornerImage.getOffset().y);
mCornerImage.setFlipX(false);
mCornerImage.render();
GuiComponent::onRender();
}
void GuiBox::init()
@ -105,6 +106,8 @@ void GuiBox::init()
mVerticalImage.init();
mHorizontalImage.init();
mCornerImage.init();
GuiComponent::init();
}
void GuiBox::deinit()
@ -112,16 +115,18 @@ void GuiBox::deinit()
mVerticalImage.deinit();
mHorizontalImage.deinit();
mCornerImage.deinit();
GuiComponent::deinit();
}
int GuiBox::getHorizontalBorderWidth()
{
return mHorizontalImage.getWidth();
return mHorizontalImage.getTextureSize().x;
}
int GuiBox::getVerticalBorderWidth()
{
return mVerticalImage.getHeight();
return mVerticalImage.getTextureSize().y;
}
bool GuiBox::hasBackground()

View file

@ -30,18 +30,17 @@ public:
bool hasBackground();
void render();
void init();
void deinit();
protected:
void onRender();
private:
ImageComponent mBackgroundImage, mHorizontalImage, mVerticalImage, mCornerImage;
int getHorizontalBorderWidth();
int getVerticalBorderWidth();
unsigned int mWidth, mHeight;
};
#endif

View file

@ -94,7 +94,7 @@ void GuiGameList::render()
std::string desc = game->getDescription();
if(!desc.empty())
Renderer::drawWrappedText(desc, (int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getHeight() + 12, (int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), mTheme->getColor("description"), mTheme->getDescriptionFont());
Renderer::drawWrappedText(desc, (int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getSize().y + 12, (int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), mTheme->getColor("description"), mTheme->getDescriptionFont());
}
mScreenshot->render();

View file

@ -5,8 +5,7 @@
#include "../Log.h"
#include "../Renderer.h"
unsigned int ImageComponent::getWidth() { return mSize.x; }
unsigned int ImageComponent::getHeight() { return mSize.y; }
Vector2u ImageComponent::getTextureSize() { return mTextureSize; }
ImageComponent::ImageComponent(Window* window, int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool allowUpscale) : GuiComponent(window)
{
@ -175,6 +174,11 @@ void ImageComponent::resize()
if(resizeScale.y)
mSize.y = (int)(mSize.y * resizeScale.y);
}
if(mTiled)
{
mSize = mTargetSize;
}
}
void ImageComponent::unloadImage()
@ -212,6 +216,8 @@ void ImageComponent::setTiling(bool tile)
if(mTiled)
mAllowUpscale = false;
resize();
}
void ImageComponent::setResize(unsigned int width, unsigned int height, bool allowUpscale)
@ -241,8 +247,8 @@ void ImageComponent::onRender()
if(mTiled)
{
float xCount = (float)mTargetSize.x / mTextureSize.x;
float yCount = (float)mTargetSize.y / mTextureSize.y;
float xCount = (float)mSize.x / mTextureSize.x;
float yCount = (float)mSize.y / mTextureSize.y;
Renderer::buildGLColorArray(colors, 0xFFFFFF00 | (getOpacity()), 6);
buildImageArray(0, 0, points, texs, xCount, yCount);
@ -259,13 +265,13 @@ void ImageComponent::onRender()
void ImageComponent::buildImageArray(int posX, int posY, GLfloat* points, GLfloat* texs, float px, float py)
{
points[0] = posX - (mSize.x * mOrigin.x) * px; points[1] = posY - (mSize.y * mOrigin.y) * py;
points[2] = posX - (mSize.x * mOrigin.x) * px; points[3] = posY + (mSize.y * (1 - mOrigin.y)) * py;
points[4] = posX + (mSize.x * (1 - mOrigin.x)) * px; points[5] = posY - (mSize.y * mOrigin.y) * py;
points[0] = posX - (mSize.x * mOrigin.x); points[1] = posY - (mSize.y * mOrigin.y);
points[2] = posX - (mSize.x * mOrigin.x); points[3] = posY + (mSize.y * (1 - mOrigin.y));
points[4] = posX + (mSize.x * (1 - mOrigin.x)); points[5] = posY - (mSize.y * mOrigin.y);
points[6] = posX + (mSize.x * (1 - mOrigin.x)) * px; points[7] = posY - (mSize.y * mOrigin.y) * py;
points[8] = posX - (mSize.x * mOrigin.x) * px; points[9] = posY + (mSize.y * (1 - mOrigin.y)) * py;
points[10] = posX + (mSize.x * (1 -mOrigin.x)) * px; points[11] = posY + (mSize.y * (1 - mOrigin.y)) * py;
points[6] = posX + (mSize.x * (1 - mOrigin.x)); points[7] = posY - (mSize.y * mOrigin.y);
points[8] = posX - (mSize.x * mOrigin.x); points[9] = posY + (mSize.y * (1 - mOrigin.y));
points[10] = posX + (mSize.x * (1 -mOrigin.x)); points[11] = posY + (mSize.y * (1 - mOrigin.y));

View file

@ -26,8 +26,9 @@ public:
void setFlipX(bool flip);
void setFlipY(bool flip);
unsigned int getWidth(); //Returns render width in pixels. May be different than actual texture width.
unsigned int getHeight(); //Returns render height in pixels. May be different than actual texture height.
//You can get the rendered size of the ImageComponent with getSize().
Vector2u getTextureSize();
bool hasImage();
@ -42,9 +43,8 @@ protected:
void onRender();
private:
Vector2<unsigned int> mSize;
Vector2<unsigned int> mTargetSize;
Vector2<unsigned int> mTextureSize;
Vector2u mTargetSize;
Vector2u mTextureSize;
Vector2f mOrigin;
bool mAllowUpscale, mTiled, mFlipX, mFlipY;

View file

@ -10,8 +10,12 @@
#include <memory>
#include "../Sound.h"
#define MARQUEE_DELAY 600
#define MARQUEE_SPEED 16
#define MARQUEE_RATE 3
//A graphical list. Supports multiple colors for rows and scrolling.
//TODO - add truncation to text rendering if name exceeds a maximum width (a trailing elipses, perhaps).
//TODO - add truncation to text rendering if name exceeds a maximum width (a trailing elipses, perhaps). Marquee would be nice too.
template <typename T>
class TextListComponent : public GuiComponent
{
@ -51,10 +55,14 @@ private:
static const int SCROLLTIME = 200;
void scroll(); //helper method, scrolls in whatever direction scrollDir is
void setScrollDir(int val); //helper method, set mScrollDir as well as reset marquee stuff
int mScrollDir, mScrollAccumulator;
bool mScrolling;
int mMarqueeOffset;
int mMarqueeTime;
Font* mFont;
unsigned int mSelectorColor, mSelectedTextColorOverride;
bool mDrawCentered;
@ -83,6 +91,9 @@ TextListComponent<T>::TextListComponent(Window* window, int offsetX, int offsetY
setOffset(Vector2i(offsetX, offsetY));
mSize = Vector2u(Renderer::getScreenWidth() - getOffset().x, Renderer::getScreenHeight() - getOffset().y);
mMarqueeOffset = 0;
mMarqueeTime = -MARQUEE_DELAY;
mTextOffsetX = 0;
mFont = font;
@ -140,10 +151,17 @@ void TextListComponent<T>::onRender()
ListRow row = mRowVector.at((unsigned int)i);
int x = mTextOffsetX - (mSelection == i ? mMarqueeOffset : 0);
unsigned int color = (mSelection == i && mSelectedTextColorOverride != 0) ? mSelectedTextColorOverride : row.color;
Renderer::setClipRect(getOffset(), getSize());
if(mDrawCentered)
Renderer::drawCenteredText(row.name, mTextOffsetX, y, (mSelection == i && mSelectedTextColorOverride != 0) ? mSelectedTextColorOverride : row.color, mFont);
Renderer::drawCenteredText(row.name, x, y, color, mFont);
else
Renderer::drawText(row.name, mTextOffsetX, y, (mSelection == i && mSelectedTextColorOverride != 0) ? mSelectedTextColorOverride : row.color, mFont);
Renderer::drawText(row.name, x, y, color, mFont);
Renderer::clearClipRect();
y += entrySize;
}
@ -160,27 +178,27 @@ bool TextListComponent<T>::input(InputConfig* config, Input input)
{
if(config->isMappedTo("down", input))
{
mScrollDir = 1;
setScrollDir(1);
scroll();
return true;
}
if(config->isMappedTo("up", input))
{
mScrollDir = -1;
setScrollDir(-1);
scroll();
return true;
}
if(config->isMappedTo("pagedown", input))
{
mScrollDir = 10;
setScrollDir(10);
scroll();
return true;
}
if(config->isMappedTo("pageup", input))
{
mScrollDir = -10;
setScrollDir(-10);
scroll();
return true;
}
@ -196,6 +214,14 @@ bool TextListComponent<T>::input(InputConfig* config, Input input)
return GuiComponent::input(config, input);
}
template <typename T>
void TextListComponent<T>::setScrollDir(int val)
{
mScrollDir = val;
mMarqueeOffset = 0;
mMarqueeTime = -MARQUEE_DELAY;
}
template <typename T>
void TextListComponent<T>::stopScrolling()
{
@ -231,6 +257,22 @@ void TextListComponent<T>::update(int deltaTime)
scroll();
}
}
}else{
//if we're not scrolling and this object's text goes outside our size, marquee it!
std::string text = getSelectedName();
int w;
mFont->sizeText(text, &w, NULL);
//it's long enough to marquee
if(w - mMarqueeOffset > (int)getSize().x - 12)
{
mMarqueeTime += deltaTime;
while(mMarqueeTime > MARQUEE_SPEED)
{
mMarqueeOffset += MARQUEE_RATE;
mMarqueeTime -= MARQUEE_SPEED;
}
}
}
GuiComponent::update(deltaTime);