36 using std::string_view;
67 GUIStyledTextNode::GUIStyledTextNode(
75 const string& backgroundImage,
77 const GUIColor& backgroundImageEffectColorMul,
78 const GUIColor& backgroundImageEffectColorAdd,
83 const string& tooltip,
91 GUINode(screenNode, parentNode, id, flow, alignments, requestedConstraints, backgroundColor, backgroundImage, backgroundImageScale9Grid, backgroundImageEffectColorMul, backgroundImageEffectColorAdd, border, padding, showOn, hideOn, tooltip)
110 if (this->font !=
nullptr) this->font->initialize();
138 auto adaptNextStyles =
false;
139 for (
auto i = 0; i <
styles.size(); i++) {
142 if (adaptNextStyles ==
true) {
143 style.startIdx-= count;
144 style.endIdx-= count;
145 if (style.startIdx < 0 && style.endIdx < 0) {
150 if (style.startIdx < 0) style.startIdx = 0;
151 if (style.endIdx < 0) style.endIdx = 0;
154 if (idx < style.startIdx) {
155 style.startIdx-= count;
156 style.endIdx-= count;
157 if (style.startIdx < 0 && style.endIdx < 0) {
162 if (style.startIdx < 0) style.startIdx = 0;
163 if (style.endIdx < 0) style.endIdx = 0;
164 adaptNextStyles =
true;
167 if (idx <= style.endIdx) {
169 style.endIdx-= count;
170 if (style.endIdx < 0) {
175 if (style.endIdx < 0) style.endIdx = 0;
176 adaptNextStyles =
true;
189 auto s = Character::toString(c);
192 auto count = s.size();
193 auto adaptNextStyles =
false;
194 for (
auto& style:
styles) {
196 if (adaptNextStyles ==
true) {
197 style.startIdx+= count;
198 style.endIdx+= count;
201 if (idx < style.startIdx) {
202 style.startIdx+= count;
203 style.endIdx+= count;
204 adaptNextStyles =
true;
207 if (idx <= style.endIdx) {
209 style.endIdx+= count;
210 adaptNextStyles =
true;
226 auto count = s.size();
227 auto adaptNextStyles =
false;
228 for (
auto& style:
styles) {
230 if (adaptNextStyles ==
true) {
231 style.startIdx+= count;
232 style.endIdx+= count;
235 if (idx < style.startIdx) {
236 style.startIdx+= count;
237 style.endIdx+= count;
238 adaptNextStyles =
true;
241 if (idx <= style.endIdx) {
243 style.endIdx+= count;
244 adaptNextStyles =
true;
258 if (
font ==
nullptr)
return;
263 auto textStyleIdx = 0;
265 while (u8It.hasNext() ==
true) {
271 y+= lineConstraintsEntity.height;
275 auto reachedCursorIndex =
false;
277 if (idx == cursorIndex) {
278 reachedCursorIndex =
true;
282 if (reachedCursorIndex ==
true)
break;
298 if (renderOffsetY > yBefore) {
312 if (
font ==
nullptr)
return;
315 auto styledTextController = required_dynamic_cast<GUIStyledTextNodeController*>(
getController());
321 if (
font ==
nullptr)
return;
324 auto styledTextController = required_dynamic_cast<GUIStyledTextNodeController*>(
getController());
333 if (
font ==
nullptr)
return -1;
336 auto styledTextController = required_dynamic_cast<GUIStyledTextNodeController*>(
getController());
337 auto cursorIndex = styledTextController->getIndex();
340 auto textStyleIdx = 0;
341 auto reachedCursorIndex =
false;
353 vector<LineInfo> lines;
355 while (u8It.hasNext() ==
true) {
360 if (reachedCursorIndex ==
false) {
362 if (idx == cursorIndex) {
363 reachedCursorIndex =
true;
375 y+= lineConstraintsEntity.height;
385 if (reachedCursorIndex ==
true)
break;
396 for (
int i = lines.size() - 1; i >= 0; i--) {
397 const auto&
line = lines[i];
398 if (y -
line.y >= visibleHeight) {
412 if (
font ==
nullptr)
return -1;
415 auto styledTextController = required_dynamic_cast<GUIStyledTextNodeController*>(
getController());
416 auto cursorIndex = styledTextController->getIndex();
419 auto textStyleIdx = 0;
420 auto reachedCursorIndex =
false;
421 auto finished =
false;
423 while (u8It.hasNext() ==
true) {
428 if (reachedCursorIndex ==
false) {
430 if (idx == cursorIndex) {
431 reachedCursorIndex =
true;
436 if (reachedCursorIndex ==
true) {
442 if (reachedCursorIndex ==
true) {
444 y+= lineConstraintsEntity.height;
445 if (y >= visibleHeight) {
460 if (finished ==
true)
break;
471 if (finished ==
true) {
474 return u8It.getCharacterPosition() - 1;
511 if (
font ==
nullptr)
return;
518 auto textStyleIdx = 0;
520 while (u8It.hasNext() ==
true) {
569 int styleSize =
size;
574 auto parseStyle =
false;
575 auto parseImage =
false;
577 int imageHeight = -1;
578 float imageHorizontalScale = 1.0f;
579 float imageVerticalScale = 1.0f;
583 int styleStartIdx = -1;
585 for (
auto i = 0; i <
text.
size(); i++) {
587 if (parseStyle ==
true) {
591 auto styleTokenized = StringTools::tokenize(currentStyle,
"=");
593 if (styleStartIdx != -1 &&
594 (styleFont.empty() ==
false ||
595 styleColor.empty() ==
false ||
596 styleUrl.empty() ==
false)) {
597 if (styleColor.empty() ==
false) {
598 if (this->text.
size() > styleStartIdx)
setTextStyle(styleStartIdx, this->text.
size() - 1,
GUIColor(styleColor), styleFont, styleSize, styleUrl);
600 if (this->text.
size() > styleStartIdx)
setTextStyle(styleStartIdx, this->text.
size() - 1, styleFont, styleSize, styleUrl);
603 if (styleTokenized.size() == 2) {
604 auto command = StringTools::toLowerCase(StringTools::trim(styleTokenized[0]));
605 auto argument = StringTools::trim(styleTokenized[1]);
606 if (command ==
"font") {
607 styleFont = argument;
608 styleStartIdx = this->text.
size();
610 if (command ==
"size") {
612 styleSize = Integer::parse(argument);
614 Console::println(
"GUIStyledTextNode::setText(): size: unknown value: " + argument);
616 styleStartIdx = this->text.
size();
618 if (command ==
"color") {
619 styleColor = argument;
620 styleStartIdx = this->text.
size();
622 if (command ==
"url") {
624 styleStartIdx = this->text.
size();
626 if (command ==
"image") {
628 auto imageOptions = StringTools::tokenize(styleTokenized[1],
",");
629 for (
const auto& imageOption: imageOptions) {
630 auto nameValuePair = StringTools::tokenize(imageOption,
":");
631 if (nameValuePair.size() != 2) {
632 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: " + imageOption);
634 auto name = StringTools::trim(nameValuePair[0]);
635 auto value = StringTools::trim(nameValuePair[1]);
636 if (name.empty() ==
true || value.empty() ==
true) {
637 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: name or value empty");
639 if (name ==
"width") {
641 imageWidth = Integer::parse(value);
643 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: width: unknown value: " + value);
646 if (name ==
"height") {
648 imageHeight = Integer::parse(value);
650 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: height: unknown value: " + value);
653 if (name ==
"horizontal-scale") {
655 if (StringTools::endsWith(value,
"%")) {
656 imageHorizontalScale = Float::parse(value.substr(0, value.length() - 1)) / 100.0f;
658 imageHorizontalScale = Float::parse(value);
661 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: horizontal-scale: unknown value: " + value);
664 if (name ==
"vertical-scale") {
666 if (StringTools::endsWith(value,
"%")) {
667 imageVerticalScale = Float::parse(value.substr(0, value.length() - 1)) / 100.0f;
669 imageVerticalScale = Float::parse(value);
672 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: vertical-scale: unknown value: " + value);
675 if (name ==
"effect-color-mul") {
677 imageEffectColorMul =
GUIColor(value);
679 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: effect-color-mul: unknown value: " + value);
682 if (name ==
"effect-color-add") {
684 imageEffectColorAdd =
GUIColor(value);
686 Console::println(
"GUIStyledTextNode::setText(): unknown image style command option: effect-color-add: unknown value: " + value);
689 Console::println(
"GUIStyledTextNode::setText(): image style command option: " + name +
" = '" + value +
"'");
694 Console::println(
"GUIStyledTextNode::setText(): unknown style command: " + currentStyle);
697 if (styleTokenized.size() == 1) {
698 auto command = StringTools::toLowerCase(StringTools::trim(styleTokenized[0]));
699 if (command ==
"/font") {
702 if (command ==
"/size") {
705 if (command ==
"/color") {
708 if (command ==
"/url") {
711 if (command ==
"image") {
714 if (command ==
"/image") {
716 this->text.
append(
static_cast<char>(0));
717 setImage(this->text.
size() - 1, styleImage, styleUrl, imageWidth, imageHeight, imageHorizontalScale, imageVerticalScale, imageEffectColorMul, imageEffectColorAdd);
721 imageHorizontalScale = 1.0f;
722 imageVerticalScale = 1.0f;
726 Console::println(
"GUIStyledTextNode::setText(): unknown style command: " + currentStyle);
729 Console::println(
"GUIStyledTextNode::setText(): unknown style command: " + currentStyle);
732 currentStyle.clear();
734 if (styleFont.empty() ==
false ||
735 styleColor.empty() ==
false ||
736 styleUrl.empty() ==
false) {
737 styleStartIdx = this->text.
size();
757 if (c ==
']' && lc ==
'\\') {
760 if (parseImage ==
true) {
772 if (styleStartIdx != -1 &&
773 (styleFont.empty() ==
false ||
774 styleColor.empty() ==
false ||
775 styleUrl.empty() ==
false)) {
776 if (styleColor.empty() ==
false) {
777 if (this->text.
size() > styleStartIdx)
setTextStyle(styleStartIdx, this->text.
size() - 1,
GUIColor(styleColor), styleFont, styleSize, styleUrl);
779 if (this->text.
size() > styleStartIdx)
setTextStyle(styleStartIdx, this->text.
size() - 1, styleFont, styleSize, styleUrl);
809 auto c = u8It.
next();
812 auto l1 =
line.size();
813 Character::appendToString(
line, c);
814 auto l2 =
line.size();
819 auto l1 =
line.size();
820 Character::appendToString(
line, c);
821 auto l2 =
line.size();
833 auto c = u8It.
next();
836 auto l1 =
line.size();
837 Character::appendToString(
line, c);
838 auto l2 =
line.size();
843 if (
line.empty() ==
false && c ==
' ' && StringTools::endsWith(
line,
spaceString) ==
true) {
846 if (
line.empty() ==
true && (c ==
' ' || c ==
'\t')) {
849 auto l1 =
line.size();
850 Character::appendToString(
line, c);
851 auto l2 =
line.size();
861 if (
line.empty() ==
true) {
874 auto baseLine = 0.0f;
875 auto lineHeight = 0.0f;
876 auto lineWidth = 0.0f;
877 auto lineWidthSpaceWrap = 0.0f;
878 auto lineHeightSpaceWrap = 0.0f;
879 auto baseLineSpaceWrap = 0.0f;
880 auto imageHeight = 0.0f;
895 auto currentTextStyleIdx = textStyleIdx;
897 while (lineU8It.
hasNext() ==
true) {
901 auto c = lineU8It.
next();
903 auto currentFont = textStyle !=
nullptr && textStyle->font !=
nullptr?textStyle->font:
font;
904 baseLine = Math::max(baseLine, currentFont->getBaseLine());
905 baseLineSpaceWrap = Math::max(baseLineSpaceWrap, currentFont->getBaseLine());
906 lineHeight = Math::max(lineHeight, currentFont->getLineHeight());
907 lineHeightSpaceWrap = Math::max(lineHeightSpaceWrap, currentFont->getLineHeight());
909 if (textStyle !=
nullptr && textStyle->image !=
nullptr) {
915 Math::max(lineHeight, baseLine + imageHeight),
920 lineWidthSpaceWrap = 0.0f;
921 lineHeightSpaceWrap = 0.0f;
922 baseLineSpaceWrap = 0.0f;
924 if (lineWidth > maxLineWidth) {
926 lineWidth = lineWidthSpaceWrap;
927 lineHeight = lineHeightSpaceWrap;
928 baseLine = baseLineSpaceWrap;
939 lineWidth+= textStyle->width;
940 lineWidthSpaceWrap+= textStyle->width;
941 imageHeight = Math::max(imageHeight,
static_cast<float>(textStyle->height));
949 Math::max(lineHeight, baseLine + imageHeight),
954 lineWidthSpaceWrap = 0.0f;
955 lineHeightSpaceWrap = 0.0f;
956 baseLineSpaceWrap = 0.0f;
958 auto character = currentFont->getCharacter(c ==
'\t'?
' ':c);
959 if (character !=
nullptr) {
965 Math::max(lineHeight, baseLine + imageHeight),
970 lineWidthSpaceWrap = 0.0f;
971 lineHeightSpaceWrap = 0.0f;
972 baseLineSpaceWrap = 0.0f;
974 if (lineWidth > maxLineWidth) {
975 lineWidth = lineWidthSpaceWrap;
976 if (lineU8It.
hasNext() ==
true) {
978 lineHeight = lineHeightSpaceWrap;
979 baseLine = baseLineSpaceWrap;
991 auto charXAdvance = c ==
'\t'?character->getXAdvance() *
tabSize:character->getXAdvance();
992 lineWidth+= charXAdvance;
993 lineWidthSpaceWrap+= lineWidthSpaceWrap < Math::EPSILON && (c ==
' ' || c ==
'\t')?0.0f:charXAdvance;
1001 static_cast<int>(
line.size()),
1004 Math::max(lineHeight, baseLine + imageHeight),
1020 if (
font ==
nullptr)
return;
1045 bool visible =
false;
1065 auto styledTextController = required_dynamic_cast<GUIStyledTextNodeController*>(
getController());
1067 auto cursorIndex = styledTextController->getIndex();
1068 auto cursorSelectionIndex = styledTextController->getSelectionIndex();
1070 cursorMode = styledTextController->getCursorMode();
1080 if (findNewIndex ==
true) {
1092 if (findNewSelectionIndex ==
true) {
1093 cursorSelectionIndex = -1;
1103 auto boundTexture = -1;
1110 for (;u8It.hasNext() ==
true && u8It.getBinaryPosition() <
charEndIdx;) {
1113 auto nextCharStartIdx = u8It.getBinaryPosition();
1114 auto nextStartTextStyleIdx = textStyleIdx;
1115 auto nextStartRenderY = y;
1150 auto skipSpaces =
false;
1151 auto& currentTextStyleIdx = textStyleIdx;
1165 float left = x + xIndentLeft;
1166 float top = y + yIndentTop;
1170 ((left) / (screenWidth / 2.0f)) - 1.0f,
1171 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1172 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1173 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1174 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1175 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1176 ((left) / (screenWidth / 2.0f)) - 1.0f, ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f) ==
true) {
1189 if (visible ==
true) {
1196 if (visible ==
false) {
1216 if (findNewIndex ==
true &&
1222 if (findNewSelectionIndex ==
true &&
1230 while (lineU8It.
hasNext() ==
true) {
1233 auto c = lineU8It.
next();
1239 if (textStyle !=
nullptr) {
1240 currentFont = textStyle->font !=
nullptr?textStyle->font:
font;
1241 currentColor = textStyle->color;
1242 styleURL = textStyle->url;
1245 if (textStyle !=
nullptr && textStyle->image !=
nullptr) {
1254 float left = x + xIndentLeft;
1256 float width = textStyle->width;
1257 float height = textStyle->height;
1259 ((left) / (screenWidth / 2.0f)) - 1.0f,
1260 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1261 1.0f, 1.0f, 1.0f, 1.0f,
1264 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1265 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1266 1.0f, 1.0f, 1.0f, 1.0f,
1269 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1270 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1271 1.0f, 1.0f, 1.0f, 1.0f,
1274 ((left) / (screenWidth / 2.0f)) - 1.0f,
1275 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1276 1.0f, 1.0f, 1.0f, 1.0f,
1283 float left = x + xIndentLeft;
1286 float height = textStyle->height;
1288 ((left) / (screenWidth / 2.0f)) - 1.0f,
1289 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1292 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1293 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1296 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1297 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1300 ((left) / (screenWidth / 2.0f)) - 1.0f,
1301 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1316 if (currentURL.empty() ==
false &&
urlAreas.empty() ==
false) {
1318 urlArea.width = x - urlArea.left;
1323 if (textStyle->url.empty() ==
false) {
1325 static_cast<int>(x),
1326 static_cast<int>(y),
1327 static_cast<int>(textStyle->width),
1328 static_cast<int>(textStyle->height),
1333 x+= textStyle->width;
1339 if (currentURL.empty() ==
false &&
urlAreas.empty() ==
false) {
1341 urlArea.width = x - urlArea.left;
1366 if (findNewIndex ==
true &&
1372 if (findNewSelectionIndex ==
true &&
1379 float left = x + xIndentLeft;
1380 float top = y + yIndentTop;
1384 ((left) / (screenWidth / 2.0f)) - 1.0f,
1385 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1386 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1387 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1388 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1389 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1390 ((left) / (screenWidth / 2.0f)) - 1.0f, ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f) ==
false) {
1392 if (visible ==
true) {
1403 if (skipSpaces ==
true) {
1404 if (c ==
' ' || c ==
'\t') {
1413 if (findNewIndex ==
true &&
1419 if (findNewSelectionIndex ==
true &&
1426 float left = x + xIndentLeft;
1431 ((left) / (screenWidth / 2.0f)) - 1.0f,
1432 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1435 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1436 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1439 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1440 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1443 ((left) / (screenWidth / 2.0f)) - 1.0f,
1444 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1455 auto characterCount = c ==
'\t'?
tabSize:1;
1456 auto character = currentFont->
getCharacter(c ==
'\t'?
' ':c);
1457 if (character !=
nullptr) {
1459 auto xAdvance = c ==
'\t'?
tabSize * character->getXAdvance():character->getXAdvance();
1463 if (findNewIndex ==
true &&
1469 if (findNewSelectionIndex ==
true &&
1476 auto hasSelection =
false;
1477 if (cursorSelectionIndex != -1 || findNewSelectionIndex ==
true) {
1478 if ((cursorSelectionIndex != -1 &&
lineCharIdxs[kc] >= Math::min(cursorIndex, cursorSelectionIndex) &&
lineCharIdxs[kc] < Math::max(cursorIndex, cursorSelectionIndex)) ||
1479 (cursorSelectionIndex == -1 &&
lineCharIdxs[kc] >= cursorIndex)) {
1480 for (
auto l = 0; l < characterCount; l++) {
1481 float left = x + xIndentLeft + (l * character->getXAdvance());
1485 hasSelection =
true;
1489 for (
auto l = 0; l < characterCount; l++) {
1490 float left = x + xIndentLeft + (l * character->getXAdvance());
1492 if (boundTexture == -1) {
1495 lastColor = currentColor;
1501 lastColor = currentColor;
1503 if (currentColor.
equals(lastColor) ==
false) {
1505 lastColor = currentColor;
1507 currentFont->
drawCharacter(guiRenderer, character, left, top, currentColor);
1512 float left = x + xIndentLeft;
1517 ((left) / (screenWidth / 2.0f)) - 1.0f,
1518 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1521 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1522 ((screenHeight - top) / (screenHeight / 2.0f)) - 1.0f,
1525 ((left + width) / (screenWidth / 2.0f)) - 1.0f,
1526 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1529 ((left) / (screenWidth / 2.0f)) - 1.0f,
1530 ((screenHeight - top - height) / (screenHeight / 2.0f)) - 1.0f,
1541 if (styleURL != currentURL) {
1542 if (currentURL.empty() ==
false &&
urlAreas.empty() ==
false) {
1544 urlArea.width = x - urlArea.left;
1547 if (styleURL.empty() ==
false) {
1549 static_cast<int>(x),
1550 static_cast<int>(y),
1556 currentURL = styleURL;
1568 if (findNewIndex ==
true &&
1575 if (findNewSelectionIndex ==
true &&
1587 if (currentURL.empty() ==
false &&
urlAreas.empty() ==
false) {
1589 urlArea.width = x - urlArea.left;
1610 if (findNewIndex ==
true) {
1611 if (cursorIndex != -1) styledTextController->setIndex(cursorIndex);
1615 if (findNewSelectionIndex ==
true) {
1616 if (cursorSelectionIndex != -1) styledTextController->setSelectionIndex(cursorSelectionIndex);
1621 for (
const auto& style:
styles) {
1623 if (style.image !=
nullptr) Engine::getInstance()->getTextureManager()->removeTexture(style.image->getId());
1634 for (
auto i = 0; i <
styles.size(); i++) {
1636 if (startIdx >= style.startIdx && endIdx <= style.endIdx) {
1637 auto styleNext = style;
1638 style.endIdx = startIdx - 1;
1639 styleNext.startIdx = endIdx + 1;
1644 if (startIdx >= style.startIdx && startIdx <= style.endIdx) {
1645 style.endIdx = startIdx - 1;
1647 if (endIdx >= style.startIdx && endIdx <= style.endIdx) {
1648 style.startIdx = endIdx - 1;
1651 if (style.startIdx > style.endIdx ||
1652 (startIdx < style.startIdx && endIdx > style.endIdx)) {
1674 for (
auto i = 0; i <
styles.size(); i++) {
1675 const auto& style =
styles[i];
1676 if (startIdx > style.endIdx) {
1687 .startIdx = startIdx,
1696 .effectColorMul = GUIColor::GUICOLOR_EFFECT_COLOR_MUL,
1697 .effectColorAdd = GUIColor::GUICOLOR_EFFECT_COLOR_ADD
1718 for (
auto i = 0; i <
styles.size(); i++) {
1719 const auto& style =
styles[i];
1720 if (startIdx > style.endIdx) {
1731 .startIdx = startIdx,
1740 .effectColorMul = GUIColor::GUICOLOR_EFFECT_COLOR_MUL,
1741 .effectColorAdd = GUIColor::GUICOLOR_EFFECT_COLOR_ADD
1756 for (
auto i = 0; i <
styles.size(); i++) {
1757 const auto& style =
styles[i];
1758 if (idx > style.endIdx) {
1775 .textureId = Engine::getInstance()->getTextureManager()->addTexture(_image, 0),
1776 .width = width == -1?static_cast<int>(_image->getWidth() * horizontalScale):static_cast<int>(width * horizontalScale),
1777 .height = height == -1?static_cast<int>(_image->getHeight() * verticalScale):static_cast<int>(height * verticalScale),
1778 .effectColorMul = effectColorMul,
1779 .effectColorAdd = effectColorAdd
Color 4 definition class.
bool equals(const Color4 &color, float tolerance=Math::EPSILON) const
Compares this color with given color.
static const Properties * getEngineThemeProperties()
static STATIC_DLL_IMPEXT GUIColor GUICOLOR_EFFECT_COLOR_ADD
static STATIC_DLL_IMPEXT GUIColor GUICOLOR_EFFECT_COLOR_MUL
GUI element node conditions.
GUI node horizontal alignment enum.
static STATIC_DLL_IMPEXT GUINode_AlignmentHorizontal * RIGHT
static STATIC_DLL_IMPEXT GUINode_AlignmentHorizontal * CENTER
static STATIC_DLL_IMPEXT GUINode_AlignmentHorizontal * LEFT
GUI node vertical alignment enum.
static STATIC_DLL_IMPEXT GUINode_AlignmentVertical * BOTTOM
static STATIC_DLL_IMPEXT GUINode_AlignmentVertical * CENTER
static STATIC_DLL_IMPEXT GUINode_AlignmentVertical * TOP
static STATIC_DLL_IMPEXT GUINode_RequestedConstraints_RequestedConstraintsType * AUTO
float computeParentChildrenRenderOffsetXTotal()
virtual void render(GUIRenderer *guiRenderer)
Render.
GUIParentNode * parentNode
GUINode_ComputedConstraints computedConstraints
GUINodeController * getController()
GUIScreenNode * screenNode
virtual int getAutoWidth()
GUINode_RequestedConstraints requestedConstraints
float computeParentChildrenRenderOffsetYTotal()
bool shouldRender()
Returns if to render.
virtual void dispose()
Dispose node.
GUINode_Alignments alignments
GUINode_ComputedConstraints & getComputedConstraints()
GUI parent node base class thats supporting child nodes.
float getChildrenRenderOffsetX()
float getChildrenRenderOffsetY()
void setChildrenRenderOffsetY(float childrenRenderOffSetY)
Set children render offset y.
GUI screen node that represents a screen that can be rendered via GUI system.
void invalidateLayout(GUINode *node)
Mark a node to be invalidated regarding layout.
GUIFont * getFont(const string &fileName, int size)
Get font.
Texture * getImage(const string &fileName)
Get image.
GUI styled text node controller.
vector< Line > lineConstraints
int selectionIndexMousePositionX
void setImage(int idx, const string &image, const string &url=string(), int width=-1, int height=-1, float horizontalScale=1.0f, float verticalScale=1.0f, const GUIColor &effectColorMul=GUIColor::GUICOLOR_EFFECT_COLOR_MUL, const GUIColor &effectColorAdd=GUIColor::GUICOLOR_EFFECT_COLOR_ADD)
Set image.
vector< TextStyle > styles
const string getNodeType() override
void dispose() override
Dispose node.
int getContentWidth() override
void insertText(int32_t idx, int c)
Insert character c at idx.
void unsetTextStyle(int startIdx, int endIdx)
Unset text style.
vector< int > lineCharIdxs
void setIndexMousePosition(int x, int y)
Set index mouse position.
int getContentHeight() override
void setSelectionIndexMousePosition(int x, int y)
Set selection index mouse position.
void setText(const MutableString &text)
Set text.
static constexpr int MOUSEPOSITION_NONE
int doPageDown()
Do page down.
void unsetStyles()
Unset/dispose styles.
GUIColor selectionBackgroundColor
int doPageUp()
Do page up.
void setTextStyle(int startIdx, int endIdx, const GUIColor &color, const string &font=string(), int size=-1, const string &url=string())
Set text style.
void removeText(int32_t idx, int32_t count)
Remove characters at idx with given length.
void scrollToSelectionIndex()
Set scroll to selection index.
void computeContentAlignment() override
Do content alignment.
void unsetIndexMousePosition()
Unset index mouse position.
void render(GUIRenderer *guiRenderer) override
Render.
bool parentOffsetsChanged
vector< URLArea > urlAreas
void unsetSelectionIndexMousePosition()
Unset selection index mouse position.
bool isContentNode() override
int selectionIndexMousePositionY
TextStyle * getTextStyle(const vector< int > &lineCharIdxs, int lineCharIdx, int &textStyleIdx)
Get text style for.
void scrollToIndex()
Set scroll to index.
void computeContentAlignmentInternal()
Compute content alignment internal.
vector< int > lineCharBinaryIdxs
void determineNextLineConstraints(UTF8CharacterIterator &u8It, int charEndIdx, int textStyleIdx)
Determine next line constraints.
GUICharacter * getCharacter(uint32_t charId)
Get character defintion.
void drawCharacter(GUIRenderer *guiRenderer, GUICharacter *character, int x, int y, const GUIColor &color=GUIColor::GUICOLOR_WHITE)
Draw character.
void drawCharacterBackground(GUIRenderer *guiRenderer, GUICharacter *character, int x, int y, int lineHeight, const GUIColor &color)
Draw background.
const GUIColor & getGUIEffectColorAdd()
void setGUIEffectColorMul(const GUIColor &color)
Set GUI effect color mul.
void setGUIEffectColorAdd(const GUIColor &color)
Set GUI effect color add.
void bindTexture(int32_t textureId)
Bind texture.
bool isQuadVisible2(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
void addQuad(float x1, float y1, float colorR1, float colorG1, float colorB1, float colorA1, float tu1, float tv1, float x2, float y2, float colorR2, float colorG2, float colorB2, float colorA2, float tu2, float tv2, float x3, float y3, float colorR3, float colorG3, float colorB3, float colorA3, float tu3, float tv3, float x4, float y4, float colorR4, float colorG4, float colorB4, float colorA4, float tu4, float tv4, bool solidColor=false, bool rotated=false)
Add quad Note: quad vertices order 1 2 +-—+ | | | | +-—+ 4 3.
const GUIColor & getGUIEffectColorMul()
Mutable utf8 aware string class.
MutableString & append(char c)
Append character.
char getCharAt(int32_t idx) const
Get char at given binary index.
const UTF8CharacterIterator getUTF8CharacterIterator() const
int getUtf8BinaryIndex(int idx) const
MutableString & remove(int32_t idx, int32_t count, int *binaryCount=nullptr)
Remove characters at idx with given length.
const string & getString() const
MutableString & reset()
Reset.
MutableString & insert(int32_t idx, char c)
Insert character c at idx.
Properties class, which helps out with storeing or loading key value pairs from/to property files.
UTF8 string character iterator.
int getBinaryPosition() const
void seekBinaryPosition(int position) const
Set underlying binary buffer position.
int getCharacterPosition() const
std::exception Exception
Exception base class.
GUINode_AlignmentVertical * vertical
GUINode_AlignmentHorizontal * horizontal
GUI node computed constraints.
GUI node requested constraints entity.
GUINode_RequestedConstraints_RequestedConstraintsType * widthType
GUINode_RequestedConstraints_RequestedConstraintsType * heightType
GUI node scale 9 grid entity.