From ef111b99c620a412d27544ba3c0aeb58f19183e6 Mon Sep 17 00:00:00 2001 From: HW Date: Fri, 18 Oct 2013 22:38:07 +0200 Subject: [PATCH] Refactored to use strictly locals --- .../filemanager/{fm.lua => filemanager.lua} | 22 +- .../{fmhistory.lua => filemanagerhistory.lua} | 10 +- .../{fmmenu.lua => filemanagermenu.lua} | 17 +- frontend/cache.lua | 23 +- frontend/cacheitem.lua | 19 + frontend/dbg.lua | 46 +-- frontend/{settings.lua => docsettings.lua} | 9 +- frontend/document/credocument.lua | 40 ++- frontend/document/djvudocument.lua | 43 ++- frontend/document/document.lua | 50 +-- frontend/document/documentregistry.lua | 35 ++ frontend/document/koptinterface.lua | 21 +- frontend/document/pdfdocument.lua | 24 +- frontend/document/tilecacheitem.lua | 12 + frontend/gettext.lua | 11 +- frontend/{math.lua => optmath.lua} | 16 +- frontend/ui/data/creoptions.lua | 38 +- frontend/ui/data/koptoptions.lua | 76 ++-- frontend/ui/data/strings.lua | 99 +++--- frontend/ui/device.lua | 85 +---- frontend/ui/device/basefrontlight.lua | 17 + frontend/ui/device/kindlefrontlight.lua | 38 ++ frontend/ui/device/kobofrontlight.lua | 28 ++ frontend/ui/event.lua | 4 +- frontend/ui/font.lua | 7 +- frontend/ui/geometry.lua | 4 +- frontend/ui/gesturedetector.lua | 58 +--- frontend/ui/gesturerange.lua | 45 +++ frontend/ui/graphics.lua | 181 ---------- frontend/ui/{inputevent.lua => input.lua} | 63 ++-- frontend/ui/reader/configurable.lua | 49 +++ .../ui/reader/readeractivityindicator.lua | 8 +- frontend/ui/reader/readerbookmark.lua | 17 +- frontend/ui/reader/readerconfig.lua | 64 +--- ...{readercopt.lua => readercoptlistener.lua} | 5 +- frontend/ui/reader/readercropping.lua | 23 +- frontend/ui/reader/readerdictionary.lua | 16 +- frontend/ui/reader/readerdogear.lua | 9 +- .../{readerflip.lua => readerflipping.lua} | 8 +- frontend/ui/reader/readerfont.lua | 10 +- frontend/ui/reader/readerfooter.lua | 24 +- frontend/ui/reader/readerfrontlight.lua | 13 +- frontend/ui/reader/readergoto.lua | 13 +- frontend/ui/reader/readerhighlight.lua | 11 +- frontend/ui/reader/readerhinting.lua | 5 +- frontend/ui/reader/readerhyphenation.lua | 8 +- ...{readerkopt.lua => readerkoptlistener.lua} | 6 +- frontend/ui/reader/readermenu.lua | 17 +- frontend/ui/reader/readerpaging.lua | 30 +- frontend/ui/reader/readerpanning.lua | 8 +- frontend/ui/reader/readerrolling.lua | 12 +- frontend/ui/reader/readerrotation.lua | 11 +- frontend/ui/reader/readerscreenshot.lua | 9 +- frontend/ui/reader/readertoc.lua | 12 +- frontend/ui/reader/readertypeset.lua | 8 +- frontend/ui/reader/readerview.lua | 22 +- frontend/ui/reader/readerzooming.lua | 13 +- frontend/ui/readerui.lua | 57 +-- frontend/ui/rendertext.lua | 22 +- frontend/ui/screen.lua | 35 +- frontend/ui/{time.lua => timeval.lua} | 4 +- frontend/ui/uimanager.lua | 37 +- .../ui/widget/{bbox.lua => bboxwidget.lua} | 7 +- frontend/ui/widget/button.lua | 16 +- frontend/ui/widget/buttontable.lua | 21 +- .../widget/{config.lua => configdialog.lua} | 63 ++-- frontend/ui/widget/confirmbox.lua | 12 +- frontend/ui/widget/container.lua | 326 ------------------ .../ui/widget/container/bottomcontainer.lua | 20 ++ .../ui/widget/container/centercontainer.lua | 25 ++ .../ui/widget/container/framecontainer.lua | 61 ++++ .../ui/widget/container/inputcontainer.lua | 94 +++++ .../ui/widget/container/leftcontainer.lua | 17 + .../ui/widget/container/rightcontainer.lua | 19 + .../widget/container/underlinecontainer.lua | 42 +++ .../ui/widget/container/widgetcontainer.lua | 70 ++++ .../widget/{dict.lua => dictquicklookup.lua} | 33 +- frontend/ui/widget/eventlistener.lua | 24 ++ frontend/ui/widget/filechooser.lua | 9 +- frontend/ui/widget/fixedtextwidget.lua | 29 ++ frontend/ui/widget/focusmanager.lua | 7 +- frontend/ui/widget/group.lua | 172 --------- frontend/ui/widget/horizontalgroup.lua | 61 ++++ frontend/ui/widget/horizontalspan.lua | 14 + frontend/ui/widget/iconbutton.lua | 10 +- .../ui/widget/{image.lua => imagewidget.lua} | 8 +- frontend/ui/widget/infomessage.lua | 15 +- frontend/ui/widget/inputdialog.lua | 30 +- frontend/ui/widget/inputtext.lua | 16 +- .../ui/widget/{line.lua => linewidget.lua} | 6 +- frontend/ui/widget/menu.lua | 46 ++- frontend/ui/widget/notification.lua | 12 +- frontend/ui/widget/overlapgroup.lua | 51 +++ .../{progress.lua => progresswidget.lua} | 8 +- frontend/ui/widget/rectspan.lua | 15 + frontend/ui/widget/scrolltextwidget.lua | 80 +++++ frontend/ui/widget/span.lua | 27 -- .../ui/widget/{text.lua => textboxwidget.lua} | 164 +-------- frontend/ui/widget/textwidget.lua | 60 ++++ frontend/ui/widget/toggleswitch.lua | 24 +- frontend/ui/widget/touchmenu.lua | 49 ++- frontend/ui/widget/verticalgroup.lua | 64 ++++ .../{scrollbar.lua => verticalscrollbar.lua} | 6 +- frontend/ui/widget/verticalspan.lua | 14 + .../{keyboard.lua => virtualkeyboard.lua} | 29 +- frontend/ui/widget/{base.lua => widget.lua} | 36 +- reader.lua | 22 +- 107 files changed, 1997 insertions(+), 1664 deletions(-) rename frontend/apps/filemanager/{fm.lua => filemanager.lua} (69%) rename frontend/apps/filemanager/{fmhistory.lua => filemanagerhistory.lua} (83%) rename frontend/apps/filemanager/{fmmenu.lua => filemanagermenu.lua} (83%) create mode 100644 frontend/cacheitem.lua rename frontend/{settings.lua => docsettings.lua} (96%) create mode 100644 frontend/document/documentregistry.lua create mode 100644 frontend/document/tilecacheitem.lua rename frontend/{math.lua => optmath.lua} (81%) create mode 100644 frontend/ui/device/basefrontlight.lua create mode 100644 frontend/ui/device/kindlefrontlight.lua create mode 100644 frontend/ui/device/kobofrontlight.lua create mode 100644 frontend/ui/gesturerange.lua delete mode 100644 frontend/ui/graphics.lua rename frontend/ui/{inputevent.lua => input.lua} (95%) create mode 100644 frontend/ui/reader/configurable.lua rename frontend/ui/reader/{readercopt.lua => readercoptlistener.lua} (90%) rename frontend/ui/reader/{readerflip.lua => readerflipping.lua} (72%) rename frontend/ui/reader/{readerkopt.lua => readerkoptlistener.lua} (92%) rename frontend/ui/{time.lua => timeval.lua} (98%) rename frontend/ui/widget/{bbox.lua => bboxwidget.lua} (97%) rename frontend/ui/widget/{config.lua => configdialog.lua} (88%) delete mode 100644 frontend/ui/widget/container.lua create mode 100644 frontend/ui/widget/container/bottomcontainer.lua create mode 100644 frontend/ui/widget/container/centercontainer.lua create mode 100644 frontend/ui/widget/container/framecontainer.lua create mode 100644 frontend/ui/widget/container/inputcontainer.lua create mode 100644 frontend/ui/widget/container/leftcontainer.lua create mode 100644 frontend/ui/widget/container/rightcontainer.lua create mode 100644 frontend/ui/widget/container/underlinecontainer.lua create mode 100644 frontend/ui/widget/container/widgetcontainer.lua rename frontend/ui/widget/{dict.lua => dictquicklookup.lua} (84%) create mode 100644 frontend/ui/widget/eventlistener.lua create mode 100644 frontend/ui/widget/fixedtextwidget.lua delete mode 100644 frontend/ui/widget/group.lua create mode 100644 frontend/ui/widget/horizontalgroup.lua create mode 100644 frontend/ui/widget/horizontalspan.lua rename frontend/ui/widget/{image.lua => imagewidget.lua} (87%) rename frontend/ui/widget/{line.lua => linewidget.lua} (87%) create mode 100644 frontend/ui/widget/overlapgroup.lua rename frontend/ui/widget/{progress.lua => progresswidget.lua} (88%) create mode 100644 frontend/ui/widget/rectspan.lua create mode 100644 frontend/ui/widget/scrolltextwidget.lua delete mode 100644 frontend/ui/widget/span.lua rename frontend/ui/widget/{text.lua => textboxwidget.lua} (61%) create mode 100644 frontend/ui/widget/textwidget.lua create mode 100644 frontend/ui/widget/verticalgroup.lua rename frontend/ui/widget/{scrollbar.lua => verticalscrollbar.lua} (83%) create mode 100644 frontend/ui/widget/verticalspan.lua rename frontend/ui/widget/{keyboard.lua => virtualkeyboard.lua} (88%) rename frontend/ui/widget/{base.lua => widget.lua} (63%) diff --git a/frontend/apps/filemanager/fm.lua b/frontend/apps/filemanager/filemanager.lua similarity index 69% rename from frontend/apps/filemanager/fm.lua rename to frontend/apps/filemanager/filemanager.lua index f0fe1eded..0045640a8 100644 --- a/frontend/apps/filemanager/fm.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -1,9 +1,19 @@ -require "ui/widget/filechooser" -require "apps/filemanager/fmhistory" -require "apps/filemanager/fmmenu" +local InputContainer = require("ui/widget/container/inputcontainer") +local FrameContainer = require("ui/widget/container/framecontainer") +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") - -FileManager = InputContainer:extend{ +local FileManager = InputContainer:extend{ title = _("FileManager"), width = Screen:getWidth(), height = Screen:getHeight(), @@ -90,3 +100,5 @@ function FileManager:onClose() end return true end + +return FileManager diff --git a/frontend/apps/filemanager/fmhistory.lua b/frontend/apps/filemanager/filemanagerhistory.lua similarity index 83% rename from frontend/apps/filemanager/fmhistory.lua rename to frontend/apps/filemanager/filemanagerhistory.lua index 2b9dcb265..479b96ac2 100644 --- a/frontend/apps/filemanager/fmhistory.lua +++ b/frontend/apps/filemanager/filemanagerhistory.lua @@ -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"), } @@ -70,4 +76,4 @@ function FileManagerHistory:updateItemTable() end end - +return FileManagerHistory diff --git a/frontend/apps/filemanager/fmmenu.lua b/frontend/apps/filemanager/filemanagermenu.lua similarity index 83% rename from frontend/apps/filemanager/fmmenu.lua rename to frontend/apps/filemanager/filemanagermenu.lua index ce5c32514..5fc56a5dc 100644 --- a/frontend/apps/filemanager/fmmenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -1,7 +1,15 @@ -require "ui/widget/menu" -require "ui/widget/touchmenu" - -FileManagerMenu = InputContainer:extend{ +local CenterContainer = require("ui/widget/container/centercontainer") +local TouchMenu = require("ui/widget/touchmenu") +local ReaderFrontLight = require("ui/reader/readerfrontlight") +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, registered_widgets = {}, } @@ -132,3 +140,4 @@ function FileManagerMenu:registerToMainMenu(widget) table.insert(self.registered_widgets, widget) end +return FileManagerMenu diff --git a/frontend/cache.lua b/frontend/cache.lua index 92f9f42f0..80721c399 100644 --- a/frontend/cache.lua +++ b/frontend/cache.lua @@ -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 ]]-- -Cache = { +local Cache = { -- cache configuration: max_memsize = DGLOBAL_CACHE_SIZE, -- cache state: @@ -89,3 +70,5 @@ function Cache:clear() self.cache_order = {} self.current_memsize = 0 end + +return Cache diff --git a/frontend/cacheitem.lua b/frontend/cacheitem.lua new file mode 100644 index 000000000..21c60465f --- /dev/null +++ b/frontend/cacheitem.lua @@ -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 diff --git a/frontend/dbg.lua b/frontend/dbg.lua index d87b6f299..071b6e35f 100644 --- a/frontend/dbg.lua +++ b/frontend/dbg.lua @@ -1,10 +1,32 @@ -require "settings" -- for dump method +local DocSettings = require("docsettings") -- for dump method -Dbg = { +local Dbg = { is_on = false, 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() self.is_on = true @@ -20,22 +42,6 @@ function Dbg:logEv(ev) self.ev_log:flush() end -function DEBUG(...) - LvDEBUG(math.huge, ...) -end +setmetatable(Dbg, Dbg_mt) -function LvDEBUG(lv, ...) - 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 +return Dbg diff --git a/frontend/settings.lua b/frontend/docsettings.lua similarity index 96% rename from frontend/settings.lua rename to frontend/docsettings.lua index bf7de9240..01844b8ef 100644 --- a/frontend/settings.lua +++ b/frontend/docsettings.lua @@ -1,4 +1,5 @@ -DocSettings = {} +local DocSettings = {} +-- lfs function DocSettings:getHistoryPath(fullpath) local i = #fullpath - 1 @@ -67,9 +68,9 @@ function DocSettings:delSetting(key) self.data[key] = nil end -function dump(data, max_lv) +function DocSettings:dump(data, max_lv) local out = {} - DocSettings:_serialize(data, out, 0, max_lv) + self:_serialize(data, out, 0, max_lv) return table.concat(out) end @@ -129,3 +130,5 @@ end function DocSettings:close() self:flush() end + +return DocSettings diff --git a/frontend/document/credocument.lua b/frontend/document/credocument.lua index a2a33b8b8..6f0b2e002 100644 --- a/frontend/document/credocument.lua +++ b/frontend/document/credocument.lua @@ -1,8 +1,10 @@ -require "ui/geometry" -require "ui/reader/readerconfig" -require "ui/data/creoptions" +local Geom = require("ui/geometry") +local 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 SCROLL_VIEW_MODE = 0, PAGE_VIEW_MODE = 1, @@ -248,16 +250,20 @@ function CreDocument:setVisiblePageCount(new_count) self._document:setVisiblePageCount(new_count) end -DocumentRegistry:addProvider("txt", "application/txt", CreDocument) -DocumentRegistry:addProvider("epub", "application/epub", CreDocument) -DocumentRegistry:addProvider("html", "application/html", CreDocument) -DocumentRegistry:addProvider("htm", "application/htm", CreDocument) -DocumentRegistry:addProvider("zip", "application/zip", CreDocument) -DocumentRegistry:addProvider("rtf", "application/rtf", CreDocument) -DocumentRegistry:addProvider("mobi", "application/mobi", CreDocument) -DocumentRegistry:addProvider("prc", "application/prc", CreDocument) -DocumentRegistry:addProvider("azw", "application/azw", CreDocument) -DocumentRegistry:addProvider("chm", "application/chm", CreDocument) -DocumentRegistry:addProvider("pdb", "application/pdb", CreDocument) -DocumentRegistry:addProvider("doc", "application/doc", CreDocument) -DocumentRegistry:addProvider("tcr", "application/tcr", CreDocument) +function CreDocument:register(registry) + registry:addProvider("txt", "application/txt", self) + registry:addProvider("epub", "application/epub", self) + registry:addProvider("html", "application/html", self) + registry:addProvider("htm", "application/htm", self) + registry:addProvider("zip", "application/zip", self) + registry:addProvider("rtf", "application/rtf", self) + registry:addProvider("mobi", "application/mobi", self) + registry:addProvider("prc", "application/prc", self) + registry:addProvider("azw", "application/azw", self) + registry:addProvider("chm", "application/chm", self) + registry:addProvider("pdb", "application/pdb", self) + registry:addProvider("doc", "application/doc", self) + registry:addProvider("tcr", "application/tcr", self) +end + +return CreDocument diff --git a/frontend/document/djvudocument.lua b/frontend/document/djvudocument.lua index c8f71af8c..e8d141229 100644 --- a/frontend/document/djvudocument.lua +++ b/frontend/document/djvudocument.lua @@ -1,10 +1,13 @@ -require "cache" -require "ui/geometry" -require "ui/reader/readerconfig" -require "ui/data/koptoptions" -require "document/koptinterface" - -DjvuDocument = Document:new{ +local Geom = require("ui/geometry") +local Cache = require("cache") +local CacheItem = require("cacheitem") +local KoptOptions = require("ui/data/koptoptions") +local KoptInterface = require("document/koptinterface") +local Document = require("document/document") +local Configurable = require("ui/reader/configurable") +-- TBD: DrawContext + +local DjvuDocument = Document:new{ _document = false, -- libdjvulibre manages its own additional cache, default value is hard written in c module. djvulibre_cache_size = nil, @@ -14,6 +17,16 @@ DjvuDocument = Document:new{ 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() self.configurable:loadDefaults(self.options) if not validDjvuFile(self.file) then @@ -33,16 +46,6 @@ function DjvuDocument:init() self:_readMetadata() 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) local _, height = self.doc:getOriginalPageSize(pageno) 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) end -DocumentRegistry:addProvider("djvu", "application/djvu", DjvuDocument) +function DjvuDocument:register(registry) + registry:addProvider("djvu", "application/djvu", self) +end + +return DjvuDocument diff --git a/frontend/document/document.lua b/frontend/document/document.lua index eeadb287f..34662ffc0 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -1,46 +1,12 @@ -require "../math" - ---[[ -This is a registry for document providers -]]-- -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 +local Cache = require("cache") +local CacheItem = require("cacheitem") +local TileCacheItem = require("document/tilecacheitem") +local Geom = require("ui/geometry") --[[ This is an abstract interface to a document ]]-- -Document = { +local Document = { -- file name file = nil, @@ -304,8 +270,4 @@ function Document:getPageText(pageno) return text end --- load implementations: - -require "document/pdfdocument" -require "document/djvudocument" -require "document/credocument" +return Document diff --git a/frontend/document/documentregistry.lua b/frontend/document/documentregistry.lua new file mode 100644 index 000000000..2a5437cff --- /dev/null +++ b/frontend/document/documentregistry.lua @@ -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 diff --git a/frontend/document/koptinterface.lua b/frontend/document/koptinterface.lua index 0a8aeeced..f318b9c26 100644 --- a/frontend/document/koptinterface.lua +++ b/frontend/document/koptinterface.lua @@ -1,11 +1,10 @@ -require "dbg" -require "cache" -require "ui/geometry" -require "ui/device" -require "ui/screen" -require "ui/reader/readerconfig" - -KoptInterface = { +local Document = require("document/document") +local Cache = require("cache") +local CacheItem = require("cacheitem") +local Screen = require("ui/screen") +-- TBD: KOPTContext + +local KoptInterface = { ocrengine = "ocrengine", tessocr_data = "data", ocr_lang = "eng", @@ -15,7 +14,7 @@ KoptInterface = { screen_dpi = Screen:getDPI(), } -ContextCacheItem = CacheItem:new{} +local ContextCacheItem = CacheItem:new{} function ContextCacheItem:onFree() if self.kctx.free then @@ -24,7 +23,7 @@ function ContextCacheItem:onFree() end end -OCREngine = CacheItem:new{} +local OCREngine = CacheItem:new{} function OCREngine:onFree() if self.ocrengine.freeOCR then @@ -811,3 +810,5 @@ function KoptInterface:logMemoryUsage(pageno) log_file:close() end end + +return KoptInterface diff --git a/frontend/document/pdfdocument.lua b/frontend/document/pdfdocument.lua index 1a376c826..bd9977fee 100644 --- a/frontend/document/pdfdocument.lua +++ b/frontend/document/pdfdocument.lua @@ -1,10 +1,12 @@ -require "cache" -require "ui/geometry" -require "ui/reader/readerconfig" -require "ui/data/koptoptions" -require "document/koptinterface" - -PdfDocument = Document:new{ +local Cache = require("cache") +local CacheItem = require("cacheitem") +local KoptOptions = require("ui/data/koptoptions") +local KoptInterface = require("document/koptinterface") +local Document = require("document/document") +local Configurable = require("ui/reader/configurable") +-- TBD: DrawContext + +local PdfDocument = Document:new{ _document = false, -- muPDF manages its own additional cache 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) end -DocumentRegistry:addProvider("pdf", "application/pdf", PdfDocument) -DocumentRegistry:addProvider("cbz", "application/cbz", PdfDocument) +function PdfDocument:register(registry) + registry:addProvider("pdf", "application/pdf", self) + registry:addProvider("cbz", "application/cbz", self) +end + +return PdfDocument diff --git a/frontend/document/tilecacheitem.lua b/frontend/document/tilecacheitem.lua new file mode 100644 index 000000000..f76ea96b6 --- /dev/null +++ b/frontend/document/tilecacheitem.lua @@ -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 diff --git a/frontend/gettext.lua b/frontend/gettext.lua index 4e0533e68..dd2891078 100644 --- a/frontend/gettext.lua +++ b/frontend/gettext.lua @@ -1,11 +1,16 @@ - lua_gettext.init("./i18n", "koreader") +local GetText = {} +local GetText_mt = {} -function _(string) +function GetText_mt.__call(gettext, string) return lua_gettext.translate(string) end -function gettextChangeLang(new_lang) +function GetText.changeLang(new_lang) lua_gettext.change_lang(new_lang) end + +setmetatable(GetText, GetText_mt) + +return GetText diff --git a/frontend/math.lua b/frontend/optmath.lua similarity index 81% rename from frontend/math.lua rename to frontend/optmath.lua index 7ca80eb0c..b6a787565 100644 --- a/frontend/math.lua +++ b/frontend/optmath.lua @@ -2,7 +2,9 @@ Simple math helper function ]]-- -function math.roundAwayFromZero(num) +local Math = {} + +function Math.roundAwayFromZero(num) if num > 0 then return math.ceil(num) else @@ -10,11 +12,11 @@ function math.roundAwayFromZero(num) end end -function math.round(num) +function Math.round(num) return math.floor(num + 0.5) end -function math.oddEven(number) +function Math.oddEven(number) if number % 2 == 1 then return "odd" else @@ -22,7 +24,7 @@ function math.oddEven(number) end end -function tmin_max(tab, func, op) +local function tmin_max(tab, func, op) if #tab == 0 then return nil, nil end local index, value = 1, tab[1] for i = 2, #tab do @@ -47,7 +49,7 @@ end Return the minimum element of a table. 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") end @@ -55,6 +57,8 @@ end Return the maximum element of a table. 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") end + +return Math diff --git a/frontend/ui/data/creoptions.lua b/frontend/ui/data/creoptions.lua index a0faefe1b..86dda4483 100644 --- a/frontend/ui/data/creoptions.lua +++ b/frontend/ui/data/creoptions.lua @@ -1,5 +1,7 @@ -require "ui/screen" -require "ui/data/strings" +local Screen = require("ui/screen") +local S = require("ui/data/strings") + +local _ = require("gettext") -- add multiply operator to Aa dict local Aa = setmetatable({"Aa"}, { @@ -12,15 +14,15 @@ local Aa = setmetatable({"Aa"}, { end }) -CreOptions = { +local CreOptions = { prefix = 'copt', { icon = "resources/icons/appbar.transform.rotate.right.large.png", options = { { name = "screen_mode", - name_text = SCREEN_MODE_STR, - toggle = {PORTRAIT_STR, LANDSCAPE_STR}, + name_text = S.SCREEN_MODE, + toggle = {S.PORTRAIT, S.LANDSCAPE}, args = {"portrait", "landscape"}, default_arg = "portrait", current_func = function() return Screen:getScreenMode() end, @@ -33,16 +35,16 @@ CreOptions = { options = { { name = "line_spacing", - name_text = LINE_SPACING_STR, - item_text = {DECREASE_STR, INCREASE_STR}, + name_text = S.LINE_SPACING, + item_text = {S.DECREASE, S.INCREASE}, args = {"decrease", "increase"}, default_arg = nil, event = "ChangeLineSpace", }, { name = "page_margins", - name_text = PAGE_MARGIN_STR, - toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, + name_text = S.PAGE_MARGIN, + toggle = {S.SMALL, S.MEDIUM, S.LARGE}, values = { {6, 5, 2, 5}, {15, 10, 10, 10}, @@ -79,8 +81,8 @@ CreOptions = { options = { { name = "font_weight", - name_text = FONT_WEIGHT_STR, - item_text = {TOGGLE_BOLD_STR}, + name_text = S.FONT_WEIGHT, + item_text = {S.TOGGLE_BOLD}, -- args is indeed not used, we put here just to keep the -- UI happy. args = {1}, @@ -89,8 +91,8 @@ CreOptions = { }, { name = "font_gamma", - name_text = GAMMA_STR, - item_text = {DECREASE_STR, INCREASE_STR}, + name_text = S.GAMMA, + item_text = {S.DECREASE, S.INCREASE}, args = {"decrease", "increase"}, default_arg = nil, event = "ChangeFontGamma", @@ -102,8 +104,8 @@ CreOptions = { options = { { name = "view_mode", - name_text = VIEW_MODE_STR, - toggle = {VIEW_SCROLL_STR, VIEW_PAGE_STR}, + name_text = S.VIEW_MODE, + toggle = {S.VIEW_SCROLL, S.VIEW_PAGE}, values = {1, 0}, default_value = 0, args = {"scroll", "page"}, @@ -112,8 +114,8 @@ CreOptions = { }, { name = "embedded_css", - name_text = EMBEDDED_STYLE_STR, - toggle = {ON_STR, OFF_STR}, + name_text = S.EMBEDDED_STYLE, + toggle = {S.ON, S.OFF}, values = {1, 0}, default_value = 1, args = {true, false}, @@ -123,3 +125,5 @@ CreOptions = { }, }, } + +return CreOptions diff --git a/frontend/ui/data/koptoptions.lua b/frontend/ui/data/koptoptions.lua index dd4f0a775..725c4159b 100644 --- a/frontend/ui/data/koptoptions.lua +++ b/frontend/ui/data/koptoptions.lua @@ -1,15 +1,17 @@ -require "ui/screen" -require "ui/data/strings" +local Screen = require("ui/screen") +local S = require("ui/data/strings") -KoptOptions = { +local _ = require("gettext") + +local KoptOptions = { prefix = 'kopt', { icon = "resources/icons/appbar.transform.rotate.right.large.png", options = { { name = "screen_mode", - name_text = SCREEN_MODE_STR, - toggle = {PORTRAIT_STR, LANDSCAPE_STR}, + name_text = S.SCREEN_MODE, + toggle = {S.PORTRAIT, S.LANDSCAPE}, alternate = false, args = {"portrait", "landscape"}, default_arg = "portrait", @@ -23,9 +25,9 @@ KoptOptions = { options = { { name = "trim_page", - name_text = PAGE_CROP_STR, + name_text = S.PAGE_CROP, width = 225, - toggle = {MANUAL_STR, AUTO_STR, SEMIAUTO_STR}, + toggle = {S.MANUAL, S.AUTO, S.SEMIAUTO}, alternate = false, values = {0, 1, 2}, default_value = DKOPTREADER_CONFIG_TRIM_PAGE, @@ -39,8 +41,8 @@ KoptOptions = { options = { { name = "full_screen", - name_text = FULL_SCREEN_STR, - toggle = {ON_STR, OFF_STR}, + name_text = S.FULL_SCREEN, + toggle = {S.ON, S.OFF}, values = {1, 0}, default_value = DFULL_SCREEN, event = "SetFullScreen", @@ -48,8 +50,8 @@ KoptOptions = { }, { name = "page_scroll", - name_text = SCROLL_MODE_STR, - toggle = {ON_STR, OFF_STR}, + name_text = S.SCROLL_MODE, + toggle = {S.ON, S.OFF}, values = {1, 0}, default_value = DSCROLL_MODE, event = "ToggleScrollMode", @@ -57,22 +59,22 @@ KoptOptions = { }, { name = "page_margin", - name_text = PAGE_MARGIN_STR, - toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, + name_text = S.PAGE_MARGIN, + toggle = {S.SMALL, S.MEDIUM, S.LARGE}, values = {0.05, 0.10, 0.15}, default_value = DKOPTREADER_CONFIG_PAGE_MARGIN, event = "MarginUpdate", }, { name = "line_spacing", - name_text = LINE_SPACING_STR, - toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, + name_text = S.LINE_SPACING, + toggle = {S.SMALL, S.MEDIUM, S.LARGE}, values = {1.0, 1.2, 1.4}, default_value = DKOPTREADER_CONFIG_LINE_SPACING, }, { name = "max_columns", - name_text = COLUMNS_STR, + name_text = S.COLUMNS, item_icons = { "resources/icons/appbar.column.one.png", "resources/icons/appbar.column.two.png", @@ -83,7 +85,7 @@ KoptOptions = { }, { name = "justification", - name_text = TEXT_ALIGN_STR, + name_text = S.TEXT_ALIGN, item_icons = { "resources/icons/appbar.align.auto.png", "resources/icons/appbar.align.left.png", @@ -112,8 +114,8 @@ KoptOptions = { }, { name = "font_fine_tune", - name_text = FONTSIZE_FINE_TUNING_STR, - toggle = {DECREASE_STR, INCREASE_STR}, + name_text = S.FONTSIZE_FINE_TUNING, + toggle = {S.DECREASE, S.INCREASE}, values = {-0.05, 0.05}, default_value = 0.05, event = "FineTuningFontSize", @@ -128,9 +130,9 @@ KoptOptions = { options = { { name = "contrast", - name_text = CONTRAST_STR, + name_text = S.CONTRAST, 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_align_center = 0.8, values = {2.0, 1.5, 1.0, 0.5, 0.2}, @@ -146,7 +148,7 @@ KoptOptions = { { name = "text_wrap", name_text = _("Reflow"), - toggle = {ON_STR, OFF_STR}, + toggle = {S.ON, S.OFF}, values = {1, 0}, default_value = DKOPTREADER_CONFIG_TEXT_WRAP, events = { @@ -163,7 +165,7 @@ KoptOptions = { }, { name="doc_language", - name_text = DOC_LANG_STR, + name_text = S.DOC_LANG, toggle = DKOPTREADER_CONFIG_DOC_LANGS_TEXT, values = DKOPTREADER_CONFIG_DOC_LANGS_CODE, default_value = DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE, @@ -172,45 +174,45 @@ KoptOptions = { }, { name="screen_rotation", - name_text = VERTICAL_TEXT_STR, - toggle = {ON_STR, OFF_STR}, + name_text = S.VERTICAL_TEXT, + toggle = {S.ON, S.OFF}, values = {90, 0}, default_value = 0, }, { name = "word_spacing", - name_text = WORD_GAP_STR, - toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, + name_text = S.WORD_GAP, + toggle = {S.SMALL, S.MEDIUM, S.LARGE}, values = DKOPTREADER_CONFIG_WORD_SAPCINGS, default_value = DKOPTREADER_CONFIG_DEFAULT_WORD_SAPCING, }, { name = "defect_size", - name_text = DEFECT_SIZE_STR, - toggle = {SMALL_STR, MEDIUM_STR, LARGE_STR}, + name_text = S.DEFECT_SIZE, + toggle = {S.SMALL, S.MEDIUM, S.LARGE}, values = {1.0, 3.0, 5.0}, default_value = DKOPTREADER_CONFIG_DEFECT_SIZE, event = "DefectSizeUpdate", }, { name = "quality", - name_text = RENDER_QUALITY_STR, - toggle = {LOW_STR, DEFAULT_STR, HIGH_STR}, + name_text = S.RENDER_QUALITY, + toggle = {S.LOW, S.DEFAULT, S.HIGH}, values={0.5, 1.0, 1.5}, default_value = DKOPTREADER_CONFIG_RENDER_QUALITY, }, { name = "auto_straighten", - name_text = AUTO_STRAIGHTEN_STR, - toggle = {ZERO_DEG_STR, FIVE_DEG_STR, TEN_DEG_STR}, + name_text = S.AUTO_STRAIGHTEN, + toggle = {S.ZERO_DEG, S.FIVE_DEG, S.TEN_DEG}, values = {0, 5, 10}, - default_value = DKOPTREADER_CONFIG_AUTO_STRAIGHTEN, + default_value = S.DKOPTREADER_CONFIG_AUTOAIGHTEN, show = false, }, { name = "detect_indent", - name_text = INDENTATION_STR, - toggle = {ON_STR, OFF_STR}, + name_text = S.INDENTATION, + toggle = {S.ON, S.OFF}, values = {1, 0}, default_value = DKOPTREADER_CONFIG_DETECT_INDENT, show = false, @@ -218,3 +220,5 @@ KoptOptions = { } }, } + +return KoptOptions diff --git a/frontend/ui/data/strings.lua b/frontend/ui/data/strings.lua index 08e52b5cc..eec7dc2ed 100644 --- a/frontend/ui/data/strings.lua +++ b/frontend/ui/data/strings.lua @@ -1,49 +1,54 @@ +local _ = require("gettext") -SCREEN_MODE_STR = _("Screen Mode") -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") +local S = {} -ON_STR = _("on") -OFF_STR = _("off") -AUTO_STR = _("auto") -MANUAL_STR = _("manual") -SEMIAUTO_STR = _("semi-auto") -SMALL_STR = _("small") -MEDIUM_STR = _("medium") -LARGE_STR = _("large") -DECREASE_STR = _("decrease") -INCREASE_STR = _("increase") -LIGHTEST_STR = _("lightest") -LIGHTER_STR = _("lighter") -DEFAULT_STR = _("default") -DARKER_STR = _("darker") -DARKEST_STR = _("darkest") -LOW_STR = _("low") -HIGH_STR = _("high") -ZERO_DEG_STR = _("0 deg") -FIVE_DEG_STR = _("5 deg") -TEN_DEG_STR = _("10 deg") -PORTRAIT_STR = _("portrait") -LANDSCAPE_STR = _("landscape") -TOGGLE_BOLD_STR = _("toggle bold") -VIEW_SCROLL_STR = _("scroll") -VIEW_PAGE_STR = _("page") +S.SCREEN_MODE = _("Screen Mode") +S.PAGE_CROP = _("Page Crop") +S.FULL_SCREEN = _("Full Screen") +S.SCROLL_MODE = _("Scroll Mode") +S.PAGE_MARGIN = _("Page Margin") +S.LINE_SPACING = _("Line Spacing") +S.COLUMNS = _("Columns") +S.TEXT_ALIGN = _("Text Align") +S.FONTSIZE_FINE_TUNING = _("Fine Tuning") +S.CONTRAST = _("Contrast") +S.REFLOW = _("Reflow") +S.DOC_LANG = _("Document Language") +S.VERTICAL_TEXT = _("Vertical Text") +S.WORD_GAP = _("Word Gap") +S.DEFECT_SIZE = _("Defect Size") +S.RENDER_QUALITY = _("Render Quality") +S.AUTO_STRAIGHTEN = _("Auto Straighten") +S.INDENTATION = _("Indentation") +S.FONT_WEIGHT = _("Font weight") +S.GAMMA = _("Gamma") +S.VIEW_MODE = _("View mode") +S.EMBEDDED_STYLE = _("Embedded style") + +S.ON = _("on") +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 diff --git a/frontend/ui/device.lua b/frontend/ui/device.lua index ac4460d44..6a8f985ff 100644 --- a/frontend/ui/device.lua +++ b/frontend/ui/device.lua @@ -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, charging_mode = false, survive_screen_saver = false, @@ -8,25 +16,6 @@ Device = { 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() if self.model then return self.model end if util.isEmulated() then @@ -219,58 +208,4 @@ function Device:getFrontlight() return self.frontlight end -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 - -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 +return Device diff --git a/frontend/ui/device/basefrontlight.lua b/frontend/ui/device/basefrontlight.lua new file mode 100644 index 000000000..b6d889661 --- /dev/null +++ b/frontend/ui/device/basefrontlight.lua @@ -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 diff --git a/frontend/ui/device/kindlefrontlight.lua b/frontend/ui/device/kindlefrontlight.lua new file mode 100644 index 000000000..beee982e5 --- /dev/null +++ b/frontend/ui/device/kindlefrontlight.lua @@ -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 diff --git a/frontend/ui/device/kobofrontlight.lua b/frontend/ui/device/kobofrontlight.lua new file mode 100644 index 000000000..6877071b5 --- /dev/null +++ b/frontend/ui/device/kobofrontlight.lua @@ -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 diff --git a/frontend/ui/event.lua b/frontend/ui/event.lua index e72f6ca23..63c8806ad 100644 --- a/frontend/ui/event.lua +++ b/frontend/ui/event.lua @@ -7,7 +7,7 @@ In order to see how event propagation works and how to make widgets event-aware see the implementation in WidgetContainer below. ]] -Event = {} +local Event = {} function Event:new(name, ...) local o = { @@ -18,3 +18,5 @@ function Event:new(name, ...) self.__index = self return o end + +return Event diff --git a/frontend/ui/font.lua b/frontend/ui/font.lua index 6d4bd617d..5a074258f 100644 --- a/frontend/ui/font.lua +++ b/frontend/ui/font.lua @@ -1,6 +1,7 @@ require "dbg" -- for DEBUG() +local Screen = require("ui/screen") -Font = { +local Font = { fontmap = { -- default font for menu contents cfont = "freefont/FreeSerif.ttf", @@ -50,7 +51,7 @@ function Font:getFace(font, size) font = self.cfont end - local size = scaleByDPI(size) + local size = Screen:scaleByDPI(size) local face = self.faces[font..size] -- build face if not found @@ -98,3 +99,5 @@ function Font:update() self.faces = {} clearGlyphCache() end + +return Font diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index de81a6c3f..1a3609ffb 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -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 or define your own types using this as a metatable ]]-- -Geom = { +local Geom = { x = 0, y = 0, w = 0, @@ -305,3 +305,5 @@ function Geom:center() w = 0, h = 0, } end + +return Geom diff --git a/frontend/ui/gesturedetector.lua b/frontend/ui/gesturedetector.lua index 2ed90be7d..d28285415 100644 --- a/frontend/ui/gesturedetector.lua +++ b/frontend/ui/gesturedetector.lua @@ -1,46 +1,6 @@ -require "ui/geometry" - -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 +local Geom = require("ui/geometry") +local TimeVal = require("ui/timeval") +local Screen = require("ui/screen") --[[ Current detectable gestures: @@ -80,7 +40,9 @@ GestureDetector:feedEvent(tev) will return a detection result when you 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 DOUBLE_TAP_INTERVAL = 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 local deadline = cur_tap.timev + TimeVal:new{ 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) -- double tap will set last_tap to nil so if it is not, then -- user must only tapped once @@ -379,7 +341,7 @@ function GestureDetector:handleNonTap(tev) local deadline = tev.timev + TimeVal:new{ sec = 0, usec = self.HOLD_INTERVAL } - Input:setTimeout(function() + self.input:setTimeout(function() if self.states[slot] == self.tapState then -- timer set in tapState, so we switch to hold DEBUG("hold gesture detected in slot", slot) @@ -680,3 +642,5 @@ function GestureDetector:adjustGesCoordinate(ges) end return ges end + +return GestureDetector diff --git a/frontend/ui/gesturerange.lua b/frontend/ui/gesturerange.lua new file mode 100644 index 000000000..f299998b0 --- /dev/null +++ b/frontend/ui/gesturerange.lua @@ -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 diff --git a/frontend/ui/graphics.lua b/frontend/ui/graphics.lua deleted file mode 100644 index 5a5b0e417..000000000 --- a/frontend/ui/graphics.lua +++ /dev/null @@ -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 - diff --git a/frontend/ui/inputevent.lua b/frontend/ui/input.lua similarity index 95% rename from frontend/ui/inputevent.lua rename to frontend/ui/input.lua index ccba48612..52cc9a355 100644 --- a/frontend/ui/inputevent.lua +++ b/frontend/ui/input.lua @@ -1,41 +1,42 @@ -require "ui/event" -require "ui/device" -require "ui/time" -require "ui/gesturedetector" -require "ui/geometry" +local Device = require("ui/device") +local GestureDetector = require("ui/gesturedetector") +local Event = require("ui/event") +local TimeVal = require("ui/timeval") +local Screen = require("ui/screen") +local Dbg = require("dbg") -- constants from -EV_SYN = 0 -EV_KEY = 1 -EV_ABS = 3 +local EV_SYN = 0 +local EV_KEY = 1 +local EV_ABS = 3 -- key press event values (KEY.value) -EVENT_VALUE_KEY_PRESS = 1 -EVENT_VALUE_KEY_REPEAT = 2 -EVENT_VALUE_KEY_RELEASE = 0 +local EVENT_VALUE_KEY_PRESS = 1 +local EVENT_VALUE_KEY_REPEAT = 2 +local EVENT_VALUE_KEY_RELEASE = 0 -- Synchronization events (SYN.code). -SYN_REPORT = 0 -SYN_CONFIG = 1 -SYN_MT_REPORT = 2 +local SYN_REPORT = 0 +local SYN_CONFIG = 1 +local SYN_MT_REPORT = 2 -- For single-touch events (ABS.code). -ABS_X = 00 -ABS_Y = 01 -ABS_PRESSURE = 24 +local ABS_X = 00 +local ABS_Y = 01 +local ABS_PRESSURE = 24 -- For multi-touch events (ABS.code). -ABS_MT_SLOT = 47 -ABS_MT_POSITION_X = 53 -ABS_MT_POSITION_Y = 54 -ABS_MT_TRACKING_ID = 57 -ABS_MT_PRESSURE = 58 +local ABS_MT_SLOT = 47 +local ABS_MT_POSITION_X = 53 +local ABS_MT_POSITION_Y = 54 +local ABS_MT_TRACKING_ID = 57 +local ABS_MT_PRESSURE = 58 --[[ an interface for key presses ]] -Key = {} +local Key = {} function Key:new(key, modifiers) local o = { key = key, modifiers = modifiers } @@ -124,7 +125,7 @@ end --[[ an interface to get input events ]] -Input = { +local Input = { event_map = {}, modifiers = {}, rotation_map = { @@ -133,7 +134,6 @@ Input = { [2] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right" }, [3] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" } }, - rotation = 0, timer_callbacks = {}, disable_double_tap = DGESDETECT_DISABLE_DOUBLE_TAP, } @@ -255,9 +255,6 @@ function Input:initTouchState() end function Input:init() - -- Screen module must have been initilized by now. - self.rotation = Screen:getRotationMode() - if Device:hasKeyboard() then self:initKeyMap() end @@ -414,8 +411,8 @@ function Input:handleKeyBoardEv(ev) end -- take device rotation into account - if self.rotation_map[self.rotation][keycode] then - keycode = self.rotation_map[self.rotation][keycode] + if self.rotation_map[Screen:getRotationMode()][keycode] then + keycode = self.rotation_map[Screen:getRotationMode()][keycode] end if keycode == "IntoSS" or keycode == "OutOfSS" @@ -661,3 +658,9 @@ function Input:sequenceToString(sequence) end return table.concat(keystring) end + +-- initialize the GestureDectector +-- so it can modify our (Input) state +GestureDetector.input = Input + +return Input diff --git a/frontend/ui/reader/configurable.lua b/frontend/ui/reader/configurable.lua new file mode 100644 index 000000000..6fac977e7 --- /dev/null +++ b/frontend/ui/reader/configurable.lua @@ -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 diff --git a/frontend/ui/reader/readeractivityindicator.lua b/frontend/ui/reader/readeractivityindicator.lua index 7fbada16b..64a44c7b0 100644 --- a/frontend/ui/reader/readeractivityindicator.lua +++ b/frontend/ui/reader/readeractivityindicator.lua @@ -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() local dev_mod = Device:getModel() @@ -41,3 +43,5 @@ function ReaderActivityIndicator:onStopActivityIndicator() end return true end + +return ReaderActivityIndicator diff --git a/frontend/ui/reader/readerbookmark.lua b/frontend/ui/reader/readerbookmark.lua index af6d4753b..caffc97f5 100644 --- a/frontend/ui/reader/readerbookmark.lua +++ b/frontend/ui/reader/readerbookmark.lua @@ -1,6 +1,15 @@ -require "ui/widget/notification" - -ReaderBookmark = InputContainer:new{ +local InputContainer = require("ui/widget/container/inputcontainer") +local CenterContainer = require("ui/widget/container/centercontainer") +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"), bookmarks = nil, } @@ -170,3 +179,5 @@ function ReaderBookmark:toggleBookmark(pn_or_xp) end self:addBookmark(pn_or_xp) end + +return ReaderBookmark diff --git a/frontend/ui/reader/readerconfig.lua b/frontend/ui/reader/readerconfig.lua index ec243b140..693148882 100644 --- a/frontend/ui/reader/readerconfig.lua +++ b/frontend/ui/reader/readerconfig.lua @@ -1,54 +1,14 @@ -require "ui/widget/config" - -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 - -ReaderConfig = InputContainer:new{ +local ConfigDialog = require("ui/widget/configdialog") +local InputContainer = require("ui/widget/container/inputcontainer") +local Device = require("ui/device") +local GestureRange = require("ui/gesturerange") +local Geom = require("ui/geometry") +local Screen = require("ui/screen") +local Event = require("ui/event") +local UIManager = require("ui/uimanager") +local _ = require("gettext") + +local ReaderConfig = InputContainer:new{ last_panel_index = 1, } @@ -130,3 +90,5 @@ function ReaderConfig:onCloseDocument() self.configurable:saveSettings(self.ui.doc_settings, self.options.prefix.."_") self.ui.doc_settings:saveSetting("config_panel_index", self.last_panel_index) end + +return ReaderConfig diff --git a/frontend/ui/reader/readercopt.lua b/frontend/ui/reader/readercoptlistener.lua similarity index 90% rename from frontend/ui/reader/readercopt.lua rename to frontend/ui/reader/readercoptlistener.lua index 79b0e53b5..8b21b7b2c 100644 --- a/frontend/ui/reader/readercopt.lua +++ b/frontend/ui/reader/readercoptlistener.lua @@ -1,5 +1,6 @@ +local EventListener = require("ui/widget/eventlistener") -ReaderCoptListener = EventListener:new{} +local ReaderCoptListener = EventListener:new{} function ReaderCoptListener:onReadSettings(config) local embedded_css = config:readSetting("copt_embedded_css") @@ -37,3 +38,5 @@ function ReaderCoptListener:onReadSettings(config) end) end end + +return ReaderCoptListener diff --git a/frontend/ui/reader/readercropping.lua b/frontend/ui/reader/readercropping.lua index d4e3df997..368b7aa29 100644 --- a/frontend/ui/reader/readercropping.lua +++ b/frontend/ui/reader/readercropping.lua @@ -1,13 +1,22 @@ -require "ui/widget/group" -require "ui/widget/bbox" -require "ui/widget/button" +local InputContainer = require("ui/widget/container/inputcontainer") +local UIManager = require("ui/uimanager") +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", cancel_text = "Cancel", ok_callback = function() end, cancel_callback = function() end, - button_width = math.floor(scaleByDPI(70)), + button_width = math.floor(Screen:scaleByDPI(70)), } function PageCropDialog:init() @@ -49,7 +58,7 @@ function PageCropDialog:init() } end -ReaderCropping = InputContainer:new{} +local ReaderCropping = InputContainer:new{} function ReaderCropping:onPageCrop(mode) if mode == "auto" then return end @@ -147,3 +156,5 @@ end function ReaderCropping:onCloseDocument() self.ui.doc_settings:saveSetting("bbox", self.document.bbox) end + +return ReaderCropping diff --git a/frontend/ui/reader/readerdictionary.lua b/frontend/ui/reader/readerdictionary.lua index 17e3f7769..731e7ae64 100644 --- a/frontend/ui/reader/readerdictionary.lua +++ b/frontend/ui/reader/readerdictionary.lua @@ -1,11 +1,9 @@ -require "ui/device" -require "ui/widget/dict" +local EventListener = require("ui/widget/eventlistener") +local UIManager = require("ui/uimanager") +local DictQuickLookup = require("ui/widget/dictquicklookup") +local JSON = require("JSON") -ReaderDictionary = EventListener:new{} - -function ReaderDictionary:init() - JSON = require("JSON") -end +local ReaderDictionary = EventListener:new{} function ReaderDictionary:onLookupWord(word) self:stardictLookup(word) @@ -38,7 +36,7 @@ function ReaderDictionary:showDict(results) dialog = self.dialog, results = results, dictionary = self.default_dictionary, - width = Screen:getWidth() - scaleByDPI(120), + width = Screen:getWidth() - screen:scaleByDPI(120), height = Screen:getHeight()*0.43, }) end @@ -56,3 +54,5 @@ end function ReaderDictionary:onCloseDocument() self.ui.doc_settings:saveSetting("default_dictionary", self.default_dictionary) end + +return ReaderDictionary diff --git a/frontend/ui/reader/readerdogear.lua b/frontend/ui/reader/readerdogear.lua index 4ae3cf920..d9b2695e2 100644 --- a/frontend/ui/reader/readerdogear.lua +++ b/frontend/ui/reader/readerdogear.lua @@ -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() local widget = ImageWidget:new{ @@ -15,3 +18,5 @@ function ReaderDogear:onSetDogearVisibility(visible) self.view.dogear_visible = visible return true end + +return ReaderDogear diff --git a/frontend/ui/reader/readerflip.lua b/frontend/ui/reader/readerflipping.lua similarity index 72% rename from frontend/ui/reader/readerflip.lua rename to frontend/ui/reader/readerflipping.lua index 8b8591457..a60742caf 100644 --- a/frontend/ui/reader/readerflip.lua +++ b/frontend/ui/reader/readerflipping.lua @@ -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, } @@ -24,3 +28,5 @@ function ReaderFlipping:onSetFlippingMode(flipping_mode) end return true end + +return ReaderFlipping diff --git a/frontend/ui/reader/readerfont.lua b/frontend/ui/reader/readerfont.lua index a61aa4ce4..ae77c3db6 100644 --- a/frontend/ui/reader/readerfont.lua +++ b/frontend/ui/reader/readerfont.lua @@ -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_size = nil, line_space_percent = nil, @@ -231,3 +237,5 @@ function ReaderFont:addToMainMenu(tab_item_table) sub_item_table = self.face_table, }) end + +return ReaderFont diff --git a/frontend/ui/reader/readerfooter.lua b/frontend/ui/reader/readerfooter.lua index 019ccfbe0..286901965 100644 --- a/frontend/ui/reader/readerfooter.lua +++ b/frontend/ui/reader/readerfooter.lua @@ -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, pages = nil, progress_percentage = 0.0, @@ -24,16 +34,16 @@ function ReaderFooter:init() } local _, text_height = self.progress_text:getSize() 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}, 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}, self.progress_text, } - table.insert(horizontal_group, bar_containner) - table.insert(horizontal_group, text_containner) + table.insert(horizontal_group, bar_container) + table.insert(horizontal_group, text_container) self[1] = BottomContainer:new{ dimen = Screen:getSize(), FrameContainer:new{ @@ -63,3 +73,5 @@ function ReaderFooter:onPageUpdate(pageno) self.pages = self.view.document.info.number_of_pages self:updateFooter() end + +return ReaderFooter diff --git a/frontend/ui/reader/readerfrontlight.lua b/frontend/ui/reader/readerfrontlight.lua index 361b29b2f..f88c3319d 100644 --- a/frontend/ui/reader/readerfrontlight.lua +++ b/frontend/ui/reader/readerfrontlight.lua @@ -1,8 +1,11 @@ -require "ui/widget/container" -require "ui/widget/inputdialog" -require "ui/device" +local InputContainer = require("ui/widget/container/inputcontainer") +local Geom = require("ui/geometry") +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}, } @@ -111,3 +114,5 @@ function ReaderFrontLight:fldialIntensity() Device:getFrontlight():setIntensity(number) end end + +return ReaderFrontLight diff --git a/frontend/ui/reader/readergoto.lua b/frontend/ui/reader/readergoto.lua index e0a59dfd4..38e8070a6 100644 --- a/frontend/ui/reader/readergoto.lua +++ b/frontend/ui/reader/readergoto.lua @@ -1,8 +1,11 @@ -require "ui/widget/container" -require "ui/widget/inputdialog" +local InputContainer = require("ui/widget/container/inputcontainer") +local InputDialog = require("ui/widget/inputdialog") +local UIManager = require("ui/uimanager") +local Screen = require("ui/screen") +local Event = require("ui/event") +local _ = require("gettext") - -ReaderGoto = InputContainer:new{ +local ReaderGoto = InputContainer:new{ goto_menu_title = _("Go To"), goto_dialog_title = _("Go to Page or Location"), } @@ -77,3 +80,5 @@ function ReaderGoto:gotoLocation() -- TODO: implement go to location self:close() end + +return ReaderGoto diff --git a/frontend/ui/reader/readerhighlight.lua b/frontend/ui/reader/readerhighlight.lua index 3fcf5605b..c7e043a1e 100644 --- a/frontend/ui/reader/readerhighlight.lua +++ b/frontend/ui/reader/readerhighlight.lua @@ -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() if Device:hasKeyboard() then @@ -353,3 +358,5 @@ end function ReaderHighlight:editHighlight() DEBUG("edit highlight") end + +return ReaderHighlight diff --git a/frontend/ui/reader/readerhinting.lua b/frontend/ui/reader/readerhinting.lua index cc16c0c6e..2e68a82c9 100644 --- a/frontend/ui/reader/readerhinting.lua +++ b/frontend/ui/reader/readerhinting.lua @@ -1,5 +1,6 @@ +local EventListener = require("ui/widget/eventlistener") -ReaderHinting = EventListener:new{ +local ReaderHinting = EventListener:new{ hinting_states = {} } @@ -32,3 +33,5 @@ function ReaderHinting:onRestoreHinting() self.view.hinting = table.remove(self.hinting_states) return true end + +return ReaderHinting diff --git a/frontend/ui/reader/readerhyphenation.lua b/frontend/ui/reader/readerhyphenation.lua index d837a98f6..08c57c14d 100644 --- a/frontend/ui/reader/readerhyphenation.lua +++ b/frontend/ui/reader/readerhyphenation.lua @@ -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_table = nil, cur_hyph_idx = nil, @@ -36,3 +40,5 @@ function ReaderHyphenation:addToMainMenu(tab_item_table) sub_item_table = self.hyph_table, }) end + +return ReaderHyphenation diff --git a/frontend/ui/reader/readerkopt.lua b/frontend/ui/reader/readerkoptlistener.lua similarity index 92% rename from frontend/ui/reader/readerkopt.lua rename to frontend/ui/reader/readerkoptlistener.lua index f52e92d4f..fd0af15b7 100644 --- a/frontend/ui/reader/readerkopt.lua +++ b/frontend/ui/reader/readerkoptlistener.lua @@ -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) 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] end end + +return ReaderKoptListener diff --git a/frontend/ui/reader/readermenu.lua b/frontend/ui/reader/readermenu.lua index 157c17f3e..5a32c5ba7 100644 --- a/frontend/ui/reader/readermenu.lua +++ b/frontend/ui/reader/readermenu.lua @@ -1,7 +1,15 @@ -require "ui/widget/menu" -require "ui/widget/touchmenu" - -ReaderMenu = InputContainer:new{ +local InputContainer = require("ui/widget/container/inputcontainer") +local CenterContainer = require("ui/widget/container/centercontainer") +local TouchMenu = require("ui/widget/touchmenu") +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, registered_widgets = {}, } @@ -133,3 +141,4 @@ function ReaderMenu:registerToMainMenu(widget) table.insert(self.registered_widgets, widget) end +return ReaderMenu diff --git a/frontend/ui/reader/readerpaging.lua b/frontend/ui/reader/readerpaging.lua index 0df23431c..7016d4eb3 100644 --- a/frontend/ui/reader/readerpaging.lua +++ b/frontend/ui/reader/readerpaging.lua @@ -1,12 +1,20 @@ -require "math" - -ReaderPaging = InputContainer:new{ +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 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, number_of_pages = 0, visible_area = nil, page_area = nil, show_overlap_enable = DSHOWOVERLAP, - overlap = scaleByDPI(20), + overlap = Screen:scaleByDPI(20), 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 -- we dont take overlap into account here yet, otherwise new_va will -- always intersect with page_area - x_pan_off = math.roundAwayFromZero(x_pan_off) - y_pan_off = math.roundAwayFromZero(y_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) + x_pan_off = Math.roundAwayFromZero(x_pan_off) + y_pan_off = Math.roundAwayFromZero(y_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) if new_va:notIntersectWith(self.page_area) then -- 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 end -- we have to calculate again to count into overlap - 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.x = Math.roundAwayFromZero(self.visible_area.x+x_pan_off) + new_va.y = Math.roundAwayFromZero(self.visible_area.y+y_pan_off) end -- fit new view area into page area new_va:offsetWithin(self.page_area, 0, 0) @@ -676,3 +684,5 @@ function ReaderPaging:onGotoPage(number) self:gotoPage(number) return true end + +return ReaderPaging diff --git a/frontend/ui/reader/readerpanning.lua b/frontend/ui/reader/readerpanning.lua index 650c8bf91..c4d56583b 100644 --- a/frontend/ui/reader/readerpanning.lua +++ b/frontend/ui/reader/readerpanning.lua @@ -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 panning_steps = { normal = 50, @@ -42,3 +46,5 @@ function ReaderPanning:onPanning(args, key) dy * self.panning_steps.normal * self.dimen.h / 100) return true end + +return ReaderPanning diff --git a/frontend/ui/reader/readerrolling.lua b/frontend/ui/reader/readerrolling.lua index 34eebc387..7bc2fd6eb 100644 --- a/frontend/ui/reader/readerrolling.lua +++ b/frontend/ui/reader/readerrolling.lua @@ -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_page = nil, current_pos = 0, @@ -325,4 +331,4 @@ function ReaderRolling:gotoPercent(new_percent) self:gotoPos(new_percent * self.doc_height / 10000) end - +return ReaderRolling diff --git a/frontend/ui/reader/readerrotation.lua b/frontend/ui/reader/readerrotation.lua index 8f700b99a..8876505cb 100644 --- a/frontend/ui/reader/readerrotation.lua +++ b/frontend/ui/reader/readerrotation.lua @@ -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, current_rotation = 0 } @@ -66,3 +73,5 @@ function ReaderRotation:onTwoFingerPanRelease(arg, ges) self.rotate_angle = nil end end + +return ReaderRotation diff --git a/frontend/ui/reader/readerscreenshot.lua b/frontend/ui/reader/readerscreenshot.lua index 3605bd255..a01b4fc6a 100644 --- a/frontend/ui/reader/readerscreenshot.lua +++ b/frontend/ui/reader/readerscreenshot.lua @@ -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() local diagonal = math.sqrt( @@ -10,7 +14,7 @@ function ReaderScreenshot:init() Screenshot = { GestureRange:new{ ges = "two_finger_tap", - scale = {diagonal - scaleByDPI(100), diagonal}, + scale = {diagonal - Screen:scaleByDPI(100), diagonal}, rate = 1.0, } }, @@ -23,3 +27,4 @@ function ReaderScreenshot:onScreenshot() return true end +return ReaderScreenshot diff --git a/frontend/ui/reader/readertoc.lua b/frontend/ui/reader/readertoc.lua index b1be85dbf..8f043f1e6 100644 --- a/frontend/ui/reader/readertoc.lua +++ b/frontend/ui/reader/readertoc.lua @@ -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_menu_title = _("Table of contents"), } @@ -113,3 +121,5 @@ function ReaderToc:addToMainMenu(tab_item_table) end, }) end + +return ReaderToc diff --git a/frontend/ui/reader/readertypeset.lua b/frontend/ui/reader/readertypeset.lua index 867045423..cfd1c698a 100644 --- a/frontend/ui/reader/readertypeset.lua +++ b/frontend/ui/reader/readertypeset.lua @@ -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 = nil, internal_css = true, @@ -106,4 +110,4 @@ function ReaderTypeset:addToMainMenu(tab_item_table) }) end - +return ReaderTypeset diff --git a/frontend/ui/reader/readerview.lua b/frontend/ui/reader/readerview.lua index e7564f353..5e0b9a48e 100644 --- a/frontend/ui/reader/readerview.lua +++ b/frontend/ui/reader/readerview.lua @@ -1,9 +1,13 @@ -require "ui/widget/group" -require "ui/reader/readerflip" -require "ui/reader/readerfooter" -require "ui/reader/readerdogear" - -ReaderView = OverlapGroup:new{ +local OverlapGroup = require("ui/widget/overlapgroup") +local Screen = require("ui/screen") +local ReaderFlipping = require("ui/reader/readerflipping") +local ReaderFooter = require("ui/reader/readerfooter") +local ReaderDogear = require("ui/reader/readerdogear") +local Geom = require("ui/geometry") +local Event = require("ui/event") +local UIManager = require("ui/uimanager") + +local ReaderView = OverlapGroup:new{ document = nil, -- single page state @@ -32,8 +36,8 @@ ReaderView = OverlapGroup:new{ page_states = {}, scroll_mode = "vertical", page_gap = { - width = scaleByDPI(8), - height = scaleByDPI(8), + width = Screen:scaleByDPI(8), + height = Screen:scaleByDPI(8), color = 8, }, -- 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("highlight", self.highlight.saved) end + +return ReaderView diff --git a/frontend/ui/reader/readerzooming.lua b/frontend/ui/reader/readerzooming.lua index 2b57d02d3..9f776ba74 100644 --- a/frontend/ui/reader/readerzooming.lua +++ b/frontend/ui/reader/readerzooming.lua @@ -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, -- default to nil so we can trigger ZoomModeUpdate events on start up zoom_mode = nil, @@ -262,3 +271,5 @@ function ReaderZooming:addToMainMenu(tab_item_table) }) end end + +return ReaderZooming diff --git a/frontend/ui/readerui.lua b/frontend/ui/readerui.lua index 699470024..770c592c9 100644 --- a/frontend/ui/readerui.lua +++ b/frontend/ui/readerui.lua @@ -1,26 +1,34 @@ -require "ui/reader/readerview" -require "ui/reader/readerzooming" -require "ui/reader/readerpanning" -require "ui/reader/readerrotation" -require "ui/reader/readerpaging" -require "ui/reader/readerrolling" -require "ui/reader/readertoc" -require "ui/reader/readerbookmark" -require "ui/reader/readerfont" -require "ui/reader/readertypeset" -require "ui/reader/readermenu" -require "ui/reader/readergoto" -require "ui/reader/readerconfig" -require "ui/reader/readercropping" -require "ui/reader/readerkopt" -require "ui/reader/readercopt" -require "ui/reader/readerhinting" -require "ui/reader/readerhighlight" -require "ui/reader/readerscreenshot" -require "ui/reader/readerfrontlight" -require "ui/reader/readerdictionary" -require "ui/reader/readerhyphenation" -require "ui/reader/readeractivityindicator" +local InputContainer = require("ui/widget/container/inputcontainer") +local Geom = require("ui/geometry") +local Device = require("ui/device") +local DocSettings = require("docsettings") +local Event = require("ui/event") +local UIManager = require("ui/uimanager") +local _ = require("gettext") + +local ReaderView = require("ui/reader/readerview") +local ReaderZooming = require("ui/reader/readerzooming") +local ReaderPanning = require("ui/reader/readerpanning") +local ReaderRotation = require("ui/reader/readerrotation") +local ReaderPaging = require("ui/reader/readerpaging") +local ReaderRolling = require("ui/reader/readerrolling") +local ReaderToc = require("ui/reader/readertoc") +local ReaderBookmark = require("ui/reader/readerbookmark") +local ReaderFont = require("ui/reader/readerfont") +local ReaderTypeset = require("ui/reader/readertypeset") +local ReaderMenu = require("ui/reader/readermenu") +local ReaderGoto = require("ui/reader/readergoto") +local ReaderConfig = require("ui/reader/readerconfig") +local ReaderCropping = require("ui/reader/readercropping") +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 @@ -28,7 +36,7 @@ This is an abstraction for a reader interface it works using data gathered from a document interface ]]-- -ReaderUI = InputContainer:new{ +local ReaderUI = InputContainer:new{ key_events = { Close = { { "Home" }, doc = _("close document"), event = "Close" }, @@ -278,3 +286,4 @@ function ReaderUI:onClose() return true end +return ReaderUI diff --git a/frontend/ui/rendertext.lua b/frontend/ui/rendertext.lua index 8be7b6a95..ea46fffc1 100644 --- a/frontend/ui/rendertext.lua +++ b/frontend/ui/rendertext.lua @@ -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 ]]-- +local RenderText = {} -GlyphCache = Cache:new{ +local GlyphCache = Cache:new{ max_memsize = 512*1024, current_memsize = 0, cache = {}, @@ -56,7 +58,7 @@ local function utf8Chars(input) return read_next_glyph, input, 1 end -function getGlyph(face, charcode, bgcolor, fgcolor) +function RenderText:getGlyph(face, charcode, bgcolor, fgcolor) if bgcolor == nil then bgcolor = 0.0 end if fgcolor == nil then fgcolor = 1.0 end local hash = "glyph|"..face.hash.."|"..charcode.."|"..bgcolor.."|"..fgcolor @@ -87,13 +89,13 @@ function getGlyph(face, charcode, bgcolor, fgcolor) return rendered_glyph end -function getSubTextByWidth(text, face, width, kerning) +function RenderText:getSubTextByWidth(text, face, width, kerning) local pen_x = 0 local prevcharcode = 0 local char_list = {} for _, charcode, uchar in utf8Chars(text) do if pen_x < width then - local glyph = getGlyph(face, charcode) + local glyph = self:getGlyph(face, charcode) if kerning and prevcharcode then local kern = face.ftface:getKerning(prevcharcode, charcode) pen_x = pen_x + kern @@ -110,7 +112,7 @@ function getSubTextByWidth(text, face, width, kerning) return table.concat(char_list) end -function sizeUtf8Text(x, width, face, text, kerning) +function RenderText:sizeUtf8Text(x, width, face, text, kerning) if not text then DEBUG("sizeUtf8Text called without text"); return @@ -124,7 +126,7 @@ function sizeUtf8Text(x, width, face, text, kerning) local prevcharcode = 0 for _, charcode, uchar in utf8Chars(text) do if pen_x < (width - x) then - local glyph = getGlyph(face, charcode) + local glyph = self:getGlyph(face, charcode) if kerning and (prevcharcode ~= 0) then pen_x = pen_x + (face.ftface):getKerning(prevcharcode, charcode) 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} 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 DEBUG("renderUtf8Text called without text"); return 0 @@ -151,7 +153,7 @@ function renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor) local buffer_width = buffer:getWidth() for _, charcode, uchar in utf8Chars(text) do 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 pen_x = pen_x + face.ftface:getKerning(prevcharcode, charcode) end @@ -167,3 +169,5 @@ function renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor) return pen_x end + +return RenderText diff --git a/frontend/ui/screen.lua b/frontend/ui/screen.lua index d0e867b9d..cbb24c5ce 100644 --- a/frontend/ui/screen.lua +++ b/frontend/ui/screen.lua @@ -1,19 +1,8 @@ ---[[ - Copyright (C) 2011 Hans-Werner Hilse - - 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. +local Device = require("ui/device") +local Geom = require("ui/geometry") - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - 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 . -]]-- +-- Blitbuffer +-- einkfb --[[ Codes for rotation modes: @@ -39,7 +28,7 @@ Codes for rotation modes: --]] -Screen = { +local Screen = { width = 0, height = 0, native_rotation_mode = nil, @@ -138,16 +127,6 @@ function Screen:rescaleByDPI(px) return math.ceil(px * 167/self:getDPI()) 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() return self.fb:getPitch() end @@ -181,8 +160,6 @@ function Screen:setRotationMode(mode) self.cur_rotation_mode = mode self.bb:free() self.bb = Blitbuffer.new(self.width, self.height, self.width/2) - -- update mode for input module - Input.rotation = mode end function Screen:setScreenMode(mode) @@ -229,3 +206,5 @@ function Screen:restoreFromBB(bb) DEBUG("Got nil bb in restoreFromSavedBB!") end end + +return Screen diff --git a/frontend/ui/time.lua b/frontend/ui/timeval.lua similarity index 98% rename from frontend/ui/time.lua rename to frontend/ui/timeval.lua index c4548bf6e..baa489d94 100644 --- a/frontend/ui/time.lua +++ b/frontend/ui/timeval.lua @@ -1,4 +1,4 @@ -TimeVal = { +local TimeVal = { sec = 0, usec = 0, } @@ -100,3 +100,5 @@ function TimeVal:now() local sec, usec = util.gettime() return TimeVal:new{sec = sec, usec = usec} end + +return TimeVal diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index ad5298037..d7d2a1abe 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -1,28 +1,25 @@ -require "ui/geometry" -require "ui/device" -require "ui/inputevent" -require "ui/widget/container" -require "ui/screen" -require "debug" -require "gettext" +local Device = require("ui/device") +local Screen = require("ui/screen") +local Input = require("ui/input") +local Event = require("ui/event") -- initialize output module, this must be initialized before Input Screen:init() -- initialize the input handling Input:init() -WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears) -WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black -WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing) -WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility -WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity -WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity -WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition -WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition -WAVEFORM_MODE_AUTO = 0x101 +local WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears) +local WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black +local WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing) +local WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility +local WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity +local WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity +local WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition +local WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition +local WAVEFORM_MODE_AUTO = 0x101 -- there is only one instance of this -UIManager = { +local UIManager = { -- change this to set refresh type for next refresh -- defaults to 1 initially and will be set to 1 after each refresh default_refresh_type = 1, @@ -296,12 +293,12 @@ function UIManager:run() Device:getFrontlight():toggle() elseif (input_event == "Power" and not Device.screen_saver_mode) or input_event == "Suspend" then - UIManager:show(InfoMessage:new{ + self:show(InfoMessage:new{ text = _("Standby"), timeout = 1, }) 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 input_event == "Resume" then Device:Resume() @@ -311,3 +308,5 @@ function UIManager:run() end end end + +return UIManager diff --git a/frontend/ui/widget/bbox.lua b/frontend/ui/widget/bboxwidget.lua similarity index 97% rename from frontend/ui/widget/bbox.lua rename to frontend/ui/widget/bboxwidget.lua index 98a4e009e..d164fd80c 100644 --- a/frontend/ui/widget/bbox.lua +++ b/frontend/ui/widget/bboxwidget.lua @@ -1,10 +1,9 @@ -require "math" -require "ui/widget/container" +local InputContainer = require("ui/widget/container/inputcontainer") --[[ BBoxWidget shows a bbox for page cropping ]] -BBoxWidget = InputContainer:new{ +local BBoxWidget = InputContainer:new{ page_bbox = nil, screen_bbox = nil, linesize = 2, @@ -212,3 +211,5 @@ function BBoxWidget:onConfirmAdjust(arg, ges) end return true end + +return BBoxWidget diff --git a/frontend/ui/widget/button.lua b/frontend/ui/widget/button.lua index 0b03a3632..3cfb2bfa7 100644 --- a/frontend/ui/widget/button.lua +++ b/frontend/ui/widget/button.lua @@ -1,10 +1,18 @@ -require "ui/widget/image" -require "ui/widget/container" +local InputContainer = require("ui/widget/container/inputcontainer") +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 --]] -Button = InputContainer:new{ +local Button = InputContainer:new{ text = nil, -- mandatory icon = nil, preselect = false, @@ -134,3 +142,5 @@ function Button:onTapSelect() end return true end + +return Button diff --git a/frontend/ui/widget/buttontable.lua b/frontend/ui/widget/buttontable.lua index aa32e4f95..3cec732c8 100644 --- a/frontend/ui/widget/buttontable.lua +++ b/frontend/ui/widget/buttontable.lua @@ -1,7 +1,12 @@ -require "ui/widget/base" -require "ui/widget/line" +local VerticalGroup = require("ui/widget/verticalgroup") +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(), buttons = { { @@ -9,8 +14,8 @@ ButtonTable = VerticalGroup:new{ {text="Cancel", enabled=false, callback=nil}, }, }, - sep_width = scaleByDPI(1), - padding = scaleByDPI(2), + sep_width = Screen:scaleByDPI(1), + padding = Screen:scaleByDPI(2), zero_sep = false, button_font_face = "cfont", @@ -59,7 +64,7 @@ function ButtonTable:init() end 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{ background = 8, dimen = Geom:new{ @@ -67,5 +72,7 @@ function ButtonTable:addHorizontalSep() h = self.sep_width, } }) - table.insert(self, VerticalSpan:new{ width = scaleByDPI(2) }) + table.insert(self, VerticalSpan:new{ width = Screen:scaleByDPI(2) }) end + +return ButtonTable diff --git a/frontend/ui/widget/config.lua b/frontend/ui/widget/configdialog.lua similarity index 88% rename from frontend/ui/widget/config.lua rename to frontend/ui/widget/configdialog.lua index c1c543201..824ec7a29 100644 --- a/frontend/ui/widget/config.lua +++ b/frontend/ui/widget/configdialog.lua @@ -1,7 +1,28 @@ -require "ui/widget/container" -require "ui/widget/toggleswitch" - -MenuBarItem = InputContainer:new{} +local InputContainer = require("ui/widget/container/inputcontainer") +local CenterContainer = require("ui/widget/container/centercontainer") +local RightContainer = require("ui/widget/container/rightcontainer") +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() self.dimen = self[1]:getSize() -- we need this table per-instance, so we declare it here @@ -40,7 +61,7 @@ function MenuBarItem:invert(invert) UIManager:setDirty(self.config, "full") end -OptionTextItem = InputContainer:new{} +local OptionTextItem = InputContainer:new{} function OptionTextItem:init() local text_widget = self[1] @@ -96,7 +117,7 @@ function OptionTextItem:onTapSelect() return true end -OptionIconItem = InputContainer:new{} +local OptionIconItem = InputContainer:new{} function OptionIconItem:init() self.dimen = self.icon:getSize() self[1] = UnderlineContainer:new{ @@ -138,19 +159,7 @@ function OptionIconItem:onTapSelect() return true end ---[[ -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{} +local ConfigOption = CenterContainer:new{} function ConfigOption:init() local default_name_font_size = 20 local default_item_font_size = 16 @@ -159,7 +168,7 @@ function ConfigOption:init() local default_option_padding = 15 local vertical_group = VerticalGroup:new{} table.insert(vertical_group, VerticalSpan:new{ - width = scaleByDPI(default_option_padding), + width = Screen:scaleByDPI(default_option_padding), }) for c = 1, #self.options do 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 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 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{ - 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{} if self.options[c].name_text then @@ -325,7 +334,7 @@ function ConfigOption:init() if self.options[c].toggle then 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, toggle = self.options[c].toggle, alternate = self.options[c].alternate, @@ -350,7 +359,7 @@ function ConfigOption:init() self.dimen = vertical_group:getSize() end -ConfigPanel = FrameContainer:new{ background = 0, bordersize = 0, } +local ConfigPanel = FrameContainer:new{ background = 0, bordersize = 0, } function ConfigPanel:init() local config_options = self.config_dialog.config_options local default_option = config_options.default_options and config_options.default_options @@ -363,7 +372,7 @@ function ConfigPanel:init() table.insert(self, panel) end -MenuBar = FrameContainer:new{ background = 0, } +local MenuBar = FrameContainer:new{ background = 0, } function MenuBar:init() local config_options = self.config_dialog.config_options 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, panel_index = 1, } @@ -521,3 +530,5 @@ function ConfigDialog:onTapCloseMenu(arg, ges_ev) return true end end + +return ConfigDialog diff --git a/frontend/ui/widget/confirmbox.lua b/frontend/ui/widget/confirmbox.lua index 180f44d70..127e6b353 100644 --- a/frontend/ui/widget/confirmbox.lua +++ b/frontend/ui/widget/confirmbox.lua @@ -1,11 +1,14 @@ -require "ui/widget/container" -require "ui/widget/focusmanager" -require "ui/widget/button" +local CenterContainer = require("ui/widget/container/centercontainer") +local FrameContainer = require("ui/widget/container/centercontainer") +local FocusManager = require("ui/widget/focusmanager") +local Button = require("ui/widget/button") + +-- screen --[[ Widget that shows a message and OK/Cancel buttons ]] -ConfirmBox = FocusManager:new{ +local ConfirmBox = FocusManager:new{ text = _("no text"), width = nil, ok_text = _("OK"), @@ -88,3 +91,4 @@ function ConfirmBox:onSelect() return true end +return ConfirmBox diff --git a/frontend/ui/widget/container.lua b/frontend/ui/widget/container.lua deleted file mode 100644 index c5cdb448a..000000000 --- a/frontend/ui/widget/container.lua +++ /dev/null @@ -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 - - diff --git a/frontend/ui/widget/container/bottomcontainer.lua b/frontend/ui/widget/container/bottomcontainer.lua new file mode 100644 index 000000000..e9cfe97c8 --- /dev/null +++ b/frontend/ui/widget/container/bottomcontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/centercontainer.lua b/frontend/ui/widget/container/centercontainer.lua new file mode 100644 index 000000000..c3f1dfea2 --- /dev/null +++ b/frontend/ui/widget/container/centercontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/framecontainer.lua b/frontend/ui/widget/container/framecontainer.lua new file mode 100644 index 000000000..b32bb3f6c --- /dev/null +++ b/frontend/ui/widget/container/framecontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/inputcontainer.lua b/frontend/ui/widget/container/inputcontainer.lua new file mode 100644 index 000000000..2d5583abf --- /dev/null +++ b/frontend/ui/widget/container/inputcontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/leftcontainer.lua b/frontend/ui/widget/container/leftcontainer.lua new file mode 100644 index 000000000..608004228 --- /dev/null +++ b/frontend/ui/widget/container/leftcontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/rightcontainer.lua b/frontend/ui/widget/container/rightcontainer.lua new file mode 100644 index 000000000..eabcd9a55 --- /dev/null +++ b/frontend/ui/widget/container/rightcontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/underlinecontainer.lua b/frontend/ui/widget/container/underlinecontainer.lua new file mode 100644 index 000000000..6faf6d1a2 --- /dev/null +++ b/frontend/ui/widget/container/underlinecontainer.lua @@ -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 diff --git a/frontend/ui/widget/container/widgetcontainer.lua b/frontend/ui/widget/container/widgetcontainer.lua new file mode 100644 index 000000000..6cc7ebea5 --- /dev/null +++ b/frontend/ui/widget/container/widgetcontainer.lua @@ -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 diff --git a/frontend/ui/widget/dict.lua b/frontend/ui/widget/dictquicklookup.lua similarity index 84% rename from frontend/ui/widget/dict.lua rename to frontend/ui/widget/dictquicklookup.lua index 82d1d7490..6fc2a1e58 100644 --- a/frontend/ui/widget/dict.lua +++ b/frontend/ui/widget/dictquicklookup.lua @@ -1,10 +1,19 @@ -require "ui/widget/container" -require "ui/widget/buttontable" +local InputContainer = require("ui/widget/container/inputcontainer") +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 ]] -DictQuickLookup = InputContainer:new{ +local DictQuickLookup = InputContainer:new{ results = nil, lookupword = nil, dictionary = nil, @@ -16,13 +25,13 @@ DictQuickLookup = InputContainer:new{ width = nil, height = nil, - title_padding = scaleByDPI(5), - title_margin = scaleByDPI(2), - word_padding = scaleByDPI(2), - word_margin = scaleByDPI(2), - definition_padding = scaleByDPI(2), - definition_margin = scaleByDPI(2), - button_padding = scaleByDPI(14), + title_padding = Screen:scaleByDPI(5), + title_margin = Screen:scaleByDPI(2), + word_padding = Screen:scaleByDPI(2), + word_margin = Screen:scaleByDPI(2), + definition_padding = Screen:scaleByDPI(2), + definition_margin = Screen:scaleByDPI(2), + button_padding = Screen:scaleByDPI(14), } function DictQuickLookup:init() @@ -133,7 +142,7 @@ function DictQuickLookup:update() --background = 8, dimen = Geom:new{ 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 return true end + +return DictQuickLookup diff --git a/frontend/ui/widget/eventlistener.lua b/frontend/ui/widget/eventlistener.lua new file mode 100644 index 000000000..9e4304b0e --- /dev/null +++ b/frontend/ui/widget/eventlistener.lua @@ -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 diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index cb042f4d3..2923344ec 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -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(), width = Screen:getWidth(), no_title = true, @@ -73,3 +76,5 @@ function FileChooser:onFileSelect(file) UIManager:close(self) return true end + +return FileChooser diff --git a/frontend/ui/widget/fixedtextwidget.lua b/frontend/ui/widget/fixedtextwidget.lua new file mode 100644 index 000000000..e5c6e4c71 --- /dev/null +++ b/frontend/ui/widget/fixedtextwidget.lua @@ -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 diff --git a/frontend/ui/widget/focusmanager.lua b/frontend/ui/widget/focusmanager.lua index 8e5394723..aac793c71 100644 --- a/frontend/ui/widget/focusmanager.lua +++ b/frontend/ui/widget/focusmanager.lua @@ -1,3 +1,6 @@ +local InputContainer = require("ui/widget/container/inputcontainer") +-- UIManager + --[[ Wrapper Widget that manages focus for a whole dialog @@ -21,7 +24,7 @@ reach either or . but notice that this does _not_ do the layout for you, it rather defines an abstract layout. ]] -FocusManager = InputContainer:new{ +local FocusManager = InputContainer:new{ selected = nil, -- defaults to x=1, y=1 layout = nil, -- mandatory movement_allowed = { x = true, y = true } @@ -93,3 +96,5 @@ function FocusManager:onWrapLast() self.selected.y = 1 return true end + +return FocusManager diff --git a/frontend/ui/widget/group.lua b/frontend/ui/widget/group.lua deleted file mode 100644 index 292aa3af7..000000000 --- a/frontend/ui/widget/group.lua +++ /dev/null @@ -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 - diff --git a/frontend/ui/widget/horizontalgroup.lua b/frontend/ui/widget/horizontalgroup.lua new file mode 100644 index 000000000..7309fd52d --- /dev/null +++ b/frontend/ui/widget/horizontalgroup.lua @@ -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 diff --git a/frontend/ui/widget/horizontalspan.lua b/frontend/ui/widget/horizontalspan.lua new file mode 100644 index 000000000..f36bad312 --- /dev/null +++ b/frontend/ui/widget/horizontalspan.lua @@ -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 diff --git a/frontend/ui/widget/iconbutton.lua b/frontend/ui/widget/iconbutton.lua index a80b1ab00..155dda63d 100644 --- a/frontend/ui/widget/iconbutton.lua +++ b/frontend/ui/widget/iconbutton.lua @@ -1,11 +1,12 @@ -require "ui/widget/container" -require "ui/widget/image" - +local InputContainer = require("ui/widget/container/inputcontainer") +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 --]] -IconButton = InputContainer:new{ +local IconButton = InputContainer:new{ icon_file = "resources/info-confirm.png", dimen = nil, -- 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 end +return IconButton diff --git a/frontend/ui/widget/image.lua b/frontend/ui/widget/imagewidget.lua similarity index 87% rename from frontend/ui/widget/image.lua rename to frontend/ui/widget/imagewidget.lua index 36b8ae830..1aa3c0d82 100644 --- a/frontend/ui/widget/image.lua +++ b/frontend/ui/widget/imagewidget.lua @@ -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 = Widget:new{ +local ImageWidget = Widget:new{ file = nil, invert = nil, dim = nil, @@ -51,4 +53,4 @@ function ImageWidget:free() end end - +return ImageWidget diff --git a/frontend/ui/widget/infomessage.lua b/frontend/ui/widget/infomessage.lua index 157301421..b44985f6e 100644 --- a/frontend/ui/widget/infomessage.lua +++ b/frontend/ui/widget/infomessage.lua @@ -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 it vanishes on key press or after a given timeout ]] -InfoMessage = InputContainer:new{ +local InfoMessage = InputContainer:new{ face = Font:getFace("infofont", 25), text = "", timeout = nil, -- in seconds @@ -69,3 +78,5 @@ function InfoMessage:onTapClose() UIManager:close(self) return true end + +return InfoMessage diff --git a/frontend/ui/widget/inputdialog.lua b/frontend/ui/widget/inputdialog.lua index 90859e0a2..a534dbbae 100644 --- a/frontend/ui/widget/inputdialog.lua +++ b/frontend/ui/widget/inputdialog.lua @@ -1,7 +1,17 @@ -require "ui/widget/container" -require "ui/widget/inputtext" +local InputContainer = require("ui/widget/container/inputcontainer") +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 = "", input = "", input_hint = "", @@ -14,11 +24,11 @@ InputDialog = InputContainer:new{ title_face = Font:getFace("tfont", 22), input_face = Font:getFace("cfont", 20), - title_padding = scaleByDPI(5), - title_margin = scaleByDPI(2), - input_padding = scaleByDPI(10), - input_margin = scaleByDPI(10), - button_padding = scaleByDPI(14), + title_padding = Screen:scaleByDPI(5), + title_margin = Screen:scaleByDPI(2), + input_padding = Screen:scaleByDPI(10), + input_margin = Screen:scaleByDPI(10), + button_padding = Screen:scaleByDPI(14), } function InputDialog:init() @@ -52,7 +62,7 @@ function InputDialog:init() --background = 8, dimen = Geom:new{ w = button_table:getSize().w + self.button_padding, - h = scaleByDPI(2), + h = Screen:scaleByDPI(2), } } @@ -107,3 +117,5 @@ end function InputDialog:onClose() self.input:onCloseKeyboard() end + +return InputDialog diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua index 7a69cc65f..e46603eac 100644 --- a/frontend/ui/widget/inputtext.lua +++ b/frontend/ui/widget/inputtext.lua @@ -1,9 +1,13 @@ -require "ui/graphics" -require "ui/widget/text" -require "ui/widget/keyboard" -require "ui/widget/container" +local InputContainer = require("ui/widget/container/inputcontainer") +local ScrollTextWidget = require("ui/widget/scrolltextwidget") +local TextBoxWidget = require("ui/widget/textboxwidget") +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 = "", hint = "demo hint", charlist = {}, -- table to store input string @@ -144,3 +148,5 @@ function InputText:CharlistToString() end return s end + +return InputText diff --git a/frontend/ui/widget/line.lua b/frontend/ui/widget/linewidget.lua similarity index 87% rename from frontend/ui/widget/line.lua rename to frontend/ui/widget/linewidget.lua index eba16976f..25d5282e2 100644 --- a/frontend/ui/widget/line.lua +++ b/frontend/ui/widget/linewidget.lua @@ -1,6 +1,6 @@ -require "ui/widget/base" +local Widget = require("ui/widget/widget") -LineWidget = Widget:new{ +local LineWidget = Widget:new{ style = "solid", background = 15, dimen = nil, @@ -29,3 +29,5 @@ function LineWidget:paintTo(bb, x, y) end end end + +return LineWidget diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index fd713cf10..0c66773b8 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -1,16 +1,30 @@ -require "ui/widget/container" -require "ui/widget/focusmanager" -require "ui/widget/infomessage" -require "ui/widget/button" -require "ui/widget/text" -require "ui/widget/group" -require "ui/widget/span" -require "ui/font" +local InputContainer = require("ui/widget/container/inputcontainer") +local WidgetContainer = require("ui/widget/container/widgetcontainer") +local FrameContainer = require("ui/widget/container/framecontainer") +local CenterContainer = require("ui/widget/container/centercontainer") +local BottomContainer = require("ui/widget/container/bottomcontainer") +local UnderlineContainer = require("ui/widget/container/underlinecontainer") +local HorizontalSpan = require("ui/widget/horizontalspan") +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 --]] -ItemShortCutIcon = WidgetContainer:new{ +local ItemShortCutIcon = WidgetContainer:new{ dimen = Geom:new{ w = 22, h = 22 }, key = nil, bordersize = 2, @@ -60,7 +74,7 @@ end NOTICE: @menu entry must be provided in order to close the menu --]] -MenuCloseButton = InputContainer:new{ +local MenuCloseButton = InputContainer:new{ align = "right", menu = nil, dimen = Geom:new{}, @@ -92,7 +106,7 @@ end --[[ Widget that displays an item for menu --]] -MenuItem = InputContainer:new{ +local MenuItem = InputContainer:new{ text = nil, show_parent = nil, detail = nil, @@ -132,7 +146,7 @@ function MenuItem:init() } 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 Device:isTouchDevice() then else @@ -141,8 +155,8 @@ function MenuItem:init() } end indicator = " >>" - indicator_w = sizeUtf8Text(0, self.dimen.w, self.face, indicator, true).x - self.text = getSubTextByWidth(self.text, self.face, + indicator_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, indicator, true).x + self.text = RenderText:getSubTextByWidth(self.text, self.face, self.content_width - indicator_w, true) .. indicator end @@ -211,7 +225,7 @@ end --[[ Widget that displays menu --]] -Menu = FocusManager:new{ +local Menu = FocusManager:new{ show_parent = nil, -- face for displaying item contents cface = Font:getFace("cfont", 22), @@ -611,3 +625,5 @@ function Menu:onSwipe(arg, ges_ev) self:onPrevPage() end end + +return Menu diff --git a/frontend/ui/widget/notification.lua b/frontend/ui/widget/notification.lua index 43a76bff6..59c8675ba 100644 --- a/frontend/ui/widget/notification.lua +++ b/frontend/ui/widget/notification.lua @@ -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 --]] -Notification = InputContainer:new{ +local Notification = InputContainer:new{ face = Font:getFace("infofont", 20), text = "Null Message", timeout = nil, @@ -50,3 +57,4 @@ function Notification:onAnyKeyPressed() return true end +return Notification diff --git a/frontend/ui/widget/overlapgroup.lua b/frontend/ui/widget/overlapgroup.lua new file mode 100644 index 000000000..c4918bb55 --- /dev/null +++ b/frontend/ui/widget/overlapgroup.lua @@ -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 diff --git a/frontend/ui/widget/progress.lua b/frontend/ui/widget/progresswidget.lua similarity index 88% rename from frontend/ui/widget/progress.lua rename to frontend/ui/widget/progresswidget.lua index 3952e223e..e93efb98c 100644 --- a/frontend/ui/widget/progress.lua +++ b/frontend/ui/widget/progresswidget.lua @@ -1,10 +1,9 @@ -require "ui/widget/base" - +local Widget = require("ui/widget/widget") --[[ ProgressWidget shows a progress bar --]] -ProgressWidget = Widget:new{ +local ProgressWidget = Widget:new{ width = nil, height = nil, margin_h = 3, @@ -35,5 +34,4 @@ function ProgressWidget:setPercentage(percentage) self.percentage = percentage end - - +return ProgressWidget diff --git a/frontend/ui/widget/rectspan.lua b/frontend/ui/widget/rectspan.lua new file mode 100644 index 000000000..d02ffc6bb --- /dev/null +++ b/frontend/ui/widget/rectspan.lua @@ -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 diff --git a/frontend/ui/widget/scrolltextwidget.lua b/frontend/ui/widget/scrolltextwidget.lua new file mode 100644 index 000000000..a93fb9e45 --- /dev/null +++ b/frontend/ui/widget/scrolltextwidget.lua @@ -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 diff --git a/frontend/ui/widget/span.lua b/frontend/ui/widget/span.lua deleted file mode 100644 index 9782ce6c1..000000000 --- a/frontend/ui/widget/span.lua +++ /dev/null @@ -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 - - diff --git a/frontend/ui/widget/text.lua b/frontend/ui/widget/textboxwidget.lua similarity index 61% rename from frontend/ui/widget/text.lua rename to frontend/ui/widget/textboxwidget.lua index f29a6273b..c06d6a96c 100644 --- a/frontend/ui/widget/text.lua +++ b/frontend/ui/widget/textboxwidget.lua @@ -1,65 +1,14 @@ -require "ui/rendertext" -require "ui/widget/base" -require "ui/widget/scrollbar" +local Widget = require("ui/widget/widget") +local RenderText = require("ui/rendertext") +local Screen = require("ui/screen") +local Geom = require("ui/geometry") ---[[ -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 +-- TODO: rename string:gsplit definition --[[ A TextWidget that handles long text wrapping --]] -TextBoxWidget = Widget:new{ +local TextBoxWidget = Widget:new{ text = nil, face = nil, bgcolor = 0.0, -- [0.0, 1.0] @@ -157,7 +106,7 @@ function TextBoxWidget:_getVerticalList(alg) for w in word:gsplit("%p+", true) do local word_box = {} 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) end end @@ -245,7 +194,7 @@ end function TextBoxWidget:_render(v_list) local font_height = self.face.size 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 self._bb = Blitbuffer.new(self.width, h) local y = font_height @@ -255,7 +204,7 @@ function TextBoxWidget:_render(v_list) for _,w in ipairs(l) do --@TODO Don't use kerning for monospaced fonts. (houqp) -- 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) pen_x = pen_x + w.width end @@ -312,97 +261,4 @@ function TextBoxWidget:free() end end ---[[ -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 +return TextBoxWidget diff --git a/frontend/ui/widget/textwidget.lua b/frontend/ui/widget/textwidget.lua new file mode 100644 index 000000000..0c87f9937 --- /dev/null +++ b/frontend/ui/widget/textwidget.lua @@ -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 diff --git a/frontend/ui/widget/toggleswitch.lua b/frontend/ui/widget/toggleswitch.lua index 47a31819a..85ff147f4 100644 --- a/frontend/ui/widget/toggleswitch.lua +++ b/frontend/ui/widget/toggleswitch.lua @@ -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, fgcolor = 1, } 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 -ToggleSwitch = InputContainer:new{ - width = scaleByDPI(216), - height = scaleByDPI(30), +local ToggleSwitch = InputContainer:new{ + width = Screen:scaleByDPI(216), + height = Screen:scaleByDPI(30), bgcolor = 0, -- unfoused item color fgcolor = 7, -- focused item color } @@ -123,3 +136,4 @@ function ToggleSwitch:onTapSelect(arg, gev) UIManager.repaint_all = true end +return ToggleSwitch diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index 7dcd4110b..92e986977 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -1,13 +1,27 @@ -require "ui/widget/container" -require "ui/widget/group" -require "ui/widget/line" -require "ui/widget/iconbutton" - +local InputContainer = require("ui/widget/container/inputcontainer") +local FrameContainer = require("ui/widget/container/framecontainer") +local LeftContainer = require("ui/widget/container/leftcontainer") +local RightContainer = require("ui/widget/container/rightcontainer") +local CenterContainer = require("ui/widget/container/centercontainer") +local Font = require("ui/font") +local TextWidget = require("ui/widget/textwidget") +local LineWidget = require("ui/widget/linewidget") +local Screen = require("ui/screen") +local GestureRange = require("ui/gesturerange") +local HorizontalGroup = require("ui/widget/horizontalgroup") +local VerticalGroup = require("ui/widget/verticalgroup") +local HorizontalSpan = require("ui/widget/horizontalspan") +local VerticalSpan = require("ui/widget/verticalspan") +local IconButton = require("ui/widget/iconbutton") +local UIManager = require("ui/uimanager") +local Screen = require("ui/screen") +local Geom = require("ui/geometry") +local _ = require("gettext") --[[ TouchMenuItem widget --]] -TouchMenuItem = InputContainer:new{ +local TouchMenuItem = InputContainer:new{ menu = nil, vertical_align = "center", item = nil, @@ -58,8 +72,8 @@ end --[[ TouchMenuBar widget --]] -TouchMenuBar = InputContainer:new{ - height = scaleByDPI(70), +local TouchMenuBar = InputContainer:new{ + height = Screen:scaleByDPI(70), width = Screen:getWidth(), icons = {}, -- touch menu that holds the bar, used for trigger repaint on icons @@ -79,12 +93,12 @@ function TouchMenuBar:init() local icon_sep = LineWidget:new{ dimen = Geom:new{ - w = scaleByDPI(2), + w = Screen:scaleByDPI(2), h = self.height, } } - local icon_span = HorizontalSpan:new{ width = scaleByDPI(20) } + local icon_span = HorizontalSpan:new{ width = Screen:scaleByDPI(20) } -- build up image widget for menu icon bar self.icon_widgets = {} @@ -113,7 +127,7 @@ function TouchMenuBar:init() self.bar_sep = LineWidget:new{ dimen = Geom:new{ w = self.width, - h = scaleByDPI(2), + h = Screen:scaleByDPI(2), }, empty_segments = { { @@ -156,15 +170,15 @@ end --[[ TouchMenu widget --]] -TouchMenu = InputContainer:new{ +local TouchMenu = InputContainer:new{ tab_item_table = {}, -- for returnning in multi-level menus item_table_stack = nil, item_table = nil, - item_height = scaleByDPI(50), - bordersize = scaleByDPI(2), - padding = scaleByDPI(5), - footer_height = scaleByDPI(50), + item_height = Screen:scaleByDPI(50), + bordersize = Screen:scaleByDPI(2), + padding = Screen:scaleByDPI(5), + footer_height = Screen:scaleByDPI(50), width = nil, height = nil, page = 1, @@ -327,7 +341,7 @@ function TouchMenu:updateItems() end -- if i <= self.items end -- for c=1, self.perpage - table.insert(self.item_group, VerticalSpan:new{width = scaleByDPI(2)}) + table.insert(self.item_group, VerticalSpan:new{width = Screen:scaleByDPI(2)}) table.insert(self.item_group, self.footer) self.footer_page.text = _("Page ")..self.page.."/"..self.page_num self.time_info.text = os.date("%H:%M") @@ -412,3 +426,4 @@ function TouchMenu:onTapCloseAllMenus(arg, ges_ev) end end +return TouchMenu diff --git a/frontend/ui/widget/verticalgroup.lua b/frontend/ui/widget/verticalgroup.lua new file mode 100644 index 000000000..fe94c1f52 --- /dev/null +++ b/frontend/ui/widget/verticalgroup.lua @@ -0,0 +1,64 @@ +local WidgetContainer = require("ui/widget/container/widgetcontainer") + +--[[ +A Layout widget that puts objects under each other +--]] +local 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 + +return VerticalGroup diff --git a/frontend/ui/widget/scrollbar.lua b/frontend/ui/widget/verticalscrollbar.lua similarity index 83% rename from frontend/ui/widget/scrollbar.lua rename to frontend/ui/widget/verticalscrollbar.lua index 3a3a1a553..fd16f6f73 100644 --- a/frontend/ui/widget/scrollbar.lua +++ b/frontend/ui/widget/verticalscrollbar.lua @@ -1,5 +1,7 @@ +local Widget = require("ui/widget/widget") +local Geom = require("ui/geometry") -VerticalScrollBar = Widget:new{ +local VerticalScrollBar = Widget:new{ enable = true, low = 0, high = 1, @@ -32,3 +34,5 @@ function VerticalScrollBar:paintTo(bb, x, y) self.width - 2*self.bordersize, self.height * (self.high - self.low), self.rectcolor) end + +return VerticalScrollBar diff --git a/frontend/ui/widget/verticalspan.lua b/frontend/ui/widget/verticalspan.lua new file mode 100644 index 000000000..c3c897f71 --- /dev/null +++ b/frontend/ui/widget/verticalspan.lua @@ -0,0 +1,14 @@ +local Widget = require("ui/widget/widget") + +--[[ +Dummy Widget that reserves vertical space +--]] +local VerticalSpan = Widget:new{ + width = 0, +} + +function VerticalSpan:getSize() + return {w = 0, h = self.width} +end + +return VerticalSpan diff --git a/frontend/ui/widget/keyboard.lua b/frontend/ui/widget/virtualkeyboard.lua similarity index 88% rename from frontend/ui/widget/keyboard.lua rename to frontend/ui/widget/virtualkeyboard.lua index 39cad6e72..fc80ce751 100644 --- a/frontend/ui/widget/keyboard.lua +++ b/frontend/ui/widget/virtualkeyboard.lua @@ -1,10 +1,21 @@ -require "ui/font" -require "ui/widget/text" -require "ui/widget/image" -require "ui/widget/group" -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 BottomContainer = require("ui/widget/container/bottomcontainer") +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 ImageWidget = require("ui/widget/imagewidget") +local TextWidget = require("ui/widget/textwidget") +local Font = require("ui/font") +local Geom = require("ui/geometry") +local Screen = require("ui/screen") +local Device = require("ui/device") +local GestureRange = require("ui/gesturerange") +local UIManager = require("ui/uimanager") -VirtualKey = InputContainer:new{ +local VirtualKey = InputContainer:new{ key = nil, icon = nil, label = nil, @@ -91,7 +102,7 @@ function VirtualKey:invert(invert) UIManager:setDirty(self.keyboard, "partial") end -VirtualKeyboard = InputContainer:new{ +local VirtualKeyboard = InputContainer:new{ is_always_active = true, disable_double_tap = true, inputbox = nil, @@ -107,7 +118,7 @@ VirtualKeyboard = InputContainer:new{ height = 256, bordersize = 2, padding = 2, - key_padding = scaleByDPI(6), + key_padding = Screen:scaleByDPI(6), } function VirtualKeyboard:init() @@ -281,3 +292,5 @@ function VirtualKeyboard:delChar() UIManager:setDirty(self, "partial") UIManager:setDirty(self.inputbox, "partial") end + +return VirtualKeyboard diff --git a/frontend/ui/widget/base.lua b/frontend/ui/widget/widget.lua similarity index 63% rename from frontend/ui/widget/base.lua rename to frontend/ui/widget/widget.lua index 27096b297..96e14ddbf 100644 --- a/frontend/ui/widget/base.lua +++ b/frontend/ui/widget/widget.lua @@ -1,33 +1,4 @@ -require "ui/screen" -require "ui/rendertext" -require "ui/graphics" -require "ui/event" -require "ui/gesturedetector" -require "ui/font" - ---[[ -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" ---]] -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 - +local EventListener = require("ui/widget/eventlistener") --[[ This is a generic Widget interface @@ -40,7 +11,7 @@ if the table that was given to us as parameter has an "init" method, it will be called. use this to set _instance_ variables rather than class variables. --]] -Widget = EventListener:new() +local Widget = EventListener:new() --[[ Use this method to define a class that's inherited from current class. @@ -76,5 +47,4 @@ end function Widget:paintTo(bb, x, y) end - - +return Widget diff --git a/reader.lua b/reader.lua index f430e7cb2..6acb2f54f 100755 --- a/reader.lua +++ b/reader.lua @@ -3,14 +3,16 @@ require "defaults" package.path = "./frontend/?.lua;./?.lua" package.cpath = "/usr/lib/lua/?.so" -require "ui/uimanager" -require "ui/widget/infomessage" -require "ui/readerui" -require "document/document" -require "settings" -require "dbg" -require "gettext" -require "apps/filemanager/fm" +local UIManager = require("ui/uimanager") +local InfoMessage = require("ui/widget/infomessage") +local ReaderUI = require("ui/readerui") +local DocumentRegistry = require("document/documentregistry") +local DocSettings = require("docsettings") +local Dbg = require("dbg") +local FileManager = require("apps/filemanager/filemanager") +local Device = require("ui/device") +local Screen = require("ui/screen") +local _ = require("gettext") Profiler = nil @@ -75,10 +77,8 @@ function showHomePage(path) }) end - - -- option parsing: -longopts = { +local longopts = { debug = "d", profile = "p", help = "h",