Implement on-screen keyboard element
This commit is contained in:
parent
8d3b351083
commit
3282023edd
215
gfx/keyboard.lua
Normal file
215
gfx/keyboard.lua
Normal file
@ -0,0 +1,215 @@
|
||||
-- On-screen keyboard with hooks for standard key input events
|
||||
|
||||
local List = require("gfx.list")
|
||||
local Padding = require("gfx.padding")
|
||||
local Text = require("gfx.text")
|
||||
local Orientation = require("gfx.prop.orientation")
|
||||
local Children = require("gfx.prop.children")
|
||||
|
||||
local DEFAULT_COLOR_BG = colors.gray
|
||||
local DEFAULT_COLOR_KEY = colors.gray
|
||||
local DEFAULT_PADDING_H = 1
|
||||
local DEFAULT_PADDING_V = 1
|
||||
local HANDLER_IGNORE_CLICK = function() return true end
|
||||
|
||||
local Keyboard = Padding:new{
|
||||
bgColor = DEFAULT_COLOR_BG,
|
||||
keyColor = DEFAULT_COLOR_KEY,
|
||||
left = DEFAULT_PADDING_H,
|
||||
right = DEFAULT_PADDING_H,
|
||||
top = DEFAULT_PADDING_V,
|
||||
bottom = DEFAULT_PADDING_V,
|
||||
onKeyPress = function(key) end,
|
||||
onBackspace = function() end
|
||||
}
|
||||
|
||||
function Keyboard:new(o)
|
||||
local template = o or {}
|
||||
|
||||
if type(template.layout) == "function" then
|
||||
template.layout = template.layout()
|
||||
elseif type(template.layout) ~= "table" then
|
||||
template.layout = Keyboard.Layout.English()
|
||||
end
|
||||
|
||||
template.colorKey = template.colorKey or DEFAULT_COLOR_KEY
|
||||
template.keySlop = not not template.keySlop
|
||||
template.onClick = HANDLER_IGNORE_CLICK
|
||||
template.onKey = function(_, keyCode, _)
|
||||
if keyCode == keys.backspace then
|
||||
template.onBackspace()
|
||||
return true
|
||||
elseif keyCode == keys.enter then
|
||||
template.onKeyPress("\n")
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
template.onChar = function(_, charCode)
|
||||
template.onKeyPress(charCode)
|
||||
return true
|
||||
end
|
||||
|
||||
template.element = List:new{
|
||||
bgColor = template.bgColor,
|
||||
[Orientation:getId()] = Orientation.VERTICAL,
|
||||
[Children:getId()] = {}
|
||||
}
|
||||
|
||||
local obj = Padding.new(self, template)
|
||||
|
||||
self:setLayout(self.layout)
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
function Keyboard:setLayout(layout)
|
||||
self.layout = layout
|
||||
|
||||
local this = self
|
||||
|
||||
local KEY_BACKSPACE = "backspace"
|
||||
local KEY_ENTER = "enter"
|
||||
local function charInputKeyList(chars, backspace, enter, spacebar)
|
||||
local keysEntries = { }
|
||||
for i=1,#chars do
|
||||
local key = chars:sub(i, i)
|
||||
local keyFunc = function()
|
||||
this.onKeyPress(key)
|
||||
return true
|
||||
end
|
||||
local keySlopFunc = this.keySlop and keyFunc or HANDLER_IGNORE_CLICK
|
||||
|
||||
-- ((not backspace) and i == #keys and 0) or 1
|
||||
table.insert(keysEntries, Padding:new{ onClick = keySlopFunc, bgColor = this.bgColor, right = 1, element = Text:new{
|
||||
id = key,
|
||||
text = key,
|
||||
bgColor = this.colorKey,
|
||||
onClick = keyFunc
|
||||
}})
|
||||
end
|
||||
if enter then
|
||||
table.insert(keysEntries, Text:new{
|
||||
id = KEY_ENTER,
|
||||
text = "[<]",
|
||||
bgColor = this.colorKey,
|
||||
onClick = function()
|
||||
this.onKeyPress("\n")
|
||||
return true
|
||||
end
|
||||
})
|
||||
end
|
||||
if backspace then
|
||||
table.insert(keysEntries, Text:new{
|
||||
id = KEY_BACKSPACE,
|
||||
text = "[x]",
|
||||
bgColor = this.colorKey,
|
||||
onClick = function()
|
||||
this.onBackspace()
|
||||
return true
|
||||
end
|
||||
})
|
||||
end
|
||||
if spacebar then
|
||||
table.insert(keysEntries, Text:new{
|
||||
id = " ",
|
||||
text = "[SPACE]",
|
||||
bgColor = this.colorKey,
|
||||
onClick = function()
|
||||
this.onKeyPress(" ")
|
||||
return true
|
||||
end
|
||||
})
|
||||
end
|
||||
return List:new{
|
||||
bgColor = this.colorBg,
|
||||
[Orientation:getId()] = Orientation.HORIZONTAL,
|
||||
[Children:getId()] = keysEntries
|
||||
}
|
||||
end
|
||||
|
||||
local keyboardLines = {}
|
||||
for _,line in ipairs(this.layout) do
|
||||
local keyLineList = charInputKeyList(line[1], line.backspace, line.enter)
|
||||
table.insert(keyboardLines, keyLineList)
|
||||
end
|
||||
|
||||
self.element[Children:getId()] = keyboardLines
|
||||
self.setDirty()
|
||||
end
|
||||
|
||||
function Keyboard:setKeyColor(color)
|
||||
if color ~= self.keyColor then
|
||||
self.keyColor = color
|
||||
self:setDirty()
|
||||
end
|
||||
end
|
||||
|
||||
local function layoutNumbers(layout)
|
||||
table.insert(layout, 1, { "1234567890" })
|
||||
return layout
|
||||
end
|
||||
|
||||
local function layoutEnter(rowIndex, layout)
|
||||
for index,layoutRow in pairs(layout) do
|
||||
if index == rowIndex then
|
||||
layoutRow.enter = true
|
||||
else
|
||||
layoutRow.enter = nil
|
||||
end
|
||||
end
|
||||
return layout
|
||||
end
|
||||
|
||||
local function layoutBackspace(rowIndex, layout)
|
||||
for index,layoutRow in pairs(layout) do
|
||||
if index == rowIndex then
|
||||
layoutRow.backspace = true
|
||||
else
|
||||
layoutRow.backspace = nil
|
||||
end
|
||||
end
|
||||
return layout
|
||||
end
|
||||
|
||||
local function layoutSpacebar(layout)
|
||||
table.insert(layout, { spacebar = true, "" })
|
||||
return layout
|
||||
end
|
||||
|
||||
local function appendNumberLayout(cond, layout)
|
||||
return cond and layoutNumbers(layout) or layout
|
||||
end
|
||||
|
||||
Keyboard.Layout = {
|
||||
ItemSearch = function()
|
||||
return layoutBackspace(1, layoutNumbers({
|
||||
{ "qwertyuiop" },
|
||||
{ "asdfghjkl" },
|
||||
{ "zxcvbnm_:" }
|
||||
}))
|
||||
end,
|
||||
English = function(numberRow)
|
||||
return layoutSpacebar(layoutBackspace(1, appendNumberLayout(numberRow, layoutEnter(2, {
|
||||
{ "qwertyuiop" },
|
||||
{ "asdfghjkl" },
|
||||
{ "zxcvbnm" }
|
||||
}))))
|
||||
end,
|
||||
Swedish = function(numberRow)
|
||||
return layoutSpacebar(layoutBackspace(1, appendNumberLayout(numberRow, layoutEnter(2, {
|
||||
{ "qwertyuiopå" },
|
||||
{ "asdfghjklöä" },
|
||||
{ "zxcvbnm" }
|
||||
}))))
|
||||
end,
|
||||
Special = function(numberRow)
|
||||
return layoutSpacebar(layoutBackspace(1, appendNumberLayout(numberRow, {
|
||||
{ "!\"#¤%&/()=?" },
|
||||
{ "@£${[]}\\+^" },
|
||||
{ "§<>|;:,.-_'*" }
|
||||
})))
|
||||
end
|
||||
}
|
||||
|
||||
return Keyboard
|
@ -1,3 +1,5 @@
|
||||
-- TODO: Rename to "Column" to better represent functionality
|
||||
|
||||
local Event = require("gfx.event")
|
||||
local Element = require("gfx.element")
|
||||
local Prop = require("gfx.prop")
|
||||
|
Loading…
x
Reference in New Issue
Block a user