Refactored to use strictly locals

pull/334/head
HW 11 years ago
parent 8efdff65d3
commit ef111b99c6

@ -1,9 +1,19 @@
require "ui/widget/filechooser" local InputContainer = require("ui/widget/container/inputcontainer")
require "apps/filemanager/fmhistory" local FrameContainer = require("ui/widget/container/framecontainer")
require "apps/filemanager/fmmenu" local TextWidget = require("ui/widget/textwidget")
local FileChooser = require("ui/widget/filechooser")
local VerticalGroup = require("ui/widget/verticalgroup")
local Font = require("ui/font")
local Screen = require("ui/screen")
local Geom = require("ui/geometry")
local UIManager = require("ui/uimanager")
local Event = require("ui/event")
local DocumentRegistry = require("document/documentregistry")
local FileManagerMenu = require("apps/filemanager/filemanagermenu")
local FileManagerHistory = require("apps/filemanager/filemanagerhistory")
local _ = require("gettext")
local FileManager = InputContainer:extend{
FileManager = InputContainer:extend{
title = _("FileManager"), title = _("FileManager"),
width = Screen:getWidth(), width = Screen:getWidth(),
height = Screen:getHeight(), height = Screen:getHeight(),
@ -90,3 +100,5 @@ function FileManager:onClose()
end end
return true return true
end end
return FileManager

@ -1,4 +1,10 @@
FileManagerHistory = InputContainer:extend{ local InputContainer = require("ui/widget/container/inputcontainer")
local Screen = require("ui/screen")
local UIManager = require("ui/uimanager")
local DocSettings = require("docsettings")
local _ = require("gettext")
local FileManagerHistory = InputContainer:extend{
hist_menu_title = _("History"), hist_menu_title = _("History"),
} }
@ -70,4 +76,4 @@ function FileManagerHistory:updateItemTable()
end end
end end
return FileManagerHistory

@ -1,7 +1,15 @@
require "ui/widget/menu" local CenterContainer = require("ui/widget/container/centercontainer")
require "ui/widget/touchmenu" local TouchMenu = require("ui/widget/touchmenu")
local ReaderFrontLight = require("ui/reader/readerfrontlight")
FileManagerMenu = InputContainer:extend{ local InputContainer = require("ui/widget/container/inputcontainer")
local UIManager = require("ui/uimanager")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
local _ = require("gettext")
local FileManagerMenu = InputContainer:extend{
tab_item_table = nil, tab_item_table = nil,
registered_widgets = {}, registered_widgets = {},
} }
@ -132,3 +140,4 @@ function FileManagerMenu:registerToMainMenu(widget)
table.insert(self.registered_widgets, widget) table.insert(self.registered_widgets, widget)
end end
return FileManagerMenu

@ -1,26 +1,7 @@
--[[
Inheritable abstraction for cache items
--]]
CacheItem = {
size = 64, -- some reasonable default for simple Lua values / small tables
}
function CacheItem:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function CacheItem:onFree()
end
--[[ --[[
A global LRU cache A global LRU cache
]]-- ]]--
Cache = { local Cache = {
-- cache configuration: -- cache configuration:
max_memsize = DGLOBAL_CACHE_SIZE, max_memsize = DGLOBAL_CACHE_SIZE,
-- cache state: -- cache state:
@ -89,3 +70,5 @@ function Cache:clear()
self.cache_order = {} self.cache_order = {}
self.current_memsize = 0 self.current_memsize = 0
end end
return Cache

@ -0,0 +1,19 @@
--[[
Inheritable abstraction for cache items
--]]
local CacheItem = {
size = 64, -- some reasonable default for simple Lua values / small tables
}
function CacheItem:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function CacheItem:onFree()
end
return CacheItem

@ -1,10 +1,32 @@
require "settings" -- for dump method local DocSettings = require("docsettings") -- for dump method
Dbg = { local Dbg = {
is_on = false, is_on = false,
ev_log = nil, ev_log = nil,
} }
local Dbg_mt = {}
local function LvDEBUG(lv, ...)
local line = ""
for i,v in ipairs({...}) do
if type(v) == "table" then
line = line .. " " .. DocSettings:dump(v, lv)
else
line = line .. " " .. tostring(v)
end
end
print("#"..line)
end
local function DEBUGBT()
DEBUG(debug.traceback())
end
function Dbg_mt.__call(dbg, ...)
LvDEBUG(math.huge, ...)
end
function Dbg:turnOn() function Dbg:turnOn()
self.is_on = true self.is_on = true
@ -20,22 +42,6 @@ function Dbg:logEv(ev)
self.ev_log:flush() self.ev_log:flush()
end end
function DEBUG(...) setmetatable(Dbg, Dbg_mt)
LvDEBUG(math.huge, ...)
end
function LvDEBUG(lv, ...) return Dbg
local line = ""
for i,v in ipairs({...}) do
if type(v) == "table" then
line = line .. " " .. dump(v, lv)
else
line = line .. " " .. tostring(v)
end
end
print("#"..line)
end
function DEBUGBT()
DEBUG(debug.traceback())
end

@ -1,4 +1,5 @@
DocSettings = {} local DocSettings = {}
-- lfs
function DocSettings:getHistoryPath(fullpath) function DocSettings:getHistoryPath(fullpath)
local i = #fullpath - 1 local i = #fullpath - 1
@ -67,9 +68,9 @@ function DocSettings:delSetting(key)
self.data[key] = nil self.data[key] = nil
end end
function dump(data, max_lv) function DocSettings:dump(data, max_lv)
local out = {} local out = {}
DocSettings:_serialize(data, out, 0, max_lv) self:_serialize(data, out, 0, max_lv)
return table.concat(out) return table.concat(out)
end end
@ -129,3 +130,5 @@ end
function DocSettings:close() function DocSettings:close()
self:flush() self:flush()
end end
return DocSettings

@ -1,8 +1,10 @@
require "ui/geometry" local Geom = require("ui/geometry")
require "ui/reader/readerconfig" local CreOptions = require("ui/data/creoptions")
require "ui/data/creoptions" local Document = require("document/document")
local Configurable = require("ui/reader/configurable")
-- TBD: DrawContext
CreDocument = Document:new{ local CreDocument = Document:new{
-- this is defined in kpvcrlib/crengine/crengine/include/lvdocview.h -- this is defined in kpvcrlib/crengine/crengine/include/lvdocview.h
SCROLL_VIEW_MODE = 0, SCROLL_VIEW_MODE = 0,
PAGE_VIEW_MODE = 1, PAGE_VIEW_MODE = 1,
@ -248,16 +250,20 @@ function CreDocument:setVisiblePageCount(new_count)
self._document:setVisiblePageCount(new_count) self._document:setVisiblePageCount(new_count)
end end
DocumentRegistry:addProvider("txt", "application/txt", CreDocument) function CreDocument:register(registry)
DocumentRegistry:addProvider("epub", "application/epub", CreDocument) registry:addProvider("txt", "application/txt", self)
DocumentRegistry:addProvider("html", "application/html", CreDocument) registry:addProvider("epub", "application/epub", self)
DocumentRegistry:addProvider("htm", "application/htm", CreDocument) registry:addProvider("html", "application/html", self)
DocumentRegistry:addProvider("zip", "application/zip", CreDocument) registry:addProvider("htm", "application/htm", self)
DocumentRegistry:addProvider("rtf", "application/rtf", CreDocument) registry:addProvider("zip", "application/zip", self)
DocumentRegistry:addProvider("mobi", "application/mobi", CreDocument) registry:addProvider("rtf", "application/rtf", self)
DocumentRegistry:addProvider("prc", "application/prc", CreDocument) registry:addProvider("mobi", "application/mobi", self)
DocumentRegistry:addProvider("azw", "application/azw", CreDocument) registry:addProvider("prc", "application/prc", self)
DocumentRegistry:addProvider("chm", "application/chm", CreDocument) registry:addProvider("azw", "application/azw", self)
DocumentRegistry:addProvider("pdb", "application/pdb", CreDocument) registry:addProvider("chm", "application/chm", self)
DocumentRegistry:addProvider("doc", "application/doc", CreDocument) registry:addProvider("pdb", "application/pdb", self)
DocumentRegistry:addProvider("tcr", "application/tcr", CreDocument) registry:addProvider("doc", "application/doc", self)
registry:addProvider("tcr", "application/tcr", self)
end
return CreDocument

@ -1,10 +1,13 @@
require "cache" local Geom = require("ui/geometry")
require "ui/geometry" local Cache = require("cache")
require "ui/reader/readerconfig" local CacheItem = require("cacheitem")
require "ui/data/koptoptions" local KoptOptions = require("ui/data/koptoptions")
require "document/koptinterface" local KoptInterface = require("document/koptinterface")
local Document = require("document/document")
DjvuDocument = Document:new{ local Configurable = require("ui/reader/configurable")
-- TBD: DrawContext
local DjvuDocument = Document:new{
_document = false, _document = false,
-- libdjvulibre manages its own additional cache, default value is hard written in c module. -- libdjvulibre manages its own additional cache, default value is hard written in c module.
djvulibre_cache_size = nil, djvulibre_cache_size = nil,
@ -14,6 +17,16 @@ DjvuDocument = Document:new{
koptinterface = KoptInterface, koptinterface = KoptInterface,
} }
-- check DjVu magic string to validate
local function validDjvuFile(filename)
f = io.open(filename, "r")
if not f then return false end
local magic = f:read(8)
f:close()
if not magic or magic ~= "AT&TFORM" then return false end
return true
end
function DjvuDocument:init() function DjvuDocument:init()
self.configurable:loadDefaults(self.options) self.configurable:loadDefaults(self.options)
if not validDjvuFile(self.file) then if not validDjvuFile(self.file) then
@ -33,16 +46,6 @@ function DjvuDocument:init()
self:_readMetadata() self:_readMetadata()
end end
-- check DjVu magic string to validate
function validDjvuFile(filename)
f = io.open(filename, "r")
if not f then return false end
local magic = f:read(8)
f:close()
if not magic or magic ~= "AT&TFORM" then return false end
return true
end
function DjvuDocument:invertTextYAxel(pageno, text_table) function DjvuDocument:invertTextYAxel(pageno, text_table)
local _, height = self.doc:getOriginalPageSize(pageno) local _, height = self.doc:getOriginalPageSize(pageno)
for _,text in pairs(text_table) do for _,text in pairs(text_table) do
@ -105,4 +108,8 @@ function DjvuDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma
return self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode) return self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
end end
DocumentRegistry:addProvider("djvu", "application/djvu", DjvuDocument) function DjvuDocument:register(registry)
registry:addProvider("djvu", "application/djvu", self)
end
return DjvuDocument

@ -1,46 +1,12 @@
require "../math" local Cache = require("cache")
local CacheItem = require("cacheitem")
--[[ local TileCacheItem = require("document/tilecacheitem")
This is a registry for document providers local Geom = require("ui/geometry")
]]--
DocumentRegistry = {
providers = { }
}
function DocumentRegistry:addProvider(extension, mimetype, provider)
table.insert(self.providers, { extension = extension, mimetype = mimetype, provider = provider })
end
function DocumentRegistry:getProvider(file)
-- TODO: some implementation based on mime types?
local extension = string.lower(string.match(file, ".+%.([^.]+)") or "")
for _, provider in ipairs(self.providers) do
if extension == provider.extension then
return provider.provider
end
end
end
function DocumentRegistry:openDocument(file)
local provider = self:getProvider(file)
if provider ~= nil then
return provider:new{file = file}
end
end
TileCacheItem = CacheItem:new{}
function TileCacheItem:onFree()
if self.bb.free then
DEBUG("free blitbuffer", self.bb)
self.bb:free()
end
end
--[[ --[[
This is an abstract interface to a document This is an abstract interface to a document
]]-- ]]--
Document = { local Document = {
-- file name -- file name
file = nil, file = nil,
@ -304,8 +270,4 @@ function Document:getPageText(pageno)
return text return text
end end
-- load implementations: return Document
require "document/pdfdocument"
require "document/djvudocument"
require "document/credocument"

@ -0,0 +1,35 @@
--[[
This is a registry for document providers
]]--
local DocumentRegistry = {
providers = { }
}
function DocumentRegistry:addProvider(extension, mimetype, provider)
table.insert(self.providers, { extension = extension, mimetype = mimetype, provider = provider })
end
function DocumentRegistry:getProvider(file)
-- TODO: some implementation based on mime types?
local extension = string.lower(string.match(file, ".+%.([^.]+)") or "")
for _, provider in ipairs(self.providers) do
if extension == provider.extension then
return provider.provider
end
end
end
function DocumentRegistry:openDocument(file)
local provider = self:getProvider(file)
if provider ~= nil then
return provider:new{file = file}
end
end
-- load implementations:
require("document/pdfdocument"):register(DocumentRegistry)
require("document/djvudocument"):register(DocumentRegistry)
require("document/credocument"):register(DocumentRegistry)
return DocumentRegistry

@ -1,11 +1,10 @@
require "dbg" local Document = require("document/document")
require "cache" local Cache = require("cache")
require "ui/geometry" local CacheItem = require("cacheitem")
require "ui/device" local Screen = require("ui/screen")
require "ui/screen" -- TBD: KOPTContext
require "ui/reader/readerconfig"
local KoptInterface = {
KoptInterface = {
ocrengine = "ocrengine", ocrengine = "ocrengine",
tessocr_data = "data", tessocr_data = "data",
ocr_lang = "eng", ocr_lang = "eng",
@ -15,7 +14,7 @@ KoptInterface = {
screen_dpi = Screen:getDPI(), screen_dpi = Screen:getDPI(),
} }
ContextCacheItem = CacheItem:new{} local ContextCacheItem = CacheItem:new{}
function ContextCacheItem:onFree() function ContextCacheItem:onFree()
if self.kctx.free then if self.kctx.free then
@ -24,7 +23,7 @@ function ContextCacheItem:onFree()
end end
end end
OCREngine = CacheItem:new{} local OCREngine = CacheItem:new{}
function OCREngine:onFree() function OCREngine:onFree()
if self.ocrengine.freeOCR then if self.ocrengine.freeOCR then
@ -811,3 +810,5 @@ function KoptInterface:logMemoryUsage(pageno)
log_file:close() log_file:close()
end end
end end
return KoptInterface

@ -1,10 +1,12 @@
require "cache" local Cache = require("cache")
require "ui/geometry" local CacheItem = require("cacheitem")
require "ui/reader/readerconfig" local KoptOptions = require("ui/data/koptoptions")
require "ui/data/koptoptions" local KoptInterface = require("document/koptinterface")
require "document/koptinterface" local Document = require("document/document")
local Configurable = require("ui/reader/configurable")
PdfDocument = Document:new{ -- TBD: DrawContext
local PdfDocument = Document:new{
_document = false, _document = false,
-- muPDF manages its own additional cache -- muPDF manages its own additional cache
mupdf_cache_size = 5 * 1024 * 1024, mupdf_cache_size = 5 * 1024 * 1024,
@ -111,5 +113,9 @@ function PdfDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma,
return self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode) return self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
end end
DocumentRegistry:addProvider("pdf", "application/pdf", PdfDocument) function PdfDocument:register(registry)
DocumentRegistry:addProvider("cbz", "application/cbz", PdfDocument) registry:addProvider("pdf", "application/pdf", self)
registry:addProvider("cbz", "application/cbz", self)
end
return PdfDocument

@ -0,0 +1,12 @@
local CacheItem = require("cacheitem")
local TileCacheItem = CacheItem:new{}
function TileCacheItem:onFree()
if self.bb.free then
DEBUG("free blitbuffer", self.bb)
self.bb:free()
end
end
return TileCacheItem

@ -1,11 +1,16 @@
lua_gettext.init("./i18n", "koreader") lua_gettext.init("./i18n", "koreader")
local GetText = {}
local GetText_mt = {}
function _(string) function GetText_mt.__call(gettext, string)
return lua_gettext.translate(string) return lua_gettext.translate(string)
end end
function gettextChangeLang(new_lang) function GetText.changeLang(new_lang)
lua_gettext.change_lang(new_lang) lua_gettext.change_lang(new_lang)
end end
setmetatable(GetText, GetText_mt)
return GetText

@ -2,7 +2,9 @@
Simple math helper function Simple math helper function
]]-- ]]--
function math.roundAwayFromZero(num) local Math = {}
function Math.roundAwayFromZero(num)
if num > 0 then if num > 0 then
return math.ceil(num) return math.ceil(num)
else else
@ -10,11 +12,11 @@ function math.roundAwayFromZero(num)
end end
end end
function math.round(num) function Math.round(num)
return math.floor(num + 0.5) return math.floor(num + 0.5)
end end
function math.oddEven(number) function Math.oddEven(number)
if number % 2 == 1 then if number % 2 == 1 then
return "odd" return "odd"
else else
@ -22,7 +24,7 @@ function math.oddEven(number)
end end
end end
function tmin_max(tab, func, op) local function tmin_max(tab, func, op)
if #tab == 0 then return nil, nil end if #tab == 0 then return nil, nil end
local index, value = 1, tab[1] local index, value = 1, tab[1]
for i = 2, #tab do for i = 2, #tab do
@ -47,7 +49,7 @@ end
Return the minimum element of a table. Return the minimum element of a table.
The optional argument func specifies a one-argument ordering function. The optional argument func specifies a one-argument ordering function.
]]-- ]]--
function math.tmin(tab, func) function Math.tmin(tab, func)
return tmin_max(tab, func, "min") return tmin_max(tab, func, "min")
end end
@ -55,6 +57,8 @@ end
Return the maximum element of a table. Return the maximum element of a table.
The optional argument func specifies a one-argument ordering function. The optional argument func specifies a one-argument ordering function.
]]-- ]]--
function math.tmax(tab, func) function Math.tmax(tab, func)
return tmin_max(tab, func, "max") return tmin_max(tab, func, "max")
end end
return Math

