mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-01 03:21:41 +00:00
400 lines
13 KiB
C++
400 lines
13 KiB
C++
/* -------------------------------------------------------
|
||
Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es)
|
||
|
||
Permission is hereby granted, free of charge, to any
|
||
person obtaining a copy of this software and associated
|
||
documentation files (the "Software"), to deal in the
|
||
Software without restriction, including without limitation
|
||
the rights to use, copy, modify, merge, publish,
|
||
distribute, sublicense, and/or sell copies of the
|
||
Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice
|
||
shall be included in all copies or substantial portions of
|
||
the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
------------------------------------------------------- */
|
||
|
||
#include "ICSInputControlSystem.h"
|
||
|
||
namespace ICS
|
||
{
|
||
// load xml
|
||
void InputControlSystem::loadMouseAxisBinders(TiXmlElement* xmlControlNode)
|
||
{
|
||
TiXmlElement* xmlMouseBinder = xmlControlNode->FirstChildElement("MouseBinder");
|
||
while(xmlMouseBinder)
|
||
{
|
||
Control::ControlChangingDirection dir = Control::STOP;
|
||
if(std::string(xmlMouseBinder->Attribute("direction")) == "INCREASE")
|
||
{
|
||
dir = Control::INCREASE;
|
||
}
|
||
else if(std::string(xmlMouseBinder->Attribute("direction")) == "DECREASE")
|
||
{
|
||
dir = Control::DECREASE;
|
||
}
|
||
|
||
NamedAxis axis = /*NamedAxis::*/ X;
|
||
if((*xmlMouseBinder->Attribute("axis")) == 'Y')
|
||
{
|
||
axis = /*NamedAxis::*/ Y;
|
||
}
|
||
else if((*xmlMouseBinder->Attribute("axis")) == 'Z')
|
||
{
|
||
axis = /*NamedAxis::*/ Z;
|
||
}
|
||
|
||
addMouseAxisBinding(mControls.back(), axis, dir);
|
||
|
||
xmlMouseBinder = xmlMouseBinder->NextSiblingElement("MouseBinder");
|
||
}
|
||
}
|
||
|
||
void InputControlSystem::loadMouseButtonBinders(TiXmlElement* xmlControlNode)
|
||
{
|
||
TiXmlElement* xmlMouseButtonBinder = xmlControlNode->FirstChildElement("MouseButtonBinder");
|
||
while(xmlMouseButtonBinder)
|
||
{
|
||
Control::ControlChangingDirection dir = Control::STOP;
|
||
if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "INCREASE")
|
||
{
|
||
dir = Control::INCREASE;
|
||
}
|
||
else if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "DECREASE")
|
||
{
|
||
dir = Control::DECREASE;
|
||
}
|
||
|
||
int button = 0;
|
||
if(std::string(xmlMouseButtonBinder->Attribute("button")) == "LEFT")
|
||
{
|
||
button = SDL_BUTTON_LEFT;
|
||
}
|
||
else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "RIGHT")
|
||
{
|
||
button = SDL_BUTTON_RIGHT;
|
||
}
|
||
else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "MIDDLE")
|
||
{
|
||
button = SDL_BUTTON_MIDDLE;
|
||
}
|
||
else
|
||
{
|
||
button = FromString<int>(xmlMouseButtonBinder->Attribute("button"));
|
||
}
|
||
|
||
addMouseButtonBinding(mControls.back(), button, dir);
|
||
|
||
xmlMouseButtonBinder = xmlMouseButtonBinder->NextSiblingElement("MouseButtonBinder");
|
||
}
|
||
}
|
||
|
||
|
||
// add bindings
|
||
void InputControlSystem::addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction)
|
||
{
|
||
if(axis == /*NamedAxis::*/X)
|
||
{
|
||
mXmouseAxisBinded = true;
|
||
}
|
||
else if(axis == /*NamedAxis::*/Y)
|
||
{
|
||
mYmouseAxisBinded = true;
|
||
}
|
||
|
||
addMouseAxisBinding_(control, axis, direction);
|
||
}
|
||
|
||
/*protected*/ void InputControlSystem::addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction)
|
||
{
|
||
ICS_LOG("\tAdding AxisBinder [axis="
|
||
+ ToString<int>(axis) + ", direction="
|
||
+ ToString<int>(direction) + "]");
|
||
|
||
ControlAxisBinderItem controlAxisBinderItem;
|
||
controlAxisBinderItem.control = control;
|
||
controlAxisBinderItem.direction = direction;
|
||
mControlsMouseAxisBinderMap[ axis ] = controlAxisBinderItem;
|
||
}
|
||
|
||
void InputControlSystem::addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction)
|
||
{
|
||
ICS_LOG("\tAdding MouseButtonBinder [button="
|
||
+ ToString<int>(button) + ", direction="
|
||
+ ToString<int>(direction) + "]");
|
||
|
||
ControlButtonBinderItem controlMouseButtonBinderItem;
|
||
controlMouseButtonBinderItem.direction = direction;
|
||
controlMouseButtonBinderItem.control = control;
|
||
mControlsMouseButtonBinderMap[ button ] = controlMouseButtonBinderItem;
|
||
}
|
||
|
||
bool InputControlSystem::isMouseButtonBound(unsigned int button) const
|
||
{
|
||
return mControlsMouseButtonBinderMap.find(button) != mControlsMouseButtonBinderMap.end();
|
||
}
|
||
|
||
// get bindings
|
||
InputControlSystem::NamedAxis InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction)
|
||
{
|
||
ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin();
|
||
while(it != mControlsMouseAxisBinderMap.end())
|
||
{
|
||
if(it->first < 0 && it->second.control == control && it->second.direction == direction)
|
||
{
|
||
return (InputControlSystem::NamedAxis)(it->first);
|
||
}
|
||
++it;
|
||
}
|
||
|
||
return /*NamedAxis::*/UNASSIGNED;
|
||
}
|
||
|
||
//int InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction)
|
||
//{
|
||
// ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin();
|
||
// while(it != mControlsMouseAxisBinderMap.end())
|
||
// {
|
||
// if(it->first >= 0 && it->second.control == control && it->second.direction == direction)
|
||
// {
|
||
// return it->first;
|
||
// }
|
||
// it++;
|
||
// }
|
||
|
||
// return /*NamedAxis::*/UNASSIGNED;
|
||
//}
|
||
|
||
unsigned int InputControlSystem::getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction)
|
||
{
|
||
ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.begin();
|
||
while(it != mControlsMouseButtonBinderMap.end())
|
||
{
|
||
if(it->second.control == control && it->second.direction == direction)
|
||
{
|
||
return it->first;
|
||
}
|
||
++it;
|
||
}
|
||
|
||
return ICS_MAX_DEVICE_BUTTONS;
|
||
}
|
||
|
||
// remove bindings
|
||
void InputControlSystem::removeMouseAxisBinding(NamedAxis axis)
|
||
{
|
||
if(axis == /*NamedAxis::*/X)
|
||
{
|
||
mXmouseAxisBinded = false;
|
||
}
|
||
else if(axis == /*NamedAxis::*/Y)
|
||
{
|
||
mYmouseAxisBinded = false;
|
||
}
|
||
|
||
removeMouseAxisBinding_(axis);
|
||
}
|
||
/*protected*/ void InputControlSystem::removeMouseAxisBinding_(int axis)
|
||
{
|
||
ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.find(axis);
|
||
if(it != mControlsMouseAxisBinderMap.end())
|
||
{
|
||
mControlsMouseAxisBinderMap.erase(it);
|
||
}
|
||
}
|
||
|
||
|
||
void InputControlSystem::removeMouseButtonBinding(unsigned int button)
|
||
{
|
||
ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.find(button);
|
||
if(it != mControlsMouseButtonBinderMap.end())
|
||
{
|
||
mControlsMouseButtonBinderMap.erase(it);
|
||
}
|
||
}
|
||
|
||
// mouse Listeners
|
||
void InputControlSystem::mouseMoved(const SFO::MouseMotionEvent& evt)
|
||
{
|
||
if(mActive)
|
||
{
|
||
if(!mDetectingBindingControl)
|
||
{
|
||
if(mXmouseAxisBinded && evt.xrel)
|
||
{
|
||
ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/X ];
|
||
Control* ctrl = mouseBinderItem.control;
|
||
ctrl->setIgnoreAutoReverse(true);
|
||
if(mouseBinderItem.direction == Control::INCREASE)
|
||
{
|
||
ctrl->setValue( float( (evt.x) / float(mClientWidth) ) );
|
||
}
|
||
else if(mouseBinderItem.direction == Control::DECREASE)
|
||
{
|
||
ctrl->setValue( 1 - float( evt.x / float(mClientWidth) ) );
|
||
}
|
||
}
|
||
|
||
if(mYmouseAxisBinded && evt.yrel)
|
||
{
|
||
ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/Y ];
|
||
Control* ctrl = mouseBinderItem.control;
|
||
ctrl->setIgnoreAutoReverse(true);
|
||
if(mouseBinderItem.direction == Control::INCREASE)
|
||
{
|
||
ctrl->setValue( float( (evt.y) / float(mClientHeight) ) );
|
||
}
|
||
else if(mouseBinderItem.direction == Control::DECREASE)
|
||
{
|
||
ctrl->setValue( 1 - float( evt.y / float(mClientHeight) ) );
|
||
}
|
||
}
|
||
|
||
//! @todo Whats the range of the Z axis?
|
||
/*if(evt.state.Z.rel)
|
||
{
|
||
ControlAxisBinderItem mouseBinderItem = mControlsAxisBinderMap[ NamedAxis::Z ];
|
||
Control* ctrl = mouseBinderItem.control;
|
||
ctrl->setIgnoreAutoReverse(true);
|
||
if(mouseBinderItem.direction == Control::INCREASE)
|
||
{
|
||
ctrl->setValue( float( (evt.state.Z.abs) / float(evt.state.<2E>width?) ) );
|
||
}
|
||
else if(mouseBinderItem.direction == Control::DECREASE)
|
||
{
|
||
ctrl->setValue( float( (1 - evt.state.Z.abs) / float(evt.state.<2E>width?) ) );
|
||
}
|
||
}*/
|
||
}
|
||
else if(mDetectingBindingListener)
|
||
{
|
||
if(mDetectingBindingControl->isAxisBindable())
|
||
{
|
||
if(mMouseAxisBindingInitialValues[0] == ICS_MOUSE_AXIS_BINDING_NULL_VALUE)
|
||
{
|
||
mMouseAxisBindingInitialValues[0] = 0;
|
||
mMouseAxisBindingInitialValues[1] = 0;
|
||
mMouseAxisBindingInitialValues[2] = 0;
|
||
}
|
||
|
||
mMouseAxisBindingInitialValues[0] += evt.xrel;
|
||
mMouseAxisBindingInitialValues[1] += evt.yrel;
|
||
mMouseAxisBindingInitialValues[2] += evt.zrel;
|
||
|
||
if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN )
|
||
{
|
||
mDetectingBindingListener->mouseAxisBindingDetected(this,
|
||
mDetectingBindingControl, X, mDetectingBindingDirection);
|
||
}
|
||
else if( abs(mMouseAxisBindingInitialValues[1]) > ICS_MOUSE_BINDING_MARGIN )
|
||
{
|
||
mDetectingBindingListener->mouseAxisBindingDetected(this,
|
||
mDetectingBindingControl, Y, mDetectingBindingDirection);
|
||
}
|
||
else if( abs(mMouseAxisBindingInitialValues[2]) > ICS_MOUSE_BINDING_MARGIN )
|
||
{
|
||
mDetectingBindingListener->mouseAxisBindingDetected(this,
|
||
mDetectingBindingControl, Z, mDetectingBindingDirection);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void InputControlSystem::mousePressed(const SDL_MouseButtonEvent &evt, Uint8 btn)
|
||
{
|
||
if(mActive)
|
||
{
|
||
if(!mDetectingBindingControl)
|
||
{
|
||
ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn);
|
||
if(it != mControlsMouseButtonBinderMap.end())
|
||
{
|
||
it->second.control->setIgnoreAutoReverse(false);
|
||
if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop())
|
||
{
|
||
it->second.control->setChangingDirection(it->second.direction);
|
||
}
|
||
else
|
||
{
|
||
if(it->second.control->getValue() == 1)
|
||
{
|
||
it->second.control->setChangingDirection(Control::DECREASE);
|
||
}
|
||
else if(it->second.control->getValue() == 0)
|
||
{
|
||
it->second.control->setChangingDirection(Control::INCREASE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void InputControlSystem::mouseReleased(const SDL_MouseButtonEvent &evt, Uint8 btn)
|
||
{
|
||
if(mActive)
|
||
{
|
||
if (!mDetectingBindingControl)
|
||
{
|
||
ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn);
|
||
if(it != mControlsMouseButtonBinderMap.end())
|
||
{
|
||
it->second.control->setChangingDirection(Control::STOP);
|
||
}
|
||
}
|
||
else if(mDetectingBindingListener)
|
||
{
|
||
mDetectingBindingListener->mouseButtonBindingDetected(this,
|
||
mDetectingBindingControl, btn, mDetectingBindingDirection);
|
||
}
|
||
}
|
||
}
|
||
|
||
// mouse auto bindings
|
||
void DetectingBindingListener::mouseAxisBindingDetected(InputControlSystem* ICS, Control* control
|
||
, InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction)
|
||
{
|
||
// if the mouse axis is used by another control, remove it
|
||
ICS->removeMouseAxisBinding(axis);
|
||
|
||
// if the control has an axis assigned, remove it
|
||
InputControlSystem::NamedAxis oldAxis = ICS->getMouseAxisBinding(control, direction);
|
||
if(oldAxis != InputControlSystem::UNASSIGNED)
|
||
{
|
||
ICS->removeMouseAxisBinding(oldAxis);
|
||
}
|
||
|
||
ICS->addMouseAxisBinding(control, axis, direction);
|
||
ICS->cancelDetectingBindingState();
|
||
}
|
||
|
||
void DetectingBindingListener::mouseButtonBindingDetected(InputControlSystem* ICS, Control* control
|
||
, unsigned int button, Control::ControlChangingDirection direction)
|
||
{
|
||
// if the mouse button is used by another control, remove it
|
||
ICS->removeMouseButtonBinding(button);
|
||
|
||
// if the control has a mouse button assigned, remove it
|
||
unsigned int oldButton = ICS->getMouseButtonBinding(control, direction);
|
||
if(oldButton != ICS_MAX_DEVICE_BUTTONS)
|
||
{
|
||
ICS->removeMouseButtonBinding(oldButton);
|
||
}
|
||
|
||
ICS->addMouseButtonBinding(control, button, direction);
|
||
ICS->cancelDetectingBindingState();
|
||
}
|
||
|
||
}
|