Improved look and behaviour of new bubble widget
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5885 178a84e3-b1eb-0310-8ba1-8eac791a3b58
@@ -78,8 +78,12 @@ when the border that intersect at this corner are enabled.
|
||||
|
||||
<element type="textbubble" state="neutral" image="glass/textbubble.png"
|
||||
left_border="28" right_border="28" top_border="28" bottom_border="28"
|
||||
preserve_h_aspect_ratios="false" hborder_out_portion="1.0" />
|
||||
hborder_out_portion="0.1" vborder_out_portion="0.1" />
|
||||
|
||||
<element type="textbubble" state="focused" image="glass/textbubble2.png"
|
||||
left_border="28" right_border="28" top_border="28" bottom_border="28"
|
||||
hborder_out_portion="0.1" vborder_out_portion="0.1" />
|
||||
|
||||
<element type="progress" state="fill" image="glass/glassprogress_fill.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" />
|
||||
|
||||
@@ -77,7 +77,11 @@ when the border that intersect at this corner are enabled.
|
||||
|
||||
<element type="textbubble" state="neutral" image="ocean/textbubble.png"
|
||||
left_border="28" right_border="28" top_border="28" bottom_border="28"
|
||||
preserve_h_aspect_ratios="false" hborder_out_portion="1.0" />
|
||||
hborder_out_portion="0.1" vborder_out_portion="0.1" />
|
||||
|
||||
<element type="textbubble" state="focused" image="ocean/textbubble2.png"
|
||||
left_border="28" right_border="28" top_border="28" bottom_border="28"
|
||||
hborder_out_portion="0.1" vborder_out_portion="0.1" />
|
||||
|
||||
<element type="progress" state="fill" image="ocean/glasssgauge_fill.png"
|
||||
left_border="20" right_border="20" top_border="0" bottom_border="0"
|
||||
|
||||
@@ -77,7 +77,11 @@ when the border that intersect at this corner are enabled.
|
||||
|
||||
<element type="textbubble" state="neutral" image="peach/textbubble.png"
|
||||
left_border="28" right_border="28" top_border="28" bottom_border="28"
|
||||
preserve_h_aspect_ratios="false" hborder_out_portion="1.0" />
|
||||
hborder_out_portion="0.1" vborder_out_portion="0.1" />
|
||||
|
||||
<element type="textbubble" state="focused" image="peach/textbubble2.png"
|
||||
left_border="28" right_border="28" top_border="28" bottom_border="28"
|
||||
hborder_out_portion="0.1" vborder_out_portion="0.1" />
|
||||
|
||||
<element type="progress" state="fill" image="peach/glasssgauge_fill.png"
|
||||
left_border="20" right_border="20" top_border="0" bottom_border="0"
|
||||
|
||||
BIN
data/gui/skins/glass/textbubble.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
data/gui/skins/glass/textbubble2.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
data/gui/skins/ocean/textbubble2.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 4.5 KiB |
BIN
data/gui/skins/peach/textbubble2.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
@@ -199,7 +199,12 @@ void LayoutManager::readCoords(Widget* self, AbstractTopLevelContainer* topLevel
|
||||
float ratio = (float)parent_w / self->m_w;
|
||||
|
||||
self->m_w = (int)(self->m_w * ratio);
|
||||
if (self->m_type != WTYPE_LABEL) self->m_h = (int)(self->m_h * ratio);
|
||||
|
||||
// FIXME: ugly to hardcode widgets types here
|
||||
if (self->m_type != WTYPE_LABEL && self->m_type != WTYPE_BUBBLE)
|
||||
{
|
||||
self->m_h = (int)(self->m_h * ratio);
|
||||
}
|
||||
}
|
||||
|
||||
// ------ check for given max size
|
||||
@@ -213,7 +218,7 @@ void LayoutManager::readCoords(Widget* self, AbstractTopLevelContainer* topLevel
|
||||
{
|
||||
const int max_height = atoi( self->m_properties[PROP_MAX_HEIGHT].c_str() );
|
||||
if (self->m_h > max_height) self->m_h = max_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -1621,6 +1621,8 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool f
|
||||
{
|
||||
bubble->m_zoom += GUIEngine::getLatestDt()*10.0f;
|
||||
if (bubble->m_zoom > 1.0f) bubble->m_zoom = 1.0f;
|
||||
|
||||
bubble->updateSize();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1628,38 +1630,22 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool f
|
||||
if (bubble->m_zoom > 0.0f)
|
||||
{
|
||||
bubble->m_zoom -= GUIEngine::getLatestDt()*10.0f;
|
||||
|
||||
bubble->updateSize();
|
||||
}
|
||||
}
|
||||
|
||||
if (bubble->m_zoom > 0.0f)
|
||||
{
|
||||
core::rect< s32 > rect2 = rect;
|
||||
core::rect< s32 > rect2 = rect;
|
||||
|
||||
// minor adjustments...
|
||||
rect2.UpperLeftCorner.Y += 13;
|
||||
rect2.LowerRightCorner.X -= 15;
|
||||
rect2.LowerRightCorner.Y -= 8;
|
||||
|
||||
// apply zoom effect
|
||||
const int centerX = (rect2.UpperLeftCorner.X + rect2.LowerRightCorner.X)/2;
|
||||
const int centerY = (rect2.UpperLeftCorner.Y + rect2.LowerRightCorner.Y)/2;
|
||||
const int width = rect2.getWidth();
|
||||
const int height = rect2.getHeight();
|
||||
rect2.UpperLeftCorner.X = (int)(centerX - width*bubble->m_zoom/2.0f);
|
||||
rect2.UpperLeftCorner.Y = (int)(centerY - height*bubble->m_zoom/2.0f);
|
||||
rect2.LowerRightCorner.X = (int)(centerX + width*bubble->m_zoom/2.0f);
|
||||
rect2.LowerRightCorner.Y = (int)(centerY + height*bubble->m_zoom/2.0f);
|
||||
// minor adjustments...
|
||||
rect2.UpperLeftCorner.X -= 15;
|
||||
//rect2.LowerRightCorner.X -= 15;
|
||||
|
||||
if (bubble->isFocusedForPlayer(PLAYER_ID_GAME_MASTER))
|
||||
drawBoxFromStretchableTexture(widget, rect2, SkinConfig::m_render_params["textbubble::focused"]);
|
||||
else
|
||||
drawBoxFromStretchableTexture(widget, rect2, SkinConfig::m_render_params["textbubble::neutral"]);
|
||||
}
|
||||
|
||||
//ITexture* texture;
|
||||
//texture = SkinConfig::m_render_params["checkbox::focused+unchecked"].getImage();
|
||||
//const int texture_w = texture->getSize().Width;
|
||||
//const int texture_h = texture->getSize().Height;
|
||||
//const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||
//GUIEngine::getDriver()->draw2DImage( texture, rect, source_area,
|
||||
// 0 /* no clipping */, 0, true /* alpha */);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ void BubbleWidget::add()
|
||||
{
|
||||
m_shrinked_size = rect<s32>(m_x, m_y, m_x + m_w, m_y + m_h);
|
||||
stringw message = getText();
|
||||
|
||||
|
||||
EGUI_ALIGNMENT align = EGUIA_UPPERLEFT;
|
||||
if (m_properties[PROP_TEXT_ALIGN] == "center") align = EGUIA_CENTER;
|
||||
else if (m_properties[PROP_TEXT_ALIGN] == "right") align = EGUIA_LOWERRIGHT;
|
||||
@@ -51,15 +51,20 @@ void BubbleWidget::add()
|
||||
|
||||
m_expanded_size = m_shrinked_size;
|
||||
const int additionalNeededSize = std::max(0, text_height - m_shrinked_size.getHeight());
|
||||
m_expanded_size.UpperLeftCorner.Y -= additionalNeededSize/2;
|
||||
m_expanded_size.LowerRightCorner.Y += additionalNeededSize/2;
|
||||
|
||||
// reduce text to fit in the available space if it's too long
|
||||
while (text_height > m_shrinked_size.getHeight())
|
||||
// the '5' here is a bit arbitrary...
|
||||
if (additionalNeededSize > 5)
|
||||
{
|
||||
message = message.subString(0, message.size() - 10) + "...";
|
||||
irrwidget->setText(message.c_str());
|
||||
text_height = irrwidget->getTextHeight();
|
||||
m_expanded_size.UpperLeftCorner.Y -= additionalNeededSize/2 + 10;
|
||||
m_expanded_size.LowerRightCorner.Y += additionalNeededSize/2 + 10;
|
||||
|
||||
// reduce text to fit in the available space if it's too long
|
||||
while (text_height > m_shrinked_size.getHeight())
|
||||
{
|
||||
message = message.subString(0, message.size() - 10) + "...";
|
||||
irrwidget->setText(message.c_str());
|
||||
text_height = irrwidget->getTextHeight();
|
||||
}
|
||||
}
|
||||
m_shrinked_text = message;
|
||||
|
||||
@@ -75,8 +80,33 @@ void BubbleWidget::add()
|
||||
irrwidget->setDrawBorder(true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void BubbleWidget::updateSize()
|
||||
{
|
||||
core::rect<s32> currsize = m_shrinked_size;
|
||||
|
||||
const int y1_top = m_shrinked_size.UpperLeftCorner.Y;
|
||||
const int y1_bottom = m_shrinked_size.LowerRightCorner.Y;
|
||||
|
||||
const int y2_top = m_expanded_size.UpperLeftCorner.Y;
|
||||
const int y2_bottom = m_expanded_size.LowerRightCorner.Y;
|
||||
|
||||
currsize.UpperLeftCorner.Y = y1_top + (y2_top - y1_top)*m_zoom;
|
||||
currsize.LowerRightCorner.Y = y1_bottom + (y2_bottom - y1_bottom)*m_zoom;
|
||||
|
||||
m_element->setRelativePosition(currsize);
|
||||
|
||||
if (m_zoom > 0.5f)
|
||||
{
|
||||
getIrrlichtElement<IGUIStaticText>()->setText(getText().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
getIrrlichtElement<IGUIStaticText>()->setText(m_shrinked_text.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/*
|
||||
EventPropagation BubbleWidget::focused(const int playerID)
|
||||
{
|
||||
if (m_element != NULL)
|
||||
@@ -101,5 +131,5 @@ void BubbleWidget::unfocused(const int playerID)
|
||||
widget->setText(m_shrinked_text.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace GUIEngine
|
||||
|
||||
class BubbleWidget : public Widget
|
||||
{
|
||||
friend class Skin;
|
||||
|
||||
/** shrinked size of this widget (size allowed in layout; internal text may be bigger than that).
|
||||
* If the text all fits in the allowed layout space, m_shrinked_size == m_expanded_size.
|
||||
*/
|
||||
@@ -38,20 +40,17 @@ namespace GUIEngine
|
||||
|
||||
/** Text shrinked to fit into the allowed layout space (will be same as m_text if all text fits) */
|
||||
irr::core::stringw m_shrinked_text;
|
||||
public:
|
||||
|
||||
// For the skin
|
||||
/** For the skin to create the zooming effect */
|
||||
float m_zoom;
|
||||
|
||||
public:
|
||||
|
||||
BubbleWidget();
|
||||
|
||||
virtual void add();
|
||||
|
||||
/** \brief overriding event form base class */
|
||||
virtual EventPropagation focused(const int playerID);
|
||||
|
||||
/** \brief overriding event form base class */
|
||||
virtual void unfocused(const int playerID);
|
||||
void updateSize();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||