mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
VirtualKeyboard: Revamp visibility handling (#10852)
Move as much of the state tracking as possible inside VirtualKeyboard itself. InputDialog unfortunately needs an internal tracking of this state because it needs to know about it *before* the VK is shown, so we have to keep a bit of duplication in there, although we do try much harder to keep everything in sync (at least at function call edges), and to keep the damage contained to, essentially, the toggle button's handler. (Followup to #10803 & #10850)
This commit is contained in:
@@ -32,9 +32,8 @@ local InputText = InputContainer:extend{
|
||||
focused = true,
|
||||
parent = nil, -- parent dialog that will be set dirty
|
||||
edit_callback = nil, -- called with true when text modified, false on init or text re-set
|
||||
scroll_callback = nil, -- called with (low, high) when view is scrolled (cf ScrollTextWidget)
|
||||
scroll_callback = nil, -- called with (low, high) when view is scrolled (c.f., ScrollTextWidget)
|
||||
scroll_by_pan = false, -- allow scrolling by lines with Pan (needs scroll=true)
|
||||
manage_keyboard_state = true, -- manage keyboard hidden/shown state
|
||||
|
||||
width = nil,
|
||||
height = nil, -- when nil, will be set to original text height (possibly
|
||||
@@ -54,7 +53,10 @@ local InputText = InputContainer:extend{
|
||||
auto_para_direction = false,
|
||||
alignment_strict = false,
|
||||
|
||||
readonly = nil, -- will not support a Keyboard widget if true
|
||||
|
||||
-- for internal use
|
||||
keyboard = nil, -- Keyboard widget (either VirtualKeyboard or PhysicalKeyboard)
|
||||
text_widget = nil, -- Text Widget for cursor movement, possibly a ScrollTextWidget
|
||||
charlist = nil, -- table of individual chars from input string
|
||||
charpos = nil, -- position of the cursor, where a new char would be inserted
|
||||
@@ -65,7 +67,6 @@ local InputText = InputContainer:extend{
|
||||
for_measurement_only = nil, -- When the widget is a one-off used to compute text height
|
||||
do_select = false, -- to start text selection
|
||||
selection_start_pos = nil, -- selection start position
|
||||
is_keyboard_hidden = true, -- to be able to show the keyboard again when it was hidden. (On init, it's the caller's responsibility to call onShowKeyboard, as far as we're concerned, it's hidden)
|
||||
}
|
||||
|
||||
-- These may be (internally) overloaded as needed, depending on Device capabilities.
|
||||
@@ -73,6 +74,11 @@ function InputText:initEventListener() end
|
||||
function InputText:onFocus() end
|
||||
function InputText:onUnfocus() end
|
||||
|
||||
-- Resync our position state with our text widget's actual state
|
||||
function InputText:resyncPos()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
end
|
||||
|
||||
local function initTouchEvents()
|
||||
if Device:isTouchDevice() then
|
||||
function InputText:initEventListener()
|
||||
@@ -133,8 +139,8 @@ local function initTouchEvents()
|
||||
if self.parent.onSwitchFocus then
|
||||
self.parent:onSwitchFocus(self)
|
||||
else
|
||||
if self.is_keyboard_hidden and self.manage_keyboard_state then
|
||||
self:onShowKeyboard()
|
||||
if self.keyboard then
|
||||
self.keyboard:showKeyboard()
|
||||
end
|
||||
end
|
||||
-- zh keyboard with candidates shown here has _frame_textwidget.dimen = nil.
|
||||
@@ -144,7 +150,7 @@ local function initTouchEvents()
|
||||
local x = ges.pos.x - self._frame_textwidget.dimen.x - textwidget_offset
|
||||
local y = ges.pos.y - self._frame_textwidget.dimen.y - textwidget_offset
|
||||
self.text_widget:moveCursorToXY(x, y, true) -- restrict_to_view=true
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
return true
|
||||
end
|
||||
@@ -512,7 +518,7 @@ function InputText:initTextBox(text, char_added)
|
||||
}
|
||||
end
|
||||
-- Get back possibly modified charpos and virtual_line_num
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
|
||||
self._frame_textwidget = FrameContainer:new{
|
||||
bordersize = self.bordersize,
|
||||
@@ -676,22 +682,27 @@ dbg:guard(InputText, "onTextInput",
|
||||
end)
|
||||
|
||||
function InputText:onShowKeyboard(ignore_first_hold_release)
|
||||
Device:startTextInput()
|
||||
|
||||
if self.is_keyboard_hidden or not self.manage_keyboard_state then
|
||||
self.keyboard.ignore_first_hold_release = ignore_first_hold_release
|
||||
UIManager:show(self.keyboard)
|
||||
self.is_keyboard_hidden = false
|
||||
if self.keyboard then
|
||||
self.keyboard:showKeyboard(ignore_first_hold_release)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function InputText:onCloseKeyboard()
|
||||
Device:stopTextInput()
|
||||
if self.keyboard then
|
||||
self.keyboard:hideKeyboard()
|
||||
end
|
||||
end
|
||||
|
||||
if not self.is_keyboard_hidden or not self.manage_keyboard_state then
|
||||
UIManager:close(self.keyboard)
|
||||
self.is_keyboard_hidden = true
|
||||
function InputText:isKeyboardVisible()
|
||||
if self.keyboard then
|
||||
return self.keyboard:isVisible()
|
||||
end
|
||||
end
|
||||
|
||||
function InputText:lockKeyboard(toggle)
|
||||
if self.keyboard then
|
||||
return self.keyboard:lockVisibility(toggle)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -873,71 +884,71 @@ end
|
||||
function InputText:leftChar()
|
||||
if self.charpos == 1 then return end
|
||||
self.text_widget:moveCursorLeft()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:rightChar()
|
||||
if self.charpos > #self.charlist then return end
|
||||
self.text_widget:moveCursorRight()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:goToStartOfLine()
|
||||
local new_pos = select(1, self:getStringPos({"\n", "\r"}, {"\n", "\r"}))
|
||||
self.text_widget:moveCursorToCharPos(new_pos)
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:goToEndOfLine()
|
||||
local new_pos = select(2, self:getStringPos({"\n", "\r"}, {"\n", "\r"})) + 1
|
||||
self.text_widget:moveCursorToCharPos(new_pos)
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:goToHome()
|
||||
self.text_widget:moveCursorHome()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:goToEnd()
|
||||
self.text_widget:moveCursorEnd()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:moveCursorToCharPos(char_pos)
|
||||
self.text_widget:moveCursorToCharPos(char_pos)
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:upLine()
|
||||
self.text_widget:moveCursorUp()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:downLine()
|
||||
if #self.charlist == 0 then return end -- Avoid cursor moving within a hint.
|
||||
self.text_widget:moveCursorDown()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:scrollDown()
|
||||
self.text_widget:scrollDown()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:scrollUp()
|
||||
self.text_widget:scrollUp()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:scrollToTop()
|
||||
self.text_widget:scrollToTop()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:scrollToBottom()
|
||||
self.text_widget:scrollToBottom()
|
||||
self.charpos, self.top_line_num = self.text_widget:getCharPos()
|
||||
self:resyncPos()
|
||||
end
|
||||
|
||||
function InputText:clear()
|
||||
|
||||
Reference in New Issue
Block a user