Added documentation & style cleanup & minor potential fixes

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3931 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2009-08-27 16:14:24 +00:00
parent 88abe09dd6
commit dde666bf9a
20 changed files with 141 additions and 51 deletions

View File

@ -629,7 +629,7 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const
}
const bool mark_focused = focused || (parent_focused && w != NULL && w->m_focus == widget) ||
(mark_selected && !always_show_selection && parent_focused);
(mark_selected && !always_show_selection && parent_focused);
if(always_show_selection && mark_selected)

View File

@ -186,7 +186,7 @@ namespace GUIEngine
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
Widget constructor and it will reserve a widget ID and store it here.
2) Theorically, in 'add()', derivded widgets should checked if this value is set, and use
2) Theorically, in 'add()', derived widgets should checked if this value is set, and use
it instead of creating a new ID if it is. In practice, it's not widely implemented (FIXME) */
int m_reserved_id;

View File

@ -23,7 +23,7 @@ ButtonWidget::ButtonWidget()
{
m_type = WTYPE_BUTTON;
}
// -----------------------------------------------------------------------------
void ButtonWidget::add()
{
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
@ -34,6 +34,7 @@ void ButtonWidget::add()
m_element->setTabOrder(id);
m_element->setTabGroup(false);
}
// -----------------------------------------------------------------------------
void ButtonWidget::setLabel(const char* label)
{
m_element->setText( stringw(label).c_str() );

View File

@ -30,6 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A text button widget. See guiengine/engine.hpp for a detailed overview */
class ButtonWidget : public Widget
{
public:
@ -37,6 +38,8 @@ namespace GUIEngine
virtual ~ButtonWidget() {}
void add();
/** Change the label on the button */
void setLabel(const char* label);
};
}

View File

@ -25,7 +25,7 @@ CheckBoxWidget::CheckBoxWidget()
m_event_handler = this;
m_type = WTYPE_CHECKBOX;
}
// -----------------------------------------------------------------------------
void CheckBoxWidget::add()
{
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
@ -37,7 +37,7 @@ void CheckBoxWidget::add()
m_element->setTabOrder(id);
m_element->setTabGroup(false);
}
// -----------------------------------------------------------------------------
bool CheckBoxWidget::transmitEvent(Widget* w, std::string& originator)
{
/* toggle */

View File

@ -30,6 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A checkbox widget. See guiengine/engine.hpp for a detailed overview */
class CheckBoxWidget : public Widget
{
bool m_state;
@ -40,8 +41,12 @@ namespace GUIEngine
virtual ~CheckBoxWidget() {}
void add();
/** Get whether the checkbox is checked */
bool getState() const { return m_state; }
void setState(const bool enabled) { m_state = enabled; }
/** Set whether the checkbox is checked */
void setState(const bool checked) { m_state = checked; }
};
}

View File

@ -30,6 +30,7 @@ IconButtonWidget::IconButtonWidget(const bool clickable)
// -----------------------------------------------------------------------------
void IconButtonWidget::add()
{
// ---- Icon
ITexture* texture = GUIEngine::getDriver()->getTexture((file_manager->getDataDir() + "/" +m_properties[PROP_ICON]).c_str());
const int texture_w = texture->getSize().Width, texture_h = texture->getSize().Height;
/*
@ -63,8 +64,10 @@ void IconButtonWidget::add()
btn->setTabStop(false);
btn->setScaleImage(true);
}
// ---- label if any
stringw message = m_properties[PROP_TEXT].c_str();
if(message.size() > 0)
if (message.size() > 0)
{
widget_size += position2d<s32>(0, widget_size.getHeight());
label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size, false, false /* word wrap */, m_parent);
@ -72,6 +75,7 @@ void IconButtonWidget::add()
label->setTabStop(false);
}
// ---- IDs
id = m_element->getID();
if(clickable) m_element->setTabOrder(id);
m_element->setTabGroup(false);
@ -96,10 +100,10 @@ void IconButtonWidget::add()
button->setSprite(EGBS_BUTTON_DOWN, sprite_bank->getSprites().size()-1);
*/
}
// -----------------------------------------------------------------------------
void IconButtonWidget::setLabel(std::string new_label)
{
if(label == NULL) return;
if (label == NULL) return;
label->setText( stringw(new_label.c_str()).c_str() );
}

