Improved capabilities of icon widget, and use that for track screenshot instead of locally duplicated code

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4372 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria
2009-12-30 19:09:10 +00:00
parent ebe6dc5521
commit a6efeb5faa
4 changed files with 47 additions and 30 deletions

View File

@@ -55,6 +55,11 @@ A plain text buttons.
WTYPE_ICON_BUTTON "icon-button", "icon"
A component with an image, and optional text to go under it. The "icon" variant will have no border and will not
be clickable. PROP_ICON is mandatory for this component.
There are three ways to place the texture within the allocated space; the default (and only way currently accessible
through xml files) is to scale the texture to fit, while preserving its aspect ratio; other methods, currently only
accessible through C++ code, are to stretch the texture to fill the area without caring for aspect ratio, and another
to respect an aspect ratio other than the texture's (useful for track screenshots, which are 4:3 compressed to fit
in a power-of-two 256x256 texture)
WTYPE_CHECKBOX "checkbox"
A checkbox. Not used at the moment.

View File

@@ -26,10 +26,12 @@ using namespace irr::gui;
// -----------------------------------------------------------------------------
IconButtonWidget::IconButtonWidget(ScaleMode scale_mode, const bool tab_stop, const bool focusable)
{
m_tab_stop = tab_stop;
m_label = NULL;
m_type = WTYPE_ICON_BUTTON;
m_texture = NULL;
m_type = WTYPE_ICON_BUTTON;
m_custom_aspect_ratio = 1.0f;
m_tab_stop = tab_stop;
m_focusable = focusable;
m_scale_mode = scale_mode;
}
@@ -44,14 +46,34 @@ void IconButtonWidget::add()
// irrlicht widgets don't support scaling while keeping aspect ratio
// so, happily, let's implement it ourselves
int x_gap = 0;
float useAspectRatio = -1.0f;
if (m_scale_mode == SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO)
{
x_gap = (int)((float)w - (float)m_texture_w * (float)h / m_texture_h);
useAspectRatio = (float)m_texture_w / (float)m_texture_h;
//std::cout << "m_texture_h=" << m_texture_h << "; m_texture_w="<< m_texture_w << "; useAspectRatio=" << useAspectRatio << std::endl;
}
else if (m_scale_mode == SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO)
{
useAspectRatio = m_custom_aspect_ratio;
}
rect<s32> widget_size = rect<s32>(x + x_gap/2, y, x + w - x_gap/2, y + h);
int suggested_h = h;
int suggested_w = (useAspectRatio < 0 ? w : useAspectRatio*suggested_h);
if (suggested_w > w)
{
const float needed_scale_factor = (float)w / (float)suggested_w;
suggested_w *= needed_scale_factor;
suggested_h *= needed_scale_factor;
}
const int x_from = x + (w - suggested_w)/2; // center horizontally
const int y_from = y + (h - suggested_h)/2; // center vertically
rect<s32> widget_size = rect<s32>(x_from,
y_from,
x_from + suggested_w,
y_from + suggested_h);
//std::cout << "Creating a IGUIButton " << widget_size.UpperLeftCorner.X << ", " << widget_size.UpperLeftCorner.Y <<
//" : " << widget_size.getWidth() << "x" << widget_size.getHeight() << std::endl;

View File

@@ -35,7 +35,8 @@ namespace GUIEngine
enum ScaleMode
{
SCALE_MODE_STRETCH,
SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO
SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO,
SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO
};
protected:
@@ -46,10 +47,10 @@ namespace GUIEngine
int m_texture_w, m_texture_h;
ScaleMode m_scale_mode;
float m_custom_aspect_ratio;
public:
/** Whether to make the widget included in keyboard navigation order when adding */
bool m_tab_stop;
@@ -59,6 +60,10 @@ namespace GUIEngine
/** Callback called when this widget needs to be added (see base class Widget) */
virtual void add();
/** Call this if scale mode is SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO.
* \param custom_aspect_ratio The width/height aspect ratio */
void setCustomAspectRatio(float custom_aspect_ratio) { m_custom_aspect_ratio = custom_aspect_ratio; }
/** Change the text label if there is a label (label won't be added if there initially wasn't one) */
void setLabel(irr::core::stringw new_label);

View File

@@ -153,31 +153,16 @@ TrackInfoDialog::TrackInfoDialog(const std::string& trackIdent, const irr::core:
// ---- Track screenshot
// stretch the *texture* within the widget (and the widget has the right aspect ratio)
// (Yeah, that's complicated, but screenshots are saved compressed horizontally so it's hard to be clean)
IconButtonWidget* screenshotWidget = new IconButtonWidget(IconButtonWidget::SCALE_MODE_STRETCH, false, false);
IconButtonWidget* screenshotWidget = new IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO,
false, false);
screenshotWidget->setCustomAspectRatio(4.0f / 3.0f); // images are saved squared, but must be stretched to 4:3
core::rect< s32 > area_right(m_area.getWidth()/2, y1, m_area.getWidth(), y2-10);
const int x_from = area_right.UpperLeftCorner.X;
const int y_from = area_right.UpperLeftCorner.Y;
const int available_w = area_right.getWidth();
const int available_h = area_right.getHeight();
screenshotWidget->x = area_right.UpperLeftCorner.X;
screenshotWidget->y = area_right.UpperLeftCorner.Y;
screenshotWidget->w = area_right.getWidth();
screenshotWidget->h = area_right.getHeight();
// TODO: move that "custom aspect ratio" code into the Image widget
// find a size that has the right aspect ratio (4:3) and fits within available space
int suggested_h = available_h;
int suggested_w = (4.0f / 3.0f) * suggested_h;
if (suggested_w > available_w)
{
const float needed_scale_factor = (float)available_w / (float)suggested_w;
suggested_w *= needed_scale_factor;
suggested_h *= needed_scale_factor;
}
screenshotWidget->x = x_from + (available_w - suggested_w)/2; // center horizontally
screenshotWidget->y = y_from + (available_h - suggested_h)/2; // center vertically
screenshotWidget->w = suggested_w;
screenshotWidget->h = suggested_h;
screenshotWidget->m_properties[PROP_ICON] = "gui/main_help.png"; // temporary icon, will replace it just after
screenshotWidget->setParent(m_irrlicht_window);
screenshotWidget->add();