New main menu, more minimalistic, based on mockup by samuncle. Please comment

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10372 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2011-12-08 00:25:23 +00:00
parent 9f727200c3
commit 8b50b30ecc
21 changed files with 151 additions and 42 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 127 KiB

View File

@ -1,36 +1,40 @@
<stkgui>
<div x="5%" y="0" width="90%" height="100%" layout="vertical-row" >
<icon id="logo" align="center" proportion="8" width="100%" icon="gui/logo.png"/>
<buttonbar id="menu_toprow" proportion="3" width="75%" align="center">
<div x="0" y="0" width="100%" height="100%" layout="vertical-row" >
<topbar width="100%" height="9%" layout="horizontal-row">
<spacer proportion="1" height="1"/>
<buttonbar id="menu_bottomrow" x="0" y="0" width="30%" height="100%" align="center">
<icon-button id="options" width="64" height="64" icon="gui/main_options.png"
I18N="Main menu button" text="Options" label_location="hover"/>
<icon-button id="help" width="64" height="64" icon="gui/main_help.png"
I18N="Main menu button" text="Help" label_location="hover"/>
<icon-button id="about" width="64" height="64" icon="gui/main_about.png"
I18N="Main menu button" text="About" label_location="hover"/>
<icon-button id="quit" width="64" height="64" icon="gui/main_quit.png"
I18N="Main menu button" text="Quit" label_location="hover"/>
</buttonbar>
</topbar>
<icon id="logo" align="center" proportion="5" width="100%" icon="gui/logo.png"/>
<buttonbar id="menu_toprow" proportion="4" width="75%" align="center">
<icon-button id="story" width="128" height="128"
icon="gui/challenge.png"
icon="gui/challenge.png" label_location="hover"
I18N="Main menu button" text="Story Mode"/>
<icon-button id="new" width="128" height="128" icon="gui/main_race.png"
I18N="Main menu button" text="Single-player"/>
label_location="hover"
I18N="Main menu button" text="Single-player"/>
<icon-button id="multiplayer" width="128" height="128" icon="gui/main_race_multi.png"
I18N="Main menu button" text="Multiplayer"/>
label_location="hover"
I18N="Main menu button" text="Multiplayer"/>
<icon-button id="addons" width="128" height="128"
icon="gui/addons.png"
icon="gui/addons.png" label_location="hover"
I18N="Main menu button" text="Addons"/>
</buttonbar>
<spacer width="10" proportion="1"/>
<buttonbar id="menu_bottomrow" proportion="3" width="85%" align="center">
<icon-button id="options" width="128" height="128" icon="gui/main_options.png"
I18N="Main menu button" text="Options"/>
<icon-button id="help" width="128" height="128" icon="gui/main_help.png"
I18N="Main menu button" text="Help"/>
<icon-button id="about" width="128" height="128" icon="gui/main_about.png"
I18N="Main menu button" text="About"/>
<icon-button id="quit" width="128" height="128" icon="gui/main_quit.png"
I18N="Main menu button" text="Quit"/>
</buttonbar>
<spacer width="10" proportion="1"/>
<spacer width="10" height="3%"/>
<bottombar width="100%" height="10%" layout="horizontal-row">
<spacer width="10" height="10" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 49 KiB