View File

@ -30,6 +30,8 @@ using namespace gui;
namespace GUIEngine
{
/** A button widget with an icon and optionnaly a label beneath (from its properties in base class Widget)
See guiengine/engine.hpp for a detailed overview */
class IconButtonWidget : public Widget
{
bool clickable;
@ -39,6 +41,8 @@ namespace GUIEngine
virtual ~IconButtonWidget() {}
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);
};
}

View File

@ -23,7 +23,7 @@ LabelWidget::LabelWidget()
{
m_type = WTYPE_LABEL;
}
// -----------------------------------------------------------------------------
void LabelWidget::add()
{
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
@ -44,7 +44,7 @@ void LabelWidget::add()
m_element->setTabStop(false);
m_element->setTabGroup(false);
}
// -----------------------------------------------------------------------------
void LabelWidget::setText(stringw newText)
{
IGUIStaticText* irrwidget = Widget::getIrrlichtElement<IGUIStaticText>();

View File

@ -30,6 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A simple label widget. See guiengine/engine.hpp for a detailed overview. */
class LabelWidget : public Widget
{
public:
@ -37,6 +38,8 @@ namespace GUIEngine
virtual ~LabelWidget() {}
void add();
/** Change the text in the label */
void setText(stringw newText);
};
}

View File

