Pretty much everything Label wise is working

This commit is contained in:
2023-06-12 08:32:12 -07:00
parent a4eecbe1d4
commit c7d5377b9c
10 changed files with 306 additions and 93 deletions

View File

@ -17,88 +17,66 @@ UILabelNew::UILabelNew(SceneItem *item) :
void UILabelNew::onStart() {
this->shaderBuffer.init();
auto font = this->getGame()->assetManager.get<NewTrueTypeAsset>("font_arial");
std::vector<struct UILabelStyle> styleStack;
struct UILabelStyle current;
styleStack.push_back(current);
std::vector<struct UILabelText> texts;
texts.push_back({
.text = "Hello",
.style = {
.color = COLOR_RED,
.style = 0,
.size = 32,
.font = font
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;
}
}
});
texts.push_back({
.text = "World",
.style = {
.color = COLOR_BLUE,
.style = 1,
.size = 64,
.font = font
}
});
};
auto root = Xml::load("<root>" + this->test + "</root>");
parseChildren(&root);
this->rebufferQuads(texts);
// 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;
// (node->value)
// } else {
// auto itNode = node->children.begin();
// while(itNode != node->children.end()) {
// auto child = *itNode;
// std::cout << "Node: " << child->node << std::endl;
// 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")) {
// style.style = std::stoi(child->attributes["style"]);
// } else {
// style.style = current.style;
// }
// if(child->attributes.contains("color")) {
// style.color = std::stoi(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() {
@ -165,11 +143,10 @@ float_t UILabelNew::getContentHeight() {
}
void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
std::cout << "Rebuffering" << std::endl;
auto oldTexts = this->texts;
textureMap.clear();
glm::vec2 position(32, 32);
glm::vec2 position(0, 0);
struct FontShaderBufferData fontData;
int32_t quadIndex = 0;
int32_t partIndex = 0;

View File

