Initial incarnation of the new input configuration menu. More to come

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5349 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2010-05-02 19:39:09 +00:00
parent 68bc6a7e65
commit 1b3ea64041
19 changed files with 721 additions and 499 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -16,97 +16,21 @@
<box proportion="1" width="100%" layout="vertical-row">
<scrollable_ribbon id="devices" proportion="3" label_location="each" width="100%"
square_items="false" align="center" child_width="256" child_height="128" />
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Accelerate" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_up" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Brake" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_down" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Left" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_left" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Right" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_right" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Fire" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_fire" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center" >
<label proportion="2" height="100%" I18N="Key binding" text="Nitro" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_nitro" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Sharp Turn" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_drift" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Rescue" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_rescue" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer height="5" width="10"/>
<div width="85%" proportion="1" layout="horizontal-row" align="center">
<label proportion="2" height="100%" I18N="Key binding" text="Look Back" text_align="right"/>
<spacer proportion="1" height="100%" />
<button id="binding_look_back" proportion="3" height="100%"
I18N="Unbound key binding" text="[none]"/>
<spacer proportion="1" height="100%" />
</div>
<spacer width="5" height="5"/>
<label width="100%"
I18N="In key bindings configuration menu"
text="Press enter or double-click on a device to configure it"
text_align="center" />
<spacer width="50" height="10" />
<spacer width="5" height="20"/>
<list id="devices" proportion="5" width="75%" align="center"/>
<spacer width="50" height="25" />
<button id="add_device" proportion="1" I18N="In the input configuration screen" text="Add a device"/>
<button id="add_device" I18N="In the input configuration screen" text="Add a device"/>
<label text="* Which config to use will be inferred from which 'fire' key is pressed to join the game."
proportion="3" word_wrap="true"/>
proportion="2" word_wrap="true"/>
</box>
<spacer width="50" height="40" />

View File

@ -296,6 +296,8 @@ supertuxkart_SOURCES = \
states_screens/options_screen_av.hpp \
states_screens/options_screen_input.cpp \
states_screens/options_screen_input.hpp \
states_screens/options_screen_input2.cpp \
states_screens/options_screen_input2.hpp \
states_screens/options_screen_players.cpp \
states_screens/options_screen_players.hpp \
states_screens/race_gui.cpp \

View File

@ -199,10 +199,10 @@ void KeyboardConfig::setDefaultBinds()
//------------------------------------------------------------------------------
KeyboardConfig::KeyboardConfig()
KeyboardConfig::KeyboardConfig() : DeviceConfig(DEVICE_CONFIG_TYPE_KEYBOARD)
{
m_name = "Keyboard";
setInUse(true);
setPlugged(true);
setDefaultBinds();
}
@ -234,18 +234,18 @@ void GamepadConfig::setDefaultBinds ()
GamepadConfig::GamepadConfig ( const std::string name,
const int axis_count,
const int btnCount )
const int btnCount ) : DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
{
m_name = name;
m_axis_count = axis_count;
m_button_count = btnCount;
setInUse(false);
setPlugged(false);
setDefaultBinds();
}
//------------------------------------------------------------------------------
GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml)
GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml) : DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
{
const char* name_string = xml->getAttributeValue("name");
if(name_string == NULL)
@ -256,7 +256,7 @@ GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml)
{
m_name = name_string;
}
setInUse(false);
setPlugged(false);
setDefaultBinds();
}

View File

