mirror of https://github.com/axmolengine/axmol.git
292 lines
8.7 KiB
C++
292 lines
8.7 KiB
C++
#include "TranslationHelper.h"
|
|
#include "PackageItem.h"
|
|
#include "UIPackage.h"
|
|
#if defined(ENGINEX_VERSION)
|
|
#include "pugixml/pugixml_imp.hpp"
|
|
#else
|
|
#include "tinyxml2/tinyxml2.h"
|
|
#endif
|
|
#include "utils/ByteBuffer.h"
|
|
|
|
USING_NS_CC;
|
|
NS_FGUI_BEGIN
|
|
|
|
using namespace std;
|
|
|
|
std::unordered_map<std::string, std::unordered_map<std::string, std::string>> TranslationHelper::strings;
|
|
|
|
void TranslationHelper::loadFromXML(const char* xmlString, size_t nBytes)
|
|
{
|
|
strings.clear();
|
|
|
|
#if defined(ENGINEX_VERSION)
|
|
pugi::xml_document doc;
|
|
if (doc.load_buffer(xmlString, nBytes)) {
|
|
auto root = doc.document_element();
|
|
auto ele = doc.child("string");
|
|
while (ele)
|
|
{
|
|
std::string key = ele.attribute("name").value();
|
|
std::string text = ele.text().as_string();
|
|
size_t i = key.find("-");
|
|
if (i == std::string::npos)
|
|
continue;
|
|
|
|
std::string key2 = key.substr(0, i);
|
|
std::string key3 = key.substr(i + 1);
|
|
std::unordered_map<std::string, std::string>& col = strings[key2];
|
|
col[key3] = text;
|
|
|
|
ele = ele.next_sibling("string");
|
|
}
|
|
}
|
|
#else
|
|
tinyxml2::XMLDocument* xml = new tinyxml2::XMLDocument();
|
|
xml->Parse(xmlString, nBytes);
|
|
|
|
tinyxml2::XMLElement* root = xml->RootElement();
|
|
tinyxml2::XMLElement* ele = root->FirstChildElement("string");
|
|
while (ele)
|
|
{
|
|
std::string key = ele->Attribute("name");
|
|
std::string text = ele->GetText();
|
|
size_t i = key.find("-");
|
|
if (i == std::string::npos)
|
|
continue;
|
|
|
|
std::string key2 = key.substr(0, i);
|
|
std::string key3 = key.substr(i + 1);
|
|
std::unordered_map<std::string, std::string>& col = strings[key2];
|
|
col[key3] = text;
|
|
|
|
ele = ele->NextSiblingElement("string");
|
|
}
|
|
|
|
delete xml;
|
|
#endif
|
|
}
|
|
|
|
void TranslationHelper::translateComponent(PackageItem* item)
|
|
{
|
|
if (strings.empty())
|
|
return;
|
|
|
|
auto col = strings.find(item->owner->getId() + item->id);
|
|
if (col == strings.end())
|
|
return;
|
|
|
|
std::unordered_map<std::string, std::string>& strings = col->second;
|
|
|
|
ByteBuffer* buffer = item->rawData;
|
|
|
|
buffer->seek(0, 2);
|
|
|
|
int childCount = buffer->readShort();
|
|
for (int i = 0; i < childCount; i++)
|
|
{
|
|
int dataLen = buffer->readShort();
|
|
int curPos = buffer->getPos();
|
|
|
|
buffer->seek(curPos, 0);
|
|
|
|
ObjectType baseType = (ObjectType)buffer->readByte();
|
|
ObjectType type = baseType;
|
|
|
|
buffer->skip(4);
|
|
const string& elementId = buffer->readS();
|
|
|
|
if (type == ObjectType::COMPONENT)
|
|
{
|
|
if (buffer->seek(curPos, 6))
|
|
type = (ObjectType)buffer->readByte();
|
|
}
|
|
|
|
buffer->seek(curPos, 1);
|
|
|
|
auto it = strings.find(elementId + "-tips");
|
|
if (it != strings.end())
|
|
buffer->writeS(it->second);
|
|
|
|
buffer->seek(curPos, 2);
|
|
|
|
int gearCnt = buffer->readShort();
|
|
for (int j = 0; j < gearCnt; j++)
|
|
{
|
|
int nextPos = buffer->readShort();
|
|
nextPos += buffer->getPos();
|
|
|
|
if (buffer->readByte() == 6) //gearText
|
|
{
|
|
buffer->skip(2); //controller
|
|
int valueCnt = buffer->readShort();
|
|
for (int k = 0; k < valueCnt; k++)
|
|
{
|
|
const string& page = buffer->readS();
|
|
if (!page.empty())
|
|
{
|
|
if ((it = strings.find(elementId + "-texts_" + Value(k).asString())) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
}
|
|
}
|
|
|
|
if (buffer->readBool() && (it = strings.find(elementId + "-texts_def")) != strings.end())
|
|
buffer->writeS(it->second);
|
|
}
|
|
|
|
buffer->setPos(nextPos);
|
|
}
|
|
|
|
if (baseType == ObjectType::COMPONENT && buffer->version >= 2)
|
|
{
|
|
buffer->seek(curPos, 4);
|
|
|
|
buffer->skip(2); //pageController
|
|
|
|
buffer->skip(4 * buffer->readShort());
|
|
|
|
int cpCount = buffer->readShort();
|
|
for (int k = 0; k < cpCount; k++)
|
|
{
|
|
std::string target = buffer->readS();
|
|
int propertyId = buffer->readShort();
|
|
if (propertyId == 0 && (it = strings.find(elementId + "-cp-" + target)) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
}
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case ObjectType::TEXT:
|
|
case ObjectType::RICHTEXT:
|
|
case ObjectType::INPUTTEXT:
|
|
{
|
|
if ((it = strings.find(elementId)) != strings.end())
|
|
{
|
|
buffer->seek(curPos, 6);
|
|
buffer->writeS(it->second);
|
|
}
|
|
if ((it = strings.find(elementId + "-prompt")) != strings.end())
|
|
{
|
|
buffer->seek(curPos, 4);
|
|
buffer->writeS(it->second);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ObjectType::LIST:
|
|
{
|
|
buffer->seek(curPos, 8);
|
|
buffer->skip(2);
|
|
int itemCount = buffer->readShort();
|
|
for (int j = 0; j < itemCount; j++)
|
|
{
|
|
int nextPos = buffer->readUshort();
|
|
nextPos += buffer->getPos();
|
|
|
|
buffer->skip(2); //url
|
|
if (type == ObjectType::TREE)
|
|
buffer->skip(2);
|
|
|
|
//title
|
|
if ((it = strings.find(elementId + "-" + Value(j).asString())) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
|
|
//selected title
|
|
if ((it = strings.find(elementId + "-" + Value(j).asString() + "-0")) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
|
|
if (buffer->version >= 2)
|
|
{
|
|
buffer->skip(6);
|
|
buffer->skip(buffer->readShort() * 4); //controllers
|
|
|
|
int cpCount = buffer->readShort();
|
|
for (int k = 0; k < cpCount; k++)
|
|
{
|
|
std::string target = buffer->readS();
|
|
int propertyId = buffer->readShort();
|
|
if (propertyId == 0 && (it = strings.find(elementId + "-" + Value(j).asString() + "-" + target)) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
}
|
|
}
|
|
|
|
buffer->setPos(nextPos);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ObjectType::LABEL:
|
|
{
|
|
if (buffer->seek(curPos, 6) && (ObjectType)buffer->readByte() == type)
|
|
{
|
|
if ((it = strings.find(elementId)) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
|
|
buffer->skip(2);
|
|
if (buffer->readBool())
|
|
buffer->skip(4);
|
|
buffer->skip(4);
|
|
if (buffer->readBool() && (it = strings.find(elementId + "-prompt")) != strings.end())
|
|
buffer->writeS(it->second);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ObjectType::BUTTON:
|
|
{
|
|
if (buffer->seek(curPos, 6) && (ObjectType)buffer->readByte() == type)
|
|
{
|
|
if ((it = strings.find(elementId)) != strings.end())
|
|
buffer->writeS(it->second);
|
|
else
|
|
buffer->skip(2);
|
|
if ((it = strings.find(elementId + "-0")) != strings.end())
|
|
buffer->writeS(it->second);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ObjectType::COMBOBOX:
|
|
{
|
|
if (buffer->seek(curPos, 6) && (ObjectType)buffer->readByte() == type)
|
|
{
|
|
int itemCount = buffer->readShort();
|
|
for (int j = 0; j < itemCount; j++)
|
|
{
|
|
int nextPos = buffer->readShort();
|
|
nextPos += buffer->getPos();
|
|
|
|
if ((it = strings.find(elementId + "-" + Value(j).asString())) != strings.end())
|
|
buffer->writeS(it->second);
|
|
|
|
buffer->setPos(nextPos);
|
|
}
|
|
|
|
if ((it = strings.find(elementId)) != strings.end())
|
|
buffer->writeS(it->second);
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
buffer->setPos(curPos + dataLen);
|
|
}
|
|
}
|
|
|
|
NS_FGUI_END
|