Fix UI rendering
This commit is contained in:
parent
b087ccad1e
commit
bbee789593
@ -32,7 +32,7 @@ static void doUIMouseHover(double x, double y) {
|
||||
UIPoint hoveredAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
|
||||
UIBounds bounds = element->getBounds();
|
||||
if(!bounds.contains(hoveredAt)) continue;
|
||||
if(!bounds.containsOffset(hoveredAt)) continue;
|
||||
|
||||
hoveredElement = element;
|
||||
}
|
||||
@ -58,7 +58,7 @@ static void doUIMouseClick(double x, double y, GLFWMouseButton button) {
|
||||
UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
|
||||
UIBounds bounds = element->getBounds();
|
||||
if(!bounds.contains(clickedAt)) continue;
|
||||
if(!bounds.containsOffset(clickedAt)) continue;
|
||||
|
||||
clickedElement = element;
|
||||
}
|
||||
|
@ -100,6 +100,8 @@ void TextObject::allocateBuffer(TextBlock *block, int numChars) {
|
||||
}
|
||||
|
||||
TextMetrics TextObject::measureChars(std::u32string str, unsigned int offset, unsigned int length, std::map<unsigned int, std::vector<RenderChar>> *chars) {
|
||||
// TODO: returned metrics are incorrect when there are multiple lines of text
|
||||
|
||||
if(offset != 0 || length != str.length()) {
|
||||
length = std::min(length, (unsigned int) (str.length() - offset));
|
||||
str = str.substr(offset, length);
|
||||
|
@ -20,14 +20,20 @@ UIElement::~UIElement() {
|
||||
UI::unfocusElement(this);
|
||||
}
|
||||
|
||||
// Returns the element's position relative to its parent in pixels
|
||||
UIPoint UIElement::getPosition() {
|
||||
// Returns the element's origin position relative to its parent in pixels (not offset by getBounds())
|
||||
UIPoint UIElement::getOriginPosition() {
|
||||
return UIPoint(uiToScreen(x), uiToScreen(y));
|
||||
}
|
||||
|
||||
// Returns the element's position relative to its parent in pixels (offset by getBounds())
|
||||
UIPoint UIElement::getPosition() {
|
||||
UIBounds bounds = getBounds();
|
||||
return UIPoint(uiToScreen(x) + bounds.x, uiToScreen(y) + bounds.y);
|
||||
}
|
||||
|
||||
// Returns the element's origin position on the screen in pixels (not offset by getBounds())
|
||||
UIPoint UIElement::getScreenOriginPosition() {
|
||||
UIPoint pos = getPosition();
|
||||
UIPoint pos = getOriginPosition();
|
||||
if(parent) {
|
||||
UIPoint parentPos = parent->getScreenPosition();
|
||||
pos.x += parentPos.x;
|
||||
@ -119,11 +125,11 @@ UIBounds UIElement::offsetUIBounds(int w, int h, Origin origin) {
|
||||
void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) {
|
||||
if(!visible) return;
|
||||
|
||||
UIBounds bounds = getBounds();
|
||||
|
||||
if(enableClipping) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
UIPoint pos = getScreenPosition();
|
||||
UIBounds bounds = getBounds();
|
||||
glScissor(pos.x, kekData.screenHeight - (pos.y + bounds.h), bounds.w, bounds.h);
|
||||
glScissor(screenPos.x, kekData.screenHeight - (screenPos.y + bounds.h), bounds.w, bounds.h);
|
||||
}
|
||||
|
||||
draw(screenPos, projection);
|
||||
@ -145,7 +151,7 @@ void UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.contains(UIPoint(relX, relY))) continue;
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
hoveredChild = child;
|
||||
}
|
||||
|
||||
@ -179,7 +185,7 @@ bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button)
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.contains(UIPoint(relX, relY))) continue;
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
clickedChild = child;
|
||||
}
|
||||
|
||||
@ -203,7 +209,7 @@ bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.contains(UIPoint(relX, relY))) continue;
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
focusedChild = child;
|
||||
}
|
||||
|
||||
@ -230,7 +236,7 @@ UIElement *UIElement::dragEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.contains(UIPoint(relX, relY))) continue;
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
draggedChild = child;
|
||||
}
|
||||
|
||||
|
@ -39,23 +39,21 @@ UIElementType TextElement::getType() {
|
||||
UIBounds TextElement::getBounds() {
|
||||
TextMetrics metrics = text->getMetrics(sizePixels);
|
||||
|
||||
int w = metrics.width, h, offsetY = 0;
|
||||
int w = metrics.width, h;
|
||||
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);
|
||||
return UIBounds(offsetX(w, origin), 0, w, h);
|
||||
case TextMode::ORIGIN:
|
||||
default:
|
||||
return offsetUIBounds(w, h, origin);
|
||||
@ -71,22 +69,20 @@ std::string TextElement::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);
|
||||
text->getFont()->drawText(text, projection, 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);
|
||||
text->getFont()->drawTextFromOrigin(text, projection, screenPos.x, 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);
|
||||
text->getFont()->drawText(text, projection, screenPos.x, screenPos.y + offsetY, sizePixels, color);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,15 @@ struct UIBounds {
|
||||
w(w),
|
||||
h(h) {}
|
||||
|
||||
// Checks if a point is contained in the bounds
|
||||
inline bool contains(UIPoint pos) {
|
||||
return pos.x > x && pos.y > y && pos.x < x + w && pos.y < y + h;
|
||||
}
|
||||
|
||||
// Checks if an already offset point is contained in the bounds
|
||||
inline bool containsOffset(UIPoint pos) {
|
||||
return pos.x > 0 && pos.y > 0 && pos.x < w && pos.y < h;
|
||||
}
|
||||
};
|
||||
|
||||
enum class UIElementType {
|
||||
@ -149,7 +155,10 @@ class UIElement {
|
||||
|
||||
virtual UIElementType getType() = 0;
|
||||
|
||||
// Returns the element's position relative to its parent in pixels
|
||||
// Returns the element's origin position relative to its parent in pixels (not offset by getBounds())
|
||||
UIPoint getOriginPosition();
|
||||
|
||||
// Returns the element's position relative to its parent in pixels (offset by getBounds())
|
||||
UIPoint getPosition();
|
||||
|
||||
// Returns the element's origin position on the screen in pixels (not offset by getBounds())
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "color.h"
|
||||
#include "input.h"
|
||||
#include "kekengine.h"
|
||||
#include <GL/glew.h>
|
||||
@ -128,7 +129,13 @@ int main(int argc, char **argv) {
|
||||
button3->addChild(rect);
|
||||
UI::addElement(button3);
|
||||
|
||||
TextFieldElement *textField = new TextFieldElement(uiPx(10), uiPx(200), uiPx(500));
|
||||
RectangleElement *rect2 = new RectangleElement(uiPx(0), uiSh(0.5), uiPx(500), uiPx(250));
|
||||
rect2->origin = Origin::LEFT_CENTER;
|
||||
rect2->enableClipping = true;
|
||||
UI::addElement(rect2);
|
||||
|
||||
TextFieldElement *textField = new TextFieldElement(uiPx(0), uiPh(1) - uiPx(10), uiPx(500));
|
||||
textField->origin = kek::Origin::BOTTOM_LEFT;
|
||||
textField->color = Colors::GREEN;
|
||||
textField->focusColor = Colors::RED;
|
||||
textField->textElement->color = Colors::WHITE;
|
||||
@ -152,11 +159,18 @@ int main(int argc, char **argv) {
|
||||
ep->t->onSubmit = SubmitCallback();
|
||||
},
|
||||
&e);
|
||||
UI::addElement(textField);
|
||||
rect2->addChild(textField);
|
||||
|
||||
TextElement *text = new TextElement(uiPx(10), uiPx(260));
|
||||
text->setText("Lorem ipsum\ndolor sit amet\nsussy amogus, KekEngine sample text\nWhen the impostor is\nAmogus");
|
||||
UI::addElement(text);
|
||||
TextElement *text = new TextElement(uiPx(0), uiPx(0));
|
||||
text->setText("Lorem ipsum dolorg");
|
||||
text->textMode = TextMode::ORIGIN;
|
||||
text->textBounds = TextBounds::SMALLEST;
|
||||
|
||||
UIBounds bounds = text->getBounds();
|
||||
RectangleElement *box = new RectangleElement(uiPx(bounds.x), uiPx(bounds.y), uiPx(bounds.w), uiPx(bounds.h));
|
||||
box->color = Colors::GRAY;
|
||||
rect2->addChild(box);
|
||||
rect2->addChild(text);
|
||||
|
||||
if(Engine::start() != KEK_SUCCESS) return 1;
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user