Developer documentation improvements

* Fixed up all of util and added when absent
* Updated widget examples to new coding style
pull/2724/head
Frans de Jonge 7 years ago committed by Qingping Hou
parent 69b826781a
commit e9df73f6dc

@ -1,30 +1,11 @@
local Blitbuffer = require("ffi/blitbuffer") --[[--
local CenterContainer = require("ui/widget/container/centercontainer")
local Device = require("device")
local Font = require("ui/font")
local FrameContainer = require("ui/widget/container/framecontainer")
local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan")
local ImageWidget = require("ui/widget/imagewidget")
local InputContainer = require("ui/widget/container/inputcontainer")
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
local TextBoxWidget = require("ui/widget/textboxwidget")
local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local _ = require("gettext")
local Input = require("device").input
local Screen = require("device").screen
--[[
Widget that displays an informational message Widget that displays an informational message
it vanishes on key press or after a given timeout it vanishes on key press or after a given timeout
Example: Example:
local _ = require("gettext")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local _ = require("gettext")
local sample local sample
sample = InfoMessage:new{ sample = InfoMessage:new{
text = _("Some message"), text = _("Some message"),
@ -39,6 +20,26 @@ Example:
sample_input:onShowKeyboard() sample_input:onShowKeyboard()
UIManager:show(sample_input) UIManager:show(sample_input)
]] ]]
local Blitbuffer = require("ffi/blitbuffer")
local CenterContainer = require("ui/widget/container/centercontainer")
local Device = require("device")
local Font = require("ui/font")
local FrameContainer = require("ui/widget/container/framecontainer")
local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan")
local ImageWidget = require("ui/widget/imagewidget")
local InputContainer = require("ui/widget/container/inputcontainer")
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
local TextBoxWidget = require("ui/widget/textboxwidget")
local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local _ = require("gettext")
local Input = Device.input
local Screen = Device.screen
local InfoMessage = InputContainer:new{ local InfoMessage = InputContainer:new{
modal = true, modal = true,
face = Font:getFace("infofont", 25), face = Font:getFace("infofont", 25),

@ -3,8 +3,8 @@ Widget for taking user input.
Example: Example:
local _ = require("gettext")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local _ = require("gettext")
local sample_input local sample_input
sample_input = InputDialog:new{ sample_input = InputDialog:new{
title = _("Dialog title"), title = _("Dialog title"),

@ -121,13 +121,13 @@ function TextBoxWidget:_splitCharWidthList()
cur_line_text = table.concat(self.charlist, "", offset, idx - 1) cur_line_text = table.concat(self.charlist, "", offset, idx - 1)
else else
-- Backtrack the string until the length fit into one line. -- Backtrack the string until the length fit into one line.
-- We'll give next and prev chars to isSplitable() for a wiser decision -- We'll give next and prev chars to isSplittable() for a wiser decision
local c = self.char_width_list[idx].char local c = self.char_width_list[idx].char
local next_c = idx+1 <= size and self.char_width_list[idx+1].char or false local next_c = idx+1 <= size and self.char_width_list[idx+1].char or false
local prev_c = idx-1 >= 1 and self.char_width_list[idx-1].char or false local prev_c = idx-1 >= 1 and self.char_width_list[idx-1].char or false
local adjusted_idx = idx local adjusted_idx = idx
local adjusted_width = cur_line_width local adjusted_width = cur_line_width
while adjusted_idx > offset and not util.isSplitable(c, next_c, prev_c) do while adjusted_idx > offset and not util.isSplittable(c, next_c, prev_c) do
adjusted_width = adjusted_width - self.char_width_list[adjusted_idx].width adjusted_width = adjusted_width - self.char_width_list[adjusted_idx].width
adjusted_idx = adjusted_idx - 1 adjusted_idx = adjusted_idx - 1
next_c = c next_c = c
@ -136,7 +136,7 @@ function TextBoxWidget:_splitCharWidthList()
end end
if adjusted_idx == offset or adjusted_idx == idx then if adjusted_idx == offset or adjusted_idx == idx then
-- either a very long english word ocuppying more than one line, -- either a very long english word ocuppying more than one line,
-- or the excessive char is itself splitable: -- or the excessive char is itself splittable:
-- we let that excessive char for next line -- we let that excessive char for next line
cur_line_text = table.concat(self.charlist, "", offset, idx - 1) cur_line_text = table.concat(self.charlist, "", offset, idx - 1)
cur_line_width = cur_line_width - self.char_width_list[idx].width cur_line_width = cur_line_width - self.char_width_list[idx].width
@ -147,8 +147,8 @@ function TextBoxWidget:_splitCharWidthList()
cur_line_width = adjusted_width - self.char_width_list[adjusted_idx].width cur_line_width = adjusted_width - self.char_width_list[adjusted_idx].width
idx = adjusted_idx + 1 idx = adjusted_idx + 1
else else
-- we backtracked and we're below max width, we can let the -- we backtracked and we're below max width, we can leave the
-- splitable char on this line -- splittable char on this line
cur_line_text = table.concat(self.charlist, "", offset, adjusted_idx) cur_line_text = table.concat(self.charlist, "", offset, adjusted_idx)
cur_line_width = adjusted_width cur_line_width = adjusted_width
idx = adjusted_idx + 1 idx = adjusted_idx + 1

@ -15,8 +15,9 @@ function util.stripePunctuations(text)
return text:gsub("\226[\128-\131][\128-\191]", ''):gsub("^%p+", ''):gsub("%p+$", '') return text:gsub("\226[\128-\131][\128-\191]", ''):gsub("^%p+", ''):gsub("%p+$", '')
end end
--- Splits a string by a pattern
--[[-- --[[--
Splits a string by a pattern
Lua doesn't have a string.split() function and most of the time Lua doesn't have a string.split() function and most of the time
you don't really need it because string.gmatch() is enough. you don't really need it because string.gmatch() is enough.
However string.gmatch() has one significant disadvantage for me: However string.gmatch() has one significant disadvantage for me:
@ -24,9 +25,12 @@ You can't split a string while matching both the delimited
strings and the delimiters themselves without tracking positions strings and the delimiters themselves without tracking positions
and substrings. The gsplit function below takes care of and substrings. The gsplit function below takes care of
this problem. this problem.
Author: Peter Odding Author: Peter Odding
License: MIT/X11 License: MIT/X11
Source: http://snippets.luacode.org/snippets/String_splitting_130
Source: <a href="http://snippets.luacode.org/snippets/String_splitting_130">http://snippets.luacode.org/snippets/String_splitting_130</a>
]] ]]
----@string str string to split ----@string str string to split
----@param pattern the pattern to split against ----@param pattern the pattern to split against
@ -58,8 +62,11 @@ function util.gsplit(str, pattern, capture)
end) end)
end end
--- Converts seconds to a clock string. --[[--
-- Source: https://gist.github.com/jesseadams/791673 Converts seconds to a clock string.
Source: <a href="https://gist.github.com/jesseadams/791673">https://gist.github.com/jesseadams/791673</a>
]]
---- @int seconds number of seconds ---- @int seconds number of seconds
---- @bool withoutSeconds if true 00:00, if false 00:00:00 ---- @bool withoutSeconds if true 00:00, if false 00:00:00
---- @treturn string clock string in the form of 00:00 or 00:00:00 ---- @treturn string clock string in the form of 00:00 or 00:00:00
@ -91,16 +98,26 @@ function util.tableSize(T)
return count return count
end end
-- append all elements from t2 into t1 --- Append all elements from t2 into t1.
---- @param t1 Lua table
---- @param t2 Lua table
function util.arrayAppend(t1, t2) function util.arrayAppend(t1, t2)
for _, v in ipairs(t2) do for _, v in ipairs(t2) do
table.insert(t1, v) table.insert(t1, v)
end end
end end
-- Returns the index within this string of the last occurrence of the specified character --[[--
-- or -1 if the character does not occur. Gets last index of string in character
-- To find . you need to escape it.
Returns the index within this string of the last occurrence of the specified character
or -1 if the character does not occur.
To find . you need to escape it.
]]
---- @string string
---- @string ch
---- @treturn int last occurrence or -1 if not found
function util.lastIndexOf(string, ch) function util.lastIndexOf(string, ch)
local i = string:match(".*" .. ch .. "()") local i = string:match(".*" .. ch .. "()")
if i == nil then return -1 else return i - 1 end if i == nil then return -1 else return i - 1 end
@ -125,12 +142,16 @@ function util.splitToChars(text)
return tab return tab
end end
-- Tests whether c is a CJK character --- Tests whether c is a CJK character
---- @string c
---- @treturn boolean true if CJK
function util.isCJKChar(c) function util.isCJKChar(c)
return string.match(c, "[\228-\234][\128-\191].") == c return string.match(c, "[\228-\234][\128-\191].") == c
end end
-- Test whether str contains CJK characters --- Tests whether str contains CJK characters
---- @string str
---- @treturn boolean true if CJK
function util.hasCJKChar(str) function util.hasCJKChar(str)
return string.match(str, "[\228-\234][\128-\191].") ~= nil return string.match(str, "[\228-\234][\128-\191].") ~= nil
end end
@ -158,15 +179,15 @@ end
-- specific punctuation : e.g. "word :" or "word )" -- specific punctuation : e.g. "word :" or "word )"
-- (In french, there is a space before a colon, and it better -- (In french, there is a space before a colon, and it better
-- not be wrapped there.) -- not be wrapped there.)
local non_splitable_space_tailers = ":;,.!?)]}$%=-+*/|<>»”" local non_splittable_space_tailers = ":;,.!?)]}$%=-+*/|<>»”"
-- Same if a space has some specific other punctuation before it -- Same if a space has some specific other punctuation before it
local non_splitable_space_leaders = "([{$=-+*/|<>«“" local non_splittable_space_leaders = "([{$=-+*/|<>«“"
-- Similar rules exist for CJK text. Taken from : -- Similar rules exist for CJK text. Taken from :
-- https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages -- https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages
local cjk_non_splitable_tailers = table.concat( { local cjk_non_splittable_tailers = table.concat( {
-- Simplified Chinese -- Simplified Chinese
"!%),.:;?]}¢°·’\"†‡›℃∶、。〃〆〕〗〞﹚﹜!"%'),.:;?!]}~", "!%),.:;?]}¢°·’\"†‡›℃∶、。〃〆〕〗〞﹚﹜!"%'),.:;?!]}~",
-- Traditional Chinese -- Traditional Chinese
@ -177,7 +198,7 @@ local cjk_non_splitable_tailers = table.concat( {
"!%),.:;?]}¢°’\"†‡℃〆〈《「『〕!%),.:;?]}", "!%),.:;?]}¢°’\"†‡℃〆〈《「『〕!%),.:;?]}",
}) })
local cjk_non_splitable_leaders = table.concat( { local cjk_non_splittable_leaders = table.concat( {
-- Simplified Chinese -- Simplified Chinese
"$(£¥·‘\"〈《「『【〔〖〝﹙﹛$(.[{£¥", "$(£¥·‘\"〈《「『【〔〖〝﹙﹛$(.[{£¥",
-- Traditional Chinese -- Traditional Chinese
@ -188,23 +209,27 @@ local cjk_non_splitable_leaders = table.concat( {
"$([{£¥‘\"々〇〉》」〔$([{⦆¥₩#", "$([{£¥‘\"々〇〉》」〔$([{⦆¥₩#",
}) })
local cjk_non_splitable = table.concat( { local cjk_non_splittable = table.concat( {
-- Japanese -- Japanese
"—…‥〳〴〵", "—…‥〳〴〵",
}) })
-- Test whether a string could be separated by this char for multi-line rendering --- Test whether a string can be separated by this char for multi-line rendering.
-- Optional next or prev chars may be provided to help make the decision -- Optional next or prev chars may be provided to help make the decision
function util.isSplitable(c, next_c, prev_c) ---- @string c
---- @string next_c
---- @string prev_c
---- @treturn boolean true if splittable, false if not
function util.isSplittable(c, next_c, prev_c)
if util.isCJKChar(c) then if util.isCJKChar(c) then
-- a CJKChar is a word in itself, and so is splitable -- a CJKChar is a word in itself, and so is splittable
if cjk_non_splitable:find(c, 1, true) then if cjk_non_splittable:find(c, 1, true) then
-- except a few of them -- except a few of them
return false return false
elseif next_c and cjk_non_splitable_tailers:find(next_c, 1, true) then elseif next_c and cjk_non_splittable_tailers:find(next_c, 1, true) then
-- but followed by a char that is not permitted at start of line -- but followed by a char that is not permitted at start of line
return false return false
elseif prev_c and cjk_non_splitable_leaders:find(prev_c, 1, true) then elseif prev_c and cjk_non_splittable_leaders:find(prev_c, 1, true) then
-- but preceded by a char that is not permitted at end of line -- but preceded by a char that is not permitted at end of line
return false return false
else else
@ -214,10 +239,10 @@ function util.isSplitable(c, next_c, prev_c)
elseif c == " " then elseif c == " " then
-- we only split on a space (so punctuation sticks to prev word) -- we only split on a space (so punctuation sticks to prev word)
-- if next_c or prev_c is provided, we can make a better decision -- if next_c or prev_c is provided, we can make a better decision
if next_c and non_splitable_space_tailers:find(next_c, 1, true) then if next_c and non_splittable_space_tailers:find(next_c, 1, true) then
-- this space is followed by some punctuation that is better kept with us -- this space is followed by some punctuation that is better kept with us
return false return false
elseif prev_c and non_splitable_space_leaders:find(prev_c, 1, true) then elseif prev_c and non_splittable_space_leaders:find(prev_c, 1, true) then
-- this space is lead by some punctuation that is better kept with us -- this space is lead by some punctuation that is better kept with us
return false return false
else else
@ -225,13 +250,15 @@ function util.isSplitable(c, next_c, prev_c)
return true return true
end end
end end
-- otherwise, non splitable -- otherwise, non splittable
return false return false
end end
--- Gets filesystem type of a path --- Gets filesystem type of a path.
-- Checks if the path occurs in /proc/mounts --
----@string path an absolute path -- Checks if the path occurs in <code>/proc/mounts</code>
---- @string path an absolute path
---- @treturn string filesystem type
function util.getFilesystemType(path) function util.getFilesystemType(path)
local mounts = io.open("/proc/mounts", "r") local mounts = io.open("/proc/mounts", "r")
if not mounts then return nil end if not mounts then return nil end
@ -255,37 +282,55 @@ function util.getFilesystemType(path)
return type return type
end end
--- Replaces characters that are invalid filenames.
--
-- Replaces the characters <code>\/:*?"<>|</code> with an <code>_</code>.
-- These characters are problematic on Windows filesystems. On Linux only
-- <code>/</code> poses a problem.
---- @string str filename
---- @treturn string sanitized filename
function util.replaceInvalidChars(str) function util.replaceInvalidChars(str)
if str then if str then
return str:gsub('[\\,%/,:,%*,%?,%",%<,%>,%|]','_') return str:gsub('[\\,%/,:,%*,%?,%",%<,%>,%|]','_')
end end
end end
--- Replaces slash with an underscore.
---- @string str
---- @treturn string
function util.replaceSlashChar(str) function util.replaceSlashChar(str)
if str then if str then
return str:gsub('%/','_') return str:gsub('%/','_')
end end
end end
-- Split a file into its path and name --- Splits a file into its path and name
---- @string file
---- @treturn string path, filename
function util.splitFilePathName(file) function util.splitFilePathName(file)
if file == nil or file == "" then return "", "" end if file == nil or file == "" then return "", "" end
if string.find(file, "/") == nil then return "", file end if string.find(file, "/") == nil then return "", file end
return string.gsub(file, "(.*/)(.*)", "%1"), string.gsub(file, ".*/", "") return string.gsub(file, "(.*/)(.*)", "%1"), string.gsub(file, ".*/", "")
end end
-- Split a file name into its pure file name and suffix --- Splits a file name into its pure file name and suffix
---- @string file
---- @treturn string path, extension
function util.splitFileNameSuffix(file) function util.splitFileNameSuffix(file)
if file == nil or file == "" then return "", "" end if file == nil or file == "" then return "", "" end
if string.find(file, "%.") == nil then return file, "" end if string.find(file, "%.") == nil then return file, "" end
return string.gsub(file, "(.*)%.(.*)", "%1"), string.gsub(file, ".*%.", "") return string.gsub(file, "(.*)%.(.*)", "%1"), string.gsub(file, ".*%.", "")
end end
--- Gets file extension
---- @string filename
---- @treturn string extension
function util.getFileNameSuffix(file) function util.getFileNameSuffix(file)
local _, suffix = util.splitFileNameSuffix(file) local _, suffix = util.splitFileNameSuffix(file)
return suffix return suffix
end end
--- Adds > to touch menu items with a submenu
function util.getMenuText(item) function util.getMenuText(item)
local text local text
if item.text_func then if item.text_func then
@ -299,8 +344,9 @@ function util.getMenuText(item)
return text return text
end end
-- from http://notebook.kulchenko.com/programming/fixing-malformed-utf8-in-lua with modification
--- Replaces invalid UTF-8 characters with a replacement string. --- Replaces invalid UTF-8 characters with a replacement string.
--
-- Based on <a href="http://notebook.kulchenko.com/programming/fixing-malformed-utf8-in-lua">http://notebook.kulchenko.com/programming/fixing-malformed-utf8-in-lua</a>
---- @string str the string to be checked for invalid characters ---- @string str the string to be checked for invalid characters
---- @string replacement the string to replace invalid characters with ---- @string replacement the string to replace invalid characters with
---- @treturn string valid UTF-8 ---- @treturn string valid UTF-8

@ -86,7 +86,7 @@ describe("util module", function()
for i = 1, #table_chars do for i = 1, #table_chars do
c = table_chars[i] c = table_chars[i]
word = word .. c word = word .. c
if util.isSplitable(c) then if util.isSplittable(c) then
table.insert(table_of_words, word) table.insert(table_of_words, word)
word = "" word = ""
end end
@ -113,7 +113,7 @@ describe("util module", function()
for i = 1, #table_chars do for i = 1, #table_chars do
c = table_chars[i] c = table_chars[i]
word = word .. c word = word .. c
if util.isSplitable(c) then if util.isSplittable(c) then
table.insert(table_of_words, word) table.insert(table_of_words, word)
word = "" word = ""
end end
@ -134,7 +134,7 @@ describe("util module", function()
c = table_chars[i] c = table_chars[i]
next_c = i < #table_chars and table_chars[i+1] or nil next_c = i < #table_chars and table_chars[i+1] or nil
word = word .. c word = word .. c
if util.isSplitable(c, next_c) then if util.isSplittable(c, next_c) then
table.insert(table_of_words, word) table.insert(table_of_words, word)
word = "" word = ""
end end
@ -168,7 +168,7 @@ describe("util module", function()
next_c = i < #table_chars and table_chars[i+1] or nil next_c = i < #table_chars and table_chars[i+1] or nil
prev_c = i > 1 and table_chars[i-1] or nil prev_c = i > 1 and table_chars[i-1] or nil
word = word .. c word = word .. c
if util.isSplitable(c, next_c, prev_c) then if util.isSplittable(c, next_c, prev_c) then
table.insert(table_of_words, word) table.insert(table_of_words, word)
word = "" word = ""
end end

Loading…
Cancel
Save