项目需要,根据输入字符串,计算字符串所需要占的Size。封装代码如下,只需传入字符串,即可返回Size:
Size ChartDemoScene::calculateFontSize(const char *str ) { std::string tempString = str; log("tempString = %s",tempString.c_str()); size_t computeCount = tempString.size(); //如果字符串很长每次抽取100个字符来计算size; Size size = Size(0,0); for (int i = 0; i<computeCount ;) { std::string substring = tempString.substr(i,1); if ((substring.c_str()[0] & 0x80 )!=0) //是汉字 { substring = tempString.substr(i,3); i += 3; } else { i++; } //CCLog("subString = %s ",substring.c_str()); auto tempLabel = LabelTTF::create(substring.c_str(),"",25); tempLabel->setHorizontalAlignment(cocos2d::TextHAlignment::LEFT); Size tmpLsize = tempLabel->getContentSize(); size.width+=tmpLsize.width; } float fHeight= 0; if( size.width > chartWidth)//大于容器的宽度 { fHeight = (size.width / 200 );//计算需要多少行 } int nHeight = ceil(fHeight); if (nHeight == 0) { nHeight = 1; } Size labelSize ; if (size.width < chartWidth) { labelSize = Size(size.width,nHeight*32);//计算容器的Size } else { labelSize = Size(chartWidth,nHeight*28); } //CCLog("labelSize = (%f,%f)",labelSize.width,labelSize.height); //CCLog("fHeight = %f nHeight = %d ",fHeight,nHeight); return labelSize; }
例子:
auto scene = ChartDemoScene::createScene(); // run director->runWithScene(scene);(1)ChartDemoScene.hChartDemoScene.h
// // ChartDemoScene.h // chartDemo // // Created by chen on 14-9-2. // // #ifndef __chartDemo__ChartDemoScene__ #define __chartDemo__ChartDemoScene__ #include "cocos2d.h" #include "ui/CocosGUI.h" #include "../cocos2d/extensions/cocos-ext.h" using namespace cocos2d::ui; USING_NS_CC; USING_NS_CC_EXT; class ChartDemoScene : public cocos2d::Layer//,public cocos2d::extension::EditBoxDelegate { public: // there's no 'id' in cpp,so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'id' in cocos2d-iphone virtual bool init(); // a selector callback void menuCloseCallback(cocos2d::Ref* pSender); // implement the "static create()" method manually CREATE_FUNC(ChartDemoScene); // virtual void editBoxEditingDidBegin(cocos2d::extension::EditBox* editBox); // virtual void editBoxEditingDidEnd(cocos2d::extension::EditBox* editBox); // virtual void editBoxTextChanged(cocos2d::extension::EditBox* editBox,const std::string& text); // virtual void editBoxReturn(cocos2d::extension::EditBox* editBox); void touchEvent(Ref *pSender,Widget::TouchEventType type); void textFieldEvent(Ref* pSender,TextField::EventType type); void showAlertShow(std::string contentString); void alertCallback(ui::Text* alert); Size calculateFontSize(const char *str); std::string getcurrTime();//获取当前年月日 std::string getcurrMonthTime();//获取时分秒 // EditBox* editText; TextField* editText; Text* text; TextField* _text;//获取被删除Item的内容 std::string file_path;//存放消息记录 TextField* textContent; ui::Button* sendBtn; std::string str; Size winSize; float chartWidth; size_t length; ui::ListView* _listView; }; #endif /* defined(__chartDemo__ChartDemoScene__) */
(2)ChartDemoScene.cpp
#include "ChartDemoScene.h" #include "stdio.h" enum alertTag { Alert_Tag = 1000 }AlertTag; enum textTag { T_Tag = 100 }TextTag; USING_NS_CC; int count = 1; int _rem = 0; Scene* ChartDemoScene::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); scene->setColor(Color3B::BLACK); // 'layer' is an autorelease object auto layer = ChartDemoScene::create(); layer->setAnchorPoint(Vec2::ANCHOR_MIDDLE_BOTTOM); layer->setContentSize(Size(640,960)); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool ChartDemoScene::init() { bool bRet = false; do{ CC_BREAK_IF(!Layer::init()); //大背景 winSize = Director::getInstance()->getWinSize(); file_path = FileUtils::getInstance()->getWritablePath() + "chartContent.txt"; chartWidth = winSize.width *3 / 5; auto sprite = Sprite::create("orange_edit.png"); sprite->setScaleX(winSize.width / sprite->getContentSize().width); sprite->setScaleY(winSize.height / sprite->getContentSize().height); sprite->setAnchorPoint(Vec2::ANCHOR_MIDDLE); sprite->setPosition(Vec2(winSize.width/2,winSize.height/2)); addChild(sprite); auto layerColor = LayerColor::create(Color4B(43,177,233,255)); layerColor->setContentSize(Size(winSize.width,100)); layerColor->ignoreAnchorPointForPosition(false); layerColor->setAnchorPoint(Vec2::ANCHOR_MIDDLE_TOP); layerColor->setPosition(Vec2(winSize.width/2,winSize.height)); addChild(layerColor,4); //底部输入栏 auto layout = Layout::create(); layout->setSize(Size(winSize.width,100)); layout->setAnchorPoint(Vec2::ZERO); layout->setPosition(Vec2::ZERO); layout->setBackGroundColorType(cocos2d::ui::Layout::BackGroundColorType::SOLID); layout->setBackGroundColor(Color3B(185,185,185)); //消息显示栏 _listView = ListView::create(); _listView->setDirection(ui::ScrollView::Direction::VERTICAL); _listView->setTouchEnabled(true); _listView->setBounceEnabled(true); _listView->setGravity(cocos2d::ui::ListView::Gravity::BOTTOM); // _listView->setItemsMargin(2); _listView->setBackGroundColorType(cocos2d::ui::Layout::BackGroundColorType::SOLID); _listView->setBackGroundColor(Color3B::WHITE); _listView->setSize(Size(winSize.width,winSize.height-layout->getSize().height-25-100)); _listView->setAnchorPoint(Vec2::ANCHOR_MIDDLE_BOTTOM); _listView->setPosition(Vec2(winSize.width/2,layout->getSize().height+25)); addChild(_listView); //底部输入框背景 auto bg = Sprite::create("whitebg.png"); bg->setScaleX(winSize.width*3/5 / bg->getContentSize().width); bg->setScaleY(80 / bg->getContentSize().height); bg->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); bg->setPosition(Vec2(winSize.width/5,layout->getSize().height/2)); layout->addChild(bg); // editText = TextField::create("",30); editText->ignoreContentAdaptWithSize(false); editText->setSize(Size(winSize.width*3/5,80)); editText->setTextHorizontalAlignment(cocos2d::TextHAlignment::LEFT); editText->setTextVerticalAlignment(cocos2d::TextVAlignment::BOTTOM); editText->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); editText->setPosition(Vec2(winSize.width/5,layout->getSize().height/2)); editText->setColor(Color3B::BLACK); editText->addEventListener(CC_CALLBACK_2(ChartDemoScene::textFieldEvent,this)); layout->addChild(editText); addChild(layout); //发送按钮 sendBtn = ui::Button::create("orange_edit.png"); sendBtn->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT); sendBtn->setPosition(Vec2(winSize.width - 20,layout->getSize().height/2)); addChild(sendBtn); sendBtn->addTouchEventListener(CC_CALLBACK_2(ChartDemoScene::touchEvent,this)); auto alert_Text = ui::Text::create(); alert_Text->setSize(Size(50,200)); alert_Text->setTag(Alert_Tag); alert_Text->setOpacity(0); alert_Text->setFontSize(35); char* userdata = "11"; alert_Text->setUserData(userdata); alert_Text->setColor(Color3B::BLACK); alert_Text->setPosition(Vec2(winSize.width/2,winSize.height/8)); addChild(alert_Text); bRet = true; }while(0); return bRet; } Size ChartDemoScene::calculateFontSize(const char *str ) { std::string tempString = str; log("tempString = %s",25); tempLabel->setHorizontalAlignment(cocos2d::TextHAlignment::LEFT); Size tmpLsize = tempLabel->getContentSize(); size.width+=tmpLsize.width; } float fHeight= 0; if( size.width > chartWidth) { fHeight = (size.width / 200 ); } int nHeight = ceil(fHeight); if (nHeight == 0) { nHeight = 1; } Size labelSize ; if (size.width < chartWidth) { labelSize = Size(size.width,nHeight*32); } else { labelSize = Size(chartWidth,nHeight); return labelSize; } void ChartDemoScene::touchEvent(cocos2d::Ref *pSender,Widget::TouchEventType type) { switch (type) { case ui::Widget::TouchEventType::ENDED: { if(str.empty()) { showAlertShow("输入内容不能为空"); break; } log("str = %s",str.c_str()); auto time = getcurrMonthTime().c_str(); auto text = Text::create(time,30); text->setAnchorPoint(Vec2::ANCHOR_MIDDLE); text->setColor(Color3B::BLACK); auto _timeLayout = Layout::create(); _timeLayout->setSize(Size(_listView->getSize().width,60)); _timeLayout->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); auto rp_time = RelativeLayoutParameter::create(); rp_time->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT); text->setLayoutParameter(rp_time); _timeLayout->addChild(text); _listView->pushBackCustomItem(_timeLayout); if(count % 2) { count++; auto _lLayout = Layout::create(); _lLayout->setSize(Size(_listView->getSize().width,80)); _lLayout->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); auto _lHeader = ui::ImageView::create("logo_douban.png"); _lHeader->setAnchorPoint(Vec2::ANCHOR_MIDDLE); _lHeader->setScale(0.5); auto rp_l = RelativeLayoutParameter::create(); rp_l->setMargin(Margin(10,0)); rp_l->setRelativeName("head"); rp_l->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_CENTER_VERTICAL); _lHeader->setLayoutParameter(rp_l); _lLayout->addChild(_lHeader); auto _lTextContent = TextField::create("",30); _lTextContent->ignoreContentAdaptWithSize(false); auto size = calculateFontSize(str.c_str()); _lTextContent->setSize(size); _lTextContent->setTextHorizontalAlignment(cocos2d::TextHAlignment::LEFT); if(size.width < chartWidth) { _lTextContent->setTextHorizontalAlignment(cocos2d::TextHAlignment::RIGHT); } _lTextContent->setTextVerticalAlignment(cocos2d::TextVAlignment::CENTER); _lTextContent->setTouchEnabled(false); _lTextContent->setTag(T_Tag); _lTextContent->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); _lTextContent->setColor(Color3B::BLACK); _lTextContent->setText(str); _lLayout->addChild(_lTextContent); str.clear(); auto rp_t = RelativeLayoutParameter::create(); rp_t->setMargin(Margin(10,0)); rp_t->setRelativeToWidgetName("head"); rp_t->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_CENTER); _lTextContent->setLayoutParameter(rp_t); _listView->pushBackCustomItem(_lLayout); }else { count++; auto _rLayout = Layout::create(); _rLayout->setSize(Size(_listView->getSize().width,80)); _rLayout->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); auto _rHeader = ui::ImageView::create("logo_mingdao.png"); _rHeader->setAnchorPoint(Vec2::ANCHOR_MIDDLE); _rHeader->setScale(0.5); auto rp_r = RelativeLayoutParameter::create(); rp_r->setMargin(Margin(0,10,0)); rp_r->setRelativeName("head"); rp_r->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_CENTER_VERTICAL); _rHeader->setLayoutParameter(rp_r); _rLayout->addChild(_rHeader); auto _rTextContent = TextField::create("",30); _rTextContent->setTag(T_Tag); _rTextContent->ignoreContentAdaptWithSize(false); auto size = calculateFontSize(str.c_str()); _rTextContent->setSize(size); _rTextContent->setTextHorizontalAlignment(cocos2d::TextHAlignment::LEFT); _rTextContent->setTextVerticalAlignment(cocos2d::TextVAlignment::CENTER); _rTextContent->setTouchEnabled(false); _rTextContent->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT); _rTextContent->setColor(Color3B::BLACK); _rTextContent->setText(str); str.clear(); auto rp_l = RelativeLayoutParameter::create(); rp_l->setMargin(Margin(0,0)); rp_l->setRelativeToWidgetName("head"); rp_l->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_CENTER); _rTextContent->setLayoutParameter(rp_l); _rLayout->addChild(_rTextContent); _listView->pushBackCustomItem(_rLayout); } // if(_listView->getContentSize().height > _listView->getSize().height) // { _listView->scrollToBottom(0.5,true); // } editText->setText(""); if(count > 3 ) { _listView->removeItem(0);//删除时间标签,此时Item(0)就是内容标签 auto temp = static_cast<Layout*>(_listView->getItem(0));//获取当前内容标签 if(_text) { removeChild(_text); } _text = static_cast<TextField*>(temp->getChildByTag(T_Tag));//获取内容标签 log("string = %s",_text->getStringValue().c_str());//获取内容 log("file_path = %s",file_path.c_str()); FILE* fp = std::fopen(file_path.c_str(),"at+"); CCASSERT(fp != NULL,"file open error"); length = _text->getStringValue().length(); log("length = %lu",length); fwrite(_text->getStringValue().c_str(),length,1,fp); fclose(fp); _listView->removeItem(0); } break; } default: break; } } void ChartDemoScene::textFieldEvent(cocos2d::Ref *pSender,TextField::EventType type) { switch (type) { case TextField::EventType::ATTACH_WITH_IME: { TextField* textField = dynamic_cast<TextField*>(pSender); Size widgetSize = winSize; runAction(CCMoveTo::create(0.225f,Vec2(0,widgetSize.height / 2.0f))); textField->setTextHorizontalAlignment(TextHAlignment::LEFT); textField->setTextVerticalAlignment(TextVAlignment::TOP); } break; case TextField::EventType::DETACH_WITH_IME: { TextField* textField = dynamic_cast<TextField*>(pSender); Size widgetSize = winSize; runAction(CCMoveTo::create(0.175f,0))); textField->setTextHorizontalAlignment(TextHAlignment::LEFT); textField->setTextVerticalAlignment(TextVAlignment::CENTER); str = editText->getStringValue().c_str(); str += "\n"; } break; case TextField::EventType::INSERT_TEXT: break; case TextField::EventType::DELETE_BACKWARD: break; default: break; } } void ChartDemoScene::showAlertShow(std::string contentString) { auto alert = dynamic_cast<ui::Text*>(getChildByTag(Alert_Tag)); if (alert->getUserData() == "11") { alert->setOpacity(255); char* userdata = "110"; alert->setUserData(userdata); alert->setString(contentString); auto call_func = CallFunc::create(CC_CALLBACK_0(ChartDemoScene::alertCallback,this,alert)); auto seq = Sequence::create(FadeOut::create(1.0f),call_func,NULL); alert->runAction(seq); } } void ChartDemoScene::alertCallback(ui::Text* alert) { alert->setString(""); char* userdata = "11"; alert->setUserData(userdata); } std::string ChartDemoScene::getcurrTime()//获取当前年月日 { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) struct timeval now; struct tm* time; gettimeofday(&now,NULL); time = localtime(&now.tv_sec); int year = time->tm_year + 1900; char date[32] = {0}; sprintf(date,"%d-%02d-%02d",(int)time->tm_year + 1900,(int)time->tm_mon + 1,(int)time->tm_mday); return StringUtils::format("%s",date); #endif #if ( CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 ) struct tm* tm; time_t timep; time(timep); tm = localtime(&timep); char date[32] = {0}; sprintf(date,date); #endif } std::string ChartDemoScene::getcurrMonthTime() { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) struct timeval now; struct tm* time; gettimeofday(&now,NULL); time = localtime(&now.tv_sec); int year = time->tm_year + 1900; log("year = %d",year); char date1[24] = {0}; char date[8] = {0}; sprintf(date1,"%d:%02d:%02d:%02d:%02d:%02d",(int)time->tm_mday,time->tm_hour,time->tm_min,time->tm_sec); sprintf(date,"%02d:%02d",time->tm_min); return StringUtils::format("%s",date); #endif } void ChartDemoScene::menuCloseCallback(Ref* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); return; #endif Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif }原文链接:https://www.f2er.com/cocos2dx/347036.html