RatingComponent.cpp 3.86 KB
Newer Older
Aloshi's avatar
Aloshi committed
1 2 3
#include "RatingComponent.h"
#include "../Renderer.h"
#include "../Window.h"
4
#include "../Util.h"
Aloshi's avatar
Aloshi committed
5
#include "../resources/SVGResource.h"
Aloshi's avatar
Aloshi committed
6 7 8

RatingComponent::RatingComponent(Window* window) : GuiComponent(window)
{
Aloshi's avatar
Aloshi committed
9 10
	mFilledTexture = TextureResource::get(":/star_filled.svg", true);
	mUnfilledTexture = TextureResource::get(":/star_unfilled.svg", true);
Aloshi's avatar
Aloshi committed
11 12 13 14 15 16 17
	mValue = 0.5f;
	mSize << 64 * 5.0f, 64;
	updateVertices();
}

void RatingComponent::setValue(const std::string& value)
{
18 19 20 21 22 23
	if(value.empty())
	{
		mValue = 0.0f;
		return;
	}

Aloshi's avatar
Aloshi committed
24
	mValue = stof(value);
Aloshi's avatar
Aloshi committed
25 26 27 28
	if(mValue > 1.0f)
		mValue = 1.0f;
	else if(mValue < 0.0f)
		mValue = 0.0f;
Aloshi's avatar
Aloshi committed
29 30 31 32 33
	updateVertices();
}

std::string RatingComponent::getValue() const
{
Aloshi's avatar
Aloshi committed
34
	return std::to_string((long double)mValue);
Aloshi's avatar
Aloshi committed
35 36 37 38
}

void RatingComponent::onSizeChanged()
{
39 40 41 42 43
	if(mSize.y() == 0)
		mSize[1] = mSize.x() / 5.0f;
	else if(mSize.x() == 0)
		mSize[0] = mSize.y() * 5.0f;

Aloshi's avatar
Aloshi committed
44 45 46 47 48 49 50 51 52
	auto filledSVG = dynamic_cast<SVGResource*>(mFilledTexture.get());
	auto unfilledSVG = dynamic_cast<SVGResource*>(mUnfilledTexture.get());

	size_t sz = (size_t)round(mSize.y());
	if(filledSVG)
		filledSVG->rasterizeAt(sz, sz);
	if(unfilledSVG)
		unfilledSVG->rasterizeAt(sz, sz);

Aloshi's avatar
Aloshi committed
53 54 55 56 57 58 59
	updateVertices();
}

void RatingComponent::updateVertices()
{
	const float numStars = 5.0f;

Aloshi's avatar
Aloshi committed
60 61 62
	const float h = getSize().y();
	const float w = h * mValue * numStars;
	const float fw = h * numStars;
Aloshi's avatar
Aloshi committed
63

Aloshi's avatar
Aloshi committed
64 65
	mVertices[0].pos << 0.0f, 0.0f;
		mVertices[0].tex << 0.0f, 1.0f;
Aloshi's avatar
Aloshi committed
66
	mVertices[1].pos << w, h;
Aloshi's avatar
Aloshi committed
67 68 69
		mVertices[1].tex << mValue * numStars, 0.0f;
	mVertices[2].pos << 0.0f, h;
		mVertices[2].tex << 0.0f, 0.0f;
Aloshi's avatar
Aloshi committed
70 71

	mVertices[3] = mVertices[0];
Aloshi's avatar
Aloshi committed
72 73
	mVertices[4].pos << w, 0.0f;
		mVertices[4].tex << mValue * numStars, 1.0f;
Aloshi's avatar
Aloshi committed
74 75 76 77
	mVertices[5] = mVertices[1];

	mVertices[6] = mVertices[4];
	mVertices[7].pos << fw, h;
Aloshi's avatar
Aloshi committed
78
		mVertices[7].tex << numStars, 0.0f;
Aloshi's avatar
Aloshi committed
79 80 81
	mVertices[8] = mVertices[1];

	mVertices[9] = mVertices[6];
Aloshi's avatar
Aloshi committed
82 83
	mVertices[10].pos << fw, 0.0f;
		mVertices[10].tex << numStars, 1.0f;
Aloshi's avatar
Aloshi committed
84
	mVertices[11] = mVertices[7];
85 86 87

	for(int i = 0; i < 12; i++)
		mVertices[i].pos = roundVector(mVertices[i].pos);
Aloshi's avatar
Aloshi committed
88 89 90 91
}

void RatingComponent::render(const Eigen::Affine3f& parentTrans)
{
92
	Eigen::Affine3f trans = roundMatrix(parentTrans * getTransform());
Aloshi's avatar
Aloshi committed
93 94 95 96 97 98
	Renderer::setMatrix(trans);

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

99 100
	glColor4ub(255, 255, 255, getOpacity());

Aloshi's avatar
Aloshi committed
101 102
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Aloshi's avatar
Aloshi committed
103
	
Aloshi's avatar
Aloshi committed
104 105
	glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos);
	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex);
Aloshi's avatar
Aloshi committed
106
	
Aloshi's avatar
Aloshi committed
107 108 109 110 111 112 113 114
	mFilledTexture->bind();
	glDrawArrays(GL_TRIANGLES, 0, 6);

	mUnfilledTexture->bind();
	glDrawArrays(GL_TRIANGLES, 6, 6);

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Aloshi's avatar
Aloshi committed
115
	
Aloshi's avatar
Aloshi committed
116 117 118
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);

119 120
	glColor4ub(255, 255, 255, 255);

Aloshi's avatar
Aloshi committed
121 122 123
	renderChildren(trans);
}

124 125 126 127 128 129 130 131 132 133 134 135 136
bool RatingComponent::input(InputConfig* config, Input input)
{
	if(config->isMappedTo("a", input) && input.value != 0)
	{
		mValue += 0.2f;
		if(mValue > 1.0f)
			mValue = 0.0f;

		updateVertices();
	}

	return GuiComponent::input(config, input);
}
Aloshi's avatar
Aloshi committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152

void RatingComponent::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, "rating");
	if(!elem)
		return;

	if(properties & PATH && elem->has("filledPath"))
		mFilledTexture = TextureResource::get(elem->get<std::string>("filledPath"), true);
	if(properties & PATH && elem->has("unfilledPath"))
		mUnfilledTexture = TextureResource::get(elem->get<std::string>("unfilledPath"), true);
}
Aloshi's avatar
Aloshi committed
153 154 155 156 157 158 159

std::vector<HelpPrompt> RatingComponent::getHelpPrompts()
{
	std::vector<HelpPrompt> prompts;
	prompts.push_back(HelpPrompt("a", "+1 star"));
	return prompts;
}