2017-04-29 08:38:09 +00:00
|
|
|
local Blitbuffer = require("ffi/blitbuffer")
|
2017-08-14 19:42:15 +00:00
|
|
|
local CheckButton = require("ui/widget/checkbutton")
|
2017-04-29 08:38:09 +00:00
|
|
|
local Device = require("device")
|
2016-01-31 22:56:05 +00:00
|
|
|
local FrameContainer = require("ui/widget/container/framecontainer")
|
2017-04-29 08:38:09 +00:00
|
|
|
local Font = require("ui/font")
|
|
|
|
local GestureRange = require("ui/gesturerange")
|
|
|
|
local InputContainer = require("ui/widget/container/inputcontainer")
|
2013-10-18 20:38:07 +00:00
|
|
|
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
|
|
|
|
local TextBoxWidget = require("ui/widget/textboxwidget")
|
|
|
|
local UIManager = require("ui/uimanager")
|
2017-08-14 19:42:15 +00:00
|
|
|
local VerticalGroup = require("ui/widget/verticalgroup")
|
2016-04-21 14:13:10 +00:00
|
|
|
local util = require("util")
|
2017-08-14 19:42:15 +00:00
|
|
|
local _ = require("gettext")
|
|
|
|
local Screen = Device.screen
|
2017-04-29 08:38:09 +00:00
|
|
|
|
2016-01-31 22:56:05 +00:00
|
|
|
local Keyboard
|
2013-07-30 15:07:33 +00:00
|
|
|
|
2013-10-18 20:38:07 +00:00
|
|
|
local InputText = InputContainer:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
text = "",
|
|
|
|
hint = "demo hint",
|
2016-05-22 15:59:28 +00:00
|
|
|
charlist = nil, -- table to store input string
|
2016-04-21 14:13:10 +00:00
|
|
|
charpos = nil, -- position to insert a new char, or the position of the cursor
|
2014-03-13 13:52:43 +00:00
|
|
|
input_type = nil,
|
2014-04-23 14:19:29 +00:00
|
|
|
text_type = nil,
|
2016-05-15 09:18:38 +00:00
|
|
|
text_widget = nil, -- Text Widget for cursor movement
|
2017-08-14 19:42:15 +00:00
|
|
|
show_password_toggle = true,
|
2014-04-23 14:19:29 +00:00
|
|
|
|
2014-03-13 13:52:43 +00:00
|
|
|
width = nil,
|
|
|
|
height = nil,
|
2017-04-29 08:38:09 +00:00
|
|
|
face = Font:getFace("smallinfofont"),
|
2014-04-23 14:19:29 +00:00
|
|
|
|
2017-08-14 19:42:15 +00:00
|
|
|
padding = Screen:scaleBySize(5),
|
|
|
|
margin = Screen:scaleBySize(5),
|
|
|
|
bordersize = Screen:scaleBySize(2),
|
2014-04-23 14:19:29 +00:00
|
|
|
|
2014-03-13 13:52:43 +00:00
|
|
|
parent = nil, -- parent dialog that will be set dirty
|
|
|
|
scroll = false,
|
2014-04-23 14:19:29 +00:00
|
|
|
focused = true,
|
2013-07-30 15:07:33 +00:00
|
|
|
}
|
|
|
|
|
2016-01-31 22:56:05 +00:00
|
|
|
-- only use PhysicalKeyboard if the device does not have touch screen
|
|
|
|
if Device.isTouchDevice() then
|
|
|
|
Keyboard = require("ui/widget/virtualkeyboard")
|
|
|
|
function InputText:initEventListener()
|
2014-04-23 14:19:29 +00:00
|
|
|
self.ges_events = {
|
|
|
|
TapTextBox = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "tap",
|
|
|
|
range = self.dimen
|
|
|
|
}
|
2018-02-17 05:31:32 +00:00
|
|
|
},
|
|
|
|
HoldTextBox = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "hold",
|
|
|
|
range = self.dimen
|
|
|
|
}
|
|
|
|
},
|
2014-04-23 14:19:29 +00:00
|
|
|
}
|
|
|
|
end
|
2016-01-31 22:56:05 +00:00
|
|
|
|
2016-04-21 14:13:10 +00:00
|
|
|
function InputText:onTapTextBox(arg, ges)
|
2016-01-31 22:56:05 +00:00
|
|
|
if self.parent.onSwitchFocus then
|
|
|
|
self.parent:onSwitchFocus(self)
|
2016-06-25 17:27:23 +00:00
|
|
|
end
|
2017-08-14 19:42:15 +00:00
|
|
|
local x = ges.pos.x - self._frame_textwidget.dimen.x - self.bordersize - self.padding
|
|
|
|
local y = ges.pos.y - self._frame_textwidget.dimen.y - self.bordersize - self.padding
|
2016-06-25 17:27:23 +00:00
|
|
|
if x > 0 and y > 0 then
|
|
|
|
self.charpos = self.text_widget:moveCursor(x, y)
|
|
|
|
UIManager:setDirty(self.parent, function()
|
2017-08-20 19:39:00 +00:00
|
|
|
return "ui", self.dimen
|
2016-06-25 17:27:23 +00:00
|
|
|
end)
|
2016-01-31 22:56:05 +00:00
|
|
|
end
|
|
|
|
end
|
2018-02-17 05:31:32 +00:00
|
|
|
|
|
|
|
function InputText:onHoldTextBox(arg, ges)
|
|
|
|
if self.parent.onSwitchFocus then
|
|
|
|
self.parent:onSwitchFocus(self)
|
|
|
|
end
|
|
|
|
local x = ges.pos.x - self._frame_textwidget.dimen.x - self.bordersize - self.padding
|
|
|
|
local y = ges.pos.y - self._frame_textwidget.dimen.y - self.bordersize - self.padding
|
|
|
|
if x > 0 and y > 0 then
|
|
|
|
self.charpos = self.text_widget:moveCursor(x, y)
|
|
|
|
if Device:hasClipboard() and Device.input.hasClipboardText() then
|
|
|
|
self:addChar(Device.input.getClipboardText())
|
|
|
|
end
|
|
|
|
UIManager:setDirty(self.parent, function()
|
|
|
|
return "ui", self.dimen
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
2016-01-31 22:56:05 +00:00
|
|
|
else
|
|
|
|
Keyboard = require("ui/widget/physicalkeyboard")
|
|
|
|
function InputText:initEventListener() end
|
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:init()
|
|
|
|
self:initTextBox(self.text)
|
2017-12-17 17:27:24 +00:00
|
|
|
if self.readonly ~= true then
|
|
|
|
self:initKeyboard()
|
|
|
|
self:initEventListener()
|
|
|
|
end
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
2017-08-14 19:42:15 +00:00
|
|
|
function InputText:initTextBox(text, char_added, is_password_type)
|
2014-09-10 07:30:59 +00:00
|
|
|
self.text = text
|
2017-08-14 19:42:15 +00:00
|
|
|
if self.text_type == "password" then
|
|
|
|
is_password_type = true
|
|
|
|
end
|
2016-06-26 00:53:08 +00:00
|
|
|
local fgcolor
|
|
|
|
local show_charlist
|
|
|
|
local show_text = text
|
|
|
|
if show_text == "" or show_text == nil then
|
|
|
|
-- no preset value, use hint text if set
|
2016-06-25 17:27:23 +00:00
|
|
|
show_text = self.hint
|
2016-06-26 00:53:08 +00:00
|
|
|
fgcolor = Blitbuffer.COLOR_GREY
|
|
|
|
self.charlist = {}
|
|
|
|
self.charpos = 1
|
|
|
|
else
|
|
|
|
fgcolor = Blitbuffer.COLOR_BLACK
|
|
|
|
if self.text_type == "password" then
|
|
|
|
show_text = self.text:gsub(
|
|
|
|
"(.-).", function() return "*" end)
|
2017-03-30 22:32:01 +00:00
|
|
|
if char_added then
|
|
|
|
show_text = show_text:gsub(
|
|
|
|
"(.)$", function() return self.text:sub(-1) end)
|
|
|
|
end
|
2016-06-26 00:53:08 +00:00
|
|
|
end
|
|
|
|
self.charlist = util.splitToChars(text)
|
|
|
|
if self.charpos == nil then
|
|
|
|
self.charpos = #self.charlist + 1
|
|
|
|
end
|
2014-04-23 14:19:29 +00:00
|
|
|
end
|
2017-08-14 19:42:15 +00:00
|
|
|
if is_password_type and self.show_password_toggle then
|
|
|
|
self._check_button = self._check_button or CheckButton:new{
|
|
|
|
text = _("Show password"),
|
|
|
|
callback = function()
|
|
|
|
if self.text_type == "text" then
|
|
|
|
self.text_type = "password"
|
|
|
|
self._check_button:unCheck()
|
|
|
|
else
|
|
|
|
self.text_type = "text"
|
|
|
|
self._check_button:check()
|
|
|
|
end
|
|
|
|
self:setText(self:getText(), is_password_type)
|
|
|
|
end,
|
|
|
|
|
|
|
|
width = self.width,
|
|
|
|
height = self.height,
|
|
|
|
|
|
|
|
padding = self.padding,
|
|
|
|
margin = self.margin,
|
|
|
|
bordersize = self.bordersize,
|
|
|
|
}
|
|
|
|
self._password_toggle = FrameContainer:new{
|
|
|
|
bordersize = 0,
|
|
|
|
padding = self.padding,
|
|
|
|
margin = self.margin,
|
|
|
|
self._check_button,
|
|
|
|
}
|
|
|
|
else
|
|
|
|
self._password_toggle = nil
|
|
|
|
end
|
2016-06-26 00:53:08 +00:00
|
|
|
show_charlist = util.splitToChars(show_text)
|
2014-03-13 13:52:43 +00:00
|
|
|
if self.scroll then
|
2016-04-21 14:13:10 +00:00
|
|
|
self.text_widget = ScrollTextWidget:new{
|
2014-04-23 14:19:29 +00:00
|
|
|
text = show_text,
|
2016-06-26 00:53:08 +00:00
|
|
|
charlist = show_charlist,
|
2016-05-15 09:18:38 +00:00
|
|
|
charpos = self.charpos,
|
2016-06-25 17:27:23 +00:00
|
|
|
editable = self.focused,
|
2014-03-13 13:52:43 +00:00
|
|
|
face = self.face,
|
|
|
|
fgcolor = fgcolor,
|
|
|
|
width = self.width,
|
|
|
|
height = self.height,
|
2017-04-02 06:50:24 +00:00
|
|
|
dialog = self.parent,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
else
|
2016-04-21 14:13:10 +00:00
|
|
|
self.text_widget = TextBoxWidget:new{
|
2014-04-23 14:19:29 +00:00
|
|
|
text = show_text,
|
2016-06-26 00:53:08 +00:00
|
|
|
charlist = show_charlist,
|
2016-05-15 09:18:38 +00:00
|
|
|
charpos = self.charpos,
|
2016-06-25 17:27:23 +00:00
|
|
|
editable = self.focused,
|
2014-03-13 13:52:43 +00:00
|
|
|
face = self.face,
|
|
|
|
fgcolor = fgcolor,
|
|
|
|
width = self.width,
|
|
|
|
height = self.height,
|
|
|
|
}
|
|
|
|
end
|
2017-08-14 19:42:15 +00:00
|
|
|
self._frame_textwidget = FrameContainer:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
bordersize = self.bordersize,
|
|
|
|
padding = self.padding,
|
|
|
|
margin = self.margin,
|
2016-06-09 05:26:30 +00:00
|
|
|
color = self.focused and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_GREY,
|
2016-04-21 14:13:10 +00:00
|
|
|
self.text_widget,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
2017-08-14 19:42:15 +00:00
|
|
|
self._verticalgroup = VerticalGroup:new{
|
|
|
|
align = "left",
|
|
|
|
self._frame_textwidget,
|
|
|
|
self._password_toggle,
|
|
|
|
}
|
|
|
|
self._frame = FrameContainer:new{
|
|
|
|
bordersize = 0,
|
|
|
|
margin = 0,
|
|
|
|
padding = 0,
|
|
|
|
self._verticalgroup,
|
|
|
|
}
|
|
|
|
self[1] = self._frame
|
|
|
|
self.dimen = self._frame:getSize()
|
|
|
|
-- FIXME: self.parent is not always in the widget stack (BookStatusWidget)
|
2014-12-01 14:39:41 +00:00
|
|
|
UIManager:setDirty(self.parent, function()
|
2017-08-14 19:42:15 +00:00
|
|
|
return "ui", self.dimen
|
2014-12-01 14:39:41 +00:00
|
|
|
end)
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:initKeyboard()
|
2014-03-13 13:52:43 +00:00
|
|
|
local keyboard_layout = 2
|
|
|
|
if self.input_type == "number" then
|
2016-05-27 06:16:15 +00:00
|
|
|
keyboard_layout = 4
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
2016-01-31 22:56:05 +00:00
|
|
|
self.keyboard = Keyboard:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
layout = keyboard_layout,
|
|
|
|
inputbox = self,
|
|
|
|
width = Screen:getWidth(),
|
|
|
|
}
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
2014-04-23 14:19:29 +00:00
|
|
|
function InputText:unfocus()
|
|
|
|
self.focused = false
|
2016-06-25 17:27:23 +00:00
|
|
|
self.text_widget:unfocus()
|
2016-06-09 05:26:30 +00:00
|
|
|
self[1].color = Blitbuffer.COLOR_GREY
|
2014-04-23 14:19:29 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:focus()
|
|
|
|
self.focused = true
|
2016-06-25 17:27:23 +00:00
|
|
|
self.text_widget:focus()
|
2014-10-22 13:34:11 +00:00
|
|
|
self[1].color = Blitbuffer.COLOR_BLACK
|
2014-04-23 14:19:29 +00:00
|
|
|
end
|
|
|
|
|
2013-07-30 15:07:33 +00:00
|
|
|
function InputText:onShowKeyboard()
|
2014-03-13 13:52:43 +00:00
|
|
|
UIManager:show(self.keyboard)
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:onCloseKeyboard()
|
2014-03-13 13:52:43 +00:00
|
|
|
UIManager:close(self.keyboard)
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:getKeyboardDimen()
|
2014-03-13 13:52:43 +00:00
|
|
|
return self.keyboard.dimen
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:addChar(char)
|
2014-03-13 13:52:43 +00:00
|
|
|
if self.enter_callback and char == '\n' then
|
|
|
|
UIManager:scheduleIn(0.3, function() self.enter_callback() end)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
table.insert(self.charlist, self.charpos, char)
|
2018-02-17 05:31:32 +00:00
|
|
|
self.charpos = self.charpos + string.len(char)
|
2017-03-30 22:32:01 +00:00
|
|
|
self:initTextBox(table.concat(self.charlist), true)
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:delChar()
|
2014-03-13 13:52:43 +00:00
|
|
|
if self.charpos == 1 then return end
|
|
|
|
self.charpos = self.charpos - 1
|
|
|
|
table.remove(self.charlist, self.charpos)
|
2014-09-10 07:30:59 +00:00
|
|
|
self:initTextBox(table.concat(self.charlist))
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
2017-10-10 16:04:51 +00:00
|
|
|
function InputText:leftChar()
|
|
|
|
if self.charpos == 1 then return end
|
|
|
|
self.charpos = self.charpos -1
|
|
|
|
self:initTextBox(table.concat(self.charlist))
|
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:rightChar()
|
|
|
|
if self.charpos > #table.concat(self.charlist) then return end
|
|
|
|
self.charpos = self.charpos +1
|
|
|
|
self:initTextBox(table.concat(self.charlist))
|
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:upLine()
|
|
|
|
if self.text_widget.moveCursorUp then
|
|
|
|
self.text_widget:moveCursorUp()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function InputText:downLine()
|
|
|
|
if self.text_widget.moveCursorDown then
|
|
|
|
self.text_widget:moveCursorDown()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-20 06:45:38 +00:00
|
|
|
function InputText:clear()
|
2016-06-26 14:43:40 +00:00
|
|
|
self.charpos = nil
|
2014-09-10 07:30:59 +00:00
|
|
|
self:initTextBox("")
|
2014-11-30 00:12:00 +00:00
|
|
|
UIManager:setDirty(self.parent, function()
|
2014-12-01 14:39:41 +00:00
|
|
|
return "ui", self[1][1].dimen
|
2014-11-30 00:12:00 +00:00
|
|
|
end)
|
2014-08-20 06:45:38 +00:00
|
|
|
end
|
|
|
|
|
2013-07-30 15:07:33 +00:00
|
|
|
function InputText:getText()
|
2014-03-13 13:52:43 +00:00
|
|
|
return self.text
|
2013-07-30 15:07:33 +00:00
|
|
|
end
|
|
|
|
|
2017-08-14 19:42:15 +00:00
|
|
|
function InputText:setText(text, is_password_type)
|
2016-06-25 17:27:23 +00:00
|
|
|
self.charpos = nil
|
2017-08-14 19:42:15 +00:00
|
|
|
self:initTextBox(text, nil, is_password_type)
|
2014-11-30 00:12:00 +00:00
|
|
|
UIManager:setDirty(self.parent, function()
|
2014-12-01 14:39:41 +00:00
|
|
|
return "partial", self[1].dimen
|
2014-11-30 00:12:00 +00:00
|
|
|
end)
|
2013-08-21 11:54:46 +00:00
|
|
|
end
|
|
|
|
|
2013-10-18 20:38:07 +00:00
|
|
|
return InputText
|