axmol/extensions/cocostudio/WidgetReader/TextReader/TextReader.cpp

576 lines
20 KiB
C++

#include "cocostudio/WidgetReader/TextReader/TextReader.h"
#include "ui/UIText.h"
#include "2d/CCLabel.h"
#include "platform/CCFileUtils.h"
#include "cocostudio/CocoLoader.h"
#include "cocostudio/CSParseBinary_generated.h"
#include "cocostudio/LocalizationManager.h"
#include "flatbuffers/flatbuffers.h"
USING_NS_CC;
using namespace ui;
using namespace flatbuffers;
namespace cocostudio
{
static const char* P_TouchScaleEnable = "touchScaleEnable";
static const char* P_Text = "text";
static const char* P_FontSize = "fontSize";
static const char* P_FontName = "fontName";
static const char* P_AreaWidth = "areaWidth";
static const char* P_AreaHeight = "areaHeight";
static const char* P_HAlignment = "hAlignment";
static const char* P_VAlignment = "vAlignment";
static TextReader* instanceTextReader = nullptr;
IMPLEMENT_CLASS_NODE_READER_INFO(TextReader)
TextReader::TextReader()
{
}
TextReader::~TextReader()
{
}
TextReader* TextReader::getInstance()
{
if (!instanceTextReader)
{
instanceTextReader = new (std::nothrow) TextReader();
}
return instanceTextReader;
}
void TextReader::destroyInstance()
{
CC_SAFE_DELETE(instanceTextReader);
}
void TextReader::setPropsFromBinary(cocos2d::ui::Widget *widget, CocoLoader *cocoLoader, stExpCocoNode *cocoNode)
{
this->beginSetBasicProperties(widget);
stExpCocoNode *stChildArray = cocoNode->GetChildArray(cocoLoader);
Text* label = static_cast<Text*>(widget);
std::string binaryFilePath = GUIReader::getInstance()->getFilePath();
for (int i = 0; i < cocoNode->GetChildNum(); ++i) {
std::string key = stChildArray[i].GetName(cocoLoader);
std::string value = stChildArray[i].GetValue(cocoLoader);
//read all basic properties of widget
CC_BASIC_PROPERTY_BINARY_READER
//read all color related properties of widget
CC_COLOR_PROPERTY_BINARY_READER
else if (key == P_TouchScaleEnable) {
label->setTouchScaleChangeEnabled(valueToBool(value));
}
else if(key == P_Text){
label->setString(value);
}else if(key == P_FontSize){
label->setFontSize(valueToInt(value));
}else if(key == P_FontName){
auto& fontFilePath = binaryFilePath.append(value);
label->setFontName(fontFilePath);
}else if(key == P_AreaWidth){
label->setTextAreaSize(Size(valueToFloat(value), label->getTextAreaSize().height));
}else if(key == P_AreaHeight){
label->setTextAreaSize(Size(label->getTextAreaSize().width, valueToFloat(value)));
}else if(key == P_HAlignment){
label->setTextHorizontalAlignment((TextHAlignment)valueToInt(value));
}else if(key == P_VAlignment){
label->setTextVerticalAlignment((TextVAlignment)valueToInt(value));
}
} //end of for loop
this->endSetBasicProperties(widget);
}
void TextReader::setPropsFromJsonDictionary(Widget *widget, const rapidjson::Value &options)
{
WidgetReader::setPropsFromJsonDictionary(widget, options);
std::string jsonPath = GUIReader::getInstance()->getFilePath();
Text* label = static_cast<Text*>(widget);
bool touchScaleChangeAble = DICTOOL->getBooleanValue_json(options, P_TouchScaleEnable);
label->setTouchScaleChangeEnabled(touchScaleChangeAble);
const char* text = DICTOOL->getStringValue_json(options, P_Text,"Text Label");
label->setString(text);
label->setFontSize(DICTOOL->getIntValue_json(options, P_FontSize,20));
std::string fontName = DICTOOL->getStringValue_json(options, P_FontName, "");
std::string fontFilePath = jsonPath.append(fontName);
if (FileUtils::getInstance()->isFileExist(fontFilePath))
{
label->setFontName(fontFilePath);
}
else{
label->setFontName(fontName);
}
bool aw = DICTOOL->checkObjectExist_json(options, P_AreaWidth);
bool ah = DICTOOL->checkObjectExist_json(options, P_AreaHeight);
if (aw && ah)
{
Size size = Size(DICTOOL->getFloatValue_json(options, P_AreaWidth),DICTOOL->getFloatValue_json(options,P_AreaHeight));
label->setTextAreaSize(size);
}
bool ha = DICTOOL->checkObjectExist_json(options, P_HAlignment);
if (ha)
{
label->setTextHorizontalAlignment((TextHAlignment)DICTOOL->getIntValue_json(options, P_HAlignment));
}
bool va = DICTOOL->checkObjectExist_json(options, P_VAlignment);
if (va)
{
label->setTextVerticalAlignment((TextVAlignment)DICTOOL->getIntValue_json(options, P_VAlignment));
}
WidgetReader::setColorPropsFromJsonDictionary(widget, options);
}
Offset<Table> TextReader::createOptionsWithFlatBuffers(pugi::xml_node objectData,
flatbuffers::FlatBufferBuilder *builder)
{
auto temp = WidgetReader::getInstance()->createOptionsWithFlatBuffers(objectData, builder);
auto widgetOptions = *(Offset<WidgetOptions>*)(&temp);
bool touchScaleEnabled = false;
bool isCustomSize = false;
std::string fontName;
int fontSize = 20;
std::string text = "Text Label";
bool isLocalized = false;
int areaWidth = 0;
int areaHeight = 0;
int h_alignment = 0;
int v_alignment = 0;
bool outlineEnabled = false;
Color4B outlineColor = Color4B::BLACK;
int outlineSize = 1;
bool shadowEnabled = false;
Color4B shadowColor = Color4B::BLACK;
Size shadowOffset = Size(2, -2);
int shadowBlurRadius = 0;
// since x-studio reader 10.0.593.0
bool glowEnabled = false;
Color4B glowColor = Color4B::BLACK;
bool boldEnabled = false, underlineEnabled = false, italicsEnabled = false, strikethroughEnabled = false;
std::string path;
std::string plistFile;
int resourceType = 0;
// attributes
auto attribute = objectData.first_attribute();
while (attribute)
{
std::string name = attribute.name();
std::string value = attribute.value();
if (name == "TouchScaleChangeAble")
{
touchScaleEnabled = (value == "True") ? true : false;
}
else if (name == "LabelText")
{
text = value;
}
else if (name == "IsLocalized")
{
isLocalized = (value == "True") ? true : false;
}
else if (name == "FontSize")
{
fontSize = atoi(value.c_str());
}
else if (name == "FontName")
{
fontName = value;
}
else if (name == "AreaWidth")
{
areaWidth = atoi(value.c_str());
}
else if (name == "AreaHeight")
{
areaHeight = atoi(value.c_str());
}
else if (name == "HorizontalAlignmentType")
{
if (value == "HT_Left")
{
h_alignment = 0;
}
else if (value == "HT_Center")
{
h_alignment = 1;
}
else if (value == "HT_Right")
{
h_alignment = 2;
}
}
else if (name == "VerticalAlignmentType")
{
if (value == "VT_Top")
{
v_alignment = 0;
}
else if (value == "VT_Center")
{
v_alignment = 1;
}
else if (value == "VT_Bottom")
{
v_alignment = 2;
}
}
else if (name == "IsCustomSize")
{
isCustomSize = (value == "True") ? true : false;
}
else if (name == "OutlineEnabled")
{
outlineEnabled = (value == "True") ? true : false;
}
else if (name == "OutlineSize")
{
outlineSize = atoi(value.c_str());
}
else if (name == "ShadowEnabled")
{
shadowEnabled = (value == "True") ? true : false;
}
else if (name == "ShadowOffsetX")
{
shadowOffset.width = atof(value.c_str());
}
else if (name == "ShadowOffsetY")
{
shadowOffset.height = atof(value.c_str());
}
else if (name == "ShadowBlurRadius")
{
shadowBlurRadius = atoi(value.c_str());
}
else if (name == "GlowEnabled") {
glowEnabled = (value == "True") ? true : false;
}
else if (name == "BoldEnabled")
{
boldEnabled = (value == "True") ? true : false;
}
else if (name == "UnderlineEnabled") {
underlineEnabled = (value == "True") ? true : false;
}
else if (name == "ItalicsEnabled") {
italicsEnabled = (value == "True") ? true : false;
}
else if (name == "StrikethroughEnabled") {
strikethroughEnabled = (value == "True") ? true : false;
}
attribute = attribute.next_attribute();
}
// child elements
auto child = objectData.first_child();
while (child)
{
std::string name = child.name();
if (name == "FontResource")
{
attribute = child.first_attribute();
while (attribute)
{
name = attribute.name();
std::string value = attribute.value();
if (name == "Path")
{
path = value;
}
else if (name == "Type")
{
resourceType = 0;
}
else if (name == "Plist")
{
plistFile = value;
}
attribute = attribute.next_attribute();
}
}
else if (name == "OutlineColor")
{
attribute = child.first_attribute();
while (attribute)
{
name = attribute.name();
std::string value = attribute.value();
if (name == "A")
{
outlineColor.a = atoi(value.c_str());
}
else if (name == "R")
{
outlineColor.r = atoi(value.c_str());
}
else if (name == "G")
{
outlineColor.g = atoi(value.c_str());
}
else if (name == "B")
{
outlineColor.b = atoi(value.c_str());
}
attribute = attribute.next_attribute();
}
}
else if (name == "ShadowColor")
{
attribute = child.first_attribute();
while (attribute)
{
name = attribute.name();
std::string value = attribute.value();
if (name == "A")
{
shadowColor.a = atoi(value.c_str());
}
else if (name == "R")
{
shadowColor.r = atoi(value.c_str());
}
else if (name == "G")
{
shadowColor.g = atoi(value.c_str());
}
else if (name == "B")
{
shadowColor.b = atoi(value.c_str());
}
attribute = attribute.next_attribute();
}
}
else if(name == "GlowColor") {
attribute = child.first_attribute();
while (attribute)
{
name = attribute.name();
std::string value = attribute.value();
if (name == "A")
{
glowColor.a = atoi(value.c_str());
}
else if (name == "R")
{
glowColor.r = atoi(value.c_str());
}
else if (name == "G")
{
glowColor.g = atoi(value.c_str());
}
else if (name == "B")
{
glowColor.b = atoi(value.c_str());
}
attribute = attribute.next_attribute();
}
}
child = child.next_sibling();
}
flatbuffers::Color f_outlineColor(outlineColor.a, outlineColor.r, outlineColor.g, outlineColor.b);
flatbuffers::Color f_shadowColor(shadowColor.a, shadowColor.r, shadowColor.g, shadowColor.b);
flatbuffers::Color f_glowColor(glowColor.a, glowColor.r, glowColor.g, glowColor.b);
auto options = CreateTextOptions(*builder,
widgetOptions,
CreateResourceData(*builder,
builder->CreateString(path),
builder->CreateString(plistFile),
resourceType),
builder->CreateString(fontName),
fontSize,
builder->CreateString(text),
areaWidth,
areaHeight,
h_alignment,
v_alignment,
touchScaleEnabled,
isCustomSize,
outlineEnabled,
&f_outlineColor,
outlineSize,
shadowEnabled,
&f_shadowColor,
shadowOffset.width,
shadowOffset.height,
shadowBlurRadius,
isLocalized,
glowEnabled,
&f_glowColor, boldEnabled, underlineEnabled, italicsEnabled, strikethroughEnabled);
return *(Offset<Table>*)(&options);
}
void TextReader::setPropsWithFlatBuffers(cocos2d::Node *node, const flatbuffers::Table *textOptions)
{
Text* label = static_cast<Text*>(node);
auto options = (TextOptions*)textOptions;
bool touchScaleEnabled = options->touchScaleEnable() != 0;
label->setTouchScaleChangeEnabled(touchScaleEnabled);
int fontSize = options->fontSize();
label->setFontSize(fontSize);
Size areaSize = Size(options->areaWidth(), options->areaHeight());
if (!areaSize.equals(Size::ZERO))
{
label->setTextAreaSize(areaSize);
}
auto resourceDataDic = (options->fontResource());
std::string path = resourceDataDic->path()->c_str();
if (!path.empty() && FileUtils::getInstance()->isFileExist(path))
{
label->setFontName(path);
}
else
{
path = options->fontName()->c_str();
label->setFontName(path);
}
TextHAlignment h_alignment = (TextHAlignment)options->hAlignment();
label->setTextHorizontalAlignment(h_alignment);
TextVAlignment v_alignment = (TextVAlignment)options->vAlignment();
label->setTextVerticalAlignment((TextVAlignment)v_alignment);
bool outlineEnabled = options->outlineEnabled() != 0;
if (outlineEnabled)
{
auto f_outlineColor = options->outlineColor();
if (f_outlineColor)
{
Color4B outlineColor(f_outlineColor->r(), f_outlineColor->g(), f_outlineColor->b(), f_outlineColor->a());
label->enableOutline(outlineColor, options->outlineSize());
}
}
bool shadowEnabled = options->shadowEnabled() != 0;
if (shadowEnabled)
{
auto f_shadowColor = options->shadowColor();
if (f_shadowColor)
{
Color4B shadowColor(f_shadowColor->r(), f_shadowColor->g(), f_shadowColor->b(), f_shadowColor->a());
label->enableShadow(shadowColor, Size(options->shadowOffsetX(), options->shadowOffsetY()), options->shadowBlurRadius());
}
}
if (options->glowEnabled() != 0) {
auto f_glowColor = options->glowColor();
if (f_glowColor)
{
Color4B glowColor(f_glowColor->r(), f_glowColor->g(), f_glowColor->b(), f_glowColor->a());
label->enableGlow(glowColor);
}
}
std::string text = options->text()->c_str();
bool isLocalized = options->isLocalized() != 0;
if (isLocalized)
{
ILocalizationManager* lm = LocalizationHelper::getCurrentManager();
label->setString(lm->getLocalizationString(text));
}
else
{
label->setString(text);
}
// Save node color before set widget properties
auto oldColor = node->getColor();
auto widgetReader = WidgetReader::getInstance();
widgetReader->setPropsWithFlatBuffers(node, (Table*)options->widgetOptions());
// restore node color and set color to text to fix shadow & outline color won't show correct bug
node->setColor(oldColor);
auto optionsWidget = (WidgetOptions*)options->widgetOptions();
auto f_color = optionsWidget->color();
Color4B color(f_color->r(), f_color->g(), f_color->b(), f_color->a());
((Text *)node)->setTextColor(color);
label->setUnifySizeEnabled(false);
bool IsCustomSize = options->isCustomSize() != 0;
label->ignoreContentAdaptWithSize(!IsCustomSize);
auto widgetOptions = options->widgetOptions();
if (!label->isIgnoreContentAdaptWithSize())
{
Size contentSize(widgetOptions->size()->width(), widgetOptions->size()->height());
label->setContentSize(contentSize);
}
auto labelRenderer = dynamic_cast<cocos2d::Label*>(label->getVirtualRenderer());
if (options->boldEnabled())
labelRenderer->enableBold();
if (options->underlineEnabled())
labelRenderer->enableUnderline();
if (options->italicsEnabled())
labelRenderer->enableItalics();
if (options->strikethroughEnabled())
labelRenderer->enableStrikethrough();
}
Node* TextReader::createNodeWithFlatBuffers(const flatbuffers::Table *textOptions)
{
Text* text = Text::create();
setPropsWithFlatBuffers(text, (Table*)textOptions);
return text;
}
}