textbox vertical alignment fix
This commit is contained in:
@@ -64,6 +64,17 @@ void gui::Label::setTextOffset(glm::vec2 offset) {
|
|||||||
textOffset = offset;
|
textOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float gui::Label::getVerticalAlignmentOffset() const {
|
||||||
|
switch (valign) {
|
||||||
|
case gui::Align::center:
|
||||||
|
return (totalLineHeight * lines - size.y) / 2.f;
|
||||||
|
case gui::Align::bottom:
|
||||||
|
return totalLineHeight * lines - size.y;
|
||||||
|
default:
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec2 gui::Label::getTextOffset() const {
|
glm::vec2 gui::Label::getTextOffset() const {
|
||||||
return textOffset;
|
return textOffset;
|
||||||
}
|
}
|
||||||
@@ -95,14 +106,11 @@ size_t Label::getTextLineOffset(uint line) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Label::getLineYOffset(uint line) const {
|
int Label::getLineYOffset(uint line) const {
|
||||||
return line * totalLineHeight + textOffset.y;
|
return line * totalLineHeight + textOffset.y - getVerticalAlignmentOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Label::getLineByYOffset(int offset) const {
|
uint Label::getLineByYOffset(int offset) const {
|
||||||
if (offset < textOffset.y) {
|
return std::clamp((offset - textOffset.y + getVerticalAlignmentOffset()) / totalLineHeight, 0.f, (float)lines);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (offset - textOffset.y) / totalLineHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Label::getLineByTextIndex(size_t index) const {
|
uint Label::getLineByTextIndex(size_t index) const {
|
||||||
@@ -158,10 +166,10 @@ void Label::draw(const GfxContext* pctx, Assets* assets) {
|
|||||||
case Align::top:
|
case Align::top:
|
||||||
break;
|
break;
|
||||||
case Align::center:
|
case Align::center:
|
||||||
pos.y += (size.y-newsize.y)*0.5f;
|
pos.y += (size.y-newsize.y)*0.5f + (lines == 1 ? -lineInterval : lineInterval * 2.f);
|
||||||
break;
|
break;
|
||||||
case Align::bottom:
|
case Align::bottom:
|
||||||
pos.y += size.y-newsize.y;
|
pos.y += size.y-newsize.y + (lines == 1 ? 0 : lineHeight / 2.f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,12 +502,14 @@ void TextBox::paste(const std::wstring& text) {
|
|||||||
/// @param length length of part that will be removed
|
/// @param length length of part that will be removed
|
||||||
void TextBox::erase(size_t start, size_t length) {
|
void TextBox::erase(size_t start, size_t length) {
|
||||||
size_t end = start + length;
|
size_t end = start + length;
|
||||||
if (caret > start) {
|
|
||||||
setCaret(caret - length);
|
|
||||||
}
|
|
||||||
auto left = input.substr(0, start);
|
auto left = input.substr(0, start);
|
||||||
auto right = input.substr(end);
|
auto right = input.substr(end);
|
||||||
|
|
||||||
input = left + right;
|
input = left + right;
|
||||||
|
|
||||||
|
label->setText(input);
|
||||||
|
setCaret(start);
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,7 +568,7 @@ void TextBox::setValid(bool valid) {
|
|||||||
bool TextBox::isValid() const {
|
bool TextBox::isValid() const {
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::setMultiline(bool multiline) {
|
void TextBox::setMultiline(bool multiline) {
|
||||||
this->multiline = scrollable = multiline;
|
this->multiline = scrollable = multiline;
|
||||||
label->setMultiline(multiline);
|
label->setMultiline(multiline);
|
||||||
@@ -634,7 +644,10 @@ void gui::TextBox::scrolled(int value) {
|
|||||||
if (!scrollable || font == nullptr) return;
|
if (!scrollable || font == nullptr) return;
|
||||||
float lineHeight = font->getLineHeight() * label->getLineInterval();
|
float lineHeight = font->getLineHeight() * label->getLineInterval();
|
||||||
glm::vec2 offset = label->getTextOffset();
|
glm::vec2 offset = label->getTextOffset();
|
||||||
offset.y = std::clamp(offset.y + value * lineHeight, -std::max(lineHeight * label->getLinesNumber() - label->getSize().y, 0.f), 0.f);
|
float alignmentOffset = std::max(0.f, label->getVerticalAlignmentOffset());
|
||||||
|
offset.y = std::clamp(offset.y + value * lineHeight,
|
||||||
|
-std::max(lineHeight * label->getLinesNumber() - label->getSize().y - alignmentOffset, 0.f), // min (scroll down)
|
||||||
|
alignmentOffset); // max (scroll up)
|
||||||
label->setTextOffset(offset);
|
label->setTextOffset(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -856,16 +869,18 @@ void TextBox::setCaret(uint position) {
|
|||||||
|
|
||||||
int width = label->getSize().x;
|
int width = label->getSize().x;
|
||||||
uint line = label->getLineByTextIndex(caret);
|
uint line = label->getLineByTextIndex(caret);
|
||||||
int offset = label->getLineYOffset(line);
|
|
||||||
uint lineHeight = font->getLineHeight()*label->getLineInterval();
|
|
||||||
glm::vec2 textOffset = label->getTextOffset();
|
glm::vec2 textOffset = label->getTextOffset();
|
||||||
|
|
||||||
if (offset >= label->getSize().y) {
|
if (scrollable){
|
||||||
label->setTextOffset(glm::vec2(textOffset.x, std::min(0.f, textOffset.y - lineHeight)));
|
int offset = label->getLineYOffset(line);
|
||||||
} else if (offset < 0) {
|
uint lineHeight = font->getLineHeight()*label->getLineInterval();
|
||||||
label->setTextOffset(glm::vec2(textOffset.x, std::min(0.f, textOffset.y + lineHeight)));
|
if (offset >= label->getSize().y - lineHeight) { // scroll down
|
||||||
|
label->setTextOffset(glm::vec2(textOffset.x, std::min(0.f, textOffset.y - (offset - label->getSize().y) - lineHeight)));
|
||||||
|
} else if (offset < 0.f) { // scroll up
|
||||||
|
label->setTextOffset(glm::vec2(textOffset.x, std::min(std::max(0.f, label->getVerticalAlignmentOffset()), textOffset.y - offset + lineHeight)));
|
||||||
|
}
|
||||||
|
textOffset = label->getTextOffset();
|
||||||
}
|
}
|
||||||
textOffset = label->getTextOffset();
|
|
||||||
uint lcaret = caret - label->getTextLineOffset(line);
|
uint lcaret = caret - label->getTextLineOffset(line);
|
||||||
int realoffset = font->calcWidth(input, lcaret)+textOffset.x+2;
|
int realoffset = font->calcWidth(input, lcaret)+textOffset.x+2;
|
||||||
if (realoffset > width) {
|
if (realoffset > width) {
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ namespace gui {
|
|||||||
|
|
||||||
virtual void setTextOffset(glm::vec2 offset);
|
virtual void setTextOffset(glm::vec2 offset);
|
||||||
|
|
||||||
|
/// @return the difference between the height of the text
|
||||||
|
// and the height of the label depending on the alignment
|
||||||
|
virtual float getVerticalAlignmentOffset() const;
|
||||||
|
|
||||||
/// @brief Get position of the text relative to label position
|
/// @brief Get position of the text relative to label position
|
||||||
/// @return offset
|
/// @return offset
|
||||||
virtual glm::vec2 getTextOffset() const;
|
virtual glm::vec2 getTextOffset() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user