2013-06-14 15:48:13 +00:00
|
|
|
#include "TextComponent.h"
|
|
|
|
#include "../Renderer.h"
|
|
|
|
#include "../Log.h"
|
2013-07-03 07:54:55 +00:00
|
|
|
#include "../Window.h"
|
2013-11-25 20:49:02 +00:00
|
|
|
#include "../ThemeData.h"
|
2014-03-19 20:03:23 +00:00
|
|
|
#include "../Util.h"
|
2014-04-05 17:48:38 +00:00
|
|
|
#include "../Settings.h"
|
2013-06-14 15:48:13 +00:00
|
|
|
|
2013-07-02 05:57:31 +00:00
|
|
|
TextComponent::TextComponent(Window* window) : GuiComponent(window),
|
2014-05-03 19:51:50 +00:00
|
|
|
mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT)
|
2013-06-14 15:48:13 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-03-21 19:51:25 +00:00
|
|
|
TextComponent::TextComponent(Window* window, const std::string& text, const std::shared_ptr<Font>& font, unsigned int color, Alignment align,
|
2014-03-12 03:00:08 +00:00
|
|
|
Eigen::Vector3f pos, Eigen::Vector2f size) : GuiComponent(window),
|
2014-05-03 19:51:50 +00:00
|
|
|
mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align)
|
2013-06-14 15:48:13 +00:00
|
|
|
{
|
2014-03-08 01:35:16 +00:00
|
|
|
setFont(font);
|
2014-03-01 21:02:44 +00:00
|
|
|
setColor(color);
|
2013-06-14 15:48:13 +00:00
|
|
|
setText(text);
|
2013-07-10 11:29:43 +00:00
|
|
|
setPosition(pos);
|
|
|
|
setSize(size);
|
2013-06-14 15:48:13 +00:00
|
|
|
}
|
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
void TextComponent::onSizeChanged()
|
2013-06-14 15:48:13 +00:00
|
|
|
{
|
2013-07-10 11:29:43 +00:00
|
|
|
mAutoCalcExtent << (getSize().x() == 0), (getSize().y() == 0);
|
2013-08-22 01:08:36 +00:00
|
|
|
onTextChanged();
|
2013-06-14 15:48:13 +00:00
|
|
|
}
|
|
|
|
|
2014-03-08 01:35:16 +00:00
|
|
|
void TextComponent::setFont(const std::shared_ptr<Font>& font)
|
2013-06-14 15:48:13 +00:00
|
|
|
{
|
|
|
|
mFont = font;
|
2013-08-22 01:08:36 +00:00
|
|
|
onTextChanged();
|
2013-06-14 15:48:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TextComponent::setColor(unsigned int color)
|
|
|
|
{
|
|
|
|
mColor = color;
|
2013-10-10 21:14:33 +00:00
|
|
|
|
|
|
|
unsigned char opacity = mColor & 0x000000FF;
|
|
|
|
GuiComponent::setOpacity(opacity);
|
|
|
|
|
|
|
|
onColorChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextComponent::setOpacity(unsigned char opacity)
|
|
|
|
{
|
|
|
|
mColor = (mColor & 0xFFFFFF00) | opacity;
|
|
|
|
onColorChanged();
|
|
|
|
|
|
|
|
GuiComponent::setOpacity(opacity);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char TextComponent::getOpacity() const
|
|
|
|
{
|
|
|
|
return mColor & 0x000000FF;
|
2013-06-14 15:48:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TextComponent::setText(const std::string& text)
|
|
|
|
{
|
|
|
|
mText = text;
|
2013-08-22 01:08:36 +00:00
|
|
|
onTextChanged();
|
2013-07-02 05:57:31 +00:00
|
|
|
}
|
|
|
|
|
2014-05-03 19:51:50 +00:00
|
|
|
void TextComponent::setUppercase(bool uppercase)
|
|
|
|
{
|
|
|
|
mUppercase = uppercase;
|
|
|
|
onTextChanged();
|
|
|
|
}
|
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
void TextComponent::render(const Eigen::Affine3f& parentTrans)
|
2013-06-14 15:48:13 +00:00
|
|
|
{
|
2014-03-22 18:04:14 +00:00
|
|
|
Eigen::Affine3f trans = parentTrans * getTransform();
|
2013-07-23 06:27:28 +00:00
|
|
|
|
2014-04-19 21:29:59 +00:00
|
|
|
/*Eigen::Vector3f dim(mSize.x(), mSize.y(), 0);
|
2014-03-12 03:00:08 +00:00
|
|
|
dim = trans * dim - trans.translation();
|
2014-03-22 19:31:13 +00:00
|
|
|
Renderer::pushClipRect(Eigen::Vector2i((int)trans.translation().x(), (int)trans.translation().y()),
|
|
|
|
Eigen::Vector2i((int)(dim.x() + 0.5f), (int)(dim.y() + 0.5f)));
|
2014-04-19 21:29:59 +00:00
|
|
|
*/
|
2014-03-12 03:00:08 +00:00
|
|
|
|
2014-03-08 01:35:16 +00:00
|
|
|
if(mTextCache)
|
2013-07-23 06:27:28 +00:00
|
|
|
{
|
2014-03-21 19:51:25 +00:00
|
|
|
const Eigen::Vector2f& textSize = mTextCache->metrics.size;
|
2014-05-13 01:03:02 +00:00
|
|
|
Eigen::Vector3f off(0, (getSize().y() - textSize.y()) / 2.0f, 0);
|
2013-08-22 20:29:50 +00:00
|
|
|
|
2014-04-05 17:48:38 +00:00
|
|
|
if(Settings::getInstance()->getBool("DebugText"))
|
|
|
|
{
|
|
|
|
// draw the "textbox" area, what we are aligned within
|
|
|
|
Renderer::setMatrix(trans);
|
|
|
|
Renderer::drawRect(0.f, 0.f, mSize.x(), mSize.y(), 0xFF000033);
|
|
|
|
}
|
|
|
|
|
2014-03-21 19:51:25 +00:00
|
|
|
trans.translate(off);
|
2014-03-22 18:04:14 +00:00
|
|
|
trans = roundMatrix(trans);
|
2014-03-21 19:51:25 +00:00
|
|
|
Renderer::setMatrix(trans);
|
2014-04-05 17:48:38 +00:00
|
|
|
|
|
|
|
// draw the text area, where the text actually is going
|
|
|
|
if(Settings::getInstance()->getBool("DebugText"))
|
2014-05-13 01:03:02 +00:00
|
|
|
{
|
|
|
|
switch(mAlignment)
|
|
|
|
{
|
|
|
|
case ALIGN_LEFT:
|
|
|
|
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
|
|
|
|
break;
|
|
|
|
case ALIGN_CENTER:
|
|
|
|
Renderer::drawRect((mSize.x() - mTextCache->metrics.size.x()) / 2.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
|
|
|
|
break;
|
|
|
|
case ALIGN_RIGHT:
|
|
|
|
Renderer::drawRect(mSize.x() - mTextCache->metrics.size.x(), 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-04-05 17:48:38 +00:00
|
|
|
|
2014-03-08 01:35:16 +00:00
|
|
|
mFont->renderTextCache(mTextCache.get());
|
2013-07-23 06:27:28 +00:00
|
|
|
}
|
2013-06-14 15:48:13 +00:00
|
|
|
|
2014-04-19 21:29:59 +00:00
|
|
|
//Renderer::popClipRect();
|
2013-06-14 15:48:13 +00:00
|
|
|
}
|
2013-06-19 01:12:30 +00:00
|
|
|
|
|
|
|
void TextComponent::calculateExtent()
|
|
|
|
{
|
2013-07-10 11:29:43 +00:00
|
|
|
if(mAutoCalcExtent.x())
|
|
|
|
{
|
2014-05-03 19:51:50 +00:00
|
|
|
mSize = mFont->sizeText(mUppercase ? strToUpper(mText) : mText);
|
2013-07-10 11:29:43 +00:00
|
|
|
}else{
|
|
|
|
if(mAutoCalcExtent.y())
|
|
|
|
{
|
2014-05-03 19:51:50 +00:00
|
|
|
mSize[1] = mFont->sizeWrappedText(mUppercase ? strToUpper(mText) : mText, getSize().x()).y();
|
2013-07-10 11:29:43 +00:00
|
|
|
}
|
|
|
|
}
|
2013-07-02 05:57:31 +00:00
|
|
|
}
|
2013-08-14 12:16:49 +00:00
|
|
|
|
2013-08-22 01:08:36 +00:00
|
|
|
void TextComponent::onTextChanged()
|
|
|
|
{
|
|
|
|
calculateExtent();
|
|
|
|
|
2014-05-03 19:51:50 +00:00
|
|
|
std::string text = mUppercase ? strToUpper(mText) : mText;
|
|
|
|
|
2013-08-22 01:08:36 +00:00
|
|
|
std::shared_ptr<Font> f = getFont();
|
2014-05-13 01:03:02 +00:00
|
|
|
const bool wrap = (mSize.y() == 0 || mSize.y() > f->getHeight()*1.2f);
|
2014-05-03 19:51:50 +00:00
|
|
|
Eigen::Vector2f size = f->sizeText(text);
|
|
|
|
if(!wrap && mSize.x() && text.size() && size.x() > mSize.x())
|
2014-01-19 23:22:26 +00:00
|
|
|
{
|
|
|
|
// abbreviate text
|
2014-01-23 21:30:32 +00:00
|
|
|
const std::string abbrev = "...";
|
2014-01-19 23:22:26 +00:00
|
|
|
Eigen::Vector2f abbrevSize = f->sizeText(abbrev);
|
|
|
|
|
|
|
|
while(text.size() && size.x() + abbrevSize.x() > mSize.x())
|
|
|
|
{
|
|
|
|
text.erase(text.size() - 1, 1);
|
|
|
|
size = f->sizeText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
text.append(abbrev);
|
|
|
|
|
2014-05-13 01:03:02 +00:00
|
|
|
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(text, Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mAlignment));
|
2014-01-19 23:22:26 +00:00
|
|
|
}else{
|
2014-05-13 01:03:02 +00:00
|
|
|
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(text, mSize.x()), Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mAlignment));
|
2014-01-19 23:22:26 +00:00
|
|
|
}
|
2013-08-22 01:08:36 +00:00
|
|
|
}
|
|
|
|
|
2013-10-10 21:14:33 +00:00
|
|
|
void TextComponent::onColorChanged()
|
|
|
|
{
|
|
|
|
if(mTextCache)
|
|
|
|
{
|
|
|
|
mTextCache->setColor(mColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-14 12:16:49 +00:00
|
|
|
void TextComponent::setValue(const std::string& value)
|
|
|
|
{
|
|
|
|
setText(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TextComponent::getValue() const
|
|
|
|
{
|
|
|
|
return mText;
|
|
|
|
}
|
2014-01-01 05:39:22 +00:00
|
|
|
|
|
|
|
void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties)
|
|
|
|
{
|
|
|
|
GuiComponent::applyTheme(theme, view, element, properties);
|
|
|
|
|
|
|
|
using namespace ThemeFlags;
|
|
|
|
|
|
|
|
const ThemeData::ThemeElement* elem = theme->getElement(view, element, "text");
|
|
|
|
if(!elem)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(properties & COLOR && elem->has("color"))
|
|
|
|
setColor(elem->get<unsigned int>("color"));
|
|
|
|
|
2014-03-21 19:51:25 +00:00
|
|
|
if(properties & ALIGNMENT && elem->has("alignment"))
|
|
|
|
{
|
|
|
|
std::string str = elem->get<std::string>("alignment");
|
|
|
|
if(str == "left")
|
|
|
|
setAlignment(ALIGN_LEFT);
|
|
|
|
else if(str == "center")
|
|
|
|
setAlignment(ALIGN_CENTER);
|
2014-04-05 17:48:38 +00:00
|
|
|
else if(str == "right")
|
2014-03-21 19:51:25 +00:00
|
|
|
setAlignment(ALIGN_RIGHT);
|
|
|
|
else
|
|
|
|
LOG(LogError) << "Unknown text alignment string: " << str;
|
|
|
|
}
|
2014-01-01 05:39:22 +00:00
|
|
|
|
|
|
|
if(properties & TEXT && elem->has("text"))
|
|
|
|
setText(elem->get<std::string>("text"));
|
|
|
|
|
2014-05-03 19:51:50 +00:00
|
|
|
if(properties & FORCE_UPPERCASE && elem->has("forceUppercase"))
|
|
|
|
setUppercase(elem->get<bool>("forceUppercase"));
|
|
|
|
|
2014-01-01 05:39:22 +00:00
|
|
|
setFont(Font::getFromTheme(elem, properties, mFont));
|
|
|
|
}
|