RichText: how to get the real content size?

RichText: how to get the real content size?
0.0 0

#1

Hi guys :smile:

I’m using RichText class to put some text inside a ScrollView Instance.
I need to set the RichText width in order to split text in multiple lines.
To do that I did:

RichText* richText = RichText::create();
richText->setContentSize({720, 0});
richText->ignoreContentAdaptWithSize(false);

Then I added multiple RichElementText objects.
Finally I added richText inside my scrollView

scrollView->addChild(richText);

Because the RichText is bigger than my scrollView I need to set scrollView InnerContainerSize:

scrollView->setInnerContainerSize(richText->getContentSize());

Here comes the problem:
The richText content size height is 0, and was not updated after I added the RichElementTextobjects!

I tried also:

auto cs   = richText->getContentSize();
auto bbcs = richText->getBoundingBox().size;
auto vrs  = richText->getVirtualRendererSize();

All return the contentSize I set: {720, 0}.
How can I get real richText height?

Thanks


Rich Text or Label for text-wrapping & how to calculate Height?
How to get real size of ccui.RichText()! Please help!
#2

Anyone knows this? :pensive:


#3

Did you solve this problem?


#4

@anhtuan89 Sadly no! :weary:
You have to put a RichText instance inside a parent container like in my case?


#5
RichText *richText = RichText::createWithXML(xml);
richText->formatText(); //force calculation of content size
Size s = richText->getContentSize();  //use it

#6

Unfortunately slarsky's fix did not work for me (I only get the single line height). Every attempt I’ve made to modify the contentSize of the RichText itself has failed. In order to get this to work I had to do several things:

  1. Update the RichText object to calculate a text height value as the renderers are added.
void RichText::pushToContainer(cocos2d::Node *renderer)
{
    if (_elementRenders.size() <= 0)
    {
        setTextHeight(0.0f);
        return;
    }
    // Update _textHeight
    renderer->setOnEnterCallback([this, renderer] {
        auto height = -renderer->getPositionY() + renderer->getContentSize().height;
        if(height > getTextHeight())
        {
            setTextHeight(height);
        }
    });
    _elementRenders[_elementRenders.size()-1]->pushBack(renderer);
}
  1. Then expose the text height as a value/callback
float RichText::getTextHeight() const {
    return _textHeight;
}

void RichText::setTextHeight(float height)
{
    if (_textHeight == height) return;
    _textHeight = height;
    if (_textHeightChangedCallback)
    {
        _textHeightChangedCallback(_textHeight);
    }
}

void RichText::setTextHeightCallback(std::function<void(float)> callback)
{
    _textHeightChangedCallback = callback;
}
  1. Add a RichText child to a Layout object
    a. Center position the RichText
    b. Pass on the size of the Layout to the RichText
    c. (Using the callback) Pass on the height of the RichText to the Layout
    d. (Using the callback) Update the Y Position of the RichTextto 1.5 * height (why *1.5? because it works).
  _richText = cocos2d::ui::RichText::createWithXML(text, defaults, openUrlHandler);
  if (_richText) {
    _richText->ignoreContentAdaptWithSize(false);
    _richText->setPositionX(getContentSize().width * 0.5f);
    _richText->setContentSize(getContentSize());
    _richText->setTextHeightCallback([this](float height) {
      _richText->setPositionY(height * 1.5f);
      setContentSize(cocos2d::Size(getContentSize().width, height));
    });
    addChild(_rich_text);
  }

(code assumes this is a Layout containing a pointer to a RichText)

Now you will have a Layout that adjusts its height to the visible area of the RichText. Is this a little hacky…yes, but it works. If anyone can improve this code please let me know.