mirror of
https://github.com/koreader/koreader
synced 2024-10-31 21:20:20 +00:00
6a1fa7f612
also changed keyboard mode for number to 4
283 lines
8.7 KiB
Lua
283 lines
8.7 KiB
Lua
local InputContainer = require("ui/widget/container/inputcontainer")
|
|
local FrameContainer = require("ui/widget/container/framecontainer")
|
|
local CenterContainer = require("ui/widget/container/centercontainer")
|
|
local BottomContainer = require("ui/widget/container/bottomcontainer")
|
|
local HorizontalSpan = require("ui/widget/horizontalspan")
|
|
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
|
local VerticalSpan = require("ui/widget/verticalspan")
|
|
local VerticalGroup = require("ui/widget/verticalgroup")
|
|
local ImageWidget = require("ui/widget/imagewidget")
|
|
local TextWidget = require("ui/widget/textwidget")
|
|
local Font = require("ui/font")
|
|
local Geom = require("ui/geometry")
|
|
local Device = require("device")
|
|
local Screen = Device.screen
|
|
local GestureRange = require("ui/gesturerange")
|
|
local UIManager = require("ui/uimanager")
|
|
local DEBUG = require("dbg")
|
|
local Blitbuffer = require("ffi/blitbuffer")
|
|
|
|
local VirtualKey = InputContainer:new{
|
|
key = nil,
|
|
icon = nil,
|
|
label = nil,
|
|
|
|
keyboard = nil,
|
|
callback = nil,
|
|
|
|
width = nil,
|
|
height = math.max(Screen:getWidth(), Screen:getHeight())*0.33,
|
|
bordersize = 2,
|
|
face = Font:getFace("infont", 22),
|
|
}
|
|
|
|
function VirtualKey:init()
|
|
if self.label == "Sym" or self.label == "ABC" then
|
|
self.callback = function () self.keyboard:setLayout(self.key or self.label) end
|
|
elseif self.label == "Shift" then
|
|
self.callback = function () self.keyboard:setLayout(self.key or self.label) end
|
|
elseif self.label == "IM" then
|
|
self.callback = function () self.keyboard:setLayout(self.key or self.label) end
|
|
elseif self.label == "Äéß" then
|
|
self.callback = function () self.keyboard:setLayout(self.key or self.label) end
|
|
elseif self.label == "Backspace" then
|
|
self.callback = function () self.keyboard:delChar() end
|
|
self.hold_callback = function () self.keyboard:clear() end
|
|
else
|
|
self.callback = function () self.keyboard:addChar(self.key) end
|
|
end
|
|
|
|
local label_widget
|
|
if self.icon then
|
|
label_widget = ImageWidget:new{
|
|
file = self.icon,
|
|
}
|
|
else
|
|
label_widget = TextWidget:new{
|
|
text = self.label,
|
|
face = self.face,
|
|
}
|
|
end
|
|
self[1] = FrameContainer:new{
|
|
margin = 0,
|
|
bordersize = self.bordersize,
|
|
background = Blitbuffer.COLOR_WHITE,
|
|
radius = 5,
|
|
padding = 0,
|
|
CenterContainer:new{
|
|
dimen = Geom:new{
|
|
w = self.width - 2*self.bordersize,
|
|
h = self.height - 2*self.bordersize,
|
|
},
|
|
label_widget,
|
|
},
|
|
}
|
|
self.dimen = Geom:new{
|
|
w = self.width,
|
|
h = self.height,
|
|
}
|
|
--self.dimen = self[1]:getSize()
|
|
if Device:isTouchDevice() then
|
|
self.ges_events = {
|
|
TapSelect = {
|
|
GestureRange:new{
|
|
ges = "tap",
|
|
range = self.dimen,
|
|
},
|
|
},
|
|
HoldSelect = {
|
|
GestureRange:new{
|
|
ges = "hold",
|
|
range = self.dimen,
|
|
},
|
|
},
|
|
}
|
|
end
|
|
end
|
|
|
|
function VirtualKey:update_keyboard()
|
|
UIManager:setDirty(self.keyboard, function()
|
|
DEBUG("update key region", self[1].dimen)
|
|
return "ui", self[1].dimen
|
|
end)
|
|
end
|
|
|
|
function VirtualKey:onTapSelect()
|
|
self[1].invert = true
|
|
self:update_keyboard()
|
|
if self.callback then
|
|
self.callback()
|
|
end
|
|
UIManager:scheduleIn(0.2, function() self:invert(false) end)
|
|
return true
|
|
end
|
|
|
|
function VirtualKey:onHoldSelect()
|
|
self[1].invert = true
|
|
self:update_keyboard()
|
|
if self.hold_callback then
|
|
self.hold_callback()
|
|
end
|
|
UIManager:scheduleIn(0.2, function() self:invert(false) end)
|
|
return true
|
|
end
|
|
|
|
function VirtualKey:invert(invert)
|
|
self[1].invert = invert
|
|
self:update_keyboard()
|
|
end
|
|
|
|
local VirtualKeyboard = InputContainer:new{
|
|
is_always_active = true,
|
|
disable_double_tap = true,
|
|
inputbox = nil,
|
|
KEYS = {}, -- table to store layouts
|
|
min_layout = 2,
|
|
max_layout = 12,
|
|
layout = 2,
|
|
shiftmode = false,
|
|
symbolmode = false,
|
|
utf8mode = false,
|
|
umlautmode = false,
|
|
|
|
width = Screen:scaleBySize(600),
|
|
height = Screen:scaleBySize(256),
|
|
bordersize = 2,
|
|
padding = 2,
|
|
key_padding = Screen:scaleBySize(6),
|
|
}
|
|
|
|
local keyboard_layout = require("ui/data/keyboardlayouts/std")
|
|
function VirtualKeyboard:init()
|
|
self.KEYS = keyboard_layout
|
|
self:initLayout(self.layout)
|
|
end
|
|
|
|
function VirtualKeyboard:_refresh()
|
|
-- TODO: Ideally, ui onShow & partial onClose
|
|
UIManager:setDirty(self, function()
|
|
return "partial", self[1][1].dimen
|
|
end)
|
|
end
|
|
|
|
function VirtualKeyboard:onShow()
|
|
self:_refresh()
|
|
return true
|
|
end
|
|
|
|
function VirtualKeyboard:onCloseWidget()
|
|
self:_refresh()
|
|
return true
|
|
end
|
|
|
|
function VirtualKeyboard:initLayout(layout)
|
|
local function VKLayout(b1, b2, b3, b4)
|
|
local function boolnum(bool)
|
|
return bool and 1 or 0
|
|
end
|
|
return 2 - boolnum(b1) + 2 * boolnum(b2) + 4 * boolnum(b3) + 8 * boolnum(b4)
|
|
end
|
|
|
|
if layout then
|
|
-- to be sure layout is selected properly
|
|
layout = math.max(layout, self.min_layout)
|
|
layout = math.min(layout, self.max_layout)
|
|
self.layout = layout
|
|
-- fill the layout modes
|
|
self.shiftmode = (layout == 1 or layout == 3 or layout == 5 or layout == 7 or layout == 9 or layout == 11)
|
|
self.symbolmode = (layout == 3 or layout == 4 or layout == 7 or layout == 8 or layout == 11 or layout == 12)
|
|
self.utf8mode = (layout == 5 or layout == 6 or layout == 7 or layout == 8)
|
|
self.umlautmode = (layout == 9 or layout == 10 or layout == 11 or layout == 12)
|
|
else -- or, without input parameter, restore layout from current layout modes
|
|
self.layout = VKLayout(self.shiftmode, self.symbolmode, self.utf8mode, self.umlautmode)
|
|
end
|
|
self:addKeys()
|
|
end
|
|
|
|
function VirtualKeyboard:addKeys()
|
|
local base_key_width = math.floor((self.width - 11*self.key_padding - 2*self.padding)/10)
|
|
local base_key_height = math.floor((self.height - 5*self.key_padding - 2*self.padding)/4)
|
|
local h_key_padding = HorizontalSpan:new{width = self.key_padding}
|
|
local v_key_padding = VerticalSpan:new{width = self.key_padding}
|
|
local vertical_group = VerticalGroup:new{}
|
|
for i = 1, #self.KEYS do
|
|
local horizontal_group = HorizontalGroup:new{}
|
|
for j = 1, #self.KEYS[i] do
|
|
local width_factor = self.KEYS[i][j].width or 1.0
|
|
local key_width = math.floor((base_key_width + self.key_padding) * width_factor)
|
|
- self.key_padding
|
|
local key_height = base_key_height
|
|
local label = self.KEYS[i][j].label or self.KEYS[i][j][self.layout]
|
|
local key = VirtualKey:new{
|
|
key = self.KEYS[i][j][self.layout],
|
|
icon = self.KEYS[i][j].icon,
|
|
label = label,
|
|
keyboard = self,
|
|
width = key_width,
|
|
height = key_height,
|
|
}
|
|
table.insert(horizontal_group, key)
|
|
if j ~= #self.KEYS[i] then
|
|
table.insert(horizontal_group, h_key_padding)
|
|
end
|
|
end
|
|
table.insert(vertical_group, horizontal_group)
|
|
if i ~= #self.KEYS then
|
|
table.insert(vertical_group, v_key_padding)
|
|
end
|
|
end
|
|
|
|
local keyboard_frame = FrameContainer:new{
|
|
margin = 0,
|
|
bordersize = self.bordersize,
|
|
background = Blitbuffer.COLOR_WHITE,
|
|
radius = 0,
|
|
padding = self.padding,
|
|
CenterContainer:new{
|
|
dimen = Geom:new{
|
|
w = self.width - 2*self.bordersize -2*self.padding,
|
|
h = self.height - 2*self.bordersize -2*self.padding,
|
|
},
|
|
vertical_group,
|
|
}
|
|
}
|
|
self[1] = BottomContainer:new{
|
|
dimen = Screen:getSize(),
|
|
keyboard_frame,
|
|
}
|
|
self.dimen = keyboard_frame:getSize()
|
|
end
|
|
|
|
function VirtualKeyboard:setLayout(key)
|
|
if key == "Shift" then
|
|
self.shiftmode = not self.shiftmode
|
|
elseif key == "Sym" or key == "ABC" then
|
|
self.symbolmode = not self.symbolmode
|
|
elseif key == "Äéß" then
|
|
self.umlautmode = not self.umlautmode
|
|
if self.umlautmode then self.utf8mode = false end
|
|
elseif key == "IM" then
|
|
self.utf8mode = not self.utf8mode
|
|
if self.utf8mode then self.umlautmode = false end
|
|
end
|
|
self:initLayout()
|
|
self:_refresh()
|
|
end
|
|
|
|
function VirtualKeyboard:addChar(key)
|
|
DEBUG("add char", key)
|
|
self.inputbox:addChar(key)
|
|
end
|
|
|
|
function VirtualKeyboard:delChar()
|
|
DEBUG("delete char")
|
|
self.inputbox:delChar()
|
|
end
|
|
|
|
function VirtualKeyboard:clear()
|
|
DEBUG("clear input")
|
|
self.inputbox:clear()
|
|
end
|
|
|
|
return VirtualKeyboard
|