193 lines
4.7 KiB
C++
193 lines
4.7 KiB
C++
#include "uielements.h"
|
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
#include "internal.h"
|
|
#include "internal/ui.h"
|
|
|
|
namespace kek {
|
|
|
|
TextElement::TextElement(UIValue x, UIValue y, Font *font)
|
|
: UIElement(x, y) {
|
|
this->text = new TextObject(font, "Text");
|
|
this->sizePixels = KEK_DEFAULT_FONT_SIZE_PIXELS;
|
|
this->color = Colors::WHITE;
|
|
this->textMode = TextMode::ORIGIN;
|
|
this->textBounds = TextBounds::SMALLEST;
|
|
}
|
|
|
|
TextElement::TextElement(UIValue x, UIValue y)
|
|
: TextElement(x, y, kekData.ui->defaultFont) {}
|
|
|
|
TextElement::~TextElement() {
|
|
delete text;
|
|
}
|
|
|
|
UIElementType TextElement::getType() {
|
|
return UIElementType::TEXT;
|
|
}
|
|
|
|
UIBounds TextElement::getBounds() {
|
|
TextMetrics metrics = text->getMetrics(sizePixels);
|
|
|
|
int w = metrics.width, h, offsetY = 0;
|
|
switch(textBounds) {
|
|
case TextBounds::SMALLEST:
|
|
default:
|
|
h = metrics.height;
|
|
offsetY = metrics.offsetY;
|
|
break;
|
|
case TextBounds::LINE:
|
|
FontMetrics metrics = text->getFont()->getMetrics(sizePixels);
|
|
h = metrics.lineHeight;
|
|
offsetY = metrics.ascender;
|
|
break;
|
|
}
|
|
|
|
switch(textMode) {
|
|
case TextMode::BASELINE:
|
|
return UIBounds(offsetX(w, origin), -offsetY, w, h);
|
|
case TextMode::ORIGIN:
|
|
default:
|
|
return offsetUIBounds(w, h, origin);
|
|
}
|
|
}
|
|
|
|
void TextElement::setText(std::string text) {
|
|
this->text->setText(text);
|
|
}
|
|
|
|
std::string TextElement::getText() {
|
|
return text->getText();
|
|
}
|
|
|
|
void TextElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
|
UIBounds offset = getBounds();
|
|
|
|
switch(textMode) {
|
|
case TextMode::BASELINE:
|
|
text->getFont()->drawText(text, projection, offset.x + screenPos.x, screenPos.y, sizePixels, color);
|
|
break;
|
|
case TextMode::ORIGIN:
|
|
switch(textBounds) {
|
|
case TextBounds::SMALLEST:
|
|
default:
|
|
text->getFont()->drawTextFromOrigin(text, projection, offset.x + screenPos.x, offset.y + screenPos.y, sizePixels, color);
|
|
break;
|
|
case TextBounds::LINE:
|
|
FontMetrics metrics = text->getFont()->getMetrics(sizePixels);
|
|
int offsetY = metrics.ascender;
|
|
text->getFont()->drawText(text, projection, offset.x + screenPos.x, offset.y + screenPos.y + offsetY, sizePixels, color);
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
UIWindow::UIWindow(UIValue x, UIValue y)
|
|
: UIElement(x, y) {
|
|
addChild(new TextElement(x, y));
|
|
}
|
|
|
|
UIWindow::~UIWindow() {
|
|
}
|
|
|
|
UIElementType UIWindow::getType() {
|
|
return UIElementType::WINDOW;
|
|
}
|
|
|
|
void UIWindow::draw(UIPoint screenPos, glm::mat4 projection) {
|
|
}
|
|
|
|
static float rectangleVerts[] = {
|
|
0.0f,
|
|
1.0f,
|
|
1.0f,
|
|
1.0f,
|
|
1.0f,
|
|
0.0f,
|
|
1.0f,
|
|
0.0f,
|
|
0.0f,
|
|
0.0f,
|
|
0.0f,
|
|
1.0f,
|
|
};
|
|
|
|
RectangleElement::RectangleElement(UIValue x, UIValue y, UIValue w, UIValue h)
|
|
: UIElement(x, y) {
|
|
this->w = w;
|
|
this->h = h;
|
|
color = Colors::BLACK;
|
|
|
|
glCreateVertexArrays(1, &vao);
|
|
glCreateBuffers(1, &vbo);
|
|
|
|
glNamedBufferData(vbo, sizeof(rectangleVerts), rectangleVerts, GL_STATIC_DRAW);
|
|
|
|
glVertexArrayVertexBuffer(vao, KEK_UI_VERTEX_BUFFER_BINDING, vbo, 0, 2 * sizeof(float));
|
|
|
|
glEnableVertexArrayAttrib(vao, KEK_UI_RECT_VERTEX_SHADER_IN_POSITION);
|
|
glVertexArrayAttribFormat(vao, KEK_UI_RECT_VERTEX_SHADER_IN_POSITION, 2, GL_FLOAT, GL_FALSE, 0);
|
|
glVertexArrayAttribBinding(vao, KEK_UI_RECT_VERTEX_SHADER_IN_POSITION, KEK_UI_VERTEX_BUFFER_BINDING);
|
|
}
|
|
|
|
RectangleElement::~RectangleElement() {
|
|
glDeleteVertexArrays(1, &vao);
|
|
glDeleteBuffers(1, &vbo);
|
|
}
|
|
|
|
UIElementType RectangleElement::getType() {
|
|
return UIElementType::RECTANGLE;
|
|
}
|
|
|
|
UIBounds RectangleElement::getBounds() {
|
|
return offsetUIBounds(uiToScreen(w), uiToScreen(h), origin);
|
|
}
|
|
|
|
void RectangleElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
|
kekData.ui->rectangleShader->use();
|
|
|
|
UIBounds offset = getBounds();
|
|
|
|
glUniformMatrix4fv(glGetUniformLocation(kekData.ui->rectangleShader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
|
glm::vec4 bounds = glm::vec4(screenPos.x, screenPos.y, offset.w, offset.h);
|
|
glUniform4fv(glGetUniformLocation(kekData.ui->rectangleShader->id, "bounds"), 1, glm::value_ptr(bounds));
|
|
glUniform4fv(glGetUniformLocation(kekData.ui->rectangleShader->id, "rectColor"), 1, color.valuePointer());
|
|
|
|
glBindVertexArray(vao);
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
}
|
|
|
|
ButtonElement::ButtonElement(UIValue x, UIValue y, UIValue w, UIValue h)
|
|
: RectangleElement(x, y, w, h) {
|
|
clickable = true;
|
|
|
|
color = Colors::CYAN;
|
|
hoverColor = Colors::CYAN.darker();
|
|
|
|
text = new TextElement(uiPw(0.5), uiPh(0.5));
|
|
text->origin = Origin::CENTER;
|
|
addChild(text);
|
|
}
|
|
|
|
ButtonElement::~ButtonElement() {
|
|
delete text;
|
|
}
|
|
|
|
UIElementType ButtonElement::getType() {
|
|
return UIElementType::BUTTON;
|
|
}
|
|
|
|
void ButtonElement::click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
|
|
onClick();
|
|
}
|
|
|
|
void ButtonElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
|
RectangleElement::color = hovering ? hoverColor : color;
|
|
RectangleElement::draw(screenPos, projection);
|
|
}
|
|
|
|
}
|