First, I want something like this:
Code: Select all
+-----------------------------------------------+
| [Fixed-width1] [Fixed-width2] [Flexible width |
| with wrapping.] |
+-----------------------------------------------+
The relevant parts of the WidgetLook:
Code: Select all
<NamedArea name="ContentSize">
<Area>
<Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
<Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
<Dim type="RightEdge"><UnifiedDim scale="1" type="RightEdge" /></Dim>
<Dim type="Height"> ...Some calculated value based on FontDim baseline and linespacing... </Dim>
</Area>
</NamedArea>
<ImagerySection name="fixed1">
<TextComponent>
<Area>
...
<Dim type="RightEdge"><PropertyDim name="Fixed1Width" type="Width" /></Dim>
...
</Area>
</TextComponent>
</ImagerySection>
<ImagerySection name="fixed2">
<TextComponent>
... Similar to "fixed1" but the left edge is to the right of "fixed1" ...
</TextComponent>
</ImagerySection>
<ImagerySection name="text">
<TextComponent>
<Area>
<Dim type="LeftEdge"> ... To the right of "fixed2" ... </Dim>
<Dim type="RightEdge"><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
<Dim type="BottomEdge"><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
</Area>
<HorzFormat type="WordWrapLeftAligned" />
<VertFormat type="TopAligned" />
</TextComponent>
</ImagerySection>
The WindowRenderer has the render() method (exact copy of the Falagard renderer for ItemEntries) and the getItemPixelSize() method:
Code: Select all
Sizef WrappingItemEntryRenderer::getItemPixelSize() const
{
// get WidgetLookFeel for the assigned look.
const WidgetLookFeel& wlf = getLookNFeel();
Sizef sz(0, 0);
Window* par = d_window->getParent();
while (par && !dynamic_cast<ItemListbox*>(par))
par = par->getParent();
if (par)
sz.d_width = static_cast<ItemListbox*>(par)->getItemRenderArea().getWidth();
const ImagerySection& is = wlf.getImagerySection("text");
bool renderedOnce = false;
for (ImagerySection::TextComponentIterator it = is.getTextComponentIterator(); !it.isAtEnd() ; it++)
{
// If I don't do this invalidate/render then I get a crash (see below)
if (!renderedOnce)
{
d_window->invalidate();
d_window->render();
renderedOnce = true;
}
const TextComponent& tc(*it);
float th = tc.getVerticalTextExtent(*d_window);
if (th > sz.d_height)
sz.d_height = th;
}
return sz;
}
If I *do* call invalidate/render, it doesn't crash but I get some weird behavior. First, the returned size is 438 x ~1200, the width is right but the height should be close to 30. After some debugging, I saw that the text formatting/rendering components had split the string into dozens of lines, like having one character per line, which makes me think that it uses a very small width to format the string somewhere. It does appear alright though (it's rendered on two lines, as it should), if you ignore the huge white space at the bottom.
This very large height causes my ItemListbox to show the vertical scrollbar (its height is close to 300 px) but another strange thing happens: When I add a second item, it is not placed at +1200 but it overlaps the bottom part of the previous item. For some reason, it also causes both of them to re-wrap and become 3 lines each (maybe now it took the v-scrollbar into account and it hadn't before?).
Note that if I hack a fixed height into the getPixelSize() method (i.e. Sizef sz(0, 50); return sz;) then everything works right (scrollbar, wrapping, height, placement).
Halp!
The backtrace if I don't call invalidate/render:
Code: Select all
#7 0xb61a0886 in CEGUI::RenderedString::getPixelSize (this=0xa2fe444, ref_wnd=0xa9170c8, line=0)
at ~/cegui/cegui_mk2/source/cegui/src/RenderedString.cpp:254
#8 0xb61acf09 in CEGUI::LeftAlignedRenderedString::getVerticalExtent (this=0xa2b9268, ref_wnd=0xa9170c8)
at ~/cegui/cegui_mk2/source/cegui/src/LeftAlignedRenderedString.cpp:89
#9 0xb628d09b in CEGUI::TextComponent::getVerticalTextExtent (this=0xbf8c1b78, window=...)
at ~/cegui/cegui_mk2/source/cegui/src/falagard/TextComponent.cpp:417
#10 0xb69fde2b in WrappingItemEntryRenderer::getItemPixelSize (this=0xa919a98)
at ~/aaa/src/gui/WrappingItemEntryRenderer.cpp:99
#11 0xb61d527d in CEGUI::ItemEntry::getItemPixelSize (this=0xa9170c8)
at ~/cegui/cegui_mk2/source/cegui/src/widgets/ItemEntry.cpp:71
#12 0xb61e1156 in CEGUI::ItemListbox::layoutItemWidgets (this=0xa877e20)
at ~/cegui/cegui_mk2/source/cegui/src/widgets/ItemListbox.cpp:70
#13 0xb620c6e2 in CEGUI::ItemListBase::onListContentsChanged (this=0xa877e20, e=...)
at ~/cegui/cegui_mk2/source/cegui/src/widgets/ItemListBase.cpp:345
#14 0xb620c612 in CEGUI::ItemListBase::handleUpdatedItemData (this=0xa877e20, resort=false)
at ~/cegui/cegui_mk2/source/cegui/src/widgets/ItemListBase.cpp:320
#15 0xb620c1f4 in CEGUI::ItemListBase::addItem (this=0xa877e20, item=0xa9170c8)
at ~/cegui/cegui_mk2/source/cegui/src/widgets/ItemListBase.cpp:231