|
|
@@ -36,7 +36,6 @@
|
|
|
#include "StringUtils.h"
|
|
|
#include "Text.h"
|
|
|
#include "UI.h"
|
|
|
-#include "UIEvents.h"
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
@@ -54,8 +53,8 @@ namespace Urho3D
|
|
|
{
|
|
|
|
|
|
const int SCREEN_JOYSTICK_START_INDEX = 1000;
|
|
|
-const ShortStringHash VAR_INJECT_AS_KEY_EVENTS("VAR_INJECT_AS_KEY_EVENTS");
|
|
|
const ShortStringHash VAR_BUTTON_KEY_BINDING("VAR_BUTTON_KEY_BINDING");
|
|
|
+const ShortStringHash VAR_LAST_KEYSYM("VAR_LAST_KEYSYM");
|
|
|
const ShortStringHash VAR_SCREEN_JOYSTICK_INDEX("VAR_SCREEN_JOYSTICK_INDEX");
|
|
|
|
|
|
/// Convert SDL keycode if necessary.
|
|
|
@@ -67,12 +66,6 @@ int ConvertSDLKeyCode(int keySym, int scanCode)
|
|
|
return SDL_toupper(keySym);
|
|
|
}
|
|
|
|
|
|
-JoystickState::~JoystickState()
|
|
|
-{
|
|
|
- if (screenJoystick_)
|
|
|
- screenJoystick_->Remove();
|
|
|
-}
|
|
|
-
|
|
|
Input::Input(Context* context) :
|
|
|
Object(context),
|
|
|
mouseButtonDown_(0),
|
|
|
@@ -244,8 +237,10 @@ bool Input::DetectJoysticks()
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-unsigned Input::AddScreenJoystick(bool injectAsKeyEvents, XMLFile* layoutFile, XMLFile* styleFile)
|
|
|
+unsigned Input::AddScreenJoystick(XMLFile* layoutFile, XMLFile* styleFile)
|
|
|
{
|
|
|
+ static HashMap<String, int> keyBindings;
|
|
|
+
|
|
|
if (!graphics_)
|
|
|
{
|
|
|
LOGWARNING("Cannot add screen joystick in headless mode");
|
|
|
@@ -267,9 +262,9 @@ unsigned Input::AddScreenJoystick(bool injectAsKeyEvents, XMLFile* layoutFile, X
|
|
|
return M_MAX_UNSIGNED;
|
|
|
|
|
|
screenJoystick->SetSize(ui->GetRoot()->GetSize());
|
|
|
- screenJoystick->SetVisible(false); // Set to visible when it is "open" later
|
|
|
- screenJoystick->SetVar(VAR_INJECT_AS_KEY_EVENTS, injectAsKeyEvents);
|
|
|
+ screenJoystick->SetVisible(false); // Set to visible when it is opened later
|
|
|
ui->GetRoot()->AddChild(screenJoystick);
|
|
|
+
|
|
|
unsigned index = joysticks_.Size();
|
|
|
joysticks_.Resize(index + 1);
|
|
|
JoystickState& state = joysticks_[index];
|
|
|
@@ -290,64 +285,134 @@ unsigned Input::AddScreenJoystick(bool injectAsKeyEvents, XMLFile* layoutFile, X
|
|
|
++numButtons;
|
|
|
|
|
|
// Check whether the button has key binding
|
|
|
- if (injectAsKeyEvents)
|
|
|
+ Text* text = dynamic_cast<Text*>(element->GetChild("KeyBinding", false));
|
|
|
+ if (text)
|
|
|
{
|
|
|
- Text* text = dynamic_cast<Text*>(element->GetChild("KeyBinding", false));
|
|
|
- if (text)
|
|
|
+ text->SetVisible(false);
|
|
|
+ const String& key = text->GetText();
|
|
|
+ int keyBinding;
|
|
|
+ if (key.Length() == 1)
|
|
|
+ keyBinding = key[0];
|
|
|
+ else
|
|
|
{
|
|
|
- text->SetVisible(false);
|
|
|
- const String& key = text->GetText();
|
|
|
- if (key.Length() == 1)
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, key);
|
|
|
- else if (key == "SPACE")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_SPACE);
|
|
|
- else if (key == "LCTRL")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_LCTRL);
|
|
|
- else if (key == "RCTRL")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_RCTRL);
|
|
|
- else if (key == "LSHIFT")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_LSHIFT);
|
|
|
- else if (key == "RSHIFT")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_RSHIFT);
|
|
|
- else if (key == "LALT")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_LALT);
|
|
|
- else if (key == "RALT")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_RALT);
|
|
|
- else if (key == "TAB")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_TAB);
|
|
|
- else if (key == "RETURN")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_RETURN);
|
|
|
- else if (key == "LEFT")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_LEFT);
|
|
|
- else if (key == "RIGHT")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_RIGHT);
|
|
|
- else if (key == "UP")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_UP);
|
|
|
- else if (key == "DOWN")
|
|
|
- element->SetVar(VAR_BUTTON_KEY_BINDING, KEY_DOWN);
|
|
|
+ if (keyBindings.Empty())
|
|
|
+ {
|
|
|
+ keyBindings.Insert(MakePair<String, int>("SPACE", KEY_SPACE));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("LCTRL", KEY_LCTRL));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RCTRL", KEY_RCTRL));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("LSHIFT", KEY_LSHIFT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RSHIFT", KEY_RSHIFT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("LALT", KEY_LALT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RALT", KEY_RALT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("LGUI", KEY_LGUI));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RGUI", KEY_RGUI));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("TAB", KEY_TAB));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RETURN", KEY_RETURN));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RETURN2", KEY_RETURN2));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("ENTER", KEY_KP_ENTER));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("SELECT", KEY_SELECT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("LEFT", KEY_LEFT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("RIGHT", KEY_RIGHT));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("UP", KEY_UP));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("DOWN", KEY_DOWN));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F1", KEY_F1));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F2", KEY_F2));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F3", KEY_F3));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F4", KEY_F4));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F5", KEY_F5));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F6", KEY_F6));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F7", KEY_F7));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F8", KEY_F8));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F9", KEY_F9));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F10", KEY_F10));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F11", KEY_F11));
|
|
|
+ keyBindings.Insert(MakePair<String, int>("F12", KEY_F12));
|
|
|
+ }
|
|
|
+
|
|
|
+ HashMap<String, int>::Iterator i = keyBindings.Find(key);
|
|
|
+ if (i != keyBindings.End())
|
|
|
+ keyBinding = i->second_;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LOGERRORF("Unsupported key binding: %s", key.CString());
|
|
|
+ keyBinding = M_MAX_INT;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ if (keyBinding != M_MAX_INT)
|
|
|
+ element->SetVar(VAR_BUTTON_KEY_BINDING, keyBinding);
|
|
|
}
|
|
|
}
|
|
|
else if (name.StartsWith("Axis"))
|
|
|
+ {
|
|
|
++numAxes;
|
|
|
+
|
|
|
+ ///\todo Axis emulation for screen joystick is not fully supported yet.
|
|
|
+ LOGWARNING("Axis emulation for screen joystick is not fully supported yet");
|
|
|
+ }
|
|
|
else if (name.StartsWith("Hat"))
|
|
|
+ {
|
|
|
++numHats;
|
|
|
+
|
|
|
+ Text* text = dynamic_cast<Text*>(element->GetChild("KeyBinding", false));
|
|
|
+ if (text)
|
|
|
+ {
|
|
|
+ text->SetVisible(false);
|
|
|
+ String keyBinding = text->GetText();
|
|
|
+ if (keyBinding.Length() != 4)
|
|
|
+ {
|
|
|
+ LOGERRORF("%s has invalid key binding %s, fallback to WASD", name.CString(), keyBinding.CString());
|
|
|
+ keyBinding = "WASD";
|
|
|
+ }
|
|
|
+
|
|
|
+ element->SetVar(VAR_BUTTON_KEY_BINDING, keyBinding);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
element->SetVar(VAR_SCREEN_JOYSTICK_INDEX, index);
|
|
|
}
|
|
|
|
|
|
+ // Make sure all the children are non-focusable so they do not mistakenly to be considered as active UI input controls by application
|
|
|
+ PODVector<UIElement*> allChildren;
|
|
|
+ state.screenJoystick_->GetChildren(allChildren, true);
|
|
|
+ for (PODVector<UIElement*>::Iterator iter = allChildren.Begin(); iter != allChildren.End(); ++iter)
|
|
|
+ (*iter)->SetFocusMode(FM_NOTFOCUSABLE);
|
|
|
+
|
|
|
state.buttons_.Resize(numButtons);
|
|
|
state.buttonPress_.Resize(numButtons);
|
|
|
state.axes_.Resize(numAxes);
|
|
|
state.hats_.Resize(numHats);
|
|
|
|
|
|
- // There could be potentially more than one screen joystick, however they all will be handled by a same handler
|
|
|
+ // There could be potentially more than one screen joystick, however they all will be handled by a same handler method
|
|
|
// So there is no harm to replace the old handler with the new handler in each call to SubscribeToEvent()
|
|
|
- SubscribeToEvent(E_UIMOUSECLICK, HANDLER(Input, HandleMouseClick));
|
|
|
- SubscribeToEvent(E_UIMOUSECLICKEND, HANDLER(Input, HandleMouseClick));
|
|
|
+ SubscribeToEvent(E_TOUCHBEGIN, HANDLER(Input, HandleScreenJoystickTouch));
|
|
|
+ SubscribeToEvent(E_TOUCHMOVE, HANDLER(Input, HandleScreenJoystickTouch));
|
|
|
+ SubscribeToEvent(E_TOUCHEND, HANDLER(Input, HandleScreenJoystickTouch));
|
|
|
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
+bool Input::RemoveScreenJoystick(unsigned index)
|
|
|
+{
|
|
|
+ if (index >= joysticks_.Size())
|
|
|
+ {
|
|
|
+ LOGERRORF("Joystick index #%d is out of bound", index);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ JoystickState& state = joysticks_[index];
|
|
|
+ if (!state.screenJoystick_)
|
|
|
+ {
|
|
|
+ LOGERRORF("Failed to remove joystick at index #%d which is not a screen joystick", index);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ state.screenJoystick_->Remove();
|
|
|
+ joysticks_.Erase(index);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
void Input::SetScreenKeyboardVisible(bool enable)
|
|
|
{
|
|
|
if (!graphics_)
|
|
|
@@ -366,7 +431,7 @@ bool Input::OpenJoystick(unsigned index)
|
|
|
{
|
|
|
if (index >= joysticks_.Size())
|
|
|
{
|
|
|
- LOGERRORF("Joystick index #%d is out of bound.", index);
|
|
|
+ LOGERRORF("Joystick index #%d is out of bound", index);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -464,12 +529,12 @@ String Input::GetScancodeName(int scancode) const
|
|
|
|
|
|
bool Input::GetKeyDown(int key) const
|
|
|
{
|
|
|
- return keyDown_.Contains(key);
|
|
|
+ return keyDown_.Contains(SDL_toupper(key));
|
|
|
}
|
|
|
|
|
|
bool Input::GetKeyPress(int key) const
|
|
|
{
|
|
|
- return keyPress_.Contains(key);
|
|
|
+ return keyPress_.Contains(SDL_toupper(key));
|
|
|
}
|
|
|
|
|
|
bool Input::GetScancodeDown(int scancode) const
|
|
|
@@ -928,9 +993,9 @@ void Input::HandleSDLEvent(void* sdlEvent)
|
|
|
eventData[P_TOUCHID] = touchID;
|
|
|
eventData[P_X] = state.position_.x_;
|
|
|
eventData[P_Y] = state.position_.y_;
|
|
|
+ SendEvent(E_TOUCHEND, eventData);
|
|
|
|
|
|
touches_.Erase(touchID);
|
|
|
- SendEvent(E_TOUCHEND, eventData);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
@@ -1176,12 +1241,14 @@ void Input::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
|
|
|
Update();
|
|
|
}
|
|
|
|
|
|
-void Input::HandleMouseClick(StringHash eventType, VariantMap& eventData)
|
|
|
+void Input::HandleScreenJoystickTouch(StringHash eventType, VariantMap& eventData)
|
|
|
{
|
|
|
- using namespace UIMouseClickEnd;
|
|
|
+ using namespace TouchBegin;
|
|
|
|
|
|
// Only interested in events from screen joystick(s)
|
|
|
- UIElement* element = static_cast<UIElement*>(eventData[eventType == E_UIMOUSECLICK ? P_ELEMENT : P_BEGINELEMENT].GetPtr());
|
|
|
+ TouchState& state = touches_[eventData[P_TOUCHID].GetInt()];
|
|
|
+ IntVector2 position(state.position_.x_, state.position_.y_);
|
|
|
+ UIElement* element = eventType == E_TOUCHBEGIN ? GetSubsystem<UI>()->GetElementAt(position) : state.touchedElement_;
|
|
|
if (!element)
|
|
|
return;
|
|
|
Variant variant = element->GetVar(VAR_SCREEN_JOYSTICK_INDEX);
|
|
|
@@ -1189,8 +1256,10 @@ void Input::HandleMouseClick(StringHash eventType, VariantMap& eventData)
|
|
|
return;
|
|
|
unsigned index = variant.GetUInt();
|
|
|
|
|
|
- int x = eventData[P_X].GetInt();
|
|
|
- int y = eventData[P_Y].GetInt();
|
|
|
+ if (eventType == E_TOUCHEND)
|
|
|
+ state.touchedElement_.Reset();
|
|
|
+ else
|
|
|
+ state.touchedElement_ = element;
|
|
|
|
|
|
// Prepare a fake SDL event
|
|
|
SDL_Event evt;
|
|
|
@@ -1198,60 +1267,36 @@ void Input::HandleMouseClick(StringHash eventType, VariantMap& eventData)
|
|
|
const String& name = element->GetName();
|
|
|
if (name.StartsWith("Button"))
|
|
|
{
|
|
|
+ if (eventType == E_TOUCHMOVE)
|
|
|
+ return;
|
|
|
+
|
|
|
// Determine whether to inject a joystick event or keyboard event
|
|
|
- if (joysticks_[index].screenJoystick_->GetVar(VAR_INJECT_AS_KEY_EVENTS).GetBool())
|
|
|
+ Variant variant = element->GetVar(VAR_BUTTON_KEY_BINDING);
|
|
|
+ if (variant.IsEmpty())
|
|
|
{
|
|
|
- Variant variant = element->GetVar(VAR_BUTTON_KEY_BINDING);
|
|
|
- if (variant.IsEmpty())
|
|
|
- return;
|
|
|
-
|
|
|
- evt.type = eventType == E_UIMOUSECLICK ? SDL_KEYDOWN : SDL_KEYUP;
|
|
|
- evt.key.keysym.sym = variant.GetInt();
|
|
|
- evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
|
|
|
+ evt.type = eventType == E_TOUCHBEGIN ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
|
|
|
+ evt.jbutton.which = SCREEN_JOYSTICK_START_INDEX + index;
|
|
|
+ evt.jbutton.button = ToUInt(name.Substring(6));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- evt.type = eventType == E_UIMOUSECLICK ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
|
|
|
- evt.jbutton.which = SCREEN_JOYSTICK_START_INDEX + index;
|
|
|
- evt.jbutton.button = ToUInt(name.Substring(6));
|
|
|
+ evt.type = eventType == E_TOUCHBEGIN ? SDL_KEYDOWN : SDL_KEYUP;
|
|
|
+ evt.key.keysym.sym = variant.GetInt();
|
|
|
+ evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
|
|
|
}
|
|
|
}
|
|
|
else if (name.StartsWith("Hat"))
|
|
|
{
|
|
|
- if (joysticks_[index].screenJoystick_->GetVar(VAR_INJECT_AS_KEY_EVENTS).GetBool())
|
|
|
- {
|
|
|
- evt.type = eventType == E_UIMOUSECLICK ? SDL_KEYDOWN : SDL_KEYUP;
|
|
|
- IntVector2 relPosition = IntVector2(x, y) - element->GetScreenPosition() - element->GetSize() / 2;
|
|
|
- if (relPosition.y_ < 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
|
|
|
- {
|
|
|
- evt.key.keysym.sym = SDLK_w;
|
|
|
- evt.key.keysym.scancode = SDL_SCANCODE_W;
|
|
|
- }
|
|
|
- else if (relPosition.y_ > 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
|
|
|
- {
|
|
|
- evt.key.keysym.sym = SDLK_s;
|
|
|
- evt.key.keysym.scancode = SDL_SCANCODE_S;
|
|
|
- }
|
|
|
- else if (relPosition.x_ < 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
|
|
|
- {
|
|
|
- evt.key.keysym.sym = SDLK_a;
|
|
|
- evt.key.keysym.scancode = SDL_SCANCODE_A;
|
|
|
- }
|
|
|
- else if (relPosition.x_ > 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
|
|
|
- {
|
|
|
- evt.key.keysym.sym = SDLK_d;
|
|
|
- evt.key.keysym.scancode = SDL_SCANCODE_D;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ Variant variant = element->GetVar(VAR_BUTTON_KEY_BINDING);
|
|
|
+ if (variant.IsEmpty())
|
|
|
{
|
|
|
evt.type = SDL_JOYHATMOTION;
|
|
|
evt.jaxis.which = SCREEN_JOYSTICK_START_INDEX + index;
|
|
|
evt.jhat.hat = ToUInt(name.Substring(3));
|
|
|
evt.jhat.value = HAT_CENTER;
|
|
|
- if (eventType == E_UIMOUSECLICK)
|
|
|
+ if (eventType != E_TOUCHEND)
|
|
|
{
|
|
|
- IntVector2 relPosition = IntVector2(x, y) - element->GetScreenPosition() - element->GetSize() / 2;
|
|
|
+ IntVector2 relPosition = position - element->GetScreenPosition() - element->GetSize() / 2;
|
|
|
if (relPosition.y_ < 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
|
|
|
evt.jhat.value |= HAT_UP;
|
|
|
if (relPosition.y_ > 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
|
|
|
@@ -1262,6 +1307,55 @@ void Input::HandleMouseClick(StringHash eventType, VariantMap& eventData)
|
|
|
evt.jhat.value |= HAT_RIGHT;
|
|
|
}
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Hat is binded by 4 keys, like 'WASD'
|
|
|
+ String keyBinding = variant.GetString();
|
|
|
+
|
|
|
+ if (eventType == E_TOUCHEND)
|
|
|
+ {
|
|
|
+ evt.type = SDL_KEYUP;
|
|
|
+ evt.key.keysym.sym = element->GetVar(VAR_LAST_KEYSYM).GetInt();
|
|
|
+ if (!evt.key.keysym.sym)
|
|
|
+ return;
|
|
|
+
|
|
|
+ element->SetVar(VAR_LAST_KEYSYM, 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ evt.type = SDL_KEYDOWN;
|
|
|
+ IntVector2 relPosition = position - element->GetScreenPosition() - element->GetSize() / 2;
|
|
|
+ if (relPosition.y_ < 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
|
|
|
+ evt.key.keysym.sym = keyBinding[0];
|
|
|
+ else if (relPosition.y_ > 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
|
|
|
+ evt.key.keysym.sym = keyBinding[2];
|
|
|
+ else if (relPosition.x_ < 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
|
|
|
+ evt.key.keysym.sym = keyBinding[1];
|
|
|
+ else if (relPosition.x_ > 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
|
|
|
+ evt.key.keysym.sym = keyBinding[3];
|
|
|
+ else
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (eventType == E_TOUCHMOVE && evt.key.keysym.sym != element->GetVar(VAR_LAST_KEYSYM).GetInt())
|
|
|
+ {
|
|
|
+ // Dragging past the directional boundary will cause an additional key up event for previous key symbol
|
|
|
+ SDL_Event evt;
|
|
|
+ evt.type = SDL_KEYUP;
|
|
|
+ evt.key.keysym.sym = element->GetVar(VAR_LAST_KEYSYM).GetInt();
|
|
|
+ if (evt.key.keysym.sym)
|
|
|
+ {
|
|
|
+ evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
|
|
|
+ HandleSDLEvent(&evt);
|
|
|
+ }
|
|
|
+
|
|
|
+ element->SetVar(VAR_LAST_KEYSYM, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
|
|
|
+
|
|
|
+ element->SetVar(VAR_LAST_KEYSYM, evt.key.keysym.sym);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
return;
|