From 58435be5ccdd836540a8f3b42a0476f6dc88efa3 Mon Sep 17 00:00:00 2001 From: B_y <342854406@qq.com> Date: Sat, 4 Apr 2015 22:35:07 +0800 Subject: [PATCH 1/4] Update UIRichText.h support underline/outline label/sprite cache --- cocos/ui/UIRichText.h | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/cocos/ui/UIRichText.h b/cocos/ui/UIRichText.h index cab8927b5c28..b397ccf4c206 100644 --- a/cocos/ui/UIRichText.h +++ b/cocos/ui/UIRichText.h @@ -26,12 +26,16 @@ #define __UIRICHTEXT_H__ #include "ui/UIWidget.h" +#include "ui/GUIExport.h" +#include "2d/CCSprite.h" +#include "2d/CCLabel.h" +#include NS_CC_BEGIN namespace ui { -class RichElement : public Ref +class CC_GUI_DLL RichElement : public Ref { public: enum class Type @@ -51,22 +55,25 @@ class RichElement : public Ref friend class RichText; }; -class RichElementText : public RichElement +class CC_GUI_DLL RichElementText : public RichElement { public: RichElementText(){_type = Type::TEXT;}; virtual ~RichElementText(){}; - bool init(int tag, const Color3B& color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize); - static RichElementText* create(int tag, const Color3B& color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize); + bool init(int tag, const Color3B& color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize,bool isUnderLine,bool isOutLine,const Color4B& outLineColor); + static RichElementText* create(int tag, const Color3B& color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize,bool isUnderLine = false,bool isOutLine = false,const Color4B& outLineColor=Color4B::WHITE); protected: std::string _text; std::string _fontName; float _fontSize; + bool _isUnderLine; + bool _isOutLine; + Color4B _outLineColor; friend class RichText; }; -class RichElementImage : public RichElement +class CC_GUI_DLL RichElementImage : public RichElement { public: RichElementImage(){_type = Type::IMAGE;}; @@ -80,7 +87,7 @@ class RichElementImage : public RichElement friend class RichText; }; -class RichElementCustomNode : public RichElement +class CC_GUI_DLL RichElementCustomNode : public RichElement { public: RichElementCustomNode(){_type = Type::CUSTOM;}; @@ -92,7 +99,21 @@ class RichElementCustomNode : public RichElement friend class RichText; }; -class RichText : public Widget +class RichCacheElement : public Ref +{ +public: + RichCacheElement():_isUse(false),_node(nullptr){}; + virtual ~RichCacheElement(); + bool init(bool isUse, Node* node); + static RichCacheElement* create(bool isUse, Node* node); +protected: + bool _isUse; + Node* _node; + friend class RichText; +}; + +typedef std::vector< std::string > stringVector; +class CC_GUI_DLL RichText : public Widget { public: RichText(); @@ -102,29 +123,45 @@ class RichText : public Widget void pushBackElement(RichElement* element); void removeElement(int index); void removeElement(RichElement* element); - virtual void visit(cocos2d::Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags) override; + void setVerticalSpace(float space); virtual void setAnchorPoint(const Vec2 &pt); - virtual const Size& getVirtualRendererSize() const override; + virtual Size getVirtualRendererSize() const override; + void cleanAllElement(); void formatText(); virtual void ignoreContentAdaptWithSize(bool ignore); virtual std::string getDescription() const override; + Node* getContainer(){ return _elementRenderersContainer; }; + stringVector split(const std::string& s,const std::string& delim); + virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override; CC_CONSTRUCTOR_ACCESS: virtual bool init() override; protected: + void onDraw(const Mat4 &transform, uint32_t flags); + CustomCommand _customCommand; + virtual void adaptRenderers(); + virtual void initRenderer(); void pushToContainer(Node* renderer); - void handleTextRenderer(const std::string& text, const std::string& fontName, float fontSize, const Color3B& color, GLubyte opacity); - void handleImageRenderer(const std::string& fileParh, const Color3B& color, GLubyte opacity); - void handleCustomRenderer(Node* renderer); + void handleTextRenderer(const std::string& text, const std::string& fontName, float fontSize,bool isUnder, const Color3B& color, GLubyte opacity,int tag,bool isOutLine,const Color4B& outLineColor); + void handleImageRenderer(const std::string& fileParh, const Color3B& color, GLubyte opacity,int tag); + void handleCustomRenderer(Node* renderer,int tag); void formarRenderers(); void addNewLine(); + + Label* getCacheLabel(); + Sprite* getCacheImage(); + Node* makeLabel(Label* pTarget,const Color3B& color, const std::string& text, const std::string& fontName, int fontSize,bool isUnder, int tag,bool isOutLine,const Color4B& outLineColor); + Node* makeImage(Sprite* pTarget, const std::string& filePath,int tag); protected: bool _formatTextDirty; Vector _richElements; std::vector*> _elementRenders; + Vector _cacheLabElements; + Vector _cacheImgElements; + std::set _underLineTags; float _leftSpaceWidth; float _verticalSpace; Node* _elementRenderersContainer; From d04edb92dc2bd0e98ca656336ad7edae1d251a3e Mon Sep 17 00:00:00 2001 From: B_y <342854406@qq.com> Date: Sat, 4 Apr 2015 22:36:17 +0800 Subject: [PATCH 2/4] Update UIRichText.cpp support underline/outline label/sprite cache --- cocos/ui/UIRichText.cpp | 420 +++++++++++++++++++++++++++++----------- 1 file changed, 308 insertions(+), 112 deletions(-) diff --git a/cocos/ui/UIRichText.cpp b/cocos/ui/UIRichText.cpp index e1c827199b07..3405c8b35616 100644 --- a/cocos/ui/UIRichText.cpp +++ b/cocos/ui/UIRichText.cpp @@ -24,30 +24,18 @@ #include "UIRichText.h" #include "platform/CCFileUtils.h" -#include "2d/CCLabel.h" -#include "2d/CCSprite.h" +#include "base/ccUTF8.h" +#include "ui/UIHelper.h" +#include "2d/CCDrawingPrimitives.h" +#include "2d/CCSpriteFrameCache.h" +#include "renderer/CCRenderer.h" +#include "renderer/CCCustomCommand.h" +#include "CCDirector.h" NS_CC_BEGIN namespace ui { - -static int _calcCharCount(const char * pszText) -{ - int n = 0; - char ch = 0; - while ((ch = *pszText)) - { - CC_BREAK_IF(! ch); - - if (0x80 != (0xC0 & ch)) - { - ++n; - } - ++pszText; - } - return n; -} - + bool RichElement::init(int tag, const Color3B &color, GLubyte opacity) { _tag = tag; @@ -57,25 +45,28 @@ bool RichElement::init(int tag, const Color3B &color, GLubyte opacity) } -RichElementText* RichElementText::create(int tag, const Color3B &color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize) +RichElementText* RichElementText::create(int tag, const Color3B &color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize,bool isUnderLine,bool isOutLine,const Color4B& outLineColor) { - RichElementText* element = new RichElementText(); - if (element && element->init(tag, color, opacity, text, fontName, fontSize)) + RichElementText* element = new (std::nothrow) RichElementText(); + if (element && element->init(tag, color, opacity, text, fontName, fontSize,isUnderLine,isOutLine,outLineColor)) { element->autorelease(); return element; } CC_SAFE_DELETE(element); - return NULL; + return nullptr; } -bool RichElementText::init(int tag, const Color3B &color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize) +bool RichElementText::init(int tag, const Color3B &color, GLubyte opacity, const std::string& text, const std::string& fontName, float fontSize,bool isUnderLine,bool isOutLine,const Color4B& outLineColor) { if (RichElement::init(tag, color, opacity)) { _text = text; _fontName = fontName; _fontSize = fontSize; + _isUnderLine = isUnderLine; + _isOutLine = isOutLine; + _outLineColor = outLineColor; return true; } return false; @@ -83,14 +74,14 @@ bool RichElementText::init(int tag, const Color3B &color, GLubyte opacity, const RichElementImage* RichElementImage::create(int tag, const Color3B &color, GLubyte opacity, const std::string& filePath) { - RichElementImage* element = new RichElementImage(); + RichElementImage* element = new (std::nothrow) RichElementImage(); if (element && element->init(tag, color, opacity, filePath)) { element->autorelease(); return element; } CC_SAFE_DELETE(element); - return NULL; + return nullptr; } bool RichElementImage::init(int tag, const Color3B &color, GLubyte opacity, const std::string& filePath) @@ -105,14 +96,14 @@ bool RichElementImage::init(int tag, const Color3B &color, GLubyte opacity, cons RichElementCustomNode* RichElementCustomNode::create(int tag, const Color3B &color, GLubyte opacity, cocos2d::Node *customNode) { - RichElementCustomNode* element = new RichElementCustomNode(); + RichElementCustomNode* element = new (std::nothrow) RichElementCustomNode(); if (element && element->init(tag, color, opacity, customNode)) { element->autorelease(); return element; } CC_SAFE_DELETE(element); - return NULL; + return nullptr; } bool RichElementCustomNode::init(int tag, const Color3B &color, GLubyte opacity, cocos2d::Node *customNode) @@ -126,6 +117,32 @@ bool RichElementCustomNode::init(int tag, const Color3B &color, GLubyte opacity, return false; } +bool RichCacheElement::init( bool isUse, Node* node ) +{ + _isUse = isUse; + _node = node; + _node->retain(); + return true; +} + +RichCacheElement* RichCacheElement::create( bool isUse, Node* node ) +{ + RichCacheElement* element = new (std::nothrow) RichCacheElement(); + if (element && element->init(isUse,node)) + { + element->autorelease(); + return element; + } + CC_SAFE_DELETE(element); + return nullptr; +} + +RichCacheElement::~RichCacheElement() +{ + if (_node) _node->release(); +} + + RichText::RichText(): _formatTextDirty(true), _leftSpaceWidth(0.0f), @@ -138,18 +155,21 @@ _elementRenderersContainer(nullptr) RichText::~RichText() { _richElements.clear(); + _cacheLabElements.clear(); + _cacheImgElements.clear(); + _underLineTags.clear(); } RichText* RichText::create() { - RichText* widget = new RichText(); + RichText* widget = new (std::nothrow) RichText(); if (widget && widget->init()) { widget->autorelease(); return widget; } CC_SAFE_DELETE(widget); - return NULL; + return nullptr; } bool RichText::init() @@ -191,12 +211,32 @@ void RichText::removeElement(RichElement *element) _richElements.eraseObject(element); _formatTextDirty = true; } - + +void RichText::cleanAllElement() +{ + _richElements.clear(); + auto len = _cacheImgElements.size(); + for (int i=0;i_isUse = false; + _cacheImgElements.at(i)->_node->removeFromParentAndCleanup(false); + } + + len = _cacheLabElements.size(); + for (int i=0;i_isUse = false; + _cacheLabElements.at(i)->_node->removeFromParentAndCleanup(false); + } + _underLineTags.clear(); + _formatTextDirty = true; +} + void RichText::formatText() { if (_formatTextDirty) { - _elementRenderersContainer->removeAllChildren(); + _elementRenderersContainer->removeAllChildrenWithCleanup(false); _elementRenders.clear(); if (_ignoreSize) { @@ -204,26 +244,19 @@ void RichText::formatText() for (ssize_t i=0; i<_richElements.size(); i++) { RichElement* element = _richElements.at(i); - Node* elementRenderer = NULL; + Node* elementRenderer = nullptr; switch (element->_type) { case RichElement::Type::TEXT: { - RichElementText* elmtText = static_cast(element); - if (FileUtils::getInstance()->isFileExist(elmtText->_fontName)) - { - elementRenderer = Label::createWithTTF(elmtText->_text.c_str(), elmtText->_fontName, elmtText->_fontSize); - } - else - { - elementRenderer = Label::createWithSystemFont(elmtText->_text.c_str(), elmtText->_fontName, elmtText->_fontSize); - } + RichElementText* elmtText = static_cast(element); + elementRenderer = makeLabel(getCacheLabel(),elmtText->_color,elmtText->_text.c_str(), elmtText->_fontName, elmtText->_fontSize,elmtText->_isUnderLine,elmtText->_tag,elmtText->_isOutLine,elmtText->_outLineColor); break; } case RichElement::Type::IMAGE: { RichElementImage* elmtImage = static_cast(element); - elementRenderer = Sprite::create(elmtImage->_filePath.c_str()); + elementRenderer = makeImage(getCacheImage(),elmtImage->_filePath,elmtImage->_tag); break; } case RichElement::Type::CUSTOM: @@ -235,7 +268,6 @@ void RichText::formatText() default: break; } - elementRenderer->setColor(element->_color); elementRenderer->setOpacity(element->_opacity); pushToContainer(elementRenderer); } @@ -252,19 +284,19 @@ void RichText::formatText() case RichElement::Type::TEXT: { RichElementText* elmtText = static_cast(element); - handleTextRenderer(elmtText->_text.c_str(), elmtText->_fontName.c_str(), elmtText->_fontSize, elmtText->_color, elmtText->_opacity); + handleTextRenderer(elmtText->_text.c_str(), elmtText->_fontName.c_str(), elmtText->_fontSize,elmtText->_isUnderLine, elmtText->_color, elmtText->_opacity,elmtText->_tag,elmtText->_isOutLine,elmtText->_outLineColor); break; } case RichElement::Type::IMAGE: { RichElementImage* elmtImage = static_cast(element); - handleImageRenderer(elmtImage->_filePath.c_str(), elmtImage->_color, elmtImage->_opacity); + handleImageRenderer(elmtImage->_filePath.c_str(), elmtImage->_color, elmtImage->_opacity,elmtImage->_tag); break; } case RichElement::Type::CUSTOM: { RichElementCustomNode* elmtCustom = static_cast(element); - handleCustomRenderer(elmtCustom->_customNode); + handleCustomRenderer(elmtCustom->_customNode,elmtCustom->_tag); break; } default: @@ -277,66 +309,134 @@ void RichText::formatText() } } -void RichText::handleTextRenderer(const std::string& text, const std::string& fontName, float fontSize, const Color3B &color, GLubyte opacity) -{ - auto fileExist = FileUtils::getInstance()->isFileExist(fontName); - Label* textRenderer = nullptr; - if (fileExist) - { - textRenderer = Label::createWithTTF(text, fontName, fontSize); - } - else - { - textRenderer = Label::createWithSystemFont(text, fontName, fontSize); - } - float textRendererWidth = textRenderer->getContentSize().width; - _leftSpaceWidth -= textRendererWidth; - if (_leftSpaceWidth < 0.0f) - { - float overstepPercent = (-_leftSpaceWidth) / textRendererWidth; - std::string curText = text; - size_t stringLength = _calcCharCount(text.c_str()); - int leftLength = stringLength * (1.0f - overstepPercent); - std::string leftWords = curText.substr(0, leftLength); - std::string cutWords = curText.substr(leftLength, curText.length()-1); - if (leftLength > 0) +void RichText::handleTextRenderer(const std::string& text, const std::string& fontName, float fontSize,bool isUnder, const Color3B& color, GLubyte opacity,int tag,bool isOutLine,const Color4B& outLineColor){ + Node* textRenderer = nullptr; + float textRendererWidth = 0; + + stringVector vect = split(text,"\n"); + if (vect.size() == 1 ){ + textRenderer = makeLabel(getCacheLabel(),color,text, fontName, fontSize,isUnder,tag,isOutLine,outLineColor); + + textRendererWidth = textRenderer->getContentSize().width; + _leftSpaceWidth -= textRendererWidth; + + + if (_leftSpaceWidth < 0.0f) { - Label* leftRenderer = nullptr; - if (fileExist) + float overstepPercent = (-_leftSpaceWidth) / textRendererWidth; + std::string curText = text; + size_t stringLength = StringUtils::getCharacterCountInUTF8String(text); + int leftLength = stringLength * (1.0f - overstepPercent); + std::string leftWords = Helper::getSubStringOfUTF8String(curText,0,leftLength); + std::string cutWords = Helper::getSubStringOfUTF8String(curText, leftLength, stringLength - leftLength); + if (leftLength > 0) { - leftRenderer = Label::createWithTTF(leftWords.substr(0, leftLength).c_str(), fontName, fontSize); - } - else - { - leftRenderer = Label::createWithSystemFont(leftWords.substr(0, leftLength).c_str(), fontName, fontSize); + Node* leftRenderer = nullptr; + leftRenderer = makeLabel(getCacheLabel(),color,leftWords, fontName, fontSize,isUnder,tag,isOutLine,outLineColor); + if (leftRenderer) + { + leftRenderer->setOpacity(opacity); + pushToContainer(leftRenderer); + } } - if (leftRenderer) + + addNewLine(); + handleTextRenderer(cutWords.c_str(), fontName, fontSize,isUnder, color, opacity,tag,isOutLine,outLineColor); + } + else + { + textRenderer->setOpacity(opacity); + pushToContainer(textRenderer); + } + + }else{ + auto len = vect.size(); + for (int i=0;isetTag(tag); + + if (s == "") { + ((Label*)textRenderer)->setString(" ");//hold on the new line + pushToContainer(textRenderer); + addNewLine(); + continue; + } + + textRendererWidth = textRenderer->getContentSize().width; + _leftSpaceWidth -= textRendererWidth; + if (_leftSpaceWidth < 0.0f) { - leftRenderer->setColor(color); - leftRenderer->setOpacity(opacity); - pushToContainer(leftRenderer); + float overstepPercent = (-_leftSpaceWidth) / textRendererWidth; + std::string curText = s; + size_t stringLength = StringUtils::getCharacterCountInUTF8String(s); + int leftLength = stringLength * (1.0f - overstepPercent); + std::string leftWords = Helper::getSubStringOfUTF8String(curText,0,leftLength); + std::string cutWords = Helper::getSubStringOfUTF8String(curText, leftLength, stringLength - leftLength); + if (leftLength > 0) + { + Node* leftRenderer = nullptr; + leftRenderer = makeLabel(getCacheLabel(),color,leftWords, fontName, fontSize,isUnder,tag,isOutLine,outLineColor); + if (leftRenderer) + { + leftRenderer->setOpacity(opacity); + pushToContainer(leftRenderer); + } + } + + addNewLine(); + handleTextRenderer(cutWords.c_str(), fontName, fontSize,isUnder, color, opacity,tag,isOutLine,outLineColor); + }else{ + textRenderer->setOpacity(opacity); + pushToContainer(textRenderer); + addNewLine(); } } + } - addNewLine(); - handleTextRenderer(cutWords.c_str(), fontName, fontSize, color, opacity); +} + + void RichText::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags) + { + _customCommand.init(_globalZOrder); + _customCommand.func = CC_CALLBACK_0(RichText::onDraw, this, transform, flags); + renderer->addCommand(&_customCommand); } - else + + void RichText::onDraw(const Mat4 &transform, uint32_t flags) { - textRenderer->setColor(color); - textRenderer->setOpacity(opacity); - pushToContainer(textRenderer); + Director* director = Director::getInstance(); + director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); + director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform); + + auto children = _elementRenderersContainer->getChildren(); + auto len = children.size(); + for (int i=0; igetTag()) >= 1){ + DrawPrimitives::setDrawColor4B(pChild->getDisplayedColor().r, + pChild->getDisplayedColor().g, + pChild->getDisplayedColor().b, + pChild->getDisplayedOpacity()); + DrawPrimitives::setPointSize(2); + DrawPrimitives::drawLine(pChild->getPosition(), + Vec2(pChild->getContentSize().width+pChild->getPosition().x,pChild->getPosition().y)); + } + } + //end draw + director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } -} -void RichText::handleImageRenderer(const std::string& fileParh, const Color3B &color, GLubyte opacity) +void RichText::handleImageRenderer(const std::string& fileParh, const Color3B &color, GLubyte opacity,int tag) { - Sprite* imageRenderer = Sprite::create(fileParh); - handleCustomRenderer(imageRenderer); + Node* imageRenderer = makeImage(getCacheImage(),fileParh,tag); + handleCustomRenderer(imageRenderer,tag); } -void RichText::handleCustomRenderer(cocos2d::Node *renderer) +void RichText::handleCustomRenderer(cocos2d::Node *renderer,int tag) { + renderer->setTag(tag); Size imgSize = renderer->getContentSize(); _leftSpaceWidth -= imgSize.width; if (_leftSpaceWidth < 0.0f) @@ -370,8 +470,8 @@ void RichText::formarRenderers() { Node* l = row->at(j); l->setAnchorPoint(Vec2::ZERO); - l->setPosition(Vec2(nextPosX, 0.0f)); - _elementRenderersContainer->addChild(l, 1, (int)j); + l->setPosition(nextPosX, 0.0f); + _elementRenderersContainer->addChild(l, 1); Size iSize = l->getContentSize(); newContentSizeWidth += iSize.width; newContentSizeHeight = MAX(newContentSizeHeight, iSize.height); @@ -409,12 +509,12 @@ void RichText::formarRenderers() { Node* l = row->at(j); l->setAnchorPoint(Vec2::ZERO); - l->setPosition(Vec2(nextPosX, nextPosY)); - _elementRenderersContainer->addChild(l, 1, (int)(i*10 + j)); + l->setPosition(nextPosX, nextPosY); + _elementRenderersContainer->addChild(l, 1); nextPosX += l->getContentSize().width; } } - _elementRenderersContainer->setContentSize(_size); + _elementRenderersContainer->setContentSize(_contentSize); delete [] maxHeights; } @@ -430,16 +530,21 @@ void RichText::formarRenderers() if (_ignoreSize) { Size s = getVirtualRendererSize(); - _size = s; + this->setContentSize(s); } else { - _size = _customSize; + this->setContentSize(_customSize); } - updateContentSizeWithTextureSize(_size); + updateContentSizeWithTextureSize(_contentSize); _elementRenderersContainer->setPosition(_contentSize.width / 2.0f, _contentSize.height / 2.0f); } +void RichText::adaptRenderers() +{ + this->formatText(); +} + void RichText::pushToContainer(cocos2d::Node *renderer) { if (_elementRenders.size() <= 0) @@ -448,15 +553,6 @@ void RichText::pushToContainer(cocos2d::Node *renderer) } _elementRenders[_elementRenders.size()-1]->pushBack(renderer); } - -void RichText::visit(cocos2d::Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags) -{ - if (_enabled) - { - formatText(); - Widget::visit(renderer, parentTransform, parentFlags); - } -} void RichText::setVerticalSpace(float space) { @@ -469,7 +565,7 @@ void RichText::setAnchorPoint(const Vec2 &pt) _elementRenderersContainer->setAnchorPoint(pt); } -const Size& RichText::getVirtualRendererSize() const +Size RichText::getVirtualRendererSize() const { return _elementRenderersContainer->getContentSize(); } @@ -488,6 +584,106 @@ std::string RichText::getDescription() const return "RichText"; } +Label* RichText::getCacheLabel() +{ + Label* ret = nullptr; + auto len = _cacheLabElements.size(); + for (int i=0;i_isUse == false) + { + pElement->_isUse = true; + ret = (Label*)pElement->_node; + break; + } + } + if (ret == nullptr){ + ret = Label::create(); + _cacheLabElements.pushBack(RichCacheElement::create(true,ret)); + } + return ret; +} + +Sprite* RichText::getCacheImage() +{ + Sprite* ret = nullptr; + auto len = _cacheImgElements.size(); + for (int i=0;i_isUse == false) + { + pElement->_isUse = true; + ret = (Sprite*)pElement->_node; + break; + } + } + if (ret == nullptr){ + ret = Sprite::create(); + _cacheImgElements.pushBack(RichCacheElement::create(true,ret)); + } + return ret; +} + +Node* RichText::makeLabel( Label* pTarget,const Color3B& color, const std::string& text, const std::string& fontName, int fontSize,bool isUnder, int tag,bool isOutLine,const Color4B& outLineColor) +{ + bool fileExist = FileUtils::getInstance()->isFileExist(fontName); + + if (fileExist) { + TTFConfig ttfConfig(fontName.c_str(),fontSize,GlyphCollection::DYNAMIC); + pTarget->setTTFConfig(ttfConfig); + if (isOutLine) { + pTarget->setTextColor(Color4B(color)); + pTarget->enableOutline(outLineColor,2); + }else{ + pTarget->setColor(color); + } + + }else{ + pTarget->setColor(color); + pTarget->setSystemFontName(fontName); + pTarget->setSystemFontSize(fontSize); + } + if (isUnder) { + _underLineTags.insert(tag); + } + pTarget->setString(text); + pTarget->setTag(tag); + return pTarget; +} + +Node* RichText::makeImage( Sprite* pTarget, const std::string& filePath,int tag ) +{ + auto spriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName(filePath); + if(spriteFrame && pTarget->isFrameDisplayed(spriteFrame) == false){ + pTarget->setSpriteFrame(spriteFrame); + }else{ + pTarget->setTexture(filePath); + } + pTarget->setTag(tag); + return pTarget; +} + +////////////////////////////////////////////////////////////////////////// +std::vector< std::string > RichText::split(const std::string& s,const std::string& delim) +{ + std::vector< std::string > ret; + size_t last = 0; + size_t index=s.find_first_of(delim,last); + while (index!=std::string::npos) + { + ret.push_back(s.substr(last,index-last)); + last=index+1; + index=s.find_first_of(delim,last); + } + if (index-last>0) + { + ret.push_back(s.substr(last,index-last)); + } + return ret; +} + } -NS_CC_END \ No newline at end of file +NS_CC_END From fa07e630224f9e8803fba63229811ad68138953b Mon Sep 17 00:00:00 2001 From: B_y <342854406@qq.com> Date: Mon, 6 Apr 2015 11:38:08 +0800 Subject: [PATCH 3/4] Update UIRichText.h support sprite anim --- cocos/ui/UIRichText.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cocos/ui/UIRichText.h b/cocos/ui/UIRichText.h index b397ccf4c206..958eaa777344 100644 --- a/cocos/ui/UIRichText.h +++ b/cocos/ui/UIRichText.h @@ -78,12 +78,15 @@ class CC_GUI_DLL RichElementImage : public RichElement public: RichElementImage(){_type = Type::IMAGE;}; virtual ~RichElementImage(){}; - bool init(int tag, const Color3B& color, GLubyte opacity, const std::string& filePath); - static RichElementImage* create(int tag, const Color3B& color, GLubyte opacity, const std::string& filePath); + bool init(int tag, const Color3B& color, GLubyte opacity, const std::string& filePath,bool isAnim,float delay,bool isLoop); + static RichElementImage* create(int tag, const Color3B& color, GLubyte opacity, const std::string& filePath,bool isAnim=false,float delay=0.0f,bool isLoop=true); protected: std::string _filePath; Rect _textureRect; int _textureType; + bool _isAnim; + bool _isLoop; + float _delay; friend class RichText; }; @@ -146,7 +149,7 @@ class CC_GUI_DLL RichText : public Widget virtual void initRenderer(); void pushToContainer(Node* renderer); void handleTextRenderer(const std::string& text, const std::string& fontName, float fontSize,bool isUnder, const Color3B& color, GLubyte opacity,int tag,bool isOutLine,const Color4B& outLineColor); - void handleImageRenderer(const std::string& fileParh, const Color3B& color, GLubyte opacity,int tag); + void handleImageRenderer(const std::string& fileParh, const Color3B& color, GLubyte opacity,int tag,bool isAnim,float delay,bool isLoop); void handleCustomRenderer(Node* renderer,int tag); void formarRenderers(); void addNewLine(); @@ -154,7 +157,7 @@ class CC_GUI_DLL RichText : public Widget Label* getCacheLabel(); Sprite* getCacheImage(); Node* makeLabel(Label* pTarget,const Color3B& color, const std::string& text, const std::string& fontName, int fontSize,bool isUnder, int tag,bool isOutLine,const Color4B& outLineColor); - Node* makeImage(Sprite* pTarget, const std::string& filePath,int tag); + Node* makeImage(Sprite* pTarget, const std::string& filePath,int tag,bool isAnim,float delay,bool isLoop); protected: bool _formatTextDirty; Vector _richElements; From abb9c856ec34d8c865c09efad6d1fa1a41085643 Mon Sep 17 00:00:00 2001 From: B_y <342854406@qq.com> Date: Mon, 6 Apr 2015 11:38:56 +0800 Subject: [PATCH 4/4] Update UIRichText.cpp support sprite anim --- cocos/ui/UIRichText.cpp | 49 ++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/cocos/ui/UIRichText.cpp b/cocos/ui/UIRichText.cpp index 3405c8b35616..75c6d62f2e5f 100644 --- a/cocos/ui/UIRichText.cpp +++ b/cocos/ui/UIRichText.cpp @@ -31,6 +31,8 @@ #include "renderer/CCRenderer.h" #include "renderer/CCCustomCommand.h" #include "CCDirector.h" +#include "2d/CCAnimation.h" +#include "2d/CCActionInterval.h" NS_CC_BEGIN @@ -72,10 +74,10 @@ bool RichElementText::init(int tag, const Color3B &color, GLubyte opacity, const return false; } -RichElementImage* RichElementImage::create(int tag, const Color3B &color, GLubyte opacity, const std::string& filePath) +RichElementImage* RichElementImage::create(int tag, const Color3B& color, GLubyte opacity, const std::string& filePath,bool isAnim,float delay,bool isLoop) { RichElementImage* element = new (std::nothrow) RichElementImage(); - if (element && element->init(tag, color, opacity, filePath)) + if (element && element->init(tag, color, opacity, filePath,isAnim,delay,isLoop)) { element->autorelease(); return element; @@ -84,11 +86,14 @@ RichElementImage* RichElementImage::create(int tag, const Color3B &color, GLubyt return nullptr; } -bool RichElementImage::init(int tag, const Color3B &color, GLubyte opacity, const std::string& filePath) +bool RichElementImage::init(int tag, const Color3B& color, GLubyte opacity, const std::string& filePath,bool isAnim,float delay,bool isLoop) { if (RichElement::init(tag, color, opacity)) { _filePath = filePath; + _isAnim = isAnim; + _delay = delay; + _isLoop = isLoop; return true; } return false; @@ -256,7 +261,7 @@ void RichText::formatText() case RichElement::Type::IMAGE: { RichElementImage* elmtImage = static_cast(element); - elementRenderer = makeImage(getCacheImage(),elmtImage->_filePath,elmtImage->_tag); + elementRenderer = makeImage(getCacheImage(),elmtImage->_filePath,elmtImage->_tag,elmtImage->_isAnim,elmtImage->_delay,elmtImage->_isLoop); break; } case RichElement::Type::CUSTOM: @@ -290,7 +295,7 @@ void RichText::formatText() case RichElement::Type::IMAGE: { RichElementImage* elmtImage = static_cast(element); - handleImageRenderer(elmtImage->_filePath.c_str(), elmtImage->_color, elmtImage->_opacity,elmtImage->_tag); + handleImageRenderer(elmtImage->_filePath.c_str(), elmtImage->_color, elmtImage->_opacity,elmtImage->_tag,elmtImage->_isAnim,elmtImage->_delay,elmtImage->_isLoop); break; } case RichElement::Type::CUSTOM: @@ -428,9 +433,9 @@ void RichText::handleTextRenderer(const std::string& text, const std::string& fo director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } -void RichText::handleImageRenderer(const std::string& fileParh, const Color3B &color, GLubyte opacity,int tag) +void RichText::handleImageRenderer(const std::string& fileParh, const Color3B &color, GLubyte opacity,int tag,bool isAnim,float delay,bool isLoop) { - Node* imageRenderer = makeImage(getCacheImage(),fileParh,tag); + Node* imageRenderer = makeImage(getCacheImage(),fileParh,tag,isAnim,delay,isLoop); handleCustomRenderer(imageRenderer,tag); } @@ -653,7 +658,7 @@ Node* RichText::makeLabel( Label* pTarget,const Color3B& color, const std::strin return pTarget; } -Node* RichText::makeImage( Sprite* pTarget, const std::string& filePath,int tag ) +Node* RichText::makeImage( Sprite* pTarget, const std::string& filePath,int tag,bool isAnim,float delay,bool isLoop ) { auto spriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName(filePath); if(spriteFrame && pTarget->isFrameDisplayed(spriteFrame) == false){ @@ -661,6 +666,34 @@ Node* RichText::makeImage( Sprite* pTarget, const std::string& filePath,int tag }else{ pTarget->setTexture(filePath); } + + if (isAnim) { + + SpriteFrameCache *pCache = SpriteFrameCache::getInstance(); + Vector v; + + SpriteFrame *pFrame = NULL; + int index = 1; + char buf[128] = {0}; + do + { + sprintf(buf,"%s%d.png",filePath.c_str(),index++); + pFrame = pCache->getSpriteFrameByName(buf); + if(pFrame == NULL){ + break; + } + v.pushBack(pFrame); + } while (true); + + Animation *pAnim = Animation::createWithSpriteFrames(v); + pAnim->setLoops(isLoop?-1:0); + pAnim->setRestoreOriginalFrame(true); + pAnim->setDelayPerUnit(delay); + pTarget->setContentSize(v.at(0)->getOriginalSize()); + pTarget->stopAllActions(); + pTarget->runAction(Animate::create(pAnim)); + } + pTarget->setTag(tag); return pTarget; }