Multiline listbox

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

yamashi
Just popping in
Just popping in
Posts: 7
Joined: Sat Oct 25, 2008 01:43

Multiline listbox

Postby yamashi » Sat Oct 25, 2008 18:20

Hi !

I am trying to figure out a way to use multiline for each of my items because horizontal scrolling is annoying...

Here is my listbox code :

Code: Select all

server = (Listbox*)Wmgr->createWindow("TaharezLook/Listbox","ServerList");
        MenuBackground->addChildWindow( server );
        server->setPosition( UVector2( UDim( 0.07f, 0.0f ), UDim( 0.22f, 0.0f ) ) );
        server->setSize( UVector2( UDim( 0.7f, 0.0f ), UDim( 0.5f, 0.0f ) ) );


And here is the code is use to add item to the listbox :

Code: Select all

CEGUI::ListboxTextItem *listboxitem =
         new CEGUI::ListboxTextItem (CEGUI::String((utf8*)str),id);
      listboxitem->setSelected(server->getItemCount() == 0);
      listboxitem->setSelectionColours(colour(0.57f,0.39f,0.39f));
      listboxitem->setSelectionBrushImage("TaharezLook", "ListboxSelectionBrush");
      server->addItem(listboxitem);


Thanks for your help !

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Sun Oct 26, 2008 10:39

Hi,

The supplied ListboxTextItem does not do any text wrapping, although it should be possible to create a subclass to do that (The ListboxItem based classes are really light-weight and easy to subclass).

I might create an example for you later today - depends how time goes...

CE.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Sun Oct 26, 2008 20:58

Ok. Here is a rough (but working) first draft of a ListboxTextItem based class that does word-wrapping.

This is not 100% perfect, but will be useful in many cases. There should probably be checks in place in case the looknfeel is not assigned properly, and also a check to make sure that d_owner really is a Listbox. This solution could be easily extended to allow for a configurable formatting, but anyway, you can base your own code on this :)

The class declaration is like so:

Code: Select all

namespace CEGUI
{
/*!
\brief
    ListboxTextItem based class that renders item text with word-wrapping.
*/
class ListboxWordWrapItem : public ListboxTextItem
{
public:
    ListboxWordWrapItem(const String& text,
                        uint item_id = 0,
                        void* item_data = 0,
                        bool disabled = false,
                        bool auto_delete = true);

    // override the members related to drawing and layout
    Size getPixelSize(void) const;
    void draw(RenderCache& cache, const Rect& targetRect, float zBase,
              float alpha, const Rect* clipper) const;
};

}


And the member definitions are like so:

Code: Select all

namespace CEGUI
{
//----------------------------------------------------------------------------//
ListboxWordWrapItem::ListboxWordWrapItem(const String& text, uint item_id,
                                         void* item_data, bool disabled,
                                         bool auto_delete) :

    ListboxTextItem(text, item_id, item_data, disabled, auto_delete)
{
}

//----------------------------------------------------------------------------//
Size ListboxWordWrapItem::getPixelSize(void) const
{
    Size sz(0,0);
    Font* fnt = getFont();

    // if no owner window or no font, return a zero size
    if (!d_owner || !fnt)
        return sz;

    // get the looknfeel assigned to the listbox owner window
    const WidgetLookFeel& wlf =
        WidgetLookManager::getSingleton().getWidgetLook(d_owner->getLookNFeel());

    // get the area for the named area "ItemRenderingArea"
    Rect wnd_area =
        wlf.getNamedArea("ItemRenderingArea").getArea().getPixelRect(*d_owner);

    size_t lines = fnt->getFormattedLineCount(d_itemText,
                                                wnd_area,
                                                WordWrapLeftAligned);

    sz.d_height = PixelAligned(fnt->getLineSpacing()) * lines;
    sz.d_width = PixelAligned(fnt->getFormattedTextExtent(d_itemText,
                                                          wnd_area,
                                                          WordWrapLeftAligned));

    return sz;

}

//----------------------------------------------------------------------------//
void ListboxWordWrapItem::draw(RenderCache& cache,const Rect& targetRect,
                               float zBase,  float alpha,
                               const Rect* clipper) const
{
    // render selection brush into item area if item is selected
    if (d_selected && d_selectBrush != 0)
        cache.cacheImage(*d_selectBrush, targetRect, zBase,
                         getModulateAlphaColourRect(d_selectCols, alpha),
                         clipper);

    Font* font = getFont();

    // render text with word wrapped formatting.
    if (font)
    {
        Rect finalPos(targetRect);
        finalPos.d_top +=
            PixelAligned((font->getLineSpacing() - font->getFontHeight()) / 2);
        cache.cacheText(d_itemText, font, WordWrapLeftAligned, finalPos, zBase,
                        getModulateAlphaColourRect(d_textCols, alpha), clipper);
    }
}

//----------------------------------------------------------------------------//

}


HTH

CE

yamashi
Just popping in
Just popping in
Posts: 7
Joined: Sat Oct 25, 2008 01:43

Postby yamashi » Mon Oct 27, 2008 01:22

Thanks a lot !
It's perfect !
You should put it in the librairy sources an option to enable or not wordwrapping ;-)

thanks again !


Return to “Help”

Who is online

Users browsing this forum: No registered users and 17 guests