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)
@ -141,7 +141,7 @@ local InputDialog = FocusManager:extend{
add_scroll_buttons=false,-- add scroll Up/Down buttons to first row of buttons
add_scroll_buttons=false,-- add scroll Up/Down buttons to first row of buttons
add_nav_bar=false,-- append a row of page navigation buttons
add_nav_bar=false,-- append a row of page navigation buttons
-- note that the text widget can be scrolled with Swipe North/South even when no button
-- note that the text widget can be scrolled with Swipe North/South even when no button
keyboard_hidden =false,-- start with keyboard hidden in full fullscreen mode
keyboard_visible =true,-- whether we start with the keyboard visible or not (i.e., our caller skipped onShowKeyboard)
-- needs add_nav_bar to have a Show keyboard button to get it back
-- needs add_nav_bar to have a Show keyboard button to get it back
scroll_by_pan=false,-- allow scrolling by lines with Pan (= Swipe, but wait a bit at end
scroll_by_pan=false,-- allow scrolling by lines with Pan (= Swipe, but wait a bit at end
-- of gesture before releasing) (may conflict with movable)
-- of gesture before releasing) (may conflict with movable)
@ -162,8 +162,8 @@ local InputDialog = FocusManager:extend{
edited_callback=nil,-- Called on each text modification
edited_callback=nil,-- Called on each text modification
-- For use by TextEditor plugin:
-- For use by TextEditor plugin:
view_pos_callback=nil,-- Called with no arg to get initial top_line_num/charpos,
view_pos_callback=nil,-- Called with no args on init to retrieve top_line_num/charpos (however the caller chooses to do so, e.g., some will store it in a LuaSettings),
-- called with (top_line_num, charpos) to give back position on close.
-- called with (top_line_num, charpos) on close to let the callback do its thing so that the no args branch spits back useful data..
-- Set to false if movable gestures conflicts with subwidgets gestures
-- Set to false if movable gestures conflicts with subwidgets gestures
is_movable=true,
is_movable=true,
@ -189,6 +189,7 @@ local InputDialog = FocusManager:extend{
alignment_strict=false,
alignment_strict=false,
-- for internal use
-- for internal use
_keyboard_was_visible=nil,-- previous kb visibility state
_text_modified=false,-- previous known modified status
_text_modified=false,-- previous known modified status
-- NOTE: Only called by fullscreen and/or add_nav_bar codepaths
-- We do not currently have !fullscreen add_nav_bar callers...
functionInputDialog:toggleKeyboard(force_toggle)
-- Remember the *current* visibility, as the following close will reset it
localvisible=self:isKeyboardVisible()
-- When we forcibly close the keyboard, remember its current visiblity state, so that we can properly restore it later.
-- (This is used by some buttons in fullscreen mode, where we might want to keep the original keyboard hidden when popping up a new one for another InputDialog).
ifforce_toggle==falsethen
-- NOTE: visible will be nil between our own init and a show of the keyboard, which is precisely what happens when we *hide* the keyboard.
self._keyboard_was_visible=visible==true
end
self.input=self:getInputText()-- re-init with up-to-date text
self.input=self:getInputText()-- re-init with up-to-date text
self:onClose()-- will close keyboard and save view position
self:onClose()-- will close keyboard and save view position
self:free()
self:free()
ifforce_toggle==falseandnotvisiblethen
-- Already hidden, bye!
return
end
-- Init needs to know the keyboard's visibility state *before* the widget is actually shown...
ifforce_toggle==truethen
self.keyboard_visible=true
elseifforce_toggle==falsethen
self.keyboard_visible=false
elseifself._keyboard_was_visible~=nilthen
self.keyboard_visible=self._keyboard_was_visible
self._keyboard_was_visible=nil
else
self.keyboard_visible=notvisible
end
self:init()
self:init()
ifnotself.keyboard_hiddenthen
-- NOTE: If we ever have non-fullscreen add_nav_bar callers, it might make sense *not* to lock the keyboard there?
ifself.keyboard_visiblethen
self:lockKeyboard(false)
self:onShowKeyboard()
self:onShowKeyboard()
else
self:onCloseKeyboard()
-- Prevent InputText:onTapTextBox from opening the keyboard back up on top of our buttons
self:lockKeyboard(true)
end
end
-- Make sure we refresh the nav bar, as it will have moved, and it belongs to us, not to VK or our input widget...
self:refreshButtons()
end
end
functionInputDialog:onKeyboardHeightChanged()
functionInputDialog:onKeyboardHeightChanged()
localvisible=self:isKeyboardVisible()
self.input=self:getInputText()-- re-init with up-to-date text
self.input=self:getInputText()-- re-init with up-to-date text
self:onClose()-- will close keyboard and save view position
self:onClose()-- will close keyboard and save view position
self._input_widget:onCloseWidget()-- proper cleanup of InputText and its keyboard
self._input_widget:onCloseWidget()-- proper cleanup of InputText and its keyboard
@ -555,8 +616,11 @@ function InputDialog:onKeyboardHeightChanged()
self:free()
self:free()
-- Restore original text_height (or reset it if none to force recomputing it)
-- Restore original text_height (or reset it if none to force recomputing it)
self.text_height=self.orig_text_heightornil
self.text_height=self.orig_text_heightornil
-- Same deal as in toggleKeyboard...
self.keyboard_visible=visible
self:init()
self:init()
ifnotself.keyboard_hiddenthen
ifself.keyboard_visiblethen
self:onShowKeyboard()
self:onShowKeyboard()
end
end
-- Our position on screen has probably changed, so have the full screen refreshed
-- Our position on screen has probably changed, so have the full screen refreshed
@ -573,14 +637,16 @@ function InputDialog:onCloseDialog()
end
end
functionInputDialog:onClose()
functionInputDialog:onClose()
-- Tell our input widget to poke its text widget so that we'll pickup up to date values
self._input_widget:resyncPos()
-- Remember current view & position in case of re-init
-- Remember current view & position in case of re-init
@ -32,9 +32,8 @@ local InputText = InputContainer:extend{
focused=true,
focused=true,
parent=nil,-- parent dialog that will be set dirty
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
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)
scroll_by_pan=false,-- allow scrolling by lines with Pan (needs scroll=true)
manage_keyboard_state=true,-- manage keyboard hidden/shown state
width=nil,
width=nil,
height=nil,-- when nil, will be set to original text height (possibly
height=nil,-- when nil, will be set to original text height (possibly
@ -54,7 +53,10 @@ local InputText = InputContainer:extend{
auto_para_direction=false,
auto_para_direction=false,
alignment_strict=false,
alignment_strict=false,
readonly=nil,-- will not support a Keyboard widget if true
-- for internal use
-- for internal use
keyboard=nil,-- Keyboard widget (either VirtualKeyboard or PhysicalKeyboard)
text_widget=nil,-- Text Widget for cursor movement, possibly a ScrollTextWidget
text_widget=nil,-- Text Widget for cursor movement, possibly a ScrollTextWidget
charlist=nil,-- table of individual chars from input string
charlist=nil,-- table of individual chars from input string
charpos=nil,-- position of the cursor, where a new char would be inserted
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
for_measurement_only=nil,-- When the widget is a one-off used to compute text height
do_select=false,-- to start text selection
do_select=false,-- to start text selection
selection_start_pos=nil,-- selection start position
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.
-- These may be (internally) overloaded as needed, depending on Device capabilities.
@ -73,6 +74,11 @@ function InputText:initEventListener() end
functionInputText:onFocus()end
functionInputText:onFocus()end
functionInputText:onUnfocus()end
functionInputText:onUnfocus()end
-- Resync our position state with our text widget's actual state