multiline labels

This commit is contained in:
MihailRis
2024-02-25 21:03:21 +03:00
parent fcc5d11814
commit d189bdc107
7 changed files with 237 additions and 93 deletions
+86 -6
View File
@@ -1,5 +1,7 @@
#include "controls.h"
#include <queue>
#include <sstream>
#include <iostream>
#include "../../window/Events.h"
@@ -30,9 +32,16 @@ Label::Label(std::wstring text, std::string fontName)
void Label::setText(std::wstring text) {
this->text = text;
lines = 1;
for (size_t i = 0; i < text.length(); i++) {
if (text[i] == L'\n') {
lines++;
}
}
lines = std::max(lines, 1U);
}
std::wstring Label::getText() const {
const std::wstring& Label::getText() const {
return text;
}
@@ -44,18 +53,45 @@ const std::string& Label::getFontName() const {
return fontName;
}
void Label::setVerticalAlign(Align align) {
this->valign = align;
}
Align Label::getVerticalAlign() const {
return valign;
}
float Label::getLineInterval() const {
return lineInterval;
}
void Label::setLineInterval(float interval) {
lineInterval = interval;
}
int Label::getTextYOffset() const {
return textYOffset;
}
int Label::getLineYOffset(uint line) const {
return line * totalLineHeight + textYOffset;
}
void Label::draw(const GfxContext* pctx, Assets* assets) {
if (supplier) {
setText(supplier());
}
auto batch = pctx->getBatch2D();
auto font = assets->getFont(fontName);
batch->color = getColor();
Font* font = assets->getFont(fontName);
uint lineHeight = font->getLineHeight();
glm::vec2 size = getSize();
glm::vec2 newsize (
font->calcWidth(text),
font->getLineHeight()+font->getYOffset()
(lines == 1 ? lineHeight : lineHeight*lineInterval)*lines + font->getYOffset()
);
glm::vec2 coord = calcCoord();
@@ -69,14 +105,48 @@ void Label::draw(const GfxContext* pctx, Assets* assets) {
coord.x += size.x-newsize.x;
break;
}
coord.y += (size.y-newsize.y)*0.5f;
font->draw(batch, text, coord.x, coord.y);
switch (valign) {
case Align::top:
break;
case Align::center:
coord.y += (size.y-newsize.y)*0.5f;
break;
case Align::bottom:
coord.y += size.y-newsize.y;
break;
}
textYOffset = coord.y;
totalLineHeight = lineHeight * lineInterval;
if (multiline) {
size_t offset = 0;
for (uint i = 0; i < lines; i++) {
std::wstring_view view(text.c_str()+offset, text.length()-offset);
size_t end = view.find(L'\n');
if (end != std::wstring::npos) {
view = std::wstring_view(text.c_str()+offset, end);
offset += end + 1;
}
font->draw(batch, view, coord.x, coord.y + i * totalLineHeight, FontStyle::none);
}
} else {
font->draw(batch, text, coord.x, coord.y, FontStyle::none);
}
}
void Label::textSupplier(wstringsupplier supplier) {
this->supplier = supplier;
}
void Label::setMultiline(bool multiline) {
this->multiline = multiline;
}
bool Label::isMultiline() const {
return multiline;
}
// ================================= Image ====================================
Image::Image(std::string texture, glm::vec2 size) : UINode(glm::vec2(), size), texture(texture) {
setInteractive(false);
@@ -264,7 +334,7 @@ void TextBox::draw(const GfxContext* pctx, Assets* assets) {
if (!isFocused())
return;
const int yoffset = 2;
const int yoffset = 0;
const int lineHeight = font->getLineHeight();
glm::vec2 lcoord = label->calcCoord();
auto batch = pctx->getBatch2D();
@@ -390,6 +460,16 @@ bool TextBox::isValid() const {
return valid;
}
void TextBox::setMultiline(bool multiline) {
this->multiline = multiline;
label->setMultiline(multiline);
label->setVerticalAlign(multiline ? Align::top : Align::center);
}
bool TextBox::isMultiline() const {
return multiline;
}
void TextBox::setOnEditStart(runnable oneditstart) {
onEditStart = oneditstart;
}