mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-10 03:39:55 +00:00
Merge branch 'lua_input' into 'master'
Update Lua package openmw.input See merge request OpenMW/openmw!1356
This commit is contained in:
commit
bd694128b9
@ -49,8 +49,8 @@ namespace MWBase
|
||||
virtual void setGamepadGuiCursorEnabled(bool enabled) = 0;
|
||||
virtual void setAttemptJump(bool jumping) = 0;
|
||||
|
||||
virtual void toggleControlSwitch (const std::string& sw, bool value) = 0;
|
||||
virtual bool getControlSwitch (const std::string& sw) = 0;
|
||||
virtual void toggleControlSwitch(std::string_view sw, bool value) = 0;
|
||||
virtual bool getControlSwitch(std::string_view sw) = 0;
|
||||
|
||||
virtual std::string getActionDescription (int action) const = 0;
|
||||
virtual std::string getActionKeyBindingName (int action) const = 0;
|
||||
@ -58,8 +58,8 @@ namespace MWBase
|
||||
virtual bool actionIsActive(int action) const = 0;
|
||||
|
||||
virtual float getActionValue(int action) const = 0; // returns value in range [0, 1]
|
||||
virtual bool isControllerButtonPressed(SDL_GameControllerButton button) const = 0;
|
||||
virtual float getControllerAxisValue(SDL_GameControllerAxis axis) const = 0; // returns value in range [-1, 1]
|
||||
virtual uint32_t getMouseButtonsState() const = 0;
|
||||
virtual int getMouseMoveX() const = 0;
|
||||
virtual int getMouseMoveY() const = 0;
|
||||
|
||||
|
@ -653,14 +653,13 @@ namespace MWInput
|
||||
return mInputBinder->getKeyBinding(mInputBinder->getControl(actionId), ICS::Control::INCREASE);
|
||||
}
|
||||
|
||||
float BindingsManager::getControllerAxisValue(SDL_GameControllerAxis axis) const
|
||||
SDL_GameController* BindingsManager::getControllerOrNull() const
|
||||
{
|
||||
const auto& controllers = mInputBinder->getJoystickInstanceMap();
|
||||
if (controllers.empty())
|
||||
return 0;
|
||||
SDL_GameController* cntrl = controllers.begin()->second;
|
||||
constexpr int AXIS_MAX_ABSOLUTE_VALUE = 32768;
|
||||
return SDL_GameControllerGetAxis(cntrl, axis) / static_cast<float>(AXIS_MAX_ABSOLUTE_VALUE);
|
||||
return nullptr;
|
||||
else
|
||||
return controllers.begin()->second;
|
||||
}
|
||||
|
||||
void BindingsManager::actionValueChanged(int action, float currentValue, float previousValue)
|
||||
|
@ -43,7 +43,8 @@ namespace MWInput
|
||||
|
||||
bool actionIsActive(int id) const;
|
||||
float getActionValue(int id) const; // returns value in range [0, 1]
|
||||
float getControllerAxisValue(SDL_GameControllerAxis axis) const; // returns value in range [-1, 1]
|
||||
|
||||
SDL_GameController* getControllerOrNull() const;
|
||||
|
||||
void mousePressed(const SDL_MouseButtonEvent &evt, int deviceID);
|
||||
void mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID);
|
||||
|
@ -403,4 +403,24 @@ namespace MWInput
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float ControllerManager::getAxisValue(SDL_GameControllerAxis axis) const
|
||||
{
|
||||
SDL_GameController* cntrl = mBindingsManager->getControllerOrNull();
|
||||
constexpr int AXIS_MAX_ABSOLUTE_VALUE = 32768;
|
||||
if (cntrl)
|
||||
return SDL_GameControllerGetAxis(cntrl, axis) / static_cast<float>(AXIS_MAX_ABSOLUTE_VALUE);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ControllerManager::isButtonPressed(SDL_GameControllerButton button) const
|
||||
{
|
||||
SDL_GameController* cntrl = mBindingsManager->getControllerOrNull();
|
||||
if (cntrl)
|
||||
return SDL_GameControllerGetButton(cntrl, button) > 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,12 +34,15 @@ namespace MWInput
|
||||
void processChangedSettings(const Settings::CategorySettingVector& changed);
|
||||
|
||||
void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; }
|
||||
bool joystickLastUsed() { return mJoystickLastUsed; }
|
||||
bool joystickLastUsed() const { return mJoystickLastUsed; }
|
||||
|
||||
void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; }
|
||||
|
||||
void setGamepadGuiCursorEnabled(bool enabled) { mGamepadGuiCursorEnabled = enabled; }
|
||||
bool gamepadGuiCursorEnabled() { return mGamepadGuiCursorEnabled; }
|
||||
bool gamepadGuiCursorEnabled() const { return mGamepadGuiCursorEnabled; }
|
||||
|
||||
float getAxisValue(SDL_GameControllerAxis axis) const; // returns value in range [-1, 1]
|
||||
bool isButtonPressed(SDL_GameControllerButton button) const;
|
||||
|
||||
private:
|
||||
// Return true if GUI consumes input.
|
||||
|
@ -29,12 +29,15 @@ namespace MWInput
|
||||
mSwitches["vanitymode"] = true;
|
||||
}
|
||||
|
||||
bool ControlSwitch::get(const std::string& key)
|
||||
bool ControlSwitch::get(std::string_view key)
|
||||
{
|
||||
return mSwitches[key];
|
||||
auto it = mSwitches.find(key);
|
||||
if (it == mSwitches.end())
|
||||
throw std::runtime_error("Incorrect ControlSwitch: " + std::string(key));
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void ControlSwitch::set(const std::string& key, bool value)
|
||||
void ControlSwitch::set(std::string_view key, bool value)
|
||||
{
|
||||
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
|
||||
|
||||
@ -59,7 +62,10 @@ namespace MWInput
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->rotateObject(player.getPlayer(), osg::Vec3f());
|
||||
}
|
||||
mSwitches[key] = value;
|
||||
auto it = mSwitches.find(key);
|
||||
if (it == mSwitches.end())
|
||||
throw std::runtime_error("Incorrect ControlSwitch: " + std::string(key));
|
||||
it->second = value;
|
||||
}
|
||||
|
||||
void ControlSwitch::write(ESM::ESMWriter& writer, Loading::Listener& /*progress*/)
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
@ -23,8 +24,8 @@ namespace MWInput
|
||||
public:
|
||||
ControlSwitch();
|
||||
|
||||
bool get(const std::string& key);
|
||||
void set(const std::string& key, bool value);
|
||||
bool get(std::string_view key);
|
||||
void set(std::string_view key, bool value);
|
||||
void clear();
|
||||
|
||||
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||
@ -32,7 +33,7 @@ namespace MWInput
|
||||
int countSavedGameRecords() const;
|
||||
|
||||
private:
|
||||
std::map<std::string, bool> mSwitches;
|
||||
std::map<std::string, bool, std::less<>> mSwitches;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -135,12 +135,12 @@ namespace MWInput
|
||||
mSensorManager->processChangedSettings(changed);
|
||||
}
|
||||
|
||||
bool InputManager::getControlSwitch(const std::string& sw)
|
||||
bool InputManager::getControlSwitch(std::string_view sw)
|
||||
{
|
||||
return mControlSwitch->get(sw);
|
||||
}
|
||||
|
||||
void InputManager::toggleControlSwitch(const std::string& sw, bool value)
|
||||
void InputManager::toggleControlSwitch(std::string_view sw, bool value)
|
||||
{
|
||||
mControlSwitch->set(sw, value);
|
||||
}
|
||||
@ -180,14 +180,14 @@ namespace MWInput
|
||||
return mBindingsManager->getActionValue(action);
|
||||
}
|
||||
|
||||
float InputManager::getControllerAxisValue(SDL_GameControllerAxis axis) const
|
||||
bool InputManager::isControllerButtonPressed(SDL_GameControllerButton button) const
|
||||
{
|
||||
return mBindingsManager->getControllerAxisValue(axis);
|
||||
return mControllerManager->isButtonPressed(button);
|
||||
}
|
||||
|
||||
uint32_t InputManager::getMouseButtonsState() const
|
||||
float InputManager::getControllerAxisValue(SDL_GameControllerAxis axis) const
|
||||
{
|
||||
return mMouseManager->getButtonsState();
|
||||
return mControllerManager->getAxisValue(axis);
|
||||
}
|
||||
|
||||
int InputManager::getMouseMoveX() const
|
||||
|
@ -70,8 +70,8 @@ namespace MWInput
|
||||
void setGamepadGuiCursorEnabled(bool enabled) override;
|
||||
void setAttemptJump(bool jumping) override;
|
||||
|
||||
void toggleControlSwitch (const std::string& sw, bool value) override;
|
||||
bool getControlSwitch (const std::string& sw) override;
|
||||
void toggleControlSwitch(std::string_view sw, bool value) override;
|
||||
bool getControlSwitch(std::string_view sw) override;
|
||||
|
||||
std::string getActionDescription (int action) const override;
|
||||
std::string getActionKeyBindingName (int action) const override;
|
||||
@ -79,8 +79,8 @@ namespace MWInput
|
||||
bool actionIsActive(int action) const override;
|
||||
|
||||
float getActionValue(int action) const override;
|
||||
bool isControllerButtonPressed(SDL_GameControllerButton button) const override;
|
||||
float getControllerAxisValue(SDL_GameControllerAxis axis) const override;
|
||||
uint32_t getMouseButtonsState() const override;
|
||||
int getMouseMoveX() const override;
|
||||
int getMouseMoveY() const override;
|
||||
|
||||
|
@ -34,7 +34,6 @@ namespace MWInput
|
||||
, mMouseWheel(0)
|
||||
, mMouseLookEnabled(false)
|
||||
, mGuiCursorEnabled(true)
|
||||
, mButtonsState(0)
|
||||
, mMouseMoveX(0)
|
||||
, mMouseMoveY(0)
|
||||
{
|
||||
@ -199,7 +198,7 @@ namespace MWInput
|
||||
|
||||
void MouseManager::update(float dt)
|
||||
{
|
||||
mButtonsState = SDL_GetRelativeMouseState(&mMouseMoveX, &mMouseMoveY);
|
||||
SDL_GetRelativeMouseState(&mMouseMoveX, &mMouseMoveY);
|
||||
|
||||
if (!mMouseLookEnabled)
|
||||
return;
|
||||
|
@ -38,7 +38,6 @@ namespace MWInput
|
||||
void setMouseLookEnabled(bool enabled) { mMouseLookEnabled = enabled; }
|
||||
void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; }
|
||||
|
||||
uint32_t getButtonsState() const { return mButtonsState; }
|
||||
int getMouseMoveX() const { return mMouseMoveX; }
|
||||
int getMouseMoveY() const { return mMouseMoveY; }
|
||||
|
||||
@ -58,7 +57,6 @@ namespace MWInput
|
||||
bool mMouseLookEnabled;
|
||||
bool mGuiCursorEnabled;
|
||||
|
||||
uint32_t mButtonsState;
|
||||
int mMouseMoveX;
|
||||
int mMouseMoveY;
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include <SDL_mouse.h>
|
||||
|
||||
#include "../mwbase/inputmanager.hpp"
|
||||
#include "../mwinput/actions.hpp"
|
||||
@ -18,9 +19,14 @@ namespace MWLua
|
||||
sol::table initInputPackage(const Context& context)
|
||||
{
|
||||
sol::usertype<SDL_Keysym> keyEvent = context.mLua->sol().new_usertype<SDL_Keysym>("KeyEvent");
|
||||
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { return std::string(1, static_cast<char>(e.sym)); });
|
||||
keyEvent["code"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.sym; });
|
||||
keyEvent["modifiers"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.mod; });
|
||||
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e)
|
||||
{
|
||||
if (e.sym > 0 && e.sym <= 255)
|
||||
return std::string(1, static_cast<char>(e.sym));
|
||||
else
|
||||
return std::string();
|
||||
});
|
||||
keyEvent["code"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.scancode; });
|
||||
keyEvent["withShift"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_SHIFT; });
|
||||
keyEvent["withCtrl"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_CTRL; });
|
||||
keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; });
|
||||
@ -31,9 +37,26 @@ namespace MWLua
|
||||
|
||||
api["isIdle"] = [input]() { return input->isIdle(); };
|
||||
api["isActionPressed"] = [input](int action) { return input->actionIsActive(action); };
|
||||
api["isKeyPressed"] = [input](SDL_Scancode code) -> bool
|
||||
{
|
||||
int maxCode;
|
||||
const auto* state = SDL_GetKeyboardState(&maxCode);
|
||||
if (code >= 0 && code < maxCode)
|
||||
return state[code] != 0;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
api["isShiftPressed"] = [input]() -> bool { return SDL_GetModState() & KMOD_SHIFT; };
|
||||
api["isCtrlPressed"] = [input]() -> bool { return SDL_GetModState() & KMOD_CTRL; };
|
||||
api["isAltPressed"] = [input]() -> bool { return SDL_GetModState() & KMOD_ALT; };
|
||||
api["isSuperPressed"] = [input]() -> bool { return SDL_GetModState() & KMOD_GUI; };
|
||||
api["isControllerButtonPressed"] = [input](int button)
|
||||
{
|
||||
return input->isControllerButtonPressed(static_cast<SDL_GameControllerButton>(button));
|
||||
};
|
||||
api["isMouseButtonPressed"] = [input](int button) -> bool
|
||||
{
|
||||
return input->getMouseButtonsState() & (1 << (button - 1));
|
||||
return SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(button);
|
||||
};
|
||||
api["getMouseMoveX"] = [input]() { return input->getMouseMoveX(); };
|
||||
api["getMouseMoveY"] = [input]() { return input->getMouseMoveY(); };
|
||||
@ -45,104 +68,213 @@ namespace MWLua
|
||||
return input->getActionValue(axis - SDL_CONTROLLER_AXIS_MAX) * 2 - 1;
|
||||
};
|
||||
|
||||
api["getControlSwitch"] = [input](const std::string& key) { return input->getControlSwitch(key); };
|
||||
api["setControlSwitch"] = [input](const std::string& key, bool v) { input->toggleControlSwitch(key, v); };
|
||||
api["getControlSwitch"] = [input](std::string_view key) { return input->getControlSwitch(key); };
|
||||
api["setControlSwitch"] = [input](std::string_view key, bool v) { input->toggleControlSwitch(key, v); };
|
||||
|
||||
api["ACTION"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||
"GameMenu", MWInput::A_GameMenu,
|
||||
"Screenshot", MWInput::A_Screenshot,
|
||||
"Inventory", MWInput::A_Inventory,
|
||||
"Console", MWInput::A_Console,
|
||||
api["ACTION"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, MWInput::Actions>({
|
||||
{"GameMenu", MWInput::A_GameMenu},
|
||||
{"Screenshot", MWInput::A_Screenshot},
|
||||
{"Inventory", MWInput::A_Inventory},
|
||||
{"Console", MWInput::A_Console},
|
||||
|
||||
"MoveLeft", MWInput::A_MoveLeft,
|
||||
"MoveRight", MWInput::A_MoveRight,
|
||||
"MoveForward", MWInput::A_MoveForward,
|
||||
"MoveBackward", MWInput::A_MoveBackward,
|
||||
{"MoveLeft", MWInput::A_MoveLeft},
|
||||
{"MoveRight", MWInput::A_MoveRight},
|
||||
{"MoveForward", MWInput::A_MoveForward},
|
||||
{"MoveBackward", MWInput::A_MoveBackward},
|
||||
|
||||
"Activate", MWInput::A_Activate,
|
||||
"Use", MWInput::A_Use,
|
||||
"Jump", MWInput::A_Jump,
|
||||
"AutoMove", MWInput::A_AutoMove,
|
||||
"Rest", MWInput::A_Rest,
|
||||
"Journal", MWInput::A_Journal,
|
||||
"Weapon", MWInput::A_Weapon,
|
||||
"Spell", MWInput::A_Spell,
|
||||
"Run", MWInput::A_Run,
|
||||
"CycleSpellLeft", MWInput::A_CycleSpellLeft,
|
||||
"CycleSpellRight", MWInput::A_CycleSpellRight,
|
||||
"CycleWeaponLeft", MWInput::A_CycleWeaponLeft,
|
||||
"CycleWeaponRight", MWInput::A_CycleWeaponRight,
|
||||
"ToggleSneak", MWInput::A_ToggleSneak,
|
||||
"AlwaysRun", MWInput::A_AlwaysRun,
|
||||
"Sneak", MWInput::A_Sneak,
|
||||
{"Activate", MWInput::A_Activate},
|
||||
{"Use", MWInput::A_Use},
|
||||
{"Jump", MWInput::A_Jump},
|
||||
{"AutoMove", MWInput::A_AutoMove},
|
||||
{"Rest", MWInput::A_Rest},
|
||||
{"Journal", MWInput::A_Journal},
|
||||
{"Weapon", MWInput::A_Weapon},
|
||||
{"Spell", MWInput::A_Spell},
|
||||
{"Run", MWInput::A_Run},
|
||||
{"CycleSpellLeft", MWInput::A_CycleSpellLeft},
|
||||
{"CycleSpellRight", MWInput::A_CycleSpellRight},
|
||||
{"CycleWeaponLeft", MWInput::A_CycleWeaponLeft},
|
||||
{"CycleWeaponRight", MWInput::A_CycleWeaponRight},
|
||||
{"ToggleSneak", MWInput::A_ToggleSneak},
|
||||
{"AlwaysRun", MWInput::A_AlwaysRun},
|
||||
{"Sneak", MWInput::A_Sneak},
|
||||
|
||||
"QuickSave", MWInput::A_QuickSave,
|
||||
"QuickLoad", MWInput::A_QuickLoad,
|
||||
"QuickMenu", MWInput::A_QuickMenu,
|
||||
"ToggleWeapon", MWInput::A_ToggleWeapon,
|
||||
"ToggleSpell", MWInput::A_ToggleSpell,
|
||||
"TogglePOV", MWInput::A_TogglePOV,
|
||||
{"QuickSave", MWInput::A_QuickSave},
|
||||
{"QuickLoad", MWInput::A_QuickLoad},
|
||||
{"QuickMenu", MWInput::A_QuickMenu},
|
||||
{"ToggleWeapon", MWInput::A_ToggleWeapon},
|
||||
{"ToggleSpell", MWInput::A_ToggleSpell},
|
||||
{"TogglePOV", MWInput::A_TogglePOV},
|
||||
|
||||
"QuickKey1", MWInput::A_QuickKey1,
|
||||
"QuickKey2", MWInput::A_QuickKey2,
|
||||
"QuickKey3", MWInput::A_QuickKey3,
|
||||
"QuickKey4", MWInput::A_QuickKey4,
|
||||
"QuickKey5", MWInput::A_QuickKey5,
|
||||
"QuickKey6", MWInput::A_QuickKey6,
|
||||
"QuickKey7", MWInput::A_QuickKey7,
|
||||
"QuickKey8", MWInput::A_QuickKey8,
|
||||
"QuickKey9", MWInput::A_QuickKey9,
|
||||
"QuickKey10", MWInput::A_QuickKey10,
|
||||
"QuickKeysMenu", MWInput::A_QuickKeysMenu,
|
||||
{"QuickKey1", MWInput::A_QuickKey1},
|
||||
{"QuickKey2", MWInput::A_QuickKey2},
|
||||
{"QuickKey3", MWInput::A_QuickKey3},
|
||||
{"QuickKey4", MWInput::A_QuickKey4},
|
||||
{"QuickKey5", MWInput::A_QuickKey5},
|
||||
{"QuickKey6", MWInput::A_QuickKey6},
|
||||
{"QuickKey7", MWInput::A_QuickKey7},
|
||||
{"QuickKey8", MWInput::A_QuickKey8},
|
||||
{"QuickKey9", MWInput::A_QuickKey9},
|
||||
{"QuickKey10", MWInput::A_QuickKey10},
|
||||
{"QuickKeysMenu", MWInput::A_QuickKeysMenu},
|
||||
|
||||
"ToggleHUD", MWInput::A_ToggleHUD,
|
||||
"ToggleDebug", MWInput::A_ToggleDebug,
|
||||
{"ToggleHUD", MWInput::A_ToggleHUD},
|
||||
{"ToggleDebug", MWInput::A_ToggleDebug},
|
||||
|
||||
"ZoomIn", MWInput::A_ZoomIn,
|
||||
"ZoomOut", MWInput::A_ZoomOut
|
||||
));
|
||||
{"ZoomIn", MWInput::A_ZoomIn},
|
||||
{"ZoomOut", MWInput::A_ZoomOut}
|
||||
}));
|
||||
|
||||
api["CONTROL_SWITCH"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||
"Controls", "playercontrols",
|
||||
"Fighting", "playerfighting",
|
||||
"Jumping", "playerjumping",
|
||||
"Looking", "playerlooking",
|
||||
"Magic", "playermagic",
|
||||
"ViewMode", "playerviewswitch",
|
||||
"VanityMode", "vanitymode"
|
||||
));
|
||||
api["CONTROL_SWITCH"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, std::string_view>({
|
||||
{"Controls", "playercontrols"},
|
||||
{"Fighting", "playerfighting"},
|
||||
{"Jumping", "playerjumping"},
|
||||
{"Looking", "playerlooking"},
|
||||
{"Magic", "playermagic"},
|
||||
{"ViewMode", "playerviewswitch"},
|
||||
{"VanityMode", "vanitymode"}
|
||||
}));
|
||||
|
||||
api["CONTROLLER_BUTTON"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||
"A", SDL_CONTROLLER_BUTTON_A,
|
||||
"B", SDL_CONTROLLER_BUTTON_B,
|
||||
"X", SDL_CONTROLLER_BUTTON_X,
|
||||
"Y", SDL_CONTROLLER_BUTTON_Y,
|
||||
"Back", SDL_CONTROLLER_BUTTON_BACK,
|
||||
"Guide", SDL_CONTROLLER_BUTTON_GUIDE,
|
||||
"Start", SDL_CONTROLLER_BUTTON_START,
|
||||
"LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK,
|
||||
"RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK,
|
||||
"LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
|
||||
"RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
|
||||
"DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP,
|
||||
"DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN,
|
||||
"DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT,
|
||||
"DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT
|
||||
));
|
||||
api["CONTROLLER_BUTTON"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, SDL_GameControllerButton>({
|
||||
{"A", SDL_CONTROLLER_BUTTON_A},
|
||||
{"B", SDL_CONTROLLER_BUTTON_B},
|
||||
{"X", SDL_CONTROLLER_BUTTON_X},
|
||||
{"Y", SDL_CONTROLLER_BUTTON_Y},
|
||||
{"Back", SDL_CONTROLLER_BUTTON_BACK},
|
||||
{"Guide", SDL_CONTROLLER_BUTTON_GUIDE},
|
||||
{"Start", SDL_CONTROLLER_BUTTON_START},
|
||||
{"LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK},
|
||||
{"RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK},
|
||||
{"LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER},
|
||||
{"RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER},
|
||||
{"DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP},
|
||||
{"DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN},
|
||||
{"DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT},
|
||||
{"DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT}
|
||||
}));
|
||||
|
||||
api["CONTROLLER_AXIS"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||
"LeftX", SDL_CONTROLLER_AXIS_LEFTX,
|
||||
"LeftY", SDL_CONTROLLER_AXIS_LEFTY,
|
||||
"RightX", SDL_CONTROLLER_AXIS_RIGHTX,
|
||||
"RightY", SDL_CONTROLLER_AXIS_RIGHTY,
|
||||
"TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT,
|
||||
"TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
|
||||
api["CONTROLLER_AXIS"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
||||
{"LeftX", SDL_CONTROLLER_AXIS_LEFTX},
|
||||
{"LeftY", SDL_CONTROLLER_AXIS_LEFTY},
|
||||
{"RightX", SDL_CONTROLLER_AXIS_RIGHTX},
|
||||
{"RightY", SDL_CONTROLLER_AXIS_RIGHTY},
|
||||
{"TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT},
|
||||
{"TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT},
|
||||
|
||||
"LookUpDown", SDL_CONTROLLER_AXIS_MAX + MWInput::A_LookUpDown,
|
||||
"LookLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_LookLeftRight,
|
||||
"MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveForwardBackward,
|
||||
"MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveLeftRight
|
||||
));
|
||||
{"LookUpDown", SDL_CONTROLLER_AXIS_MAX + MWInput::A_LookUpDown},
|
||||
{"LookLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_LookLeftRight},
|
||||
{"MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveForwardBackward},
|
||||
{"MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveLeftRight}
|
||||
}));
|
||||
|
||||
api["KEY"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, SDL_Scancode>({
|
||||
{"_0", SDL_SCANCODE_0},
|
||||
{"_1", SDL_SCANCODE_1},
|
||||
{"_2", SDL_SCANCODE_2},
|
||||
{"_3", SDL_SCANCODE_3},
|
||||
{"_4", SDL_SCANCODE_4},
|
||||
{"_5", SDL_SCANCODE_5},
|
||||
{"_6", SDL_SCANCODE_6},
|
||||
{"_7", SDL_SCANCODE_7},
|
||||
{"_8", SDL_SCANCODE_8},
|
||||
{"_9", SDL_SCANCODE_9},
|
||||
|
||||
{"NP_0", SDL_SCANCODE_KP_0},
|
||||
{"NP_1", SDL_SCANCODE_KP_1},
|
||||
{"NP_2", SDL_SCANCODE_KP_2},
|
||||
{"NP_3", SDL_SCANCODE_KP_3},
|
||||
{"NP_4", SDL_SCANCODE_KP_4},
|
||||
{"NP_5", SDL_SCANCODE_KP_5},
|
||||
{"NP_6", SDL_SCANCODE_KP_6},
|
||||
{"NP_7", SDL_SCANCODE_KP_7},
|
||||
{"NP_8", SDL_SCANCODE_KP_8},
|
||||
{"NP_9", SDL_SCANCODE_KP_9},
|
||||
{"NP_Divide", SDL_SCANCODE_KP_DIVIDE},
|
||||
{"NP_Enter", SDL_SCANCODE_KP_ENTER},
|
||||
{"NP_Minus", SDL_SCANCODE_KP_MINUS},
|
||||
{"NP_Multiply", SDL_SCANCODE_KP_MULTIPLY},
|
||||
{"NP_Delete", SDL_SCANCODE_KP_PERIOD},
|
||||
{"NP_Plus", SDL_SCANCODE_KP_PLUS},
|
||||
|
||||
{"F1", SDL_SCANCODE_F1},
|
||||
{"F2", SDL_SCANCODE_F2},
|
||||
{"F3", SDL_SCANCODE_F3},
|
||||
{"F4", SDL_SCANCODE_F4},
|
||||
{"F5", SDL_SCANCODE_F5},
|
||||
{"F6", SDL_SCANCODE_F6},
|
||||
{"F7", SDL_SCANCODE_F7},
|
||||
{"F8", SDL_SCANCODE_F8},
|
||||
{"F9", SDL_SCANCODE_F9},
|
||||
{"F10", SDL_SCANCODE_F10},
|
||||
{"F11", SDL_SCANCODE_F11},
|
||||
{"F12", SDL_SCANCODE_F12},
|
||||
|
||||
{"A", SDL_SCANCODE_A},
|
||||
{"B", SDL_SCANCODE_B},
|
||||
{"C", SDL_SCANCODE_C},
|
||||
{"D", SDL_SCANCODE_D},
|
||||
{"E", SDL_SCANCODE_E},
|
||||
{"F", SDL_SCANCODE_F},
|
||||
{"G", SDL_SCANCODE_G},
|
||||
{"H", SDL_SCANCODE_H},
|
||||
{"I", SDL_SCANCODE_I},
|
||||
{"J", SDL_SCANCODE_J},
|
||||
{"K", SDL_SCANCODE_K},
|
||||
{"L", SDL_SCANCODE_L},
|
||||
{"M", SDL_SCANCODE_M},
|
||||
{"N", SDL_SCANCODE_N},
|
||||
{"O", SDL_SCANCODE_O},
|
||||
{"P", SDL_SCANCODE_P},
|
||||
{"Q", SDL_SCANCODE_Q},
|
||||
{"R", SDL_SCANCODE_R},
|
||||
{"S", SDL_SCANCODE_S},
|
||||
{"T", SDL_SCANCODE_T},
|
||||
{"U", SDL_SCANCODE_U},
|
||||
{"V", SDL_SCANCODE_V},
|
||||
{"W", SDL_SCANCODE_W},
|
||||
{"X", SDL_SCANCODE_X},
|
||||
{"Y", SDL_SCANCODE_Y},
|
||||
{"Z", SDL_SCANCODE_Z},
|
||||
|
||||
{"LeftArrow", SDL_SCANCODE_LEFT},
|
||||
{"RightArrow", SDL_SCANCODE_RIGHT},
|
||||
{"UpArrow", SDL_SCANCODE_UP},
|
||||
{"DownArrow", SDL_SCANCODE_DOWN},
|
||||
|
||||
{"LeftAlt", SDL_SCANCODE_LALT},
|
||||
{"LeftCtrl", SDL_SCANCODE_LCTRL},
|
||||
{"LeftBracket", SDL_SCANCODE_LEFTBRACKET},
|
||||
{"LeftSuper", SDL_SCANCODE_LGUI},
|
||||
{"LeftShift", SDL_SCANCODE_LSHIFT},
|
||||
{"RightAlt", SDL_SCANCODE_RALT},
|
||||
{"RightCtrl", SDL_SCANCODE_RCTRL},
|
||||
{"RightSuper", SDL_SCANCODE_RGUI},
|
||||
{"RightBracket", SDL_SCANCODE_RIGHTBRACKET},
|
||||
{"RightShift", SDL_SCANCODE_RSHIFT},
|
||||
|
||||
{"BackSlash", SDL_SCANCODE_BACKSLASH},
|
||||
{"Backspace", SDL_SCANCODE_BACKSPACE},
|
||||
{"CapsLock", SDL_SCANCODE_CAPSLOCK},
|
||||
{"Comma", SDL_SCANCODE_COMMA},
|
||||
{"Delete", SDL_SCANCODE_DELETE},
|
||||
{"End", SDL_SCANCODE_END},
|
||||
{"Enter", SDL_SCANCODE_RETURN},
|
||||
{"Equals", SDL_SCANCODE_EQUALS},
|
||||
{"Escape", SDL_SCANCODE_ESCAPE},
|
||||
{"Home", SDL_SCANCODE_HOME},
|
||||
{"Insert", SDL_SCANCODE_INSERT},
|
||||
{"Minus", SDL_SCANCODE_MINUS},
|
||||
{"NumLock", SDL_SCANCODE_NUMLOCKCLEAR},
|
||||
{"PageDown", SDL_SCANCODE_PAGEDOWN},
|
||||
{"PageUp", SDL_SCANCODE_PAGEUP},
|
||||
{"Pause", SDL_SCANCODE_PAUSE},
|
||||
{"PrintScreen", SDL_SCANCODE_PRINTSCREEN},
|
||||
{"ScrollLock", SDL_SCANCODE_SCROLLLOCK},
|
||||
{"Semicolon", SDL_SCANCODE_SEMICOLON},
|
||||
{"Slash", SDL_SCANCODE_SLASH},
|
||||
{"Space", SDL_SCANCODE_SPACE},
|
||||
{"Tab", SDL_SCANCODE_TAB}
|
||||
}));
|
||||
|
||||
return LuaUtil::makeReadOnly(api);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace MWLua
|
||||
{
|
||||
auto* lua = context.mLua;
|
||||
sol::table api(lua->sol(), sol::create);
|
||||
api["API_REVISION"] = 8;
|
||||
api["API_REVISION"] = 9;
|
||||
api["quit"] = [lua]()
|
||||
{
|
||||
std::string traceback = lua->sol()["debug"]["traceback"]().get<std::string>();
|
||||
@ -43,27 +43,27 @@ namespace MWLua
|
||||
"Activator", "Armor", "Book", "Clothing", "Creature", "Door", "Ingredient",
|
||||
"Light", "Miscellaneous", "NPC", "Player", "Potion", "Static", "Weapon"
|
||||
});
|
||||
api["EQUIPMENT_SLOT"] = LuaUtil::makeReadOnly(lua->sol().create_table_with(
|
||||
"Helmet", MWWorld::InventoryStore::Slot_Helmet,
|
||||
"Cuirass", MWWorld::InventoryStore::Slot_Cuirass,
|
||||
"Greaves", MWWorld::InventoryStore::Slot_Greaves,
|
||||
"LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron,
|
||||
"RightPauldron", MWWorld::InventoryStore::Slot_RightPauldron,
|
||||
"LeftGauntlet", MWWorld::InventoryStore::Slot_LeftGauntlet,
|
||||
"RightGauntlet", MWWorld::InventoryStore::Slot_RightGauntlet,
|
||||
"Boots", MWWorld::InventoryStore::Slot_Boots,
|
||||
"Shirt", MWWorld::InventoryStore::Slot_Shirt,
|
||||
"Pants", MWWorld::InventoryStore::Slot_Pants,
|
||||
"Skirt", MWWorld::InventoryStore::Slot_Skirt,
|
||||
"Robe", MWWorld::InventoryStore::Slot_Robe,
|
||||
"LeftRing", MWWorld::InventoryStore::Slot_LeftRing,
|
||||
"RightRing", MWWorld::InventoryStore::Slot_RightRing,
|
||||
"Amulet", MWWorld::InventoryStore::Slot_Amulet,
|
||||
"Belt", MWWorld::InventoryStore::Slot_Belt,
|
||||
"CarriedRight", MWWorld::InventoryStore::Slot_CarriedRight,
|
||||
"CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft,
|
||||
"Ammunition", MWWorld::InventoryStore::Slot_Ammunition
|
||||
));
|
||||
api["EQUIPMENT_SLOT"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
||||
{"Helmet", MWWorld::InventoryStore::Slot_Helmet},
|
||||
{"Cuirass", MWWorld::InventoryStore::Slot_Cuirass},
|
||||
{"Greaves", MWWorld::InventoryStore::Slot_Greaves},
|
||||
{"LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron},
|
||||
{"RightPauldron", MWWorld::InventoryStore::Slot_RightPauldron},
|
||||
{"LeftGauntlet", MWWorld::InventoryStore::Slot_LeftGauntlet},
|
||||
{"RightGauntlet", MWWorld::InventoryStore::Slot_RightGauntlet},
|
||||
{"Boots", MWWorld::InventoryStore::Slot_Boots},
|
||||
{"Shirt", MWWorld::InventoryStore::Slot_Shirt},
|
||||
{"Pants", MWWorld::InventoryStore::Slot_Pants},
|
||||
{"Skirt", MWWorld::InventoryStore::Slot_Skirt},
|
||||
{"Robe", MWWorld::InventoryStore::Slot_Robe},
|
||||
{"LeftRing", MWWorld::InventoryStore::Slot_LeftRing},
|
||||
{"RightRing", MWWorld::InventoryStore::Slot_RightRing},
|
||||
{"Amulet", MWWorld::InventoryStore::Slot_Amulet},
|
||||
{"Belt", MWWorld::InventoryStore::Slot_Belt},
|
||||
{"CarriedRight", MWWorld::InventoryStore::Slot_CarriedRight},
|
||||
{"CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft},
|
||||
{"Ammunition", MWWorld::InventoryStore::Slot_Ammunition}
|
||||
}));
|
||||
return LuaUtil::makeReadOnly(api);
|
||||
}
|
||||
|
||||
|
@ -47,14 +47,15 @@ namespace MWLua
|
||||
return LObject(getId(r.mHitObject), worldView->getObjectRegistry());
|
||||
});
|
||||
|
||||
api["COLLISION_TYPE"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||
"World", MWPhysics::CollisionType_World,
|
||||
"Door", MWPhysics::CollisionType_Door,
|
||||
"Actor", MWPhysics::CollisionType_Actor,
|
||||
"HeightMap", MWPhysics::CollisionType_HeightMap,
|
||||
"Projectile", MWPhysics::CollisionType_Projectile,
|
||||
"Water", MWPhysics::CollisionType_Water,
|
||||
"Default", MWPhysics::CollisionType_Default));
|
||||
api["COLLISION_TYPE"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string_view, MWPhysics::CollisionType>({
|
||||
{"World", MWPhysics::CollisionType_World},
|
||||
{"Door", MWPhysics::CollisionType_Door},
|
||||
{"Actor", MWPhysics::CollisionType_Actor},
|
||||
{"HeightMap", MWPhysics::CollisionType_HeightMap},
|
||||
{"Projectile", MWPhysics::CollisionType_Projectile},
|
||||
{"Water", MWPhysics::CollisionType_Water},
|
||||
{"Default", MWPhysics::CollisionType_Default}
|
||||
}));
|
||||
|
||||
api["castRay"] = [](const osg::Vec3f& from, const osg::Vec3f& to, sol::optional<sol::table> options)
|
||||
{
|
||||
|
@ -38,6 +38,15 @@ namespace LuaUtil
|
||||
// A shortcut to create a new Lua table.
|
||||
sol::table newTable() { return sol::table(mLua, sol::create); }
|
||||
|
||||
template <typename Key, typename Value>
|
||||
sol::table tableFromPairs(std::initializer_list<std::pair<Key, Value>> list)
|
||||
{
|
||||
sol::table res(mLua, sol::create);
|
||||
for (const auto& [k, v] : list)
|
||||
res[k] = v;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Registers a package that will be available from every sandbox via `require(name)`.
|
||||
// The package can be either a sol::table with an API or a sol::function. If it is a function,
|
||||
// it will be evaluated (once per sandbox) the first time when requested. If the package
|
||||
|
@ -17,6 +17,38 @@
|
||||
-- @param #number actionId One of @{openmw.input#ACTION}
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is a keyboard button currently pressed.
|
||||
-- @function [parent=#input] isKeyPressed
|
||||
-- @param #number keyCode Key code (the same code that is used in @{openmw.input#KeyEvent})
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is a controller button currently pressed.
|
||||
-- @function [parent=#input] isControllerButtonPressed
|
||||
-- @param #number buttonId Button index (see @{openmw.input#CONTROLLER_BUTTON})
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is `Shift` key pressed.
|
||||
-- @function [parent=#input] isShiftPressed
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is `Ctrl` key pressed.
|
||||
-- @function [parent=#input] isCtrlPressed
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is `Alt` key pressed.
|
||||
-- @function [parent=#input] isAltPressed
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is `Super`/`Win` key pressed.
|
||||
-- @function [parent=#input] isSuperPressed
|
||||
-- @return #boolean
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Is a mouse button currently pressed.
|
||||
-- @function [parent=#input] isMouseButtonPressed
|
||||
@ -156,10 +188,117 @@
|
||||
-- Values that can be used with getAxisValue.
|
||||
-- @field [parent=#input] #CONTROLLER_AXIS CONTROLLER_AXIS
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- @type KEY
|
||||
-- @field #number _0
|
||||
-- @field #number _1
|
||||
-- @field #number _2
|
||||
-- @field #number _3
|
||||
-- @field #number _4
|
||||
-- @field #number _5
|
||||
-- @field #number _6
|
||||
-- @field #number _7
|
||||
-- @field #number _8
|
||||
-- @field #number _9
|
||||
-- @field #number NP_0
|
||||
-- @field #number NP_1
|
||||
-- @field #number NP_2
|
||||
-- @field #number NP_3
|
||||
-- @field #number NP_4
|
||||
-- @field #number NP_5
|
||||
-- @field #number NP_6
|
||||
-- @field #number NP_7
|
||||
-- @field #number NP_8
|
||||
-- @field #number NP_9
|
||||
-- @field #number NP_Divide
|
||||
-- @field #number NP_Enter
|
||||
-- @field #number NP_Minus
|
||||
-- @field #number NP_Multiply
|
||||
-- @field #number NP_Delete
|
||||
-- @field #number NP_Plus
|
||||
-- @field #number F1
|
||||
-- @field #number F2
|
||||
-- @field #number F3
|
||||
-- @field #number F4
|
||||
-- @field #number F5
|
||||
-- @field #number F6
|
||||
-- @field #number F7
|
||||
-- @field #number F8
|
||||
-- @field #number F9
|
||||
-- @field #number F10
|
||||
-- @field #number F11
|
||||
-- @field #number F12
|
||||
-- @field #number A
|
||||
-- @field #number B
|
||||
-- @field #number C
|
||||
-- @field #number D
|
||||
-- @field #number E
|
||||
-- @field #number F
|
||||
-- @field #number G
|
||||
-- @field #number H
|
||||
-- @field #number I
|
||||
-- @field #number J
|
||||
-- @field #number K
|
||||
-- @field #number L
|
||||
-- @field #number M
|
||||
-- @field #number N
|
||||
-- @field #number O
|
||||
-- @field #number P
|
||||
-- @field #number Q
|
||||
-- @field #number R
|
||||
-- @field #number S
|
||||
-- @field #number T
|
||||
-- @field #number U
|
||||
-- @field #number V
|
||||
-- @field #number W
|
||||
-- @field #number X
|
||||
-- @field #number Y
|
||||
-- @field #number Z
|
||||
-- @field #number LeftArrow
|
||||
-- @field #number RightArrow
|
||||
-- @field #number UpArrow
|
||||
-- @field #number DownArrow
|
||||
-- @field #number LeftAlt
|
||||
-- @field #number LeftCtrl
|
||||
-- @field #number LeftBracket
|
||||
-- @field #number LeftSuper
|
||||
-- @field #number LeftShift
|
||||
-- @field #number RightAlt
|
||||
-- @field #number RightCtrl
|
||||
-- @field #number RightBracket
|
||||
-- @field #number RightSuper
|
||||
-- @field #number RightShift
|
||||
-- @field #number BackSlash
|
||||
-- @field #number Backspace
|
||||
-- @field #number CapsLock
|
||||
-- @field #number Comma
|
||||
-- @field #number Delete
|
||||
-- @field #number End
|
||||
-- @field #number Enter
|
||||
-- @field #number Equals
|
||||
-- @field #number Escape
|
||||
-- @field #number Home
|
||||
-- @field #number Insert
|
||||
-- @field #number Minus
|
||||
-- @field #number NumLock
|
||||
-- @field #number PageDown
|
||||
-- @field #number PageUp
|
||||
-- @field #number Pause
|
||||
-- @field #number PrintScreen
|
||||
-- @field #number ScrollLock
|
||||
-- @field #number Semicolon
|
||||
-- @field #number Slash
|
||||
-- @field #number Space
|
||||
-- @field #number Tab
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Key codes.
|
||||
-- @field [parent=#input] #KEY KEY
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- The argument of `onKeyPress`/`onKeyRelease` engine handlers.
|
||||
-- @type KeyboardEvent
|
||||
-- @field [parent=#KeyboardEvent] #string symbol The pressed symbol (1-symbol string).
|
||||
-- @field [parent=#KeyboardEvent] #string symbol The pressed symbol (1-symbol string if can be represented or an empty string otherwise).
|
||||
-- @field [parent=#KeyboardEvent] #string code Key code.
|
||||
-- @field [parent=#KeyboardEvent] #boolean withShift Is `Shift` key pressed.
|
||||
-- @field [parent=#KeyboardEvent] #boolean withCtrl Is `Control` key pressed.
|
||||
|
Loading…
x
Reference in New Issue
Block a user