@ -1,5 +1,7 @@
require "ui/screen" local Screen = require("ui/screen")
require "ui/data/strings" local S = require("ui/data/strings")
local _ = require("gettext")
-- add multiply operator to Aa dict -- add multiply operator to Aa dict
local Aa = setmetatable({"Aa"}, { local Aa = setmetatable({"Aa"}, {
@ -12,15 +14,15 @@ local Aa = setmetatable({"Aa"}, {
end end
}) })
CreOptions = { local CreOptions = {
prefix = 'copt', prefix = 'copt',
{ {
icon = "resources/icons/appbar.transform.rotate.right.large.png", icon = "resources/icons/appbar.transform.rotate.right.large.png",
options = { options = {
{ {
name = "screen_mode", name = "screen_mode",
name_text = SCREEN_MODE_STR, name_text = S.SCREEN_MODE,
toggle = {PORTRAIT_STR, LANDSCAPE_STR}, toggle = {S.PORTRAIT, S.LANDSCAPE},
args = {"portrait", "landscape"}, args = {"portrait", "landscape"},
default_arg = "portrait", default_arg = "portrait",
current_func = function() return Screen:getScreenMode() end, current_func = function() return Screen:getScreenMode() end,
@ -33,16 +35,16 @@ CreOptions = {
options = { options = {
{ {
name = "line_spacing", name = "line_spacing",
name_text = LINE_SPACING_STR, name_text = S.LINE_SPACING,
item_text = {DECREASE_STR, INCREASE_STR}, item_text = {S.DECREASE, S.INCREASE},
args = {"decrease", "increase"}, args = {"decrease", "increase"},
default_arg = nil, default_arg = nil,
event = "ChangeLineSpace", event = "ChangeLineSpace",
}, },
{ {
name = "page_margins", name = "page_margins",
name_text = PAGE_MARGIN_STR, name_text = S.PAGE_MARGIN,
toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = { values = {
{6, 5, 2, 5}, {6, 5, 2, 5},
{15, 10, 10, 10}, {15, 10, 10, 10},
@ -79,8 +81,8 @@ CreOptions = {
options = { options = {
{ {
name = "font_weight", name = "font_weight",
name_text = FONT_WEIGHT_STR, name_text = S.FONT_WEIGHT,
item_text = {TOGGLE_BOLD_STR}, item_text = {S.TOGGLE_BOLD},
-- args is indeed not used, we put here just to keep the -- args is indeed not used, we put here just to keep the
-- UI happy. -- UI happy.
args = {1}, args = {1},
@ -89,8 +91,8 @@ CreOptions = {
}, },
{ {
name = "font_gamma", name = "font_gamma",
name_text = GAMMA_STR, name_text = S.GAMMA,
item_text = {DECREASE_STR, INCREASE_STR}, item_text = {S.DECREASE, S.INCREASE},
args = {"decrease", "increase"}, args = {"decrease", "increase"},
default_arg = nil, default_arg = nil,
event = "ChangeFontGamma", event = "ChangeFontGamma",
@ -102,8 +104,8 @@ CreOptions = {
options = { options = {
{ {
name = "view_mode", name = "view_mode",
name_text = VIEW_MODE_STR, name_text = S.VIEW_MODE,
toggle = {VIEW_SCROLL_STR, VIEW_PAGE_STR}, toggle = {S.VIEW_SCROLL, S.VIEW_PAGE},
values = {1, 0}, values = {1, 0},
default_value = 0, default_value = 0,
args = {"scroll", "page"}, args = {"scroll", "page"},
@ -112,8 +114,8 @@ CreOptions = {
}, },
{ {
name = "embedded_css", name = "embedded_css",
name_text = EMBEDDED_STYLE_STR, name_text = S.EMBEDDED_STYLE,
toggle = {ON_STR, OFF_STR}, toggle = {S.ON, S.OFF},
values = {1, 0}, values = {1, 0},
default_value = 1, default_value = 1,
args = {true, false}, args = {true, false},
@ -123,3 +125,5 @@ CreOptions = {
}, },
}, },
} }
return CreOptions

@ -1,15 +1,17 @@
require "ui/screen" local Screen = require("ui/screen")
require "ui/data/strings" local S = require("ui/data/strings")
KoptOptions = { local _ = require("gettext")
local KoptOptions = {
prefix = 'kopt', prefix = 'kopt',
{ {
icon = "resources/icons/appbar.transform.rotate.right.large.png", icon = "resources/icons/appbar.transform.rotate.right.large.png",
options = { options = {
{ {
name = "screen_mode", name = "screen_mode",
name_text = SCREEN_MODE_STR, name_text = S.SCREEN_MODE,
toggle = {PORTRAIT_STR, LANDSCAPE_STR}, toggle = {S.PORTRAIT, S.LANDSCAPE},
alternate = false, alternate = false,
args = {"portrait", "landscape"}, args = {"portrait", "landscape"},
default_arg = "portrait", default_arg = "portrait",
@ -23,9 +25,9 @@ KoptOptions = {
options = { options = {
{ {
name = "trim_page", name = "trim_page",
name_text = PAGE_CROP_STR, name_text = S.PAGE_CROP,
width = 225, width = 225,
toggle = {MANUAL_STR, AUTO_STR, SEMIAUTO_STR}, toggle = {S.MANUAL, S.AUTO, S.SEMIAUTO},
alternate = false, alternate = false,
values = {0, 1, 2}, values = {0, 1, 2},
default_value = DKOPTREADER_CONFIG_TRIM_PAGE, default_value = DKOPTREADER_CONFIG_TRIM_PAGE,
@ -39,8 +41,8 @@ KoptOptions = {
options = { options = {
{ {
name = "full_screen", name = "full_screen",
name_text = FULL_SCREEN_STR, name_text = S.FULL_SCREEN,
toggle = {ON_STR, OFF_STR}, toggle = {S.ON, S.OFF},
values = {1, 0}, values = {1, 0},
default_value = DFULL_SCREEN, default_value = DFULL_SCREEN,
event = "SetFullScreen", event = "SetFullScreen",
@ -48,8 +50,8 @@ KoptOptions = {
}, },
{ {
name = "page_scroll", name = "page_scroll",
name_text = SCROLL_MODE_STR, name_text = S.SCROLL_MODE,
toggle = {ON_STR, OFF_STR}, toggle = {S.ON, S.OFF},
values = {1, 0}, values = {1, 0},
default_value = DSCROLL_MODE, default_value = DSCROLL_MODE,
event = "ToggleScrollMode", event = "ToggleScrollMode",
@ -57,22 +59,22 @@ KoptOptions = {
}, },
{ {
name = "page_margin", name = "page_margin",
name_text = PAGE_MARGIN_STR, name_text = S.PAGE_MARGIN,
toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = {0.05, 0.10, 0.15}, values = {0.05, 0.10, 0.15},
default_value = DKOPTREADER_CONFIG_PAGE_MARGIN, default_value = DKOPTREADER_CONFIG_PAGE_MARGIN,
event = "MarginUpdate", event = "MarginUpdate",
}, },
{ {
name = "line_spacing", name = "line_spacing",
name_text = LINE_SPACING_STR, name_text = S.LINE_SPACING,
toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = {1.0, 1.2, 1.4}, values = {1.0, 1.2, 1.4},
default_value = DKOPTREADER_CONFIG_LINE_SPACING, default_value = DKOPTREADER_CONFIG_LINE_SPACING,
}, },
{ {
name = "max_columns", name = "max_columns",
name_text = COLUMNS_STR, name_text = S.COLUMNS,
item_icons = { item_icons = {
"resources/icons/appbar.column.one.png", "resources/icons/appbar.column.one.png",
"resources/icons/appbar.column.two.png", "resources/icons/appbar.column.two.png",
@ -83,7 +85,7 @@ KoptOptions = {
}, },
{ {
name = "justification", name = "justification",
name_text = TEXT_ALIGN_STR, name_text = S.TEXT_ALIGN,
item_icons = { item_icons = {
"resources/icons/appbar.align.auto.png", "resources/icons/appbar.align.auto.png",
"resources/icons/appbar.align.left.png", "resources/icons/appbar.align.left.png",
@ -112,8 +114,8 @@ KoptOptions = {
}, },
{ {
name = "font_fine_tune", name = "font_fine_tune",
name_text = FONTSIZE_FINE_TUNING_STR, name_text = S.FONTSIZE_FINE_TUNING,
toggle = {DECREASE_STR, INCREASE_STR}, toggle = {S.DECREASE, S.INCREASE},
values = {-0.05, 0.05}, values = {-0.05, 0.05},
default_value = 0.05, default_value = 0.05,
event = "FineTuningFontSize", event = "FineTuningFontSize",
@ -128,9 +130,9 @@ KoptOptions = {
options = { options = {
{ {
name = "contrast", name = "contrast",
name_text = CONTRAST_STR, name_text = S.CONTRAST,
name_align_right = 0.2, name_align_right = 0.2,
item_text = {LIGHTEST_STR , LIGHTER_STR, DEFAULT_STR, DARKER_STR, DARKEST_STR}, item_text = {S.LIGHTEST , S.LIGHTER, S.DEFAULT, S.DARKER, S.DARKEST},
item_font_size = 18, item_font_size = 18,
item_align_center = 0.8, item_align_center = 0.8,
values = {2.0, 1.5, 1.0, 0.5, 0.2}, values = {2.0, 1.5, 1.0, 0.5, 0.2},
@ -146,7 +148,7 @@ KoptOptions = {
{ {
name = "text_wrap", name = "text_wrap",
name_text = _("Reflow"), name_text = _("Reflow"),
toggle = {ON_STR, OFF_STR}, toggle = {S.ON, S.OFF},
values = {1, 0}, values = {1, 0},
default_value = DKOPTREADER_CONFIG_TEXT_WRAP, default_value = DKOPTREADER_CONFIG_TEXT_WRAP,
events = { events = {
@ -163,7 +165,7 @@ KoptOptions = {
}, },
{ {
name="doc_language", name="doc_language",
name_text = DOC_LANG_STR, name_text = S.DOC_LANG,
toggle = DKOPTREADER_CONFIG_DOC_LANGS_TEXT, toggle = DKOPTREADER_CONFIG_DOC_LANGS_TEXT,
values = DKOPTREADER_CONFIG_DOC_LANGS_CODE, values = DKOPTREADER_CONFIG_DOC_LANGS_CODE,
default_value = DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE, default_value = DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE,
@ -172,45 +174,45 @@ KoptOptions = {
}, },
{ {
name="screen_rotation", name="screen_rotation",
name_text = VERTICAL_TEXT_STR, name_text = S.VERTICAL_TEXT,
toggle = {ON_STR, OFF_STR}, toggle = {S.ON, S.OFF},
values = {90, 0}, values = {90, 0},
default_value = 0, default_value = 0,
}, },
{ {
name = "word_spacing", name = "word_spacing",
name_text = WORD_GAP_STR, name_text = S.WORD_GAP,
toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = DKOPTREADER_CONFIG_WORD_SAPCINGS, values = DKOPTREADER_CONFIG_WORD_SAPCINGS,
default_value = DKOPTREADER_CONFIG_DEFAULT_WORD_SAPCING, default_value = DKOPTREADER_CONFIG_DEFAULT_WORD_SAPCING,
}, },
{ {
name = "defect_size", name = "defect_size",
name_text = DEFECT_SIZE_STR, name_text = S.DEFECT_SIZE,
toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = {1.0, 3.0, 5.0}, values = {1.0, 3.0, 5.0},
default_value = DKOPTREADER_CONFIG_DEFECT_SIZE, default_value = DKOPTREADER_CONFIG_DEFECT_SIZE,
event = "DefectSizeUpdate", event = "DefectSizeUpdate",
}, },
{ {
name = "quality", name = "quality",
name_text = RENDER_QUALITY_STR, name_text = S.RENDER_QUALITY,
toggle = {LOW_STR, DEFAULT_STR, HIGH_STR}, toggle = {S.LOW, S.DEFAULT, S.HIGH},
values={0.5, 1.0, 1.5}, values={0.5, 1.0, 1.5},
default_value = DKOPTREADER_CONFIG_RENDER_QUALITY, default_value = DKOPTREADER_CONFIG_RENDER_QUALITY,
}, },
{ {
name = "auto_straighten", name = "auto_straighten",
name_text = AUTO_STRAIGHTEN_STR, name_text = S.AUTO_STRAIGHTEN,
toggle = {ZERO_DEG_STR, FIVE_DEG_STR, TEN_DEG_STR}, toggle = {S.ZERO_DEG, S.FIVE_DEG, S.TEN_DEG},
values = {0, 5, 10}, values = {0, 5, 10},
default_value = DKOPTREADER_CONFIG_AUTO_STRAIGHTEN, default_value = S.DKOPTREADER_CONFIG_AUTOAIGHTEN,
show = false, show = false,
}, },
{ {
name = "detect_indent", name = "detect_indent",
name_text = INDENTATION_STR, name_text = S.INDENTATION,
toggle = {ON_STR, OFF_STR}, toggle = {S.ON, S.OFF},
values = {1, 0}, values = {1, 0},
default_value = DKOPTREADER_CONFIG_DETECT_INDENT, default_value = DKOPTREADER_CONFIG_DETECT_INDENT,
show = false, show = false,
@ -218,3 +220,5 @@ KoptOptions = {
} }
}, },
} }
return KoptOptions

@ -1,49 +1,54 @@
local _ = require("gettext")
SCREEN_MODE_STR = _("Screen Mode") local S = {}
PAGE_CROP_STR = _("Page Crop")
FULL_SCREEN_STR = _("Full Screen")
SCROLL_MODE_STR = _("Scroll Mode")
PAGE_MARGIN_STR = _("Page Margin")
LINE_SPACING_STR = _("Line Spacing")
COLUMNS_STR = _("Columns")
TEXT_ALIGN_STR = _("Text Align")
FONTSIZE_FINE_TUNING_STR = _("Fine Tuning")
CONTRAST_STR = _("Contrast")
REFLOW_STR = _("Reflow")
DOC_LANG_STR = _("Document Language")
VERTICAL_TEXT_STR = _("Vertical Text")
WORD_GAP_STR = _("Word Gap")
DEFECT_SIZE_STR = _("Defect Size")
RENDER_QUALITY_STR = _("Render Quality")
AUTO_STRAIGHTEN_STR = _("Auto Straighten")
INDENTATION_STR = _("Indentation")
FONT_WEIGHT_STR = _("Font weight")
GAMMA_STR = _("Gamma")
VIEW_MODE_STR = _("View mode")
EMBEDDED_STYLE_STR = _("Embedded style")
ON_STR = _("on") S.SCREEN_MODE = _("Screen Mode")
OFF_STR = _("off") S.PAGE_CROP = _("Page Crop")
AUTO_STR = _("auto") S.FULL_SCREEN = _("Full Screen")
MANUAL_STR = _("manual") S.SCROLL_MODE = _("Scroll Mode")
SEMIAUTO_STR = _("semi-auto") S.PAGE_MARGIN = _("Page Margin")
SMALL_STR = _("small") S.LINE_SPACING = _("Line Spacing")
MEDIUM_STR = _("medium") S.COLUMNS = _("Columns")
LARGE_STR = _("large") S.TEXT_ALIGN = _("Text Align")
DECREASE_STR = _("decrease") S.FONTSIZE_FINE_TUNING = _("Fine Tuning")
INCREASE_STR = _("increase") S.CONTRAST = _("Contrast")
LIGHTEST_STR = _("lightest") S.REFLOW = _("Reflow")
LIGHTER_STR = _("lighter") S.DOC_LANG = _("Document Language")
DEFAULT_STR = _("default") S.VERTICAL_TEXT = _("Vertical Text")
DARKER_STR = _("darker") S.WORD_GAP = _("Word Gap")
DARKEST_STR = _("darkest") S.DEFECT_SIZE = _("Defect Size")
LOW_STR = _("low") S.RENDER_QUALITY = _("Render Quality")
HIGH_STR = _("high") S.AUTO_STRAIGHTEN = _("Auto Straighten")
ZERO_DEG_STR = _("0 deg") S.INDENTATION = _("Indentation")
FIVE_DEG_STR = _("5 deg") S.FONT_WEIGHT = _("Font weight")
TEN_DEG_STR = _("10 deg") S.GAMMA = _("Gamma")
PORTRAIT_STR = _("portrait") S.VIEW_MODE = _("View mode")
LANDSCAPE_STR = _("landscape") S.EMBEDDED_STYLE = _("Embedded style")
TOGGLE_BOLD_STR = _("toggle bold")
VIEW_SCROLL_STR = _("scroll") S.ON = _("on")
VIEW_PAGE_STR = _("page") S.OFF = _("off")
S.AUTO = _("auto")
S.MANUAL = _("manual")
S.SEMIAUTO = _("semi-auto")
S.SMALL = _("small")
S.MEDIUM = _("medium")
S.LARGE = _("large")
S.DECREASE = _("decrease")
S.INCREASE = _("increase")
S.LIGHTEST = _("lightest")
S.LIGHTER = _("lighter")
S.DEFAULT = _("default")
S.DARKER = _("darker")
S.DARKEST = _("darkest")
S.LOW = _("low")
S.HIGH = _("high")
S.ZERO_DEG = _("0 deg")
S.FIVE_DEG = _("5 deg")
S.TEN_DEG = _("10 deg")
S.PORTRAIT = _("portrait")
S.LANDSCAPE = _("landscape")
S.TOGGLE_BOLD = _("toggle bold")
S.VIEW_SCROLL = _("scroll")
S.VIEW_PAGE = _("page")
return S

@ -1,4 +1,12 @@
Device = { local KindleFrontLight = require("ui/device/kindlefrontlight")
local KoboFrontLight = require("ui/device/kobofrontlight")
local BaseFrontLight = require("ui/device/basefrontlight")
-- Screen
-- util
-- lfs
local Device = {
screen_saver_mode = false, screen_saver_mode = false,
charging_mode = false, charging_mode = false,
survive_screen_saver = false, survive_screen_saver = false,
@ -8,25 +16,6 @@ Device = {
frontlight = nil, frontlight = nil,
} }
BaseFrontLight = {
min = 1, max = 10,
intensity = nil,
}
KindleFrontLight = {
min = 0, max = 24,
kpw_fl = "/sys/devices/system/fl_tps6116x/fl_tps6116x0/fl_intensity",
intensity = nil,
lipc_handle = nil,
}
KoboFrontLight = {
min = 1, max = 100,
intensity = 20,
restore_settings = true,
fl = nil,
}
function Device:getModel() function Device:getModel()
if self.model then return self.model end if self.model then return self.model end
if util.isEmulated() then if util.isEmulated() then
@ -219,58 +208,4 @@ function Device:getFrontlight()
return self.frontlight return self.frontlight
end end
function BaseFrontLight:init() end return Device
function BaseFrontLight:toggle() end
function BaseFrontLight:setIntensityHW() end
function BaseFrontLight:setIntensity(intensity)
intensity = intensity < self.min and self.min or intensity
intensity = intensity > self.max and self.max or intensity
self.intensity = intensity
self:setIntensityHW()
end
function KindleFrontLight:init()
require "liblipclua"
self.lipc_handle = lipc.init("com.github.koreader")
if self.lipc_handle then
self.intensity = self.lipc_handle:get_int_property("com.lab126.powerd", "flIntensity")
end
end
function KindleFrontLight:toggle()
local f = io.open(self.kpw_fl, "r")
local sysint = tonumber(f:read("*all"):match("%d+"))
f:close()
if sysint == 0 then
self:setIntensity(self.intensity)
else
os.execute("echo -n 0 > " .. self.kpw_fl)
end
end
KindleFrontLight.setIntensity = BaseFrontLight.setIntensity
function KindleFrontLight:setIntensityHW()
if self.lipc_handle ~= nil then
self.lipc_handle:set_int_property("com.lab126.powerd", "flIntensity", self.intensity)
end
end
function KoboFrontLight:init()
self.fl = kobolight.open()
end
function KoboFrontLight:toggle()
if self.fl ~= nil then
self.fl:toggle()
end
end
KoboFrontLight.setIntensity = BaseFrontLight.setIntensity
function KoboFrontLight:setIntensityHW()
if self.fl ~= nil then
self.fl:setBrightness(self.intensity)
end
end

@ -0,0 +1,17 @@
local BaseFrontLight = {
min = 1, max = 10,
intensity = nil,
}
function BaseFrontLight:init() end
function BaseFrontLight:toggle() end
function BaseFrontLight:setIntensityHW() end
function BaseFrontLight:setIntensity(intensity)
intensity = intensity < self.min and self.min or intensity
intensity = intensity > self.max and self.max or intensity
self.intensity = intensity
self:setIntensityHW()
end
return BaseFrontLight

@ -0,0 +1,38 @@
local BaseFrontLight = require("ui/device/basefrontlight")
-- liblipclua, see require below
local KindleFrontLight = {
min = 0, max = 24,
kpw_fl = "/sys/devices/system/fl_tps6116x/fl_tps6116x0/fl_intensity",
intensity = nil,
lipc_handle = nil,
}
function KindleFrontLight:init()
require "liblipclua"
self.lipc_handle = lipc.init("com.github.koreader")
if self.lipc_handle then
self.intensity = self.lipc_handle:get_int_property("com.lab126.powerd", "flIntensity")
end
end
function KindleFrontLight:toggle()
local f = io.open(self.kpw_fl, "r")
local sysint = tonumber(f:read("*all"):match("%d+"))
f:close()
if sysint == 0 then
self:setIntensity(self.intensity)
else
os.execute("echo -n 0 > " .. self.kpw_fl)
end
end
KindleFrontLight.setIntensity = BaseFrontLight.setIntensity
function KindleFrontLight:setIntensityHW()
if self.lipc_handle ~= nil then
self.lipc_handle:set_int_property("com.lab126.powerd", "flIntensity", self.intensity)
end
end
return KindleFrontLight

@ -0,0 +1,28 @@
local BaseFrontLight = require("ui/device/basefrontlight")
local KoboFrontLight = {
min = 1, max = 100,
intensity = 20,
restore_settings = true,
fl = nil,
}
function KoboFrontLight:init()
self.fl = kobolight.open()
end
function KoboFrontLight:toggle()
if self.fl ~= nil then
self.fl:toggle()
end
end
KoboFrontLight.setIntensity = BaseFrontLight.setIntensity
function KoboFrontLight:setIntensityHW()
if self.fl ~= nil then
self.fl:setBrightness(self.intensity)
end
end
return KoboFrontLight

@ -7,7 +7,7 @@ In order to see how event propagation works and how to make
widgets event-aware see the implementation in WidgetContainer widgets event-aware see the implementation in WidgetContainer
below. below.
]] ]]
Event = {} local Event = {}
function Event:new(name, ...) function Event:new(name, ...)
local o = { local o = {
@ -18,3 +18,5 @@ function Event:new(name, ...)
self.__index = self self.__index = self
return o return o
end end
return Event

@ -1,6 +1,7 @@
require "dbg" -- for DEBUG() require "dbg" -- for DEBUG()
local Screen = require("ui/screen")
Font = { local Font = {
fontmap = { fontmap = {
-- default font for menu contents -- default font for menu contents
cfont = "freefont/FreeSerif.ttf", cfont = "freefont/FreeSerif.ttf",
@ -50,7 +51,7 @@ function Font:getFace(font, size)
font = self.cfont font = self.cfont
end end
local size = scaleByDPI(size) local size = Screen:scaleByDPI(size)
local face = self.faces[font..size] local face = self.faces[font..size]
-- build face if not found -- build face if not found
@ -98,3 +99,5 @@ function Font:update()
self.faces = {} self.faces = {}
clearGlyphCache() clearGlyphCache()
end end
return Font

@ -9,7 +9,7 @@ some behaviour is defined for dimensions { w = ..., h = ... }
just use it on simple tables that have x, y and/or w, h just use it on simple tables that have x, y and/or w, h
or define your own types using this as a metatable or define your own types using this as a metatable
]]-- ]]--
Geom = { local Geom = {
x = 0, x = 0,
y = 0, y = 0,
w = 0, w = 0,
@ -305,3 +305,5 @@ function Geom:center()
w = 0, h = 0, w = 0, h = 0,
} }
end end
return Geom

@ -1,46 +1,6 @@
require "ui/geometry" local Geom = require("ui/geometry")
local TimeVal = require("ui/timeval")
GestureRange = { local Screen = require("ui/screen")
ges = nil,
-- spatial range limits the gesture emitting position
range = nil,
-- temproal range limits the gesture emitting rate
rate = nil,
-- span limits of this gesture
scale = nil,
}
function GestureRange:new(o)
local o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function GestureRange:match(gs)
if gs.ges ~= self.ges then
return false
end
if self.range then
if not self.range:contains(gs.pos) then
return false
end
end
if self.rate then
local last_time = self.last_time or TimeVal:new{}
if gs.time - last_time > TimeVal:new{usec = 1000000 / self.rate} then
self.last_time = gs.time
else
return false
end
end
if self.scale then
if self.scale[1] > gs.span or self.scale[2] < gs.span then
return false
end
end
return true
end
--[[ --[[
Current detectable gestures: Current detectable gestures:
@ -80,7 +40,9 @@ GestureDetector:feedEvent(tev) will return a detection result when you
feed a touch release event to it. feed a touch release event to it.
--]] --]]
GestureDetector = { local GestureDetector = {
-- must be initialized with the Input singleton class
input = nil,
-- all the time parameters are in us -- all the time parameters are in us
DOUBLE_TAP_INTERVAL = 300 * 1000, DOUBLE_TAP_INTERVAL = 300 * 1000,
TWO_FINGER_TAP_DURATION = 300 * 1000, TWO_FINGER_TAP_DURATION = 300 * 1000,
@ -351,9 +313,9 @@ function GestureDetector:handleDoubleTap(tev)
-- deadline should be calculated by adding current tap time and the interval -- deadline should be calculated by adding current tap time and the interval
local deadline = cur_tap.timev + TimeVal:new{ local deadline = cur_tap.timev + TimeVal:new{
sec = 0, sec = 0,
usec = not Input.disable_double_tap and self.DOUBLE_TAP_INTERVAL or 0, usec = not self.input.disable_double_tap and self.DOUBLE_TAP_INTERVAL or 0,
} }
Input:setTimeout(function() self.input:setTimeout(function()
DEBUG("in tap timer", self.last_taps[slot] ~= nil) DEBUG("in tap timer", self.last_taps[slot] ~= nil)
-- double tap will set last_tap to nil so if it is not, then -- double tap will set last_tap to nil so if it is not, then
-- user must only tapped once -- user must only tapped once
@ -379,7 +341,7 @@ function GestureDetector:handleNonTap(tev)
local deadline = tev.timev + TimeVal:new{ local deadline = tev.timev + TimeVal:new{
sec = 0, usec = self.HOLD_INTERVAL sec = 0, usec = self.HOLD_INTERVAL
} }
Input:setTimeout(function() self.input:setTimeout(function()
if self.states[slot] == self.tapState then if self.states[slot] == self.tapState then
-- timer set in tapState, so we switch to hold -- timer set in tapState, so we switch to hold
DEBUG("hold gesture detected in slot", slot) DEBUG("hold gesture detected in slot", slot)
@ -680,3 +642,5 @@ function GestureDetector:adjustGesCoordinate(ges)
end end
return ges return ges
end end
return GestureDetector

@ -0,0 +1,45 @@
-- TimeVal
local GestureRange = {
ges = nil,
-- spatial range limits the gesture emitting position
range = nil,
-- temproal range limits the gesture emitting rate
rate = nil,
-- span limits of this gesture
scale = nil,
}
function GestureRange:new(o)
local o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function GestureRange:match(gs)
if gs.ges ~= self.ges then
return false
end
if self.range then
if not self.range:contains(gs.pos) then
return false
end
end
if self.rate then
local last_time = self.last_time or TimeVal:new{}
if gs.time - last_time > TimeVal:new{usec = 1000000 / self.rate} then
self.last_time = gs.time
else
return false
end
end
if self.scale then
if self.scale[1] > gs.span or self.scale[2] < gs.span then
return false
end
end
return true
end
return GestureRange

@ -1,181 +0,0 @@
--[[
Draw a border
@x: start position in x axis
@y: start position in y axis
@w: width of the border
@h: height of the border
@bw: line width of the border
@c: color for loading bar
@r: radius of for border's corner (nil or 0 means right corner border)
--]]
function blitbuffer.paintBorder(bb, x, y, w, h, bw, c, r)
x, y = math.ceil(x), math.ceil(y)
h, w = math.ceil(h), math.ceil(w)
if not r or r == 0 then
bb:paintRect(x, y, w, bw, c)
bb:paintRect(x, y+h-bw, w, bw, c)
bb:paintRect(x, y+bw, bw, h - 2*bw, c)
bb:paintRect(x+w-bw, y+bw, bw, h - 2*bw, c)
else
if h < 2*r then r = math.floor(h/2) end
if w < 2*r then r = math.floor(w/2) end
bb:paintRoundedCorner(x, y, w, h, bw, r, c)
bb:paintRect(r+x, y, w-2*r, bw, c)
bb:paintRect(r+x, y+h-bw, w-2*r, bw, c)
bb:paintRect(x, r+y, bw, h-2*r, c)
bb:paintRect(x+w-bw, r+y, bw, h-2*r, c)
end
end
--[[
Fill a rounded corner rectangular area
@x: start position in x axis
@y: start position in y axis
@w: width of the area
@h: height of the area
@c: color used to fill the area
@r: radius of for four corners
--]]
function blitbuffer.paintRoundedRect(bb, x, y, w, h, c, r)
x, y = math.ceil(x), math.ceil(y)
h, w = math.ceil(h), math.ceil(w)
if not r or r == 0 then
bb:paintRect(x, y, w, h, c)
else
if h < 2*r then r = math.floor(h/2) end
if w < 2*r then r = math.floor(w/2) end
bb:paintBorder(x, y, w, h, r, c, r)
bb:paintRect(x+r, y+r, w-2*r, h-2*r, c)
end
end
--[[
Draw a progress bar according to following args:
@x: start position in x axis
@y: start position in y axis
@w: width for progress bar
@h: height for progress bar
@load_m_w: width margin for loading bar
@load_m_h: height margin for loading bar
@load_percent: progress in percent
@c: color for loading bar
--]]
function blitbuffer.progressBar(bb, x, y, w, h,
load_m_w, load_m_h, load_percent, c)
if load_m_h*2 > h then
load_m_h = h/2
end
bb:paintBorder(x, y, w, h, 2, 15)
bb:paintRect(x+load_m_w, y+load_m_h,
(w-2*load_m_w)*load_percent, (h-2*load_m_h), c)
end
------------------------------------------------
-- Start of Cursor class
------------------------------------------------
Cursor = {
x_pos = 0,
y_pos = 0,
--color = 15,
h = 10,
w = nil,
line_w = nil,
is_cleared = true,
}
function Cursor:new(o)
o = o or {}
o.x_pos = o.x_pos or self.x_pos
o.y_pos = o.y_pos or self.y_pos
o.line_width_factor = o.line_width_factor or 10
setmetatable(o, self)
self.__index = self
o:setHeight(o.h or self.h)
return o
end
function Cursor:setHeight(h)
self.h = h
self.w = self.h / 3
self.line_w = math.floor(self.h / self.line_width_factor)
end
function Cursor:_draw(x, y)
local up_down_width = math.floor(self.line_w / 2)
local body_h = self.h - (up_down_width * 2)
-- paint upper horizontal line
fb.bb:invertRect(x, y, self.w, up_down_width)
-- paint middle vertical line
fb.bb:invertRect(x + (self.w / 2) - up_down_width, y + up_down_width,
self.line_w, body_h)
-- paint lower horizontal line
fb.bb:invertRect(x, y + body_h + up_down_width, self.w, up_down_width)
end
function Cursor:draw()
if self.is_cleared then
self.is_cleared = false
self:_draw(self.x_pos, self.y_pos)
end
end
function Cursor:clear()
if not self.is_cleared then
self.is_cleared = true
self:_draw(self.x_pos, self.y_pos)
end
end
function Cursor:move(x_off, y_off)
self.x_pos = self.x_pos + x_off
self.y_pos = self.y_pos + y_off
end
function Cursor:moveHorizontal(x_off)
self.x_pos = self.x_pos + x_off
end
function Cursor:moveVertical(x_off)
self.y_pos = self.y_pos + y_off
end
function Cursor:moveAndDraw(x_off, y_off)
self:clear()
self:move(x_off, y_off)
self:draw()
end
function Cursor:moveTo(x_pos, y_pos)
self.x_pos = x_pos
self.y_pos = y_pos
end
function Cursor:moveToAndDraw(x_pos, y_pos)
self:clear()
self.x_pos = x_pos
self.y_pos = y_pos
self:draw()
end
function Cursor:moveHorizontalAndDraw(x_off)
self:clear()
self:move(x_off, 0)
self:draw()
end
function Cursor:moveVerticalAndDraw(y_off)
self:clear()
self:move(0, y_off)
self:draw()
end

@ -1,41 +1,42 @@
require "ui/event" local Device = require("ui/device")
require "ui/device" local GestureDetector = require("ui/gesturedetector")
require "ui/time" local Event = require("ui/event")
require "ui/gesturedetector" local TimeVal = require("ui/timeval")
require "ui/geometry" local Screen = require("ui/screen")
local Dbg = require("dbg")
-- constants from <linux/input.h> -- constants from <linux/input.h>
EV_SYN = 0 local EV_SYN = 0
EV_KEY = 1 local EV_KEY = 1
EV_ABS = 3 local EV_ABS = 3
-- key press event values (KEY.value) -- key press event values (KEY.value)
EVENT_VALUE_KEY_PRESS = 1 local EVENT_VALUE_KEY_PRESS = 1
EVENT_VALUE_KEY_REPEAT = 2 local EVENT_VALUE_KEY_REPEAT = 2
EVENT_VALUE_KEY_RELEASE = 0 local EVENT_VALUE_KEY_RELEASE = 0
-- Synchronization events (SYN.code). -- Synchronization events (SYN.code).
SYN_REPORT = 0 local SYN_REPORT = 0
SYN_CONFIG = 1 local SYN_CONFIG = 1
SYN_MT_REPORT = 2 local SYN_MT_REPORT = 2
-- For single-touch events (ABS.code). -- For single-touch events (ABS.code).
ABS_X = 00 local ABS_X = 00
ABS_Y = 01 local ABS_Y = 01
ABS_PRESSURE = 24 local ABS_PRESSURE = 24
-- For multi-touch events (ABS.code). -- For multi-touch events (ABS.code).
ABS_MT_SLOT = 47 local ABS_MT_SLOT = 47
ABS_MT_POSITION_X = 53 local ABS_MT_POSITION_X = 53
ABS_MT_POSITION_Y = 54 local ABS_MT_POSITION_Y = 54
ABS_MT_TRACKING_ID = 57 local ABS_MT_TRACKING_ID = 57
ABS_MT_PRESSURE = 58 local ABS_MT_PRESSURE = 58
--[[ --[[
an interface for key presses an interface for key presses
]] ]]
Key = {} local Key = {}
function Key:new(key, modifiers) function Key:new(key, modifiers)
local o = { key = key, modifiers = modifiers } local o = { key = key, modifiers = modifiers }
@ -124,7 +125,7 @@ end
--[[ --[[
an interface to get input events an interface to get input events
]] ]]
Input = { local Input = {
event_map = {}, event_map = {},
modifiers = {}, modifiers = {},
rotation_map = { rotation_map = {
@ -133,7 +134,6 @@ Input = {
[2] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right" }, [2] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right" },
[3] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" } [3] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" }
}, },
rotation = 0,
timer_callbacks = {}, timer_callbacks = {},
disable_double_tap = DGESDETECT_DISABLE_DOUBLE_TAP, disable_double_tap = DGESDETECT_DISABLE_DOUBLE_TAP,
} }
@ -255,9 +255,6 @@ function Input:initTouchState()
end end
function Input:init() function Input:init()
-- Screen module must have been initilized by now.
self.rotation = Screen:getRotationMode()
if Device:hasKeyboard() then if Device:hasKeyboard() then
self:initKeyMap() self:initKeyMap()
end end
@ -414,8 +411,8 @@ function Input:handleKeyBoardEv(ev)
end end
-- take device rotation into account -- take device rotation into account
if self.rotation_map[self.rotation][keycode] then if self.rotation_map[Screen:getRotationMode()][keycode] then
keycode = self.rotation_map[self.rotation][keycode] keycode = self.rotation_map[Screen:getRotationMode()][keycode]
end end
if keycode == "IntoSS" or keycode == "OutOfSS" if keycode == "IntoSS" or keycode == "OutOfSS"
@ -661,3 +658,9 @@ function Input:sequenceToString(sequence)
end end
return table.concat(keystring) return table.concat(keystring)
end end
-- initialize the GestureDectector
-- so it can modify our (Input) state
GestureDetector.input = Input
return Input

@ -0,0 +1,49 @@
local Configurable = {}
function Configurable:hash(sep)
local hash = ""
local excluded = {multi_threads = true,}
for key,value in pairs(self) do
if type(value) == "number" or type(value) == "string"
and not excluded[key] then
hash = hash..sep..value
end
end
return hash
end
function Configurable:loadDefaults(config_options)
for i=1,#config_options do
local options = config_options[i].options
for j=1,#config_options[i].options do
local key = config_options[i].options[j].name
self[key] = config_options[i].options[j].default_value
if not self[key] then
self[key] = config_options[i].options[j].default_arg
end
end
end
end
function Configurable:loadSettings(settings, prefix)
for key,value in pairs(self) do
if type(value) == "number" or type(value) == "string"
or type(value) == "table" then
local saved_value = settings:readSetting(prefix..key)
self[key] = (saved_value == nil) and self[key] or saved_value
--Debug("Configurable:loadSettings", "key", key, "saved value", saved_value,"Configurable.key", self[key])
end
end
--Debug("loaded config:", dump(Configurable))
end
function Configurable:saveSettings(settings, prefix)
for key,value in pairs(self) do
if type(value) == "number" or type(value) == "string"
or type(value) == "table" then
settings:saveSetting(prefix..key, value)
end
end
end
return Configurable

@ -1,6 +1,8 @@
require "ui/device" local EventListener = require("ui/widget/eventlistener")
local Device = require("ui/device")
-- lipc
ReaderActivityIndicator = EventListener:new{} local ReaderActivityIndicator = EventListener:new{}
function ReaderActivityIndicator:init() function ReaderActivityIndicator:init()
local dev_mod = Device:getModel() local dev_mod = Device:getModel()
@ -41,3 +43,5 @@ function ReaderActivityIndicator:onStopActivityIndicator()
end end
return true return true
end end
return ReaderActivityIndicator

@ -1,6 +1,15 @@
require "ui/widget/notification" local InputContainer = require("ui/widget/container/inputcontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
ReaderBookmark = InputContainer:new{ local Menu = require("ui/widget/menu")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
local UIManager = require("ui/uimanager")
local Event = require("ui/event")
local _ = require("gettext")
local ReaderBookmark = InputContainer:new{
bm_menu_title = _("Bookmarks"), bm_menu_title = _("Bookmarks"),
bookmarks = nil, bookmarks = nil,
} }
@ -170,3 +179,5 @@ function ReaderBookmark:toggleBookmark(pn_or_xp)
end end
self:addBookmark(pn_or_xp) self:addBookmark(pn_or_xp)
end end
return ReaderBookmark

@ -1,54 +1,14 @@
require "ui/widget/config" local ConfigDialog = require("ui/widget/configdialog")
local InputContainer = require("ui/widget/container/inputcontainer")
Configurable = {} local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
function Configurable:hash(sep) local Geom = require("ui/geometry")
local hash = "" local Screen = require("ui/screen")
local excluded = {multi_threads = true,} local Event = require("ui/event")
for key,value in pairs(self) do local UIManager = require("ui/uimanager")
if type(value) == "number" or type(value) == "string" local _ = require("gettext")
and not excluded[key] then
hash = hash..sep..value local ReaderConfig = InputContainer:new{
end
end
return hash
end
function Configurable:loadDefaults(config_options)
for i=1,#config_options do
local options = config_options[i].options
for j=1,#config_options[i].options do
local key = config_options[i].options[j].name
self[key] = config_options[i].options[j].default_value
if not self[key] then
self[key] = config_options[i].options[j].default_arg
end
end
end
end
function Configurable:loadSettings(settings, prefix)
for key,value in pairs(self) do
if type(value) == "number" or type(value) == "string"
or type(value) == "table" then
local saved_value = settings:readSetting(prefix..key)
self[key] = (saved_value == nil) and self[key] or saved_value
--Debug("Configurable:loadSettings", "key", key, "saved value", saved_value,"Configurable.key", self[key])
end
end
--Debug("loaded config:", dump(Configurable))
end
function Configurable:saveSettings(settings, prefix)
for key,value in pairs(self) do
if type(value) == "number" or type(value) == "string"
or type(value) == "table" then
settings:saveSetting(prefix..key, value)
end
end
end
ReaderConfig = InputContainer:new{
last_panel_index = 1, last_panel_index = 1,
} }
@ -130,3 +90,5 @@ function ReaderConfig:onCloseDocument()
self.configurable:saveSettings(self.ui.doc_settings, self.options.prefix.."_") self.configurable:saveSettings(self.ui.doc_settings, self.options.prefix.."_")
self.ui.doc_settings:saveSetting("config_panel_index", self.last_panel_index) self.ui.doc_settings:saveSetting("config_panel_index", self.last_panel_index)
end end
return ReaderConfig

@ -1,5 +1,6 @@
local EventListener = require("ui/widget/eventlistener")
ReaderCoptListener = EventListener:new{} local ReaderCoptListener = EventListener:new{}
function ReaderCoptListener:onReadSettings(config) function ReaderCoptListener:onReadSettings(config)
local embedded_css = config:readSetting("copt_embedded_css") local embedded_css = config:readSetting("copt_embedded_css")
@ -37,3 +38,5 @@ function ReaderCoptListener:onReadSettings(config)
end) end)
end end
end end
return ReaderCoptListener

@ -1,13 +1,22 @@
require "ui/widget/group" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/bbox" local UIManager = require("ui/uimanager")
require "ui/widget/button" local Geom = require("ui/geometry")
local Event = require("ui/event")
local Screen = require("ui/screen")
local LeftContainer = require("ui/widget/container/leftcontainer")
local RightContainer = require("ui/widget/container/rightcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local VerticalGroup = require("ui/widget/verticalgroup")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local Button = require("ui/widget/button")
local _ = require("gettext")
PageCropDialog = VerticalGroup:new{ local PageCropDialog = VerticalGroup:new{
ok_text = "OK", ok_text = "OK",
cancel_text = "Cancel", cancel_text = "Cancel",
ok_callback = function() end, ok_callback = function() end,
cancel_callback = function() end, cancel_callback = function() end,
button_width = math.floor(scaleByDPI(70)), button_width = math.floor(Screen:scaleByDPI(70)),
} }
function PageCropDialog:init() function PageCropDialog:init()
@ -49,7 +58,7 @@ function PageCropDialog:init()
} }
end end
ReaderCropping = InputContainer:new{} local ReaderCropping = InputContainer:new{}
function ReaderCropping:onPageCrop(mode) function ReaderCropping:onPageCrop(mode)
if mode == "auto" then return end if mode == "auto" then return end
@ -147,3 +156,5 @@ end
function ReaderCropping:onCloseDocument() function ReaderCropping:onCloseDocument()
self.ui.doc_settings:saveSetting("bbox", self.document.bbox) self.ui.doc_settings:saveSetting("bbox", self.document.bbox)
end end
return ReaderCropping

@ -1,11 +1,9 @@
require "ui/device" local EventListener = require("ui/widget/eventlistener")
require "ui/widget/dict" local UIManager = require("ui/uimanager")
local DictQuickLookup = require("ui/widget/dictquicklookup")
local JSON = require("JSON")
ReaderDictionary = EventListener:new{} local ReaderDictionary = EventListener:new{}
function ReaderDictionary:init()
JSON = require("JSON")
end
function ReaderDictionary:onLookupWord(word) function ReaderDictionary:onLookupWord(word)
self:stardictLookup(word) self:stardictLookup(word)
@ -38,7 +36,7 @@ function ReaderDictionary:showDict(results)
dialog = self.dialog, dialog = self.dialog,
results = results, results = results,
dictionary = self.default_dictionary, dictionary = self.default_dictionary,
width = Screen:getWidth() - scaleByDPI(120), width = Screen:getWidth() - screen:scaleByDPI(120),
height = Screen:getHeight()*0.43, height = Screen:getHeight()*0.43,
}) })
end end
@ -56,3 +54,5 @@ end
function ReaderDictionary:onCloseDocument() function ReaderDictionary:onCloseDocument()
self.ui.doc_settings:saveSetting("default_dictionary", self.default_dictionary) self.ui.doc_settings:saveSetting("default_dictionary", self.default_dictionary)
end end
return ReaderDictionary

@ -1,6 +1,9 @@
require "ui/widget/image" local RightContainer = require("ui/widget/container/rightcontainer")
local ImageWidget = require("ui/widget/imagewidget")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
ReaderDogear = RightContainer:new{} local ReaderDogear = RightContainer:new{}
function ReaderDogear:init() function ReaderDogear:init()
local widget = ImageWidget:new{ local widget = ImageWidget:new{
@ -15,3 +18,5 @@ function ReaderDogear:onSetDogearVisibility(visible)
self.view.dogear_visible = visible self.view.dogear_visible = visible
return true return true
end end
return ReaderDogear

@ -1,5 +1,9 @@
local LeftContainer = require("ui/widget/container/leftcontainer")
local ImageWidget = require("ui/widget/imagewidget")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
ReaderFlipping = LeftContainer:new{ local ReaderFlipping = LeftContainer:new{
orig_reflow_mode = 0, orig_reflow_mode = 0,
} }
@ -24,3 +28,5 @@ function ReaderFlipping:onSetFlippingMode(flipping_mode)
end end
return true return true
end end
return ReaderFlipping

@ -1,4 +1,10 @@
ReaderFont = InputContainer:new{ local InputContainer = require("ui/widget/container/inputcontainer")
local Device = require("ui/device")
local Screen = require("ui/screen")
local UIManager = require("ui/uimanager")
local _ = require("gettext")
local ReaderFont = InputContainer:new{
font_face = nil, font_face = nil,
font_size = nil, font_size = nil,
line_space_percent = nil, line_space_percent = nil,
@ -231,3 +237,5 @@ function ReaderFont:addToMainMenu(tab_item_table)
sub_item_table = self.face_table, sub_item_table = self.face_table,
}) })
end end
return ReaderFont

@ -1,6 +1,16 @@
require "ui/widget/progress" local InputContainer = require("ui/widget/container/inputcontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local RightContainer = require("ui/widget/container/rightcontainer")
local BottomContainer = require("ui/widget/container/bottomcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local ProgressWidget = require("ui/widget/progresswidget")
local TextWidget = require("ui/widget/textwidget")
local Screen = require("ui/screen")
local Geom = require("ui/geometry")
local Font = require("ui/font")
local HorizontalGroup = require("ui/widget/horizontalgroup")
ReaderFooter = InputContainer:new{ local ReaderFooter = InputContainer:new{
pageno = nil, pageno = nil,
pages = nil, pages = nil,
progress_percentage = 0.0, progress_percentage = 0.0,
@ -24,16 +34,16 @@ function ReaderFooter:init()
} }
local _, text_height = self.progress_text:getSize() local _, text_height = self.progress_text:getSize()
local horizontal_group = HorizontalGroup:new{} local horizontal_group = HorizontalGroup:new{}
local bar_containner = RightContainer:new{ local bar_container = RightContainer:new{
dimen = Geom:new{w = Screen:getWidth()*self.bar_width, h = self.height}, dimen = Geom:new{w = Screen:getWidth()*self.bar_width, h = self.height},
self.progress_bar, self.progress_bar,
} }
local text_containner = CenterContainer:new{ local text_container = CenterContainer:new{
dimen = Geom:new{w = Screen:getWidth()*self.text_width, h = self.height}, dimen = Geom:new{w = Screen:getWidth()*self.text_width, h = self.height},
self.progress_text, self.progress_text,
} }
table.insert(horizontal_group, bar_containner) table.insert(horizontal_group, bar_container)
table.insert(horizontal_group, text_containner) table.insert(horizontal_group, text_container)
self[1] = BottomContainer:new{ self[1] = BottomContainer:new{
dimen = Screen:getSize(), dimen = Screen:getSize(),
FrameContainer:new{ FrameContainer:new{
@ -63,3 +73,5 @@ function ReaderFooter:onPageUpdate(pageno)
self.pages = self.view.document.info.number_of_pages self.pages = self.view.document.info.number_of_pages
self:updateFooter() self:updateFooter()
end end
return ReaderFooter

@ -1,8 +1,11 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/inputdialog" local Geom = require("ui/geometry")
require "ui/device" local Screen = require("ui/screen")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local _ = require("gettext")
ReaderFrontLight = InputContainer:new{ local ReaderFrontLight = InputContainer:new{
steps = {0,1,2,3,4,5,6,7,8,9,10}, steps = {0,1,2,3,4,5,6,7,8,9,10},
} }
@ -111,3 +114,5 @@ function ReaderFrontLight:fldialIntensity()
Device:getFrontlight():setIntensity(number) Device:getFrontlight():setIntensity(number)
end end
end end
return ReaderFrontLight

@ -1,8 +1,11 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/inputdialog" local InputDialog = require("ui/widget/inputdialog")
local UIManager = require("ui/uimanager")
local Screen = require("ui/screen")
local Event = require("ui/event")
local _ = require("gettext")
local ReaderGoto = InputContainer:new{
ReaderGoto = InputContainer:new{
goto_menu_title = _("Go To"), goto_menu_title = _("Go To"),
goto_dialog_title = _("Go to Page or Location"), goto_dialog_title = _("Go to Page or Location"),
} }
@ -77,3 +80,5 @@ function ReaderGoto:gotoLocation()
-- TODO: implement go to location -- TODO: implement go to location
self:close() self:close()
end end
return ReaderGoto

@ -1,6 +1,11 @@
require "ui/widget/buttontable" local InputContainer = require("ui/widget/container/inputcontainer")
local GestureRange = require("ui/gesturerange")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
local Device = require("ui/device")
local _ = require("gettext")
ReaderHighlight = InputContainer:new{} local ReaderHighlight = InputContainer:new{}
function ReaderHighlight:init() function ReaderHighlight:init()
if Device:hasKeyboard() then if Device:hasKeyboard() then
@ -353,3 +358,5 @@ end
function ReaderHighlight:editHighlight() function ReaderHighlight:editHighlight()
DEBUG("edit highlight") DEBUG("edit highlight")
end end
return ReaderHighlight

@ -1,5 +1,6 @@
local EventListener = require("ui/widget/eventlistener")
ReaderHinting = EventListener:new{ local ReaderHinting = EventListener:new{
hinting_states = {} hinting_states = {}
} }
@ -32,3 +33,5 @@ function ReaderHinting:onRestoreHinting()
self.view.hinting = table.remove(self.hinting_states) self.view.hinting = table.remove(self.hinting_states)
return true return true
end end
return ReaderHinting

@ -1,5 +1,9 @@
local InputContainer = require("ui/widget/container/inputcontainer")
local UIManager = require("ui/uimanager")
local InfoMessage = require("ui/widget/infomessage")
local _ = require("gettext")
ReaderHyphenation = InputContainer:new{ local ReaderHyphenation = InputContainer:new{
hyph_menu_title = _("Hyphenation"), hyph_menu_title = _("Hyphenation"),
hyph_table = nil, hyph_table = nil,
cur_hyph_idx = nil, cur_hyph_idx = nil,
@ -36,3 +40,5 @@ function ReaderHyphenation:addToMainMenu(tab_item_table)
sub_item_table = self.hyph_table, sub_item_table = self.hyph_table,
}) })
end end
return ReaderHyphenation

@ -1,5 +1,7 @@
local EventListener = require("ui/widget/eventlistener")
local Event = require("ui/event")
ReaderKoptListener = EventListener:new{} local ReaderKoptListener = EventListener:new{}
function ReaderKoptListener:setZoomMode(zoom_mode) function ReaderKoptListener:setZoomMode(zoom_mode)
if self.document.configurable.text_wrap == 1 then if self.document.configurable.text_wrap == 1 then
@ -58,3 +60,5 @@ function ReaderKoptListener:onDocLangUpdate(lang)
self.document.configurable.word_spacing = DKOPTREADER_CONFIG_WORD_SAPCINGS[3] self.document.configurable.word_spacing = DKOPTREADER_CONFIG_WORD_SAPCINGS[3]
end end
end end
return ReaderKoptListener

@ -1,7 +1,15 @@
require "ui/widget/menu" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/touchmenu" local CenterContainer = require("ui/widget/container/centercontainer")
local TouchMenu = require("ui/widget/touchmenu")
ReaderMenu = InputContainer:new{ local UIManager = require("ui/uimanager")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local Geom = require("ui/geometry")
local Event = require("ui/event")
local Screen = require("ui/screen")
local _ = require("gettext")
local ReaderMenu = InputContainer:new{
tab_item_table = nil, tab_item_table = nil,
registered_widgets = {}, registered_widgets = {},
} }
@ -133,3 +141,4 @@ function ReaderMenu:registerToMainMenu(widget)
table.insert(self.registered_widgets, widget) table.insert(self.registered_widgets, widget)
end end
return ReaderMenu

@ -1,12 +1,20 @@
require "math" local InputContainer = require("ui/widget/container/inputcontainer")
local Screen = require("ui/screen")
ReaderPaging = InputContainer:new{ local Geom = require("ui/geometry")
local Input = require("ui/input")
local GestureRange = require("ui/gesturerange")
local Device = require("ui/device")
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
local Math = require("optmath")
local ReaderPaging = InputContainer:new{
current_page = 0, current_page = 0,
number_of_pages = 0, number_of_pages = 0,
visible_area = nil, visible_area = nil,
page_area = nil, page_area = nil,
show_overlap_enable = DSHOWOVERLAP, show_overlap_enable = DSHOWOVERLAP,
overlap = scaleByDPI(20), overlap = Screen:scaleByDPI(20),
flip_steps = {0,1,2,5,10,20,50,100} flip_steps = {0,1,2,5,10,20,50,100}
} }
@ -569,10 +577,10 @@ function ReaderPaging:onGotoPageRel(diff)
-- adjust offset to help with page turn decision -- adjust offset to help with page turn decision
-- we dont take overlap into account here yet, otherwise new_va will -- we dont take overlap into account here yet, otherwise new_va will
-- always intersect with page_area -- always intersect with page_area
x_pan_off = math.roundAwayFromZero(x_pan_off) x_pan_off = Math.roundAwayFromZero(x_pan_off)
y_pan_off = math.roundAwayFromZero(y_pan_off) y_pan_off = Math.roundAwayFromZero(y_pan_off)
new_va.x = math.roundAwayFromZero(self.visible_area.x+x_pan_off) new_va.x = Math.roundAwayFromZero(self.visible_area.x+x_pan_off)
new_va.y = math.roundAwayFromZero(self.visible_area.y+y_pan_off) new_va.y = Math.roundAwayFromZero(self.visible_area.y+y_pan_off)
if new_va:notIntersectWith(self.page_area) then if new_va:notIntersectWith(self.page_area) then
-- view area out of page area, do a page turn -- view area out of page area, do a page turn
@ -604,8 +612,8 @@ function ReaderPaging:onGotoPageRel(diff)
y_pan_off = y_pan_off + self.overlap y_pan_off = y_pan_off + self.overlap
end end
-- we have to calculate again to count into overlap -- we have to calculate again to count into overlap
new_va.x = math.roundAwayFromZero(self.visible_area.x+x_pan_off) new_va.x = Math.roundAwayFromZero(self.visible_area.x+x_pan_off)
new_va.y = math.roundAwayFromZero(self.visible_area.y+y_pan_off) new_va.y = Math.roundAwayFromZero(self.visible_area.y+y_pan_off)
end end
-- fit new view area into page area -- fit new view area into page area
new_va:offsetWithin(self.page_area, 0, 0) new_va:offsetWithin(self.page_area, 0, 0)
@ -676,3 +684,5 @@ function ReaderPaging:onGotoPage(number)
self:gotoPage(number) self:gotoPage(number)
return true return true
end end
return ReaderPaging

@ -1,4 +1,8 @@
ReaderPanning = InputContainer:new{ local InputContainer = require("ui/widget/container/inputcontainer")
local Device = require("ui/device")
local _ = require("gettext")
local ReaderPanning = InputContainer:new{
-- defaults -- defaults
panning_steps = { panning_steps = {
normal = 50, normal = 50,
@ -42,3 +46,5 @@ function ReaderPanning:onPanning(args, key)
dy * self.panning_steps.normal * self.dimen.h / 100) dy * self.panning_steps.normal * self.dimen.h / 100)
return true return true
end end
return ReaderPanning

@ -1,6 +1,12 @@
require "ui/reader/readerpanning" local InputContainer = require("ui/widget/container/inputcontainer")
local Screen = require("ui/screen")
local Geom = require("ui/geometry")
local Input = require("ui/input")
local GestureRange = require("ui/gesturerange")
local ReaderPanning = require("ui/reader/readerpanning")
local _ = require("gettext")
ReaderRolling = InputContainer:new{ local ReaderRolling = InputContainer:new{
old_doc_height = nil, old_doc_height = nil,
old_page = nil, old_page = nil,
current_pos = 0, current_pos = 0,
@ -325,4 +331,4 @@ function ReaderRolling:gotoPercent(new_percent)
self:gotoPos(new_percent * self.doc_height / 10000) self:gotoPos(new_percent * self.doc_height / 10000)
end end
return ReaderRolling

@ -1,4 +1,11 @@
ReaderRotation = InputContainer:new{ local InputContainer = require("ui/widget/container/inputcontainer")
local Screen = require("ui/screen")
local Geom = require("ui/geometry")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local _ = require("gettext")
local ReaderRotation = InputContainer:new{
ROTATE_ANGLE_THRESHOLD = 15, ROTATE_ANGLE_THRESHOLD = 15,
current_rotation = 0 current_rotation = 0
} }
@ -66,3 +73,5 @@ function ReaderRotation:onTwoFingerPanRelease(arg, ges)
self.rotate_angle = nil self.rotate_angle = nil
end end
end end
return ReaderRotation

@ -1,5 +1,9 @@
local InputContainer = require("ui/widget/container/inputcontainer")
local Screen = require("ui/screen")
local GestureRange = require("ui/gesturerange")
local UIManager = require("ui/uimanager")
ReaderScreenshot = InputContainer:new{} local ReaderScreenshot = InputContainer:new{}
function ReaderScreenshot:init() function ReaderScreenshot:init()
local diagonal = math.sqrt( local diagonal = math.sqrt(
@ -10,7 +14,7 @@ function ReaderScreenshot:init()
Screenshot = { Screenshot = {
GestureRange:new{ GestureRange:new{
ges = "two_finger_tap", ges = "two_finger_tap",
scale = {diagonal - scaleByDPI(100), diagonal}, scale = {diagonal - Screen:scaleByDPI(100), diagonal},
rate = 1.0, rate = 1.0,
} }
}, },
@ -23,3 +27,4 @@ function ReaderScreenshot:onScreenshot()
return true return true
end end
return ReaderScreenshot

@ -1,4 +1,12 @@
ReaderToc = InputContainer:new{ local InputContainer = require("ui/widget/container/inputcontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local Menu = require("ui/widget/menu")
local Screen = require("ui/screen")
local Device = require("ui/device")
local UIManager = require("ui/uimanager")
local _ = require("gettext")
local ReaderToc = InputContainer:new{
toc = nil, toc = nil,
toc_menu_title = _("Table of contents"), toc_menu_title = _("Table of contents"),
} }
@ -113,3 +121,5 @@ function ReaderToc:addToMainMenu(tab_item_table)
end, end,
}) })
end end
return ReaderToc

@ -1,4 +1,8 @@
ReaderTypeset = InputContainer:new{ local InputContainer = require("ui/widget/container/inputcontainer")
local _ = require("gettext")
-- lfs
local ReaderTypeset = InputContainer:new{
css_menu_title = _("Set render style"), css_menu_title = _("Set render style"),
css = nil, css = nil,
internal_css = true, internal_css = true,
@ -106,4 +110,4 @@ function ReaderTypeset:addToMainMenu(tab_item_table)
}) })
end end
return ReaderTypeset

@ -1,9 +1,13 @@
require "ui/widget/group" local OverlapGroup = require("ui/widget/overlapgroup")
require "ui/reader/readerflip" local Screen = require("ui/screen")
require "ui/reader/readerfooter" local ReaderFlipping = require("ui/reader/readerflipping")
require "ui/reader/readerdogear" local ReaderFooter = require("ui/reader/readerfooter")
local ReaderDogear = require("ui/reader/readerdogear")
ReaderView = OverlapGroup:new{ local Geom = require("ui/geometry")
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
local ReaderView = OverlapGroup:new{
document = nil, document = nil,
-- single page state -- single page state
@ -32,8 +36,8 @@ ReaderView = OverlapGroup:new{
page_states = {}, page_states = {},
scroll_mode = "vertical", scroll_mode = "vertical",
page_gap = { page_gap = {
width = scaleByDPI(8), width = Screen:scaleByDPI(8),
height = scaleByDPI(8), height = Screen:scaleByDPI(8),
color = 8, color = 8,
}, },
-- DjVu page rendering mode (used in djvu.c:drawPage()) -- DjVu page rendering mode (used in djvu.c:drawPage())
@ -571,3 +575,5 @@ function ReaderView:onCloseDocument()
self.ui.doc_settings:saveSetting("gamma", self.state.gamma) self.ui.doc_settings:saveSetting("gamma", self.state.gamma)
self.ui.doc_settings:saveSetting("highlight", self.highlight.saved) self.ui.doc_settings:saveSetting("highlight", self.highlight.saved)
end end
return ReaderView

@ -1,4 +1,13 @@
ReaderZooming = InputContainer:new{ local InputContainer = require("ui/widget/container/inputcontainer")
local Device = require("ui/device")
local Input = require("ui/input")
local Screen = require("ui/screen")
local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange")
local Event = require("ui/event")
local _ = require("gettext")
local ReaderZooming = InputContainer:new{
zoom = 1.0, zoom = 1.0,
-- default to nil so we can trigger ZoomModeUpdate events on start up -- default to nil so we can trigger ZoomModeUpdate events on start up
zoom_mode = nil, zoom_mode = nil,
@ -262,3 +271,5 @@ function ReaderZooming:addToMainMenu(tab_item_table)
}) })
end end
end end
return ReaderZooming

@ -1,26 +1,34 @@
require "ui/reader/readerview" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/reader/readerzooming" local Geom = require("ui/geometry")
require "ui/reader/readerpanning" local Device = require("ui/device")
require "ui/reader/readerrotation" local DocSettings = require("docsettings")
require "ui/reader/readerpaging" local Event = require("ui/event")
require "ui/reader/readerrolling" local UIManager = require("ui/uimanager")
require "ui/reader/readertoc" local _ = require("gettext")
require "ui/reader/readerbookmark"
require "ui/reader/readerfont" local ReaderView = require("ui/reader/readerview")
require "ui/reader/readertypeset" local ReaderZooming = require("ui/reader/readerzooming")
require "ui/reader/readermenu" local ReaderPanning = require("ui/reader/readerpanning")
require "ui/reader/readergoto" local ReaderRotation = require("ui/reader/readerrotation")
require "ui/reader/readerconfig" local ReaderPaging = require("ui/reader/readerpaging")
require "ui/reader/readercropping" local ReaderRolling = require("ui/reader/readerrolling")
require "ui/reader/readerkopt" local ReaderToc = require("ui/reader/readertoc")
require "ui/reader/readercopt" local ReaderBookmark = require("ui/reader/readerbookmark")
require "ui/reader/readerhinting" local ReaderFont = require("ui/reader/readerfont")
require "ui/reader/readerhighlight" local ReaderTypeset = require("ui/reader/readertypeset")
require "ui/reader/readerscreenshot" local ReaderMenu = require("ui/reader/readermenu")
require "ui/reader/readerfrontlight" local ReaderGoto = require("ui/reader/readergoto")
require "ui/reader/readerdictionary" local ReaderConfig = require("ui/reader/readerconfig")
require "ui/reader/readerhyphenation" local ReaderCropping = require("ui/reader/readercropping")
require "ui/reader/readeractivityindicator" local ReaderKoptListener = require("ui/reader/readerkoptlistener")
local ReaderCoptListener = require("ui/reader/readercoptlistener")
local ReaderHinting = require("ui/reader/readerhinting")
local ReaderHighlight = require("ui/reader/readerhighlight")
local ReaderScreenshot = require("ui/reader/readerscreenshot")
local ReaderFrontLight = require("ui/reader/readerfrontlight")
local ReaderDictionary = require("ui/reader/readerdictionary")
local ReaderHyphenation = require("ui/reader/readerhyphenation")
local ReaderActivityIndicator = require("ui/reader/readeractivityindicator")
--[[ --[[
This is an abstraction for a reader interface This is an abstraction for a reader interface
@ -28,7 +36,7 @@ This is an abstraction for a reader interface
it works using data gathered from a document interface it works using data gathered from a document interface
]]-- ]]--
ReaderUI = InputContainer:new{ local ReaderUI = InputContainer:new{
key_events = { key_events = {
Close = { { "Home" }, Close = { { "Home" },
doc = _("close document"), event = "Close" }, doc = _("close document"), event = "Close" },
@ -278,3 +286,4 @@ function ReaderUI:onClose()
return true return true
end end
return ReaderUI

@ -1,10 +1,12 @@
require "cache" local Cache = require("cache")
local CacheItem = require("cacheitem")
--[[ --[[
TODO: all these functions should probably be methods on Face objects TODO: all these functions should probably be methods on Face objects
]]-- ]]--
local RenderText = {}
GlyphCache = Cache:new{ local GlyphCache = Cache:new{
max_memsize = 512*1024, max_memsize = 512*1024,
current_memsize = 0, current_memsize = 0,
cache = {}, cache = {},
@ -56,7 +58,7 @@ local function utf8Chars(input)
return read_next_glyph, input, 1 return read_next_glyph, input, 1
end end
function getGlyph(face, charcode, bgcolor, fgcolor) function RenderText:getGlyph(face, charcode, bgcolor, fgcolor)
if bgcolor == nil then bgcolor = 0.0 end if bgcolor == nil then bgcolor = 0.0 end
if fgcolor == nil then fgcolor = 1.0 end if fgcolor == nil then fgcolor = 1.0 end
local hash = "glyph|"..face.hash.."|"..charcode.."|"..bgcolor.."|"..fgcolor local hash = "glyph|"..face.hash.."|"..charcode.."|"..bgcolor.."|"..fgcolor
@ -87,13 +89,13 @@ function getGlyph(face, charcode, bgcolor, fgcolor)
return rendered_glyph return rendered_glyph
end end
function getSubTextByWidth(text, face, width, kerning) function RenderText:getSubTextByWidth(text, face, width, kerning)
local pen_x = 0 local pen_x = 0
local prevcharcode = 0 local prevcharcode = 0
local char_list = {} local char_list = {}
for _, charcode, uchar in utf8Chars(text) do for _, charcode, uchar in utf8Chars(text) do
if pen_x < width then if pen_x < width then
local glyph = getGlyph(face, charcode) local glyph = self:getGlyph(face, charcode)
if kerning and prevcharcode then if kerning and prevcharcode then
local kern = face.ftface:getKerning(prevcharcode, charcode) local kern = face.ftface:getKerning(prevcharcode, charcode)
pen_x = pen_x + kern pen_x = pen_x + kern
@ -110,7 +112,7 @@ function getSubTextByWidth(text, face, width, kerning)
return table.concat(char_list) return table.concat(char_list)
end end
function sizeUtf8Text(x, width, face, text, kerning) function RenderText:sizeUtf8Text(x, width, face, text, kerning)
if not text then if not text then
DEBUG("sizeUtf8Text called without text"); DEBUG("sizeUtf8Text called without text");
return return
@ -124,7 +126,7 @@ function sizeUtf8Text(x, width, face, text, kerning)
local prevcharcode = 0 local prevcharcode = 0
for _, charcode, uchar in utf8Chars(text) do for _, charcode, uchar in utf8Chars(text) do
if pen_x < (width - x) then if pen_x < (width - x) then
local glyph = getGlyph(face, charcode) local glyph = self:getGlyph(face, charcode)
if kerning and (prevcharcode ~= 0) then if kerning and (prevcharcode ~= 0) then
pen_x = pen_x + (face.ftface):getKerning(prevcharcode, charcode) pen_x = pen_x + (face.ftface):getKerning(prevcharcode, charcode)
end end
@ -138,7 +140,7 @@ function sizeUtf8Text(x, width, face, text, kerning)
return { x = pen_x, y_top = pen_y_top, y_bottom = pen_y_bottom} return { x = pen_x, y_top = pen_y_top, y_bottom = pen_y_bottom}
end end
function renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor) function RenderText:renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor)
if not text then if not text then
DEBUG("renderUtf8Text called without text"); DEBUG("renderUtf8Text called without text");
return 0 return 0
@ -151,7 +153,7 @@ function renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor)
local buffer_width = buffer:getWidth() local buffer_width = buffer:getWidth()
for _, charcode, uchar in utf8Chars(text) do for _, charcode, uchar in utf8Chars(text) do
if pen_x < buffer_width then if pen_x < buffer_width then
local glyph = getGlyph(face, charcode, bgcolor, fgcolor) local glyph = self:getGlyph(face, charcode, bgcolor, fgcolor)
if kerning and (prevcharcode ~= 0) then if kerning and (prevcharcode ~= 0) then
pen_x = pen_x + face.ftface:getKerning(prevcharcode, charcode) pen_x = pen_x + face.ftface:getKerning(prevcharcode, charcode)
end end
@ -167,3 +169,5 @@ function renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor)
return pen_x return pen_x
end end
return RenderText

@ -1,19 +1,8 @@
--[[ local Device = require("ui/device")
Copyright (C) 2011 Hans-Werner Hilse <hilse@web.de> local Geom = require("ui/geometry")
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, -- Blitbuffer
but WITHOUT ANY WARRANTY; without even the implied warranty of -- einkfb
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]--
--[[ --[[
Codes for rotation modes: Codes for rotation modes:
@ -39,7 +28,7 @@ Codes for rotation modes:
--]] --]]
Screen = { local Screen = {
width = 0, width = 0,
height = 0, height = 0,
native_rotation_mode = nil, native_rotation_mode = nil,
@ -138,16 +127,6 @@ function Screen:rescaleByDPI(px)
return math.ceil(px * 167/self:getDPI()) return math.ceil(px * 167/self:getDPI())
end end
-- make a shortcut to Screen:scaleByDPI
function scaleByDPI(px)
return Screen:scaleByDPI(px)
end
-- make a shortcut to Screen:rescaleByDPI
function rescaleByDPI(px)
return Screen:rescaleByDPI(px)
end
function Screen:getPitch() function Screen:getPitch()
return self.fb:getPitch() return self.fb:getPitch()
end end
@ -181,8 +160,6 @@ function Screen:setRotationMode(mode)
self.cur_rotation_mode = mode self.cur_rotation_mode = mode
self.bb:free() self.bb:free()
self.bb = Blitbuffer.new(self.width, self.height, self.width/2) self.bb = Blitbuffer.new(self.width, self.height, self.width/2)
-- update mode for input module
Input.rotation = mode
end end
function Screen:setScreenMode(mode) function Screen:setScreenMode(mode)
@ -229,3 +206,5 @@ function Screen:restoreFromBB(bb)
DEBUG("Got nil bb in restoreFromSavedBB!") DEBUG("Got nil bb in restoreFromSavedBB!")
end end
end end
return Screen

@ -1,4 +1,4 @@
TimeVal = { local TimeVal = {
sec = 0, sec = 0,
usec = 0, usec = 0,
} }
@ -100,3 +100,5 @@ function TimeVal:now()
local sec, usec = util.gettime() local sec, usec = util.gettime()
return TimeVal:new{sec = sec, usec = usec} return TimeVal:new{sec = sec, usec = usec}
end end
return TimeVal

@ -1,28 +1,25 @@
require "ui/geometry" local Device = require("ui/device")
require "ui/device" local Screen = require("ui/screen")
require "ui/inputevent" local Input = require("ui/input")
require "ui/widget/container" local Event = require("ui/event")
require "ui/screen"
require "debug"
require "gettext"
-- initialize output module, this must be initialized before Input -- initialize output module, this must be initialized before Input
Screen:init() Screen:init()
-- initialize the input handling -- initialize the input handling
Input:init() Input:init()
WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears) local WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears)
WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black local WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black
WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing) local WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing)
WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility local WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility
WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity local WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity
WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity local WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity
WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition local WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition
WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition local WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition
WAVEFORM_MODE_AUTO = 0x101 local WAVEFORM_MODE_AUTO = 0x101
-- there is only one instance of this -- there is only one instance of this
UIManager = { local UIManager = {
-- change this to set refresh type for next refresh -- change this to set refresh type for next refresh
-- defaults to 1 initially and will be set to 1 after each refresh -- defaults to 1 initially and will be set to 1 after each refresh
default_refresh_type = 1, default_refresh_type = 1,
@ -296,12 +293,12 @@ function UIManager:run()
Device:getFrontlight():toggle() Device:getFrontlight():toggle()
elseif (input_event == "Power" and not Device.screen_saver_mode) or elseif (input_event == "Power" and not Device.screen_saver_mode) or
input_event == "Suspend" then input_event == "Suspend" then
UIManager:show(InfoMessage:new{ self:show(InfoMessage:new{
text = _("Standby"), text = _("Standby"),
timeout = 1, timeout = 1,
}) })
Device:prepareSuspend() Device:prepareSuspend()
UIManager:scheduleIn(0.5, function() Device:Suspend() end) self:scheduleIn(0.5, function() Device:Suspend() end)
elseif (input_event == "Power" and Device.screen_saver_mode) or elseif (input_event == "Power" and Device.screen_saver_mode) or
input_event == "Resume" then input_event == "Resume" then
Device:Resume() Device:Resume()
@ -311,3 +308,5 @@ function UIManager:run()
end end
end end
end end
return UIManager

@ -1,10 +1,9 @@
require "math" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/container"
--[[ --[[
BBoxWidget shows a bbox for page cropping BBoxWidget shows a bbox for page cropping
]] ]]
BBoxWidget = InputContainer:new{ local BBoxWidget = InputContainer:new{
page_bbox = nil, page_bbox = nil,
screen_bbox = nil, screen_bbox = nil,
linesize = 2, linesize = 2,
@ -212,3 +211,5 @@ function BBoxWidget:onConfirmAdjust(arg, ges)
end end
return true return true
end end
return BBoxWidget

@ -1,10 +1,18 @@
require "ui/widget/image" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/container" local TextWidget = require("ui/widget/textwidget")
local ImageWidget = require("ui/widget/imagewidget")
local Font = require("ui/font")
local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange")
local FrameContainer = require("ui/widget/container/framecontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local Device = require("ui/device")
local _ = require("gettext")
--[[ --[[
a button widget that shows text or a icon and handles callback when tapped a button widget that shows text or a icon and handles callback when tapped
--]] --]]
Button = InputContainer:new{ local Button = InputContainer:new{
text = nil, -- mandatory text = nil, -- mandatory
icon = nil, icon = nil,
preselect = false, preselect = false,
@ -134,3 +142,5 @@ function Button:onTapSelect()
end end
return true return true
end end
return Button

@ -1,7 +1,12 @@
require "ui/widget/base" local VerticalGroup = require("ui/widget/verticalgroup")
require "ui/widget/line" local HorizontalGroup = require("ui/widget/horizontalgroup")
local VerticalSpan = require("ui/widget/verticalspan")
local LineWidget = require("ui/widget/linewidget")
local Button = require("ui/widget/button")
local Screen = require("ui/screen")
local Geom = require("ui/geometry")
ButtonTable = VerticalGroup:new{ local ButtonTable = VerticalGroup:new{
width = Screen:getWidth(), width = Screen:getWidth(),
buttons = { buttons = {
{ {
@ -9,8 +14,8 @@ ButtonTable = VerticalGroup:new{
{text="Cancel", enabled=false, callback=nil}, {text="Cancel", enabled=false, callback=nil},
}, },
}, },
sep_width = scaleByDPI(1), sep_width = Screen:scaleByDPI(1),
padding = scaleByDPI(2), padding = Screen:scaleByDPI(2),
zero_sep = false, zero_sep = false,
button_font_face = "cfont", button_font_face = "cfont",
@ -59,7 +64,7 @@ function ButtonTable:init()
end end
function ButtonTable:addHorizontalSep() function ButtonTable:addHorizontalSep()
table.insert(self, VerticalSpan:new{ width = scaleByDPI(2) }) table.insert(self, VerticalSpan:new{ width = Screen:scaleByDPI(2) })
table.insert(self, LineWidget:new{ table.insert(self, LineWidget:new{
background = 8, background = 8,
dimen = Geom:new{ dimen = Geom:new{
@ -67,5 +72,7 @@ function ButtonTable:addHorizontalSep()
h = self.sep_width, h = self.sep_width,
} }
}) })
table.insert(self, VerticalSpan:new{ width = scaleByDPI(2) }) table.insert(self, VerticalSpan:new{ width = Screen:scaleByDPI(2) })
end end
return ButtonTable

@ -1,7 +1,28 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/toggleswitch" local CenterContainer = require("ui/widget/container/centercontainer")
local RightContainer = require("ui/widget/container/rightcontainer")
MenuBarItem = InputContainer:new{} local FrameContainer = require("ui/widget/container/framecontainer")
local BottomContainer = require("ui/widget/container/bottomcontainer")
local UnderlineContainer = require("ui/widget/container/underlinecontainer")
local ImageWidget = require("ui/widget/imagewidget")
local TextWidget = require("ui/widget/textwidget")
local FixedTextWidget = require("ui/widget/fixedtextwidget")
local ToggleSwitch = require("ui/widget/toggleswitch")
local Font = require("ui/font")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local UIManager = require("ui/uimanager")
local RectSpan = require("ui/widget/rectspan")
local HorizontalSpan = require("ui/widget/horizontalspan")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local VerticalSpan = require("ui/widget/verticalspan")
local VerticalGroup = require("ui/widget/verticalgroup")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
local Event = require("ui/event")
local _ = require("gettext")
local MenuBarItem = InputContainer:new{}
function MenuBarItem:init() function MenuBarItem:init()
self.dimen = self[1]:getSize() self.dimen = self[1]:getSize()
-- we need this table per-instance, so we declare it here -- we need this table per-instance, so we declare it here
@ -40,7 +61,7 @@ function MenuBarItem:invert(invert)
UIManager:setDirty(self.config, "full") UIManager:setDirty(self.config, "full")
end end
OptionTextItem = InputContainer:new{} local OptionTextItem = InputContainer:new{}
function OptionTextItem:init() function OptionTextItem:init()
local text_widget = self[1] local text_widget = self[1]
@ -96,7 +117,7 @@ function OptionTextItem:onTapSelect()
return true return true
end end
OptionIconItem = InputContainer:new{} local OptionIconItem = InputContainer:new{}
function OptionIconItem:init() function OptionIconItem:init()
self.dimen = self.icon:getSize() self.dimen = self.icon:getSize()
self[1] = UnderlineContainer:new{ self[1] = UnderlineContainer:new{
@ -138,19 +159,7 @@ function OptionIconItem:onTapSelect()
return true return true
end end
--[[ local ConfigOption = CenterContainer:new{}
Dummy Widget that reserves vertical and horizontal space
]]
RectSpan = Widget:new{
width = 0,
hright = 0,
}
function RectSpan:getSize()
return {w = self.width, h = self.height}
end
ConfigOption = CenterContainer:new{}
function ConfigOption:init() function ConfigOption:init()
local default_name_font_size = 20 local default_name_font_size = 20
local default_item_font_size = 16 local default_item_font_size = 16
@ -159,7 +168,7 @@ function ConfigOption:init()
local default_option_padding = 15 local default_option_padding = 15
local vertical_group = VerticalGroup:new{} local vertical_group = VerticalGroup:new{}
table.insert(vertical_group, VerticalSpan:new{ table.insert(vertical_group, VerticalSpan:new{
width = scaleByDPI(default_option_padding), width = Screen:scaleByDPI(default_option_padding),
}) })
for c = 1, #self.options do for c = 1, #self.options do
if self.options[c].show ~= false then if self.options[c].show ~= false then
@ -169,9 +178,9 @@ function ConfigOption:init()
local name_font_size = self.options[c].name_font_size and self.options[c].name_font_size or default_name_font_size local name_font_size = self.options[c].name_font_size and self.options[c].name_font_size or default_name_font_size
local item_font_face = self.options[c].item_font_face and self.options[c].item_font_face or "cfont" local item_font_face = self.options[c].item_font_face and self.options[c].item_font_face or "cfont"
local item_font_size = self.options[c].item_font_size and self.options[c].item_font_size or default_item_font_size local item_font_size = self.options[c].item_font_size and self.options[c].item_font_size or default_item_font_size
local option_height = scaleByDPI(self.options[c].height and self.options[c].height or default_option_height) local option_height = Screen:scaleByDPI(self.options[c].height and self.options[c].height or default_option_height)
local items_spacing = HorizontalSpan:new{ local items_spacing = HorizontalSpan:new{
width = scaleByDPI(self.options[c].spacing and self.options[c].spacing or default_items_spacing) width = Screen:scaleByDPI(self.options[c].spacing and self.options[c].spacing or default_items_spacing)
} }
local horizontal_group = HorizontalGroup:new{} local horizontal_group = HorizontalGroup:new{}
if self.options[c].name_text then if self.options[c].name_text then
@ -325,7 +334,7 @@ function ConfigOption:init()
if self.options[c].toggle then if self.options[c].toggle then
local switch = ToggleSwitch:new{ local switch = ToggleSwitch:new{
width = scaleByDPI(self.options[c].width or 216), width = Screen:scaleByDPI(self.options[c].width or 216),
name = self.options[c].name, name = self.options[c].name,
toggle = self.options[c].toggle, toggle = self.options[c].toggle,
alternate = self.options[c].alternate, alternate = self.options[c].alternate,
@ -350,7 +359,7 @@ function ConfigOption:init()
self.dimen = vertical_group:getSize() self.dimen = vertical_group:getSize()
end end
ConfigPanel = FrameContainer:new{ background = 0, bordersize = 0, } local ConfigPanel = FrameContainer:new{ background = 0, bordersize = 0, }
function ConfigPanel:init() function ConfigPanel:init()
local config_options = self.config_dialog.config_options local config_options = self.config_dialog.config_options
local default_option = config_options.default_options and config_options.default_options local default_option = config_options.default_options and config_options.default_options
@ -363,7 +372,7 @@ function ConfigPanel:init()
table.insert(self, panel) table.insert(self, panel)
end end
MenuBar = FrameContainer:new{ background = 0, } local MenuBar = FrameContainer:new{ background = 0, }
function MenuBar:init() function MenuBar:init()
local config_options = self.config_dialog.config_options local config_options = self.config_dialog.config_options
local menu_items = {} local menu_items = {}
@ -419,7 +428,7 @@ Widget that displays config menubar and config panel
--]] --]]
ConfigDialog = InputContainer:new{ local ConfigDialog = InputContainer:new{
--is_borderless = false, --is_borderless = false,
panel_index = 1, panel_index = 1,
} }
@ -521,3 +530,5 @@ function ConfigDialog:onTapCloseMenu(arg, ges_ev)
return true return true
end end
end end
return ConfigDialog

@ -1,11 +1,14 @@
require "ui/widget/container" local CenterContainer = require("ui/widget/container/centercontainer")
require "ui/widget/focusmanager" local FrameContainer = require("ui/widget/container/centercontainer")
require "ui/widget/button" local FocusManager = require("ui/widget/focusmanager")
local Button = require("ui/widget/button")
-- screen
--[[ --[[
Widget that shows a message and OK/Cancel buttons Widget that shows a message and OK/Cancel buttons
]] ]]
ConfirmBox = FocusManager:new{ local ConfirmBox = FocusManager:new{
text = _("no text"), text = _("no text"),
width = nil, width = nil,
ok_text = _("OK"), ok_text = _("OK"),
@ -88,3 +91,4 @@ function ConfirmBox:onSelect()
return true return true
end end
return ConfirmBox

@ -1,326 +0,0 @@
require "ui/widget/base"
--[[
WidgetContainer is a container for another Widget
--]]
WidgetContainer = Widget:new()
function WidgetContainer:init()
if not self.dimen then
self.dimen = Geom:new{}
end
end
function WidgetContainer:getSize()
if self.dimen then
-- fixed size
return self.dimen
elseif self[1] then
-- return size of first child widget
return self[1]:getSize()
else
return Geom:new{ w = 0, h = 0 }
end
end
--[[
delete all child widgets
--]]
function WidgetContainer:clear()
while table.remove(self) do end
end
function WidgetContainer:paintTo(bb, x, y)
-- default to pass request to first child widget
if self[1] then
return self[1]:paintTo(bb, x, y)
end
end
function WidgetContainer:propagateEvent(event)
-- propagate to children
for _, widget in ipairs(self) do
if widget:handleEvent(event) then
-- stop propagating when an event handler returns true
return true
end
end
return false
end
--[[
Containers will pass events to children or react on them themselves
--]]
function WidgetContainer:handleEvent(event)
if not self:propagateEvent(event) then
-- call our own standard event handler
return Widget.handleEvent(self, event)
else
return true
end
end
function WidgetContainer:free()
for _, widget in ipairs(self) do
if widget.free then widget:free() end
end
end
--[[
BottomContainer contains its content (1 widget) at the bottom of its own
dimensions
--]]
BottomContainer = WidgetContainer:new()
function BottomContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb,
x + math.floor((self.dimen.w - contentSize.w)/2),
y + (self.dimen.h - contentSize.h))
end
--[[
CenterContainer centers its content (1 widget) within its own dimensions
--]]
CenterContainer = WidgetContainer:new()
function CenterContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
local x_pos = x
local y_pos = y
if self.ignore ~= "height" then
y_pos = y + math.floor((self.dimen.h - contentSize.h)/2)
end
if self.ignore ~= "width" then
x_pos = x + math.floor((self.dimen.w - contentSize.w)/2)
end
self[1]:paintTo(bb, x_pos, y_pos)
end
--[[
LeftContainer aligns its content (1 widget) at the left of its own dimensions
--]]
LeftContainer = WidgetContainer:new()
function LeftContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb, x , y + math.floor((self.dimen.h - contentSize.h)/2))
end
--[[
RightContainer aligns its content (1 widget) at the right of its own dimensions
--]]
RightContainer = WidgetContainer:new()
function RightContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb,
x + (self.dimen.w - contentSize.w),
y + math.floor((self.dimen.h - contentSize.h)/2))
end
--[[
A FrameContainer is some graphics content (1 widget) that is surrounded by a
frame
--]]
FrameContainer = WidgetContainer:new{
background = nil,
color = 15,
margin = 0,
radius = 0,
bordersize = 2,
padding = 5,
width = nil,
height = nil,
invert = false,
}
function FrameContainer:getSize()
local content_size = self[1]:getSize()
return Geom:new{
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
}
end
function FrameContainer:paintTo(bb, x, y)
local my_size = self:getSize()
self.dimen = Geom:new{
x = x, y = y,
w = my_size.w,
h = my_size.h
}
local container_width = self.width or my_size.w
local container_height = self.height or my_size.h
--@TODO get rid of margin here? 13.03 2013 (houqp)
if self.background then
bb:paintRoundedRect(x, y, container_width, container_height,
self.background, self.radius)
end
if self.bordersize > 0 then
bb:paintBorder(x + self.margin, y + self.margin,
container_width - self.margin * 2,
container_height - self.margin * 2,
self.bordersize, self.color, self.radius)
end
if self[1] then
self[1]:paintTo(bb,
x + self.margin + self.bordersize + self.padding,
y + self.margin + self.bordersize + self.padding)
end
if self.invert then
bb:invertRect(x + self.bordersize, y + self.bordersize,
container_width - 2*self.bordersize,
container_height - 2*self.bordersize)
end
end
--[[
an UnderlineContainer is a WidgetContainer that is able to paint
a line under its child node
--]]
UnderlineContainer = WidgetContainer:new{
linesize = 2,
padding = 1,
color = 0,
vertical_align = "top",
}
function UnderlineContainer:getSize()
return self:getContentSize()
end
function UnderlineContainer:getContentSize()
local contentSize = self[1]:getSize()
return Geom:new{
w = contentSize.w,
h = contentSize.h + self.linesize + self.padding
}
end
function UnderlineContainer:paintTo(bb, x, y)
local container_size = self:getSize()
local content_size = self:getContentSize()
local p_y = y
if self.vertical_align == "center" then
p_y = math.floor((container_size.h - content_size.h) / 2) + y
elseif self.vertical_align == "bottom" then
p_y = (container_size.h - content_size.h) + y
end
self[1]:paintTo(bb, x, p_y)
bb:paintRect(x, y + container_size.h - self.linesize,
container_size.w, self.linesize, self.color)
end
--[[
an InputContainer is an WidgetContainer that handles input events
an example for a key_event is this:
PanBy20 = {
{ "Shift", Input.group.Cursor },
seqtext = "Shift+Cursor",
doc = "pan by 20px",
event = "Pan", args = 20, is_inactive = true,
},
PanNormal = {
{ Input.group.Cursor },
seqtext = "Cursor",
doc = "pan by 10 px", event = "Pan", args = 10,
},
Quit = { {"Home"} },
it is suggested to reference configurable sequences from another table
and store that table as configuration setting
--]]
InputContainer = WidgetContainer:new{
vertical_align = "top",
}
function InputContainer:_init()
-- we need to do deep copy here
local new_key_events = {}
if self.key_events then
for k,v in pairs(self.key_events) do
new_key_events[k] = v
end
end
self.key_events = new_key_events
local new_ges_events = {}
if self.ges_events then
for k,v in pairs(self.ges_events) do
new_ges_events[k] = v
end
end
self.ges_events = new_ges_events
if not self.dimen then
self.dimen = Geom:new{}
end
end
function InputContainer:paintTo(bb, x, y)
self.dimen.x = x
self.dimen.y = y
if self[1] then
if self.vertical_align == "center" then
local content_size = self[1]:getSize()
self[1]:paintTo(bb, x, y + math.floor((self.dimen.h - content_size.h)/2))
else
self[1]:paintTo(bb, x, y)
end
end
end
--[[
the following handler handles keypresses and checks if they lead to a command.
if this is the case, we retransmit another event within ourselves
--]]
function InputContainer:onKeyPress(key)
for name, seq in pairs(self.key_events) do
if not seq.is_inactive then
for _, oneseq in ipairs(seq) do
if key:match(oneseq) then
local eventname = seq.event or name
return self:handleEvent(Event:new(eventname, seq.args, key))
end
end
end
end
end
function InputContainer:onGesture(ev)
for name, gsseq in pairs(self.ges_events) do
for _, gs_range in ipairs(gsseq) do
--DEBUG("gs_range", gs_range)
if gs_range:match(ev) then
local eventname = gsseq.event or name
return self:handleEvent(Event:new(eventname, gsseq.args, ev))
end
end
end
end

@ -0,0 +1,20 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
--[[
BottomContainer contains its content (1 widget) at the bottom of its own
dimensions
--]]
local BottomContainer = WidgetContainer:new()
function BottomContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb,
x + math.floor((self.dimen.w - contentSize.w)/2),
y + (self.dimen.h - contentSize.h))
end
return BottomContainer

@ -0,0 +1,25 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
--[[
CenterContainer centers its content (1 widget) within its own dimensions
--]]
local CenterContainer = WidgetContainer:new()
function CenterContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
local x_pos = x
local y_pos = y
if self.ignore ~= "height" then
y_pos = y + math.floor((self.dimen.h - contentSize.h)/2)
end
if self.ignore ~= "width" then
x_pos = x + math.floor((self.dimen.w - contentSize.w)/2)
end
self[1]:paintTo(bb, x_pos, y_pos)
end
return CenterContainer

@ -0,0 +1,61 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local Geom = require("ui/geometry")
--[[
A FrameContainer is some graphics content (1 widget) that is surrounded by a
frame
--]]
local FrameContainer = WidgetContainer:new{
background = nil,
color = 15,
margin = 0,
radius = 0,
bordersize = 2,
padding = 5,
width = nil,
height = nil,
invert = false,
}
function FrameContainer:getSize()
local content_size = self[1]:getSize()
return Geom:new{
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
}
end
function FrameContainer:paintTo(bb, x, y)
local my_size = self:getSize()
self.dimen = Geom:new{
x = x, y = y,
w = my_size.w,
h = my_size.h
}
local container_width = self.width or my_size.w
local container_height = self.height or my_size.h
--@TODO get rid of margin here? 13.03 2013 (houqp)
if self.background then
bb:paintRoundedRect(x, y, container_width, container_height,
self.background, self.radius)
end
if self.bordersize > 0 then
bb:paintBorder(x + self.margin, y + self.margin,
container_width - self.margin * 2,
container_height - self.margin * 2,
self.bordersize, self.color, self.radius)
end
if self[1] then
self[1]:paintTo(bb,
x + self.margin + self.bordersize + self.padding,
y + self.margin + self.bordersize + self.padding)
end
if self.invert then
bb:invertRect(x + self.bordersize, y + self.bordersize,
container_width - 2*self.bordersize,
container_height - 2*self.bordersize)
end
end
return FrameContainer

@ -0,0 +1,94 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local Event = require("ui/event")
--[[
an InputContainer is an WidgetContainer that handles input events
an example for a key_event is this:
PanBy20 = {
{ "Shift", Input.group.Cursor },
seqtext = "Shift+Cursor",
doc = "pan by 20px",
event = "Pan", args = 20, is_inactive = true,
},
PanNormal = {
{ Input.group.Cursor },
seqtext = "Cursor",
doc = "pan by 10 px", event = "Pan", args = 10,
},
Quit = { {"Home"} },
it is suggested to reference configurable sequences from another table
and store that table as configuration setting
--]]
local InputContainer = WidgetContainer:new{
vertical_align = "top",
}
function InputContainer:_init()
-- we need to do deep copy here
local new_key_events = {}
if self.key_events then
for k,v in pairs(self.key_events) do
new_key_events[k] = v
end
end
self.key_events = new_key_events
local new_ges_events = {}
if self.ges_events then
for k,v in pairs(self.ges_events) do
new_ges_events[k] = v
end
end
self.ges_events = new_ges_events
if not self.dimen then
self.dimen = Geom:new{}
end
end
function InputContainer:paintTo(bb, x, y)
self.dimen.x = x
self.dimen.y = y
if self[1] then
if self.vertical_align == "center" then
local content_size = self[1]:getSize()
self[1]:paintTo(bb, x, y + math.floor((self.dimen.h - content_size.h)/2))
else
self[1]:paintTo(bb, x, y)
end
end
end
--[[
the following handler handles keypresses and checks if they lead to a command.
if this is the case, we retransmit another event within ourselves
--]]
function InputContainer:onKeyPress(key)
for name, seq in pairs(self.key_events) do
if not seq.is_inactive then
for _, oneseq in ipairs(seq) do
if key:match(oneseq) then
local eventname = seq.event or name
return self:handleEvent(Event:new(eventname, seq.args, key))
end
end
end
end
end
function InputContainer:onGesture(ev)
for name, gsseq in pairs(self.ges_events) do
for _, gs_range in ipairs(gsseq) do
--DEBUG("gs_range", gs_range)
if gs_range:match(ev) then
local eventname = gsseq.event or name
return self:handleEvent(Event:new(eventname, gsseq.args, ev))
end
end
end
end
return InputContainer

@ -0,0 +1,17 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
--[[
LeftContainer aligns its content (1 widget) at the left of its own dimensions
--]]
local LeftContainer = WidgetContainer:new()
function LeftContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb, x , y + math.floor((self.dimen.h - contentSize.h)/2))
end
return LeftContainer

@ -0,0 +1,19 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
--[[
RightContainer aligns its content (1 widget) at the right of its own dimensions
--]]
local RightContainer = WidgetContainer:new()
function RightContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb,
x + (self.dimen.w - contentSize.w),
y + math.floor((self.dimen.h - contentSize.h)/2))
end
return RightContainer

@ -0,0 +1,42 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local Geom = require("ui/geometry")
--[[
an UnderlineContainer is a WidgetContainer that is able to paint
a line under its child node
--]]
local UnderlineContainer = WidgetContainer:new{
linesize = 2,
padding = 1,
color = 0,
vertical_align = "top",
}
function UnderlineContainer:getSize()
return self:getContentSize()
end
function UnderlineContainer:getContentSize()
local contentSize = self[1]:getSize()
return Geom:new{
w = contentSize.w,
h = contentSize.h + self.linesize + self.padding
}
end
function UnderlineContainer:paintTo(bb, x, y)
local container_size = self:getSize()
local content_size = self:getContentSize()
local p_y = y
if self.vertical_align == "center" then
p_y = math.floor((container_size.h - content_size.h) / 2) + y
elseif self.vertical_align == "bottom" then
p_y = (container_size.h - content_size.h) + y
end
self[1]:paintTo(bb, x, p_y)
bb:paintRect(x, y + container_size.h - self.linesize,
container_size.w, self.linesize, self.color)
end
return UnderlineContainer

@ -0,0 +1,70 @@
local Geom = require("ui/geometry")
local Widget = require("ui/widget/widget")
--[[
WidgetContainer is a container for another Widget
--]]
local WidgetContainer = Widget:new()
function WidgetContainer:init()
if not self.dimen then
self.dimen = Geom:new{}
end
end
function WidgetContainer:getSize()
if self.dimen then
-- fixed size
return self.dimen
elseif self[1] then
-- return size of first child widget
return self[1]:getSize()
else
return Geom:new{ w = 0, h = 0 }
end
end
--[[
delete all child widgets
--]]
function WidgetContainer:clear()
while table.remove(self) do end
end
function WidgetContainer:paintTo(bb, x, y)
-- default to pass request to first child widget
if self[1] then
return self[1]:paintTo(bb, x, y)
end
end
function WidgetContainer:propagateEvent(event)
-- propagate to children
for _, widget in ipairs(self) do
if widget:handleEvent(event) then
-- stop propagating when an event handler returns true
return true
end
end
return false
end
--[[
Containers will pass events to children or react on them themselves
--]]
function WidgetContainer:handleEvent(event)
if not self:propagateEvent(event) then
-- call our own standard event handler
return Widget.handleEvent(self, event)
else
return true
end
end
function WidgetContainer:free()
for _, widget in ipairs(self) do
if widget.free then widget:free() end
end
end
return WidgetContainer

@ -1,10 +1,19 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/buttontable" local FrameContainer = require("ui/widget/container/framecontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local TextWidget = require("ui/widget/textwidget")
local TextBoxWidget = require("ui/widget/textboxwidget")
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
local LineWidget = require("ui/widget/linewidget")
local Screen = require("ui/screen")
local GestureRange = require("ui/gesturerange")
local Geom = require("ui/geometry")
local Font = require("ui/font")
--[[ --[[
Display quick lookup word definition Display quick lookup word definition
]] ]]
DictQuickLookup = InputContainer:new{ local DictQuickLookup = InputContainer:new{
results = nil, results = nil,
lookupword = nil, lookupword = nil,
dictionary = nil, dictionary = nil,
@ -16,13 +25,13 @@ DictQuickLookup = InputContainer:new{
width = nil, width = nil,
height = nil, height = nil,
title_padding = scaleByDPI(5), title_padding = Screen:scaleByDPI(5),
title_margin = scaleByDPI(2), title_margin = Screen:scaleByDPI(2),
word_padding = scaleByDPI(2), word_padding = Screen:scaleByDPI(2),
word_margin = scaleByDPI(2), word_margin = Screen:scaleByDPI(2),
definition_padding = scaleByDPI(2), definition_padding = Screen:scaleByDPI(2),
definition_margin = scaleByDPI(2), definition_margin = Screen:scaleByDPI(2),
button_padding = scaleByDPI(14), button_padding = Screen:scaleByDPI(14),
} }
function DictQuickLookup:init() function DictQuickLookup:init()
@ -133,7 +142,7 @@ function DictQuickLookup:update()
--background = 8, --background = 8,
dimen = Geom:new{ dimen = Geom:new{
w = button_table:getSize().w + self.button_padding, w = button_table:getSize().w + self.button_padding,
h = scaleByDPI(2), h = Screen:scaleByDPI(2),
} }
} }
@ -260,3 +269,5 @@ function DictQuickLookup:onTapCloseDict(arg, ges_ev)
end end
return true return true
end end
return DictQuickLookup

@ -0,0 +1,24 @@
--[[
The EventListener is an interface that handles events
EventListeners have a rudimentary event handler/dispatcher that
will call a method "onEventName" for an event with name
"EventName"
--]]
local EventListener = {}
function EventListener:new(o)
local o = o or {}
setmetatable(o, self)
self.__index = self
if o.init then o:init() end
return o
end
function EventListener:handleEvent(event)
if self[event.handler] then
return self[event.handler](self, unpack(event.args))
end
end
return EventListener

@ -1,6 +1,9 @@
require "ui/widget/menu" local Menu = require("ui/widget/menu")
local Screen = require("ui/screen")
local UIManager = require("ui/uimanager")
-- lfs
FileChooser = Menu:extend{ local FileChooser = Menu:extend{
height = Screen:getHeight(), height = Screen:getHeight(),
width = Screen:getWidth(), width = Screen:getWidth(),
no_title = true, no_title = true,
@ -73,3 +76,5 @@ function FileChooser:onFileSelect(file)
UIManager:close(self) UIManager:close(self)
return true return true
end end
return FileChooser

@ -0,0 +1,29 @@
local TextWidget = require("ui/widget/textwidget")
local RenderText = require("ui/rendertext")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
--[[
FixedTextWidget
--]]
local FixedTextWidget = TextWidget:new{}
function FixedTextWidget:getSize()
local tsize = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.face, self.text, true)
if not tsize then
return Geom:new{}
end
self._length = tsize.x
self._height = self.face.size
return Geom:new{
w = self._length,
h = self._height,
}
end
function FixedTextWidget:paintTo(bb, x, y)
RenderText:renderUtf8Text(bb, x, y+self._height, self.face, self.text,
true, self.bgcolor, self.fgcolor)
end
return FixedTextWidget

@ -1,3 +1,6 @@
local InputContainer = require("ui/widget/container/inputcontainer")
-- UIManager
--[[ --[[
Wrapper Widget that manages focus for a whole dialog Wrapper Widget that manages focus for a whole dialog
@ -21,7 +24,7 @@ reach either <okbutton> or <cancelbutton>.
but notice that this does _not_ do the layout for you, but notice that this does _not_ do the layout for you,
it rather defines an abstract layout. it rather defines an abstract layout.
]] ]]
FocusManager = InputContainer:new{ local FocusManager = InputContainer:new{
selected = nil, -- defaults to x=1, y=1 selected = nil, -- defaults to x=1, y=1
layout = nil, -- mandatory layout = nil, -- mandatory
movement_allowed = { x = true, y = true } movement_allowed = { x = true, y = true }
@ -93,3 +96,5 @@ function FocusManager:onWrapLast()
self.selected.y = 1 self.selected.y = 1
return true return true
end end
return FocusManager

@ -1,172 +0,0 @@
require "ui/widget/container"
--[[
A Layout widget that puts objects besides each others
--]]
HorizontalGroup = WidgetContainer:new{
align = "center",
_size = nil,
}
function HorizontalGroup:getSize()
if not self._size then
self._size = { w = 0, h = 0 }
self._offsets = { }
for i, widget in ipairs(self) do
local w_size = widget:getSize()
self._offsets[i] = {
x = self._size.w,
y = w_size.h
}
self._size.w = self._size.w + w_size.w
if w_size.h > self._size.h then
self._size.h = w_size.h
end
end
end
return self._size
end
function HorizontalGroup:paintTo(bb, x, y)
local size = self:getSize()
for i, widget in ipairs(self) do
if self.align == "center" then
widget:paintTo(bb,
x + self._offsets[i].x,
y + math.floor((size.h - self._offsets[i].y) / 2))
elseif self.align == "top" then
widget:paintTo(bb, x + self._offsets[i].x, y)
elseif self.align == "bottom" then
widget:paintTo(bb, x + self._offsets[i].x, y + size.h - self._offsets[i].y)
end
end
end
function HorizontalGroup:clear()
self:free()
WidgetContainer.clear(self)
end
function HorizontalGroup:resetLayout()
self._size = nil
self._offsets = {}
end
function HorizontalGroup:free()
self:resetLayout()
WidgetContainer.free(self)
end
--[[
A Layout widget that puts objects under each other
--]]
VerticalGroup = WidgetContainer:new{
align = "center",
_size = nil,
_offsets = {}
}
function VerticalGroup:getSize()
if not self._size then
self._size = { w = 0, h = 0 }
self._offsets = { }
for i, widget in ipairs(self) do
local w_size = widget:getSize()
self._offsets[i] = {
x = w_size.w,
y = self._size.h,
}
self._size.h = self._size.h + w_size.h
if w_size.w > self._size.w then
self._size.w = w_size.w
end
end
end
return self._size
end
function VerticalGroup:paintTo(bb, x, y)
local size = self:getSize()
for i, widget in ipairs(self) do
if self.align == "center" then
widget:paintTo(bb,
x + math.floor((size.w - self._offsets[i].x) / 2),
y + self._offsets[i].y)
elseif self.align == "left" then
widget:paintTo(bb, x, y + self._offsets[i].y)
elseif self.align == "right" then
widget:paintTo(bb,
x + size.w - self._offsets[i].x,
y + self._offsets[i].y)
end
end
end
function VerticalGroup:clear()
self:free()
WidgetContainer.clear(self)
end
function VerticalGroup:resetLayout()
self._size = nil
self._offsets = {}
end
function VerticalGroup:free()
self:resetLayout()
WidgetContainer.free(self)
end
--[[
A Layout widget that puts objects above each other
--]]
OverlapGroup = WidgetContainer:new{
_size = nil,
}
function OverlapGroup:getSize()
if not self._size then
self._size = {w = 0, h = 0}
self._offsets = { x = math.huge, y = math.huge }
for i, widget in ipairs(self) do
local w_size = widget:getSize()
if self._size.h < w_size.h then
self._size.h = w_size.h
end
if self._size.w < w_size.w then
self._size.w = w_size.w
end
end
end
if self.dimen.w then
self._size.w = self.dimen.w
end
if self.dimen.h then
self._size.h = self.dimen.h
end
return self._size
end
function OverlapGroup:paintTo(bb, x, y)
local size = self:getSize()
for i, wget in ipairs(self) do
local wget_size = wget:getSize()
if wget.align == "right" then
wget:paintTo(bb, x+size.w-wget_size.w, y)
elseif wget.align == "center" then
wget:paintTo(bb, x+math.floor((size.w-wget_size.w)/2), y)
else
-- default to left
wget:paintTo(bb, x, y)
end
end
end

@ -0,0 +1,61 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
--[[
A Layout widget that puts objects besides each others
--]]
local HorizontalGroup = WidgetContainer:new{
align = "center",
_size = nil,
}
function HorizontalGroup:getSize()
if not self._size then
self._size = { w = 0, h = 0 }
self._offsets = { }
for i, widget in ipairs(self) do
local w_size = widget:getSize()
self._offsets[i] = {
x = self._size.w,
y = w_size.h
}
self._size.w = self._size.w + w_size.w
if w_size.h > self._size.h then
self._size.h = w_size.h
end
end
end
return self._size
end
function HorizontalGroup:paintTo(bb, x, y)
local size = self:getSize()
for i, widget in ipairs(self) do
if self.align == "center" then
widget:paintTo(bb,
x + self._offsets[i].x,
y + math.floor((size.h - self._offsets[i].y) / 2))
elseif self.align == "top" then
widget:paintTo(bb, x + self._offsets[i].x, y)
elseif self.align == "bottom" then
widget:paintTo(bb, x + self._offsets[i].x, y + size.h - self._offsets[i].y)
end
end
end
function HorizontalGroup:clear()
self:free()
WidgetContainer.clear(self)
end
function HorizontalGroup:resetLayout()
self._size = nil
self._offsets = {}
end
function HorizontalGroup:free()
self:resetLayout()
WidgetContainer.free(self)
end
return HorizontalGroup

@ -0,0 +1,14 @@
local Widget = require("ui/widget/widget")
--[[
Dummy Widget that reserves horizontal space
--]]
local HorizontalSpan = Widget:new{
width = 0,
}
function HorizontalSpan:getSize()
return {w = self.width, h = 0}
end
return HorizontalSpan

@ -1,11 +1,12 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/image" local ImageWidget = require("ui/widget/imagewidget")
local GestureRange = require("ui/gesturerange")
local UIManager = require("ui/uimanager")
--[[ --[[
Button with a big icon image! Designed for touch device Button with a big icon image! Designed for touch device
--]] --]]
IconButton = InputContainer:new{ local IconButton = InputContainer:new{
icon_file = "resources/info-confirm.png", icon_file = "resources/info-confirm.png",
dimen = nil, dimen = nil,
-- show_parent is used for UIManager:setDirty, so we can trigger repaint -- show_parent is used for UIManager:setDirty, so we can trigger repaint
@ -53,3 +54,4 @@ function IconButton:onSetDimensions(new_dimen)
self.dimen = new_dimen self.dimen = new_dimen
end end
return IconButton

@ -1,9 +1,11 @@
require "ui/widget/base" local Widget = require("ui/widget/widget")
local Geom = require("ui/geometry")
-- Image
--[[ --[[
ImageWidget shows an image from a file ImageWidget shows an image from a file
--]] --]]
ImageWidget = Widget:new{ local ImageWidget = Widget:new{
file = nil, file = nil,
invert = nil, invert = nil,
dim = nil, dim = nil,
@ -51,4 +53,4 @@ function ImageWidget:free()
end end
end end
return ImageWidget

@ -1,11 +1,20 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
local Font = require("ui/font")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local FrameContainer = require("ui/widget/container/framecontainer")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local ImageWidget = require("ui/widget/imagewidget")
local TextBoxWidget = require("ui/widget/textboxwidget")
local HorizontalSpan = require("ui/widget/horizontalspan")
local UIManager = require("ui/uimanager")
--[[ --[[
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
]] ]]
InfoMessage = InputContainer:new{ local InfoMessage = InputContainer:new{
face = Font:getFace("infofont", 25), face = Font:getFace("infofont", 25),
text = "", text = "",
timeout = nil, -- in seconds timeout = nil, -- in seconds
@ -69,3 +78,5 @@ function InfoMessage:onTapClose()
UIManager:close(self) UIManager:close(self)
return true return true
end end
return InfoMessage

@ -1,7 +1,17 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/inputtext" local FrameContainer = require("ui/widget/container/framecontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local ButtonTable = require("ui/widget/buttontable")
local TextWidget = require("ui/widget/textwidget")
local LineWidget = require("ui/widget/linewidget")
local InputText = require("ui/widget/inputtext")
local VerticalGroup = require("ui/widget/verticalgroup")
local Font = require("ui/font")
local Geom = require("ui/geometry")
local UIManager = require("ui/uimanager")
local Screen = require("ui/screen")
InputDialog = InputContainer:new{ local InputDialog = InputContainer:new{
title = "", title = "",
input = "", input = "",
input_hint = "", input_hint = "",
@ -14,11 +24,11 @@ InputDialog = InputContainer:new{
title_face = Font:getFace("tfont", 22), title_face = Font:getFace("tfont", 22),
input_face = Font:getFace("cfont", 20), input_face = Font:getFace("cfont", 20),
title_padding = scaleByDPI(5), title_padding = Screen:scaleByDPI(5),
title_margin = scaleByDPI(2), title_margin = Screen:scaleByDPI(2),
input_padding = scaleByDPI(10), input_padding = Screen:scaleByDPI(10),
input_margin = scaleByDPI(10), input_margin = Screen:scaleByDPI(10),
button_padding = scaleByDPI(14), button_padding = Screen:scaleByDPI(14),
} }
function InputDialog:init() function InputDialog:init()
@ -52,7 +62,7 @@ function InputDialog:init()
--background = 8, --background = 8,
dimen = Geom:new{ dimen = Geom:new{
w = button_table:getSize().w + self.button_padding, w = button_table:getSize().w + self.button_padding,
h = scaleByDPI(2), h = Screen:scaleByDPI(2),
} }
} }
@ -107,3 +117,5 @@ end
function InputDialog:onClose() function InputDialog:onClose()
self.input:onCloseKeyboard() self.input:onCloseKeyboard()
end end
return InputDialog

@ -1,9 +1,13 @@
require "ui/graphics" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/text" local ScrollTextWidget = require("ui/widget/scrolltextwidget")
require "ui/widget/keyboard" local TextBoxWidget = require("ui/widget/textboxwidget")
require "ui/widget/container" local FrameContainer = require("ui/widget/container/framecontainer")
local VirtualKeyboard = require("ui/widget/virtualkeyboard")
local Font = require("ui/font")
local Screen = require("ui/screen")
local UIManager = require("ui/uimanager")
InputText = InputContainer:new{ local InputText = InputContainer:new{
text = "", text = "",
hint = "demo hint", hint = "demo hint",
charlist = {}, -- table to store input string charlist = {}, -- table to store input string
@ -144,3 +148,5 @@ function InputText:CharlistToString()
end end
return s return s
end end
return InputText

@ -1,6 +1,6 @@
require "ui/widget/base" local Widget = require("ui/widget/widget")
LineWidget = Widget:new{ local LineWidget = Widget:new{
style = "solid", style = "solid",
background = 15, background = 15,
dimen = nil, dimen = nil,
@ -29,3 +29,5 @@ function LineWidget:paintTo(bb, x, y)
end end
end end
end end
return LineWidget

@ -1,16 +1,30 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
require "ui/widget/focusmanager" local WidgetContainer = require("ui/widget/container/widgetcontainer")
require "ui/widget/infomessage" local FrameContainer = require("ui/widget/container/framecontainer")
require "ui/widget/button" local CenterContainer = require("ui/widget/container/centercontainer")
require "ui/widget/text" local BottomContainer = require("ui/widget/container/bottomcontainer")
require "ui/widget/group" local UnderlineContainer = require("ui/widget/container/underlinecontainer")
require "ui/widget/span" local HorizontalSpan = require("ui/widget/horizontalspan")
require "ui/font" local FocusManager = require("ui/widget/focusmanager")
local TextWidget = require("ui/widget/textwidget")
local OverlapGroup = require("ui/widget/overlapgroup")
local VerticalGroup = require("ui/widget/verticalgroup")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local Button = require("ui/widget/button")
local GestureRange = require("ui/gesturerange")
local Font = require("ui/font")
local Geom = require("ui/geometry")
local Device = require("ui/device")
local Screen = require("ui/screen")
local Input = require("ui/input")
local UIManager = require("ui/uimanager")
local RenderText = require("ui/rendertext")
local _ = require("gettext")
--[[ --[[
Widget that displays a shortcut icon for menu item Widget that displays a shortcut icon for menu item
--]] --]]
ItemShortCutIcon = WidgetContainer:new{ local ItemShortCutIcon = WidgetContainer:new{
dimen = Geom:new{ w = 22, h = 22 }, dimen = Geom:new{ w = 22, h = 22 },
key = nil, key = nil,
bordersize = 2, bordersize = 2,
@ -60,7 +74,7 @@ end
NOTICE: NOTICE:
@menu entry must be provided in order to close the menu @menu entry must be provided in order to close the menu
--]] --]]
MenuCloseButton = InputContainer:new{ local MenuCloseButton = InputContainer:new{
align = "right", align = "right",
menu = nil, menu = nil,
dimen = Geom:new{}, dimen = Geom:new{},
@ -92,7 +106,7 @@ end
--[[ --[[
Widget that displays an item for menu Widget that displays an item for menu
--]] --]]
MenuItem = InputContainer:new{ local MenuItem = InputContainer:new{
text = nil, text = nil,
show_parent = nil, show_parent = nil,
detail = nil, detail = nil,
@ -132,7 +146,7 @@ function MenuItem:init()
} }
end end
w = sizeUtf8Text(0, self.dimen.w, self.face, self.text, true).x w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, self.text, true).x
if w >= self.content_width then if w >= self.content_width then
if Device:isTouchDevice() then if Device:isTouchDevice() then
else else
@ -141,8 +155,8 @@ function MenuItem:init()
} }
end end
indicator = " >>" indicator = " >>"
indicator_w = sizeUtf8Text(0, self.dimen.w, self.face, indicator, true).x indicator_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, indicator, true).x
self.text = getSubTextByWidth(self.text, self.face, self.text = RenderText:getSubTextByWidth(self.text, self.face,
self.content_width - indicator_w, true) .. indicator self.content_width - indicator_w, true) .. indicator
end end
@ -211,7 +225,7 @@ end
--[[ --[[
Widget that displays menu Widget that displays menu
--]] --]]
Menu = FocusManager:new{ local Menu = FocusManager:new{
show_parent = nil, show_parent = nil,
-- face for displaying item contents -- face for displaying item contents
cface = Font:getFace("cfont", 22), cface = Font:getFace("cfont", 22),
@ -611,3 +625,5 @@ function Menu:onSwipe(arg, ges_ev)
self:onPrevPage() self:onPrevPage()
end end
end end
return Menu

@ -1,9 +1,16 @@
require "ui/widget/container" local InputContainer = require("ui/widget/container/inputcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local TextBoxWidget = require("ui/widget/textboxwidget")
local Font = require("ui/font")
local Geom = require("ui/geometry")
local Device = require("ui/device")
local UIManager = require("ui/uimanager")
--[[ --[[
Widget that displays a tiny notification on top of screen Widget that displays a tiny notification on top of screen
--]] --]]
Notification = InputContainer:new{ local Notification = InputContainer:new{
face = Font:getFace("infofont", 20), face = Font:getFace("infofont", 20),
text = "Null Message", text = "Null Message",
timeout = nil, timeout = nil,
@ -50,3 +57,4 @@ function Notification:onAnyKeyPressed()
return true return true
end end
return Notification

@ -0,0 +1,51 @@
local WidgetContainer = require("ui/widget/container/widgetcontainer")
--[[
A Layout widget that puts objects above each other
--]]
local OverlapGroup = WidgetContainer:new{
_size = nil,
}
function OverlapGroup:getSize()
if not self._size then
self._size = {w = 0, h = 0}
self._offsets = { x = math.huge, y = math.huge }
for i, widget in ipairs(self) do
local w_size = widget:getSize()
if self._size.h < w_size.h then
self._size.h = w_size.h
end
if self._size.w < w_size.w then
self._size.w = w_size.w
end
end
end
if self.dimen.w then
self._size.w = self.dimen.w
end
if self.dimen.h then
self._size.h = self.dimen.h
end
return self._size
end
function OverlapGroup:paintTo(bb, x, y)
local size = self:getSize()
for i, wget in ipairs(self) do
local wget_size = wget:getSize()
if wget.align == "right" then
wget:paintTo(bb, x+size.w-wget_size.w, y)
elseif wget.align == "center" then
wget:paintTo(bb, x+math.floor((size.w-wget_size.w)/2), y)
else
-- default to left
wget:paintTo(bb, x, y)
end
end
end
return OverlapGroup

@ -1,10 +1,9 @@
require "ui/widget/base" local Widget = require("ui/widget/widget")
--[[ --[[
ProgressWidget shows a progress bar ProgressWidget shows a progress bar
--]] --]]
ProgressWidget = Widget:new{ local ProgressWidget = Widget:new{
width = nil, width = nil,
height = nil, height = nil,
margin_h = 3, margin_h = 3,
@ -35,5 +34,4 @@ function ProgressWidget:setPercentage(percentage)
self.percentage = percentage self.percentage = percentage
end end
return ProgressWidget

@ -0,0 +1,15 @@
local Widget = require("ui/widget/widget")
--[[
Dummy Widget that reserves vertical and horizontal space
]]
local RectSpan = Widget:new{
width = 0,
hright = 0,
}
function RectSpan:getSize()
return {w = self.width, h = self.height}
end
return RectSpan

@ -0,0 +1,80 @@
local InputContainer = require("ui/widget/container/inputcontainer")
local TextBoxWidget = require("ui/widget/textboxwidget")
local VerticalScrollBar = require("ui/widget/verticalscrollbar")
local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange")
local UIManager = require("ui/uimanager")
local Screen = require("ui/screen")
--[[
Text widget with vertical scroll bar
--]]
local ScrollTextWidget = InputContainer:new{
text = nil,
face = nil,
bgcolor = 0.0, -- [0.0, 1.0]
fgcolor = 1.0, -- [0.0, 1.0]
width = 400,
height = 20,
scroll_bar_width = Screen:scaleByDPI(6),
text_scroll_span = Screen:scaleByDPI(6),
dialog = nil,
}
function ScrollTextWidget:init()
self.text_widget = TextBoxWidget:new{
text = self.text,
face = self.face,
bgcolor = self.bgcolor,
fgcolor = self.fgcolor,
width = self.width - self.scroll_bar_width - self.text_scroll_span,
height = self.height
}
local visible_line_count = self.text_widget:getVisLineCount()
local total_line_count = self.text_widget:getAllLineCount()
self.v_scroll_bar = VerticalScrollBar:new{
enable = visible_line_count < total_line_count,
low = 0,
high = visible_line_count/total_line_count,
width = Screen:scaleByDPI(6),
height = self.height,
}
local horizontal_group = HorizontalGroup:new{}
table.insert(horizontal_group, self.text_widget)
table.insert(horizontal_group, HorizontalSpan:new{width = Screen:scaleByDPI(6)})
table.insert(horizontal_group, self.v_scroll_bar)
self[1] = horizontal_group
self.dimen = Geom:new(self[1]:getSize())
if Device:isTouchDevice() then
self.ges_events = {
Swipe = {
GestureRange:new{
ges = "swipe",
range = self.dimen,
},
},
}
end
end
function ScrollTextWidget:updateScrollBar(text)
local virtual_line_num = text:getVirtualLineNum()
local visible_line_count = text:getVisLineCount()
local all_line_count = text:getAllLineCount()
self.v_scroll_bar:set(
(virtual_line_num - 1) / all_line_count,
(virtual_line_num - 1 + visible_line_count) / all_line_count
)
end
function ScrollTextWidget:onSwipe(arg, ges)
if ges.direction == "north" then
self.text_widget:scrollDown()
self:updateScrollBar(self.text_widget)
elseif ges.direction == "south" then
self.text_widget:scrollUp()
self:updateScrollBar(self.text_widget)
end
UIManager:setDirty(self.dialog, "partial")
return true
end

@ -1,27 +0,0 @@
require "ui/widget/base"
--[[
Dummy Widget that reserves horizontal space
--]]
HorizontalSpan = Widget:new{
width = 0,
}
function HorizontalSpan:getSize()
return {w = self.width, h = 0}
end
--[[
Dummy Widget that reserves vertical space
--]]
VerticalSpan = Widget:new{
width = 0,
}
function VerticalSpan:getSize()
return {w = 0, h = self.width}
end

@ -1,65 +1,14 @@
require "ui/rendertext" local Widget = require("ui/widget/widget")
require "ui/widget/base" local RenderText = require("ui/rendertext")
require "ui/widget/scrollbar" local Screen = require("ui/screen")
local Geom = require("ui/geometry")
--[[ -- TODO: rename string:gsplit definition
A TextWidget puts a string on a single line
--]]
TextWidget = Widget:new{
text = nil,
face = nil,
bgcolor = 0.0, -- [0.0, 1.0]
fgcolor = 1.0, -- [0.0, 1.0]
_bb = nil,
_length = 0,
_height = 0,
_maxlength = 1200,
}
--function TextWidget:_render()
--local h = self.face.size * 1.3
--self._bb = Blitbuffer.new(self._maxlength, h)
--self._length = renderUtf8Text(self._bb, 0, h*0.8, self.face, self.text, self.color)
--end
function TextWidget:getSize()
--if not self._bb then
--self:_render()
--end
--return { w = self._length, h = self._bb:getHeight() }
local tsize = sizeUtf8Text(0, Screen:getWidth(), self.face, self.text, true)
if not tsize then
return Geom:new{}
end
self._length = tsize.x
self._height = self.face.size * 1.5
return Geom:new{
w = self._length,
h = self._height,
}
end
function TextWidget:paintTo(bb, x, y)
--if not self._bb then
--self:_render()
--end
--bb:blitFrom(self._bb, x, y, 0, 0, self._length, self._bb:getHeight())
--@TODO Don't use kerning for monospaced fonts. (houqp)
renderUtf8Text(bb, x, y+self._height*0.7, self.face, self.text,
true, self.bgcolor, self.fgcolor)
end
function TextWidget:free()
if self._bb then
self._bb:free()
self._bb = nil
end
end
--[[ --[[
A TextWidget that handles long text wrapping A TextWidget that handles long text wrapping
--]] --]]
TextBoxWidget = Widget:new{ local TextBoxWidget = Widget:new{
text = nil, text = nil,
face = nil, face = nil,
bgcolor = 0.0, -- [0.0, 1.0] bgcolor = 0.0, -- [0.0, 1.0]
@ -157,7 +106,7 @@ function TextBoxWidget:_getVerticalList(alg)
for w in word:gsplit("%p+", true) do for w in word:gsplit("%p+", true) do
local word_box = {} local word_box = {}
word_box.word = w word_box.word = w
word_box.width = sizeUtf8Text(0, Screen:getWidth(), self.face, w, true).x word_box.width = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.face, w, true).x
table.insert(h_list, word_box) table.insert(h_list, word_box)
end end
end end
@ -245,7 +194,7 @@ end
function TextBoxWidget:_render(v_list) function TextBoxWidget:_render(v_list)
local font_height = self.face.size local font_height = self.face.size
local line_height_px = self.line_height * font_height local line_height_px = self.line_height * font_height
local space_w = sizeUtf8Text(0, Screen:getWidth(), self.face, " ", true).x local space_w = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.face, " ", true).x
local h = (font_height + line_height_px) * #v_list local h = (font_height + line_height_px) * #v_list
self._bb = Blitbuffer.new(self.width, h) self._bb = Blitbuffer.new(self.width, h)
local y = font_height local y = font_height
@ -255,7 +204,7 @@ function TextBoxWidget:_render(v_list)
for _,w in ipairs(l) do for _,w in ipairs(l) do
--@TODO Don't use kerning for monospaced fonts. (houqp) --@TODO Don't use kerning for monospaced fonts. (houqp)
-- refert to cb25029dddc42693cc7aaefbe47e9bd3b7e1a750 in master tree -- refert to cb25029dddc42693cc7aaefbe47e9bd3b7e1a750 in master tree
renderUtf8Text(self._bb, pen_x, y, self.face, w.word, true, RenderText:renderUtf8Text(self._bb, pen_x, y, self.face, w.word, true,
self.bgcolor, self.fgcolor) self.bgcolor, self.fgcolor)
pen_x = pen_x + w.width pen_x = pen_x + w.width
end end
@ -312,97 +261,4 @@ function TextBoxWidget:free()
end end
end end
--[[ return TextBoxWidget
FixedTextWidget
--]]
FixedTextWidget = TextWidget:new{}
function FixedTextWidget:getSize()
local tsize = sizeUtf8Text(0, Screen:getWidth(), self.face, self.text, true)
if not tsize then
return Geom:new{}
end
self._length = tsize.x
self._height = self.face.size
return Geom:new{
w = self._length,
h = self._height,
}
end
function FixedTextWidget:paintTo(bb, x, y)
renderUtf8Text(bb, x, y+self._height, self.face, self.text,
true, self.bgcolor, self.fgcolor)
end
--[[
Text widget with vertical scroll bar
--]]
ScrollTextWidget = InputContainer:new{
text = nil,
face = nil,
bgcolor = 0.0, -- [0.0, 1.0]
fgcolor = 1.0, -- [0.0, 1.0]
width = 400,
height = 20,
scroll_bar_width = scaleByDPI(6),
text_scroll_span = scaleByDPI(6),
dialog = nil,
}
function ScrollTextWidget:init()
self.text_widget = TextBoxWidget:new{
text = self.text,
face = self.face,
bgcolor = self.bgcolor,
fgcolor = self.fgcolor,
width = self.width - self.scroll_bar_width - self.text_scroll_span,
height = self.height
}
local visible_line_count = self.text_widget:getVisLineCount()
local total_line_count = self.text_widget:getAllLineCount()
self.v_scroll_bar = VerticalScrollBar:new{
enable = visible_line_count < total_line_count,
low = 0,
high = visible_line_count/total_line_count,
width = scaleByDPI(6),
height = self.height,
}
local horizontal_group = HorizontalGroup:new{}
table.insert(horizontal_group, self.text_widget)
table.insert(horizontal_group, HorizontalSpan:new{width = scaleByDPI(6)})
table.insert(horizontal_group, self.v_scroll_bar)
self[1] = horizontal_group
self.dimen = Geom:new(self[1]:getSize())
if Device:isTouchDevice() then
self.ges_events = {
Swipe = {
GestureRange:new{
ges = "swipe",
range = self.dimen,
},
},
}
end
end
function ScrollTextWidget:updateScrollBar(text)
local virtual_line_num = text:getVirtualLineNum()
local visible_line_count = text:getVisLineCount()
local all_line_count = text:getAllLineCount()
self.v_scroll_bar:set(
(virtual_line_num - 1) / all_line_count,
(virtual_line_num - 1 + visible_line_count) / all_line_count
)
end
function ScrollTextWidget:onSwipe(arg, ges)
if ges.direction == "north" then
self.text_widget:scrollDown()
self:updateScrollBar(self.text_widget)
elseif ges.direction == "south" then
self.text_widget:scrollUp()
self:updateScrollBar(self.text_widget)
end
UIManager:setDirty(self.dialog, "partial")
return true
end

@ -0,0 +1,60 @@
local Widget = require("ui/widget/widget")
local Screen = require("ui/screen")
local RenderText = require("ui/rendertext")
local Geom = require("ui/geometry")
--[[
A TextWidget puts a string on a single line
--]]
local TextWidget = Widget:new{
text = nil,
face = nil,
bgcolor = 0.0, -- [0.0, 1.0]
fgcolor = 1.0, -- [0.0, 1.0]
_bb = nil,
_length = 0,
_height = 0,
_maxlength = 1200,
}
--function TextWidget:_render()
--local h = self.face.size * 1.3
--self._bb = Blitbuffer.new(self._maxlength, h)
--self._length = RenderText:renderUtf8Text(self._bb, 0, h*0.8, self.face, self.text, self.color)
--end
function TextWidget:getSize()
--if not self._bb then
--self:_render()
--end
--return { w = self._length, h = self._bb:getHeight() }
local tsize = RenderText:sizeUtf8Text(0, Screen:getWidth(), self.face, self.text, true)
if not tsize then
return Geom:new{}
end
self._length = tsize.x
self._height = self.face.size * 1.5
return Geom:new{
w = self._length,
h = self._height,
}
end
function TextWidget:paintTo(bb, x, y)
--if not self._bb then
--self:_render()
--end
--bb:blitFrom(self._bb, x, y, 0, 0, self._length, self._bb:getHeight())
--@TODO Don't use kerning for monospaced fonts. (houqp)
RenderText:renderUtf8Text(bb, x, y+self._height*0.7, self.face, self.text,
true, self.bgcolor, self.fgcolor)
end
function TextWidget:free()
if self._bb then
self._bb:free()
self._bb = nil
end
end
return TextWidget

@ -1,16 +1,29 @@
local TextWidget = require("ui/widget/textwidget")
local InputContainer = require("ui/widget/container/inputcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local Font = require("ui/font")
local Geom = require("ui/geometry")
local RenderText = require("ui/rendertext")
local UIManager = require("ui/uimanager")
local Screen = require("ui/screen")
local Device = require("ui/device")
local GestureRange = require("ui/gesturerange")
local _ = require("gettext")
ToggleLabel = TextWidget:new{ local ToggleLabel = TextWidget:new{
bgcolor = 0, bgcolor = 0,
fgcolor = 1, fgcolor = 1,
} }
function ToggleLabel:paintTo(bb, x, y) function ToggleLabel:paintTo(bb, x, y)
renderUtf8Text(bb, x, y+self._height*0.75, self.face, self.text, true, self.bgcolor, self.fgcolor) RenderText:renderUtf8Text(bb, x, y+self._height*0.75, self.face, self.text, true, self.bgcolor, self.fgcolor)
end end
ToggleSwitch = InputContainer:new{ local ToggleSwitch = InputContainer:new{
width = scaleByDPI(216), width = Screen:scaleByDPI(216),
height = scaleByDPI(30), height = Screen:scaleByDPI(30),
bgcolor = 0, -- unfoused item color bgcolor = 0, -- unfoused item color
fgcolor = 7, -- focused item color fgcolor = 7, -- focused item color
} }
@ -123,3 +136,4 @@ function ToggleSwitch:onTapSelect(arg, gev)
UIManager.repaint_all = true UIManager.repaint_all = true
end end
return ToggleSwitch

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save