lua hotkeys system
This commit is contained in:
parent
c4b2dd18d6
commit
060d8740f5
3
TODO
3
TODO
|
@ -1,5 +1,4 @@
|
|||
== Core
|
||||
[bart] a class for binding hotkeys
|
||||
[bart] review directories loading search
|
||||
[bart] load modules from zip packages
|
||||
[bart] create a class for reading binary files
|
||||
|
@ -44,12 +43,10 @@
|
|||
[bart] padding
|
||||
[bart] review and make more error prone with more warnings
|
||||
[bart] a real working border and background property in otui
|
||||
[bart] merge states declared in inherited styles
|
||||
[bart] reapply anchor styles when adding new childs
|
||||
|
||||
== Client modules
|
||||
[bart] modules managment interface
|
||||
[bart] restore Console key binding
|
||||
[bart] console history, text selection, scrolling
|
||||
|
||||
== Client
|
||||
|
|
|
@ -124,7 +124,8 @@ function Terminal.init()
|
|||
terminalWidget = displayUI('terminal.otui')
|
||||
terminalWidget:setVisible(false)
|
||||
|
||||
terminalButton = TopMenu.addButton('terminalButton', 'Terminal', '/core_styles/icons/terminal.png', Terminal.show)
|
||||
terminalButton = TopMenu.addButton('terminalButton', 'Terminal (Ctrl + T)', '/core_styles/icons/terminal.png', Terminal.toggle)
|
||||
Hotkeys.bind('Ctrl+T', Terminal.toggle)
|
||||
|
||||
commandLineEdit = terminalWidget:getChildById('commandLineEdit')
|
||||
connect(commandLineEdit, { onKeyPress = onCommandLineKeyPress })
|
||||
|
@ -135,6 +136,7 @@ function Terminal.init()
|
|||
end
|
||||
|
||||
function Terminal.terminate()
|
||||
Hotkeys.unbind('Ctrl+T')
|
||||
Logger.setOnLog(nil)
|
||||
terminalButton:destroy()
|
||||
terminalButton = nil
|
||||
|
@ -145,6 +147,14 @@ function Terminal.terminate()
|
|||
commandEnv = nil
|
||||
end
|
||||
|
||||
function Terminal.toggle()
|
||||
if terminalWidget:isVisible() then
|
||||
Terminal.hide()
|
||||
else
|
||||
Terminal.show()
|
||||
end
|
||||
end
|
||||
|
||||
function Terminal.show()
|
||||
terminalWidget:show()
|
||||
terminalWidget:lock()
|
||||
|
|
|
@ -7,6 +7,7 @@ RectPanel
|
|||
background-color: #000000
|
||||
opacity: 216
|
||||
anchors.fill: parent
|
||||
@onEscape: Terminal.hide()
|
||||
|
||||
Panel
|
||||
id: terminalBuffer
|
||||
|
|
|
@ -54,7 +54,8 @@ end
|
|||
|
||||
-- public functions
|
||||
function EnterGame.init()
|
||||
enterGameButton = TopMenu.addButton('enterGameButton', 'Login', '/core_styles/icons/login.png', EnterGame.openWindow)
|
||||
enterGameButton = TopMenu.addButton('enterGameButton', 'Login (Ctrl + G)', '/core_styles/icons/login.png', EnterGame.openWindow)
|
||||
Hotkeys.bind('Ctrl+G', EnterGame.openWindow)
|
||||
motdButton = TopMenu.addButton('motdButton', 'Message of the day', '/core_styles/icons/motd.png', EnterGame.displayMotd)
|
||||
motdButton:hide()
|
||||
enterGame = displayUI('entergame.otui')
|
||||
|
@ -79,6 +80,7 @@ function EnterGame.init()
|
|||
end
|
||||
|
||||
function EnterGame.terminate()
|
||||
Hotkeys.unbind('Ctrl+G')
|
||||
enterGame:destroy()
|
||||
enterGame = nil
|
||||
enterGameButton:destroy()
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
Options = {}
|
||||
|
||||
local optionsWindow
|
||||
local optionsButton
|
||||
|
||||
function Options.init()
|
||||
optionsButton = TopMenu.addButton('settingsButton', 'Options', '/core_styles/icons/settings.png', Options.show)
|
||||
Options.load()
|
||||
end
|
||||
optionsWindow = displayUI('options.otui')
|
||||
optionsWindow:setVisible(false)
|
||||
optionsButton = TopMenu.addButton('settingsButton', 'Options (Ctrl+O)', '/core_styles/icons/settings.png', Options.toggle)
|
||||
Hotkeys.bind('Ctrl+O', Options.toggle)
|
||||
|
||||
function Options.terminate()
|
||||
TopMenu.removeButton(optionsButton)
|
||||
end
|
||||
|
||||
function Options.load()
|
||||
-- load settings
|
||||
local booleanOptions = { vsync = true,
|
||||
showfps = true,
|
||||
fullscreen = false,
|
||||
|
@ -23,8 +21,30 @@ function Options.load()
|
|||
end
|
||||
end
|
||||
|
||||
function Options.terminate()
|
||||
Hotkeys.unbind('Ctrl+O')
|
||||
optionsWindow:destroy()
|
||||
optionsWindow = nil
|
||||
optionsButton:destroy()
|
||||
optionsButton = nil
|
||||
end
|
||||
|
||||
function Options.toggle()
|
||||
if optionsWindow:isVisible() then
|
||||
Options.hide()
|
||||
else
|
||||
Options.show()
|
||||
end
|
||||
end
|
||||
|
||||
function Options.show()
|
||||
displayUI('options.otui', { locked = true })
|
||||
optionsWindow:show()
|
||||
optionsWindow:lock()
|
||||
end
|
||||
|
||||
function Options.hide()
|
||||
optionsWindow:unlock()
|
||||
optionsWindow:hide()
|
||||
end
|
||||
|
||||
function Options.openWebpage()
|
||||
|
|
|
@ -20,6 +20,8 @@ MainWindow
|
|||
id: optionsWindow
|
||||
title: Options
|
||||
size: 286 140
|
||||
@onEnter: Options.hide()
|
||||
@onEscape: Options.hide()
|
||||
|
||||
OptionCheckBox
|
||||
id: vsync
|
||||
|
@ -45,4 +47,4 @@ MainWindow
|
|||
anchors.bottom: parent.bottom
|
||||
margin-right: 10
|
||||
margin-bottom: 10
|
||||
@onClick: self:getParent():destroy()
|
||||
@onClick: Options.hide()
|
|
@ -5,24 +5,27 @@ local topMenu
|
|||
local leftButtonsPanel
|
||||
local rightButtonsPanel
|
||||
|
||||
-- private functions
|
||||
local function onLogout()
|
||||
if Game.isOnline() then
|
||||
Game.logout(false)
|
||||
else
|
||||
exit()
|
||||
end
|
||||
end
|
||||
|
||||
-- public functions
|
||||
function TopMenu.init()
|
||||
topMenu = displayUI('topmenu.otui')
|
||||
leftButtonsPanel = topMenu:getChildById('leftButtonsPanel')
|
||||
rightButtonsPanel = topMenu:getChildById('rightButtonsPanel')
|
||||
|
||||
TopMenu.addRightButton('logoutButton', 'Logout', '/core_styles/icons/logout.png',
|
||||
function()
|
||||
if Game.isOnline() then
|
||||
Game.logout(false)
|
||||
else
|
||||
exit()
|
||||
end
|
||||
end
|
||||
)
|
||||
TopMenu.addRightButton('logoutButton', 'Logout (Ctrl+Q)', '/core_styles/icons/logout.png', onLogout)
|
||||
Hotkeys.bind('Ctrl+Q', onLogout)
|
||||
end
|
||||
|
||||
function TopMenu.terminate()
|
||||
Hotkeys.unbind('Ctrl+Q')
|
||||
leftButtonsPanel = nil
|
||||
rightButtonsPanel = nil
|
||||
topMenu:destroy()
|
||||
|
|
Binary file not shown.
|
@ -14,6 +14,38 @@ LogFatal = 4
|
|||
|
||||
ActiveFocusReason = 2
|
||||
|
||||
KeyboardNoModifier = 0
|
||||
KeyboardCtrlModifier = 1
|
||||
KeyboardAltModifier = 2
|
||||
KeyboardCtrlAltModifier = 3
|
||||
KeyboardShiftModifier = 4
|
||||
KeyboardCtrlShiftModifier = 5
|
||||
KeyboardAltShiftModifier = 6
|
||||
KeyboardCtrlAltShiftModifier = 7
|
||||
|
||||
MouseNoButton = 0
|
||||
MouseLeftButton = 1
|
||||
MouseRightButton = 2
|
||||
MouseMidButton = 3
|
||||
|
||||
AlignNone = 0
|
||||
AlignLeft = 1
|
||||
AlignRight = 2
|
||||
AlignTop = 4
|
||||
AlignBottom = 8
|
||||
AlignHorizontalCenter = 16
|
||||
AlignVerticalCenter = 32
|
||||
AlignTopLeft = 5
|
||||
AlignTopRight = 6
|
||||
AlignBottomLeft = 9
|
||||
AlignBottomRight = 10
|
||||
AlignLeftCenter = 33
|
||||
AlignRightCenter = 34
|
||||
AlignTopCenter = 20
|
||||
AlignBottomCenter = 24
|
||||
AlignCenter = 48
|
||||
|
||||
|
||||
KeyUnknown = 0
|
||||
KeyEscape = 1
|
||||
KeyTab = 2
|
||||
|
@ -123,29 +155,113 @@ KeyF10 = 138
|
|||
KeyF11 = 139
|
||||
KeyF12 = 140
|
||||
|
||||
KeyboardNoModifier = 0
|
||||
KeyboardCtrlModifier = 1
|
||||
KeyboardAltModifier = 2
|
||||
KeyboardShiftModifier = 4
|
||||
|
||||
MouseNoButton = 0
|
||||
MouseLeftButton = 1
|
||||
MouseRightButton = 2
|
||||
MouseMidButton = 3
|
||||
|
||||
AlignNone = 0
|
||||
AlignLeft = 1
|
||||
AlignRight = 2
|
||||
AlignTop = 4
|
||||
AlignBottom = 8
|
||||
AlignHorizontalCenter = 16
|
||||
AlignVerticalCenter = 32
|
||||
AlignTopLeft = 5
|
||||
AlignTopRight = 6
|
||||
AlignBottomLeft = 9
|
||||
AlignBottomRight = 10
|
||||
AlignLeftCenter = 33
|
||||
AlignRightCenter = 34
|
||||
AlignTopCenter = 20
|
||||
AlignBottomCenter = 24
|
||||
AlignCenter = 48
|
||||
KeyCodeDescs = {
|
||||
[KeyUnknown] = 'Unknown',
|
||||
[KeyEscape] = 'Escape',
|
||||
[KeyTab] = 'Tab',
|
||||
[KeyBackspace] = 'Backspace',
|
||||
[KeyReturn] = 'Return',
|
||||
[KeyEnter] = 'Enter',
|
||||
[KeyInsert] = 'Insert',
|
||||
[KeyDelete] = 'Delete',
|
||||
[KeyPause] = 'Pause',
|
||||
[KeyPrintScreen] = 'PrintScreen',
|
||||
[KeyHome] = 'Home',
|
||||
[KeyEnd] = 'End',
|
||||
[KeyPageUp] = 'PageUp',
|
||||
[KeyPageDown] = 'PageDown',
|
||||
[KeyUp] = 'Up',
|
||||
[KeyDown] = 'Down',
|
||||
[KeyLeft] = 'Left',
|
||||
[KeyRight] = 'Right',
|
||||
[KeyNumLock] = 'NumLock',
|
||||
[KeyScrollLock] = 'ScrollLock',
|
||||
[KeyCapsLock] = 'CapsLock',
|
||||
[KeyCtrl] = 'Ctrl',
|
||||
[KeyShift] = 'Shift',
|
||||
[KeyAlt] = 'Alt',
|
||||
[KeyAltGr] = 'AltGr',
|
||||
[KeyMeta] = 'Meta',
|
||||
[KeyMenu] = 'Menu',
|
||||
[KeySpace] = 'Space',
|
||||
[KeyExclamation] = '!',
|
||||
[KeyQuote] = '\"',
|
||||
[KeyNumberSign] = '#',
|
||||
[KeyDollar] = '$',
|
||||
[KeyPercent] = '%',
|
||||
[KeyAmpersand] = '&',
|
||||
[KeyApostrophe] = '\'',
|
||||
[KeyLeftParen] = '(',
|
||||
[KeyRightParen] = ')',
|
||||
[KeyAsterisk] = '*',
|
||||
[KeyPlus] = '+',
|
||||
[KeyComma] = ',',
|
||||
[KeyMinus] = '-',
|
||||
[KeyPeriod] = '.',
|
||||
[KeySlash] = '/',
|
||||
[Key0] = '0',
|
||||
[Key1] = '1',
|
||||
[Key2] = '2',
|
||||
[Key3] = '3',
|
||||
[Key4] = '4',
|
||||
[Key5] = '5',
|
||||
[Key6] = '6',
|
||||
[Key7] = '7',
|
||||
[Key8] = '8',
|
||||
[Key9] = '9',
|
||||
[KeyColon] = ':',
|
||||
[KeySemicolon] = ';',
|
||||
[KeyLess] = '<',
|
||||
[KeyEqual] = '=',
|
||||
[KeyGreater] = '>',
|
||||
[KeyQuestion] = '?',
|
||||
[KeyAtSign] = '@',
|
||||
[KeyA] = 'A',
|
||||
[KeyB] = 'B',
|
||||
[KeyC] = 'C',
|
||||
[KeyD] = 'D',
|
||||
[KeyE] = 'E',
|
||||
[KeyF] = 'F',
|
||||
[KeyG] = 'G',
|
||||
[KeyH] = 'H',
|
||||
[KeyI] = 'I',
|
||||
[KeyJ] = 'J',
|
||||
[KeyK] = 'K',
|
||||
[KeyL] = 'L',
|
||||
[KeyM] = 'M',
|
||||
[KeyN] = 'N',
|
||||
[KeyO] = 'O',
|
||||
[KeyP] = 'P',
|
||||
[KeyQ] = 'Q',
|
||||
[KeyR] = 'R',
|
||||
[KeyS] = 'S',
|
||||
[KeyT] = 'T',
|
||||
[KeyU] = 'U',
|
||||
[KeyV] = 'V',
|
||||
[KeyW] = 'W',
|
||||
[KeyX] = 'X',
|
||||
[KeyY] = 'Y',
|
||||
[KeyZ] = 'Z',
|
||||
[KeyLeftBracket] = '[',
|
||||
[KeyBackslash] = '\\',
|
||||
[KeyRightBracket] = ']',
|
||||
[KeyCaret] = '^',
|
||||
[KeyUnderscore] = '_',
|
||||
[KeyGrave] = '`',
|
||||
[KeyLeftCurly] = '{',
|
||||
[KeyBar] = '|',
|
||||
[KeyRightCurly] = '}',
|
||||
[KeyTilde] = '~',
|
||||
[KeyF1] = 'F1',
|
||||
[KeyF2] = 'F2',
|
||||
[KeyF3] = 'F3',
|
||||
[KeyF4] = 'F4',
|
||||
[KeyF5] = 'F5',
|
||||
[KeyF6] = 'F6',
|
||||
[KeyF7] = 'F7',
|
||||
[KeyF8] = 'F8',
|
||||
[KeyF9] = 'F9',
|
||||
[KeyF10] = 'F10',
|
||||
[KeyF11] = 'F11',
|
||||
[KeyF12] = 'F12'
|
||||
}
|
|
@ -17,3 +17,4 @@ Module
|
|||
require 'dispatcher'
|
||||
require 'effects'
|
||||
require 'settings'
|
||||
require 'hotkeys'
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
function string:split(sep)
|
||||
local t = { }
|
||||
local function helper(word)
|
||||
table.insert(t, word)
|
||||
return ""
|
||||
end
|
||||
if not self:gsub("%w+", helper):find("%S") then
|
||||
return t
|
||||
function string.split(s, delim)
|
||||
local start = 1
|
||||
local results = {}
|
||||
while true do
|
||||
local pos = string.find(s, delim, start, true)
|
||||
if not pos then
|
||||
break
|
||||
end
|
||||
table.insert(results, string.sub(s, start, pos-1))
|
||||
start = pos + string.len(delim)
|
||||
end
|
||||
table.insert(results, string.sub(s, start))
|
||||
table.removevalue(results, '')
|
||||
return results
|
||||
end
|
||||
|
||||
function string:starts(start)
|
||||
return self:sub(1, #start) == start
|
||||
function string.starts(s, start)
|
||||
return string.sub(s, 1, #start) == start
|
||||
end
|
||||
|
||||
function string:trim()
|
||||
return self:match('^%s*(.*%S)') or ''
|
||||
function string.trim(s)
|
||||
return string.match(s, '^%s*(.*%S)') or ''
|
||||
end
|
||||
|
|
|
@ -40,13 +40,17 @@ function table.find(t, value)
|
|||
end
|
||||
|
||||
function table.removevalue(t, value)
|
||||
local queue = {}
|
||||
for k,v in pairs(t) do
|
||||
if v == value then
|
||||
table.insert(queue, k)
|
||||
table.remove(t, k)
|
||||
end
|
||||
end
|
||||
for i,v in pairs(queue) do
|
||||
table.remove(t, i)
|
||||
end
|
||||
end
|
||||
|
||||
function table.compare(t, other)
|
||||
if #t ~= #other then return false end
|
||||
for k,v in pairs(t) do
|
||||
if v ~= other[k] then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -1,6 +1,96 @@
|
|||
Hotkeys = {}
|
||||
|
||||
function Hotkeys.bindKey(keyDesc, func)
|
||||
|
||||
-- private functions
|
||||
local function translateKeyCombo(keyCombo)
|
||||
if not keyCombo or #keyCombo == 0 then return nil end
|
||||
table.sort(keyCombo)
|
||||
local keyComboDesc = ''
|
||||
for k,v in pairs(keyCombo) do
|
||||
local keyDesc = KeyCodeDescs[v]
|
||||
if keyDesc == nil then return nil end
|
||||
keyComboDesc = keyComboDesc .. '+' .. keyDesc
|
||||
end
|
||||
keyComboDesc = keyComboDesc:sub(2)
|
||||
return keyComboDesc
|
||||
end
|
||||
|
||||
local function retranslateKeyComboDesc(keyComboDesc)
|
||||
if keyComboDesc == nil then return nil end
|
||||
local keyCombo = {}
|
||||
for i,currentKeyDesc in ipairs(keyComboDesc:split('+')) do
|
||||
for keyCode, keyDesc in pairs(KeyCodeDescs) do
|
||||
if keyDesc:lower() == currentKeyDesc:trim():lower() then
|
||||
table.insert(keyCombo, keyCode)
|
||||
end
|
||||
end
|
||||
end
|
||||
return translateKeyCombo(keyCombo)
|
||||
end
|
||||
|
||||
local function determineKeyComboDesc(keyCode, keyboardModifiers)
|
||||
local keyCombo = {}
|
||||
if keyCode == KeyShift or keyCode == KeyAlt or keyCode == KeyAltGr then
|
||||
table.insert(keyCombo, keyCode)
|
||||
elseif KeyCodeDescs[keyCode] ~= nil then
|
||||
if keyboardModifiers == KeyboardCtrlModifier then
|
||||
table.insert(keyCombo, KeyCtrl)
|
||||
elseif keyboardModifiers == KeyboardAltModifier then
|
||||
table.insert(keyCombo, KeyAlt)
|
||||
elseif keyboardModifiers == KeyboardCtrlAltModifier then
|
||||
table.insert(keyCombo, KeyCtrl)
|
||||
table.insert(keyCombo, KeyAlt)
|
||||
elseif keyboardModifiers == KeyboardShiftModifier then
|
||||
table.insert(keyCombo, KeyShift)
|
||||
elseif keyboardModifiers == KeyboardCtrlShiftModifier then
|
||||
table.insert(keyCombo, KeyCtrl)
|
||||
table.insert(keyCombo, KeyShift)
|
||||
elseif keyboardModifiers == KeyboardAltShiftModifier then
|
||||
table.insert(keyCombo, KeyAlt)
|
||||
table.insert(keyCombo, KeyShift)
|
||||
elseif keyboardModifiers == KeyboardCtrlAltShiftModifier then
|
||||
table.insert(keyCombo, KeyCtrl)
|
||||
table.insert(keyCombo, KeyAlt)
|
||||
table.insert(keyCombo, KeyShift)
|
||||
end
|
||||
table.insert(keyCombo, keyCode)
|
||||
end
|
||||
table.sort(keyCombo)
|
||||
return translateKeyCombo(keyCombo)
|
||||
end
|
||||
|
||||
local function onWidgetKeyPress(widget, keyCode, keyText, keyboardModifiers)
|
||||
local keyComboDesc = determineKeyComboDesc(keyCode, keyboardModifiers)
|
||||
local callback = widget.boundKeyCombos[keyComboDesc]
|
||||
if callback then
|
||||
callback()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function connectWidgetHotkeyEvent(widget)
|
||||
if widget.boundKeyCombos then return end
|
||||
connect(widget, { onKeyPress = onWidgetKeyPress })
|
||||
widget.boundKeyCombos = {}
|
||||
end
|
||||
|
||||
-- public functions
|
||||
function Hotkeys.bind(keyComboDesc, callback, widget)
|
||||
widget = widget or rootWidget
|
||||
connectWidgetHotkeyEvent(widget)
|
||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||
if keyComboDesc then
|
||||
widget.boundKeyCombos[keyComboDesc] = callback
|
||||
else
|
||||
error('key combo \'' .. keyComboDesc .. '\' is failed')
|
||||
end
|
||||
end
|
||||
|
||||
function Hotkeys.unbind(keyComboDesc, widget)
|
||||
widget = widget or rootWidget
|
||||
if widget.boundKeyCombos == nil then return end
|
||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||
if keyComboDesc then
|
||||
widget.boundKeyCombos[keyComboDesc] = nil
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue