Lots of small fixes and cleanup; major change : totally bypass irrLicht's icon rendering in the GUI, which is insufficient for our needs. Use a new system that's much more flexible. Improved locking icon on the way. A few minor glitches introduced, to be fixed soon

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@4290 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2009-12-14 20:15:09 +00:00
parent 29c1623f29
commit 68ba369ff4
18 changed files with 282 additions and 216 deletions

View File

@ -6,10 +6,10 @@
align="center" text_align="center" />
<buttonbar id="gps" height="175" width="100%" align="center" square_items="true">
<icon-button id="gp1" width="171" height="128" icon="gui/track1.png" text="Penguin Playground"/>
<icon-button id="gp2" width="171" height="128" icon="gui/track2.png" text="Snag Drive"/>
<icon-button id="gp3" width="171" height="128" icon="gui/track3.png" text="To the Moon and Back"/>
<icon-button id="gp4" width="171" height="128" icon="gui/track4.png" text="At World's End"/>
<icon-button id="gp1" width="171" height="128" icon="gui/track_random.png" text="Penguin Playground"/>
<icon-button id="gp2" width="171" height="128" icon="gui/track_random.png" text="Snag Drive"/>
<icon-button id="gp3" width="171" height="128" icon="gui/track_random.png" text="To the Moon and Back"/>
<icon-button id="gp4" width="171" height="128" icon="gui/track_random.png" text="At World's End"/>
</buttonbar>
<header width="100%" I18N="Section in track selection screen" text="All Tracks"

View File