BIN
data/gui/top_bar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -77,6 +77,12 @@ void Screen::parseScreenFileDiv(irr::io::IXMLReader* xml, PtrVector<Widget>& app
w->m_bottom_bar = true;
append_to.push_back(w);
}
else if (wcscmp(L"topbar", xml->getNodeName()) == 0)
{
Widget* w = new Widget(WTYPE_DIV);
w->m_top_bar = true;
append_to.push_back(w);
}
else if (wcscmp(L"roundedbox", xml->getNodeName()) == 0)
{
Widget* w = new Widget(WTYPE_DIV);
@ -243,6 +249,10 @@ if(prop_name != NULL) widget.m_properties[prop_flag] = core::stringc(prop_name).
return;
if (wcscmp(L"roundedbox", xml->getNodeName()) == 0)
return;
if (wcscmp(L"bottombar", xml->getNodeName()) == 0)
return;
if (wcscmp(L"topbar", xml->getNodeName()) == 0)
return;
// we're done parsing this 'ribbon', return one step back in the recursive call
if (wcscmp(L"ribbon", xml->getNodeName()) == 0 ||

View File

@ -1578,6 +1578,18 @@ void Skin::renderSections(PtrVector<Widget>* within_vector)
irr_driver->getVideoDriver()->draw2DImage(tex, r1, r2,
0, 0, /*alpha*/true);
}
else if (widget.isTopBar())
{
ITexture* tex =
irr_driver->getTexture( file_manager->getGUIDir()
+ "top_bar.png" );
core::recti r1(0, 0,
(int)widget.m_w, (int)widget.m_h);
core::recti r2(core::dimension2di(0,0), tex->getSize());
irr_driver->getVideoDriver()->draw2DImage(tex, r1, r2,
0, 0, /*alpha*/false);
}
else
{
renderSections( &widget.m_children );

View File

@ -74,6 +74,7 @@ Widget::Widget(WidgetType type, bool reserve_id)
m_parent = NULL;
m_focusable = true;
m_bottom_bar = false;
m_top_bar = false;
m_event_handler = NULL;
m_reserve_id = reserve_id;
m_show_bounding_box = false;
@ -259,7 +260,7 @@ void Widget::setFocusForPlayer(const int playerID)
// Unset focus flag on previous widget that had focus
if (GUIEngine::getFocusForPlayer(playerID) != NULL)
{
GUIEngine::getFocusForPlayer(playerID)->unfocused(playerID);
GUIEngine::getFocusForPlayer(playerID)->unfocused(playerID, this);
GUIEngine::getFocusForPlayer(playerID)->m_player_focus[playerID] = false;
}
@ -276,7 +277,7 @@ void Widget::unsetFocusForPlayer(const int playerID)
{
assert(m_magic_number == 0xCAFEC001);
if (m_player_focus[playerID]) this->unfocused(playerID);
if (m_player_focus[playerID]) this->unfocused(playerID, NULL);
m_player_focus[playerID] = false;
}

View File

@ -191,7 +191,7 @@ namespace GUIEngine
virtual EventPropagation focused(const int playerID) { setWithinATextBox(false); return EVENT_LET; }
/** override in children if you need to know when the widget is unfocused. */
virtual void unfocused(const int playerID) { }
virtual void unfocused(const int playerID, Widget* new_focus) { }
/**
* An irrlicht parent (most often used to put widgets in dialogs)
@ -238,7 +238,8 @@ namespace GUIEngine
bool m_focusable;
bool m_bottom_bar;
bool m_top_bar;
/** If a badge wouldn't look too pretty on the very side of the widget */
int m_badge_x_shift;
@ -332,7 +333,8 @@ namespace GUIEngine
bool isSelected(const int playerID) const { return m_selected[playerID]; }
bool isBottomBar() const { return m_bottom_bar; }
bool isTopBar () const { return m_top_bar; }
/**
* \name Enabling or disabling widgets
* \{

View File

@ -156,7 +156,7 @@ EventPropagation BubbleWidget::focused(const int playerID)
// ----------------------------------------------------------------------------
/*
void BubbleWidget::unfocused(const int playerID)
void BubbleWidget::unfocused(const int playerID, Widget* new_focus)
{
if (m_element != NULL)
{

View File

@ -59,3 +59,6 @@ EventPropagation CheckBoxWidget::transmitEvent(Widget* w,
/* notify main event handler */
return EVENT_LET;
}
// -----------------------------------------------------------------------------

View File

@ -53,6 +53,7 @@ namespace GUIEngine
/** Set whether the checkbox is checked */
void setState(const bool checked) { m_state = checked; }
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getHeightNeededAroundLabel() const { return 10; }

View File

@ -139,6 +139,11 @@ void IconButtonWidget::add()
m_label->setTabStop(false);
m_label->setNotClipped(true);
if (m_properties[PROP_LABELS_LOCATION] == "hover")
{
m_label->setVisible(false);
}
const int max_w = m_label->getAbsolutePosition().getWidth();
if (!word_wrap &&
(int)GUIEngine::getFont()->getDimension(message.c_str()).Width > max_w + 4) // arbitrarily allow for 4 pixels
@ -225,3 +230,25 @@ void IconButtonWidget::setLabel(stringw new_label)
m_label->setOverrideFont( NULL );
}
}
// -----------------------------------------------------------------------------
EventPropagation IconButtonWidget::focused(const int playerID)
{
Widget::focused(playerID);
if (m_label != NULL && m_properties[PROP_LABELS_LOCATION] == "hover")
{
m_label->setVisible(true);
}
return EVENT_LET;
}
// -----------------------------------------------------------------------------
void IconButtonWidget::unfocused(const int playerID, Widget* new_focus)
{
Widget::unfocused(playerID, new_focus);
if (m_label != NULL && m_properties[PROP_LABELS_LOCATION] == "hover")
{
m_label->setVisible(false);
}
}

