2013-06-02 15:08:32 +00:00
|
|
|
#ifndef _TEXTLISTCOMPONENT_H_
|
|
|
|
#define _TEXTLISTCOMPONENT_H_
|
|
|
|
|
|
|
|
#include "../Renderer.h"
|
2013-10-04 23:24:41 +00:00
|
|
|
#include "../resources/Font.h"
|
2013-06-02 15:08:32 +00:00
|
|
|
#include "../GuiComponent.h"
|
|
|
|
#include "../InputManager.h"
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <memory>
|
|
|
|
#include "../Sound.h"
|
2013-07-10 11:29:43 +00:00
|
|
|
#include "../Log.h"
|
2013-11-12 23:28:15 +00:00
|
|
|
#include "../ThemeData.h"
|
|
|
|
#include <functional>
|
2013-06-02 15:08:32 +00:00
|
|
|
|
|
|
|
//A graphical list. Supports multiple colors for rows and scrolling.
|
|
|
|
template <typename T>
|
|
|
|
class TextListComponent : public GuiComponent
|
|
|
|
{
|
|
|
|
public:
|
2013-11-12 23:28:15 +00:00
|
|
|
TextListComponent(Window* window);
|
2013-06-02 15:08:32 +00:00
|
|
|
virtual ~TextListComponent();
|
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
bool input(InputConfig* config, Input input) override;
|
|
|
|
void update(int deltaTime) override;
|
|
|
|
void render(const Eigen::Affine3f& parentTrans) override;
|
2014-01-01 05:39:22 +00:00
|
|
|
void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties) override;
|
2013-07-10 11:29:43 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
struct ListRow
|
|
|
|
{
|
|
|
|
std::string name;
|
|
|
|
T object;
|
|
|
|
unsigned int colorId;
|
2013-11-21 22:39:02 +00:00
|
|
|
std::shared_ptr<TextCache> textCache;
|
2013-11-12 23:28:15 +00:00
|
|
|
};
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
void add(const std::string& name, const T& obj, unsigned int colorId);
|
|
|
|
void remove(const T& obj);
|
2013-06-02 15:08:32 +00:00
|
|
|
void clear();
|
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
inline const std::string& getSelectedName() const { return mRowVector.at(mCursor).name; }
|
|
|
|
inline T getSelected() const { return mRowVector.at(mCursor).object; }
|
|
|
|
inline const std::vector<ListRow>& getList() const { return mRowVector; }
|
|
|
|
|
|
|
|
void setCursor(const T& select);
|
2013-12-22 22:56:11 +00:00
|
|
|
void setCursor(typename std::vector<ListRow>::const_iterator& it);
|
2013-11-12 23:28:15 +00:00
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
void stopScrolling();
|
2014-01-25 00:10:13 +00:00
|
|
|
inline bool isScrolling() const { return mScrollDir != 0 && mScrollAccumulator >= 0; }
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-12-30 23:23:34 +00:00
|
|
|
enum CursorState
|
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
CURSOR_STOPPED,
|
|
|
|
CURSOR_SCROLLING
|
|
|
|
};
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2014-01-22 02:43:33 +00:00
|
|
|
enum Alignment
|
|
|
|
{
|
|
|
|
ALIGN_LEFT,
|
|
|
|
ALIGN_CENTER,
|
|
|
|
ALIGN_RIGHT
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void setAlignment(Alignment align) { mAlignment = align; }
|
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
inline void setCursorChangedCallback(const std::function<void(CursorState state)>& func) { mCursorChangedCallback = func; }
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-12-30 23:23:34 +00:00
|
|
|
inline void setFont(const std::shared_ptr<Font>& font)
|
|
|
|
{
|
|
|
|
mFont = font;
|
|
|
|
for(auto it = mRowVector.begin(); it != mRowVector.end(); it++)
|
|
|
|
it->textCache.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void setSelectorColor(unsigned int color) { mSelectorColor = color; }
|
|
|
|
inline void setSelectedColor(unsigned int color) { mSelectedColor = color; }
|
|
|
|
inline void setScrollSound(const std::shared_ptr<Sound>& sound) { mScrollSound = sound; }
|
|
|
|
inline void setColor(unsigned int id, unsigned int color) { mColors[id] = color; }
|
2014-01-03 16:40:36 +00:00
|
|
|
inline void setSound(const std::shared_ptr<Sound>& sound) { mScrollSound = sound; }
|
2013-12-30 23:23:34 +00:00
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
private:
|
2013-11-12 23:28:15 +00:00
|
|
|
static const int MARQUEE_DELAY = 900;
|
|
|
|
static const int MARQUEE_SPEED = 16;
|
|
|
|
static const int MARQUEE_RATE = 3;
|
|
|
|
|
|
|
|
static const int SCROLL_DELAY = 507;
|
|
|
|
static const int SCROLL_TIME = 150;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
|
|
|
void scroll(); //helper method, scrolls in whatever direction scrollDir is
|
2013-06-02 22:33:49 +00:00
|
|
|
void setScrollDir(int val); //helper method, set mScrollDir as well as reset marquee stuff
|
2013-11-12 23:28:15 +00:00
|
|
|
void onCursorChanged(CursorState state);
|
2013-06-02 15:08:32 +00:00
|
|
|
|
|
|
|
int mScrollDir, mScrollAccumulator;
|
|
|
|
|
2013-06-02 22:33:49 +00:00
|
|
|
int mMarqueeOffset;
|
|
|
|
int mMarqueeTime;
|
|
|
|
|
2014-01-22 02:43:33 +00:00
|
|
|
Alignment mAlignment;
|
2014-01-22 03:10:49 +00:00
|
|
|
float mHorizontalMargin;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
|
|
|
std::vector<ListRow> mRowVector;
|
2013-11-12 23:28:15 +00:00
|
|
|
int mCursor;
|
|
|
|
|
|
|
|
std::function<void(CursorState state)> mCursorChangedCallback;
|
2013-12-30 23:23:34 +00:00
|
|
|
|
|
|
|
std::shared_ptr<Font> mFont;
|
|
|
|
unsigned int mSelectorColor;
|
|
|
|
unsigned int mSelectedColor;
|
|
|
|
std::shared_ptr<Sound> mScrollSound;
|
|
|
|
static const unsigned int COLOR_ID_COUNT = 2;
|
|
|
|
unsigned int mColors[COLOR_ID_COUNT];
|
2013-06-02 15:08:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
2013-11-12 23:28:15 +00:00
|
|
|
TextListComponent<T>::TextListComponent(Window* window) :
|
|
|
|
GuiComponent(window)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
mCursor = 0;
|
2013-06-02 15:08:32 +00:00
|
|
|
mScrollDir = 0;
|
|
|
|
mScrollAccumulator = 0;
|
|
|
|
|
2013-06-02 22:33:49 +00:00
|
|
|
mMarqueeOffset = 0;
|
|
|
|
mMarqueeTime = -MARQUEE_DELAY;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2014-01-22 03:10:49 +00:00
|
|
|
mHorizontalMargin = 0;
|
2014-01-22 02:43:33 +00:00
|
|
|
mAlignment = ALIGN_CENTER;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-12-30 23:23:34 +00:00
|
|
|
mFont = Font::get(FONT_SIZE_MEDIUM);
|
|
|
|
mSelectorColor = 0x000000FF;
|
|
|
|
mSelectedColor = 0;
|
|
|
|
mColors[0] = 0x0000FFFF;
|
|
|
|
mColors[1] = 0x00FF00FF;
|
2013-07-10 11:29:43 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
template <typename T>
|
|
|
|
TextListComponent<T>::~TextListComponent()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2013-07-10 11:29:43 +00:00
|
|
|
void TextListComponent<T>::render(const Eigen::Affine3f& parentTrans)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-07-10 11:29:43 +00:00
|
|
|
Eigen::Affine3f trans = parentTrans * getTransform();
|
2013-11-21 22:39:02 +00:00
|
|
|
|
2013-12-30 23:23:34 +00:00
|
|
|
std::shared_ptr<Font>& font = mFont;
|
2013-11-12 23:28:15 +00:00
|
|
|
|
2013-06-02 19:34:50 +00:00
|
|
|
const int cutoff = 0;
|
2013-11-12 23:28:15 +00:00
|
|
|
const int entrySize = font->getHeight() + 5;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
|
|
|
int startEntry = 0;
|
|
|
|
|
|
|
|
//number of entries that can fit on the screen simultaniously
|
2013-08-23 16:21:00 +00:00
|
|
|
int screenCount = (int)mSize.y() / entrySize;
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
if((int)mRowVector.size() >= screenCount)
|
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
startEntry = mCursor - (int)(screenCount * 0.5);
|
2013-06-02 15:08:32 +00:00
|
|
|
if(startEntry < 0)
|
|
|
|
startEntry = 0;
|
|
|
|
if(startEntry >= (int)mRowVector.size() - screenCount)
|
|
|
|
startEntry = mRowVector.size() - screenCount;
|
|
|
|
}
|
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
float y = (float)cutoff;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
|
|
|
if(mRowVector.size() == 0)
|
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
font->drawCenteredText("The list is empty.", 0, y, 0xFF0000FF);
|
2013-06-02 15:08:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int listCutoff = startEntry + screenCount;
|
|
|
|
if(listCutoff > (int)mRowVector.size())
|
|
|
|
listCutoff = mRowVector.size();
|
|
|
|
|
2013-08-06 13:15:20 +00:00
|
|
|
Eigen::Vector3f dim(getSize().x(), getSize().y(), 0);
|
|
|
|
dim = trans * dim - trans.translation();
|
|
|
|
Renderer::pushClipRect(Eigen::Vector2i((int)trans.translation().x(), (int)trans.translation().y()), Eigen::Vector2i((int)dim.x(), (int)dim.y()));
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
for(int i = startEntry; i < listCutoff; i++)
|
|
|
|
{
|
|
|
|
//draw selector bar
|
2013-11-12 23:28:15 +00:00
|
|
|
if(mCursor == i)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-21 22:39:02 +00:00
|
|
|
Renderer::setMatrix(trans);
|
2013-12-30 23:23:34 +00:00
|
|
|
Renderer::drawRect(0, (int)y, (int)getSize().x(), font->getHeight(), mSelectorColor);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
2013-11-21 22:39:02 +00:00
|
|
|
ListRow& row = mRowVector.at((unsigned int)i);
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
unsigned int color;
|
2013-12-30 23:23:34 +00:00
|
|
|
if(mCursor == i && mSelectedColor)
|
|
|
|
color = mSelectedColor;
|
2013-11-12 23:28:15 +00:00
|
|
|
else
|
2013-12-30 23:23:34 +00:00
|
|
|
color = mColors[row.colorId];
|
2013-11-12 23:28:15 +00:00
|
|
|
|
2013-11-21 22:39:02 +00:00
|
|
|
if(!row.textCache)
|
|
|
|
row.textCache = std::unique_ptr<TextCache>(font->buildTextCache(row.name, 0, 0, 0x000000FF));
|
|
|
|
|
|
|
|
row.textCache->setColor(color);
|
|
|
|
|
2014-01-22 02:43:33 +00:00
|
|
|
Eigen::Vector3f offset(0, y, 0);
|
2013-11-21 22:39:02 +00:00
|
|
|
|
2014-01-22 02:43:33 +00:00
|
|
|
switch(mAlignment)
|
|
|
|
{
|
|
|
|
case ALIGN_LEFT:
|
2014-01-22 03:10:49 +00:00
|
|
|
offset[0] = mHorizontalMargin;
|
2014-01-22 02:43:33 +00:00
|
|
|
break;
|
|
|
|
case ALIGN_CENTER:
|
|
|
|
offset[0] = (mSize.x() - row.textCache->metrics.size.x()) / 2;
|
2014-01-22 03:10:49 +00:00
|
|
|
if(offset[0] < 0)
|
|
|
|
offset[0] = 0;
|
2014-01-22 02:43:33 +00:00
|
|
|
break;
|
|
|
|
case ALIGN_RIGHT:
|
|
|
|
offset[0] = (mSize.x() - row.textCache->metrics.size.x());
|
2014-01-22 03:10:49 +00:00
|
|
|
offset[0] -= mHorizontalMargin;
|
|
|
|
if(offset[0] < 0)
|
|
|
|
offset[0] = 0;
|
|
|
|
|
2014-01-22 02:43:33 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-01-22 03:10:49 +00:00
|
|
|
if(mCursor == i)
|
|
|
|
offset[0] -= mMarqueeOffset;
|
|
|
|
|
2013-11-21 22:39:02 +00:00
|
|
|
Eigen::Affine3f drawTrans = trans;
|
|
|
|
drawTrans.translate(offset);
|
|
|
|
Renderer::setMatrix(drawTrans);
|
2013-06-02 22:33:49 +00:00
|
|
|
|
2013-11-21 22:39:02 +00:00
|
|
|
font->renderTextCache(row.textCache.get());
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
y += entrySize;
|
|
|
|
}
|
2013-06-02 19:34:50 +00:00
|
|
|
|
2013-06-14 15:48:13 +00:00
|
|
|
Renderer::popClipRect();
|
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
GuiComponent::renderChildren(trans);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool TextListComponent<T>::input(InputConfig* config, Input input)
|
|
|
|
{
|
|
|
|
if(mRowVector.size() > 0)
|
|
|
|
{
|
|
|
|
if(input.value != 0)
|
|
|
|
{
|
|
|
|
if(config->isMappedTo("down", input))
|
|
|
|
{
|
2013-06-02 22:33:49 +00:00
|
|
|
setScrollDir(1);
|
2013-06-02 15:08:32 +00:00
|
|
|
scroll();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(config->isMappedTo("up", input))
|
|
|
|
{
|
2013-06-02 22:33:49 +00:00
|
|
|
setScrollDir(-1);
|
2013-06-02 15:08:32 +00:00
|
|
|
scroll();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(config->isMappedTo("pagedown", input))
|
|
|
|
{
|
2013-06-02 22:33:49 +00:00
|
|
|
setScrollDir(10);
|
2013-06-02 15:08:32 +00:00
|
|
|
scroll();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(config->isMappedTo("pageup", input))
|
|
|
|
{
|
2013-06-02 22:33:49 +00:00
|
|
|
setScrollDir(-10);
|
2013-06-02 15:08:32 +00:00
|
|
|
scroll();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}else{
|
2013-11-12 23:28:15 +00:00
|
|
|
if(config->isMappedTo("down", input) || config->isMappedTo("up", input) ||
|
|
|
|
config->isMappedTo("pagedown", input) || config->isMappedTo("pageup", input))
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
|
|
|
stopScrolling();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-02 19:34:50 +00:00
|
|
|
return GuiComponent::input(config, input);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 22:33:49 +00:00
|
|
|
template <typename T>
|
|
|
|
void TextListComponent<T>::setScrollDir(int val)
|
|
|
|
{
|
|
|
|
mScrollDir = val;
|
|
|
|
mMarqueeOffset = 0;
|
|
|
|
mMarqueeTime = -MARQUEE_DELAY;
|
2013-11-12 23:28:15 +00:00
|
|
|
mScrollAccumulator = -SCROLL_DELAY;
|
2013-06-02 22:33:49 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
template <typename T>
|
|
|
|
void TextListComponent<T>::stopScrolling()
|
|
|
|
{
|
|
|
|
mScrollAccumulator = 0;
|
|
|
|
mScrollDir = 0;
|
2013-11-12 23:28:15 +00:00
|
|
|
onCursorChanged(CURSOR_STOPPED);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TextListComponent<T>::update(int deltaTime)
|
|
|
|
{
|
|
|
|
if(mScrollDir != 0)
|
|
|
|
{
|
|
|
|
mScrollAccumulator += deltaTime;
|
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
while(mScrollAccumulator >= SCROLL_TIME)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
mScrollAccumulator -= SCROLL_TIME;
|
|
|
|
scroll();
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 22:33:49 +00:00
|
|
|
}else{
|
|
|
|
//if we're not scrolling and this object's text goes outside our size, marquee it!
|
|
|
|
std::string text = getSelectedName();
|
2013-07-10 11:29:43 +00:00
|
|
|
|
2013-12-30 23:23:34 +00:00
|
|
|
Eigen::Vector2f textSize = mFont->sizeText(text);
|
2013-06-02 22:33:49 +00:00
|
|
|
|
|
|
|
//it's long enough to marquee
|
2014-01-22 03:10:49 +00:00
|
|
|
if(textSize.x() - mMarqueeOffset > getSize().x() - 12 - (mAlignment != ALIGN_CENTER ? mHorizontalMargin : 0))
|
2013-06-02 22:33:49 +00:00
|
|
|
{
|
|
|
|
mMarqueeTime += deltaTime;
|
|
|
|
while(mMarqueeTime > MARQUEE_SPEED)
|
|
|
|
{
|
|
|
|
mMarqueeOffset += MARQUEE_RATE;
|
|
|
|
mMarqueeTime -= MARQUEE_SPEED;
|
|
|
|
}
|
|
|
|
}
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
2013-06-02 19:34:50 +00:00
|
|
|
|
|
|
|
GuiComponent::update(deltaTime);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TextListComponent<T>::scroll()
|
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
mCursor += mScrollDir;
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
if(mCursor < 0)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
|
|
|
if(mScrollDir < -1)
|
2013-11-12 23:28:15 +00:00
|
|
|
mCursor = 0;
|
2013-06-02 15:08:32 +00:00
|
|
|
else
|
2013-11-12 23:28:15 +00:00
|
|
|
mCursor += mRowVector.size();
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
2013-11-12 23:28:15 +00:00
|
|
|
if(mCursor >= (int)mRowVector.size())
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
|
|
|
if(mScrollDir > 1)
|
2013-11-12 23:28:15 +00:00
|
|
|
mCursor = (int)mRowVector.size() - 1;
|
2013-06-02 15:08:32 +00:00
|
|
|
else
|
2013-11-12 23:28:15 +00:00
|
|
|
mCursor -= mRowVector.size();
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
onCursorChanged(CURSOR_SCROLLING);
|
2013-12-30 23:23:34 +00:00
|
|
|
|
|
|
|
if(mScrollSound)
|
|
|
|
mScrollSound->play();
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//list management stuff
|
|
|
|
template <typename T>
|
2013-11-12 23:28:15 +00:00
|
|
|
void TextListComponent<T>::add(const std::string& name, const T& obj, unsigned int color)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-12-30 23:23:34 +00:00
|
|
|
assert(color < COLOR_ID_COUNT);
|
2013-11-12 23:28:15 +00:00
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
ListRow row = {name, obj, color};
|
|
|
|
mRowVector.push_back(row);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2013-11-12 23:28:15 +00:00
|
|
|
void TextListComponent<T>::remove(const T& obj)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
for(auto it = mRowVector.begin(); it != mRowVector.end(); it++)
|
|
|
|
{
|
|
|
|
if((*it).object == obj)
|
|
|
|
{
|
|
|
|
if(mCursor > 0 && it - mRowVector.begin() >= mCursor)
|
|
|
|
{
|
|
|
|
mCursor--;
|
|
|
|
onCursorChanged(CURSOR_STOPPED);
|
|
|
|
}
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
mRowVector.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
LOG(LogError) << "Tried to remove an object we couldn't find";
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2013-11-12 23:28:15 +00:00
|
|
|
void TextListComponent<T>::clear()
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
mRowVector.clear();
|
|
|
|
mCursor = 0;
|
|
|
|
mScrollDir = 0;
|
|
|
|
mMarqueeOffset = 0;
|
|
|
|
mMarqueeTime = -MARQUEE_DELAY;
|
|
|
|
onCursorChanged(CURSOR_STOPPED);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2013-11-12 23:28:15 +00:00
|
|
|
void TextListComponent<T>::setCursor(const T& obj)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
for(auto it = mRowVector.begin(); it != mRowVector.end(); it++)
|
|
|
|
{
|
|
|
|
if((*it).object == obj)
|
|
|
|
{
|
|
|
|
mCursor = it - mRowVector.begin();
|
|
|
|
onCursorChanged(CURSOR_STOPPED);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2013-06-02 15:08:32 +00:00
|
|
|
|
2013-11-12 23:28:15 +00:00
|
|
|
LOG(LogError) << "Tried to set cursor to object we couldn't find";
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
2013-12-22 22:16:01 +00:00
|
|
|
|
|
|
|
template <typename T>
|
2013-12-22 22:56:11 +00:00
|
|
|
void TextListComponent<T>::setCursor(typename std::vector<ListRow>::const_iterator& it)
|
2013-12-22 22:16:01 +00:00
|
|
|
{
|
|
|
|
assert(it != mRowVector.end());
|
|
|
|
mCursor = it - mRowVector.begin();
|
|
|
|
onCursorChanged(CURSOR_STOPPED);
|
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
template <typename T>
|
2013-11-12 23:28:15 +00:00
|
|
|
void TextListComponent<T>::onCursorChanged(CursorState state)
|
2013-06-02 15:08:32 +00:00
|
|
|
{
|
2013-11-12 23:28:15 +00:00
|
|
|
if(mCursorChangedCallback)
|
|
|
|
mCursorChangedCallback(state);
|
2013-06-02 15:08:32 +00:00
|
|
|
}
|
|
|
|
|
2014-01-01 05:39:22 +00:00
|
|
|
template <typename T>
|
|
|
|
void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties)
|
|
|
|
{
|
|
|
|
GuiComponent::applyTheme(theme, view, element, properties);
|
|
|
|
|
|
|
|
const ThemeData::ThemeElement* elem = theme->getElement(view, element, "textlist");
|
2014-01-03 14:26:39 +00:00
|
|
|
if(!elem)
|
|
|
|
return;
|
2014-01-01 05:39:22 +00:00
|
|
|
|
|
|
|
using namespace ThemeFlags;
|
|
|
|
if(properties & COLOR)
|
|
|
|
{
|
|
|
|
if(elem->has("selectorColor"))
|
|
|
|
setSelectorColor(elem->get<unsigned int>("selectorColor"));
|
|
|
|
if(elem->has("selectedColor"))
|
|
|
|
setSelectedColor(elem->get<unsigned int>("selectedColor"));
|
|
|
|
if(elem->has("primaryColor"))
|
|
|
|
setColor(0, elem->get<unsigned int>("primaryColor"));
|
|
|
|
if(elem->has("secondaryColor"))
|
|
|
|
setColor(1, elem->get<unsigned int>("secondaryColor"));
|
|
|
|
}
|
|
|
|
|
|
|
|
setFont(Font::getFromTheme(elem, properties, mFont));
|
2014-01-03 16:40:36 +00:00
|
|
|
|
|
|
|
if(properties & SOUND && elem->has("scrollSound"))
|
|
|
|
setSound(Sound::get(elem->get<std::string>("scrollSound")));
|
2014-01-10 20:24:07 +00:00
|
|
|
|
2014-01-22 03:10:49 +00:00
|
|
|
if(properties & ALIGNMENT)
|
2014-01-22 02:43:33 +00:00
|
|
|
{
|
2014-01-22 03:10:49 +00:00
|
|
|
if(elem->has("alignment"))
|
|
|
|
{
|
|
|
|
const std::string& str = elem->get<std::string>("alignment");
|
|
|
|
if(str == "left")
|
|
|
|
setAlignment(ALIGN_LEFT);
|
|
|
|
else if(str == "center")
|
|
|
|
setAlignment(ALIGN_CENTER);
|
|
|
|
else if(str == "right")
|
|
|
|
setAlignment(ALIGN_RIGHT);
|
|
|
|
else
|
|
|
|
LOG(LogError) << "Unknown TextListComponent alignment \"" << str << "\"!";
|
|
|
|
}
|
|
|
|
if(elem->has("horizontalMargin"))
|
|
|
|
{
|
|
|
|
mHorizontalMargin = elem->get<float>("horizontalMargin") * (mParent ? mParent->getSize().x() : (float)Renderer::getScreenWidth());
|
|
|
|
}
|
2014-01-22 02:43:33 +00:00
|
|
|
}
|
2014-01-01 05:39:22 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 15:08:32 +00:00
|
|
|
#endif
|