From 911f98fccac7611d9c21ef97122c1b8b5f1ec728 Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 4 May 2009 01:15:12 +0000 Subject: [PATCH] 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 --- data/gui/options_av.stkgui | 4 +- src/gui/engine.hpp | 6 +-- src/gui/screen_loader.cpp | 6 ++- src/gui/skin.cpp | 93 +++++++++++++------------------------- src/gui/skin.hpp | 4 -- src/gui/state_manager.cpp | 34 +++++++++----- src/gui/widget.cpp | 41 ++--------------- src/gui/widget.hpp | 18 ++++---- 8 files changed, 75 insertions(+), 131 deletions(-) diff --git a/data/gui/options_av.stkgui b/data/gui/options_av.stkgui index 0f255dc06..446986632 100644 --- a/data/gui/options_av.stkgui +++ b/data/gui/options_av.stkgui @@ -21,7 +21,7 @@
- +
@@ -34,7 +34,7 @@
- +
diff --git a/src/gui/engine.hpp b/src/gui/engine.hpp index e27e019fc..8a5a2b98e 100644 --- a/src/gui/engine.hpp +++ b/src/gui/engine.hpp @@ -19,19 +19,17 @@ Ribbon widgets are of spawn type ( ... ) 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. diff --git a/src/gui/screen_loader.cpp b/src/gui/screen_loader.cpp index a123a74ac..ee4941106 100644 --- a/src/gui/screen_loader.cpp +++ b/src/gui/screen_loader.cpp @@ -72,8 +72,10 @@ void parseScreenFileDiv(irr::io::IrrXMLReader* xml, ptr_vector& 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())) { diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp index 9162d3ca8..d10fad473 100644 --- a/src/gui/skin.cpp +++ b/src/gui/skin.cpp @@ -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(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(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(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); diff --git a/src/gui/skin.hpp b/src/gui/skin.hpp index 055108779..a5d3f46bf 100644 --- a/src/gui/skin.hpp +++ b/src/gui/skin.hpp @@ -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: diff --git a/src/gui/state_manager.cpp b/src/gui/state_manager.cpp index 7dee5a0d1..ec863e80a 100644 --- a/src/gui/state_manager.cpp +++ b/src/gui/state_manager.cpp @@ -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::getCurrentScreen()->getWidget("sfx_volume")); + // ---- sfx volume + GUIEngine::SpinnerWidget* gauge = dynamic_cast + (GUIEngine::getCurrentScreen()->getWidget("sfx_volume")); assert(gauge != NULL); - gauge->setValue( sfx_manager->getMasterSFXVolume() ); + gauge->setValue( sfx_manager->getMasterSFXVolume()*10.0f ); - gauge = dynamic_cast - (GUIEngine::getCurrentScreen()->getWidget("music_volume")); + gauge = dynamic_cast + (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::getCurrentScreen()->getWidget("sfx_enabled")); GUIEngine::CheckBoxWidget* music = dynamic_cast (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::getCurrentScreen()->getWidget("resolutions")); @@ -365,25 +369,31 @@ namespace StateManager } else if(name == "music_volume") { + /* GUIEngine::GaugeWidget* w = dynamic_cast(widget); assert(w != NULL); - + sound_manager->setMasterMusicVolume( w->getValue() ); + */ + + GUIEngine::SpinnerWidget* w = dynamic_cast(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(widget); - // GUIEngine::getCurrentScreen()->getWidget("sfx_volume") + GUIEngine::SpinnerWidget* w = dynamic_cast(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 diff --git a/src/gui/widget.cpp b/src/gui/widget.cpp index db7d4c354..554b737b8 100644 --- a/src/gui/widget.cpp +++ b/src/gui/widget.cpp @@ -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 widget_size = rect(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(m_element); - assert(sb != NULL); - return (float)sb->getPos() / sb->getMax(); -} -// ----------------------------------------------------------------------------- -void GaugeWidget::setValue(const float val) -{ - IGUIScrollBar* sb = dynamic_cast(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 diff --git a/src/gui/widget.hpp b/src/gui/widget.hpp index cf2f5c503..502c07eec 100644 --- a/src/gui/widget.hpp +++ b/src/gui/widget.hpp @@ -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 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