diff --git a/data/gui/tracks.stkgui b/data/gui/tracks.stkgui
index 9d087a6ce..f40ee4c71 100644
--- a/data/gui/tracks.stkgui
+++ b/data/gui/tracks.stkgui
@@ -6,10 +6,10 @@
align="center" text_align="center" />
-
-
-
-
+
+
+
+
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))
{
diff --git a/src/guiengine/screen.cpp b/src/guiengine/screen.cpp
index 47adbf229..9f0cd9f0b 100644
--- a/src/guiengine/screen.cpp
+++ b/src/guiengine/screen.cpp
@@ -391,17 +391,19 @@ Widget* Screen::getWidget(const int id, ptr_vector* within_vector)
// -----------------------------------------------------------------------------
Widget* Screen::getFirstWidget(ptr_vector* 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* 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 ||
diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp
index 4bfa4a89f..1767a4696 100644
--- a/src/guiengine/skin.cpp
+++ b/src/guiengine/skin.cpp
@@ -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 center = core::position2d(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 source_area = core::rect(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(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(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 source_area = core::rect(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& 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 source_area = core::rect(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 center = core::position2d(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 center = core::position2d(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 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");
}
diff --git a/src/guiengine/skin.hpp b/src/guiengine/skin.hpp
index c6d41a8e8..4cab80558 100644
--- a/src/guiengine/skin.hpp
+++ b/src/guiengine/skin.hpp
@@ -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
diff --git a/src/guiengine/widget.cpp b/src/guiengine/widget.cpp
index 92511b048..550897fa5 100644
--- a/src/guiengine/widget.cpp
+++ b/src/guiengine/widget.cpp
@@ -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()
diff --git a/src/guiengine/widget.hpp b/src/guiengine/widget.hpp
index af02c9fe4..c38021a30 100644
--- a/src/guiengine/widget.hpp
+++ b/src/guiengine/widget.hpp
@@ -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
diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp
index d954faa6a..70447a304 100644
--- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp
+++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp
@@ -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(&row.m_children[i]);
assert(icon != NULL);
- IGUIButton* button = icon->getIrrlichtElement();
- 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
diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.hpp b/src/guiengine/widgets/dynamic_ribbon_widget.hpp
index a5fa76105..42dd8d59b 100644
--- a/src/guiengine/widgets/dynamic_ribbon_widget.hpp
+++ b/src/guiengine/widgets/dynamic_ribbon_widget.hpp
@@ -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 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. */
diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp
index e09fc9a0b..050222b1a 100644
--- a/src/guiengine/widgets/icon_button_widget.cpp
+++ b/src/guiengine/widgets/icon_button_widget.cpp
@@ -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 widget_size;
- if (clickable)
- {
- widget_size = rect(x + x_gap/2, y, x + w - x_gap/2, y + h);
+ rect widget_size = rect(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(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(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 >& rectangles = sprite_bank->getPositions();
- rectangles.push_back(rect(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() );
}
diff --git a/src/guiengine/widgets/icon_button_widget.hpp b/src/guiengine/widgets/icon_button_widget.hpp
index 6bbbe5f64..0d9ba985c 100644
--- a/src/guiengine/widgets/icon_button_widget.hpp
+++ b/src/guiengine/widgets/icon_button_widget.hpp
@@ -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);
};
}
diff --git a/src/guiengine/widgets/ribbon_widget.cpp b/src/guiengine/widgets/ribbon_widget.cpp
index 62308c671..0e73b92a6 100644
--- a/src/guiengine/widgets/ribbon_widget.cpp
+++ b/src/guiengine/widgets/ribbon_widget.cpp
@@ -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 subsize = rect(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 icon_part = rect(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 subsize = rect(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 subsize = rect(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(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
diff --git a/src/states_screens/challenges.cpp b/src/states_screens/challenges.cpp
index 069a528fd..a22a3e88d 100644
--- a/src/states_screens/challenges.cpp
+++ b/src/states_screens/challenges.cpp
@@ -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; ngetKartById(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();
diff --git a/src/states_screens/options_screen_av.cpp b/src/states_screens/options_screen_av.cpp
index 83b94eb1d..9c2792198 100644
--- a/src/states_screens/options_screen_av.cpp
+++ b/src/states_screens/options_screen_av.cpp
@@ -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;
diff --git a/src/states_screens/options_screen_input.cpp b/src/states_screens/options_screen_input.cpp
index 17a9b183e..c101ef80a 100644
--- a/src/states_screens/options_screen_input.cpp
+++ b/src/states_screens/options_screen_input.cpp
@@ -103,15 +103,14 @@ void OptionsScreenInput::init()
for (int i=0; igetDeviceList()->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");
}
}
diff --git a/src/states_screens/race_setup_screen.cpp b/src/states_screens/race_setup_screen.cpp
index cc5b5c953..1328c4791 100644
--- a/src/states_screens/race_setup_screen.cpp
+++ b/src/states_screens/race_setup_screen.cpp
@@ -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;
diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp
index d8e9f4100..b7b97be80 100644
--- a/src/states_screens/tracks_screen.cpp
+++ b/src/states_screens/tracks_screen.cpp
@@ -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; ngetTrack(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();
}