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; mOffset.y = y;
} }
Vector2u GuiComponent::getSize()
{
return mSize;
}
//Children stuff. //Children stuff.
void GuiComponent::addChild(GuiComponent* cmp) void GuiComponent::addChild(GuiComponent* cmp)
{ {

View file

@ -20,7 +20,7 @@ public:
virtual void update(int deltaTime); 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. //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(); virtual void render();
//Called when the Renderer initializes. Passes to children. //Called when the Renderer initializes. Passes to children.
@ -34,6 +34,8 @@ public:
void setOffset(Vector2i offset); void setOffset(Vector2i offset);
void setOffset(int x, int y); void setOffset(int x, int y);
Vector2u getSize();
void setParent(GuiComponent* parent); void setParent(GuiComponent* parent);
GuiComponent* getParent(); GuiComponent* getParent();
@ -50,6 +52,7 @@ protected:
Window* mWindow; Window* mWindow;
GuiComponent* mParent; GuiComponent* mParent;
Vector2i mOffset; Vector2i mOffset;
Vector2u mSize;
std::vector<GuiComponent*> mChildren; std::vector<GuiComponent*> mChildren;
}; };

View file

@ -35,6 +35,10 @@ namespace Renderer
void translatef(float x, float y); void translatef(float x, float y);
void translate(Vector2i offset); 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 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 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); 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); 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) void drawRect(int x, int y, int w, int h, unsigned int color)
{ {
#ifdef USE_OPENGL_ES #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<int> Vector2i;
typedef Vector2<unsigned int> Vector2u;
typedef Vector2<float> Vector2f; typedef Vector2<float> Vector2f;
#endif #endif

View file

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

View file

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

View file

@ -94,7 +94,7 @@ void GuiGameList::render()
std::string desc = game->getDescription(); std::string desc = game->getDescription();
if(!desc.empty()) 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(); mScreenshot->render();

View file

@ -5,8 +5,7 @@
#include "../Log.h" #include "../Log.h"
#include "../Renderer.h" #include "../Renderer.h"
unsigned int ImageComponent::getWidth() { return mSize.x; } Vector2u ImageComponent::getTextureSize() { return mTextureSize; }
unsigned int ImageComponent::getHeight() { return mSize.y; }
ImageComponent::ImageComponent(Window* window, int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool allowUpscale) : GuiComponent(window) 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) if(resizeScale.y)
mSize.y = (int)(mSize.y * resizeScale.y); mSize.y = (int)(mSize.y * resizeScale.y);
} }
if(mTiled)
{
mSize = mTargetSize;
}
} }
void ImageComponent::unloadImage() void ImageComponent::unloadImage()
@ -212,6 +216,8 @@ void ImageComponent::setTiling(bool tile)
if(mTiled) if(mTiled)
mAllowUpscale = false; mAllowUpscale = false;
resize();
} }
void ImageComponent::setResize(unsigned int width, unsigned int height, bool allowUpscale) void ImageComponent::setResize(unsigned int width, unsigned int height, bool allowUpscale)
@ -241,8 +247,8 @@ void ImageComponent::onRender()
if(mTiled) if(mTiled)
{ {
float xCount = (float)mTargetSize.x / mTextureSize.x; float xCount = (float)mSize.x / mTextureSize.x;
float yCount = (float)mTargetSize.y / mTextureSize.y; float yCount = (float)mSize.y / mTextureSize.y;
Renderer::buildGLColorArray(colors, 0xFFFFFF00 | (getOpacity()), 6); Renderer::buildGLColorArray(colors, 0xFFFFFF00 | (getOpacity()), 6);
buildImageArray(0, 0, points, texs, xCount, yCount); 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) 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[0] = posX - (mSize.x * mOrigin.x); points[1] = posY - (mSize.y * mOrigin.y);
points[2] = posX - (mSize.x * mOrigin.x) * px; points[3] = posY + (mSize.y * (1 - mOrigin.y)) * py; points[2] = posX - (mSize.x * mOrigin.x); points[3] = posY + (mSize.y * (1 - mOrigin.y));
points[4] = posX + (mSize.x * (1 - mOrigin.x)) * px; points[5] = posY - (mSize.y * mOrigin.y) * py; 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[6] = posX + (mSize.x * (1 - mOrigin.x)); points[7] = posY - (mSize.y * mOrigin.y);
points[8] = posX - (mSize.x * mOrigin.x) * px; points[9] = posY + (mSize.y * (1 - mOrigin.y)) * py; points[8] = posX - (mSize.x * mOrigin.x); points[9] = posY + (mSize.y * (1 - mOrigin.y));
points[10] = posX + (mSize.x * (1 -mOrigin.x)) * px; points[11] = posY + (mSize.y * (1 - mOrigin.y)) * py; 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 setFlipX(bool flip);
void setFlipY(bool flip); void setFlipY(bool flip);
unsigned int getWidth(); //Returns render width in pixels. May be different than actual texture width. //You can get the rendered size of the ImageComponent with getSize().
unsigned int getHeight(); //Returns render height in pixels. May be different than actual texture height. Vector2u getTextureSize();
bool hasImage(); bool hasImage();
@ -42,9 +43,8 @@ protected:
void onRender(); void onRender();
private: private:
Vector2<unsigned int> mSize; Vector2u mTargetSize;
Vector2<unsigned int> mTargetSize; Vector2u mTextureSize;
Vector2<unsigned int> mTextureSize;
Vector2f mOrigin; Vector2f mOrigin;
bool mAllowUpscale, mTiled, mFlipX, mFlipY; bool mAllowUpscale, mTiled, mFlipX, mFlipY;

View file

@ -10,8 +10,12 @@
#include <memory> #include <memory>
#include "../Sound.h" #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. //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> template <typename T>
class TextListComponent : public GuiComponent class TextListComponent : public GuiComponent
{ {
@ -51,10 +55,14 @@ private:
static const int SCROLLTIME = 200; static const int SCROLLTIME = 200;
void scroll(); //helper method, scrolls in whatever direction scrollDir is 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; int mScrollDir, mScrollAccumulator;
bool mScrolling; bool mScrolling;
int mMarqueeOffset;
int mMarqueeTime;
Font* mFont; Font* mFont;
unsigned int mSelectorColor, mSelectedTextColorOverride; unsigned int mSelectorColor, mSelectedTextColorOverride;
bool mDrawCentered; bool mDrawCentered;
@ -83,6 +91,9 @@ TextListComponent<T>::TextListComponent(Window* window, int offsetX, int offsetY
setOffset(Vector2i(offsetX, offsetY)); setOffset(Vector2i(offsetX, offsetY));
mSize = Vector2u(Renderer::getScreenWidth() - getOffset().x, Renderer::getScreenHeight() - getOffset().y);
mMarqueeOffset = 0;
mMarqueeTime = -MARQUEE_DELAY;
mTextOffsetX = 0; mTextOffsetX = 0;
mFont = font; mFont = font;
@ -140,10 +151,17 @@ void TextListComponent<T>::onRender()
ListRow row = mRowVector.at((unsigned int)i); 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) 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 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; y += entrySize;
} }
@ -160,27 +178,27 @@ bool TextListComponent<T>::input(InputConfig* config, Input input)
{ {
if(config->isMappedTo("down", input)) if(config->isMappedTo("down", input))
{ {
mScrollDir = 1; setScrollDir(1);
scroll(); scroll();
return true; return true;
} }
if(config->isMappedTo("up", input)) if(config->isMappedTo("up", input))
{ {
mScrollDir = -1; setScrollDir(-1);
scroll(); scroll();
return true; return true;
} }
if(config->isMappedTo("pagedown", input)) if(config->isMappedTo("pagedown", input))
{ {
mScrollDir = 10; setScrollDir(10);
scroll(); scroll();
return true; return true;
} }
if(config->isMappedTo("pageup", input)) if(config->isMappedTo("pageup", input))
{ {
mScrollDir = -10; setScrollDir(-10);
scroll(); scroll();
return true; return true;
} }
@ -196,6 +214,14 @@ bool TextListComponent<T>::input(InputConfig* config, Input input)
return GuiComponent::input(config, 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> template <typename T>
void TextListComponent<T>::stopScrolling() void TextListComponent<T>::stopScrolling()
{ {
@ -231,6 +257,22 @@ void TextListComponent<T>::update(int deltaTime)
scroll(); 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); GuiComponent::update(deltaTime);