got sick with my own gauge implementation using an irrlicht scrollbar(irrlicht has no gauge widget) - it had all kinds of weird side effects. I rewrote it using my Spinner widget instead. Some functionnality is lost but at least it's pretty much bug-free
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3461 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
5f96bcf478
commit
911f98fcca
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div width="75%" height="30" layout="horizontal-row" >
|
||||
<spacer proportion="1" height="100%"/>
|
||||
<gauge id="music_volume" proportion="1" height="100%"/>
|
||||
<gauge id="music_volume" proportion="1" height="100%" min_value="0" max_value="10"/>
|
||||
</div>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
@ -34,7 +34,7 @@
|
||||
</div>
|
||||
<div width="75%" height="30" layout="horizontal-row" >
|
||||
<spacer proportion="1" height="100%"/>
|
||||
<gauge id="sfx_volume" proportion="1" height="100%"/>
|
||||
<gauge id="sfx_volume" proportion="1" height="100%" min_value="0" max_value="10"/>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -19,19 +19,17 @@ Ribbon widgets are of spawn type (<ribbon> ... </ribbon>) and may contain icon-b
|
||||
Property PROP_SQUARE can be set to tell the engine if the ribbon's contents are rectangular or not (this will
|
||||
affect the type of highlighting used)
|
||||
|
||||
WTYPE_SPINNER "spinner"
|
||||
WTYPE_SPINNER "spinner", "gauge"
|
||||
A spinner component (lets you choose numbers). Sprecify PROP_MIN_VALUE and PROP_MAX_VALUE to have control
|
||||
over values (default will be from 0 to 10). You can specify an icon; then, include a sprintf format string
|
||||
like %i in the name, and at runtime the current number will be inserted into the given name to find the
|
||||
right file for each possible value the spinner can take. It may also display arbitrary text instead of
|
||||
numbers, though this cannot be achieve in the XML file; use the ->addLabel(...) method in code to do this.
|
||||
The "gauge" variant behaves similarly, but a fill band shows how close to the max the value is.
|
||||
|
||||
WTYPE_BUTTON "button"
|
||||
A plain text buttons.
|
||||
|
||||
WTYPE_GAUGE "gauge"
|
||||
A control that lets users choose a value between a maximal and a minimal value, with a graphical filling bar.
|
||||
|
||||
WTYPE_ICON_BUTTON "icon-button", "icon"
|
||||
A component with an image, and optional text to go under it. The "icon" variant will have no border and will not
|
||||
be clickable. PROP_ICON is mandatory for this component.
|
||||
|
@ -72,8 +72,10 @@ void parseScreenFileDiv(irr::io::IrrXMLReader* xml, ptr_vector<Widget>& append_t
|
||||
}
|
||||
else if (!strcmp("gauge", xml->getNodeName()))
|
||||
{
|
||||
type = WTYPE_GAUGE;
|
||||
append_to.push_back(new GaugeWidget());
|
||||
//type = WTYPE_GAUGE;
|
||||
//append_to.push_back(new GaugeWidget());
|
||||
type = WTYPE_SPINNER;
|
||||
append_to.push_back(new SpinnerWidget(true));
|
||||
}
|
||||
else if (!strcmp("icon-button", xml->getNodeName()))
|
||||
{
|
||||
|
@ -532,12 +532,37 @@ void Skin::drawSpinnerBody(const core::rect< s32 > &rect, const Widget* widget,
|
||||
params.hborder_out_portion = 0.0f;
|
||||
|
||||
drawBoxFromStretchableTexture(rect, (focused || pressed ? m_tex_fspinner : m_tex_spinner), params);
|
||||
|
||||
const SpinnerWidget* w = dynamic_cast<const SpinnerWidget*>(widget);
|
||||
if( w->isGauge() )
|
||||
{
|
||||
// the width of an handle is about 0.84 the height in the current skin. FIXME - don't hardcode.
|
||||
const int handle_size = (int)( widget->h*0.84f );
|
||||
|
||||
|
||||
const float value = (float)(w->getValue() - w->getMin()) / (w->getMax() - w->getMin());
|
||||
|
||||
|
||||
const core::rect< s32 > dest_area = core::rect< s32 >(widget->x + handle_size,
|
||||
widget->y,
|
||||
widget->x + handle_size + (int)((widget->w - 2*handle_size)*value),
|
||||
widget->y + widget->h);
|
||||
|
||||
const int texture_w = m_tex_gaugefill->getSize().Width;
|
||||
const int texture_h = m_tex_gaugefill->getSize().Height;
|
||||
|
||||
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||
|
||||
|
||||
GUIEngine::getDriver()->draw2DImage(m_tex_gaugefill, dest_area, source_area,
|
||||
0 /* no clipping */, 0, true /* alpha */);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Skin::drawSpinnerChild(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused)
|
||||
{
|
||||
|
||||
|
||||
if(pressed)
|
||||
{
|
||||
Widget* spinner = widget->m_event_handler;
|
||||
@ -550,8 +575,8 @@ void Skin::drawSpinnerChild(const core::rect< s32 > &rect, Widget* widget, const
|
||||
else return;
|
||||
|
||||
core::rect< s32 > rect2 = core::rect< s32 >( spinner->x, spinner->y,
|
||||
spinner->x + spinner->w,
|
||||
spinner->y + spinner->h );
|
||||
spinner->x + spinner->w,
|
||||
spinner->y + spinner->h );
|
||||
|
||||
static BoxRenderParams params;
|
||||
// FIXME - move these numbers to a config file
|
||||
@ -570,48 +595,6 @@ void Skin::drawSpinnerChild(const core::rect< s32 > &rect, Widget* widget, const
|
||||
|
||||
}
|
||||
|
||||
void Skin::drawGauge(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
||||
{
|
||||
static BoxRenderParams params;
|
||||
// FIXME - move these numbers to a config file
|
||||
params.left_border = 110;
|
||||
params.right_border = 110;
|
||||
params.top_border = 0;
|
||||
params.bottom_border = 36;
|
||||
|
||||
params.hborder_out_portion = -0.9;
|
||||
|
||||
drawBoxFromStretchableTexture(rect, (focused ? m_tex_fspinner : m_tex_spinner), params);
|
||||
}
|
||||
void Skin::drawGaugeFill(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
||||
{
|
||||
// FIXME - move these numbers to a config file
|
||||
const int left_border = 110;
|
||||
//const int right_border = 110;
|
||||
//const int border_above = 0;
|
||||
//const int border_below = 36;
|
||||
|
||||
|
||||
GaugeWidget* w = dynamic_cast<GaugeWidget*>(widget);
|
||||
|
||||
// the width of an handle is about 0.844 the height in the current skin. FIXME - don't hardcode.
|
||||
const int handle_size = (int)(widget->h*0.844f) + left_border*0.2;
|
||||
|
||||
// the 'rect' argument will be too small, because irrlicht has no suitable gauge component, so i used a scrollbar
|
||||
const core::rect< s32 > dest_area = core::rect< s32 >(widget->x+handle_size, widget->y,
|
||||
widget->x + handle_size + (int)((widget->w - 2*handle_size)*w->getValue()),
|
||||
widget->y + widget->h);
|
||||
|
||||
const int texture_w = m_tex_gaugefill->getSize().Width;
|
||||
const int texture_h = m_tex_gaugefill->getSize().Height;
|
||||
|
||||
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||
|
||||
|
||||
GUIEngine::getDriver()->draw2DImage(m_tex_gaugefill, dest_area, source_area,
|
||||
0 /* no clipping */, 0, true /* alpha */);
|
||||
}
|
||||
|
||||
void Skin::drawCheckBox(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
||||
{
|
||||
CheckBoxWidget* w = dynamic_cast<CheckBoxWidget*>(widget);
|
||||
@ -695,22 +678,15 @@ void Skin::draw2DRectangle (IGUIElement *element, const video::SColor &color, co
|
||||
{
|
||||
if(StateManager::isGameState()) return; // ignore in game mode
|
||||
|
||||
const bool focused = GUIEngine::getGUIEnv()->hasFocus(element);
|
||||
//const bool focused = GUIEngine::getGUIEnv()->hasFocus(element);
|
||||
const int id = element->getID();
|
||||
|
||||
Widget* widget = GUIEngine::getCurrentScreen()->getWidget(id);
|
||||
if(widget == NULL) return;
|
||||
|
||||
const WidgetType type = widget->m_type;
|
||||
// const WidgetType type = widget->m_type;
|
||||
|
||||
|
||||
if(type == WTYPE_GAUGE)
|
||||
{
|
||||
drawGauge(rect, widget, focused);
|
||||
}
|
||||
|
||||
//printf("draw rectangle\n");
|
||||
// GUIEngine::getDriver()->draw2DRectangle( SColor(255, 0, 150, 150), pos );
|
||||
|
||||
}
|
||||
void Skin::process3DPane(IGUIElement *element, const core::rect< s32 > &rect, const bool pressed)
|
||||
{
|
||||
@ -754,11 +730,6 @@ void Skin::process3DPane(IGUIElement *element, const core::rect< s32 > &rect, co
|
||||
{
|
||||
drawSpinnerBody(rect, widget, pressed, focused);
|
||||
}
|
||||
else if(type == WTYPE_GAUGE)
|
||||
{
|
||||
if(!pressed)
|
||||
drawGaugeFill(rect, widget, focused);
|
||||
}
|
||||
else if(type == WTYPE_CHECKBOX)
|
||||
{
|
||||
drawCheckBox(rect, widget, focused);
|
||||
|
@ -54,16 +54,12 @@ namespace GUIEngine
|
||||
ITexture* m_tex_bubble;
|
||||
ITexture* m_tex_squarefocus;
|
||||
ITexture* m_tex_gaugefill;
|
||||
ITexture* m_tex_gauge;
|
||||
|
||||
ITexture* m_tex_checkbox;
|
||||
ITexture* m_tex_fcheckbox;
|
||||
ITexture* m_tex_dcheckbox;
|
||||
ITexture* m_tex_dfcheckbox;
|
||||
|
||||
|
||||
|
||||
|
||||
void drawBoxFromStretchableTexture(const core::rect< s32 > &dest, ITexture* source, const BoxRenderParams& params);
|
||||
|
||||
public:
|
||||
|
@ -277,31 +277,35 @@ namespace StateManager
|
||||
else if(screen_name == "options_input.stkgui") ribbon->select( "controls" );
|
||||
}
|
||||
|
||||
// init audio-video sub-screen
|
||||
// ---- init audio-video sub-screen
|
||||
if(screen_name == "options_av.stkgui")
|
||||
{
|
||||
GUIEngine::GaugeWidget* gauge = dynamic_cast<GUIEngine::GaugeWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("sfx_volume"));
|
||||
// ---- sfx volume
|
||||
GUIEngine::SpinnerWidget* gauge = dynamic_cast<GUIEngine::SpinnerWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("sfx_volume"));
|
||||
assert(gauge != NULL);
|
||||
|
||||
gauge->setValue( sfx_manager->getMasterSFXVolume() );
|
||||
gauge->setValue( sfx_manager->getMasterSFXVolume()*10.0f );
|
||||
|
||||
|
||||
gauge = dynamic_cast<GUIEngine::GaugeWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("music_volume"));
|
||||
gauge = dynamic_cast<GUIEngine::SpinnerWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("music_volume"));
|
||||
assert(gauge != NULL);
|
||||
gauge->setValue( sound_manager->getMasterMusicVolume() );
|
||||
gauge->setValue( sound_manager->getMasterMusicVolume()*10.f );
|
||||
|
||||
|
||||
// ---- music volume
|
||||
GUIEngine::CheckBoxWidget* sfx = dynamic_cast<GUIEngine::CheckBoxWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("sfx_enabled"));
|
||||
|
||||
GUIEngine::CheckBoxWidget* music = dynamic_cast<GUIEngine::CheckBoxWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("music_enabled"));
|
||||
|
||||
// ---- audio enables/disables
|
||||
sfx->setState( user_config->doSFX() );
|
||||
music->setState( user_config->doMusic() );
|
||||
|
||||
// ---- resolutinos
|
||||
{
|
||||
GUIEngine::RibbonGridWidget* res = dynamic_cast<GUIEngine::RibbonGridWidget*>
|
||||
(GUIEngine::getCurrentScreen()->getWidget("resolutions"));
|
||||
@ -365,25 +369,31 @@ namespace StateManager
|
||||
}
|
||||
else if(name == "music_volume")
|
||||
{
|
||||
/*
|
||||
GUIEngine::GaugeWidget* w = dynamic_cast<GUIEngine::GaugeWidget*>(widget);
|
||||
assert(w != NULL);
|
||||
|
||||
|
||||
sound_manager->setMasterMusicVolume( w->getValue() );
|
||||
*/
|
||||
|
||||
GUIEngine::SpinnerWidget* w = dynamic_cast<GUIEngine::SpinnerWidget*>(widget);
|
||||
assert(w != NULL);
|
||||
|
||||
sound_manager->setMasterMusicVolume( w->getValue()/10.0f );
|
||||
}
|
||||
else if(name == "sfx_volume")
|
||||
{
|
||||
static SFXBase* sample_sound = NULL;
|
||||
|
||||
GUIEngine::GaugeWidget* w = dynamic_cast<GUIEngine::GaugeWidget*>(widget);
|
||||
// GUIEngine::getCurrentScreen()->getWidget("sfx_volume")
|
||||
GUIEngine::SpinnerWidget* w = dynamic_cast<GUIEngine::SpinnerWidget*>(widget);
|
||||
assert(w != NULL);
|
||||
|
||||
if(sample_sound == NULL)
|
||||
sample_sound = sfx_manager->newSFX( SFXManager::SOUND_SKID );
|
||||
sample_sound->volume(1);
|
||||
|
||||
sfx_manager->setMasterSFXVolume( w->getValue() );
|
||||
user_config->m_sfx_volume = w->getValue();
|
||||
sfx_manager->setMasterSFXVolume( w->getValue()/10.0f );
|
||||
user_config->m_sfx_volume = w->getValue()/10.0f;
|
||||
// std::cout << "w->getValue()=" << w->getValue() << std::endl;
|
||||
|
||||
// play a sample sound to show the user what this volume is like
|
||||
|
@ -287,42 +287,6 @@ bool CheckBoxWidget::transmitEvent(Widget* w, std::string& originator)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark Gauge Widget
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void GaugeWidget::add()
|
||||
{
|
||||
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
|
||||
IGUIScrollBar* sb = GUIEngine::getGUIEnv()->addScrollBar(true /* horizontal */, widget_size, NULL, ++id_counter);
|
||||
sb->setMax(100);
|
||||
sb->setSmallStep(10);
|
||||
sb->setLargeStep(10);
|
||||
|
||||
m_element = sb;
|
||||
|
||||
id = m_element->getID();
|
||||
m_element->setTabOrder(id);
|
||||
m_element->setTabGroup(false);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
float GaugeWidget::getValue()
|
||||
{
|
||||
IGUIScrollBar* sb = dynamic_cast<IGUIScrollBar*>(m_element);
|
||||
assert(sb != NULL);
|
||||
return (float)sb->getPos() / sb->getMax();
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void GaugeWidget::setValue(const float val)
|
||||
{
|
||||
IGUIScrollBar* sb = dynamic_cast<IGUIScrollBar*>(m_element);
|
||||
assert(sb != NULL);
|
||||
|
||||
sb->setPos( (int)round(sb->getMax()*val) );
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark Icon Button
|
||||
@ -697,6 +661,11 @@ void RibbonWidget::setLabel(const int id, std::string new_name)
|
||||
#pragma mark Spinner
|
||||
#endif
|
||||
|
||||
SpinnerWidget::SpinnerWidget(const bool gauge)
|
||||
{
|
||||
m_gauge = gauge;
|
||||
}
|
||||
|
||||
void SpinnerWidget::add()
|
||||
{
|
||||
// retrieve min and max values
|
||||
|
@ -17,7 +17,6 @@ namespace GUIEngine
|
||||
WTYPE_RIBBON,
|
||||
WTYPE_SPINNER,
|
||||
WTYPE_BUTTON,
|
||||
WTYPE_GAUGE,
|
||||
WTYPE_ICON_BUTTON,
|
||||
WTYPE_CHECKBOX,
|
||||
WTYPE_LABEL,
|
||||
@ -174,30 +173,29 @@ namespace GUIEngine
|
||||
void setState(const bool enabled) { m_state = enabled; }
|
||||
};
|
||||
|
||||
|
||||
class GaugeWidget : public Widget
|
||||
{
|
||||
void add();
|
||||
public:
|
||||
virtual ~GaugeWidget() {}
|
||||
float getValue();
|
||||
void setValue(const float value);
|
||||
};
|
||||
|
||||
class SpinnerWidget : public Widget
|
||||
{
|
||||
int m_value, m_min, m_max;
|
||||
std::vector<std::string> m_labels;
|
||||
bool m_graphical;
|
||||
bool m_gauge;
|
||||
|
||||
bool transmitEvent(Widget* w, std::string& originator);
|
||||
bool rightPressed();
|
||||
bool leftPressed();
|
||||
void add();
|
||||
public:
|
||||
|
||||
SpinnerWidget(const bool gauge=false);
|
||||
virtual ~SpinnerWidget() {}
|
||||
void setValue(const int new_value);
|
||||
void addLabel(std::string label);
|
||||
|
||||
bool isGauge() const { return m_gauge; }
|
||||
int getValue() const { return m_value; }
|
||||
int getMax() const { return m_max; }
|
||||
int getMin() const { return m_min; }
|
||||
};
|
||||
|
||||
class IconButtonWidget : public Widget
|
||||
|
Loading…
Reference in New Issue
Block a user