@ -81,6 +81,8 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
Widget* w = GUIEngine::getWidget(id);
if (w == NULL) break;
if (!w->m_focusable) return GUIEngine::EVENT_BLOCK;
// These events are only triggered by keyboard/mouse (or so I hope...)
const int playerID = input_manager->getPlayerKeyboardID();
if (input_manager->masterPlayerOnly() && playerID != 0) break;
@ -92,6 +94,8 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
Widget* w = GUIEngine::getWidget(id);
if (w == NULL) break;
if (!w->m_focusable) return GUIEngine::EVENT_BLOCK;
// When a modal dialog is shown, don't select widgets out of the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(w))
{

View File

@ -391,17 +391,19 @@ Widget* Screen::getWidget(const int id, ptr_vector<Widget>* within_vector)
// -----------------------------------------------------------------------------
Widget* Screen::getFirstWidget(ptr_vector<Widget>* within_vector)
{
if(within_vector == NULL) within_vector = &m_widgets;
if (within_vector == NULL) within_vector = &m_widgets;
for(int i = 0; i < within_vector->size(); i++)
for (int i = 0; i < within_vector->size(); i++)
{
if (!within_vector->get(i)->m_focusable) continue;
// if container, also checks children
if(within_vector->get(i)->m_children.size() > 0 &&
within_vector->get(i)->m_type != WTYPE_RIBBON &&
within_vector->get(i)->m_type != WTYPE_SPINNER)
if (within_vector->get(i)->m_children.size() > 0 &&
within_vector->get(i)->m_type != WTYPE_RIBBON &&
within_vector->get(i)->m_type != WTYPE_SPINNER)
{
Widget* w = getFirstWidget(&within_vector->get(i)->m_children);
if(w != NULL) return w;
if (w != NULL) return w;
}
if (within_vector->get(i)->m_element == NULL || within_vector->get(i)->m_element->getTabOrder() == -1 ||
@ -416,15 +418,17 @@ Widget* Screen::getLastWidget(ptr_vector<Widget>* within_vector)
{
if (within_vector == NULL) within_vector = &m_widgets;
for(int i = within_vector->size()-1; i >= 0; i--)
for (int i = within_vector->size()-1; i >= 0; i--)
{
if (!within_vector->get(i)->m_focusable) continue;
// if container, also checks children
if(within_vector->get(i)->m_children.size() > 0 &&
within_vector->get(i)->m_type != WTYPE_RIBBON &&
within_vector->get(i)->m_type != WTYPE_SPINNER)
if (within_vector->get(i)->m_children.size() > 0 &&
within_vector->get(i)->m_type != WTYPE_RIBBON &&
within_vector->get(i)->m_type != WTYPE_SPINNER)
{
Widget* w = getLastWidget(&within_vector->get(i)->m_children);
if(w != NULL) return w;
if (w != NULL) return w;
}
if (within_vector->get(i)->m_element == NULL || within_vector->get(i)->m_element->getTabOrder() == -1 ||

View File

@ -589,12 +589,12 @@ void Skin::drawButton(Widget* w, const core::rect< s32 > &rect, const bool press
{
core::rect< s32 > sized_rect = rect;
core::position2d<u32> center = core::position2d<u32>(irr_driver->getFrameSize()/2);
const float size = sin(m_dialog_size*M_PI*0.5f);
const float texture_size = sin(m_dialog_size*M_PI*0.5f);
sized_rect.UpperLeftCorner.X = center.X + (int)((rect.UpperLeftCorner.X - center.X)*size);
sized_rect.UpperLeftCorner.Y = center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*size);
sized_rect.LowerRightCorner.X = center.X + (int)((rect.LowerRightCorner.X - center.X)*size);
sized_rect.LowerRightCorner.Y = center.Y + (int)((rect.LowerRightCorner.Y - center.Y)*size);
sized_rect.UpperLeftCorner.X = center.X + (int)((rect.UpperLeftCorner.X - center.X)*texture_size);
sized_rect.UpperLeftCorner.Y = center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*texture_size);
sized_rect.LowerRightCorner.X = center.X + (int)((rect.LowerRightCorner.X - center.X)*texture_size);
sized_rect.LowerRightCorner.Y = center.Y + (int)((rect.LowerRightCorner.Y - center.Y)*texture_size);
if (focused)
drawBoxFromStretchableTexture(w, sized_rect, SkinConfig::m_render_params["button::focused"]);
@ -633,13 +633,13 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const
RibbonType type = parentRibbon->getRibbonType();
/* tab-bar ribbons */
if(type == RIBBON_TABS)
if (type == RIBBON_TABS)
{
BoxRenderParams* params;
if(mark_selected && (focused || parent_focused))
if (mark_selected && (focused || parent_focused))
params = &SkinConfig::m_render_params["tab::focused"];
else if(mark_selected)
else if (mark_selected)
params = &SkinConfig::m_render_params["tab::down"];
else
params = &SkinConfig::m_render_params["tab::neutral"];
@ -794,6 +794,8 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const
{
drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo4::neutral"]);
}
drawIconButton(rect, widget, pressed, focused);
} // end if icon ribbons
@ -902,6 +904,50 @@ void Skin::drawSpinnerChild(const core::rect< s32 > &rect, Widget* widget, const
}
void Skin::drawIconButton(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused)
{
if (focused)
{
int grow = 45;
static float glow_effect = 0;
const float dt = GUIEngine::getLatestDt();
glow_effect += dt*3;
if (glow_effect > 6.2832f /* 2*PI */) glow_effect -= 6.2832f;
grow = (int)(45 + 10*sin(glow_effect));
const int glow_center_x = rect.UpperLeftCorner.X + rect.getWidth()/2;
const int glow_center_y = rect.LowerRightCorner.Y;
ITexture* tex_ficonhighlight = SkinConfig::m_render_params["focusHalo::neutral"].getImage();
const int texture_w = tex_ficonhighlight->getSize().Width;
const int texture_h = tex_ficonhighlight->getSize().Height;
core::rect<s32> source_area = core::rect<s32>(0, 0, texture_w, texture_h);
const core::rect< s32 > rect2 = core::rect< s32 >(glow_center_x - 45 - grow,
glow_center_y - 25 - grow/2,
glow_center_x + 45 + grow,
glow_center_y + 25 + grow/2);
GUIEngine::getDriver()->draw2DImage(tex_ficonhighlight, rect2, source_area,
0 /* no clipping */, 0, true /* alpha */);
}
IconButtonWidget* icon_widget = (IconButtonWidget*) widget;
//std::cout << "Drawing icon button '" << icon_widget->m_properties[PROP_ID] << "' : " << icon_widget->m_texture->getName().c_str() << "; size : " <<
// icon_widget->m_texture_w << "," << icon_widget->m_texture_h <<
// " --> " << rect.UpperLeftCorner.X << ", " << rect.UpperLeftCorner.Y << " " << rect.getWidth() << "x" << rect.getHeight() << "\n";
GUIEngine::getDriver()->draw2DImage(icon_widget->m_texture, rect,
core::rect<s32>(0,0,icon_widget->m_texture_w, icon_widget->m_texture_h),
0 /* no clipping */, 0, true /* alpha */);
}
void Skin::drawCheckBox(const core::rect< s32 > &rect, Widget* widget, bool focused)
{
CheckBoxWidget* w = dynamic_cast<CheckBoxWidget*>(widget);
@ -1030,45 +1076,15 @@ void Skin::process3DPane(IGUIElement *element, const core::rect< s32 > &rect, co
if (widget->m_event_handler != NULL && widget->m_event_handler->m_type == WTYPE_RIBBON)
{
drawRibbonChild(rect, widget, pressed /* pressed */, focused /* focused */);
drawRibbonChild(rect, widget, pressed, focused);
}
else if (widget->m_event_handler != NULL && widget->m_event_handler->m_type == WTYPE_SPINNER)
{
drawSpinnerChild(rect, widget, pressed /* pressed */, focused /* focused */);
drawSpinnerChild(rect, widget, pressed, focused);
}
else if (type == WTYPE_ICON_BUTTON)
{
if (focused)
{
int grow = 45;
static float glow_effect = 0;
const float dt = GUIEngine::getLatestDt();
glow_effect += dt*3;
if (glow_effect > 6.2832f /* 2*PI */) glow_effect -= 6.2832f;
grow = (int)(45 + 10*sin(glow_effect));
const int glow_center_x = rect.UpperLeftCorner.X + rect.getWidth()/2;
const int glow_center_y = rect.LowerRightCorner.Y;
ITexture* tex_ficonhighlight = SkinConfig::m_render_params["focusHalo::neutral"].getImage();
const int texture_w = tex_ficonhighlight->getSize().Width;
const int texture_h = tex_ficonhighlight->getSize().Height;
core::rect<s32> source_area = core::rect<s32>(0, 0, texture_w, texture_h);
const core::rect< s32 > rect2 = core::rect< s32 >(glow_center_x - 45 - grow,
glow_center_y - 25 - grow/2,
glow_center_x + 45 + grow,
glow_center_y + 25 + grow/2);
GUIEngine::getDriver()->draw2DImage(tex_ficonhighlight, rect2, source_area,
0 /* no clipping */, 0, true /* alpha */);
}
drawIconButton(rect, widget, pressed, focused);
}
else if(type == WTYPE_BUTTON)
{
@ -1094,6 +1110,30 @@ void Skin::process3DPane(IGUIElement *element, const core::rect< s32 > &rect, co
SColor color(255, 255, 0, 0);
GUIEngine::getFont()->draw(idstring.c_str(), rect, color, true, true);
}
if (widget->m_lock_badge || widget->m_okay_badge)
{
// TODO
video::ITexture* texture = NULL;
if (widget->m_lock_badge) texture = irr_driver->getTexture(file_manager->getTextureFile("gui_lock.png"));
else if (widget->m_okay_badge) texture = irr_driver->getTexture(file_manager->getTextureFile("green_check.png"));
else { assert(false); return; }
const core::dimension2d<u32>& texture_size = texture->getSize();
const float aspectRatio = (float)texture_size.Width / (float)texture_size.Height;
const int h = std::min( rect.getHeight()/2 , (int)(texture_size.Height) );
int w = aspectRatio*h;
const core::rect<s32> source_area = core::rect<s32>(0, 0, texture_size.Width, texture_size.Height);
const core::rect< s32 > rect2 = core::rect< s32 >(rect.UpperLeftCorner.X,
rect.LowerRightCorner.Y - h,
rect.UpperLeftCorner.X + w,
rect.LowerRightCorner.Y);
GUIEngine::getDriver()->draw2DImage(texture, rect2, source_area,
0 /* no clipping */, 0, true /* alpha */);
}
}
void Skin::draw3DButtonPanePressed (IGUIElement *element, const core::rect< s32 > &rect, const core::rect< s32 > *clip)
@ -1140,12 +1180,12 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool f
if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && widget->m_parent->getType() == gui::EGUIET_WINDOW)
{
core::position2d<u32> center = core::position2d<u32>(irr_driver->getFrameSize()/2);
const float size = sin(m_dialog_size*M_PI*0.5f);
const float texture_size = sin(m_dialog_size*M_PI*0.5f);
borderArea.UpperLeftCorner.X = center.X + (int)((rect.UpperLeftCorner.X - center.X)*size);
borderArea.UpperLeftCorner.Y = center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*size);
borderArea.LowerRightCorner.X = center.X + (int)((rect.LowerRightCorner.X - center.X)*size);
borderArea.LowerRightCorner.Y = center.Y + (int)((rect.LowerRightCorner.Y - center.Y)*size);
borderArea.UpperLeftCorner.X = center.X + (int)((rect.UpperLeftCorner.X - center.X)*texture_size);
borderArea.UpperLeftCorner.Y = center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*texture_size);
borderArea.LowerRightCorner.X = center.X + (int)((rect.LowerRightCorner.X - center.X)*texture_size);
borderArea.LowerRightCorner.Y = center.Y + (int)((rect.LowerRightCorner.Y - center.Y)*texture_size);
}
GUIEngine::getDriver()->draw2DRectangle( colorFocus, borderArea );
@ -1160,12 +1200,12 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool f
if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && widget->m_parent->getType() == gui::EGUIET_WINDOW)
{
core::position2d<u32> center = core::position2d<u32>(irr_driver->getFrameSize()/2);
const float size = sin(m_dialog_size*M_PI*0.5f);
const float texture_size = sin(m_dialog_size*M_PI*0.5f);
core::rect< s32 > sizedRect;
sizedRect.UpperLeftCorner.X = center.X + (int)((rect.UpperLeftCorner.X - center.X)*size);
sizedRect.UpperLeftCorner.Y = center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*size);
sizedRect.LowerRightCorner.X = center.X + (int)((rect.LowerRightCorner.X - center.X)*size);
sizedRect.LowerRightCorner.Y = center.Y + (int)((rect.LowerRightCorner.Y - center.Y)*size);
sizedRect.UpperLeftCorner.X = center.X + (int)((rect.UpperLeftCorner.X - center.X)*texture_size);
sizedRect.UpperLeftCorner.Y = center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*texture_size);
sizedRect.LowerRightCorner.X = center.X + (int)((rect.LowerRightCorner.X - center.X)*texture_size);
sizedRect.LowerRightCorner.Y = center.Y + (int)((rect.LowerRightCorner.Y - center.Y)*texture_size);
GUIEngine::getDriver()->draw2DRectangle( color, sizedRect );
}
else
@ -1207,11 +1247,11 @@ core::rect< s32 > Skin::draw3DWindowBackground (IGUIElement *element, bool drawT
core::position2d<s32> center = sized_rect.getCenter();
const int w = sized_rect.getWidth();
const int h = sized_rect.getHeight();
const float size = sin(m_dialog_size*M_PI*0.5f);
sized_rect.UpperLeftCorner.X = (int)(center.X - (w/2.0f)*size);
sized_rect.UpperLeftCorner.Y = (int)(center.Y - (h/2.0f)*size);
sized_rect.LowerRightCorner.X = (int)(center.X + (w/2.0f)*size);
sized_rect.LowerRightCorner.Y = (int)(center.Y + (h/2.0f)*size);
const float texture_size = sin(m_dialog_size*M_PI*0.5f);
sized_rect.UpperLeftCorner.X = (int)(center.X - (w/2.0f)*texture_size);
sized_rect.UpperLeftCorner.Y = (int)(center.Y - (h/2.0f)*texture_size);
sized_rect.LowerRightCorner.X = (int)(center.X + (w/2.0f)*texture_size);
sized_rect.LowerRightCorner.Y = (int)(center.Y + (h/2.0f)*texture_size);
drawBoxFromStretchableTexture( ModalDialog::getCurrent(), sized_rect, SkinConfig::m_render_params["window::neutral"]);
m_dialog_size += GUIEngine::getLatestDt()*5;
@ -1309,9 +1349,9 @@ u32 Skin::getIcon (EGUI_DEFAULT_ICON icon) const
return 0;
}
s32 Skin::getSize (EGUI_DEFAULT_SIZE size) const
s32 Skin::getSize (EGUI_DEFAULT_SIZE texture_size) const
{
return m_fallback_skin->getSize(size);
return m_fallback_skin->getSize(texture_size);
}
IGUISpriteBank* Skin::getSpriteBank () const
@ -1341,9 +1381,9 @@ void Skin::setIcon (EGUI_DEFAULT_ICON icon, u32 index)
m_fallback_skin->setIcon(icon, index);
}
void Skin::setSize (EGUI_DEFAULT_SIZE which, s32 size)
void Skin::setSize (EGUI_DEFAULT_SIZE which, s32 texture_size)
{
m_fallback_skin->setSize(which, size);
m_fallback_skin->setSize(which, texture_size);
//printf("setting size\n");
}

View File

@ -230,6 +230,7 @@ namespace GUIEngine
void drawCheckBox(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused);
void drawList(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused);
void drawListSelection(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused);
void drawIconButton(const irr::core::rect< irr::s32 > &rect, Widget* widget, const bool pressed, bool focused);
public:
// dirty way to have dialogs that zoom in

View File

@ -64,6 +64,7 @@ Widget::Widget(bool reserve_id)
m_element = NULL;
m_title_font = false;
m_type = WTYPE_NONE;
m_focusable = true;
m_event_handler = NULL;
m_show_bounding_box = false;
@ -80,6 +81,9 @@ Widget::Widget(bool reserve_id)
}
m_reserved_id = -1;
m_lock_badge = false;
m_okay_badge = false;
}
Widget::~Widget()

View File

@ -196,6 +196,15 @@ namespace GUIEngine
/** Whether to show a bounding box around this widget (used for sections) */
bool m_show_bounding_box;
/** Show a 'locked' badge on this widget */
bool m_lock_badge;
/** Show a 'good' badge on this widget */
bool m_okay_badge;
/** Set to false if widget is something that should not receieve focus */
bool m_focusable;
/** Used in two cases :
1) For 'placeholder' divisions; at the time the layout is created, there is nothing to
place there yet, but we know there eventually will. So in this case pass 'true' to the

View File

@ -220,11 +220,11 @@ void DynamicRibbonWidget::setSubElements()
// set size to get proper ratio (as most textures are saved scaled down to 256x256)
icon->m_properties[PROP_WIDTH] = m_properties[PROP_CHILD_WIDTH];
icon->m_properties[PROP_HEIGHT] = m_properties[PROP_CHILD_HEIGHT];
if (m_text == "all") icon->m_text = " ";
if (m_text == "all") icon->m_text = " "; // FIXME: what's that??
// std::cout << "ribbon text = " << m_properties[PROP_TEXT].c_str() << std::endl;
icon->m_type = WTYPE_ICON_BUTTON;
ribbon->m_children.push_back( icon );
}
m_children.push_back( ribbon );
@ -234,12 +234,14 @@ void DynamicRibbonWidget::setSubElements()
}
// -----------------------------------------------------------------------------
void DynamicRibbonWidget::addItem( const irr::core::stringw& user_name, const std::string& code_name, const std::string& image_file )
void DynamicRibbonWidget::addItem( const irr::core::stringw& user_name, const std::string& code_name,
const std::string& image_file, const bool locked )
{
ItemDescription desc;
desc.m_user_name = user_name;
desc.m_code_name = code_name;
desc.m_sshot_file = image_file;
desc.m_locked = locked;
m_items.push_back(desc);
}
@ -248,7 +250,7 @@ void DynamicRibbonWidget::clearItems()
{
m_items.clear();
}
// -----------------------------------------------------------------------------
void DynamicRibbonWidget::elementRemoved()
{
Widget::elementRemoved();
@ -566,8 +568,6 @@ void DynamicRibbonWidget::updateItemDisplay()
{
IconButtonWidget* icon = dynamic_cast<IconButtonWidget*>(&row.m_children[i]);
assert(icon != NULL);
IGUIButton* button = icon->getIrrlichtElement<IGUIButton>();
assert(button != NULL);
int col_scroll = i + m_scroll_offset;
while (col_scroll > max_scroll) col_scroll -= max_scroll+1;
@ -576,20 +576,19 @@ void DynamicRibbonWidget::updateItemDisplay()
if (icon_id < item_amount)
{
std::string track_sshot = m_items[icon_id].m_sshot_file;
button->setImage( GUIEngine::getDriver()->getTexture( track_sshot.c_str() ));
button->setPressedImage( GUIEngine::getDriver()->getTexture( track_sshot.c_str()) );
std::string item_icon = m_items[icon_id].m_sshot_file;
icon->setImage( item_icon.c_str() );
icon->m_properties[PROP_ID] = m_items[icon_id].m_code_name;
icon->m_text = m_items[icon_id].m_user_name;
icon->m_lock_badge = m_items[icon_id].m_locked;
row.setLabel(i, m_items[icon_id].m_user_name);
}
else
{
button->setImage( GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/main_help.png").c_str() ) );
button->setPressedImage( GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/main_help.png").c_str() ) );
icon->m_properties[PROP_ID] = "gui/main_help.png";
icon->setImage( "/gui/main_help.png" );
icon->m_properties[PROP_ID] = "?";
}
} // next column
} // next row

View File

@ -46,6 +46,7 @@ namespace GUIEngine
irr::core::stringw m_user_name;
std::string m_code_name;
std::string m_sshot_file;
bool m_locked;
};
/** A dynamic ribbon (builds upon RibbonWidget, adding dynamic contents creation and sizing, scrolling, multiple-row
@ -147,8 +148,14 @@ namespace GUIEngine
ptr_vector<RibbonWidget, REF> m_rows;
/** Dynamically add an item to the ribbon's list of items (will not be visible until you
call 'updateItemDisplay' or 'add') */
void addItem( const irr::core::stringw& user_name, const std::string& code_name, const std::string& image_file );
* call 'updateItemDisplay' or 'add').
*
* \param user_name The name that will shown to the user (may be translated)
* \param code_name The non-translated internal name used to uniquely identify this item.
* \param image_name A path to a texture that will the icon of this item (path relative to data dir, just like PROP_ICON)
* \param locked Whether to add a lock icon to this item (does nop actual locing, only adds an icon)
*/
void addItem( const irr::core::stringw& user_name, const std::string& code_name, const std::string& image_file, const bool locked=false );
/** Clears all items added through 'addItem'. You can then add new items with 'addItem' and call
'updateItemDisplay' to update the display. */

View File

@ -26,47 +26,33 @@ using namespace irr::gui;
// -----------------------------------------------------------------------------
IconButtonWidget::IconButtonWidget(const bool clickable)
{
IconButtonWidget::clickable = clickable;
label = NULL;
m_clickable = clickable;
m_label = NULL;
m_type = WTYPE_ICON_BUTTON;
m_texture = NULL;
m_focusable = clickable;
}
// -----------------------------------------------------------------------------
void IconButtonWidget::add()
{
// ---- Icon
ITexture* texture = GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" +m_properties[PROP_ICON]).c_str());
assert(texture != NULL);
const int texture_w = texture->getSize().Width, texture_h = texture->getSize().Height;
m_texture = GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" +m_properties[PROP_ICON]).c_str());
assert(m_texture != NULL);
m_texture_w = m_texture->getSize().Width;
m_texture_h = m_texture->getSize().Height;
// irrlicht widgets don't support scaling while keeping aspect ratio
// so, happily, let's implement it ourselves
const int x_gap = (int)((float)w - (float)texture_w * (float)h / texture_h);
const int x_gap = (int)((float)w - (float)m_texture_w * (float)h / m_texture_h);
rect<s32> widget_size;
if (clickable)
{
widget_size = rect<s32>(x + x_gap/2, y, x + w - x_gap/2, y + h);
rect<s32> widget_size = rect<s32>(x + x_gap/2, y, x + w - x_gap/2, y + h);
//std::cout << "Creating a IGUIButton " << widget_size.UpperLeftCorner.X << ", " << widget_size.UpperLeftCorner.Y <<
//" : " << widget_size.getWidth() << "x" << widget_size.getHeight() << std::endl;
IGUIButton* btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, (m_clickable ? getNewID() : getNewNoFocusID()), L"");
//MyGUIButton* btn = new MyGUIButton(GUIEngine::getGUIEnv(), m_parent, getNewID(), widget_size, true);
IGUIButton* btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, getNewID(), L"");
btn->setUseAlphaChannel(true);
btn->setImage(texture);
btn->setScaleImage(true);
//btn->setDrawBorder(false);
btn->setTabStop(true);
m_element = btn;
}
else
{
widget_size = rect<s32>(x + x_gap/2, y, x + w - x_gap/2, y + h);
IGUIImage* btn = GUIEngine::getGUIEnv()->addImage(widget_size, m_parent, getNewNoFocusID());
m_element = btn;
btn->setUseAlphaChannel(true);
btn->setImage(texture);
btn->setTabStop(false);
btn->setScaleImage(true);
}
btn->setTabStop(m_clickable);
m_element = btn;
id = m_element->getID();
// ---- label if any
@ -75,40 +61,39 @@ void IconButtonWidget::add()
{
widget_size = rect<s32>(x, y + h, x + w, y + h*2);
label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size, false, false /* word wrap */, m_parent);
label->setTextAlignment(EGUIA_CENTER, EGUIA_UPPERLEFT);
label->setTabStop(false);
m_label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size, false, false /* word wrap */, m_parent);
m_label->setTextAlignment(EGUIA_CENTER, EGUIA_UPPERLEFT);
m_label->setTabStop(false);
}
// ---- IDs
id = m_element->getID();
if(clickable) m_element->setTabOrder(id);
if (m_clickable) m_element->setTabOrder(id);
m_element->setTabGroup(false);
/*
IGUISpriteBank* sprite_bank = GUIEngine::getGUIEnv()->getSkin()->getSpriteBank();
// GUIEngine::getDriver()->makeColorKeyTexture(GUIEngine::getDriver()->getTexture("irrlichtlogo2.png"), position2di(0,0));
sprite_bank->addTexture( GUIEngine::getDriver()->getTexture("irrlichtlogo2.png") );
SGUISprite sprite;
sprite.frameTime = 3000;
SGUISpriteFrame frame;
core::array<core::rect<s32> >& rectangles = sprite_bank->getPositions();
rectangles.push_back(rect<s32>(0,0,128,128));
frame.rectNumber = rectangles.size()-1;
frame.textureNumber = sprite_bank->getTextureCount() - 1;
sprite.Frames.push_back(frame);
sprite_bank->getSprites().push_back(sprite);
button->setSpriteBank(sprite_bank);
button->setSprite(EGBS_BUTTON_UP, sprite_bank->getSprites().size()-1);
button->setSprite(EGBS_BUTTON_DOWN, sprite_bank->getSprites().size()-1);
*/
}
// -----------------------------------------------------------------------------
/** \precondition At the moment, the new texture must have the same aspct ratio as the previous one since the object will not
* be modified to fit a different aspect ratio
*/
void IconButtonWidget::setImage(const char* path_to_texture)
{
m_properties[PROP_ICON] = path_to_texture;
m_texture = GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" + m_properties[PROP_ICON]).c_str());
if (m_texture == NULL)
{
// texture not found, try with absolute path
m_texture = GUIEngine::getDriver()->getTexture(m_properties[PROP_ICON].c_str());
}
assert(m_texture != NULL);
m_texture_w = m_texture->getSize().Width;
m_texture_h = m_texture->getSize().Height;
}
// -----------------------------------------------------------------------------
void IconButtonWidget::setLabel(std::string new_label)
{
if (label == NULL) return;
if (m_label == NULL) return;
label->setText( stringw(new_label.c_str()).c_str() );
m_label->setText( stringw(new_label.c_str()).c_str() );
}

