TextComponent.cpp 4.05 KB
Newer Older
Aloshi's avatar
Aloshi committed
1 2 3
#include "TextComponent.h"
#include "../Renderer.h"
#include "../Log.h"
Aloshi's avatar
Aloshi committed
4
#include "../Window.h"
5
#include "../ThemeData.h"
Aloshi's avatar
Aloshi committed
6

7
TextComponent::TextComponent(Window* window) : GuiComponent(window), 
8
	mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true, true), mCentered(false)
Aloshi's avatar
Aloshi committed
9 10 11
{
}

12
TextComponent::TextComponent(Window* window, const std::string& text, std::shared_ptr<Font> font, Eigen::Vector3f pos, Eigen::Vector2f size) : GuiComponent(window), 
13
	mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true, true), mCentered(false)
Aloshi's avatar
Aloshi committed
14 15 16
{
	setText(text);
	setFont(font);
17 18
	setPosition(pos);
	setSize(size);
Aloshi's avatar
Aloshi committed
19 20
}

21
void TextComponent::onSizeChanged()
Aloshi's avatar
Aloshi committed
22
{
23
	mAutoCalcExtent << (getSize().x() == 0), (getSize().y() == 0);
24
	onTextChanged();
Aloshi's avatar
Aloshi committed
25 26
}

Aloshi's avatar
Aloshi committed
27
void TextComponent::setFont(std::shared_ptr<Font> font)
Aloshi's avatar
Aloshi committed
28 29
{
	mFont = font;
30
	onTextChanged();
Aloshi's avatar
Aloshi committed
31 32 33 34 35
}

void TextComponent::setColor(unsigned int color)
{
	mColor = color;
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

	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;
Aloshi's avatar
Aloshi committed
54 55 56 57 58
}

void TextComponent::setText(const std::string& text)
{
	mText = text;
59
	onTextChanged();
60 61
}

62 63 64 65 66
void TextComponent::setCentered(bool center)
{
	mCentered = center;
}

Aloshi's avatar
Aloshi committed
67
std::shared_ptr<Font> TextComponent::getFont() const
68
{
Aloshi's avatar
Aloshi committed
69 70 71
	if(mFont)
		return mFont;
	else
72
		return Font::get(FONT_SIZE_MEDIUM);
Aloshi's avatar
Aloshi committed
73 74
}

75
void TextComponent::render(const Eigen::Affine3f& parentTrans)
Aloshi's avatar
Aloshi committed
76
{
Aloshi's avatar
Aloshi committed
77
	std::shared_ptr<Font> font = getFont();
Aloshi's avatar
Aloshi committed
78

79
	Eigen::Affine3f trans = parentTrans * getTransform();
80 81 82 83 84

	if(font && !mText.empty())
	{
		if(mCentered)
		{
85
			const Eigen::Vector2f& textSize = mTextCache->metrics.size;
86
			Eigen::Vector2f pos((getSize().x() - textSize.x()) / 2, 0);
87 88 89 90

			Eigen::Affine3f centeredTrans = trans;
			centeredTrans = centeredTrans.translate(Eigen::Vector3f(pos.x(), pos.y(), 0));
			Renderer::setMatrix(centeredTrans);
91 92
		}else{
			Renderer::setMatrix(trans);
93
		}
94 95

		font->renderTextCache(mTextCache.get());
96
	}
Aloshi's avatar
Aloshi committed
97

98
	GuiComponent::renderChildren(trans);
Aloshi's avatar
Aloshi committed
99
}
100 101 102

void TextComponent::calculateExtent()
{
Aloshi's avatar
Aloshi committed
103
	std::shared_ptr<Font> font = getFont();
104

105 106 107 108 109 110 111 112 113
	if(mAutoCalcExtent.x())
	{
		mSize = font->sizeText(mText);
	}else{
		if(mAutoCalcExtent.y())
		{
			mSize[1] = font->sizeWrappedText(mText, getSize().x()).y();
		}
	}
114
}
Aloshi's avatar
Aloshi committed
115

116 117 118 119 120
void TextComponent::onTextChanged()
{
	calculateExtent();

	std::shared_ptr<Font> f = getFont();
121 122 123 124 125
	const bool wrap = (mSize.y() == 0 || (int)mSize.y() > f->getHeight());
	Eigen::Vector2f size = f->sizeText(mText);
	if(!wrap && mSize.x() && mText.size() && size.x() > mSize.x())
	{
		// abbreviate text
126
		const std::string abbrev = "...";
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
		Eigen::Vector2f abbrevSize = f->sizeText(abbrev);

		std::string text = mText;
		while(text.size() && size.x() + abbrevSize.x() > mSize.x())
		{
			text.erase(text.size() - 1, 1);
			size = f->sizeText(text);
		}

		text.append(abbrev);

		mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(text, 0, 0, (mColor >> 8 << 8) | mOpacity));
	}else{
		mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(mText, mSize.x()), 0, 0, (mColor >> 8 << 8) | mOpacity));
	}
142 143
}

144 145 146 147 148 149 150 151
void TextComponent::onColorChanged()
{
	if(mTextCache)
	{
		mTextCache->setColor(mColor);
	}
}

Aloshi's avatar
Aloshi committed
152 153 154 155 156 157 158 159 160
void TextComponent::setValue(const std::string& value)
{
	setText(value);
}

std::string TextComponent::getValue() const
{
	return mText;
}
161 162 163 164 165 166 167 168 169 170 171 172 173 174

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"));

175
	if(properties & ALIGNMENT && elem->has("center"))
176 177 178 179 180 181 182
		setCentered(elem->get<bool>("center"));

	if(properties & TEXT && elem->has("text"))
		setText(elem->get<std::string>("text"));

	setFont(Font::getFromTheme(elem, properties, mFont));
}