@ -20,6 +20,12 @@ struct KeyBinding
};
enum DeviceConfigType
{
DEVICE_CONFIG_TYPE_GAMEPAD,
DEVICE_CONFIG_TYPE_KEYBOARD
};
//==== D E V I C E C O N F I G =================================================
@ -32,18 +38,26 @@ class DeviceConfig
private:
KeyBinding m_bindings[PA_COUNT];
bool m_inuse; //!< Is there a device connected to the system which uses this config?
bool m_plugged; //!< Is there a device connected to the system which uses this config?
protected:
std::string m_name;
DeviceConfigType m_type;
DeviceConfig(DeviceConfigType type)
{
m_type = type;
}
public:
std::string getName() const { return m_name; };
irr::core::stringw getBindingAsString (const PlayerAction action) const;
irr::core::stringw toString ();
std::string getName () const { return m_name; };
irr::core::stringw toString ();
DeviceConfigType getType () const { return m_type; }
irr::core::stringw getBindingAsString(const PlayerAction action) const;
void serialize (std::ofstream& stream);
bool deserializeAction (irr::io::IrrXMLReader* xml);
@ -52,8 +66,8 @@ public:
const int id,
Input::AxisDirection direction = Input::AD_NEUTRAL);
void setInUse (bool inuse) {m_inuse = inuse;}
bool isInUse () {return m_inuse;}
void setPlugged (bool plugged) {m_plugged = plugged;}
bool isPlugged () {return m_plugged;}
/**
* Don't call this directly unless you are KeyboardDevice or GamepadDevice

View File

@ -43,7 +43,7 @@ namespace GUIEngine
/** 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 16; }
virtual int getHeightNeededAroundLabel() const { return 8; }
public:
ButtonWidget();

View File

@ -62,6 +62,8 @@ namespace GUIEngine
* A dynamic ribbon builds upon RibbonWidget, adding dynamic contents creation and sizing,
* scrolling, multiple-row layouts.
* \ingroup widgets
* \note items you add to a list are kept after the the ribbon was in is removed
* (i.e. you don't need to add items everytime the screen is shown, only upon loading)
*/
class DynamicRibbonWidget : public Widget, public RibbonWidget::IRibbonListener
{

View File

@ -31,7 +31,40 @@ using namespace irr::gui;
ListWidget::ListWidget() : Widget(WTYPE_LIST)
{
m_use_icons = false; //TODO: make configurable if needed
m_use_icons = false;
m_icons = NULL;
}
// -----------------------------------------------------------------------------
void ListWidget::setIcons(STKModifiedSpriteBank* icons)
{
m_use_icons = (icons != NULL);
m_icons = icons;
if (m_use_icons)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
list->setSpriteBank(m_icons);
// determine needed height
int item_height = 0;
const core::array< core::rect<s32> >& rects = m_icons->getPositions();
const int count = rects.size();
for (int n=0; n<count; n++)
{
const int h = rects[n].getHeight();
if (h > item_height) item_height = h;
}
if (item_height > 0)
{
list->setItemHeight( item_height );
}
}
}
// -----------------------------------------------------------------------------
@ -43,19 +76,6 @@ void ListWidget::add()
IGUIListBox* list = GUIEngine::getGUIEnv()->addListBox (widget_size, m_parent, getNewID());
list->setAutoScrollEnabled(false);
if (m_use_icons)
{
//TODO: allow choosing which icons to use
video::ITexture* icon = irr_driver->getTexture( file_manager->getGUIDir() + "/difficulty_medium.png" );
// TODO: delete the bank when done using, it currently leaks
STKModifiedSpriteBank* bank = new STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
bank->setScale(0.5f);
bank->addTextureAsSprite(icon);
list->setSpriteBank(bank);
list->setItemHeight( icon->getSize().Height*0.5f );
}
m_element = list;
}
@ -67,35 +87,52 @@ void ListWidget::clear()
assert(list != NULL);
list->clear();
m_internal_names.clear();
}
// -----------------------------------------------------------------------------
void ListWidget::addItem(const char* item)
void ListWidget::addItem(const stringw item, const int icon)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
if (m_use_icons)
if (m_use_icons && icon != -1)
{
//TODO: allow choosing which icon to use
u32 newItem = list->addItem( stringw(item).c_str(), 0 /* icon */ );
u32 newItem = list->addItem( item.c_str(), icon );
list->setItemOverrideColor( newItem, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) );
list->setItemOverrideColor( newItem, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) );
}
else
{
list->addItem( stringw(item).c_str() );
list->addItem( item.c_str() );
}
}
// -----------------------------------------------------------------------------
std::string ListWidget::getSelectionName() const
void ListWidget::addItem(const std::string internalName, const irr::core::stringw item, const int icon)
{
m_internal_names[item] = internalName;
addItem(item, icon);
}
// -----------------------------------------------------------------------------
std::string ListWidget::getSelectionInternalName()
{
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
return stringc( list->getListItem( list->getSelected() ) ).c_str();
return m_internal_names[ list->getListItem( list->getSelected() ) ];
}
// -----------------------------------------------------------------------------
irr::core::stringw ListWidget::getSelectionLabel() const
{
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
return list->getListItem( list->getSelected() );
}
// -----------------------------------------------------------------------------

View File

