前端之家收集整理的这篇文章主要介绍了
cocostudio: GUIReader分析(1),
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
GUIReader分析(1):
1、GUIReader用于cocostudio所做UI界面导出json的解析,
并生成对应的UI元素。
GUIReader* GUIReader::shareReader()
{
if (!sharedReader)
{
sharedReader = new GUIReader();
}
return sharedReader;
}
2、主要函数:
cocos2d::ui::Widget* widgetFromJsonFile(const char* fileName);
-----源码-->>>
//解析json文件
cocos2d::ui::Widget* GUIReader::widgetFromJsonFile(const char *fileName)
{
unsigned char *pBytes = NULL;
std::string jsonpath;
rapidjson::Document jsonDict;
//获取json文件的全路径
jsonpath = CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName);
int pos = jsonpath.find_last_of('/');
m_strFilePath = jsonpath.substr(0,pos+1);
unsigned long size = 0;
//读取json文件
pBytes = CCFileUtils::sharedFileUtils()->getFileData(jsonpath.c_str(),"r",&size);
if(NULL == pBytes || strcmp((const char*)pBytes,"") == 0)
{
printf("read json file[%s] error!\n",fileName);
return NULL;
}
CCData *data = new CCData(pBytes,size);
std::string load_str = std::string((const char *)data->getBytes(),data->getSize() );
CC_SAFE_DELETE(data);
//解析json文件内容
jsonDict.Parse<0>(load_str.c_str());
if (jsonDict.HasParseError())
{
CCLOG("GetParseError %s\n",jsonDict.GetParseError());
}
cocos2d::ui::Widget* widget = NULL;
//DICTOOL获取json信息的工具类#define DICTOOL DictionaryHelper::shareHelper()
//得到json文件的版本,即使用那个版本的cocostudio做的
const char* fileVersion = DICTOOL->getStringValue_json(jsonDict,"version");
WidgetPropertiesReader * pReader = NULL;
if (fileVersion)
{
//根据不同的版本去掉用不同的解析类,如 "version": "1.6.0.0",versionInteger = 1600
//所以我们这里使用WidgetPropertiesReader0300
int versionInteger = getVersionInteger(fileVersion);
if (versionInteger < 250)
{
pReader = new WidgetPropertiesReader0250();
widget = pReader->createWidget(jsonDict,m_strFilePath.c_str(),fileName);
}
else
{
pReader = new WidgetPropertiesReader0300();
widget = pReader->createWidget(jsonDict,fileName);
}
}
else
{
pReader = new WidgetPropertiesReader0250();
widget = pReader->createWidget(jsonDict,fileName);
}
CC_SAFE_DELETE(pReader);
CC_SAFE_DELETE_ARRAY(pBytes);
return widget;
}
3、WidgetPropertiesReader0300类的分析:
3.1、
//jsonDict -- 解析后的json数据
//m_strFilePath -- json文件所在目录的全路径,不包含json文件名
//fileName -- json文件名
createWidget(jsonDict,fileName)方法:
----->>>>
/*0.3.0.0~1.0.0.0*/ 这里有点疑惑,看到这个注释我以为WidgetPropertiesReader0300用来解析0.3.0.0~1.0.0.0的版本,
//但是我调试了下,想我上面分析的那样,我是用cocostudio的版本是1.6.0.0,
//"version": "1.6.0.0",versionInteger = 1600,大于250,所以使用的是WidgetPropertiesReader0300解析。
//所以忽略这个注释。
cocos2d::ui::Widget* WidgetPropertiesReader0300::createWidget(const rapidjson::Value& data,const char* fullPath,const char* fileName)
{
m_strFilePath = fullPath;
/*如果我们在制作界面的过程中使用了.plist问价,那么生成的json文件中会有
textures 字段,如下所示:
"textures": [
"hero.plist"
]
*/
int texturesCount = DICTOOL->getArrayCount_json(data,"textures");
//.plist文件,用CCSpriteFrameCache加载,路径为json文件的全路径目录部分 + "xx.plist"
for (int i=0; i<texturesCount; i++)
{
const char* file = DICTOOL->getStringValueFromArray_json(data,"textures",i);
std::string tp = fullPath;
tp.append(file);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(tp.c_str());
}
/*
"designHeight": 640,"designWidth": 960,*/
float fileDesignWidth = DICTOOL->getFloatValue_json(data,"designWidth");
float fileDesignHeight = DICTOOL->getFloatValue_json(data,"designHeight");
if (fileDesignWidth <= 0 || fileDesignHeight <= 0) {
printf("Read design size error!\n");
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
GUIReader::shareReader()->storeFileDesignSize(fileName,winSize);
}
else
{
GUIReader::shareReader()->storeFileDesignSize(fileName,CCSizeMake(fileDesignWidth,fileDesignHeight));
}
/*
"widgetTree": {
"classname": "Panel","name": null,"children": [
*/
//解析UI树,生成UI
const rapidjson::Value& widgetTree = DICTOOL->getSubDictionary_json(data,"widgetTree");
cocos2d::ui::Widget* widget = widgetFromJsonDictionary(widgetTree);
/* *********temp********* */
if (widget->getContentSize().equals(CCSizeZero))
{
widget->setSize(CCSizeMake(fileDesignWidth,fileDesignHeight));
}
/* ********************** */
// widget->setFileDesignSize(CCSizeMake(fileDesignWidth,fileDesignHeight));
const rapidjson::Value& actions = DICTOOL->getSubDictionary_json(data,"animation");
/* *********temp********* */
// ActionManager::shareManager()->releaseActions();
/* ********************** */
CCLOG("file name == [%s]",fileName);
CCObject* rootWidget = (CCObject*) widget;
ActionManager::shareManager()->initWithDictionary(fileName,actions,rootWidget);
return widget;
}
------>>>>
widgetFromJsonDictionary:
//根据json文件生成UI树
cocos2d::ui::Widget* WidgetPropertiesReader0300::widgetFromJsonDictionary(const rapidjson::Value& data)
{
//获取类名,如: "classname": "Panel"
const char* classname = DICTOOL->getStringValue_json(data,"classname");
const rapidjson::Value& uiOptions = DICTOOL->getSubDictionary_json(data,"options");
//根据类名创建不同的对象,在GUIReader构造函数中,注册了很多类的创建函数。
/*
在GUIReader::GUIReader()
{
ObjectFactory* factoryCreate = ObjectFactory::getInstance();
factoryCreate->registerType(CREATE_CLASS_WIDGET_READER_INFO(ButtonReader));
.......
factoryCreate->registerType(CREATE_CLASS_GUI_INFO(Button));
.............
}
*/
cocos2d::ui::Widget* widget = ObjectFactory::getInstance()->createGUI(classname);
// create widget reader to parse properties of widget
// 得到不同UI元素的对应的不同解析类,如ButtonReader,CheckBoxReader等等
std::string readerName = getWidgetReaderClassName(classname);
WidgetReaderProtocol* reader = this->createWidgetReaderProtocol(readerName);
if (reader)
{
// widget parse with widget reader
setPropsForAllWidgetFromJsonDictionary(reader,widget,uiOptions);
}
else
{
// 1st.,custom widget parse properties of parent widget with parent widget reader
// 自定义控件
readerName = this->getWidgetReaderClassName(widget);
reader = this->createWidgetReaderProtocol(readerName);
if (reader && widget) {
setPropsForAllWidgetFromJsonDictionary(reader,uiOptions);
// 2nd.,custom widget parse with custom reader
const char* customProperty = DICTOOL->getStringValue_json(uiOptions,"customProperty");
rapidjson::Document customJsonDict;
customJsonDict.Parse<0>(customProperty);
if (customJsonDict.HasParseError())
{
CCLOG("GetParseError %s\n",customJsonDict.GetParseError());
}
setPropsForAllCustomWidgetFromJsonDictionary(classname,customJsonDict);
}else{
CCLOG("Widget or WidgetReader doesn't exists!!! Please check your json file.");
}
}
//遍历子节点UI树,生成整个UI树,最终返回根节点
int childrenCount = DICTOOL->getArrayCount_json(data,"children");
for (int i = 0; i < childrenCount; i++)
{
const rapidjson::Value& subData = DICTOOL->getDictionaryFromArray_json(data,"children",i);
cocos2d::ui::Widget* child = widgetFromJsonDictionary(subData);
if (child)
{
PageView* pageView = dynamic_cast<PageView*>(widget);
if (pageView)
{
pageView->addPage(static_cast<Layout*>(child));
}
else
{
ListView* listView = dynamic_cast<ListView*>(widget);
if (listView)
{
listView->pushBackCustomItem(child);
}
else
{
widget->addChild(child);
}
}
}
}
return widget;
}
原文链接:https://www.f2er.com/cocos2dx/343039.html