Progress untangle
This commit is contained in:
		@@ -5,7 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
#include "scene/SceneItemComponent.hpp"
 | 
					#include "scene/SceneItemComponent.hpp"
 | 
				
			||||||
#include "scene/components/ui/text/UILabelNew.hpp"
 | 
					#include "scene/components/ui/text/UILabel.hpp"
 | 
				
			||||||
#include "input/InputManager.hpp"
 | 
					#include "input/InputManager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VN_TEXTBOX_SPEED 25.0f
 | 
					#define VN_TEXTBOX_SPEED 25.0f
 | 
				
			||||||
@@ -15,7 +15,7 @@ namespace Dawn {
 | 
				
			|||||||
  class VNTextboxScroller : public SceneItemComponent {
 | 
					  class VNTextboxScroller : public SceneItemComponent {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
      // @optional
 | 
					      // @optional
 | 
				
			||||||
      StateProperty<UILabelNew*> label;
 | 
					      StateProperty<UILabel*> label;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      StateEvent<> eventReadyToClose;
 | 
					      StateEvent<> eventReadyToClose;
 | 
				
			||||||
      StateEvent<> eventCharacterRevealed;
 | 
					      StateEvent<> eventCharacterRevealed;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,13 +4,13 @@
 | 
				
			|||||||
// https://opensource.org/licenses/MIT
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
#include "scene/components/ui/text/UILabelNew.hpp"
 | 
					#include "scene/components/ui/text/UILabel.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Dawn {
 | 
					namespace Dawn {
 | 
				
			||||||
  class FPSLabelComponent : public SceneItemComponent {
 | 
					  class FPSLabelComponent : public SceneItemComponent {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
      /* @optional */
 | 
					      /* @optional */
 | 
				
			||||||
      UILabelNew *label = nullptr;
 | 
					      UILabel *label = nullptr;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      FPSLabelComponent(SceneItem *item);
 | 
					      FPSLabelComponent(SceneItem *item);
 | 
				
			||||||
      void onStart() override;
 | 
					      void onStart() override;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,7 +40,7 @@ namespace Dawn {
 | 
				
			|||||||
      /**
 | 
					      /**
 | 
				
			||||||
       * Internal method to update the alignment of this item.
 | 
					       * Internal method to update the alignment of this item.
 | 
				
			||||||
       */
 | 
					       */
 | 
				
			||||||
      void updateAlignment();
 | 
					      virtual void updateAlignment();
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
      StateProperty<bool_t> alignmentNeedsUpdating;
 | 
					      StateProperty<bool_t> alignmentNeedsUpdating;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
# Copyright (c) 2022 Dominic Masters
 | 
					# Copyright (c) 2023 Dominic Masters
 | 
				
			||||||
# 
 | 
					# 
 | 
				
			||||||
# This software is released under the MIT License.
 | 
					# This software is released under the MIT License.
 | 
				
			||||||
# https://opensource.org/licenses/MIT
 | 
					# https://opensource.org/licenses/MIT
 | 
				
			||||||
@@ -6,5 +6,6 @@
 | 
				
			|||||||
# Sources
 | 
					# Sources
 | 
				
			||||||
target_sources(${DAWN_TARGET_NAME}
 | 
					target_sources(${DAWN_TARGET_NAME}
 | 
				
			||||||
  PRIVATE
 | 
					  PRIVATE
 | 
				
			||||||
    UILabelNew.cpp
 | 
					    UILabel.cpp
 | 
				
			||||||
 | 
					    UIRichTextLabel.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -3,83 +3,22 @@
 | 
				
			|||||||
// This software is released under the MIT License.
 | 
					// This software is released under the MIT License.
 | 
				
			||||||
// https://opensource.org/licenses/MIT
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "UILabelNew.hpp"
 | 
					#include "UILabel.hpp"
 | 
				
			||||||
#include "game/DawnGame.hpp"
 | 
					#include "game/DawnGame.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Dawn;
 | 
					using namespace Dawn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
UILabelNew::UILabelNew(SceneItem *item) :
 | 
					UILabel::UILabel(SceneItem *item) :
 | 
				
			||||||
  UIComponentRenderable(item)
 | 
					  UIComponentRenderable(item)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void UILabelNew::onStart() {
 | 
					void UILabel::onStart() {
 | 
				
			||||||
  this->shaderBuffer.init();
 | 
					  this->shaderBuffer.init();
 | 
				
			||||||
 | 
					 | 
				
			||||||
  std::vector<struct UILabelStyle> styleStack;
 | 
					 | 
				
			||||||
  struct UILabelStyle current;
 | 
					 | 
				
			||||||
  styleStack.push_back(current);
 | 
					 | 
				
			||||||
  std::vector<struct UILabelText> texts;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  std::function<void(Xml*)> parseChildren = [&](Xml *node) {
 | 
					 | 
				
			||||||
    if(node->children.empty()) {
 | 
					 | 
				
			||||||
      struct UILabelText text;
 | 
					 | 
				
			||||||
      text.style = current;
 | 
					 | 
				
			||||||
      text.text = node->value;
 | 
					 | 
				
			||||||
      texts.push_back(text);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      auto itNode = node->children.begin();
 | 
					 | 
				
			||||||
      while(itNode != node->children.end()) {
 | 
					 | 
				
			||||||
        auto child = *itNode;
 | 
					 | 
				
			||||||
        assertTrue(child->node == "font");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct UILabelStyle style;
 | 
					 | 
				
			||||||
        if(child->attributes.contains("font")) {
 | 
					 | 
				
			||||||
          style.font = this->getGame()->assetManager.get<NewTrueTypeAsset>(child->attributes["font"]);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          style.font = current.font;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(child->attributes.contains("size")) {
 | 
					 | 
				
			||||||
          style.size = std::stoi(child->attributes["size"]);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          style.size = current.size;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(child->attributes.contains("style")) {
 | 
					 | 
				
			||||||
          std::string s = child->attributes["style"];
 | 
					 | 
				
			||||||
          style.style = 0;
 | 
					 | 
				
			||||||
          if(s.find("bold") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_BOLD;
 | 
					 | 
				
			||||||
          if(s.find("italic") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_ITALICS;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          style.style = current.style;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(child->attributes.contains("color")) {
 | 
					 | 
				
			||||||
          style.color = Color::fromString(child->attributes["color"]);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          style.color = current.color;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        styleStack.push_back(style);
 | 
					 | 
				
			||||||
        current = style;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        parseChildren(child);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        styleStack.pop_back();
 | 
					 | 
				
			||||||
        current = styleStack.back();
 | 
					 | 
				
			||||||
        ++itNode;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto root = Xml::load("<root>" + this->test + "</root>");
 | 
					 | 
				
			||||||
  parseChildren(&root);
 | 
					 | 
				
			||||||
  this->rebufferQuads(texts);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
 | 
					std::vector<struct ShaderPassItem> UILabel::getUIRenderPasses() {
 | 
				
			||||||
  // if(this->texts.size() == 0) return {};
 | 
					  // if(this->texts.size() == 0) return {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto canvas = this->getCanvas();
 | 
					  auto canvas = this->getCanvas();
 | 
				
			||||||
@@ -92,6 +31,8 @@ std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
 | 
				
			|||||||
  item.parameterBuffers[shader->bufferUiCanvas] = &canvas->shaderBuffer;
 | 
					  item.parameterBuffers[shader->bufferUiCanvas] = &canvas->shaderBuffer;
 | 
				
			||||||
  item.parameterBuffers[shader->bufferFont] = &this->shaderBuffer;
 | 
					  item.parameterBuffers[shader->bufferFont] = &this->shaderBuffer;
 | 
				
			||||||
  item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
 | 
					  item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
 | 
				
			||||||
 | 
					  item.start = quadStart * QUAD_VERTICE_COUNT;
 | 
				
			||||||
 | 
					  item.count = quadCount == -1 ? -1 : quadCount * QUAD_VERTICE_COUNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Map texture slots
 | 
					  // Map texture slots
 | 
				
			||||||
  auto it = textureMap.begin();
 | 
					  auto it = textureMap.begin();
 | 
				
			||||||
@@ -126,23 +67,15 @@ std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
 | 
				
			|||||||
  return { item };
 | 
					  return { item };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float_t UILabelNew::getWidth() {
 | 
					float_t UILabel::getContentWidth() {
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float_t UILabelNew::getHeight() {
 | 
					float_t UILabel::getContentHeight() {
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float_t UILabelNew::getContentWidth() {
 | 
					void UILabel::rebufferQuads(std::vector<struct UILabelText> newTexts) {
 | 
				
			||||||
  return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
float_t UILabelNew::getContentHeight() {
 | 
					 | 
				
			||||||
  return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
 | 
					 | 
				
			||||||
  auto oldTexts = this->texts;
 | 
					  auto oldTexts = this->texts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  textureMap.clear();
 | 
					  textureMap.clear();
 | 
				
			||||||
@@ -150,13 +83,13 @@ void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
 | 
				
			|||||||
  struct FontShaderBufferData fontData;
 | 
					  struct FontShaderBufferData fontData;
 | 
				
			||||||
  int32_t quadIndex = 0;
 | 
					  int32_t quadIndex = 0;
 | 
				
			||||||
  int32_t partIndex = 0;
 | 
					  int32_t partIndex = 0;
 | 
				
			||||||
  int32_t quadCount = 0;
 | 
					  quadCountTotal = 0;
 | 
				
			||||||
  int32_t nextTexture = 0;
 | 
					  int32_t nextTexture = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Determine how many quads there are, and the texture indexes.
 | 
					  // Determine how many quads there are, and the texture indexes.
 | 
				
			||||||
  auto itText = texts.begin();
 | 
					  auto itText = newTexts.begin();
 | 
				
			||||||
  while(itText != texts.end()) {
 | 
					  while(itText != newTexts.end()) {
 | 
				
			||||||
    quadCount += itText->text.length();
 | 
					    quadCountTotal += itText->text.length();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Determine font and lock it.
 | 
					    // Determine font and lock it.
 | 
				
			||||||
    assertNotNull(itText->style.font);
 | 
					    assertNotNull(itText->style.font);
 | 
				
			||||||
@@ -172,9 +105,6 @@ void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
 | 
				
			|||||||
      assertTrue(nextTexture < FONT_SHADER_TEXTURE_MAX);
 | 
					      assertTrue(nextTexture < FONT_SHADER_TEXTURE_MAX);
 | 
				
			||||||
      textureMap[itText->texture] = nextTexture++;
 | 
					      textureMap[itText->texture] = nextTexture++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
    // Set initial line height
 | 
					 | 
				
			||||||
    position.y = mathMax<float_t>(itText->style.size, position.y);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ++itText;
 | 
					    ++itText;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -190,17 +120,18 @@ void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Update texts.
 | 
					  // Update texts.
 | 
				
			||||||
  this->texts = texts;
 | 
					  this->texts = newTexts;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Create mesh
 | 
					  // Create mesh
 | 
				
			||||||
  this->mesh.createBuffers(
 | 
					  this->mesh.createBuffers(
 | 
				
			||||||
    QUAD_VERTICE_COUNT * quadCount,
 | 
					    QUAD_VERTICE_COUNT * quadCountTotal,
 | 
				
			||||||
    QUAD_INDICE_COUNT * quadCount
 | 
					    QUAD_INDICE_COUNT * quadCountTotal
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Buffer the text quads
 | 
					  // Buffer the text quads
 | 
				
			||||||
  itText = texts.begin();
 | 
					  itText = newTexts.begin();
 | 
				
			||||||
  while(itText != texts.end()) {
 | 
					  while(itText != newTexts.end()) {
 | 
				
			||||||
 | 
					    position.y += itText->style.size;
 | 
				
			||||||
    quadIndex += this->bufferQuads(
 | 
					    quadIndex += this->bufferQuads(
 | 
				
			||||||
      *itText,
 | 
					      *itText,
 | 
				
			||||||
      fontData,
 | 
					      fontData,
 | 
				
			||||||
@@ -209,6 +140,7 @@ void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
 | 
				
			|||||||
      quadIndex,
 | 
					      quadIndex,
 | 
				
			||||||
      partIndex
 | 
					      partIndex
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    // position.y -= itText->style.size;
 | 
				
			||||||
    ++partIndex;
 | 
					    ++partIndex;
 | 
				
			||||||
    ++itText;
 | 
					    ++itText;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -216,7 +148,7 @@ void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
 | 
				
			|||||||
  shaderBuffer.buffer(&fontData);
 | 
					  shaderBuffer.buffer(&fontData);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int32_t UILabelNew::bufferQuads(
 | 
					int32_t UILabel::bufferQuads(
 | 
				
			||||||
  struct UILabelText text,
 | 
					  struct UILabelText text,
 | 
				
			||||||
  struct FontShaderBufferData &bufferData,
 | 
					  struct FontShaderBufferData &bufferData,
 | 
				
			||||||
  std::map<NewTrueTypeFaceTexture*, int32_t> &textureMap,
 | 
					  std::map<NewTrueTypeFaceTexture*, int32_t> &textureMap,
 | 
				
			||||||
@@ -233,17 +165,46 @@ int32_t UILabelNew::bufferQuads(
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // For each char
 | 
					  // For each char
 | 
				
			||||||
 | 
					  int32_t lastSpaceCharacter = -1;
 | 
				
			||||||
  for(int32_t i = 0; i < len; i++) {
 | 
					  for(int32_t i = 0; i < len; i++) {
 | 
				
			||||||
    char ch = text.text[i];
 | 
					    char ch = text.text[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(ch == '\n') {
 | 
				
			||||||
 | 
					      position.x = 0;
 | 
				
			||||||
 | 
					      position.y += text.style.size;
 | 
				
			||||||
 | 
					      ch = ' ';
 | 
				
			||||||
 | 
					      lastSpaceCharacter = i;
 | 
				
			||||||
 | 
					    } else if(ch == ' ') {
 | 
				
			||||||
 | 
					      lastSpaceCharacter = i;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Invalid/Unsupported chars
 | 
				
			||||||
 | 
					    assertTrue(ch >= NEW_TRUETYPE_CHAR_BEGIN && ch < NEW_TRUETYPE_CHAR_END);
 | 
				
			||||||
 | 
					    assertTrue(ch != '\r');
 | 
				
			||||||
 | 
					    assertTrue(ch != '\t');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int32_t j = quadStart + i;
 | 
					    int32_t j = quadStart + i;
 | 
				
			||||||
    FT_ULong c = ch;
 | 
					    FT_ULong c = ch;
 | 
				
			||||||
    auto charInfo = text.texture->getCharacterData(c);
 | 
					    auto charInfo = text.texture->getCharacterData(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Word wrapping
 | 
				
			||||||
 | 
					    if(
 | 
				
			||||||
 | 
					      lastSpaceCharacter != -1 &&
 | 
				
			||||||
 | 
					      this->width > 0 &&
 | 
				
			||||||
 | 
					      (position.x+charInfo.advanceX) > this->width
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					      text.text[lastSpaceCharacter] = '\n';
 | 
				
			||||||
 | 
					      i = lastSpaceCharacter - 1;
 | 
				
			||||||
 | 
					      lastSpaceCharacter = -1;
 | 
				
			||||||
 | 
					      continue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Determine texture coordinates.
 | 
					    // Determine texture coordinates.
 | 
				
			||||||
    glm::vec2 uv0 = glm::vec2(0.0f, charInfo.textureY) / wh;
 | 
					    glm::vec2 uv0 = glm::vec2(0.0f, charInfo.textureY) / wh;
 | 
				
			||||||
    glm::vec2 uv1 = uv0 + (charInfo.bitmapSize / wh);
 | 
					    glm::vec2 uv1 = uv0 + (charInfo.bitmapSize / wh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Buffer the quad.
 | 
					    // Buffer the quad.
 | 
				
			||||||
 | 
					    assertTrue(j < FONT_SHADER_QUADS_MAX);
 | 
				
			||||||
    QuadMesh::bufferQuadMeshWithZ(&this->mesh,
 | 
					    QuadMesh::bufferQuadMeshWithZ(&this->mesh,
 | 
				
			||||||
      position + charInfo.bitmapPosition, uv0,
 | 
					      position + charInfo.bitmapPosition, uv0,
 | 
				
			||||||
      position + charInfo.bitmapPosition + charInfo.bitmapSize, uv1,
 | 
					      position + charInfo.bitmapPosition + charInfo.bitmapSize, uv1,
 | 
				
			||||||
@@ -9,6 +9,8 @@
 | 
				
			|||||||
#include "asset/assets/NewTrueTypeAsset.hpp"
 | 
					#include "asset/assets/NewTrueTypeAsset.hpp"
 | 
				
			||||||
#include "util/Xml.hpp"
 | 
					#include "util/Xml.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UI_LABEL_MAX_WIDTH_NONE -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Dawn {
 | 
					namespace Dawn {
 | 
				
			||||||
  struct UILabelStyle {
 | 
					  struct UILabelStyle {
 | 
				
			||||||
    struct Color color = COLOR_WHITE;
 | 
					    struct Color color = COLOR_WHITE;
 | 
				
			||||||
@@ -32,7 +34,7 @@ namespace Dawn {
 | 
				
			|||||||
    struct NewTrueTypeFaceTexture *texture = nullptr;
 | 
					    struct NewTrueTypeFaceTexture *texture = nullptr;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  class UILabelNew : public UIComponentRenderable {
 | 
					  class UILabel : public UIComponentRenderable {
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
      Mesh mesh;
 | 
					      Mesh mesh;
 | 
				
			||||||
      FontShaderBuffer shaderBuffer;
 | 
					      FontShaderBuffer shaderBuffer;
 | 
				
			||||||
@@ -60,19 +62,24 @@ namespace Dawn {
 | 
				
			|||||||
        int32_t partIndex
 | 
					        int32_t partIndex
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
      std::string test;
 | 
					      int32_t quadStart = 0;
 | 
				
			||||||
 | 
					      int32_t quadCount = -1;
 | 
				
			||||||
 | 
					      int32_t quadCountTotal = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      UILabelNew(SceneItem *item);
 | 
					      UILabel(SceneItem *item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      void onStart() override;
 | 
					      void onStart() override;
 | 
				
			||||||
      std::vector<struct ShaderPassItem> getUIRenderPasses() override;
 | 
					      std::vector<struct ShaderPassItem> getUIRenderPasses() override;
 | 
				
			||||||
      float_t getWidth() override;
 | 
					 | 
				
			||||||
      float_t getHeight() override;
 | 
					 | 
				
			||||||
      float_t getContentWidth() override;
 | 
					      float_t getContentWidth() override;
 | 
				
			||||||
      float_t getContentHeight() override;
 | 
					      float_t getContentHeight() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /**
 | 
				
			||||||
 | 
					       * Rebuffer the quads for this label. This method will perform all the
 | 
				
			||||||
 | 
					       * necessary difference calculations from where the current state of this text is.
 | 
				
			||||||
 | 
					       * 
 | 
				
			||||||
 | 
					       * @param texts Texts to buffer.
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
      void rebufferQuads(std::vector<struct UILabelText> texts);
 | 
					      void rebufferQuads(std::vector<struct UILabelText> texts);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										82
									
								
								src/dawn/scene/components/ui/text/UIRichTextLabel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/dawn/scene/components/ui/text/UIRichTextLabel.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					// Copyright (c) 2023 Dominic Masters
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// This software is released under the MIT License.
 | 
				
			||||||
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "UIRichTextLabel.hpp"
 | 
				
			||||||
 | 
					#include "game/DawnGame.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace Dawn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UIRichTextLabel::UIRichTextLabel(SceneItem *item) :
 | 
				
			||||||
 | 
					  UILabel(item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UIRichTextLabel::onStart() {
 | 
				
			||||||
 | 
					  UILabel::onStart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect([&]{
 | 
				
			||||||
 | 
					    std::vector<struct UILabelStyle> styleStack;
 | 
				
			||||||
 | 
					    struct UILabelStyle current;
 | 
				
			||||||
 | 
					    styleStack.push_back(current);
 | 
				
			||||||
 | 
					    std::vector<struct UILabelText> bufferTexts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::function<void(Xml*)> parseChildren = [&](Xml *node) {
 | 
				
			||||||
 | 
					      if(node->children.empty()) {
 | 
				
			||||||
 | 
					        struct UILabelText text;
 | 
				
			||||||
 | 
					        text.style = current;
 | 
				
			||||||
 | 
					        text.text = node->value;
 | 
				
			||||||
 | 
					        bufferTexts.push_back(text);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        auto itNode = node->children.begin();
 | 
				
			||||||
 | 
					        while(itNode != node->children.end()) {
 | 
				
			||||||
 | 
					          auto child = *itNode;
 | 
				
			||||||
 | 
					          assertTrue(child->node == "font");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          struct UILabelStyle style;
 | 
				
			||||||
 | 
					          if(child->attributes.contains("font")) {
 | 
				
			||||||
 | 
					            style.font = this->getGame()->assetManager.get<NewTrueTypeAsset>(child->attributes["font"]);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            style.font = current.font;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(child->attributes.contains("size")) {
 | 
				
			||||||
 | 
					            style.size = std::stoi(child->attributes["size"]);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            style.size = current.size;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(child->attributes.contains("style")) {
 | 
				
			||||||
 | 
					            std::string s = child->attributes["style"];
 | 
				
			||||||
 | 
					            style.style = 0;
 | 
				
			||||||
 | 
					            if(s.find("bold") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_BOLD;
 | 
				
			||||||
 | 
					            if(s.find("italic") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_ITALICS;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            style.style = current.style;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(child->attributes.contains("color")) {
 | 
				
			||||||
 | 
					            style.color = Color::fromString(child->attributes["color"]);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            style.color = current.color;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          styleStack.push_back(style);
 | 
				
			||||||
 | 
					          current = style;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          parseChildren(child);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          styleStack.pop_back();
 | 
				
			||||||
 | 
					          current = styleStack.back();
 | 
				
			||||||
 | 
					          ++itNode;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto root = Xml::load("<root>" + ((std::string)this->richText) + "</root>");
 | 
				
			||||||
 | 
					    parseChildren(&root);
 | 
				
			||||||
 | 
					    this->rebufferQuads(bufferTexts);
 | 
				
			||||||
 | 
					  }, this->richText)();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								src/dawn/scene/components/ui/text/UIRichTextLabel.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/dawn/scene/components/ui/text/UIRichTextLabel.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					// Copyright (c) 2023 Dominic Masters
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// This software is released under the MIT License.
 | 
				
			||||||
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "UILabel.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Dawn {
 | 
				
			||||||
 | 
					  class UIRichTextLabel : public UILabel {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					      StateProperty<std::string> richText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      UIRichTextLabel(SceneItem *item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      void onStart() override;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
#include "scene/Scene.hpp"
 | 
					#include "scene/Scene.hpp"
 | 
				
			||||||
#include "prefabs/SimpleSpinningCubePrefab.hpp"
 | 
					#include "prefabs/SimpleSpinningCubePrefab.hpp"
 | 
				
			||||||
#include "scene/components/display/Camera.hpp"
 | 
					#include "scene/components/display/Camera.hpp"
 | 
				
			||||||
#include "scene/components/ui/text/UILabelNew.hpp"
 | 
					#include "scene/components/ui/text/UIRichTextLabel.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Dawn {
 | 
					namespace Dawn {
 | 
				
			||||||
  class HelloWorldScene : public Scene {
 | 
					  class HelloWorldScene : public Scene {
 | 
				
			||||||
@@ -26,8 +26,24 @@ namespace Dawn {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        auto newLabelItem = this->createSceneItem();
 | 
					        auto newLabelItem = this->createSceneItem();
 | 
				
			||||||
        newLabelItem->transform.setParent(canvas->transform);
 | 
					        newLabelItem->transform.setParent(canvas->transform);
 | 
				
			||||||
        auto newLabel = newLabelItem->addComponent<UILabelNew>();
 | 
					        auto newLabel = newLabelItem->addComponent<UIRichTextLabel>();
 | 
				
			||||||
        newLabel->test = "<font font=\"font_arial\" size=\"32\" color=\"COLOR_BLUE\">Hello</font><font style=\"bold\" font=\"font_arial\" size=\"64\" color=\"COLOR_RED\">World</font>";
 | 
					        // newLabel->maxWidth = 300.0f;
 | 
				
			||||||
 | 
					        newLabel->richText = std::string(
 | 
				
			||||||
 | 
					          "<font font=\"font_arial\" size=\"16\" color=\"COLOR_BLUE\">"
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
 | 
				
			||||||
 | 
					          "</font>"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      std::vector<Asset*> getRequiredAssets() override {
 | 
					      std::vector<Asset*> getRequiredAssets() override {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
#include "util/macro.hpp"
 | 
					#include "util/macro.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FONT_SHADER_PARTS_MAX 4
 | 
					#define FONT_SHADER_PARTS_MAX 4
 | 
				
			||||||
#define FONT_SHADER_QUADS_MAX 32
 | 
					#define FONT_SHADER_QUADS_MAX 1024
 | 
				
			||||||
#define FONT_SHADER_TEXTURE_MAX 4
 | 
					#define FONT_SHADER_TEXTURE_MAX 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Dawn {
 | 
					namespace Dawn {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user