@ -25,15 +25,25 @@
#include "guiengine/widget.hpp"
#include "utils/ptr_vector.hpp"
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
namespace GUIEngine
{
/** \brief A vertical list widget with text entries
* \ingroup widgets
* \note items you add to a list are not kept after the the list is in was removed
* (i.e. you need to add items everytime the screen is shown)
*/
class ListWidget : public Widget
{
/** \brief whether this list has icons */
bool m_use_icons;
/** \brief if m_use_icons is true, this will contain the icon bank */
irr::gui::STKModifiedSpriteBank* m_icons;
std::map< irr::core::stringw /*label*/, std::string /* internal name */> m_internal_names;
public:
ListWidget();
@ -45,26 +55,63 @@ namespace GUIEngine
/** \brief implement callback from base class GUIEngine::Widget */
virtual void unfocused(const int playerID);
/** \brief set the icon bank to use for list entries.
* The height of list entries will be ajusted to the size of the highest icon.
* Icons must therefore be at least as high as text.
* \note the list widget does NOT take ownership of the bank, dso you must delete it when
* you're done with it (but do not delete it when the list widget is still active)
* \precondition may only be called after the widget has been added to the screen with add()
*/
void setIcons(irr::gui::STKModifiedSpriteBank* icons);
// ---- contents management
/** \brief add an item to the list */
void addItem(const char* item);
/**
* \brief add an item to the list
* \param item name of the item
* \param icon ID of the icon within the icon bank. Only used if an icon bank was passed.
* \precondition may only be called after the widget has been added to the screen with add()
*/
void addItem(const irr::core::stringw item, const int icon=-1);
/** \brief erases all items in the list */
/**
* \brief add an item to the list
* \param item name of the item
* \param icon ID of the icon within the icon bank. Only used if an icon bank was passed.
* \precondition may only be called after the widget has been added to the screen with add()
*/
void addItem(const std::string internalName, const irr::core::stringw item, const int icon=-1);
/**
* \brief erases all items in the list
* \precondition may only be called after the widget has been added to the screen with add()
*/
void clear();
/** \return the number of items in the list */
/**
* \return the number of items in the list
* \precondition may only be called after the widget has been added to the screen with add()
*/
int getItemCount() const;
/** \return the index of the selected element within the list, or -1 if none */
/**
* \return the index of the selected element within the list, or -1 if none
* \precondition may only be called after the widget has been added to the screen with add()
*/
int getSelectionID() const;
/** \return the text of the selected item */
std::string getSelectionName() const;
/**
* \return the text of the selected item
* \precondition may only be called after the widget has been added to the screen with add()
*/
std::string getSelectionInternalName();
irr::core::stringw getSelectionLabel() const;
/**
* \brief change the selected item
* \param index the index of the element to select within the list, or -1 to select nothing
* \precondition may only be called after the widget has been added to the screen with add()
*/
void setSelectionID(const int index);
};

View File

@ -39,6 +39,8 @@ namespace GUIEngine
/** \brief A static text/icons/tabs bar widget.
* The contents of this ribbon are static.
* \ingroup widgets
* \note items you add to a list are kept after the the ribbon was in is removed
* (i.e. you don't need to add items everytime the screen is shown, only upon loading)
*/
class RibbonWidget : public Widget
{

View File

@ -12,6 +12,7 @@
9507E9D20FC1CDCE00BD2B92 /* OpenAL.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FA0FC1B63C00DB481B /* OpenAL.framework */; };
9507E9DB0FC1CDD500BD2B92 /* Vorbis.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FB0FC1B63C00DB481B /* Vorbis.framework */; };
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */; };
950D45D1118E040E006CFC41 /* options_screen_input2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 950D45CF118E040E006CFC41 /* options_screen_input2.cpp */; };
951B7D19108E52C900BC03AE /* challenges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951B7D18108E52C900BC03AE /* challenges.cpp */; };
951BC65E0FFAF290006B5FF1 /* ipo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951BC65C0FFAF290006B5FF1 /* ipo.cpp */; };
9522F125107948AD0067ECF5 /* main_menu_screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9522F124107948AD0067ECF5 /* main_menu_screen.cpp */; };
@ -309,6 +310,8 @@
9507E9B60FC1CCE900BD2B92 /* stk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = stk.icns; sourceTree = SOURCE_ROOT; };
950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGUISpriteBank.cpp; path = ../../guiengine/CGUISpriteBank.cpp; sourceTree = SOURCE_ROOT; };
950D448B118DEE3C006CFC41 /* CGUISpriteBank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGUISpriteBank.h; path = ../../guiengine/CGUISpriteBank.h; sourceTree = SOURCE_ROOT; };
950D45CF118E040E006CFC41 /* options_screen_input2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = options_screen_input2.cpp; path = ../../states_screens/options_screen_input2.cpp; sourceTree = SOURCE_ROOT; };
950D45D0118E040E006CFC41 /* options_screen_input2.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = options_screen_input2.hpp; path = ../../states_screens/options_screen_input2.hpp; sourceTree = SOURCE_ROOT; };
951B7D17108E52C900BC03AE /* challenges.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = challenges.hpp; path = ../../states_screens/challenges.hpp; sourceTree = SOURCE_ROOT; };
951B7D18108E52C900BC03AE /* challenges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = challenges.cpp; path = ../../states_screens/challenges.cpp; sourceTree = SOURCE_ROOT; };
951BC65C0FFAF290006B5FF1 /* ipo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ipo.cpp; path = ../../animations/ipo.cpp; sourceTree = SOURCE_ROOT; };
@ -1275,6 +1278,8 @@
9522F1EA107961560067ECF5 /* options_screen_av.hpp */,
9522F1EB107961560067ECF5 /* options_screen_input.cpp */,
9522F1EE107961560067ECF5 /* options_screen_input.hpp */,
950D45CF118E040E006CFC41 /* options_screen_input2.cpp */,
950D45D0118E040E006CFC41 /* options_screen_input2.hpp */,
9522F1ED107961560067ECF5 /* options_screen_players.cpp */,
9522F1EC107961560067ECF5 /* options_screen_players.hpp */,
958330C810122B4A00C5137E /* race_gui.cpp */,
@ -2537,6 +2542,7 @@
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */,
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */,
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */,
950D45D1118E040E006CFC41 /* options_screen_input2.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -88,7 +88,7 @@ bool DeviceManager::initialize()
printf("using existing configuration.\n");
}
gamepadConfig->setInUse(true);
gamepadConfig->setPlugged(true);
gamepadDevice = new GamePadDevice( id,
m_irrlicht_gamepads[id].Name.c_str(),
m_irrlicht_gamepads[id].Axes,

View File

@ -43,7 +43,7 @@
#include "race/history.hpp"
#include "race/race_manager.hpp"
#include "states_screens/kart_selection.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_input2.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
InputManager *input_manager;
@ -214,7 +214,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
if (type == Input::IT_KEYBOARD)
{
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
return;
}
else if (type == Input::IT_STICKMOTION)
@ -230,7 +230,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
if (abs(value) > Input::MAX_VALUE/2.0f)
{
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
return;
}
}
@ -249,12 +249,12 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
}
else if ( abs(value) < Input::MAX_VALUE/8.0f && id_has_high_value )
{
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
}
else if ( abs(value) < Input::MAX_VALUE/8.0f && inverse_id_has_high_value )
{
m_sensed_input->axisDirection = (axisDirection?0:-1);
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
}
}
}

View File

@ -16,19 +16,21 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_input2.hpp"
#include "states_screens/options_screen_av.hpp"
#include "states_screens/options_screen_players.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/CGUISpriteBank.h"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "input/input_manager.hpp"
#include "input/device_manager.hpp"
#include "io/file_manager.hpp"
#include "states_screens/dialogs/add_device_dialog.hpp"
#include "states_screens/dialogs/press_a_key_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@ -45,198 +47,35 @@ DEFINE_SCREEN_SINGLETON( OptionsScreenInput );
OptionsScreenInput::OptionsScreenInput() : Screen("options_input.stkgui")
{
m_inited = false;
}
// -----------------------------------------------------------------------------
void OptionsScreenInput::loadedFromFile()
{
m_inited = false;
}
{
video::ITexture* icon1 = irr_driver->getTexture( file_manager->getGUIDir() + "/keyboard.png" );
video::ITexture* icon2 = irr_driver->getTexture( file_manager->getGUIDir() + "/gamepad.png" );
// -----------------------------------------------------------------------------
void OptionsScreenInput::updateInputButtons(DeviceConfig* config)
{
// Should never happen
if (config == NULL)
{
printf("ERROR: No configuration associated with device?\n");
abort();
}
// to detect duplicate entries
std::set<core::stringw> existing_bindings;
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_up");
core::stringw binding_name = config->getBindingAsString(PA_ACCEL);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_down");
core::stringw binding_name = config->getBindingAsString(PA_BRAKE);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_left");
core::stringw binding_name = config->getBindingAsString(PA_LEFT);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_right");
core::stringw binding_name = config->getBindingAsString(PA_RIGHT);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
std::set<core::stringw>::iterator it;
/*
std::cout << "existing_bindings contains:";
for ( it=existing_bindings.begin() ; it != existing_bindings.end(); it++ )
{
std::wcout << (*it).c_str() << ", ";
}
std::cout << "\n";
*/
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_fire");
core::stringw binding_name = config->getBindingAsString(PA_FIRE);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
//std::cout << "Setting bad badge!!!!\n";
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_nitro");
core::stringw binding_name = config->getBindingAsString(PA_NITRO);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_drift");
core::stringw binding_name = config->getBindingAsString(PA_DRIFT);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_rescue");
core::stringw binding_name = config->getBindingAsString(PA_RESCUE);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_look_back");
core::stringw binding_name = config->getBindingAsString(PA_LOOK_BACK);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
m_icon_bank->addTextureAsSprite(icon1);
m_icon_bank->addTextureAsSprite(icon2);
// scale icons depending on screen resolution. the numbers below are a bit arbitrary
const int screen_width = irr_driver->getFrameSize().Width;
const float scale = 0.3f + 0.2f*std::max(0, screen_width - 640)/564.0f;
m_icon_bank->setScale(scale);
}
// -----------------------------------------------------------------------------
void OptionsScreenInput::buildDeviceList()
{
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
GUIEngine::ListWidget* devices = this->getWidget<GUIEngine::ListWidget>("devices");
assert( devices != NULL );
assert( m_icon_bank != NULL );
devices->setIcons(m_icon_bank);
const int keyboard_config_count = input_manager->getDeviceList()->getKeyboardConfigAmount();
for (int i=0; i<keyboard_config_count; i++)
@ -247,8 +86,9 @@ void OptionsScreenInput::buildDeviceList()
kbname << "keyboard" << i;
const std::string internal_name = kbname.str();
devices->addItem(StringUtils::insertValues(_("Keyboard %i"), i), internal_name, "/gui/keyboard.png");
//FIXME: I18N: since irrLicht's list widget has the nasty tendency to put the
// icons very close to the text, I'm adding spaces to compensate...
devices->addItem(internal_name, StringUtils::insertValues(_(" Keyboard %i"), i), 0 /* icon */);
}
const int gpad_config_count = input_manager->getDeviceList()->getGamePadConfigAmount();
@ -256,16 +96,19 @@ void OptionsScreenInput::buildDeviceList()
for (int i = 0; i < gpad_config_count; i++)
{
GamepadConfig *config = input_manager->getDeviceList()->getGamepadConfig(i);
// Don't display the configuration if a matching device is not available
if (config->isInUse())
if (config->isPlugged())
{
const irr::core::stringw name = config->getName().c_str();
//FIXME: since irrLicht's list widget has the nasty tendency to put the
// icons very close to the text, I'm adding spaces to compensate...
const irr::core::stringw name = irr::core::stringw(" ") + config->getName().c_str();
std::ostringstream gpname;
gpname << "gamepad" << i;
const std::string internal_name = gpname.str();
devices->addItem(name, internal_name, "/gui/gamepad.png");
devices->addItem(internal_name, name, 1 /* icon */);
}
}
}
@ -276,124 +119,44 @@ void OptionsScreenInput::init()
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
/*
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
assert( devices != NULL );
*/
if (!m_inited)
{
buildDeviceList();
m_inited = true;
}
devices->updateItemDisplay();
buildDeviceList();
//devices->updateItemDisplay();
/*
// trigger displaying bindings for default selected device
const std::string name2("devices");
eventCallback(devices, name2, PLAYER_ID_GAME_MASTER);
*/
}
// -----------------------------------------------------------------------------
void OptionsScreenInput::rebuildDeviceList()
{
/*
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
assert( devices != NULL );
devices->clearItems();
buildDeviceList();
devices->updateItemDisplay();
}
// -----------------------------------------------------------------------------
static PlayerAction binding_to_set;
static std::string binding_to_set_button;
void OptionsScreenInput::gotSensedInput(Input* sensedInput)
{
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
*/
ListWidget* devices = this->getWidget<ListWidget>("devices");
assert( devices != NULL );
std::string deviceID = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
const bool keyboard = sensedInput->type == Input::IT_KEYBOARD && deviceID.find("keyboard") != std::string::npos;
const bool gamepad = (sensedInput->type == Input::IT_STICKMOTION ||
sensedInput->type == Input::IT_STICKBUTTON) &&
deviceID.find("gamepad") != std::string::npos;
if (!keyboard && !gamepad) return;
if (gamepad)
{
if (sensedInput->type != Input::IT_STICKMOTION &&
sensedInput->type != Input::IT_STICKBUTTON)
{
return; // that kind of input does not interest us
}
}
if (keyboard)
{
if(UserConfigParams::m_verbosity>=5)
std::cout << "% Binding " << KartActionStrings[binding_to_set]
<< " : setting to keyboard key " << sensedInput->btnID << " \n\n";
// extract keyboard ID from name
int configID = -1;
sscanf( devices->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(), "keyboard%i", &configID );
KeyboardConfig* keyboard = input_manager->getDeviceList()->getKeyboardConfig(configID);
keyboard->setBinding(binding_to_set, Input::IT_KEYBOARD, sensedInput->btnID, Input::AD_NEUTRAL);
// refresh display
init();
}
else if (gamepad)
{
if(UserConfigParams::m_verbosity>=5)
std::cout << "% Binding " << KartActionStrings[binding_to_set]
<< " : setting to gamepad #" << sensedInput->deviceID << " : ";
if (sensedInput->type == Input::IT_STICKMOTION)
{
std::cout << "axis " << sensedInput->btnID << " direction " <<
(sensedInput->axisDirection == Input::AD_NEGATIVE ? "-" : "+") << "\n\n";
}
else if (sensedInput->type == Input::IT_STICKBUTTON)
{
std::cout << "button " << sensedInput->btnID << "\n\n";
}
else
{
std::cout << "Sensed unknown gamepad event type??\n";
}
// extract gamepad ID from name
int configID = -1;
sscanf( devices->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(), "gamepad%i", &configID );
GamepadConfig* config = input_manager->getDeviceList()->getGamepadConfig(configID);
config->setBinding(binding_to_set, sensedInput->type, sensedInput->btnID,
(Input::AxisDirection)sensedInput->axisDirection);
// refresh display
init();
}
else
{
return;
}
ModalDialog::dismiss();
input_manager->setMode(InputManager::MENU);
// re-select the previous button
ButtonWidget* btn = this->getWidget<ButtonWidget>(binding_to_set_button.c_str());
if(btn != NULL) btn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
// save new binding to file
input_manager->getDeviceList()->serialize();
devices->clear();
buildDeviceList();
}
// -----------------------------------------------------------------------------
void OptionsScreenInput::tearDown()
@ -424,17 +187,19 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
}
else if (name == "devices")
{
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
ListWidget* devices = this->getWidget<ListWidget>("devices");
assert(devices != NULL);
const std::string& selection = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
const std::string& selection = devices->getSelectionInternalName();
if (selection.find("gamepad") != std::string::npos)
{
int i = -1, read = 0;
read = sscanf( selection.c_str(), "gamepad%i", &i );
if (read == 1 && i != -1)
{
updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) );
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceList()->getGamepadConfig(i) );
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
//updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) );
}
else
{
@ -447,7 +212,9 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
read = sscanf( selection.c_str(), "keyboard%i", &i );
if (read == 1 && i != -1)
{
updateInputButtons( input_manager->getDeviceList()->getKeyboardConfig(i) );
// updateInputButtons( input_manager->getDeviceList()->getKeyboardConfig(i) );
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceList()->getKeyboardConfig(i) );
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
}
else
{
@ -459,83 +226,14 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
std::cerr << "Cannot read internal input device ID : " << selection.c_str() << std::endl;
}
}
else if(name.find("binding_") != std::string::npos)
{
binding_to_set_button = name;
if(name == "binding_up")
{
binding_to_set = PA_ACCEL;
}
else if(name == "binding_down")
{
binding_to_set = PA_BRAKE;
}
else if(name == "binding_left")
{
binding_to_set = PA_LEFT;
}
else if(name == "binding_right")
{
binding_to_set = PA_RIGHT;
}
else if(name == "binding_fire")
{
binding_to_set = PA_FIRE;
}
else if(name == "binding_nitro")
{
binding_to_set = PA_NITRO;
}
else if(name == "binding_drift")
{
binding_to_set = PA_DRIFT;
}
else if(name == "binding_rescue")
{
binding_to_set = PA_RESCUE;
}
else if(name == "binding_look_back")
{
binding_to_set = PA_LOOK_BACK;
}
else
{
std::cerr << "Unknown binding name : " << name.c_str() << std::endl;
return;
}
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
assert( devices != NULL );
if(UserConfigParams::m_verbosity>=5)
std::cout << "\n% Entering sensing mode for "
<< devices->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str()
<< std::endl;
new PressAKeyDialog(0.4f, 0.4f);
std::string selection = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection.find("keyboard") != std::string::npos)
{
input_manager->setMode(InputManager::INPUT_SENSE_KEYBOARD);
}
else if (selection.find("gamepad") != std::string::npos)
{
input_manager->setMode(InputManager::INPUT_SENSE_GAMEPAD);
}
else
{
std::cerr << "unknown selection device in options : " << selection.c_str() << std::endl;
}
}
}
// -----------------------------------------------------------------------------
void OptionsScreenInput::unloaded()
{
m_inited = false;
delete m_icon_bank;
m_icon_bank = NULL;
}

View File

@ -26,6 +26,8 @@
namespace GUIEngine { class Widget; }
class DeviceConfig;
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
struct Input;
@ -36,12 +38,12 @@ struct Input;
class OptionsScreenInput : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<OptionsScreenInput>
{
OptionsScreenInput();
bool m_inited;
void updateInputButtons(DeviceConfig* config);
void buildDeviceList();
irr::gui::STKModifiedSpriteBank* m_icon_bank;
public:
friend class GUIEngine::ScreenSingleton<OptionsScreenInput>;
@ -65,12 +67,7 @@ public:
* This will cause the displayed list to be updated accordingly with the data in the device manager.
*/
void rebuildDeviceList();
/**
* \brief invoke in "input sensing" mode, when input was sensed.
* Updates the input bindings accordingly with the sensed input.
*/
void gotSensedInput(Input* sensedInput);
};
#endif

View File

@ -0,0 +1,420 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_input2.hpp"
#include "states_screens/options_screen_av.hpp"
#include "states_screens/options_screen_players.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/CGUISpriteBank.h"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "input/input_manager.hpp"
#include "input/device_manager.hpp"
#include "io/file_manager.hpp"
#include "states_screens/dialogs/press_a_key_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <iostream>
#include <sstream>
#include <set>
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( OptionsScreenInput2 );
// -----------------------------------------------------------------------------
OptionsScreenInput2::OptionsScreenInput2() : Screen("options_device.stkgui")
{
m_config = NULL;
}
// -----------------------------------------------------------------------------
void OptionsScreenInput2::loadedFromFile()
{
}
// -----------------------------------------------------------------------------
void OptionsScreenInput2::updateInputButtons()
{
assert(m_config != NULL);
// to detect duplicate entries
std::set<core::stringw> existing_bindings;
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_up");
core::stringw binding_name = m_config->getBindingAsString(PA_ACCEL);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_down");
core::stringw binding_name = m_config->getBindingAsString(PA_BRAKE);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_left");
core::stringw binding_name = m_config->getBindingAsString(PA_LEFT);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_right");
core::stringw binding_name = m_config->getBindingAsString(PA_RIGHT);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
std::set<core::stringw>::iterator it;
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_fire");
core::stringw binding_name = m_config->getBindingAsString(PA_FIRE);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
//std::cout << "Setting bad badge!!!!\n";
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_nitro");
core::stringw binding_name = m_config->getBindingAsString(PA_NITRO);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_drift");
core::stringw binding_name = m_config->getBindingAsString(PA_DRIFT);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_rescue");
core::stringw binding_name = m_config->getBindingAsString(PA_RESCUE);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
{
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_look_back");
core::stringw binding_name = m_config->getBindingAsString(PA_LOOK_BACK);
btn->setLabel( binding_name );
// check if another binding already uses this key
if (existing_bindings.find(binding_name) != existing_bindings.end())
{
btn->setBadge(BAD_BADGE);
}
else
{
existing_bindings.insert(binding_name);
btn->resetAllBadges();
}
}
}
// -----------------------------------------------------------------------------
void OptionsScreenInput2::init()
{
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
updateInputButtons();
LabelWidget* label = this->getWidget<LabelWidget>("title");
label->setText( m_config->getName().c_str() );
}
// -----------------------------------------------------------------------------
static PlayerAction binding_to_set;
static std::string binding_to_set_button;
void OptionsScreenInput2::gotSensedInput(Input* sensedInput)
{
const bool keyboard = (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD &&
sensedInput->type == Input::IT_KEYBOARD);
const bool gamepad = (sensedInput->type == Input::IT_STICKMOTION ||
sensedInput->type == Input::IT_STICKBUTTON) &&
m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD;
if (keyboard)
{
if (UserConfigParams::m_verbosity>=5)
{
std::cout << "% Binding " << KartActionStrings[binding_to_set]
<< " : setting to keyboard key " << sensedInput->btnID << " \n\n";
}
KeyboardConfig* keyboard = (KeyboardConfig*)m_config;
keyboard->setBinding(binding_to_set, Input::IT_KEYBOARD, sensedInput->btnID, Input::AD_NEUTRAL);
// refresh display
init();
}
else if (gamepad)
{
if (UserConfigParams::m_verbosity>=5)
{
std::cout << "% Binding " << KartActionStrings[binding_to_set]
<< " : setting to gamepad #" << sensedInput->deviceID << " : ";
if (sensedInput->type == Input::IT_STICKMOTION)
{
std::cout << "axis " << sensedInput->btnID << " direction "
<< (sensedInput->axisDirection == Input::AD_NEGATIVE ? "-" : "+") << "\n\n";
}
else if (sensedInput->type == Input::IT_STICKBUTTON)
{
std::cout << "button " << sensedInput->btnID << "\n\n";
}
else
{
std::cout << "Sensed unknown gamepad event type??\n";
}
}
// extract gamepad ID from name
GamepadConfig* config = (GamepadConfig*)m_config;
config->setBinding(binding_to_set, sensedInput->type, sensedInput->btnID,
(Input::AxisDirection)sensedInput->axisDirection);
// refresh display
init();
}
else
{
return;
}
ModalDialog::dismiss();
input_manager->setMode(InputManager::MENU);
// re-select the previous button
ButtonWidget* btn = this->getWidget<ButtonWidget>(binding_to_set_button.c_str());
if(btn != NULL) btn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
// save new binding to file
input_manager->getDeviceList()->serialize();
}
// -----------------------------------------------------------------------------
void OptionsScreenInput2::tearDown()
{
}
// -----------------------------------------------------------------------------
void OptionsScreenInput2::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
//const std::string& screen_name = this->getName();
if (name == "options_choice")
{
std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str();
if (selection == "tab_audio_video")
{
StateManager::get()->replaceTopMostScreen(OptionsScreenAV::getInstance());
}
else if (selection == "tab_players")
{
StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
}
else if (selection == "tab_controls")
{
}
}
else if (name == "back_to_device_list")
{
StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
}
else if (name == "back")
{
StateManager::get()->escapePressed();
}
else if(name.find("binding_") != std::string::npos)
{
binding_to_set_button = name;
if(name == "binding_up")
{
binding_to_set = PA_ACCEL;
}
else if(name == "binding_down")
{
binding_to_set = PA_BRAKE;
}
else if(name == "binding_left")
{
binding_to_set = PA_LEFT;
}
else if(name == "binding_right")
{
binding_to_set = PA_RIGHT;
}
else if(name == "binding_fire")
{
binding_to_set = PA_FIRE;
}
else if(name == "binding_nitro")
{
binding_to_set = PA_NITRO;
}
else if(name == "binding_drift")
{
binding_to_set = PA_DRIFT;
}
else if(name == "binding_rescue")
{
binding_to_set = PA_RESCUE;
}
else if(name == "binding_look_back")
{
binding_to_set = PA_LOOK_BACK;
}
else
{
std::cerr << "Unknown binding name : " << name.c_str() << std::endl;
return;
}
if (UserConfigParams::m_verbosity>=5)
{
std::cout << "\n% Entering sensing mode for "
<< m_config->getName().c_str()
<< std::endl;
}
new PressAKeyDialog(0.4f, 0.4f);
if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD)
{
input_manager->setMode(InputManager::INPUT_SENSE_KEYBOARD);
}
else if (m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD)
{
input_manager->setMode(InputManager::INPUT_SENSE_GAMEPAD);
}
else
{
std::cerr << "unknown selection device in options : " << m_config->getName().c_str() << std::endl;
}
}
}
// -----------------------------------------------------------------------------
void OptionsScreenInput2::unloaded()
{
}

