2016-06-05 07:33:31 +00:00
--[[--
A TextWidget that handles long text wrapping
Example :
local Foo = TextBoxWidget : new {
face = Font : getFace ( " cfont " , 25 ) ,
text = ' We can show multiple lines. \n Foo. \n Bar. ' ,
-- width = Screen:getWidth()*2/3,
}
UIManager : show ( Foo )
] ]
2014-06-02 14:01:11 +00:00
local Blitbuffer = require ( " ffi/blitbuffer " )
2018-01-16 11:32:49 +00:00
local Device = require ( " device " )
local Font = require ( " ui/font " )
local FrameContainer = require ( " ui/widget/container/framecontainer " )
2017-04-02 06:50:24 +00:00
local Geom = require ( " ui/geometry " )
2018-01-16 11:32:49 +00:00
local GestureRange = require ( " ui/gesturerange " )
local InputContainer = require ( " ui/widget/container/inputcontainer " )
2016-04-21 14:13:10 +00:00
local LineWidget = require ( " ui/widget/linewidget " )
2013-10-18 20:38:07 +00:00
local RenderText = require ( " ui/rendertext " )
2018-01-16 11:32:49 +00:00
local RightContainer = require ( " ui/widget/container/rightcontainer " )
2017-09-13 14:56:20 +00:00
local Size = require ( " ui/size " )
2018-01-16 11:32:49 +00:00
local TextWidget = require ( " ui/widget/textwidget " )
2016-12-06 21:10:25 +00:00
local TimeVal = require ( " ui/timeval " )
2018-01-16 11:32:49 +00:00
local UIManager = require ( " ui/uimanager " )
2018-01-31 08:16:34 +00:00
local Math = require ( " optmath " )
2017-04-02 06:50:24 +00:00
local logger = require ( " logger " )
local util = require ( " util " )
2017-09-11 08:32:39 +00:00
local Screen = require ( " device " ) . screen
2013-03-12 17:18:53 +00:00
2018-01-16 11:32:49 +00:00
local TextBoxWidget = InputContainer : new {
2014-03-13 13:52:43 +00:00
text = nil ,
2016-05-15 09:18:38 +00:00
editable = false , -- Editable flag for whether drawing the cursor or not.
2017-01-01 09:24:49 +00:00
justified = false , -- Should text be justified (spaces widened to fill width)
2018-01-16 11:32:49 +00:00
alignment = " left " , -- or "center", "right"
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
dialog = nil , -- parent dialog that will be set dirty
2014-03-13 13:52:43 +00:00
face = nil ,
bold = nil ,
2016-04-21 14:13:10 +00:00
line_height = 0.3 , -- in em
2014-10-22 13:34:11 +00:00
fgcolor = Blitbuffer.COLOR_BLACK ,
2017-09-11 08:32:39 +00:00
width = Screen : scaleBySize ( 400 ) , -- in pixels
2016-04-21 14:13:10 +00:00
height = nil , -- nil value indicates unscrollable text widget
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
top_line_num = nil , -- original virtual_line_num to scroll to
charpos = nil , -- idx of char to draw the cursor on its left (can exceed #charlist by 1)
-- for internal use
charlist = nil , -- idx => char
char_width = nil , -- char => width
idx_pad = nil , -- idx => pad for char at idx, if non zero
vertical_string_list = nil ,
virtual_line_num = 1 , -- index of the top displayed line
line_height_px = nil , -- height of a line in px
lines_per_page = nil , -- number of visible lines
text_height = nil , -- adjusted height to visible text (lines_per_page*line_height_px)
cursor_line = nil , -- LineWidget to draw the vertical cursor.
2014-03-13 13:52:43 +00:00
_bb = nil ,
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
2018-01-16 11:32:49 +00:00
-- We can provide a list of images: each image will be displayed on each
-- scrolled page, in its top right corner (if more images than pages, remaining
-- images will not be displayed at all - if more pages than images, remaining
-- pages won't have any image).
-- Each 'image' is a table with the following keys:
-- width width of small image displayed by us
-- height height of small image displayed by us
-- bb blitbuffer of small image, may be initially nil
-- optional:
-- hi_width same as previous for a high-resolution version of the
-- hi_height image, to be displayed by ImageViewer when Hold on
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- hi_bb blitbuffer of high-resolution image
2018-01-16 11:32:49 +00:00
-- title ImageViewer title
-- caption ImageViewer caption
--
-- load_bb_func function called (with one arg: false to load 'bb', true to load 'hi_bb)
-- when bb or hi_bb is nil: its job is to load/build bb or hi_bb.
-- The page will refresh itself when load_bb_func returns.
images = nil , -- list of such images
line_num_to_image = nil , -- will be filled by self:_splitCharWidthList()
image_padding_left = Screen : scaleBySize ( 10 ) ,
image_padding_bottom = Screen : scaleBySize ( 3 ) ,
image_alt_face = Font : getFace ( " xx_smallinfofont " ) ,
image_alt_fgcolor = Blitbuffer.COLOR_BLACK ,
2013-03-12 17:18:53 +00:00
}
2013-07-28 08:06:45 +00:00
function TextBoxWidget : init ( )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self.line_height_px = Math.round ( ( 1 + self.line_height ) * self.face . size )
2016-05-15 09:18:38 +00:00
self.cursor_line = LineWidget : new {
2016-04-21 14:13:10 +00:00
dimen = Geom : new {
2017-09-13 14:56:20 +00:00
w = Size.line . medium ,
2016-06-05 07:33:31 +00:00
h = self.line_height_px ,
2015-10-18 12:46:22 +00:00
}
2016-04-21 14:13:10 +00:00
}
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
if self.height then
-- luajit may segfault if we were provided with a negative height
-- also ensure we display at least one line
if self.height < self.line_height_px then
self.height = self.line_height_px
end
-- if no self.height, these will be set just after self:_splitCharWidthList()
self.lines_per_page = math.floor ( self.height / self.line_height_px )
self.text_height = self.lines_per_page * self.line_height_px
end
2016-05-15 09:18:38 +00:00
self : _evalCharWidthList ( )
self : _splitCharWidthList ( )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
if self.charpos and self.charpos > # self.charlist + 1 then
self.charpos = # self.charlist + 1
end
2016-05-15 09:18:38 +00:00
if self.height == nil then
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self.lines_per_page = # self.vertical_string_list
self.text_height = self.lines_per_page * self.line_height_px
self.virtual_line_num = 1
2016-05-15 09:18:38 +00:00
else
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- Show the previous displayed area in case of re-init (focus/unfocus)
-- InputText may have re-created us, while providing the previous charlist,
-- charpos and top_line_num.
-- We need to show the line containing charpos, while trying to
-- keep the previous top_line_num
if self.editable and self.charpos then
self : scrollViewToCharPos ( )
2018-01-16 11:32:49 +00:00
end
2016-05-15 09:18:38 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
2016-05-15 09:18:38 +00:00
if self.editable then
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : moveCursorToCharPos ( self.charpos or 1 )
2016-05-15 09:18:38 +00:00
end
self.dimen = Geom : new ( self : getSize ( ) )
2018-01-16 11:32:49 +00:00
if Device : isTouchDevice ( ) then
self.ges_events = {
TapImage = {
GestureRange : new {
ges = " tap " ,
range = function ( ) return self.dimen end ,
} ,
} ,
}
end
2013-03-12 17:18:53 +00:00
end
2016-06-25 17:27:23 +00:00
function TextBoxWidget : unfocus ( )
self.editable = false
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : free ( )
2016-06-25 17:27:23 +00:00
self : init ( )
end
function TextBoxWidget : focus ( )
self.editable = true
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : free ( )
2016-06-25 17:27:23 +00:00
self : init ( )
end
2016-06-05 07:33:31 +00:00
-- Split `self.text` into `self.charlist` and evaluate the width of each char in it.
2016-04-21 14:13:10 +00:00
function TextBoxWidget : _evalCharWidthList ( )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- if self.charlist is provided, use it directly
2016-05-15 09:18:38 +00:00
if self.charlist == nil then
2016-05-22 15:59:28 +00:00
self.charlist = util.splitToChars ( self.text )
2016-05-15 09:18:38 +00:00
end
2018-04-21 20:16:14 +00:00
-- get width of each distinct char
local char_width = { }
for _ , c in ipairs ( self.charlist ) do
if not char_width [ c ] then
char_width [ c ] = RenderText : sizeUtf8Text ( 0 , Screen : getWidth ( ) , self.face , c , true , self.bold ) . x
2016-12-06 21:10:25 +00:00
end
2016-05-15 09:18:38 +00:00
end
2018-04-21 20:16:14 +00:00
self.char_width = char_width
self.idx_pad = { }
2013-07-28 08:06:45 +00:00
end
2016-04-21 14:13:10 +00:00
-- Split the text into logical lines to fit into the text box.
function TextBoxWidget : _splitCharWidthList ( )
2016-06-26 00:53:08 +00:00
self.vertical_string_list = { }
2013-07-28 08:06:45 +00:00
2016-05-15 09:18:38 +00:00
local idx = 1
2018-04-21 20:16:14 +00:00
local size = # self.charlist
2016-05-15 09:18:38 +00:00
local ln = 1
2018-04-21 20:16:14 +00:00
local offset , end_offset , cur_line_width
2018-01-16 11:32:49 +00:00
local image_num = 0
local targeted_width = self.width
local image_lines_remaining = 0
2016-05-15 09:18:38 +00:00
while idx <= size do
2018-01-16 11:32:49 +00:00
-- Every scrolled page, we want to add the next (if any) image at its top right
-- (if not scrollable, we will display only the first image)
-- We need to make shorter lines and leave room for the image
if self.images and # self.images > 0 then
if self.line_num_to_image == nil then
self.line_num_to_image = { }
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
if ( self.lines_per_page and ln % self.lines_per_page == 1 ) -- first line of a scrolled page
or ( self.lines_per_page == nil and ln == 1 ) then -- first line if not scrollabled
2018-01-16 11:32:49 +00:00
image_num = image_num + 1
if image_num <= # self.images then
local image = self.images [ image_num ]
self.line_num_to_image [ ln ] = image
-- Resize image if really too big: bb will be cropped if already there,
-- but if loaded later with load_bb_func, load_bb_func may resize it
-- to the width and height we have updated here.
if image.width > self.width / 2 then
image.height = math.floor ( image.height * ( self.width / 2 / image.width ) )
image.width = math.floor ( self.width / 2 )
end
if image.height > self.height / 2 then
image.width = math.floor ( image.width * ( self.height / 2 / image.height ) )
image.height = math.floor ( self.height / 2 )
end
targeted_width = self.width - image.width - self.image_padding_left
image_lines_remaining = math.ceil ( ( image.height + self.image_padding_bottom ) / self.line_height_px )
end
end
if image_lines_remaining > 0 then
image_lines_remaining = image_lines_remaining - 1
else
targeted_width = self.width -- text can now use full width
end
end
2018-04-21 20:16:14 +00:00
-- end_offset will be the idx of char at end of line
offset = idx -- idx of char at start of line
-- We append chars until the accumulated width exceeds `targeted_width`,
2016-05-15 09:18:38 +00:00
-- or a newline occurs, or no more chars to consume.
cur_line_width = 0
local hard_newline = false
while idx <= size do
2018-04-21 20:16:14 +00:00
if self.charlist [ idx ] == " \n " then
2016-05-15 09:18:38 +00:00
hard_newline = true
break
end
2018-04-21 20:16:14 +00:00
cur_line_width = cur_line_width + self.char_width [ self.charlist [ idx ] ]
2018-01-16 11:32:49 +00:00
if cur_line_width > targeted_width then break else idx = idx + 1 end
2016-05-15 09:18:38 +00:00
end
2018-01-16 11:32:49 +00:00
if cur_line_width <= targeted_width then -- a hard newline or end of string
2018-04-21 20:16:14 +00:00
end_offset = idx - 1
2016-05-15 09:18:38 +00:00
else
-- Backtrack the string until the length fit into one line.
2017-04-04 07:57:14 +00:00
-- We'll give next and prev chars to isSplittable() for a wiser decision
2018-04-21 20:16:14 +00:00
local c = self.charlist [ idx ]
local next_c = idx + 1 <= size and self.charlist [ idx + 1 ] or false
local prev_c = idx - 1 >= 1 and self.charlist [ idx - 1 ] or false
2016-12-12 22:41:16 +00:00
local adjusted_idx = idx
local adjusted_width = cur_line_width
2017-04-04 07:57:14 +00:00
while adjusted_idx > offset and not util.isSplittable ( c , next_c , prev_c ) do
2018-04-21 20:16:14 +00:00
adjusted_width = adjusted_width - self.char_width [ self.charlist [ adjusted_idx ] ]
2016-12-12 22:41:16 +00:00
adjusted_idx = adjusted_idx - 1
next_c = c
c = prev_c
2018-04-21 20:16:14 +00:00
prev_c = adjusted_idx - 1 >= 1 and self.charlist [ adjusted_idx - 1 ] or false
2016-12-12 22:41:16 +00:00
end
if adjusted_idx == offset or adjusted_idx == idx then
2018-04-21 20:16:14 +00:00
-- either a very long english word occupying more than one line,
2017-04-04 07:57:14 +00:00
-- or the excessive char is itself splittable:
2016-12-12 22:41:16 +00:00
-- we let that excessive char for next line
2017-08-18 14:40:48 +00:00
if adjusted_idx == offset then -- let the fact a long word was splitted be known
self.has_split_inside_word = true
end
2018-04-21 20:16:14 +00:00
end_offset = idx - 1
cur_line_width = cur_line_width - self.char_width [ self.charlist [ idx ] ]
2017-01-01 09:24:49 +00:00
elseif c == " " then
-- we backtracked and we're below max width, but the last char
-- is a space, we can ignore it
2018-04-21 20:16:14 +00:00
end_offset = adjusted_idx - 1
cur_line_width = adjusted_width - self.char_width [ self.charlist [ adjusted_idx ] ]
2017-01-01 09:24:49 +00:00
idx = adjusted_idx + 1
2016-05-15 09:18:38 +00:00
else
2017-04-04 07:57:14 +00:00
-- we backtracked and we're below max width, we can leave the
-- splittable char on this line
2018-04-21 20:16:14 +00:00
end_offset = adjusted_idx
2016-12-12 22:41:16 +00:00
cur_line_width = adjusted_width
idx = adjusted_idx + 1
end
2017-01-01 09:24:49 +00:00
if self.justified then
-- this line was splitted and can be justified
2018-04-21 20:16:14 +00:00
-- we record in idx_pad the nb of pixels to add to each char
-- to make the whole line justified. This also helps hold
-- position accuracy.
2018-01-16 11:32:49 +00:00
local fill_width = targeted_width - cur_line_width
2017-01-01 09:24:49 +00:00
if fill_width > 0 then
2018-04-21 20:16:14 +00:00
local nbspaces = 0
for sidx = offset , end_offset do
if self.charlist [ sidx ] == " " then
nbspaces = nbspaces + 1
end
end
2017-01-01 09:24:49 +00:00
if nbspaces > 0 then
-- width added to all spaces
local space_add_w = math.floor ( fill_width / nbspaces )
-- nb of spaces to which we'll add 1 more pixel
local space_add1_nb = fill_width - space_add_w * nbspaces
2018-04-21 20:16:14 +00:00
for cidx = offset , end_offset do
local pad
if self.charlist [ cidx ] == " " then
2017-01-01 09:24:49 +00:00
pad = space_add_w
if space_add1_nb > 0 then
pad = pad + 1
space_add1_nb = space_add1_nb - 1
end
2018-04-21 20:16:14 +00:00
if pad > 0 then self.idx_pad [ cidx ] = pad end
2017-01-01 09:24:49 +00:00
end
end
else
-- very long word, or CJK text with no space
-- pad first chars with 1 pixel
2018-04-21 20:16:14 +00:00
for cidx = offset , end_offset do
2017-01-01 09:24:49 +00:00
if fill_width > 0 then
2018-04-21 20:16:14 +00:00
self.idx_pad [ cidx ] = 1
2017-01-01 09:24:49 +00:00
fill_width = fill_width - 1
2018-04-21 20:16:14 +00:00
else
break
2017-01-01 09:24:49 +00:00
end
end
end
end
end
2018-01-16 11:32:49 +00:00
end -- endif cur_line_width > targeted_width
2016-06-27 16:45:01 +00:00
if cur_line_width < 0 then break end
2016-06-05 07:33:31 +00:00
self.vertical_string_list [ ln ] = {
offset = offset ,
2018-04-21 20:16:14 +00:00
end_offset = end_offset ,
2017-01-01 09:24:49 +00:00
width = cur_line_width ,
2016-06-05 07:33:31 +00:00
}
2016-05-15 09:18:38 +00:00
if hard_newline then
idx = idx + 1
2018-04-21 20:16:14 +00:00
-- end_offset = nil means no text
self.vertical_string_list [ ln + 1 ] = { offset = idx , end_offset = nil , width = 0 }
2016-12-06 21:10:25 +00:00
else
-- If next char is a space, discard it so it does not become
-- an ugly leading space on the next line
2018-04-21 20:16:14 +00:00
if idx <= size and self.charlist [ idx ] == " " then
2016-12-06 21:10:25 +00:00
idx = idx + 1
end
2016-05-15 09:18:38 +00:00
end
ln = ln + 1
-- Make sure `idx` point to the next char to be processed in the next loop.
end
2013-03-12 17:18:53 +00:00
end
2018-04-21 20:16:14 +00:00
function TextBoxWidget : _getLineText ( vertical_string )
if not vertical_string.end_offset then return " " end
return table.concat ( self.charlist , " " , vertical_string.offset , vertical_string.end_offset )
end
function TextBoxWidget : _getLinePads ( vertical_string )
if not vertical_string.end_offset then return end
local pads = { }
for idx = vertical_string.offset , vertical_string.end_offset do
table.insert ( pads , self.idx_pad [ idx ] or 0 )
end
return pads
end
2019-08-23 17:53:53 +00:00
---- Lays out text.
2016-04-21 14:13:10 +00:00
function TextBoxWidget : _renderText ( start_row_idx , end_row_idx )
2014-03-13 13:52:43 +00:00
local font_height = self.face . size
2016-05-15 09:18:38 +00:00
if start_row_idx < 1 then start_row_idx = 1 end
if end_row_idx > # self.vertical_string_list then end_row_idx = # self.vertical_string_list end
local row_count = end_row_idx == 0 and 1 or end_row_idx - start_row_idx + 1
2018-01-16 11:32:49 +00:00
-- We need a bb with the full height (even if we display only a few lines, we
-- may have to draw an image bigger than these lines)
local h = self.height or self.line_height_px * row_count
2017-04-02 06:50:24 +00:00
if self._bb then self._bb : free ( ) end
2018-01-16 11:32:49 +00:00
local bbtype = nil
if self.line_num_to_image and self.line_num_to_image [ start_row_idx ] then
2019-03-14 19:58:45 +00:00
bbtype = Screen : isColorEnabled ( ) and Blitbuffer.TYPE_BBRGB32 or Blitbuffer.TYPE_BB8
2018-01-16 11:32:49 +00:00
end
self._bb = Blitbuffer.new ( self.width , h , bbtype )
2014-10-22 14:40:24 +00:00
self._bb : fill ( Blitbuffer.COLOR_WHITE )
2016-05-15 09:18:38 +00:00
local y = font_height
for i = start_row_idx , end_row_idx do
local line = self.vertical_string_list [ i ]
2018-01-16 11:32:49 +00:00
local pen_x = 0 -- when alignment == "left"
if self.alignment == " center " then
pen_x = ( self.width - line.width ) / 2 or 0
elseif self.alignment == " right " then
pen_x = ( self.width - line.width )
end
2019-08-23 17:53:53 +00:00
--- @todo don't use kerning for monospaced fonts. (houqp)
--- refer to [cb25029dddc42693cc7aaefbe47e9bd3b7e1a750](https://github.com/koreader/koreader/commit/cb25029dddc42693cc7aaefbe47e9bd3b7e1a750) in master tree
2018-04-21 20:16:14 +00:00
RenderText : renderUtf8Text ( self._bb , pen_x , y , self.face , self : _getLineText ( line ) , true , self.bold , self.fgcolor , nil , self : _getLinePads ( line ) )
2016-06-05 07:33:31 +00:00
y = y + self.line_height_px
2016-05-15 09:18:38 +00:00
end
2018-01-16 11:32:49 +00:00
-- Render image if any
self : _renderImage ( start_row_idx )
end
function TextBoxWidget : _renderImage ( start_row_idx )
local scheduled_update = self.scheduled_update
self.scheduled_update = nil -- reset it, so we don't have to whenever we return below
if not self.line_num_to_image or not self.line_num_to_image [ start_row_idx ] then
return -- no image on this page
end
local image = self.line_num_to_image [ start_row_idx ]
local do_schedule_update = false
local display_bb = false
local display_alt = false
local status_text = nil
local alt_text = image.title or " "
if image.caption then
alt_text = alt_text .. " \n " .. image.caption
end
-- Decide what to do/display
if image.bb then -- we have a bb
if scheduled_update then -- we're called from a scheduled update
display_bb = true -- display the bb we got
else
-- not from a scheduled update, but update from Tap on image
-- or we are back to this page from another one
if self.image_show_alt_text then
display_alt = true -- display alt_text
else
display_bb = true -- display the bb we have
end
end
else -- no bb yet
display_alt = true -- nothing else to display but alt_text
if scheduled_update then -- we just failed loading a bb in a scheduled update
status_text = " ⚠ " -- show a warning triangle below alt_text
else
-- initial display of page (or back on it and previous
-- load_bb_func failed: try it again)
if image.load_bb_func then -- we can load a bb
do_schedule_update = true -- load it and call us again
status_text = " ♲ " -- display loading recycle sign below alt_text
end
end
end
-- logger.dbg("display_bb:", display_bb, "display_alt", display_alt, "status_text:", status_text, "do_schedule_update:", do_schedule_update)
-- Do what's been decided
if display_bb then
2019-03-14 19:58:45 +00:00
-- With alpha-blending if the image contains an alpha channel
local bbtype = image.bb : getType ( )
if bbtype == Blitbuffer.TYPE_BB8A or bbtype == Blitbuffer.TYPE_BBRGB32 then
2019-03-18 08:35:27 +00:00
-- NOTE: MuPDF feeds us premultiplied alpha (and we don't care w/ GifLib, as alpha is all or nothing).
self._bb : pmulalphablitFrom ( image.bb , self.width - image.width , 0 )
2019-03-14 19:58:45 +00:00
else
self._bb : blitFrom ( image.bb , self.width - image.width , 0 )
end
2018-01-16 11:32:49 +00:00
end
local status_height = 0
if status_text then
local status_widget = TextWidget : new {
text = status_text ,
face = Font : getFace ( " cfont " , 20 ) ,
2019-03-14 19:58:45 +00:00
fgcolor = Blitbuffer.COLOR_DARK_GRAY ,
2018-01-16 11:32:49 +00:00
bold = true ,
}
status_height = status_widget : getSize ( ) . h
status_widget = FrameContainer : new {
background = Blitbuffer.COLOR_WHITE ,
bordersize = 0 ,
margin = 0 ,
padding = 0 ,
RightContainer : new {
dimen = {
w = image.width ,
h = status_height ,
} ,
status_widget ,
} ,
}
status_widget : paintTo ( self._bb , self.width - image.width , image.height - status_height )
status_widget : free ( )
end
if display_alt then
local alt_widget = TextBoxWidget : new {
text = alt_text ,
face = self.image_alt_face ,
fgcolor = self.image_alt_fgcolor ,
width = image.width ,
-- don't draw over status_text if any
height = math.max ( 0 , image.height - status_height ) ,
}
alt_widget : paintTo ( self._bb , self.width - image.width , 0 )
alt_widget : free ( )
end
if do_schedule_update then
if self.image_update_action then
-- Cancel any previous one, if we changed page quickly
UIManager : unschedule ( self.image_update_action )
end
-- Remember on which page we were launched, so we can
-- abort if page has changed
local scheduled_for_linenum = start_row_idx
self.image_update_action = function ( )
self.image_update_action = nil
if scheduled_for_linenum ~= self.virtual_line_num then
return -- no more on this page
end
local dismissed = image.load_bb_func ( ) -- will update self.bb (or not if failure)
if dismissed then
-- If dismissed, the dismiss event may be resent, we
-- may soon just go display another page. So delay this update a
-- bit to see if that happened
UIManager : scheduleIn ( 0.1 , function ( )
if scheduled_for_linenum == self.virtual_line_num then
-- we are still on the same page
self : update ( true )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
UIManager : setDirty ( self.dialog or " all " , function ( )
2018-01-16 11:32:49 +00:00
-- return "ui", self.dimen
-- We can refresh only the image area, even if we have just
-- re-rendered the whole textbox as the text has been
-- rendered just the same as it was
return " ui " , Geom : new {
x = self.dimen . x + self.width - image.width ,
y = self.dimen . y ,
w = image.width ,
h = image.height ,
}
end )
end
end )
else
-- Image loaded (or not if failure): call us again
-- with scheduled_update = true so we can draw what we got
self : update ( true )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
UIManager : setDirty ( self.dialog or " all " , function ( )
2018-01-16 11:32:49 +00:00
-- return "ui", self.dimen
-- We can refresh only the image area, even if we have just
-- re-rendered the whole textbox as the text has been
-- rendered just the same as it was
return " ui " , Geom : new {
x = self.dimen . x + self.width - image.width ,
y = self.dimen . y ,
w = image.width ,
h = image.height ,
}
end )
end
end
-- Wrap it with Trapper, as load_bb_func may be using some of its
-- dismissable methods
local Trapper = require ( " ui/trapper " )
UIManager : scheduleIn ( 0.1 , function ( ) Trapper : wrap ( self.image_update_action ) end )
end
2013-07-28 08:06:45 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : getCharWidth ( idx )
return self.char_width [ self.charlist [ idx ] ]
2013-07-28 08:06:45 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : getVisLineCount ( )
return self.lines_per_page
2016-06-26 00:53:08 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : getAllLineCount ( )
return # self.vertical_string_list
end
function TextBoxWidget : getTextHeight ( )
return self.text_height
end
function TextBoxWidget : getLineHeight ( )
return self.line_height_px
end
function TextBoxWidget : getVisibleHeightRatios ( )
local low = ( self.virtual_line_num - 1 ) / # self.vertical_string_list
local high = ( self.virtual_line_num - 1 + self.lines_per_page ) / # self.vertical_string_list
return low , high
end
function TextBoxWidget : getCharPos ( )
-- returns virtual_line_num too
return self.charpos , self.virtual_line_num
end
function TextBoxWidget : getSize ( )
if self.width and self.height then
return Geom : new { w = self.width , h = self.height }
else
return Geom : new { w = self.width , h = self._bb : getHeight ( ) }
2016-05-15 09:18:38 +00:00
end
2013-07-28 08:06:45 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : paintTo ( bb , x , y )
self.dimen . x , self.dimen . y = x , y
bb : blitFrom ( self._bb , x , y , 0 , 0 , self.width , self._bb : getHeight ( ) )
2013-07-28 08:06:45 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : free ( )
logger.dbg ( " TextBoxWidget:free called " )
-- :free() is called when our parent widget is closing, and
-- here whenever :_renderText() is being called, to display
-- a new page: cancel any scheduled image update, as it
-- is no longer related to current page
if self.image_update_action then
logger.dbg ( " TextBoxWidget:free: cancelling self.image_update_action " )
UIManager : unschedule ( self.image_update_action )
end
if self._bb then
self._bb : free ( )
self._bb = nil
end
if self.cursor_restore_bb then
self.cursor_restore_bb : free ( )
self.cursor_restore_bb = nil
end
2016-04-21 14:13:10 +00:00
end
2018-01-16 11:32:49 +00:00
function TextBoxWidget : update ( scheduled_update )
self : free ( )
-- We set this flag so :_renderText() can know we were called from a
-- scheduled update and so not schedule another one
self.scheduled_update = scheduled_update
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
2018-01-16 11:32:49 +00:00
self.scheduled_update = nil
end
function TextBoxWidget : onTapImage ( arg , ges )
if self.line_num_to_image and self.line_num_to_image [ self.virtual_line_num ] then
local image = self.line_num_to_image [ self.virtual_line_num ]
local tap_x = ges.pos . x - self.dimen . x
local tap_y = ges.pos . y - self.dimen . y
-- Check that this tap is on this image
if tap_x > self.width - image.width and tap_x < self.width and
tap_y > 0 and tap_y < image.height then
logger.dbg ( " tap on image " )
if image.bb then
-- Toggle between image and alt_text
self.image_show_alt_text = not self.image_show_alt_text
self : update ( )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
UIManager : setDirty ( self.dialog or " all " , function ( )
2018-01-16 11:32:49 +00:00
-- return "ui", self.dimen
-- We can refresh only the image area, even if we have just
-- re-rendered the whole textbox as the text has been
-- rendered just the same as it was
return " ui " , Geom : new {
x = self.dimen . x + self.width - image.width ,
y = self.dimen . y ,
w = image.width ,
h = image.height ,
}
end )
return true
end
end
end
end
2016-04-21 14:13:10 +00:00
2013-07-28 08:06:45 +00:00
function TextBoxWidget : scrollDown ( )
2018-01-16 11:32:49 +00:00
self.image_show_alt_text = nil -- reset image bb/alt state
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
if self.virtual_line_num + self.lines_per_page <= # self.vertical_string_list then
2016-05-15 09:18:38 +00:00
self : free ( )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self.virtual_line_num = self.virtual_line_num + self.lines_per_page
-- If last line shown, set it to be the last line of view
-- (only if editable, as this would be confusing when reading
-- a dictionary result or a wikipedia page)
if self.editable then
if self.virtual_line_num > # self.vertical_string_list - self.lines_per_page + 1 then
self.virtual_line_num = # self.vertical_string_list - self.lines_per_page + 1
if self.virtual_line_num < 1 then
self.virtual_line_num = 1
end
end
end
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
end
if self.editable then
-- move cursor to first line of visible area
local ln = self.height == nil and 1 or self.virtual_line_num
self : moveCursorToCharPos ( self.vertical_string_list [ ln ] and self.vertical_string_list [ ln ] . offset or 1 )
2016-05-15 09:18:38 +00:00
end
2013-07-28 08:06:45 +00:00
end
function TextBoxWidget : scrollUp ( )
2018-01-16 11:32:49 +00:00
self.image_show_alt_text = nil
2016-05-15 09:18:38 +00:00
if self.virtual_line_num > 1 then
self : free ( )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
if self.virtual_line_num <= self.lines_per_page then
2016-05-15 09:18:38 +00:00
self.virtual_line_num = 1
else
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self.virtual_line_num = self.virtual_line_num - self.lines_per_page
2016-05-15 09:18:38 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
end
if self.editable then
-- move cursor to first line of visible area
local ln = self.height == nil and 1 or self.virtual_line_num
self : moveCursorToCharPos ( self.vertical_string_list [ ln ] and self.vertical_string_list [ ln ] . offset or 1 )
2018-01-31 08:16:34 +00:00
end
end
2018-08-10 16:05:09 +00:00
function TextBoxWidget : scrollLines ( nb_lines )
-- nb_lines can be negative
if nb_lines == 0 then
return
end
self.image_show_alt_text = nil
local new_line_num = self.virtual_line_num + nb_lines
if new_line_num < 1 then
new_line_num = 1
end
if new_line_num > # self.vertical_string_list - self.lines_per_page + 1 then
new_line_num = # self.vertical_string_list - self.lines_per_page + 1
end
self.virtual_line_num = new_line_num
self : free ( )
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
if self.editable then
local x , y = self : _getXYForCharPos ( ) -- luacheck: no unused
if y < 0 or y >= self.text_height then
-- move cursor to first line of visible area
local ln = self.height == nil and 1 or self.virtual_line_num
self : moveCursorToCharPos ( self.vertical_string_list [ ln ] and self.vertical_string_list [ ln ] . offset or 1 )
end
end
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : scrollToTop ( )
self.image_show_alt_text = nil
if self.virtual_line_num > 1 then
self : free ( )
self.virtual_line_num = 1
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
end
if self.editable then
-- move cursor to first char
self : moveCursorToCharPos ( 1 )
end
end
function TextBoxWidget : scrollToBottom ( )
self.image_show_alt_text = nil
-- Show last line of text on last line of view
local ln = # self.vertical_string_list - self.lines_per_page + 1
if ln < 1 then
ln = 1
end
if self.virtual_line_num ~= ln then
self : free ( )
self.virtual_line_num = ln
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
end
if self.editable then
-- move cursor to last char
self : moveCursorToCharPos ( # self.charlist + 1 )
end
end
2018-01-31 08:16:34 +00:00
function TextBoxWidget : scrollToRatio ( ratio )
self.image_show_alt_text = nil
ratio = math.max ( 0 , math.min ( 1 , ratio ) ) -- ensure ratio is between 0 and 1 (100%)
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
local page_count = 1 + math.floor ( ( # self.vertical_string_list - 1 ) / self.lines_per_page )
2018-01-31 08:16:34 +00:00
local page_num = 1 + Math.round ( ( page_count - 1 ) * ratio )
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
local line_num = 1 + ( page_num - 1 ) * self.lines_per_page
2018-01-31 08:16:34 +00:00
if line_num ~= self.virtual_line_num then
self : free ( )
self.virtual_line_num = line_num
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
end
if self.editable then
-- move cursor to first line of visible area
local ln = self.height == nil and 1 or self.virtual_line_num
self : moveCursorToCharPos ( self.vertical_string_list [ ln ] . offset )
2016-05-15 09:18:38 +00:00
end
2013-03-12 17:18:53 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
--- Cursor management
-- Return the coordinates (relative to current view, so negative y is possible)
-- of the left of char at charpos (use self.charpos if none provided)
function TextBoxWidget : _getXYForCharPos ( charpos )
if not charpos then
charpos = self.charpos
end
if self.text == nil or string.len ( self.text ) == 0 then
return 0 , 0
end
-- Find the line number: scan up/down from current virtual_line_num
local ln = self.height == nil and 1 or self.virtual_line_num
if charpos > self.vertical_string_list [ ln ] . offset then -- after first line
while ln < # self.vertical_string_list do
if self.vertical_string_list [ ln + 1 ] . offset > charpos then
break
else
ln = ln + 1
end
end
elseif charpos < self.vertical_string_list [ ln ] . offset then -- before first line
while ln > 1 do
ln = ln - 1
if self.vertical_string_list [ ln ] . offset <= charpos then
break
end
end
2014-03-13 13:52:43 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
local y = ( ln - self.virtual_line_num ) * self.line_height_px
-- Find the x offset in the current line.
local x = 0
local offset = self.vertical_string_list [ ln ] . offset
local nbchars = # self.charlist
while offset < charpos do
if offset <= nbchars then -- charpos may exceed #self.charlist
x = x + self.char_width [ self.charlist [ offset ] ] + ( self.idx_pad [ offset ] or 0 )
end
offset = offset + 1
end
-- Cursor can be drawn at x, it will be on the left of the char pointed by charpos
-- (x=0 for first char of line - for end of line, it will be before the \n, the \n
-- itself being not displayed)
return x , y
2013-03-12 17:18:53 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- Return the charpos at provided coordinates (relative to current view,
-- so negative y is allowed)
function TextBoxWidget : getCharPosAtXY ( x , y )
if # self.vertical_string_list == 0 then
-- if there's no text at all, nothing to do
return 1
end
local ln = self.height == nil and 1 or self.virtual_line_num
ln = ln + math.floor ( y / self.line_height_px )
if ln < 1 then
return 1 -- return start of first line
elseif ln > # self.vertical_string_list then
return # self.charlist + 1 -- return end of last line
end
if x > self.vertical_string_list [ ln ] . width then -- no need to loop thru chars
local pos = self.vertical_string_list [ ln ] . end_offset
if not pos then -- empty line
pos = self.vertical_string_list [ ln ] . offset
end
return pos + 1 -- after last char
end
local idx = self.vertical_string_list [ ln ] . offset
local end_offset = self.vertical_string_list [ ln ] . end_offset
if not end_offset then -- empty line
return idx
2017-10-10 16:04:51 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
local w = 0
local w_prev
while idx <= end_offset do
w_prev = w
w = w + self.char_width [ self.charlist [ idx ] ] + ( self.idx_pad [ idx ] or 0 )
if w > x then -- we're on this char at idx
if x - w_prev < w - x then -- nearest to char start
return idx
else -- nearest to char end: draw cursor before next char
return idx + 1
end
break
end
idx = idx + 1
end
return end_offset + 1 -- should not happen
2017-10-10 16:04:51 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- Tunables for the next function: not sure yet which combination is
-- best to get the less cursor trail - and initially got some crashes
-- when using refresh funcs. It finally feels fine with both set to true,
-- but one can turn them to false with a setting to check how some other
-- combinations do.
local CURSOR_COMBINE_REGIONS = G_reader_settings : nilOrTrue ( " ui_cursor_combine_regions " )
local CURSOR_USE_REFRESH_FUNCS = G_reader_settings : nilOrTrue ( " ui_cursor_use_refresh_funcs " )
-- Update charpos to the one provided; if out of current view, update
-- virtual_line_num to move it to view, and draw the cursor
function TextBoxWidget : moveCursorToCharPos ( charpos )
if not self.editable then
-- we shouldn't have been called if not editable
logger.warn ( " TextBoxWidget:moveCursorToCharPos called, but not editable " )
return
end
self.charpos = charpos
self.prev_virtual_line_num = self.virtual_line_num
local x , y = self : _getXYForCharPos ( ) -- we can get y outside current view
-- adjust self.virtual_line_num for overflowed y to have y in current view
if y < 0 then
local scroll_lines = math.ceil ( - y / self.line_height_px )
self.virtual_line_num = self.virtual_line_num - scroll_lines
if self.virtual_line_num < 1 then
self.virtual_line_num = 1
end
y = y + scroll_lines * self.line_height_px
end
if y >= self.text_height then
local scroll_lines = math.floor ( ( y - self.text_height ) / self.line_height_px ) + 1
self.virtual_line_num = self.virtual_line_num + scroll_lines
-- needs to deal with possible overflow ?
y = y - scroll_lines * self.line_height_px
end
if not self._bb then
return -- no bb yet to render the cursor too
end
if self.virtual_line_num ~= self.prev_virtual_line_num then
-- We scrolled the view: full render and refresh needed
self : free ( )
self : _renderText ( self.virtual_line_num , self.virtual_line_num + self.lines_per_page - 1 )
-- Store the original image of where we will draw the cursor, for a
-- quick restore and two small refreshes when moving only the cursor
self.cursor_restore_x = x
self.cursor_restore_y = y
self.cursor_restore_bb = Blitbuffer.new ( self.cursor_line . dimen.w , self.cursor_line . dimen.h , self._bb : getType ( ) )
self.cursor_restore_bb : blitFrom ( self._bb , 0 , 0 , x , y , self.cursor_line . dimen.w , self.cursor_line . dimen.h )
-- Paint the cursor, and refresh the whole widget
self.cursor_line : paintTo ( self._bb , x , y )
UIManager : setDirty ( self.dialog or " all " , function ( )
return " ui " , self.dimen
end )
elseif self._bb then
if CURSOR_USE_REFRESH_FUNCS then
-- We didn't scroll the view, only the cursor was moved
local restore_x , restore_y
if self.cursor_restore_bb then
-- Restore the previous cursor position content, and do
-- a small ui refresh of the old cursor area
self._bb : blitFrom ( self.cursor_restore_bb , self.cursor_restore_x , self.cursor_restore_y ,
0 , 0 , self.cursor_line . dimen.w , self.cursor_line . dimen.h )
-- remember current values for use in the setDirty funcs, as
-- we will have overriden them when these are called
restore_x = self.cursor_restore_x
restore_y = self.cursor_restore_y
if not CURSOR_COMBINE_REGIONS then
UIManager : setDirty ( self.dialog or " all " , function ( )
return " ui " , Geom : new {
x = self.dimen . x + restore_x ,
y = self.dimen . y + restore_y ,
w = self.cursor_line . dimen.w ,
h = self.cursor_line . dimen.h ,
}
end )
end
self.cursor_restore_bb : free ( )
self.cursor_restore_bb = nil
end
-- Store the original image of where we will draw the new cursor
self.cursor_restore_x = x
self.cursor_restore_y = y
self.cursor_restore_bb = Blitbuffer.new ( self.cursor_line . dimen.w , self.cursor_line . dimen.h , self._bb : getType ( ) )
self.cursor_restore_bb : blitFrom ( self._bb , 0 , 0 , x , y , self.cursor_line . dimen.w , self.cursor_line . dimen.h )
-- Paint the cursor, and do a small ui refresh of the new cursor area
self.cursor_line : paintTo ( self._bb , x , y )
UIManager : setDirty ( self.dialog or " all " , function ( )
local cursor_region = Geom : new {
x = self.dimen . x + x ,
y = self.dimen . y + y ,
w = self.cursor_line . dimen.w ,
h = self.cursor_line . dimen.h ,
}
if CURSOR_COMBINE_REGIONS and restore_x and restore_y then
local restore_region = Geom : new {
x = self.dimen . x + restore_x ,
y = self.dimen . y + restore_y ,
w = self.cursor_line . dimen.w ,
h = self.cursor_line . dimen.h ,
}
cursor_region = cursor_region : combine ( restore_region )
end
return " ui " , cursor_region
end )
else -- CURSOR_USE_REFRESH_FUNCS = false
-- We didn't scroll the view, only the cursor was moved
local restore_region
if self.cursor_restore_bb then
-- Restore the previous cursor position content, and do
-- a small ui refresh of the old cursor area
self._bb : blitFrom ( self.cursor_restore_bb , self.cursor_restore_x , self.cursor_restore_y ,
0 , 0 , self.cursor_line . dimen.w , self.cursor_line . dimen.h )
if self.dimen then
restore_region = Geom : new {
x = self.dimen . x + self.cursor_restore_x ,
y = self.dimen . y + self.cursor_restore_y ,
w = self.cursor_line . dimen.w ,
h = self.cursor_line . dimen.h ,
}
if not CURSOR_COMBINE_REGIONS then
UIManager : setDirty ( self.dialog or " all " , " ui " , restore_region )
end
end
self.cursor_restore_bb : free ( )
self.cursor_restore_bb = nil
end
-- Store the original image of where we will draw the new cursor
self.cursor_restore_x = x
self.cursor_restore_y = y
self.cursor_restore_bb = Blitbuffer.new ( self.cursor_line . dimen.w , self.cursor_line . dimen.h , self._bb : getType ( ) )
self.cursor_restore_bb : blitFrom ( self._bb , 0 , 0 , x , y , self.cursor_line . dimen.w , self.cursor_line . dimen.h )
-- Paint the cursor, and do a small ui refresh of the new cursor area
self.cursor_line : paintTo ( self._bb , x , y )
if self.dimen then
local cursor_region = Geom : new {
x = self.dimen . x + x ,
y = self.dimen . y + y ,
w = self.cursor_line . dimen.w ,
h = self.cursor_line . dimen.h ,
}
if CURSOR_COMBINE_REGIONS and restore_region then
cursor_region = cursor_region : combine ( restore_region )
end
UIManager : setDirty ( self.dialog or " all " , " ui " , cursor_region )
end
end
2017-10-10 16:04:51 +00:00
end
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : moveCursorToXY ( x , y , restrict_to_view )
if restrict_to_view then
-- Wrap y to current view (when getting coordinates from gesture)
-- (no real need to check for x, getCharPosAtXY() is ok with any x)
if y < 0 then
y = 0
end
if y >= self.text_height then
y = self.text_height - 1
end
end
local charpos = self : getCharPosAtXY ( x , y )
self : moveCursorToCharPos ( charpos )
2013-03-12 17:18:53 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- Update self.virtual_line_num to the page containing charpos
function TextBoxWidget : scrollViewToCharPos ( )
if self.top_line_num then
-- if previous top_line_num provided, go to that line
self.virtual_line_num = self.top_line_num
if self.virtual_line_num < 1 then
self.virtual_line_num = 1
end
if self.virtual_line_num > # self.vertical_string_list then
self.virtual_line_num = # self.vertical_string_list
end
-- Ensure we don't show too much blank at end (when deleting last lines)
-- local max_empty_lines = math.floor(self.lines_per_page / 2)
-- Best to not allow any, for initially non-scrolled widgets
local max_empty_lines = 0
local max_virtual_line_num = # self.vertical_string_list - self.lines_per_page + 1 + max_empty_lines
if self.virtual_line_num > max_virtual_line_num then
self.virtual_line_num = max_virtual_line_num
if self.virtual_line_num < 1 then
self.virtual_line_num = 1
end
end
-- and adjust if cursor is out of view
self : moveCursorToCharPos ( self.charpos )
return
2018-01-16 11:32:49 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
-- Otherwise, find the "hard" page containing charpos
local ln = 1
while true do
local lend = ln + self.lines_per_page - 1
if lend >= # self.vertical_string_list then
break -- last page
end
if self.vertical_string_list [ lend + 1 ] . offset >= self.charpos then
break
end
ln = ln + self.lines_per_page
2014-03-13 13:52:43 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
self.virtual_line_num = ln
2013-03-12 17:18:53 +00:00
end
Text input fixes and enhancements (#4084)
InputText, ScrollTextWidget, TextBoxWidget:
- proper line scrolling when moving cursor or inserting/deleting text
to behave like most text editors do
- fix cursor navigation, optimize refreshes when moving only the cursor,
don't recreate the textwidget when moving cursor up/down
- optimize refresh areas, stick to "ui" to avoid a "partial" black
flash every 6 appended or deleted chars
InputText:
- fix issue when toggling Show password multiple times
- new option: InputText.cursor_at_end (default: true)
- if no InputText.height provided, measure the text widget height
that we would start with, and use a ScrollTextWidget with that
fixed height, so widget does not overflow container if we extend
the text and increase the number of lines
- as we are using "ui" refreshes while text editing, allows refreshing
the InputText with a diagonal swipe on it (actually, refresh the
whole screen, which allows refreshing the keyboard too if needed)
ScrollTextWidget:
- properly align scrollbar with its TextBoxWidget
TextBoxWidget:
- some cleanup (added new properties to avoid many method calls), added
proxy methods for upper widgets to get them
- reordered/renamed/refactored the *CharPos* methods for easier reading
(sorry for the diff that won't help reviewing, but that was needed)
InputDialog:
- new options:
allow_newline = false, -- allow entering new lines
cursor_at_end = true, -- starts with cursor at end of text, ready to append
fullscreen = false, -- adjust to full screen minus keyboard
condensed = false, -- true will prevent adding air and balance between elements
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
- find the most adequate text height, when none provided or fullscreen, to
not overflow screen (and not be stuck with Cancel/Save buttons hidden)
- had to disable the use of a MovableContainer (many issues like becoming
transparent when a PathChooser comes in front, Hold to paste from
clipboard, moving the InputDialog under the keyboard and getting stuck...)
GestureRange: fix possible crash (when event processed after widget
destruction ?)
LoginDialog: fix some ui stack increase and possible crash when switching
focus many times.
2018-07-19 06:30:40 +00:00
function TextBoxWidget : moveCursorLeft ( )
if self.charpos > 1 then
self : moveCursorToCharPos ( self.charpos - 1 )
end
end
function TextBoxWidget : moveCursorRight ( )
if self.charpos < # self.charlist + 1 then -- we can move after last char
self : moveCursorToCharPos ( self.charpos + 1 )
end
end
function TextBoxWidget : moveCursorUp ( )
if self.vertical_string_list and # self.vertical_string_list < 2 then return end
local x , y = self : _getXYForCharPos ( )
self : moveCursorToXY ( x , y - self.line_height_px )
end
function TextBoxWidget : moveCursorDown ( )
if self.vertical_string_list and # self.vertical_string_list < 2 then return end
local x , y = self : _getXYForCharPos ( )
self : moveCursorToXY ( x , y + self.line_height_px )
end
--- Text selection with Hold
2016-12-06 21:10:25 +00:00
-- Allow selection of a single word at hold position
2015-10-18 12:46:22 +00:00
function TextBoxWidget : onHoldWord ( callback , ges )
2016-06-05 07:33:31 +00:00
if not callback then return end
2015-10-18 12:46:22 +00:00
local x , y = ges.pos . x - self.dimen . x , ges.pos . y - self.dimen . y
2016-11-30 15:41:03 +00:00
local line_num = math.ceil ( y / self.line_height_px ) + self.virtual_line_num - 1
2016-06-05 07:33:31 +00:00
local line = self.vertical_string_list [ line_num ]
2016-12-29 08:10:38 +00:00
logger.dbg ( " holding on line " , line )
2016-06-05 07:33:31 +00:00
if line then
local char_start = line.offset
local char_end -- char_end is non-inclusive
if line_num >= # self.vertical_string_list then
2018-04-21 20:16:14 +00:00
char_end = # self.charlist + 1
2016-06-05 07:33:31 +00:00
else
char_end = self.vertical_string_list [ line_num + 1 ] . offset
end
local char_probe_x = 0
local idx = char_start
-- find which character the touch is holding
while idx < char_end do
2019-08-23 17:53:53 +00:00
--- @fixme This might break if kerning is enabled.
2018-04-21 20:16:14 +00:00
char_probe_x = char_probe_x + self.char_width [ self.charlist [ idx ] ] + ( self.idx_pad [ idx ] or 0 )
2016-06-05 07:33:31 +00:00
if char_probe_x > x then
-- ignore spaces
2018-04-21 20:16:14 +00:00
if self.charlist [ idx ] == " " then break end
2016-06-05 07:33:31 +00:00
-- now find which word the character is in
2018-04-21 20:16:14 +00:00
local words = util.splitToWords ( self : _getLineText ( line ) )
2016-06-05 07:33:31 +00:00
local probe_idx = char_start
2016-06-28 15:50:21 +00:00
for _ , w in ipairs ( words ) do
2016-06-05 07:33:31 +00:00
-- +1 for word separtor
2016-06-28 15:50:21 +00:00
probe_idx = probe_idx + # util.splitToChars ( w )
if idx <= probe_idx - 1 then
2016-06-05 07:33:31 +00:00
callback ( w )
return
end
2015-10-18 12:46:22 +00:00
end
break
end
2016-06-05 07:33:31 +00:00
idx = idx + 1
2015-10-18 12:46:22 +00:00
end
end
2016-06-05 07:33:31 +00:00
return
2015-10-18 12:46:22 +00:00
end
2016-12-06 21:10:25 +00:00
-- Allow selection of one or more words (with no visual feedback)
-- Gestures should be declared in widget using us (e.g dictquicklookup.lua)
-- Constants for which side of a word to find
local FIND_START = 1
local FIND_END = 2
2018-03-07 14:59:59 +00:00
function TextBoxWidget : onHoldStartText ( _ , ges )
2018-03-05 20:27:55 +00:00
-- store hold start position and timestamp, will be used on release
2016-12-06 21:10:25 +00:00
self.hold_start_x = ges.pos . x - self.dimen . x
self.hold_start_y = ges.pos . y - self.dimen . y
2018-03-05 20:27:55 +00:00
-- check coordinates are actually inside our area
if self.hold_start_x < 0 or self.hold_start_x > self.dimen . w or
self.hold_start_y < 0 or self.hold_start_y > self.dimen . h then
self.hold_start_tv = nil -- don't process coming HoldRelease event
return false -- let event be processed by other widgets
end
2016-12-06 21:10:25 +00:00
self.hold_start_tv = TimeVal.now ( )
2018-03-07 14:59:59 +00:00
return true
end
function TextBoxWidget : onHoldPanText ( _ , ges )
-- We don't highlight the currently selected text, but just let this
-- event pop up if we are not currently selecting text
if not self.hold_start_tv then
return false
2018-03-05 20:27:55 +00:00
end
2018-03-07 14:59:59 +00:00
-- Don't let that event be processed by other widget
2016-12-06 21:10:25 +00:00
return true
end
function TextBoxWidget : onHoldReleaseText ( callback , ges )
if not callback then return end
local hold_end_x = ges.pos . x - self.dimen . x
local hold_end_y = ges.pos . y - self.dimen . y
2016-12-17 17:54:40 +00:00
-- check we have seen a HoldStart event
if not self.hold_start_tv then
return false
end
-- check start and end coordinates are actually inside our area
if self.hold_start_x < 0 or hold_end_x < 0 or
self.hold_start_x > self.dimen . w or hold_end_x > self.dimen . w or
self.hold_start_y < 0 or hold_end_y < 0 or
self.hold_start_y > self.dimen . h or hold_end_y > self.dimen . h then
return false
end
2016-12-06 21:10:25 +00:00
local hold_duration = TimeVal.now ( ) - self.hold_start_tv
hold_duration = hold_duration.sec + hold_duration.usec / 1000000
2018-01-16 11:32:49 +00:00
-- If page contains an image, check if Hold is on this image and deal
-- with it directly
if self.line_num_to_image and self.line_num_to_image [ self.virtual_line_num ] then
local image = self.line_num_to_image [ self.virtual_line_num ]
if hold_end_x > self.width - image.width and hold_end_y < image.height then
-- Only if low-res image is loaded, so we have something to display
-- if high-res loading is not implemented or if its loading fails
if image.bb then
logger.dbg ( " hold on image " )
local load_and_show_image = function ( )
if not image.hi_bb and image.load_bb_func then
image.load_bb_func ( true ) -- load high res image if implemented
end
-- display hi_bb, or low-res bb if hi_bb has not been
-- made (if not implemented, or failed, or dismissed)
local ImageViewer = require ( " ui/widget/imageviewer " )
local imgviewer = ImageViewer : new {
image = image.hi_bb or image.bb , -- fallback to low-res if high-res failed
image_disposable = false , -- we may re-use our bb if called again
with_title_bar = true ,
title_text = image.title ,
caption = image.caption ,
fullscreen = true ,
}
UIManager : show ( imgviewer )
end
-- Wrap it with Trapper, as load_bb_func may be using some of its
-- dismissable methods
local Trapper = require ( " ui/trapper " )
UIManager : scheduleIn ( 0.1 , function ( ) Trapper : wrap ( load_and_show_image ) end )
-- And we return without calling the "Hold on text" callback
2018-01-29 20:27:24 +00:00
return true
2018-01-16 11:32:49 +00:00
end
end
end
2016-12-06 21:10:25 +00:00
-- Swap start and end if needed
local x0 , y0 , x1 , y1
-- first, sort by y/line_num
local start_line_num = math.ceil ( self.hold_start_y / self.line_height_px )
local end_line_num = math.ceil ( hold_end_y / self.line_height_px )
if start_line_num < end_line_num then
x0 , y0 = self.hold_start_x , self.hold_start_y
x1 , y1 = hold_end_x , hold_end_y
elseif start_line_num > end_line_num then
x0 , y0 = hold_end_x , hold_end_y
x1 , y1 = self.hold_start_x , self.hold_start_y
else -- same line_num : sort by x
if self.hold_start_x <= hold_end_x then
x0 , y0 = self.hold_start_x , self.hold_start_y
x1 , y1 = hold_end_x , hold_end_y
else
x0 , y0 = hold_end_x , hold_end_y
x1 , y1 = self.hold_start_x , self.hold_start_y
end
end
2016-12-17 17:54:40 +00:00
-- Reset start infos, so we do not reuse them and can catch
-- a missed start event
self.hold_start_x = nil
self.hold_start_y = nil
self.hold_start_tv = nil
2016-12-06 21:10:25 +00:00
-- similar code to find start or end is in _findWordEdge() helper
local sel_start_idx = self : _findWordEdge ( x0 , y0 , FIND_START )
local sel_end_idx = self : _findWordEdge ( x1 , y1 , FIND_END )
if not sel_start_idx or not sel_end_idx then
-- one or both hold points were out of text
return true
end
local selected_text = table.concat ( self.charlist , " " , sel_start_idx , sel_end_idx )
2016-12-29 08:10:38 +00:00
logger.dbg ( " onHoldReleaseText (duration: " , hold_duration , " ) : " , sel_start_idx , " > " , sel_end_idx , " = " , selected_text )
2016-12-06 21:10:25 +00:00
callback ( selected_text , hold_duration )
return true
end
function TextBoxWidget : _findWordEdge ( x , y , side )
if side ~= FIND_START and side ~= FIND_END then
return
end
local line_num = math.ceil ( y / self.line_height_px ) + self.virtual_line_num - 1
local line = self.vertical_string_list [ line_num ]
if not line then
return -- below last line : no selection
end
local char_start = line.offset
local char_end -- char_end is non-inclusive
if line_num >= # self.vertical_string_list then
2018-04-21 20:16:14 +00:00
char_end = # self.charlist + 1
2016-12-06 21:10:25 +00:00
else
char_end = self.vertical_string_list [ line_num + 1 ] . offset
end
local char_probe_x = 0
local idx = char_start
local edge_idx = nil
-- find which character the touch is holding
while idx < char_end do
2018-04-21 20:16:14 +00:00
char_probe_x = char_probe_x + self.char_width [ self.charlist [ idx ] ] + ( self.idx_pad [ idx ] or 0 )
2016-12-06 21:10:25 +00:00
if char_probe_x > x then
-- character found, find which word the character is in, and
-- get its start/end idx
2018-04-21 20:16:14 +00:00
local words = util.splitToWords ( self : _getLineText ( line ) )
2016-12-06 21:10:25 +00:00
-- words may contain separators (space, punctuation) : we don't
-- discriminate here, it's the caller job to clean what was
-- selected
local probe_idx = char_start
local next_probe_idx
for _ , w in ipairs ( words ) do
next_probe_idx = probe_idx + # util.splitToChars ( w )
if idx < next_probe_idx then
if side == FIND_START then
edge_idx = probe_idx
elseif side == FIND_END then
edge_idx = next_probe_idx - 1
end
break
end
probe_idx = next_probe_idx
end
if edge_idx then
break
end
end
idx = idx + 1
end
return edge_idx
end
2013-10-18 20:38:07 +00:00
return TextBoxWidget