Page 1 of 1

text wrapping in Tooltips

Posted: Sat Mar 28, 2009 19:22
by Lastmerlin
Hi,

if I set a rather long Tooltip text for a Window then the width of the Tooltip will increase accordingly - in the worst case larger than the screen width. Even if the Tooltip fits the screen this could look quite ugly.

Is there a possibility to do automatic Text wrapping inside Tooltips ? The problem is of course, that the width of the tooltip is calculated automatically. I am thinking of some sort of maximal width for the tooltip and if the calculated width exceeds this, the text will be wrapped instead.

The reason why I dont want to insert newlines into the text is, that it should be translated via gettext. Having newlines in such strings is a bad thing.

Thanks in advance for any help.

Posted: Sun Mar 29, 2009 09:26
by CrazyEddie
Hi,

I think we'll have to mark this up as a short-coming of the current implementation. As you say, the auto-sizing is what causes the quandary. What you could try (and this is totally off the top of my head, never tried it) is setting a max size for the tooltip and use one of the word-wrapped text formattings in the looknfeel and see if you get any joy (you may end up with height issues instead!).

Let us know if you do try that, and how it goes. If it's a bust, I'll raise it as a semi-bug / enhancement request.

CE.

Posted: Sun Mar 29, 2009 10:13
by Lastmerlin
You were absolutely right, I've changed in Code:

Code: Select all

   CEGUI::Tooltip* ttip = CEGUI::System::getSingleton().getDefaultTooltip();
   ttip->setMaxSize(CEGUI::UVector2(cegui_reldim(0.4), cegui_reldim(1.0)));


and in the .looknfeel:

Code: Select all

 <HorzFormat type="WordWrapCentreAligned" />


... and ended up with neatly wrapped text in a Tooltip window that is to small to display the entire text :D

The implementation needed is:
- check the width without wrapping
- if smaller than maxwidth: set width and height accordingly
- if bigger than maxwidth: set the width to maxwidth and recalculate height

I guess next step would be deriving CEGUI::Tooltip and rewrite getTextSize_impl() ? But i am not sure I want to do this now :D

Posted: Sun Mar 29, 2009 16:13
by Lastmerlin
got it working :D

Here is the code:

tooltip.h

Code: Select all

#include "CEGUI.h"

class TextWrapTooltip : public CEGUI::Tooltip
{
   public:
      TextWrapTooltip(const CEGUI::String &type, const CEGUI::String &name);
      
      virtual CEGUI::Size getTextSize_impl() const;
};

class TextWrapTooltipFactory : public CEGUI::WindowFactory
{
   public:
      TextWrapTooltipFactory();
      
      virtual CEGUI::Window * createWindow (const CEGUI::String &name)
      {
         return new TextWrapTooltip(d_type,name);
      }
      
      virtual void  destroyWindow (CEGUI::Window *window)
      {
         delete window;
      }
};


tooltip.cpp

Code: Select all

TextWrapTooltip::TextWrapTooltip(const CEGUI::String &type, const CEGUI::String &name)
   : CEGUI::Tooltip(type,name)
{
}

CEGUI::Size TextWrapTooltip::getTextSize_impl() const
{
   CEGUI::Font* fnt = getFont();

   if (fnt)
   {
      CEGUI::Rect area(CEGUI::System::getSingleton().getRenderer()->getRect());

      // get required size of the tool tip according to the text extents.
      float width = PixelAligned(fnt->getFormattedTextExtent(d_text, area, CEGUI::LeftAligned));
      
      CEGUI::Vector2 maxsize = getMaxSize().asAbsolute(area.getSize());
      
      // check that size does not exceed max size
      if (width > maxsize.d_x)
      {
         width = maxsize.d_x;
      }
      
      area.setWidth(width);
      float height = PixelAligned(fnt->getFormattedLineCount(d_text, area, CEGUI::WordWrapLeftAligned) * fnt->getLineSpacing());
      
      return CEGUI::Size(width, height);
   }
   else
   {
      return CEGUI::Size(0,0);
   }
   return CEGUI::Tooltip::getTextSize_impl();
}

TextWrapTooltipFactory::TextWrapTooltipFactory()
   : CEGUI::WindowFactory::WindowFactory("TextWrapTooltip")
{
   
}


some CEGUI setup code

Code: Select all

CEGUI::WindowFactoryManager::getSingleton().addFactory( new TextWrapTooltipFactory );
   CEGUI::WindowFactoryManager::getSingleton().addFalagardWindowMapping ("TextWrapTooltip", "CEGUI/Tooltip", "TaharezLook/Tooltip","Falagard/Tooltip");
   

   CEGUI::System::getSingleton().setDefaultTooltip( (CEGUI::utf8*)"TextWrapTooltip" );


Any further recommendations ? I see that there could be a small memory leak because I never delete the TextWrapTooltipFactory object. But the rest looks fine to me.

Posted: Sun Mar 29, 2009 16:40
by CrazyEddie
Hi again,

It's cool to see that you have it working :) I think everything looks fine from a cursory look, at least nothing gave me that "ugh! that's horrible" feeling :lol:

With regards to the memory leak, if you have CEGUI 0.6.2 or better, you can have CEGUI create - and later destroy - the factory instance for you by using the templatised version of addFactory, like this:

Code: Select all

CEGUI::WindowFactoryManager::getSingleton().addFactory<TextWrapTooltipFactory>();


CE.