View File

@ -122,6 +122,12 @@ namespace GUIEngine
{
m_highlight_texture = texture;
}
/** \brief override from base class */
virtual EventPropagation focused(const int playerID);
/** \brief override from base class */
virtual void unfocused(const int playerID, Widget* new_focus);
};
}

View File

@ -231,7 +231,7 @@ void ListWidget::selectItemWithLabel(const irr::core::stringw& name)
// -----------------------------------------------------------------------------
void ListWidget::unfocused(const int playerID)
void ListWidget::unfocused(const int playerID, Widget* new_focus)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();

View File

@ -96,7 +96,7 @@ namespace GUIEngine
virtual void add();
/** \brief implement callback from base class GUIEngine::Widget */
virtual void unfocused(const int playerID);
virtual void unfocused(const int playerID, Widget* new_focus);
/** \brief implement callback from base class GUIEngine::Widget */
virtual void elementRemoved();

View File

@ -66,10 +66,16 @@ RibbonWidget::RibbonWidget(const RibbonType type) : Widget(WTYPE_RIBBON)
// ----------------------------------------------------------------------------
void RibbonWidget::add()
{
m_labels.clearWithoutDeleting();
{
assert(m_magic_number == 0xCAFEC001);
assert(m_x > -10.0f);
assert(m_y > -10.0f);
assert(m_w > 0.0f);
assert(m_h > 0.0f);
m_labels.clearWithoutDeleting();
rect<s32> widget_size = rect<s32>(m_x, m_y, m_x + m_w, m_y + m_h);
int id = (m_reserved_id == -1 ? getNewID() : m_reserved_id);
@ -111,8 +117,14 @@ void RibbonWidget::add()
}
if (m_children[i].m_text.size() > 0) with_label++;
else without_label++;
bool has_label_underneath = m_children[i].m_text.size() > 0;
if (m_children[i].m_properties[PROP_LABELS_LOCATION].size() > 0)
{
has_label_underneath = false;
}
if (has_label_underneath) with_label++;
else without_label++;
total_needed_space += m_children[i].m_w;
}
@ -267,7 +279,12 @@ void RibbonWidget::add()
// find how much space to keep for the label under the button.
// consider font size, whether the label is multiline, etc...
const bool has_label = m_children[i].m_text.size() > 0;
bool has_label = m_children[i].m_text.size() > 0;
if (m_children[i].m_properties[PROP_LABELS_LOCATION].size() > 0)
{
has_label = false;
}
const int needed_space_under_button = has_label
? GUIEngine::getFontHeight()
@ -422,6 +439,7 @@ EventPropagation RibbonWidget::rightPressed(const int playerID)
if (m_children.size() < 2) return EVENT_LET;
m_selection[playerID]++;
if (m_selection[playerID] >= m_children.size())
{
if (m_listener != NULL) m_listener->onRibbonWidgetScroll(1);
@ -457,7 +475,7 @@ EventPropagation RibbonWidget::leftPressed(const int playerID)
if (m_deactivated) return EVENT_LET;
// empty ribbon, or only one item (can't move left)
if (m_children.size() < 2) return EVENT_LET;
m_selection[playerID]--;
if (m_selection[playerID] < 0)
{
@ -467,6 +485,7 @@ EventPropagation RibbonWidget::leftPressed(const int playerID)
? 0
: m_children.size()-1;
}
updateSelection();
if (m_ribbon_type == RIBBON_COMBO)
@ -510,6 +529,14 @@ EventPropagation RibbonWidget::focused(const int playerID)
(playerID == mousePlayerID || playerID == PLAYER_ID_GAME_MASTER))
{
m_mouse_focus = m_children.get(m_selection[playerID]);
m_mouse_focus->focused(playerID);
}
}
else
{
if (m_selection[playerID] != -1)
{
m_children.get(m_selection[playerID])->focused(playerID);
}
}
@ -521,8 +548,17 @@ EventPropagation RibbonWidget::focused(const int playerID)
// ----------------------------------------------------------------------------
void RibbonWidget::unfocused(const int playerID)
void RibbonWidget::unfocused(const int playerID, Widget* new_focus)
{
if (new_focus != NULL && new_focus != this && !m_children.contains(new_focus))
{
if (m_selection[playerID] != -1)
{
m_children.get(m_selection[playerID])->unfocused(playerID, new_focus);
}
}
//if (m_selection[0] != -1) m_children.get(m_selection[0])->unfocused(0);
} // unfocused
// ----------------------------------------------------------------------------
@ -548,6 +584,7 @@ EventPropagation RibbonWidget::mouseHovered(Widget* child,
{
// Was already selected, don't send another event
if (m_selection[mousePlayerID] == i) return EVENT_BLOCK;
// Don't change selection on hover for others
m_selection[mousePlayerID] = i;
break;
@ -588,7 +625,13 @@ void RibbonWidget::updateSelection()
{
for (int i=0; i<subbuttons_amount; i++)
{
m_children[i].m_selected[p] = (i == m_selection[p]);
bool new_val = (i == m_selection[p]);
if (!new_val && m_children[i].m_selected[p])
{
m_children[i].unfocused(PLAYER_ID_GAME_MASTER, NULL);
}
m_children[i].m_selected[p] = new_val;
if (new_val) m_children[i].focused(PLAYER_ID_GAME_MASTER);
}
}

View File

@ -82,7 +82,7 @@ namespace GUIEngine
const std::string& originator,
const int playerID=0);
virtual EventPropagation focused(const int playerID);
virtual void unfocused(const int playerID);
virtual void unfocused(const int playerID, Widget* new_focus);
PtrVector<irr::gui::IGUIStaticText, REF> m_labels;

View File

@ -140,7 +140,7 @@ EventPropagation TextBoxWidget::focused(const int playerID)
// -----------------------------------------------------------------------------
void TextBoxWidget::unfocused(const int playerID)
void TextBoxWidget::unfocused(const int playerID, Widget* new_focus)
{
assert(playerID == 0); // No support for multiple players in text areas!

View File

@ -62,7 +62,7 @@ namespace GUIEngine
void addItem(const char* item);
virtual EventPropagation focused(const int playerID);
virtual void unfocused(const int playerID);
virtual void unfocused(const int playerID, Widget* new_focus);
void addListener(ITextBoxWidgetListener* listener);
void clearListeners();