@ -11,7 +11,7 @@
namespace Dawn {
struct UILabelStyle {
struct Color color = COLOR_MAGENTA;
struct Color color = COLOR_WHITE;
flag_t style = 0;
uint32_t size = 16;
NewTrueTypeAsset *font = nullptr;

View File

@ -24,14 +24,15 @@ tool_texture(texture_eth FILE=${LIMINAL_ASSETS_DIR}/textures/eth.png)
tool_texture(texture_border FILE=${LIMINAL_ASSETS_DIR}/textures/texture_test.png)
tool_newtruetype(font_arial
# REGULAR="/usr/share/fonts/TTF/arial.ttf"
# BOLD="/usr/share/fonts/TTF/arialbd.ttf"
# ITALICS="/usr/share/fonts/TTF/ariali.ttf"
# BOLD_ITALICS="/usr/share/fonts/TTF/arialbi.ttf"
REGULAR="C:\\Windows\\Fonts\\arial.ttf"
BOLD="C:\\Windows\\Fonts\\arialbd.ttf"
ITALICS="C:\\Windows\\Fonts\\ariali.ttf"
BOLD_ITALICS="C:\\Windows\\Fonts\\arialbi.ttf"
REGULAR="/usr/share/fonts/TTF/arial.ttf"
BOLD="/usr/share/fonts/TTF/arialbd.ttf"
ITALICS="/usr/share/fonts/TTF/ariali.ttf"
BOLD_ITALICS="/usr/share/fonts/TTF/arialbi.ttf"
# REGULAR="C:\\Windows\\Fonts\\arial.ttf"
# BOLD="C:\\Windows\\Fonts\\arialbd.ttf"
# ITALICS="C:\\Windows\\Fonts\\ariali.ttf"
# BOLD_ITALICS="C:\\Windows\\Fonts\\arialbi.ttf"
)
tool_scene(${LIMINAL_ASSETS_DIR}/scenes/SceneBase.xml)

View File

@ -27,6 +27,7 @@ namespace Dawn {
auto newLabelItem = this->createSceneItem();
newLabelItem->transform.setParent(canvas->transform);
auto newLabel = newLabelItem->addComponent<UILabelNew>();
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>";
}
std::vector<Asset*> getRequiredAssets() override {

View File

@ -16,6 +16,7 @@ set(
set(D ${CMAKE_CURRENT_LIST_DIR})
set(
DAWN_SHARED_SOURCES
${D}/display/Color.cpp
${D}/assert/assert.cpp
${D}/util/Xml.cpp
${D}/util/UsageLock.cpp

View File

@ -0,0 +1,40 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
#include "util/parser/TypeParsers.hpp"
using namespace Dawn;
struct Color Color::fromString(std::string str) {
// Convert to lowercase
auto lower = stringToLowercase(str);
if(stringIncludes(lower, "cornflower")) {
return COLOR_CORNFLOWER_BLUE;
} else if(stringIncludes(lower, "magenta")) {
return COLOR_MAGENTA;
} else if(stringIncludes(lower, "white")) {
return COLOR_WHITE;
} else if(stringIncludes(lower, "black")) {
return COLOR_BLACK;
} else if(stringIncludes(lower, "red")) {
return COLOR_RED;
} else if(stringIncludes(lower, "green")) {
return COLOR_GREEN;
} else if(stringIncludes(lower, "blue")) {
return COLOR_BLUE;
}
// TODO: Parse other kinds of colors
assertUnreachable();
return {};
}

View File

@ -4,7 +4,8 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
#include "dawnsharedlibs.hpp"
#include "util/string.hpp"
namespace Dawn {
struct ColorU8 {
@ -13,6 +14,15 @@ namespace Dawn {
#pragma pack(push, 4)
struct Color {
/**
* Returns a color from a string.
*
* @param str String to parse.
* @return Color parsed.
*/
static struct Color fromString(std::string str);
float_t r, g, b, a;
struct Color operator * (const float_t &x) {

View File

@ -30,8 +30,6 @@ namespace Dawn {
static Xml load(std::string data);
static void load(Xml *xml, std::string data, size_t *j);
std::string node;
std::string value;
std::map<std::string, std::string> attributes;

View File

@ -0,0 +1,155 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "util/string.hpp"
namespace Dawn {
static inline std::string rawParser(std::string v, std::string *error) {
return v;
};
static inline std::string stringParser(std::string v, std::string *error) {
return "\"" + v + "\"";
};
static inline std::string floatParser(std::string v, std::string *error) {
v = stringTrim(v);
// Make sure number contains decimal
if(v.find(".") == std::string::npos) {
v += ".0";
}
// Make sure number contains a number before the decimal
if(v.find(".") == 0) {
v = "0" + v;
}
// Make sure ends with f
if(v.find("f") == std::string::npos) {
v += "f";
}
return v;
};
static inline std::string intParser(std::string v, std::string *error) {
v = stringTrim(v);
return v;
}
static inline std::string boolParser(std::string v, std::string *error) {
v = stringTrim(v);
if(v == "true") return "true";
if(v == "false") return "false";
*error = "Invalid bool value: " + v;
return std::string("");
}
static inline std::string vec2Parser(std::string v, std::string *error) {
// Split string by comma into two strings that we pass into float
auto split = stringSplit(v, ",");
if(split.size() != 2) {
*error = "Invalid vec2 value: " + v;
return std::string("");
}
return std::string(
"glm::vec2(" +
floatParser(split[0], error) + ", " +
floatParser(split[1], error) +
")"
);
};
static inline std::string vec3Parser(std::string v, std::string *error) {
// Split string by comma into two strings that we pass into float
auto split = stringSplit(v, ",");
if(split.size() != 3) {
*error = "Invalid vec3 value: " + v;
return std::string("");
}
return std::string(
"glm::vec3(" +
floatParser(split[0], error) + ", " +
floatParser(split[1], error) + ", " +
floatParser(split[2], error) +
")"
);
};
static inline std::string vec6Parser(std::string v, std::string *error) {
// Split string by comma into two strings that we pass into float
auto split = stringSplit(v, ",");
if(split.size() != 6) {
*error = "Invalid vec6 value: " + v;
return std::string("");
}
return std::string(
"glm::vec6(" +
floatParser(split[0], error) + ", " +
floatParser(split[1], error) + ", " +
floatParser(split[2], error) + ", " +
floatParser(split[3], error) + ", " +
floatParser(split[4], error) + ", " +
floatParser(split[5], error) +
")"
);
};
static inline std::string vec4Parser(std::string v, std::string *error) {
// Split string by comma into two strings that we pass into float
auto split = stringSplit(v, ",");
if(split.size() != 4) {
*error = "Invalid vec4 value: " + v;
return std::string("");
}
return std::string(
"glm::vec4(" +
floatParser(split[0], error) + ", " +
floatParser(split[1], error) + ", " +
floatParser(split[2], error) + ", " +
floatParser(split[3], error) +
")"
);
};
static inline std::string colorParser(std::string v, std::string *error) {
return rawParser(v, error);
}
static inline std::function<std::string(std::string, std::string*)> parserFromTypeName(std::string type) {
std::function<std::string(std::string, std::string*)> parser = rawParser;
if(type.find("string") != std::string::npos) {
parser = stringParser;
} else if(type.find("float") != std::string::npos) {
parser = floatParser;
} else if(type.find("Color") != std::string::npos) {
parser = colorParser;
} else if(type.find("vec2") != std::string::npos) {
parser = vec2Parser;
} else if(type.find("vec3") != std::string::npos) {
parser = vec3Parser;
} else if(type.find("vec4") != std::string::npos) {
parser = vec4Parser;
} else if(type == "int32_t" || type == "int") {
parser = intParser;
} else if(type == "bool_t") {
parser = boolParser;
} else if(type == "flag_t") {
parser = rawParser;
} else if(type.starts_with("enum")) {
parser = rawParser;
} else if(type.find("*") == (type.size() - 1)) {
type = type.substr(0, type.size() - 1);
parser = rawParser;
} else {
throw std::string("Invalid parser type");
}
return parser;
}
}

View File

@ -95,4 +95,34 @@ static inline std::string stringRTrim(const std::string &i) {
*/
static inline std::string stringTrim(const std::string &s) {
return stringLTrim(stringRTrim(s));
}
/**
* Checks if a string contains another string.
*
* @param haystack String to scan.
* @param needle String to search for.
* @return True if the string is found, false otherwise.
*/
static inline bool_t stringIncludes(const std::string &haystack, const std::string &needle) {
return haystack.find(needle) != std::string::npos;
}
/**
* Converts an entire string to lowercase.
*
* @param str String to convert.
* @return A new string with all lowercase characters.
*/
static inline std::string stringToLowercase(const std::string &str) {
std::string data = str;
std::transform(
data.begin(),
data.end(),
data.begin(),
[](char c) {
return std::tolower(c);
}
);
return data;
}