View File

@ -31,16 +31,25 @@ namespace GUIEngine
See guiengine/engine.hpp for a detailed overview */
class IconButtonWidget : public Widget
{
bool clickable;
irr::gui::IGUIStaticText* label;
friend class Skin;
bool m_clickable;
irr::gui::IGUIStaticText* m_label;
irr::video::ITexture* m_texture;
int m_texture_w, m_texture_h;
public:
IconButtonWidget(const bool clickable=true);
virtual ~IconButtonWidget() {}
void add();
/** Callback called when this widget needs to be added (see base class Widget) */
virtual void add();
/** Change the text label if there is a label (label won't be added if there initially wasn't one) */
void setLabel(std::string new_label);
/** Change the texture used for this icon. The path is relative to the data directory, just like PROP_ICON. */
void setImage(const char* path_to_texture);
};
}

View File

@ -74,7 +74,7 @@ void RibbonWidget::add()
int free_h_space = w - total_needed_space;
int biggest_y = 0;
//int biggest_y = 0;
const int button_y = 10;
float global_zoom = 1;
@ -85,27 +85,26 @@ void RibbonWidget::add()
const int one_button_space = (int)round((float)w / (float)subbuttons_amount);
// ---- add children
for(int i=0; i<subbuttons_amount; i++)
for (int i=0; i<subbuttons_amount; i++)
{
const int widget_x = one_button_space*(i+1) - one_button_space/2;
IGUIButton * subbtn;
if(/*m_children[i].m_type == WTYPE_BUTTON*/ getRibbonType() == RIBBON_TABS)
if (getRibbonType() == RIBBON_TABS)
{
IGUIButton * subbtn;
rect<s32> subsize = rect<s32>(widget_x - one_button_space/2+2, 0,
widget_x + one_button_space/2-2, h);
stringw& message = m_children[i].m_text;
if(m_children[i].m_type == WTYPE_BUTTON)
if (m_children[i].m_type == WTYPE_BUTTON)
{
subbtn = GUIEngine::getGUIEnv()->addButton(subsize, btn, getNewNoFocusID(), message.c_str(), L"");
subbtn->setTabStop(false);
subbtn->setTabGroup(false);
}
else if(m_children[i].m_type == WTYPE_ICON_BUTTON)
else if (m_children[i].m_type == WTYPE_ICON_BUTTON)
{
rect<s32> icon_part = rect<s32>(15,
0,
@ -145,34 +144,46 @@ void RibbonWidget::add()
m_children[i].m_element = subbtn;
}
else if(m_children[i].m_type == WTYPE_ICON_BUTTON)
else if (m_children[i].m_type == WTYPE_ICON_BUTTON)
{
const bool has_label = m_children[i].m_text.size() > 0;
// how much space to keep for the label under the button
const bool has_label = m_children[i].m_text.size() > 0;
const int needed_space_under_button = has_label ? 30 : 10; // quite arbitrary for now
// For now, the image stretches to keep the aspect ratio of the widget (FIXME, doesn't work)
//float imageRatio = (float)m_children[i].w/(float)m_children[i].h;
// size of the image
video::ITexture* image = GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" + m_children[i].m_properties[PROP_ICON]).c_str());
float image_h = image->getSize().Height;
float image_w = image->getSize().Width;
//float image_w = image_h*imageRatio;
// if button too high to fit, scale down
float zoom = global_zoom;
while(button_y + m_children[i].h*zoom + needed_space_under_button > h) zoom -= 0.01f;
while (button_y + image_h*zoom + needed_space_under_button > h) zoom -= 0.01f;
// ---- add bitmap button part
const float image_w = m_children[i].w*zoom;
rect<s32> subsize = rect<s32>(widget_x - (int)(image_w/2.0f), button_y,
widget_x + (int)(image_w/2.0f), button_y + (int)(m_children[i].h*zoom));
//rect<s32> subsize = rect<s32>(widget_x - (int)(image_w/2.0f), button_y,
// widget_x + (int)(image_w/2.0f), button_y + (int)(m_children[i].h*zoom));
//subbtn = new MyGUIButton(GUIEngine::getGUIEnv(), btn, getNewNoFocusID(), subsize, true);
subbtn = GUIEngine::getGUIEnv()->addButton(subsize, btn, getNewNoFocusID(), L"");
subbtn->setScaleImage(true);
m_children[i].x = widget_x - (int)(image_w*zoom/2.0f);
m_children[i].y = button_y;
m_children[i].w = image_w*zoom;
m_children[i].h = image_h*zoom;
m_children[i].m_element = subbtn;
subbtn->setUseAlphaChannel(true);
subbtn->setImage( GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" + m_children[i].m_properties[PROP_ICON]).c_str()) );
m_children.get(i)->m_parent = btn;
m_children.get(i)->add();
//subbtn->setUseAlphaChannel(true);
//subbtn->setImage( GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" + m_children[i].m_properties[PROP_ICON]).c_str()) );
// ---- label part
if(has_label)
/*
if (has_label)
{
subsize = rect<s32>(widget_x - one_button_space/2,
(int)((button_y + m_children[i].h)*zoom) + 5 /* leave 5 pixels between button and label */,
(int)((button_y + m_children[i].h)*zoom) + 5, // leave 5 pixels between button and label
widget_x + (int)(one_button_space/2.0f), h);
stringw& message = m_children[i].m_text;
@ -186,9 +197,9 @@ void RibbonWidget::add()
const int final_y = subsize.getHeight() + label->getTextHeight();
if(final_y > biggest_y) biggest_y = final_y;
}
subbtn->setTabStop(false);
subbtn->setTabGroup(false);
*/
//subbtn->setTabStop(false);
//subbtn->setTabGroup(false);
}
else
{
@ -196,7 +207,7 @@ void RibbonWidget::add()
}
m_children[i].id = subbtn->getID();
//m_children[i].id = subbtn->getID();
m_children[i].m_event_handler = this;
}// next sub-button

View File

@ -67,7 +67,7 @@ namespace GUIEngine
{
sprintf(buffer, "challenge%i", n);
w->addItem(activeChallenges[n]->getName() + L"\n" + activeChallenges[n]->getChallengeDescription(),
buffer, file_manager->getGUIDir() + "/challenge.png");
buffer, "/gui/challenge.png");
}
for (int n=0; n<solvedChallengeAmount; n++)
{

View File

@ -900,8 +900,7 @@ void KartSelectionScreen::init()
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
if (prop->getIdent() == default_kart)
{
std::string icon_path = file_manager->getDataDir() ;
icon_path += "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
w->addItem(prop->getName(), prop->getIdent().c_str(), icon_path.c_str());
//std::cout << "Add item : " << prop->getIdent().c_str() << std::endl;
break;
@ -914,15 +913,14 @@ void KartSelectionScreen::init()
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
if (prop->getIdent() != default_kart)
{
std::string icon_path = file_manager->getDataDir() ;
icon_path += "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
w->addItem(prop->getName(), prop->getIdent().c_str(), icon_path.c_str());
//std::cout << "Add item : " << prop->getIdent().c_str() << std::endl;
}
}
// add random
w->addItem(_("Random Kart"), "randomkart", file_manager->getGUIDir()+"/random_kart.png");
w->addItem(_("Random Kart"), "randomkart", "/gui/random_kart.png");
/*
@ -1090,8 +1088,7 @@ void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name,
{
const KartProperties* prop = kart_properties_manager->getKartById(n);
std::string icon_path = file_manager->getDataDir() ;
icon_path += "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str());
}
}
@ -1104,13 +1101,12 @@ void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name,
{
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
std::string icon_path = file_manager->getDataDir() ;
icon_path += "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str());
}
}
// add random
w->addItem(_("Random Kart"), "randomkart", file_manager->getGUIDir()+"/random_kart.png");
w->addItem(_("Random Kart"), "randomkart", "/gui/random_kart.png");
w->updateItemDisplay();

View File

@ -88,16 +88,11 @@ void OptionsScreenAV::init()
#define ABOUT_EQUAL(a , b) (fabsf( a - b ) < 0.01)
if( ABOUT_EQUAL( ratio, (5.0f/4.0f) ) )
res->addItem(name, name, file_manager->getDataDir() + "/gui/screen54.png");
else if( ABOUT_EQUAL( ratio, (4.0f/3.0f) ) )
res->addItem(name, name, file_manager->getDataDir() + "/gui/screen43.png");
else if( ABOUT_EQUAL( ratio, (16.0f/10.0f) ) )
res->addItem(name, name, file_manager->getDataDir() + "/gui/screen1610.png");
else if( ABOUT_EQUAL( ratio, (5.0f/3.0f) ) )
res->addItem(name, name, file_manager->getDataDir() + "/gui/screen53.png");
else if( ABOUT_EQUAL( ratio, (3.0f/2.0f) ) )
res->addItem(name, name, file_manager->getDataDir() + "/gui/screen32.png");
if (ABOUT_EQUAL( ratio, (5.0f/4.0f) )) res->addItem(name, name, "/gui/screen54.png");
else if (ABOUT_EQUAL( ratio, (4.0f/3.0f) )) res->addItem(name, name, "/gui/screen43.png");
else if (ABOUT_EQUAL( ratio, (16.0f/10.0f))) res->addItem(name, name, "/gui/screen1610.png");
else if (ABOUT_EQUAL( ratio, (5.0f/3.0f) )) res->addItem(name, name, "/gui/screen53.png");
else if (ABOUT_EQUAL( ratio, (3.0f/2.0f) )) res->addItem(name, name, "/gui/screen32.png");
else
{
std::cout << "Unknown screen size ratio : " << ratio << std::endl;

View File

@ -103,15 +103,14 @@ void OptionsScreenInput::init()
for (int i=0; i<keyboard_config_count; i++)
{
KeyboardConfig *config = input_manager->getDeviceList()->getKeyboardConfig(i);
//KeyboardConfig *config = input_manager->getDeviceList()->getKeyboardConfig(i);
std::ostringstream kbname;
kbname << "keyboard" << i;
const std::string internal_name = kbname.str();
devices->addItem(StringUtils::insertValues(_("Keyboard %i"), i), internal_name,
file_manager->getDataDir() + "/gui/keyboard.png");
devices->addItem(StringUtils::insertValues(_("Keyboard %i"), i), internal_name, "/gui/keyboard.png");
}
const int gpad_config_count = input_manager->getDeviceList()->getGamePadConfigAmount();
@ -128,8 +127,7 @@ void OptionsScreenInput::init()
gpname << "gamepad" << i;
const std::string internal_name = gpname.str();
const std::string iconpath = file_manager->getDataDir() + "/gui/gamepad.png";
devices->addItem(name, internal_name, iconpath);
devices->addItem(name, internal_name, "/gui/gamepad.png");
}
}

View File

@ -156,31 +156,26 @@ void RaceSetupScreen::init()
{
// FIXME: find a nice name than 'regular race' -.-
w2->addItem( _("Regular Race\nAll blows allowed, so catch weapons and make clever use of them!"),
"normal",
file_manager->getDataDir() + "/gui/mode_normal.png");
"normal", "/gui/mode_normal.png");
w2->addItem( _("Time Trial\nContains no powerups, so only your driving skills matter!"),
"timetrial",
file_manager->getDataDir() + "/gui/mode_tt.png");
"timetrial", "/gui/mode_tt.png");
if (unlock_manager->isLocked("followtheleader"))
{
w2->addItem( _("Locked!\nFulfill challenges to gain access to locked areas"),
"locked",
file_manager->getDataDir() + "textures/gui_lock.png");
w2->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", "/gui/mode_ftl.png", true);
}
else
{
w2->addItem( _("Follow the Leader\nrun for second place, as the last kart will be disqualified every time the counter hits zero. Beware : going in front of the leader will get you eliminated too!"),
"ftl",
file_manager->getDataDir() + "/gui/mode_ftl.png");
"ftl", "/gui/mode_ftl.png", false);
}
if (race_manager->getNumPlayers() > 1)
{
w2->addItem( _("3-Strikes Battle\nonly in multiplayer games. Hit others with weapons until they lose all their lives."),
"3strikes",
file_manager->getDataDir() + "/gui/mode_3strikes.png");
"3strikes", "/gui/mode_3strikes.png");
}
m_inited = true;

View File

@ -79,24 +79,33 @@ void TracksScreen::init()
w->clearItems();
const int trackAmount = track_manager->getNumberOfTracks();
bool hasLockedTracks = false;
//bool hasLockedTracks = false;
for (int n=0; n<trackAmount; n++)
{
Track* curr = track_manager->getTrack(n);
/*
if (unlock_manager->isLocked(curr->getIdent()))
{
hasLockedTracks = true;
continue;
}
w->addItem(curr->getName(), curr->getIdent(), curr->getScreenshotFile());
*/
if (unlock_manager->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", curr->getScreenshotFile(), true );
}
else
{
w->addItem( curr->getName(), curr->getIdent(), curr->getScreenshotFile(), false );
}
}
w->addItem(_("Random Track"), "random_track", file_manager->getGUIDir() + "/track_random.png");
w->addItem(_("Random Track"), "random_track", "/gui/track_random.png");
/*
if (hasLockedTracks)
{
w->addItem(_("Locked Tracks"), "Lock", "textures/gui_lock.png");
}
*/
w->updateItemDisplay();
}