diff --git a/filechooser.lua b/filechooser.lua index 865a0147f..ae24642c2 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -1,26 +1,13 @@ require "rendertext" require "keys" require "graphics" -require "fontchooser" +require "font" require "filesearcher" require "inputbox" require "selectmenu" FileChooser = { -- Class vars: - -- font for displaying toc item names - fsize = 25, - face = nil, - fhash = nil, - --face = freetype.newBuiltinFace("sans", 25), - --fhash = "s25", - - -- font for paging display - ffsize = 16, - fface = nil, - ffhash = nil, - --sface = freetype.newBuiltinFace("sans", 16), - --sfhash = "s16", -- spacing between lines spacing = 40, @@ -93,17 +80,6 @@ function FileChooser:setPath(newPath) end end -function FileChooser:updateFont() - if self.fhash ~= FontChooser.cfont..self.fsize then - self.face = freetype.newBuiltinFace(FontChooser.cfont, self.fsize) - self.fhash = FontChooser.cfont..self.fsize - end - if self.ffhash ~= FontChooser.ffont..self.ffsize then - self.fface = freetype.newBuiltinFace(FontChooser.ffont, self.ffsize) - self.ffhash = FontChooser.ffont..self.ffsize - end -end - function FileChooser:choose(ypos, height) local perpage = math.floor(height / self.spacing) - 2 local pagedirty = true @@ -139,7 +115,9 @@ function FileChooser:choose(ypos, height) end while true do - self:updateFont() + local cface, cfhash= Font:getFaceAndHash(25) + local fface, ffhash = Font:getFaceAndHash(16, Font.ffont) + if pagedirty then fb.bb:paintRect(0, ypos, fb.bb:getWidth(), height, 0) local c @@ -147,17 +125,17 @@ function FileChooser:choose(ypos, height) local i = (self.page - 1) * perpage + c if i <= #self.dirs then -- resembles display in midnight commander: adds "/" prefix for directories - renderUtf8Text(fb.bb, 39, ypos + self.spacing*c, self.face, self.fhash, "/", true) - renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, self.face, self.fhash, self.dirs[i], true) + renderUtf8Text(fb.bb, 39, ypos + self.spacing*c, cface, cfhash, "/", true) + renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, cface, cfhash, self.dirs[i], true) elseif i <= self.items then - renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, self.face, self.fhash, self.files[i-#self.dirs], true) + renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, cface, cfhash, self.files[i-#self.dirs], true) end end - renderUtf8Text(fb.bb, 5, ypos + self.spacing * perpage + 42, self.fface, self.ffhash, + renderUtf8Text(fb.bb, 5, ypos + self.spacing * perpage + 42, fface, ffhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) local msg = self.exception_message and self.exception_message:match("[^%:]+:%d+: (.*)") or "Path: "..self.path self.exception_message = nil - renderUtf8Text(fb.bb, 5, ypos + self.spacing * (perpage+1) + 27, self.fface, self.ffhash, msg, true) + renderUtf8Text(fb.bb, 5, ypos + self.spacing * (perpage+1) + 27, fface, ffhash, msg, true) markerdirty = true end if markerdirty then @@ -190,12 +168,12 @@ function FileChooser:choose(ypos, height) elseif ev.code == KEY_F then -- invoke fontchooser menu fonts_menu = SelectMenu:new{ menu_title = "Fonts Menu", - item_array = FontChooser.fonts, + item_array = Font.fonts, } local re = fonts_menu:choose(0, height) if re then - FontChooser.cfont = FontChooser.fonts[re] - FontChooser:init() + Font.cfont = Font.fonts[re] + Font:update() end pagedirty = true elseif ev.code == KEY_S then -- invoke search input diff --git a/filesearcher.lua b/filesearcher.lua index 667f787f9..0d8153cd4 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -1,22 +1,9 @@ require "rendertext" require "keys" require "graphics" -require "fontchooser" +require "font" FileSearcher = { - -- font for displaying toc item names - fsize = 25, - face = nil, - fhash = nil, - -- font for page title - tfsize = 30, - tface = nil, - tfhash = nil, - -- font for paging display - ffsize = 16, - fface = nil, - ffhash = nil, - -- title height title_H = 45, -- spacing between lines @@ -70,23 +57,6 @@ function FileSearcher:setPath(newPath) return true end -function FileSearcher:updateFont() - if self.fhash ~= FontChooser.cfont..self.fsize then - self.face = freetype.newBuiltinFace(FontChooser.cfont, self.fsize) - self.fhash = FontChooser.cfont..self.fsize - end - - if self.tfhash ~= FontChooser.tfont..self.tfsize then - self.tface = freetype.newBuiltinFace(FontChooser.tfont, self.tfsize) - self.tfhash = FontChooser.tfont..self.tfsize - end - - if self.ffhash ~= FontChooser.ffont..self.ffsize then - self.fface = freetype.newBuiltinFace(FontChooser.ffont, self.ffsize) - self.ffhash = FontChooser.ffont..self.ffsize - end -end - function FileSearcher:setSearchResult(keywords) self.result = {} if keywords == " " then -- one space to show all files @@ -153,22 +123,25 @@ function FileSearcher:choose(ypos, height, keywords) end while true do - self:updateFont() + local cface, cfhash = Font:getFaceAndHash(22) + local tface, tfhash = Font:getFaceAndHash(25, Font.tfont) + local fface, ffhash = Font:getFaceAndHash(16, Font.ffont) + if pagedirty then markerdirty = true fb.bb:paintRect(0, ypos, fb.bb:getWidth(), height, 0) -- draw menu title - renderUtf8Text(fb.bb, 30, ypos + self.title_H, self.tface, self.tfhash, + renderUtf8Text(fb.bb, 30, ypos + self.title_H, tface, tfhash, "Search Result for: "..keywords, true) -- draw results local c if self.items == 0 then -- nothing found y = ypos + self.title_H + self.spacing * 2 - renderUtf8Text(fb.bb, 20, y, self.face, self.fhash, + renderUtf8Text(fb.bb, 20, y, cface, cfhash, "Sorry, no match found.", true) - renderUtf8Text(fb.bb, 20, y + self.spacing, self.face, self.fhash, + renderUtf8Text(fb.bb, 20, y + self.spacing, cface, cfhash, "Please try a different keyword.", true) markerdirty = false else -- found something, draw it @@ -176,7 +149,7 @@ function FileSearcher:choose(ypos, height, keywords) local i = (self.page - 1) * perpage + c if i <= self.items then y = ypos + self.title_H + (self.spacing * c) - renderUtf8Text(fb.bb, 50, y, self.face, self.fhash, + renderUtf8Text(fb.bb, 50, y, cface, cfhash, self.result[i].name, true) end end @@ -186,7 +159,7 @@ function FileSearcher:choose(ypos, height, keywords) y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H x = (fb.bb:getWidth() / 2) - 50 all_page = (math.floor(self.items / perpage)+1) - renderUtf8Text(fb.bb, x, y, self.fface, self.ffhash, + renderUtf8Text(fb.bb, x, y, fface, ffhash, "Page "..self.page.." of "..all_page, true) end @@ -251,12 +224,12 @@ function FileSearcher:choose(ypos, height, keywords) elseif ev.code == KEY_F then -- invoke fontchooser menu fonts_menu = SelectMenu:new{ menu_title = "Fonts Menu", - item_array = FontChooser.fonts, + item_array = Font.fonts, } local re = fonts_menu:choose(0, height) if re then - FontChooser.cfont = FontChooser.fonts[re] - FontChooser:init() + Font.cfont = Font.fonts[re] + Font:update() end pagedirty = true elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then diff --git a/font.lua b/font.lua new file mode 100644 index 000000000..9aadbb3b7 --- /dev/null +++ b/font.lua @@ -0,0 +1,47 @@ + +Font = { + -- default font for menu contents + cfont = "sans", + -- default font for title + tfont = "Helvetica-BoldOblique", + -- default font for footer + ffont = "sans", + + -- built in fonts + fonts = {"sans", "cjk", "mono", + "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", + "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", + "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, + + -- face table + faces = {}, +} + +function Font:getFaceAndHash(size, font) + if not font then + -- default to content font + font = self.cfont + end + + local face = self.faces[font..size] + -- build face if not found + if not face then + for _k,_v in ipairs(self.fonts) do + if font == _v then + face = freetype.newBuiltinFace(font, size) + self.faces[font..size] = face + end + end + if not face then + print("#! Font "..font.." not supported!!") + return nil + end + end + return face, font..size +end + +function Font:update() + self.faces = {} + clearglyphcache() +end + diff --git a/graphics.lua b/graphics.lua index e4b16efac..1ebb13cce 100644 --- a/graphics.lua +++ b/graphics.lua @@ -5,3 +5,25 @@ blitbuffer.paintBorder = function (bb, x, y, w, h, bw, c) bb:paintRect(x, y+bw, bw, h - 2*bw, c) bb:paintRect(x+w-bw, y+bw, bw, h - 2*bw, c) 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 +--]] +blitbuffer.progressBar = function (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 + blitbuffer.paintBorder(fb.bb, x, y, w, h, 2, 15) + fb.bb:paintRect(x+load_m_w, y+load_m_h, + (w-2*load_m_w)*load_percent, (h-2*load_m_h), c) +end diff --git a/reader.lua b/reader.lua index ae48c575e..9c18d3cee 100755 --- a/reader.lua +++ b/reader.lua @@ -103,7 +103,6 @@ else input.open("/dev/input/event2") set_k3_keycodes() end - end if optarg["G"] ~= nil then @@ -120,7 +119,7 @@ origin_rotation_mode = Screen.cur_rotation_mode reader_settings = DocSettings:open(".reader") r_cfont = reader_settings:readsetting("cfont") if r_cfont ~=nil then - FontChooser.cfont = r_cfont + Font.cfont = r_cfont end -- initialize global settings shared among all readers @@ -156,7 +155,7 @@ end -- save reader settings -reader_settings:savesetting("cfont", FontChooser.cfont) +reader_settings:savesetting("cfont", Font.cfont) reader_settings:close() -- @TODO dirty workaround, find a way to force native system poll diff --git a/screen.lua b/screen.lua index 158d20a63..24923a2e7 100644 --- a/screen.lua +++ b/screen.lua @@ -43,7 +43,8 @@ Screen = { cur_rotation_mode = 0, } --- @ orien: 1 for clockwise rotate, -1 for anti-clockwise +-- @orien: 1 for clockwise rotate, -1 for anti-clockwise +-- Remember to reread screen resolution after this function call function Screen:screenRotate(orien) if orien == "clockwise" then orien = -1 @@ -57,9 +58,6 @@ function Screen:screenRotate(orien) -- you have to reopen framebuffer after rotate fb:setOrientation(self.cur_rotation_mode) fb:close() - --local mode = self.rotation_modes[self.cur_rotation_mode] - --self.cur_rotation_mode = (self.cur_rotation_mode-1 + 1*orien)%4 + 1 - --os.execute("lipc-send-event -r 3 com.lab126.hal orientation"..mode) fb = einkfb.open("/dev/fb0") end diff --git a/selectmenu.lua b/selectmenu.lua index 32728e9ab..ec9f35a56 100644 --- a/selectmenu.lua +++ b/selectmenu.lua @@ -1,21 +1,15 @@ require "rendertext" require "keys" require "graphics" -require "fontchooser" +require "font" SelectMenu = { -- font for displaying item names fsize = 22, - face = nil, - fhash = nil, -- font for page title tfsize = 25, - tface = nil, - tfhash = nil, -- font for paging display ffsize = 16, - fface = nil, - ffhash = nil, -- font for item shortcut sface = freetype.newBuiltinFace("mono", 22), sfhash = "mono22", @@ -59,23 +53,6 @@ function SelectMenu:new(o) return o end -function SelectMenu:updateFont() - if self.fhash ~= FontChooser.cfont..self.fsize then - self.face = freetype.newBuiltinFace(FontChooser.cfont, self.fsize) - self.fhash = FontChooser.cfont..self.fsize - end - - if self.tfhash ~= FontChooser.tfont..self.tfsize then - self.tface = freetype.newBuiltinFace(FontChooser.tfont, self.tfsize) - self.tfhash = FontChooser.tfont..self.tfsize - end - - if self.ffhash ~= FontChooser.ffont..self.ffsize then - self.fface = freetype.newBuiltinFace(FontChooser.ffont, self.ffsize) - self.ffhash = FontChooser.ffont..self.ffsize - end -end - function SelectMenu:getItemIndexByShortCut(c, perpage) if c == nil then return end -- unused key for _k,_v in ipairs(self.item_shortcuts) do @@ -92,7 +69,6 @@ function SelectMenu:choose(ypos, height) local perpage = math.floor(height / self.spacing) - 2 local pagedirty = true local markerdirty = false - self:updateFont() local prevItem = function () if self.current == 1 then @@ -126,25 +102,28 @@ function SelectMenu:choose(ypos, height) self.last_shortcut = 0 while true do + local cface, cfhash = Font:getFaceAndHash(22) + local tface, tfhash = Font:getFaceAndHash(25, Font.tfont) + local fface, ffhash = Font:getFaceAndHash(16, Font.ffont) + if pagedirty then markerdirty = true -- draw menu title fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) fb.bb:paintRect(10, ypos + 10, fb.bb:getWidth() - 20, self.title_H, 5) - x = 20 - y = ypos + self.title_H - renderUtf8Text(fb.bb, x, y, self.tface, self.tfhash, - self.menu_title, true) + local x = 20 + local y = ypos + self.title_H + renderUtf8Text(fb.bb, x, y, tface, tfhash, self.menu_title, true) -- draw items fb.bb:paintRect(0, ypos + self.title_H + 10, fb.bb:getWidth(), height - self.title_H, 0) if self.items == 0 then y = ypos + self.title_H + (self.spacing * 2) - renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + renderUtf8Text(fb.bb, 30, y, cface, cfhash, "Oops... Bad news for you:", true) y = y + self.spacing - renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + renderUtf8Text(fb.bb, 30, y, cface, cfhash, self.no_item_msg, true) markerdirty = false else @@ -160,8 +139,10 @@ function SelectMenu:choose(ypos, height) else fb.bb:paintRect(10, y-22, 29, 29, 3) end - if self.item_shortcuts[c] ~= nil and string.len(self.item_shortcuts[c]) == 3 then - renderUtf8Text(fb.bb, 13, y, self.fface, self.ffhash, + if self.item_shortcuts[c] ~= nil and + string.len(self.item_shortcuts[c]) == 3 then + -- print "Del", "Sym and "Ent" + renderUtf9Text(fb.bb, 13, y, fface, ffhash, self.item_shortcuts[c], true) else renderUtf8Text(fb.bb, 18, y, self.sface, self.sfhash, @@ -170,7 +151,7 @@ function SelectMenu:choose(ypos, height) self.last_shortcut = c - renderUtf8Text(fb.bb, 50, y, self.face, self.fhash, + renderUtf8Text(fb.bb, 50, y, cface, cfhash, self.item_array[i], true) end end @@ -179,7 +160,7 @@ function SelectMenu:choose(ypos, height) -- draw footer y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H + 5 x = (fb.bb:getWidth() / 2) - 50 - renderUtf8Text(fb.bb, x, y, self.fface, self.ffhash, + renderUtf8Text(fb.bb, x, y, fface, ffhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) end diff --git a/unireader.lua b/unireader.lua index ac777cf5f..75e592e1f 100644 --- a/unireader.lua +++ b/unireader.lua @@ -620,6 +620,37 @@ function UniReader:showJumpStack() end end +function UniReader:showMenu() + local ypos = height - 50 + local load_percent = (self.pageno / self.doc:getPages()) + + fb.bb:paintRect(0, ypos, width, 50, 0) + + ypos = ypos + 15 + local face, fhash = Font:getFaceAndHash(22) + local cur_section = self:getTOCTitleByPage(self.pageno) + if cur_section ~= "" then + cur_section = "Section: "..cur_section + end + renderUtf8Text(fb.bb, 10, ypos+6, face, fhash, + "Page: "..self.pageno.."/"..self.doc:getPages().. + " "..cur_section, true) + + ypos = ypos + 15 + blitbuffer.progressBar(fb.bb, 10, ypos, width-20, 15, + 5, 4, load_percent, 8) + fb:refresh(1) + while 1 do + local ev = input.waitForEvent() + ev.code = adjustKeyEvents(ev) + if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + if ev.code == KEY_BACK or ev.code == KEY_MENU then + return + end + end + end +end + function UniReader:odd_even(number) print("## odd_even "..number) if number % 2 == 1 then @@ -746,6 +777,9 @@ function UniReader:inputloop() elseif ev.code == KEY_Z and Keys.altmode then self.bbox.enabled = not self.bbox.enabled; print("# bbox override: ", self.bbox.enabled); + elseif ev.code == KEY_MENU then + self:showMenu() + self:goto(self.pageno) end -- switch to ZOOM_BY_VALUE to enable panning on fiveway move