@ -23,13 +23,14 @@ ListWidget::ListWidget()
{
m_type = WTYPE_LIST;
}
// -----------------------------------------------------------------------------
void ListWidget::add()
{
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
m_element = GUIEngine::getGUIEnv()->addListBox (widget_size, m_parent, getNewID());
}
// -----------------------------------------------------------------------------
void ListWidget::clear()
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
@ -37,20 +38,21 @@ void ListWidget::clear()
list->clear();
}
// -----------------------------------------------------------------------------
void ListWidget::addItem(const char* item)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
list->addItem( stringw(item).c_str() );
}
// -----------------------------------------------------------------------------
int ListWidget::getSelection() const
{
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
return list->getSelected();
}
// -----------------------------------------------------------------------------
std::string ListWidget::getSelectionName() const
{
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();

View File

@ -30,6 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A vertical list widget with text entries. See guiengine/engine.hpp for a detailed overview */
class ListWidget : public Widget
{
public:

View File

@ -30,7 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A model view widget. See guiengine/engine.hpp for a detailed overview */
class ModelViewWidget : public Widget
{

View File

@ -43,7 +43,7 @@ RibbonGridWidget::RibbonGridWidget(const bool combo, const int max_rows)
// -----------------------------------------------------------------------------
void RibbonGridWidget::add()
{
m_has_label = m_properties[PROP_TEXT] == "bottom";
m_has_label = (m_properties[PROP_TEXT] == "bottom");
m_label_height = m_has_label ? 25 : 0; // FIXME : get height from font, don't hardcode
// ----- add dynamic label at bottom
@ -172,13 +172,18 @@ void RibbonGridWidget::setSubElements()
}
// add rows
for(int n=0; n<m_row_amount; n++)
for (int n=0; n<m_row_amount; n++)
{
RibbonWidget* ribbon;
if (m_combo)
ribbon = new RibbonWidget(RIBBON_COMBO, m_ids[n]);
{
ribbon = new RibbonWidget(RIBBON_COMBO);
}
else
ribbon = new RibbonWidget(RIBBON_TOOLBAR, m_ids[n]);
{
ribbon = new RibbonWidget(RIBBON_TOOLBAR);
}
ribbon->m_reserved_id = m_ids[n];
ribbon->x = x + m_arrows_w;
ribbon->y = y + (int)(n*row_height);
@ -374,6 +379,7 @@ bool RibbonGridWidget::mouseHovered(Widget* child)
// -----------------------------------------------------------------------------
void RibbonGridWidget::focused()
{
Widget::focused();
updateLabel();
const int listenerAmount = m_hover_listeners.size();
@ -494,11 +500,11 @@ void RibbonGridWidget::updateItemDisplay()
const int max_scroll = std::max(m_col_amount, m_needed_cols) - 1;
for(int n=0; n<row_amount; n++)
for (int n=0; n<row_amount; n++)
{
RibbonWidget& row = m_rows[n];
for(int i=0; i<m_col_amount; i++)
for (int i=0; i<m_col_amount; i++)
{
IconButtonWidget* icon = dynamic_cast<IconButtonWidget*>(&row.m_children[i]);
assert(icon != NULL);
@ -510,7 +516,7 @@ void RibbonGridWidget::updateItemDisplay()
icon_id = (col_scroll)*row_amount + n;
if( icon_id < item_amount )
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() ));

View File

@ -49,6 +49,8 @@ namespace GUIEngine
std::string m_sshot_file;
};
/** A dynamic ribbon (builds upon RibbonWidget, adding dynamic contents creation and sizing, scrolling, multiple-row
layouts). See guiengine/engine.hpp for a detailed overview */
class RibbonGridWidget : public Widget
{
friend class RibbonWidget;
@ -57,10 +59,11 @@ namespace GUIEngine
virtual ~RibbonGridWidget() {}
/** reference pointers only, the actual instances are owned by m_children */
/** Reference pointers only, the actual instances are owned by m_children. Used to create mtultiple-row
ribbons (what appears to be a grid of icons is actually a vector of stacked basic ribbons) */
ptr_vector<RibbonWidget, REF> m_rows;
/** Used for ribbon grids that have a label */
/** Used for ribbon grids that have a label at the bottom */
bool m_has_label;
IGUIStaticText* m_label;
int m_label_height;
@ -74,9 +77,10 @@ namespace GUIEngine
/** Width of the scrolling arrows on each side */
int m_arrows_w;
/** Current scroll offset within items */
int m_scroll_offset;
int m_needed_cols;
/** Width and height of children as declared in the GUI file */
int m_child_width, m_child_height;
/** Number of rows and columns. Number of columns can dynamically change, number of row is
@ -84,7 +88,18 @@ namespace GUIEngine
int m_row_amount;
int m_col_amount;
/** The total number of columns given item count and row count (even counting not visible with current scrolling) */
int m_needed_cols;
/** The maximum number of rows, as passed to the constructor */
int m_max_rows;
/** irrlicht relies on consecutive IDs to perform keyboard navigation between widgets. However, since this
widget is dynamic, irrlicht widgets are not created as early as all others, so by the time we're ready
to create the full contents of this widget, the ID generator is already incremented, thus messing up
keyboard navigation. To work around this, at the same time all other widgets are created, I gather a
number of IDs (the number of rows) and store them here. Then, when we're finally ready to create the
contents dynamically, we can re-use these IDs and get correct navigation order. */
std::vector<int> m_ids;
/** Whether this is a "combo" style ribbon grid widget */
@ -94,7 +109,10 @@ namespace GUIEngine
Widget* m_left_widget;
Widget* m_right_widget;
/** Returns the currently selected row */
RibbonWidget* getSelectedRibbon() const;
/** Returns the row */
RibbonWidget* getRowContaining(Widget* w) const;
/** Updates the visible label to match the currently selected item */
@ -114,35 +132,48 @@ namespace GUIEngine
/** Removes all previously added contents icons, and re-adds them (calculating the new amount) */
void setSubElements();
/** Call this to scroll within a scrollable ribbon */
void scroll(const int x_delta);
/** Used for combo ribbons, to contain the ID of the currently selected item */
int m_selected_item;
/** Callbacks */
void onRowChange(RibbonWidget* row);
void add();
bool mouseHovered(Widget* child);
public:
RibbonGridWidget(const bool combo=false, const int max_rows=4);
/** Register a listener to be notified of selection changes within the ribbon */
void registerHoverListener(RibbonGridHoverListener* listener);
void add();
/** Called when right key is pressed */
bool rightPressed();
/** Called when left key is pressed */
bool leftPressed();
/** Dynamically add an item to the ribbon's list of items (will not be visible until you
call 'updateItemDisplay' or 'add') */
void addItem( std::string user_name, std::string code_name, std::string image_file );
/** Updates icons/labels given current items and scrolling offset, taking care of resizing
the dynamic ribbon if the number of items changed */
void updateItemDisplay();
bool mouseHovered(Widget* child);
void onRowChange(RibbonWidget* row);
/** Get the internal name (ID) of the selected item */
const std::string& getSelectionIDString();
/** Get the user-visible text of the selected item */
const std::string& getSelectionText();
/** Select an item from its numerical ID. Only for [1-row] combo ribbons.
ID ranges from {0} to {number of items added through 'addItem' - 1} */
void setSelection(int item_id);
/** Select an item from its internal name */
void setSelection(const std::string& code_name);
};

View File

@ -26,14 +26,14 @@ using namespace GUIEngine;
# define round(x) (floor(x+0.5f))
#endif
RibbonWidget::RibbonWidget(const RibbonType type, int id)
// -----------------------------------------------------------------------------
RibbonWidget::RibbonWidget(const RibbonType type)
{
m_selection = 0;
m_ribbon_type = type;
m_focus = NULL;
updateSelection();
m_type = WTYPE_RIBBON;
m_given_id = id;
}
// -----------------------------------------------------------------------------
void RibbonWidget::add()
@ -43,7 +43,7 @@ void RibbonWidget::add()
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
int id = (m_given_id == -1 ? getNewID() : m_given_id);
int id = (m_reserved_id == -1 ? getNewID() : m_reserved_id);
IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, id, L"");
m_element = btn;
@ -250,11 +250,14 @@ bool RibbonWidget::leftPressed()
// -----------------------------------------------------------------------------
void RibbonWidget::focused()
{
if(m_focus == NULL) m_focus = m_children.get(m_selection);
Widget::focused();
if(m_event_handler != NULL)
if (m_focus == NULL) m_focus = m_children.get(m_selection);
if (m_event_handler != NULL)
{
GUIEngine::getGUIEnv()->setFocus(m_focus->m_element);
// FIXME : unclean, children ribbons shouldn't need to know about their parent
((RibbonGridWidget*)m_event_handler)->onRowChange( this );
}
}
@ -265,12 +268,12 @@ bool RibbonWidget::mouseHovered(Widget* child)
m_focus = child;
for(int i=0; i<subbuttons_amount; i++)
for (int i=0; i<subbuttons_amount; i++)
{
if(m_children.get(i) == child)
if (m_children.get(i) == child)
{
if(m_selection == i) return false; // was already selected, don't send another event
if(m_ribbon_type == RIBBON_TOOLBAR) m_selection = i; // don't change selection on hover for others
if (m_selection == i) return false; // was already selected, don't send another event
if (m_ribbon_type == RIBBON_TOOLBAR) m_selection = i; // don't change selection on hover for others
break;
}
}
@ -306,10 +309,10 @@ bool RibbonWidget::transmitEvent(Widget* w, std::string& originator)
GUIEngine::getGUIEnv()->setFocus(m_element);
return true;
}
// -----------------------------------------------------------------------------
void RibbonWidget::setLabel(const int id, std::string new_name)
{
if(m_labels.size() == 0) return; // ignore this call for ribbons without labels
if (m_labels.size() == 0) return; // ignore this call for ribbons without labels
assert(id >= 0);
assert(id < m_labels.size());

View File

@ -38,40 +38,64 @@ namespace GUIEngine
RIBBON_TABS /* a tab bar */
};
/** A static text/icons/tabs bar widget. The contents of this ribbon are static.
See guiengine/engine.hpp for a detailed overview */
class RibbonWidget : public Widget
{
friend class RibbonGridWidget;
friend class EventHandler;
int m_selection;
RibbonType m_ribbon_type;
int m_given_id;
/** The type of this ribbon (toolbar, combo, tabs) */
RibbonType m_ribbon_type;
void add();
/** Each item within the ribbon holds a flag saying whether it is selected or not.
This method updates the flag in all of this ribbon's children. Called everytime
selection changes.*/
void updateSelection();
/** Callbacks */
bool rightPressed();
bool leftPressed();
bool mouseHovered(Widget* child);
void updateSelection();
bool transmitEvent(Widget* w, std::string& originator);
void focused();
ptr_vector<IGUIStaticText, REF> m_labels;
public:
/** Contains which element within the ribbon is currently focused (used by the skin) */
Widget* m_focus;
RibbonWidget(const RibbonType type=RIBBON_COMBO, int id=-1);
RibbonWidget(const RibbonType type=RIBBON_COMBO);
virtual ~RibbonWidget() {}
/** Returns the numerical ID of the selected item within the ribbon */
int getSelection() const { return m_selection; }
/** Returns the string ID (internal name) of the selection */
const std::string& getSelectionIDString() { return m_children[m_selection].m_properties[PROP_ID]; }
/** Returns the user-visible text of the selection */
const std::string& getSelectionText() { return m_children[m_selection].m_properties[PROP_TEXT]; }
/** Returns the type of this ribbon (see guiengine/engine.hpp for detaield descriptions) */
RibbonType getRibbonType() const { return m_ribbon_type; }
/** Sets the ID of the selected item within the ribbon */
void setSelection(const int i) { m_selection = i; updateSelection(); }
/** Select an item in the ribbon by its internal name */
void select(std::string item);
RibbonType getRibbonType() const { return m_ribbon_type; }
const std::string& getSelectionIDString() { return m_children[m_selection].m_properties[PROP_ID]; }
const std::string& getSelectionText() { return m_children[m_selection].m_properties[PROP_TEXT]; }
/** When each item has a label, this method can be used to rename an item
(especially used in scrolling ribbons, when scrolling occurs by renaming
items - note that this statis ribbon doesn't support scrolling, only
superclasses/wrappers of this do.) */
void setLabel(const int id, std::string new_name);
};

View File

@ -25,12 +25,13 @@
#include "utils/translation.hpp"
using namespace GUIEngine;
// -----------------------------------------------------------------------------
SpinnerWidget::SpinnerWidget(const bool gauge)
{
m_gauge = gauge;
m_type = WTYPE_SPINNER;
}
// -----------------------------------------------------------------------------
void SpinnerWidget::add()
{
// retrieve min and max values
@ -142,7 +143,7 @@ void SpinnerWidget::add()
m_children[2].m_properties[PROP_ID] = "right";
m_children[2].id = m_children[2].m_element->getID();
}
// -----------------------------------------------------------------------------
void SpinnerWidget::move(const int x, const int y, const int w, const int h)
{
Widget::move(x, y, w, h);

View File

@ -30,6 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A spinner or gauge widget (to select numbers / percentages). See guiengine/engine.hpp for a detailed overview */
class SpinnerWidget : public Widget
{
int m_value, m_min, m_max;

View File

@ -30,6 +30,7 @@ using namespace gui;
namespace GUIEngine
{
/** A text field widget. See guiengine/engine.hpp for a detailed overview */
class TextBoxWidget : public Widget
{
public: