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:
parent
68bc6a7e65
commit
1b3ea64041
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 |
@ -16,97 +16,21 @@
|
|||||||
|
|
||||||
<box proportion="1" width="100%" layout="vertical-row">
|
<box proportion="1" width="100%" layout="vertical-row">
|
||||||
|
|
||||||
<scrollable_ribbon id="devices" proportion="3" label_location="each" width="100%"
|
<spacer width="5" height="5"/>
|
||||||
square_items="false" align="center" child_width="256" child_height="128" />
|
|
||||||
|
|
||||||
|
<label width="100%"
|
||||||
|
I18N="In key bindings configuration menu"
|
||||||
|
text="Press enter or double-click on a device to configure it"
|
||||||
|
text_align="center" />
|
||||||
|
|
||||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
<spacer width="5" height="20"/>
|
||||||
<label proportion="2" height="100%" I18N="Key binding" text="Accelerate" text_align="right"/>
|
<list id="devices" proportion="5" width="75%" align="center"/>
|
||||||
<spacer proportion="1" height="100%" />
|
<spacer width="50" height="25" />
|
||||||
<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"/>
|
|
||||||
|
|
||||||
|
<button id="add_device" I18N="In the input configuration screen" text="Add a device"/>
|
||||||
<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="50" height="10" />
|
|
||||||
|
|
||||||
<button id="add_device" proportion="1" 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."
|
<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>
|
</box>
|
||||||
|
|
||||||
<spacer width="50" height="40" />
|
<spacer width="50" height="40" />
|
||||||
|
@ -296,6 +296,8 @@ supertuxkart_SOURCES = \
|
|||||||
states_screens/options_screen_av.hpp \
|
states_screens/options_screen_av.hpp \
|
||||||
states_screens/options_screen_input.cpp \
|
states_screens/options_screen_input.cpp \
|
||||||
states_screens/options_screen_input.hpp \
|
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.cpp \
|
||||||
states_screens/options_screen_players.hpp \
|
states_screens/options_screen_players.hpp \
|
||||||
states_screens/race_gui.cpp \
|
states_screens/race_gui.cpp \
|
||||||
|
@ -199,10 +199,10 @@ void KeyboardConfig::setDefaultBinds()
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
KeyboardConfig::KeyboardConfig()
|
KeyboardConfig::KeyboardConfig() : DeviceConfig(DEVICE_CONFIG_TYPE_KEYBOARD)
|
||||||
{
|
{
|
||||||
m_name = "Keyboard";
|
m_name = "Keyboard";
|
||||||
setInUse(true);
|
setPlugged(true);
|
||||||
setDefaultBinds();
|
setDefaultBinds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,18 +234,18 @@ void GamepadConfig::setDefaultBinds ()
|
|||||||
|
|
||||||
GamepadConfig::GamepadConfig ( const std::string name,
|
GamepadConfig::GamepadConfig ( const std::string name,
|
||||||
const int axis_count,
|
const int axis_count,
|
||||||
const int btnCount )
|
const int btnCount ) : DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_axis_count = axis_count;
|
m_axis_count = axis_count;
|
||||||
m_button_count = btnCount;
|
m_button_count = btnCount;
|
||||||
setInUse(false);
|
setPlugged(false);
|
||||||
setDefaultBinds();
|
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");
|
const char* name_string = xml->getAttributeValue("name");
|
||||||
if(name_string == NULL)
|
if(name_string == NULL)
|
||||||
@ -256,7 +256,7 @@ GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml)
|
|||||||
{
|
{
|
||||||
m_name = name_string;
|
m_name = name_string;
|
||||||
}
|
}
|
||||||
setInUse(false);
|
setPlugged(false);
|
||||||
setDefaultBinds();
|
setDefaultBinds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 =================================================
|
//==== D E V I C E C O N F I G =================================================
|
||||||
|
|
||||||
@ -32,17 +38,25 @@ class DeviceConfig
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
KeyBinding m_bindings[PA_COUNT];
|
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:
|
protected:
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
|
DeviceConfigType m_type;
|
||||||
|
|
||||||
|
DeviceConfig(DeviceConfigType type)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string getName() const { return m_name; };
|
std::string getName () const { return m_name; };
|
||||||
irr::core::stringw getBindingAsString (const PlayerAction action) const;
|
|
||||||
irr::core::stringw toString ();
|
irr::core::stringw toString ();
|
||||||
|
DeviceConfigType getType () const { return m_type; }
|
||||||
|
irr::core::stringw getBindingAsString(const PlayerAction action) const;
|
||||||
|
|
||||||
void serialize (std::ofstream& stream);
|
void serialize (std::ofstream& stream);
|
||||||
bool deserializeAction (irr::io::IrrXMLReader* xml);
|
bool deserializeAction (irr::io::IrrXMLReader* xml);
|
||||||
@ -52,8 +66,8 @@ public:
|
|||||||
const int id,
|
const int id,
|
||||||
Input::AxisDirection direction = Input::AD_NEUTRAL);
|
Input::AxisDirection direction = Input::AD_NEUTRAL);
|
||||||
|
|
||||||
void setInUse (bool inuse) {m_inuse = inuse;}
|
void setPlugged (bool plugged) {m_plugged = plugged;}
|
||||||
bool isInUse () {return m_inuse;}
|
bool isPlugged () {return m_plugged;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't call this directly unless you are KeyboardDevice or GamepadDevice
|
* Don't call this directly unless you are KeyboardDevice or GamepadDevice
|
||||||
|
@ -43,7 +43,7 @@ namespace GUIEngine
|
|||||||
|
|
||||||
/** When inferring widget size from its label length, this method will be called to
|
/** 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 */
|
* 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:
|
public:
|
||||||
ButtonWidget();
|
ButtonWidget();
|
||||||
|
@ -62,6 +62,8 @@ namespace GUIEngine
|
|||||||
* A dynamic ribbon builds upon RibbonWidget, adding dynamic contents creation and sizing,
|
* A dynamic ribbon builds upon RibbonWidget, adding dynamic contents creation and sizing,
|
||||||
* scrolling, multiple-row layouts.
|
* scrolling, multiple-row layouts.
|
||||||
* \ingroup widgets
|
* \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
|
class DynamicRibbonWidget : public Widget, public RibbonWidget::IRibbonListener
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,40 @@ using namespace irr::gui;
|
|||||||
|
|
||||||
ListWidget::ListWidget() : Widget(WTYPE_LIST)
|
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());
|
IGUIListBox* list = GUIEngine::getGUIEnv()->addListBox (widget_size, m_parent, getNewID());
|
||||||
list->setAutoScrollEnabled(false);
|
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;
|
m_element = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,35 +87,52 @@ void ListWidget::clear()
|
|||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
|
|
||||||
list->clear();
|
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>();
|
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
|
|
||||||
if (m_use_icons)
|
if (m_use_icons && icon != -1)
|
||||||
{
|
{
|
||||||
//TODO: allow choosing which icon to use
|
u32 newItem = list->addItem( item.c_str(), icon );
|
||||||
u32 newItem = list->addItem( stringw(item).c_str(), 0 /* icon */ );
|
|
||||||
list->setItemOverrideColor( newItem, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) );
|
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) );
|
list->setItemOverrideColor( newItem, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) );
|
||||||
}
|
}
|
||||||
else
|
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>();
|
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||||
assert(list != NULL);
|
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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -25,15 +25,25 @@
|
|||||||
#include "guiengine/widget.hpp"
|
#include "guiengine/widget.hpp"
|
||||||
#include "utils/ptr_vector.hpp"
|
#include "utils/ptr_vector.hpp"
|
||||||
|
|
||||||
|
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||||
|
|
||||||
namespace GUIEngine
|
namespace GUIEngine
|
||||||
{
|
{
|
||||||
/** \brief A vertical list widget with text entries
|
/** \brief A vertical list widget with text entries
|
||||||
* \ingroup widgets
|
* \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
|
class ListWidget : public Widget
|
||||||
{
|
{
|
||||||
|
/** \brief whether this list has icons */
|
||||||
bool m_use_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:
|
public:
|
||||||
ListWidget();
|
ListWidget();
|
||||||
|
|
||||||
@ -45,26 +55,63 @@ namespace GUIEngine
|
|||||||
/** \brief implement callback from base class GUIEngine::Widget */
|
/** \brief implement callback from base class GUIEngine::Widget */
|
||||||
virtual void unfocused(const int playerID);
|
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
|
// ---- 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();
|
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;
|
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;
|
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
|
* \brief change the selected item
|
||||||
* \param index the index of the element to select within the list, or -1 to select nothing
|
* \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);
|
void setSelectionID(const int index);
|
||||||
};
|
};
|
||||||
|
@ -39,6 +39,8 @@ namespace GUIEngine
|
|||||||
/** \brief A static text/icons/tabs bar widget.
|
/** \brief A static text/icons/tabs bar widget.
|
||||||
* The contents of this ribbon are static.
|
* The contents of this ribbon are static.
|
||||||
* \ingroup widgets
|
* \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
|
class RibbonWidget : public Widget
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
9507E9D20FC1CDCE00BD2B92 /* OpenAL.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FA0FC1B63C00DB481B /* OpenAL.framework */; };
|
9507E9D20FC1CDCE00BD2B92 /* OpenAL.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FA0FC1B63C00DB481B /* OpenAL.framework */; };
|
||||||
9507E9DB0FC1CDD500BD2B92 /* Vorbis.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FB0FC1B63C00DB481B /* Vorbis.framework */; };
|
9507E9DB0FC1CDD500BD2B92 /* Vorbis.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FB0FC1B63C00DB481B /* Vorbis.framework */; };
|
||||||
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */; };
|
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 */; };
|
951B7D19108E52C900BC03AE /* challenges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951B7D18108E52C900BC03AE /* challenges.cpp */; };
|
||||||
951BC65E0FFAF290006B5FF1 /* ipo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951BC65C0FFAF290006B5FF1 /* ipo.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 */; };
|
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; };
|
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; };
|
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; };
|
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; };
|
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; };
|
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; };
|
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 */,
|
9522F1EA107961560067ECF5 /* options_screen_av.hpp */,
|
||||||
9522F1EB107961560067ECF5 /* options_screen_input.cpp */,
|
9522F1EB107961560067ECF5 /* options_screen_input.cpp */,
|
||||||
9522F1EE107961560067ECF5 /* options_screen_input.hpp */,
|
9522F1EE107961560067ECF5 /* options_screen_input.hpp */,
|
||||||
|
950D45CF118E040E006CFC41 /* options_screen_input2.cpp */,
|
||||||
|
950D45D0118E040E006CFC41 /* options_screen_input2.hpp */,
|
||||||
9522F1ED107961560067ECF5 /* options_screen_players.cpp */,
|
9522F1ED107961560067ECF5 /* options_screen_players.cpp */,
|
||||||
9522F1EC107961560067ECF5 /* options_screen_players.hpp */,
|
9522F1EC107961560067ECF5 /* options_screen_players.hpp */,
|
||||||
958330C810122B4A00C5137E /* race_gui.cpp */,
|
958330C810122B4A00C5137E /* race_gui.cpp */,
|
||||||
@ -2537,6 +2542,7 @@
|
|||||||
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */,
|
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */,
|
||||||
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */,
|
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */,
|
||||||
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */,
|
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */,
|
||||||
|
950D45D1118E040E006CFC41 /* options_screen_input2.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ bool DeviceManager::initialize()
|
|||||||
printf("using existing configuration.\n");
|
printf("using existing configuration.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepadConfig->setInUse(true);
|
gamepadConfig->setPlugged(true);
|
||||||
gamepadDevice = new GamePadDevice( id,
|
gamepadDevice = new GamePadDevice( id,
|
||||||
m_irrlicht_gamepads[id].Name.c_str(),
|
m_irrlicht_gamepads[id].Name.c_str(),
|
||||||
m_irrlicht_gamepads[id].Axes,
|
m_irrlicht_gamepads[id].Axes,
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#include "race/history.hpp"
|
#include "race/history.hpp"
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
#include "states_screens/kart_selection.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 "states_screens/state_manager.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
InputManager *input_manager;
|
InputManager *input_manager;
|
||||||
@ -214,7 +214,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
|
|||||||
|
|
||||||
if (type == Input::IT_KEYBOARD)
|
if (type == Input::IT_KEYBOARD)
|
||||||
{
|
{
|
||||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (type == Input::IT_STICKMOTION)
|
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)
|
if (abs(value) > Input::MAX_VALUE/2.0f)
|
||||||
{
|
{
|
||||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||||
return;
|
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 )
|
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 )
|
else if ( abs(value) < Input::MAX_VALUE/8.0f && inverse_id_has_high_value )
|
||||||
{
|
{
|
||||||
m_sensed_input->axisDirection = (axisDirection?0:-1);
|
m_sensed_input->axisDirection = (axisDirection?0:-1);
|
||||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,19 +16,21 @@
|
|||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "states_screens/options_screen_input.hpp"
|
#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_av.hpp"
|
||||||
#include "states_screens/options_screen_players.hpp"
|
#include "states_screens/options_screen_players.hpp"
|
||||||
|
|
||||||
|
#include "graphics/irr_driver.hpp"
|
||||||
|
#include "guiengine/CGUISpriteBank.h"
|
||||||
#include "guiengine/screen.hpp"
|
#include "guiengine/screen.hpp"
|
||||||
#include "guiengine/widget.hpp"
|
#include "guiengine/widget.hpp"
|
||||||
#include "guiengine/widgets/button_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 "guiengine/widgets/ribbon_widget.hpp"
|
||||||
#include "input/input_manager.hpp"
|
#include "input/input_manager.hpp"
|
||||||
#include "input/device_manager.hpp"
|
#include "input/device_manager.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "states_screens/dialogs/add_device_dialog.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 "states_screens/state_manager.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
@ -45,198 +47,35 @@ DEFINE_SCREEN_SINGLETON( OptionsScreenInput );
|
|||||||
|
|
||||||
OptionsScreenInput::OptionsScreenInput() : Screen("options_input.stkgui")
|
OptionsScreenInput::OptionsScreenInput() : Screen("options_input.stkgui")
|
||||||
{
|
{
|
||||||
m_inited = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void OptionsScreenInput::loadedFromFile()
|
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" );
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
|
||||||
|
m_icon_bank->addTextureAsSprite(icon1);
|
||||||
void OptionsScreenInput::updateInputButtons(DeviceConfig* config)
|
m_icon_bank->addTextureAsSprite(icon2);
|
||||||
{
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 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()
|
void OptionsScreenInput::buildDeviceList()
|
||||||
{
|
{
|
||||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
GUIEngine::ListWidget* devices = this->getWidget<GUIEngine::ListWidget>("devices");
|
||||||
assert( devices != NULL );
|
assert( devices != NULL );
|
||||||
|
|
||||||
|
assert( m_icon_bank != NULL );
|
||||||
|
devices->setIcons(m_icon_bank);
|
||||||
|
|
||||||
const int keyboard_config_count = input_manager->getDeviceList()->getKeyboardConfigAmount();
|
const int keyboard_config_count = input_manager->getDeviceList()->getKeyboardConfigAmount();
|
||||||
|
|
||||||
for (int i=0; i<keyboard_config_count; i++)
|
for (int i=0; i<keyboard_config_count; i++)
|
||||||
@ -247,8 +86,9 @@ void OptionsScreenInput::buildDeviceList()
|
|||||||
kbname << "keyboard" << i;
|
kbname << "keyboard" << i;
|
||||||
const std::string internal_name = kbname.str();
|
const std::string internal_name = kbname.str();
|
||||||
|
|
||||||
|
//FIXME: I18N: since irrLicht's list widget has the nasty tendency to put the
|
||||||
devices->addItem(StringUtils::insertValues(_("Keyboard %i"), i), internal_name, "/gui/keyboard.png");
|
// 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();
|
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++)
|
for (int i = 0; i < gpad_config_count; i++)
|
||||||
{
|
{
|
||||||
GamepadConfig *config = input_manager->getDeviceList()->getGamepadConfig(i);
|
GamepadConfig *config = input_manager->getDeviceList()->getGamepadConfig(i);
|
||||||
|
|
||||||
// Don't display the configuration if a matching device is not available
|
// 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;
|
std::ostringstream gpname;
|
||||||
gpname << "gamepad" << i;
|
gpname << "gamepad" << i;
|
||||||
const std::string internal_name = gpname.str();
|
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");
|
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
|
||||||
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
|
/*
|
||||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||||
assert( devices != NULL );
|
assert( devices != NULL );
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
if (!m_inited)
|
|
||||||
{
|
|
||||||
buildDeviceList();
|
buildDeviceList();
|
||||||
m_inited = true;
|
|
||||||
}
|
|
||||||
devices->updateItemDisplay();
|
|
||||||
|
|
||||||
|
//devices->updateItemDisplay();
|
||||||
|
|
||||||
|
/*
|
||||||
// trigger displaying bindings for default selected device
|
// trigger displaying bindings for default selected device
|
||||||
const std::string name2("devices");
|
const std::string name2("devices");
|
||||||
eventCallback(devices, name2, PLAYER_ID_GAME_MASTER);
|
eventCallback(devices, name2, PLAYER_ID_GAME_MASTER);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void OptionsScreenInput::rebuildDeviceList()
|
void OptionsScreenInput::rebuildDeviceList()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||||
assert( devices != NULL );
|
assert( devices != NULL );
|
||||||
|
|
||||||
devices->clearItems();
|
devices->clearItems();
|
||||||
buildDeviceList();
|
buildDeviceList();
|
||||||
devices->updateItemDisplay();
|
devices->updateItemDisplay();
|
||||||
}
|
*/
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
ListWidget* devices = this->getWidget<ListWidget>("devices");
|
||||||
|
|
||||||
static PlayerAction binding_to_set;
|
|
||||||
static std::string binding_to_set_button;
|
|
||||||
|
|
||||||
void OptionsScreenInput::gotSensedInput(Input* sensedInput)
|
|
||||||
{
|
|
||||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
|
||||||
assert( devices != NULL );
|
assert( devices != NULL );
|
||||||
|
|
||||||
std::string deviceID = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
devices->clear();
|
||||||
|
buildDeviceList();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void OptionsScreenInput::tearDown()
|
void OptionsScreenInput::tearDown()
|
||||||
@ -424,17 +187,19 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
|||||||
}
|
}
|
||||||
else if (name == "devices")
|
else if (name == "devices")
|
||||||
{
|
{
|
||||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
ListWidget* devices = this->getWidget<ListWidget>("devices");
|
||||||
assert(devices != NULL);
|
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)
|
if (selection.find("gamepad") != std::string::npos)
|
||||||
{
|
{
|
||||||
int i = -1, read = 0;
|
int i = -1, read = 0;
|
||||||
read = sscanf( selection.c_str(), "gamepad%i", &i );
|
read = sscanf( selection.c_str(), "gamepad%i", &i );
|
||||||
if (read == 1 && i != -1)
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -447,7 +212,9 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
|||||||
read = sscanf( selection.c_str(), "keyboard%i", &i );
|
read = sscanf( selection.c_str(), "keyboard%i", &i );
|
||||||
if (read == 1 && i != -1)
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -459,76 +226,6 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
|||||||
std::cerr << "Cannot read internal input device ID : " << selection.c_str() << std::endl;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,6 +233,7 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
|||||||
|
|
||||||
void OptionsScreenInput::unloaded()
|
void OptionsScreenInput::unloaded()
|
||||||
{
|
{
|
||||||
m_inited = false;
|
delete m_icon_bank;
|
||||||
|
m_icon_bank = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
namespace GUIEngine { class Widget; }
|
namespace GUIEngine { class Widget; }
|
||||||
class DeviceConfig;
|
class DeviceConfig;
|
||||||
|
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||||
|
|
||||||
|
|
||||||
struct Input;
|
struct Input;
|
||||||
|
|
||||||
@ -37,11 +39,11 @@ class OptionsScreenInput : public GUIEngine::Screen, public GUIEngine::ScreenSin
|
|||||||
{
|
{
|
||||||
OptionsScreenInput();
|
OptionsScreenInput();
|
||||||
|
|
||||||
bool m_inited;
|
|
||||||
|
|
||||||
void updateInputButtons(DeviceConfig* config);
|
void updateInputButtons(DeviceConfig* config);
|
||||||
void buildDeviceList();
|
void buildDeviceList();
|
||||||
|
|
||||||
|
irr::gui::STKModifiedSpriteBank* m_icon_bank;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend class GUIEngine::ScreenSingleton<OptionsScreenInput>;
|
friend class GUIEngine::ScreenSingleton<OptionsScreenInput>;
|
||||||
|
|
||||||
@ -66,11 +68,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void rebuildDeviceList();
|
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
|
#endif
|
||||||
|
420
src/states_screens/options_screen_input2.cpp
Normal file
420
src/states_screens/options_screen_input2.cpp
Normal 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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
73
src/states_screens/options_screen_input2.hpp
Normal file
73
src/states_screens/options_screen_input2.hpp
Normal 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
|
@ -161,7 +161,7 @@ void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name
|
|||||||
ListWidget* players = this->getWidget<ListWidget>("players");
|
ListWidget* players = this->getWidget<ListWidget>("players");
|
||||||
assert(players != NULL);
|
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();
|
const int playerAmount = UserConfigParams::m_all_players.size();
|
||||||
for (int n=0; n<playerAmount; n++)
|
for (int n=0; n<playerAmount; n++)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user