View File

@ -0,0 +1,73 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __HEADER_OPTIONS_SCREEN_INPUT2_HPP__
#define __HEADER_OPTIONS_SCREEN_INPUT2_HPP__
#include <string>
#include "irrlicht.h"
#include "guiengine/screen.hpp"
namespace GUIEngine { class Widget; }
class DeviceConfig;
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
struct Input;
/**
* \brief Input options screen
* \ingroup states_screens
*/
class OptionsScreenInput2 : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<OptionsScreenInput2>
{
OptionsScreenInput2();
void updateInputButtons();
DeviceConfig* m_config;
public:
friend class GUIEngine::ScreenSingleton<OptionsScreenInput2>;
void setDevice(DeviceConfig* config) { m_config = config; }
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID);
/** \brief implement optional callback from parent class GUIEngine::Screen */
virtual void unloaded();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown();
/**
* \brief invoke in "input sensing" mode, when input was sensed.
* Updates the input bindings accordingly with the sensed input.
*/
void gotSensedInput(Input* sensedInput);
};
#endif

View File

@ -161,7 +161,7 @@ void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name
ListWidget* players = this->getWidget<ListWidget>("players");
assert(players != NULL);
std::string selectedPlayer = players->getSelectionName();
std::string selectedPlayer = stringc( players->getSelectionLabel().c_str() ).c_str();
const int playerAmount = UserConfigParams::m_all_players.size();
for (int n=0; n<playerAmount; n++)
{