From 019695255d04ed385e639e6a7d57268068cc326e Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 17 Feb 2012 13:46:40 +0800 Subject: [PATCH 01/28] add: a demo for text input --- filechooser.lua | 7 +++ fileseacher.lua | 161 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 fileseacher.lua diff --git a/filechooser.lua b/filechooser.lua index ae5104c82..cfd8ef47c 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -2,6 +2,7 @@ require "rendertext" require "keys" require "graphics" require "fontchooser" +require "fileseacher" FileChooser = { -- Class vars: @@ -35,6 +36,7 @@ function FileChooser:readdir() table.insert(self.files, f) end end + --@TODO make sure .. is sortted to the first item 16.02 2012 table.sort(self.dirs) table.sort(self.files) end @@ -151,6 +153,7 @@ function FileChooser:choose(ypos, height) end local ev = input.waitForEvent() if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + print("key code:"..ev.code) if ev.code == KEY_FW_UP then if self:rotationMode() == 0 then prevItem() @@ -183,6 +186,10 @@ function FileChooser:choose(ypos, height) clearglyphcache() end pagedirty = true + elseif ev.code == KEY_S then + FileSeacher:init() + FileSeacher:choose(0, height) + pagedirty = true elseif ev.code == KEY_PGFWD then if self.page < (self.items / perpage) then if self.current + self.page*perpage > self.items then diff --git a/fileseacher.lua b/fileseacher.lua new file mode 100644 index 000000000..137ce4621 --- /dev/null +++ b/fileseacher.lua @@ -0,0 +1,161 @@ +require "rendertext" +require "keys" +require "graphics" + +FileSeacher = { + -- font for displaying file/dir names + face = freetype.newBuiltinFace("sans", 25), + fhash = "s25", + -- font for page title + tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 32), + tfhash = "hbo32", + -- font for paging display + sface = freetype.newBuiltinFace("sans", 16), + sfhash = "s16", + -- title height + title_H = 45, + -- spacing between lines + spacing = 40, + -- foot height + foot_H = 27, + + x_input = 50, + -- state buffer + fonts = {"sans", "cjk", "mono", + "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", + "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", + "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, + items = 14, + page = 1, + current = 2, + oldcurrent = 1, +} + +function FileSeacher:init() + self.items = #self.fonts + --@TODO check this 17.02 2012 + self.face = freetype.newBuiltinFace("sans", 25), + table.sort(self.fonts) +end + + +function FileSeacher:choose(ypos, height) + local perpage = math.floor(height / self.spacing) - 2 + local pagedirty = true + local markerdirty = false + + local prevItem = function () + if self.current == 1 then + if self.page > 1 then + self.current = perpage + self.page = self.page - 1 + pagedirty = true + end + else + self.current = self.current - 1 + markerdirty = true + end + end + + local nextItem = function () + if self.current == perpage then + if self.page < (self.items / perpage) then + self.current = 1 + self.page = self.page + 1 + pagedirty = true + end + else + if self.page ~= math.floor(self.items / perpage) + 1 + or self.current + (self.page-1)*perpage < self.items then + self.current = self.current + 1 + markerdirty = true + end + end + end + + + while true do + if pagedirty then + 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, + "[ Fonts Menu ]", true) + + local c + for c = 1, perpage do + 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, self.fonts[i], true) + end + end + y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H + x = (fb.bb:getWidth() / 2) - 50 + renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, + "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) + markerdirty = true + end + + if markerdirty then + if not pagedirty then + if self.oldcurrent > 0 then + y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 10 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) + end + end + -- draw new marker line + y = ypos + self.title_H + (self.spacing * self.current) + 10 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) + if not pagedirty then + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) + end + self.oldcurrent = self.current + markerdirty = false + end + + if pagedirty then + fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) + pagedirty = false + end + + local ev = input.waitForEvent() + if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + if ev.code == KEY_FW_UP then + prevItem() + elseif ev.code == KEY_FW_DOWN then + nextItem() + elseif ev.code == KEY_PGFWD then + if self.page < (self.items / perpage) then + if self.current + self.page*perpage > self.items then + self.current = self.items - self.page*perpage + end + self.page = self.page + 1 + pagedirty = true + else + self.current = self.items - (self.page-1)*perpage + markerdirty = true + end + elseif ev.code == KEY_PGBCK then + if self.page > 1 then + self.page = self.page - 1 + pagedirty = true + else + self.current = 1 + markerdirty = true + end + elseif ev.code == KEY_F then + self.x_input = self.x_input + 10 + y = ypos + self.title_H + (self.spacing) + renderUtf8Text(fb.bb, self.x_input, y, self.face, self.fhash, "f", true) + fb:refresh(1, x_input, ypos, fb.bb:getWidth(), height) + elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then + local newface = self.fonts[perpage*(self.page-1)+self.current] + return newface + elseif ev.code == KEY_BACK then + return nil + end + end + end +end From da9ff1be6fbcda1d67fd8cab18c9cc21bfe28726 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 17 Feb 2012 14:19:43 +0800 Subject: [PATCH 02/28] mod: two fix * add background to the font menu title * set default current item to 1 --- fontchooser.lua | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/fontchooser.lua b/fontchooser.lua index 920a32ec8..a9d8c8c4d 100644 --- a/fontchooser.lua +++ b/fontchooser.lua @@ -7,8 +7,8 @@ FontChooser = { face = freetype.newBuiltinFace("sans", 25), fhash = "s25", -- font for page title - tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 32), - tfhash = "hbo32", + tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 30), + tfhash = "hbo30", -- font for paging display sface = freetype.newBuiltinFace("sans", 16), sfhash = "s16", @@ -26,8 +26,8 @@ FontChooser = { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, items = 14, page = 1, - current = 2, - oldcurrent = 1, + current = 1, + oldcurrent = 0, } function FontChooser:init() @@ -73,12 +73,14 @@ function FontChooser:choose(ypos, height) while true do if pagedirty then - 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, - "[ Fonts Menu ]", true) + fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) + x = fb.bb:getWidth() - 220 -- move text to the right + y = ypos + self.title_H + renderUtf8Text(fb.bb, x, y, self.tface, self.tfhash, + "Fonts Menu", true) + fb.bb:paintRect(0, ypos + self.title_H + 10, fb.bb:getWidth(), height - self.title_H, 0) local c for c = 1, perpage do local i = (self.page - 1) * perpage + c @@ -87,6 +89,7 @@ function FontChooser:choose(ypos, height) renderUtf8Text(fb.bb, 50, y, self.face, self.fhash, self.fonts[i], true) end end + -- draw footer y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H x = (fb.bb:getWidth() / 2) - 50 renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, From 262b8113f741d028a9c1cd6ad64a04173368a690 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 17 Feb 2012 14:52:54 +0800 Subject: [PATCH 03/28] add: adjustFWKey(code) adjustFWKey() will change code event for five way keys according to current rotation mode. Add this to the input.waitForEvent loop and your UI can navigate properly in different rotation mode. --- filechooser.lua | 52 +++-------------------------------- fontchooser.lua | 1 + keys.lua | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 49 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index ae5104c82..369125944 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -51,33 +51,6 @@ function FileChooser:setPath(newPath) return true end -function FileChooser:rotationMode() - --[[ - return code for four kinds of rotation mode: - - 0 for no rotation, - 1 for landscape with bottom on the right side of screen, etc. - - 2 - --------- - | | - | | - | | - 3 | | 1 - | | - | | - | | - --------- - 0 - --]] - if KEY_FW_DOWN == 116 then - return 0 - end - orie_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_orientation", "r")) - updown_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_upside_down", "r")) - mode = orie_fd:read() + (updown_fd:read() * 2) - return mode -end function FileChooser:choose(ypos, height) local perpage = math.floor(height / self.spacing) - 1 @@ -151,30 +124,11 @@ function FileChooser:choose(ypos, height) end local ev = input.waitForEvent() if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + ev.code = adjustFWKey(ev.code) if ev.code == KEY_FW_UP then - if self:rotationMode() == 0 then - prevItem() - elseif self:rotationMode() == 2 then - nextItem() - end + prevItem() elseif ev.code == KEY_FW_DOWN then - if self:rotationMode() == 0 then - nextItem() - elseif self:rotationMode() == 2 then - prevItem() - end - elseif ev.code == KEY_FW_LEFT then - if self:rotationMode() == 1 then - prevItem() - elseif self:rotationMode() == 3 then - nextItem() - end - elseif ev.code == KEY_FW_RIGHT then - if self:rotationMode() == 1 then - nextItem() - elseif self:rotationMode() == 3 then - prevItem() - end + nextItem() elseif ev.code == KEY_F then FontChooser:init() newfont = FontChooser:choose(0, height) diff --git a/fontchooser.lua b/fontchooser.lua index 920a32ec8..6dfa86abc 100644 --- a/fontchooser.lua +++ b/fontchooser.lua @@ -119,6 +119,7 @@ function FontChooser:choose(ypos, height) local ev = input.waitForEvent() if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + ev.code = adjustFWKey(ev.code) if ev.code == KEY_FW_UP then prevItem() elseif ev.code == KEY_FW_DOWN then diff --git a/keys.lua b/keys.lua index b757dd5b0..eef4f37a3 100644 --- a/keys.lua +++ b/keys.lua @@ -131,3 +131,75 @@ function set_emu_keycodes() KEY_VPLUS = 95 -- F11 KEY_VMINUS = 96 -- F12 end + +function getRotationMode() + --[[ + return code for four kinds of rotation mode: + + 0 for no rotation, + 1 for landscape with bottom on the right side of screen, etc. + + 2 + ----------- + | ------- | + | | | | + | | | | + | | | | + 3 | | | | 1 + | | | | + | | | | + | ------- | + | | + ----------- + 0 + --]] + if KEY_FW_DOWN == 116 then -- in EMU mode always return 0 + return 0 + end + orie_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_orientation", "r")) + updown_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_upside_down", "r")) + mode = orie_fd:read() + (updown_fd:read() * 2) + return mode +end + +function adjustFWKey(code) + if getRotationMode() == 0 then + return code + elseif getRotationMode() == 1 then + if code == KEY_FW_UP then + return KEY_FW_RIGHT + elseif code == KEY_FW_RIGHT then + return KEY_FW_DOWN + elseif code == KEY_FW_DOWN then + return KEY_FW_LEFT + elseif code == KEY_FW_LEFT then + return KEY_FW_UP + else + return code + end + elseif getRotationMode() == 2 then + if code == KEY_FW_UP then + return KEY_FW_DOWN + elseif code == KEY_FW_RIGHT then + return KEY_FW_LEFT + elseif code == KEY_FW_DOWN then + return KEY_FW_UP + elseif code == KEY_FW_LEFT then + return KEY_FW_RIGHT + else + return code + end + elseif getRotationMode() == 3 then + if code == KEY_FW_UP then + return KEY_FW_LEFT + elseif code == KEY_FW_RIGHT then + return KEY_FW_UP + elseif code == KEY_FW_DOWN then + return KEY_FW_RIGHT + elseif code == KEY_FW_LEFT then + return KEY_FW_DOWN + else + return code + end + end +end From 8fdb0a4c3edcfb20ae6d5fb0e86c96e802347f7d Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 18 Feb 2012 18:21:03 +0800 Subject: [PATCH 04/28] add: demo for inputbox --- filechooser.lua | 6 +- inputbox.lua | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ keys.lua | 23 +++++++- 3 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 inputbox.lua diff --git a/filechooser.lua b/filechooser.lua index cfd8ef47c..084af48b0 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -3,6 +3,7 @@ require "keys" require "graphics" require "fontchooser" require "fileseacher" +require "inputbox" FileChooser = { -- Class vars: @@ -187,8 +188,9 @@ function FileChooser:choose(ypos, height) end pagedirty = true elseif ev.code == KEY_S then - FileSeacher:init() - FileSeacher:choose(0, height) + InputBox:input(height-100, 100) + --FileSeacher:init() + --FileSeacher:choose(0, height) pagedirty = true elseif ev.code == KEY_PGFWD then if self.page < (self.items / perpage) then diff --git a/inputbox.lua b/inputbox.lua new file mode 100644 index 000000000..d86fad050 --- /dev/null +++ b/inputbox.lua @@ -0,0 +1,153 @@ +require "rendertext" +require "keys" +require "graphics" + +InputBox = { + -- Class vars: + + -- font for displaying input content + face = freetype.newBuiltinFace("mono", 25), + fhash = "m25", + fheight = 25, + -- font for input title display + tface = freetype.newBuiltinFace("sans", 28), + tfhash = "s28", + -- spacing between lines + spacing = 40, + + input_start_x = 145, + input_start_y = nil, + input_cur_x = nil, + + input_bg = 1, + + -- state buffer + dirs = nil, + files = nil, + items = 0, + path = "", + page = 1, + current = 1, + oldcurrent = 0, +} + +function InputBox:setPath(newPath) + self.path = newPath + self:readdir() + self.items = #self.dirs + #self.files + if self.items == 0 then + return nil + end + self.page = 1 + self.current = 1 + return true +end + +function InputBox:addChar(text) + renderUtf8Text(fb.bb, self.input_cur_x, self.input_start_y, + self.face, self.fhash, text, true) + fb:refresh(1, self.input_cur_x, self.input_start_y-19, 16, self.fheight) + self.input_cur_x = self.input_cur_x + 16 +end + +function InputBox:delChar() + if self.input_start_x == self.input_cur_x then + return + end + self.input_cur_x = self.input_cur_x - 16 + --fill last character with blank rectangle + fb.bb:paintRect(self.input_cur_x, self.input_start_y-19, 16, self.fheight, self.input_bg) + fb:refresh(1, self.input_cur_x, self.input_start_y-19, 16, self.fheight) +end + +function InputBox:input(ypos, height) + local pagedirty = true + self.input_start_y = ypos + 35 + self.input_cur_x = self.input_start_x + + while true do + if pagedirty then + w = fb.bb:getWidth() - 40 + h = height - 45 + -- draw input border + fb.bb:paintRect(20, ypos, w, h, 5) + -- draw input slot + fb.bb:paintRect(140, ypos + 10, w - 130, h - 20, self.input_bg) + renderUtf8Text(fb.bb, 35, self.input_start_y, self.face, self.fhash, + "Search:", true) + markerdirty = true + end + + if pagedirty then + fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) + pagedirty = false + end + + local ev = input.waitForEvent() + if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + print("key code:"..ev.code) + --ev.code = adjustFWKey(ev.code) + if ev.code == KEY_FW_UP then + elseif ev.code == KEY_FW_DOWN then + elseif ev.code == KEY_A then + self:addChar("a") + elseif ev.code == KEY_B then + self:addChar("b") + elseif ev.code == KEY_C then + self:addChar("c") + elseif ev.code == KEY_D then + self:addChar("d") + elseif ev.code == KEY_E then + self:addChar("e") + elseif ev.code == KEY_F then + self:addChar("f") + elseif ev.code == KEY_G then + self:addChar("g") + elseif ev.code == KEY_H then + self:addChar("h") + elseif ev.code == KEY_I then + self:addChar("i") + elseif ev.code == KEY_J then + self:addChar("j") + elseif ev.code == KEY_K then + self:addChar("k") + elseif ev.code == KEY_L then + self:addChar("l") + elseif ev.code == KEY_M then + self:addChar("m") + elseif ev.code == KEY_N then + self:addChar("n") + elseif ev.code == KEY_O then + self:addChar("o") + elseif ev.code == KEY_P then + self:addChar("p") + elseif ev.code == KEY_Q then + self:addChar("q") + elseif ev.code == KEY_R then + self:addChar("r") + elseif ev.code == KEY_S then + self:addChar("s") + elseif ev.code == KEY_T then + self:addChar("t") + elseif ev.code == KEY_U then + self:addChar("u") + elseif ev.code == KEY_V then + self:addChar("v") + elseif ev.code == KEY_W then + self:addChar("w") + elseif ev.code == KEY_X then + self:addChar("x") + elseif ev.code == KEY_Y then + self:addChar("y") + elseif ev.code == KEY_Z then + self:addChar("z") + elseif ev.code == KEY_PGFWD then + elseif ev.code == KEY_PGBCK then + elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then + pagedirty = true + elseif ev.code == KEY_BACK then + self:delChar() + end + end + end +end diff --git a/keys.lua b/keys.lua index b757dd5b0..ee43be603 100644 --- a/keys.lua +++ b/keys.lua @@ -118,13 +118,34 @@ function set_emu_keycodes() KEY_ENTER = 36 + KEY_Q = 24 + KEY_W = 25 + KEY_E = 26 + KEY_R = 27 + KEY_T = 28 + KEY_Y = 29 + KEY_U = 30 + KEY_I = 31 + KEY_O = 32 + KEY_P = 33 + KEY_A = 38 KEY_S = 39 KEY_D = 40 KEY_F = 41 - + KEY_G = 42 + KEY_H = 43 KEY_J = 44 KEY_K = 45 + KEY_L = 46 + + KEY_Z = 52 + KEY_X = 53 + KEY_C = 54 + KEY_V = 55 + KEY_B = 56 + KEY_N = 57 + KEY_M = 58 KEY_SHIFT = 50 -- left shift KEY_ALT = 64 -- left alt From 3bc71354ed9b5ff33e72407a4de9b2c9bc21da35 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 18 Feb 2012 20:07:28 +0800 Subject: [PATCH 05/28] mod: add KEY_DEL for EMU mode --- keys.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/keys.lua b/keys.lua index ee43be603..8b93d90f8 100644 --- a/keys.lua +++ b/keys.lua @@ -109,6 +109,7 @@ function set_emu_keycodes() KEY_PGFWD = 117 KEY_PGBCK = 112 KEY_BACK = 22 -- backspace + KEY_DEL = 119 -- Delete KEY_MENU = 67 -- F1 KEY_FW_UP = 111 KEY_FW_DOWN = 116 From 29a9996fb226525498cd1261115d5d9aebe64844 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 18 Feb 2012 20:32:38 +0800 Subject: [PATCH 06/28] mod: inputbox finished --- filechooser.lua | 5 +++-- inputbox.lua | 13 ++++++++++--- keys.lua | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index 084af48b0..6137863b4 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -2,7 +2,7 @@ require "rendertext" require "keys" require "graphics" require "fontchooser" -require "fileseacher" +require "filesearcher" require "inputbox" FileChooser = { @@ -188,7 +188,8 @@ function FileChooser:choose(ypos, height) end pagedirty = true elseif ev.code == KEY_S then - InputBox:input(height-100, 100) + input = InputBox:input(height-100, 100) + print(input) --FileSeacher:init() --FileSeacher:choose(0, height) pagedirty = true diff --git a/inputbox.lua b/inputbox.lua index d86fad050..a8647adc9 100644 --- a/inputbox.lua +++ b/inputbox.lua @@ -21,6 +21,7 @@ InputBox = { input_bg = 1, + input_string = "", -- state buffer dirs = nil, files = nil, @@ -48,6 +49,7 @@ function InputBox:addChar(text) self.face, self.fhash, text, true) fb:refresh(1, self.input_cur_x, self.input_start_y-19, 16, self.fheight) self.input_cur_x = self.input_cur_x + 16 + self.input_string = self.input_string .. text end function InputBox:delChar() @@ -58,6 +60,7 @@ function InputBox:delChar() --fill last character with blank rectangle fb.bb:paintRect(self.input_cur_x, self.input_start_y-19, 16, self.fheight, self.input_bg) fb:refresh(1, self.input_cur_x, self.input_start_y-19, 16, self.fheight) + self.input_string = self.input_string:sub(0,-2) end function InputBox:input(ypos, height) @@ -79,7 +82,7 @@ function InputBox:input(ypos, height) end if pagedirty then - fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) + fb:refresh(1, 20, ypos, w, h) pagedirty = false end @@ -141,12 +144,16 @@ function InputBox:input(ypos, height) self:addChar("y") elseif ev.code == KEY_Z then self:addChar("z") + elseif ev.code == KEY_SPACE then + self:addChar(" ") elseif ev.code == KEY_PGFWD then elseif ev.code == KEY_PGBCK then elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - pagedirty = true - elseif ev.code == KEY_BACK then + return self.input_string + elseif ev.code == KEY_DEL then self:delChar() + elseif ev.code == KEY_BACK then + return "" end end end diff --git a/keys.lua b/keys.lua index 8b93d90f8..eb932176a 100644 --- a/keys.lua +++ b/keys.lua @@ -116,6 +116,7 @@ function set_emu_keycodes() KEY_FW_LEFT = 113 KEY_FW_RIGHT = 114 KEY_FW_PRESS = 36 -- enter for now + KEY_SPACE = 65 KEY_ENTER = 36 From 85fedef7a4968bd6212340fd1ee9b05cd6a0b35b Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 18 Feb 2012 20:35:03 +0800 Subject: [PATCH 07/28] add: filesearcher --- filesearcher.lua | 179 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 filesearcher.lua diff --git a/filesearcher.lua b/filesearcher.lua new file mode 100644 index 000000000..3f819e941 --- /dev/null +++ b/filesearcher.lua @@ -0,0 +1,179 @@ +require "rendertext" +require "keys" +require "graphics" +require "fontchooser" +require "inputbox" + +FileSearcher = { + -- Class vars: + + -- font for displaying file/dir names + face = freetype.newBuiltinFace("sans", 25), + fhash = "s25", + -- font for paging display + sface = freetype.newBuiltinFace("sans", 16), + sfhash = "s16", + -- spacing between lines + spacing = 40, + + -- state buffer + dirs = nil, + files = nil, + items = 0, + path = "", + page = 1, + current = 1, + oldcurrent = 0, +} + +function FileSearcher:readdir() + self.dirs = {} + self.files = {} + for f in lfs.dir(self.path) do + if lfs.attributes(self.path.."/"..f, "mode") == "directory" and f ~= "." and not string.match(f, "^%.[^.]") then + table.insert(self.dirs, f) + elseif string.match(f, ".+%.[pP][dD][fF]$") then + table.insert(self.files, f) + end + end + table.sort(self.dirs) + table.sort(self.files) +end + +function FileSearcher:setPath(newPath) + self.path = newPath + self:readdir() + self.items = #self.dirs + #self.files + if self.items == 0 then + return nil + end + self.page = 1 + self.current = 1 + return true +end + + +function FileSearcher:choose(ypos, height) + local perpage = math.floor(height / self.spacing) - 1 + local pagedirty = true + local markerdirty = false + + local prevItem = function () + if self.current == 1 then + if self.page > 1 then + self.current = perpage + self.page = self.page - 1 + pagedirty = true + end + else + self.current = self.current - 1 + markerdirty = true + end + end + + local nextItem = function () + if self.current == perpage then + if self.page < (self.items / perpage) then + self.current = 1 + self.page = self.page + 1 + pagedirty = true + end + else + if self.page ~= math.floor(self.items / perpage) + 1 + or self.current + (self.page-1)*perpage < self.items then + self.current = self.current + 1 + markerdirty = true + end + end + end + + while true do + if pagedirty then + fb.bb:paintRect(0, ypos, fb.bb:getWidth(), height, 0) + local c + for c = 1, perpage do + 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) + elseif i <= self.items then + renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, self.face, self.fhash, self.files[i-#self.dirs], true) + end + end + renderUtf8Text(fb.bb, 39, ypos + self.spacing * perpage + 32, self.sface, self.sfhash, + "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) + markerdirty = true + end + if markerdirty then + if not pagedirty then + if self.oldcurrent > 0 then + fb.bb:paintRect(30, ypos + self.spacing*self.oldcurrent + 10, fb.bb:getWidth() - 60, 3, 0) + fb:refresh(1, 30, ypos + self.spacing*self.oldcurrent + 10, fb.bb:getWidth() - 60, 3) + end + end + fb.bb:paintRect(30, ypos + self.spacing*self.current + 10, fb.bb:getWidth() - 60, 3, 15) + if not pagedirty then + fb:refresh(1, 30, ypos + self.spacing*self.current + 10, fb.bb:getWidth() - 60, 3) + end + self.oldcurrent = self.current + markerdirty = false + end + if pagedirty then + fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) + pagedirty = false + end + local ev = input.waitForEvent() + if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + ev.code = adjustFWKey(ev.code) + if ev.code == KEY_FW_UP then + prevItem() + elseif ev.code == KEY_FW_DOWN then + nextItem() + elseif ev.code == KEY_F then + FontChooser:init() + newfont = FontChooser:choose(0, height) + if newfont ~= nil then + self.face = freetype.newBuiltinFace(newfont, 25) + clearglyphcache() + end + pagedirty = true + elseif ev.code == KEY_S then + InputBox:input() + elseif ev.code == KEY_PGFWD then + if self.page < (self.items / perpage) then + if self.current + self.page*perpage > self.items then + self.current = self.items - self.page*perpage + end + self.page = self.page + 1 + pagedirty = true + else + self.current = self.items - (self.page-1)*perpage + markerdirty = true + end + elseif ev.code == KEY_PGBCK then + if self.page > 1 then + self.page = self.page - 1 + pagedirty = true + else + self.current = 1 + markerdirty = true + end + elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then + local newdir = self.dirs[perpage*(self.page-1)+self.current] + if newdir == ".." then + local path = string.gsub(self.path, "(.*)/[^/]+/?$", "%1") + self:setPath(path) + elseif newdir then + local path = self.path.."/"..newdir + self:setPath(path) + else + return self.path.."/"..self.files[perpage*(self.page-1)+self.current - #self.dirs] + end + pagedirty = true + elseif ev.code == KEY_BACK then + return nil + end + end + end +end From 32d1bede8c6b0de974f81e333ba50163be101723 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 19 Feb 2012 07:21:50 +0800 Subject: [PATCH 08/28] start working on filesearcher --- filechooser.lua | 13 ++-- fileseacher.lua | 161 ----------------------------------------------- filesearcher.lua | 114 +++++++++++++-------------------- inputbox.lua | 12 ++-- 4 files changed, 61 insertions(+), 239 deletions(-) delete mode 100644 fileseacher.lua diff --git a/filechooser.lua b/filechooser.lua index 6137863b4..ecec641a3 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -188,10 +188,15 @@ function FileChooser:choose(ypos, height) end pagedirty = true elseif ev.code == KEY_S then - input = InputBox:input(height-100, 100) - print(input) - --FileSeacher:init() - --FileSeacher:choose(0, height) + keywords = InputBox:input(height-100, 100, "Search:") + if keywords then + -- display search result according to keywords + FileSearcher:init() + file = FileSearcher:choose(ypos, height, keywords) + if file then + return file + end + end pagedirty = true elseif ev.code == KEY_PGFWD then if self.page < (self.items / perpage) then diff --git a/fileseacher.lua b/fileseacher.lua deleted file mode 100644 index 137ce4621..000000000 --- a/fileseacher.lua +++ /dev/null @@ -1,161 +0,0 @@ -require "rendertext" -require "keys" -require "graphics" - -FileSeacher = { - -- font for displaying file/dir names - face = freetype.newBuiltinFace("sans", 25), - fhash = "s25", - -- font for page title - tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 32), - tfhash = "hbo32", - -- font for paging display - sface = freetype.newBuiltinFace("sans", 16), - sfhash = "s16", - -- title height - title_H = 45, - -- spacing between lines - spacing = 40, - -- foot height - foot_H = 27, - - x_input = 50, - -- state buffer - fonts = {"sans", "cjk", "mono", - "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", - "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", - "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, - items = 14, - page = 1, - current = 2, - oldcurrent = 1, -} - -function FileSeacher:init() - self.items = #self.fonts - --@TODO check this 17.02 2012 - self.face = freetype.newBuiltinFace("sans", 25), - table.sort(self.fonts) -end - - -function FileSeacher:choose(ypos, height) - local perpage = math.floor(height / self.spacing) - 2 - local pagedirty = true - local markerdirty = false - - local prevItem = function () - if self.current == 1 then - if self.page > 1 then - self.current = perpage - self.page = self.page - 1 - pagedirty = true - end - else - self.current = self.current - 1 - markerdirty = true - end - end - - local nextItem = function () - if self.current == perpage then - if self.page < (self.items / perpage) then - self.current = 1 - self.page = self.page + 1 - pagedirty = true - end - else - if self.page ~= math.floor(self.items / perpage) + 1 - or self.current + (self.page-1)*perpage < self.items then - self.current = self.current + 1 - markerdirty = true - end - end - end - - - while true do - if pagedirty then - 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, - "[ Fonts Menu ]", true) - - local c - for c = 1, perpage do - 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, self.fonts[i], true) - end - end - y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H - x = (fb.bb:getWidth() / 2) - 50 - renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, - "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) - markerdirty = true - end - - if markerdirty then - if not pagedirty then - if self.oldcurrent > 0 then - y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 10 - fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) - fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) - end - end - -- draw new marker line - y = ypos + self.title_H + (self.spacing * self.current) + 10 - fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) - if not pagedirty then - fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) - end - self.oldcurrent = self.current - markerdirty = false - end - - if pagedirty then - fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) - pagedirty = false - end - - local ev = input.waitForEvent() - if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then - if ev.code == KEY_FW_UP then - prevItem() - elseif ev.code == KEY_FW_DOWN then - nextItem() - elseif ev.code == KEY_PGFWD then - if self.page < (self.items / perpage) then - if self.current + self.page*perpage > self.items then - self.current = self.items - self.page*perpage - end - self.page = self.page + 1 - pagedirty = true - else - self.current = self.items - (self.page-1)*perpage - markerdirty = true - end - elseif ev.code == KEY_PGBCK then - if self.page > 1 then - self.page = self.page - 1 - pagedirty = true - else - self.current = 1 - markerdirty = true - end - elseif ev.code == KEY_F then - self.x_input = self.x_input + 10 - y = ypos + self.title_H + (self.spacing) - renderUtf8Text(fb.bb, self.x_input, y, self.face, self.fhash, "f", true) - fb:refresh(1, x_input, ypos, fb.bb:getWidth(), height) - elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - local newface = self.fonts[perpage*(self.page-1)+self.current] - return newface - elseif ev.code == KEY_BACK then - return nil - end - end - end -end diff --git a/filesearcher.lua b/filesearcher.lua index 3f819e941..ac37e5dfe 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -1,60 +1,43 @@ require "rendertext" require "keys" require "graphics" -require "fontchooser" -require "inputbox" FileSearcher = { - -- Class vars: - -- font for displaying file/dir names face = freetype.newBuiltinFace("sans", 25), fhash = "s25", + -- font for page title + tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 32), + tfhash = "hbo32", -- font for paging display sface = freetype.newBuiltinFace("sans", 16), sfhash = "s16", + -- title height + title_H = 45, -- spacing between lines spacing = 40, + -- foot height + foot_H = 27, -- state buffer - dirs = nil, - files = nil, - items = 0, - path = "", + fonts = {"sans", "cjk", "mono", + "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", + "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", + "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, + items = 14, page = 1, - current = 1, - oldcurrent = 0, + current = 2, + oldcurrent = 1, } -function FileSearcher:readdir() - self.dirs = {} - self.files = {} - for f in lfs.dir(self.path) do - if lfs.attributes(self.path.."/"..f, "mode") == "directory" and f ~= "." and not string.match(f, "^%.[^.]") then - table.insert(self.dirs, f) - elseif string.match(f, ".+%.[pP][dD][fF]$") then - table.insert(self.files, f) - end - end - table.sort(self.dirs) - table.sort(self.files) -end - -function FileSearcher:setPath(newPath) - self.path = newPath - self:readdir() - self.items = #self.dirs + #self.files - if self.items == 0 then - return nil - end - self.page = 1 - self.current = 1 - return true +function FileSearcher:init() + self.items = #self.fonts + table.sort(self.fonts) end -function FileSearcher:choose(ypos, height) - local perpage = math.floor(height / self.spacing) - 1 +function FileSearcher:choose(ypos, height, keywords) + local perpage = math.floor(height / self.spacing) - 2 local pagedirty = true local markerdirty = false @@ -87,59 +70,59 @@ function FileSearcher:choose(ypos, height) end end + while true do if pagedirty then 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, + "Search Result for "..keywords, true) + local c for c = 1, perpage do - 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) - elseif i <= self.items then - renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, self.face, self.fhash, self.files[i-#self.dirs], true) + 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, self.fonts[i], true) end end - renderUtf8Text(fb.bb, 39, ypos + self.spacing * perpage + 32, self.sface, self.sfhash, + y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H + x = (fb.bb:getWidth() / 2) - 50 + renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) markerdirty = true end + if markerdirty then if not pagedirty then if self.oldcurrent > 0 then - fb.bb:paintRect(30, ypos + self.spacing*self.oldcurrent + 10, fb.bb:getWidth() - 60, 3, 0) - fb:refresh(1, 30, ypos + self.spacing*self.oldcurrent + 10, fb.bb:getWidth() - 60, 3) + y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 10 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) end end - fb.bb:paintRect(30, ypos + self.spacing*self.current + 10, fb.bb:getWidth() - 60, 3, 15) + -- draw new marker line + y = ypos + self.title_H + (self.spacing * self.current) + 10 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) if not pagedirty then - fb:refresh(1, 30, ypos + self.spacing*self.current + 10, fb.bb:getWidth() - 60, 3) + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) end self.oldcurrent = self.current markerdirty = false end + if pagedirty then fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) pagedirty = false end + local ev = input.waitForEvent() if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then - ev.code = adjustFWKey(ev.code) if ev.code == KEY_FW_UP then prevItem() elseif ev.code == KEY_FW_DOWN then nextItem() - elseif ev.code == KEY_F then - FontChooser:init() - newfont = FontChooser:choose(0, height) - if newfont ~= nil then - self.face = freetype.newBuiltinFace(newfont, 25) - clearglyphcache() - end - pagedirty = true - elseif ev.code == KEY_S then - InputBox:input() elseif ev.code == KEY_PGFWD then if self.page < (self.items / perpage) then if self.current + self.page*perpage > self.items then @@ -160,17 +143,8 @@ function FileSearcher:choose(ypos, height) markerdirty = true end elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - local newdir = self.dirs[perpage*(self.page-1)+self.current] - if newdir == ".." then - local path = string.gsub(self.path, "(.*)/[^/]+/?$", "%1") - self:setPath(path) - elseif newdir then - local path = self.path.."/"..newdir - self:setPath(path) - else - return self.path.."/"..self.files[perpage*(self.page-1)+self.current - #self.dirs] - end - pagedirty = true + local newface = self.fonts[perpage*(self.page-1)+self.current] + return newface elseif ev.code == KEY_BACK then return nil end diff --git a/inputbox.lua b/inputbox.lua index a8647adc9..aaf2a5f9c 100644 --- a/inputbox.lua +++ b/inputbox.lua @@ -63,7 +63,7 @@ function InputBox:delChar() self.input_string = self.input_string:sub(0,-2) end -function InputBox:input(ypos, height) +function InputBox:input(ypos, height, title) local pagedirty = true self.input_start_y = ypos + 35 self.input_cur_x = self.input_start_x @@ -77,7 +77,7 @@ function InputBox:input(ypos, height) -- draw input slot fb.bb:paintRect(140, ypos + 10, w - 130, h - 20, self.input_bg) renderUtf8Text(fb.bb, 35, self.input_start_y, self.face, self.fhash, - "Search:", true) + title, true) markerdirty = true end @@ -149,11 +149,15 @@ function InputBox:input(ypos, height) elseif ev.code == KEY_PGFWD then elseif ev.code == KEY_PGBCK then elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - return self.input_string + if self.input_string == "" then + return nil + else + return self.input_string + end elseif ev.code == KEY_DEL then self:delChar() elseif ev.code == KEY_BACK then - return "" + return nil end end end From f9804a1c9258857f83c2c09aa6370b20ea261cab Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 19 Feb 2012 09:54:52 +0800 Subject: [PATCH 09/28] searcher demo finished! waiting for refractory. --- filechooser.lua | 1 + filesearcher.lua | 72 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index ecec641a3..19ca9d382 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -188,6 +188,7 @@ function FileChooser:choose(ypos, height) end pagedirty = true elseif ev.code == KEY_S then + -- invoke search input keywords = InputBox:input(height-100, 100, "Search:") if keywords then -- display search result according to keywords diff --git a/filesearcher.lua b/filesearcher.lua index ac37e5dfe..59fffb5e9 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -19,7 +19,11 @@ FileSearcher = { -- foot height foot_H = 27, + x_input = 50, -- state buffer + dirs = {}, + files = {}, + result = {}, fonts = {"sans", "cjk", "mono", "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", @@ -30,9 +34,53 @@ FileSearcher = { oldcurrent = 1, } -function FileSearcher:init() - self.items = #self.fonts - table.sort(self.fonts) +function FileSearcher:readdir() + self.dirs = {self.path} + self.files = {} + while #self.dirs ~= 0 do + new_dirs = {} + -- handle each dir + for __, d in pairs(self.dirs) do + -- handle files in d + for f in lfs.dir(d) do + if lfs.attributes(self.path.."/"..f, "mode") == "directory" + and f ~= "." and f~= ".." and not string.match(f, "^%.[^.]") then + table.insert(new_dirs, d.."/"..f) + elseif string.match(f, ".+%.[pP][dD][fF]$") then + file_entry = {dir=d, name=f,} + table.insert(self.files, file_entry) + --print("file:"..d.."/"..f) + end + end + end + self.dirs = new_dirs + end +end + +function FileSearcher:setPath(newPath) + self.path = newPath + self:readdir() + self.items = #self.files + --@TODO check none found 19.02 2012 + if self.items == 0 then + return nil + end + self.page = 1 + self.current = 1 + return true +end + +function FileSearcher:setSearchResult(keywords) + self.result = self.files + self.items = #self.result + self.page = 1 + self.current = 1 +end + +function FileSearcher:init(keywords) + self:setPath("/home/dave/documents/kindle/backup/documents") + self:setSearchResult(keywords) + --@TODO check this 17.02 2012 end @@ -77,20 +125,25 @@ function FileSearcher:choose(ypos, height, keywords) -- draw menu title renderUtf8Text(fb.bb, 30, ypos + self.title_H, self.tface, self.tfhash, - "Search Result for "..keywords, true) + "Search Result for"..keywords, true) + -- draw results local c for c = 1, perpage do 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, self.fonts[i], true) + renderUtf8Text(fb.bb, 50, y, self.face, self.fhash, + self.result[i].name, true) end end + + -- draw footer 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.sface, self.sfhash, - "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) + "Page "..self.page.." of "..all_page, true) markerdirty = true end @@ -142,9 +195,12 @@ function FileSearcher:choose(ypos, height, keywords) self.current = 1 markerdirty = true end + elseif ev.code == KEY_S then + input = InputBox:input(height-100, 100) elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - local newface = self.fonts[perpage*(self.page-1)+self.current] - return newface + -- return full file path + file_entry = self.files[perpage*(self.page-1)+self.current] + return file_entry.dir .. "/" .. file_entry.name elseif ev.code == KEY_BACK then return nil end From 060ad5cb01a88966ee57d331e448ef6b2016c71a Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 19 Feb 2012 14:41:44 +0800 Subject: [PATCH 10/28] finished search feature! --- filechooser.lua | 10 ++++- filesearcher.lua | 67 ++++++++++++++++++++---------- inputbox.lua | 106 +++++++++++++++++++++++++---------------------- 3 files changed, 110 insertions(+), 73 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index 19ca9d382..bd2fedbbc 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -190,8 +190,14 @@ function FileChooser:choose(ypos, height) elseif ev.code == KEY_S then -- invoke search input keywords = InputBox:input(height-100, 100, "Search:") - if keywords then - -- display search result according to keywords + if keywords then -- display search result according to keywords + --[[ + ---------------------------------------------------------------- + || uncomment following line and set the correct path if you want + || to test search feature in EMU mode + ---------------------------------------------------------------- + --]] + --FileSearcher:init("/home/dave/documents/kindle/backup/documents") FileSearcher:init() file = FileSearcher:choose(ypos, height, keywords) if file then diff --git a/filesearcher.lua b/filesearcher.lua index 59fffb5e9..d59e0cd49 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -19,18 +19,13 @@ FileSearcher = { -- foot height foot_H = 27, - x_input = 50, -- state buffer dirs = {}, files = {}, result = {}, - fonts = {"sans", "cjk", "mono", - "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", - "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", - "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, - items = 14, - page = 1, - current = 2, + items = 0, + page = 0, + current = 1, oldcurrent = 1, } @@ -71,16 +66,27 @@ function FileSearcher:setPath(newPath) end function FileSearcher:setSearchResult(keywords) - self.result = self.files + self.result = {} + if keywords == " " then -- one space to show all files + self.result = self.files + else + for __,f in pairs(self.files) do + if string.find(string.lower(f.name), keywords) then + table.insert(self.result, f) + end + end + end self.items = #self.result self.page = 1 self.current = 1 end -function FileSearcher:init(keywords) - self:setPath("/home/dave/documents/kindle/backup/documents") - self:setSearchResult(keywords) - --@TODO check this 17.02 2012 +function FileSearcher:init(search_path) + if search_path then + self:setPath(search_path) + else + self:setPath("/mnt/us/documents") + end end @@ -118,23 +124,34 @@ function FileSearcher:choose(ypos, height, keywords) end end + self:setSearchResult(keywords) while true do 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, - "Search Result for"..keywords, true) + "Search Result for: "..keywords, true) -- draw results local c - for c = 1, perpage do - 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, - self.result[i].name, true) + if self.items == 0 then -- nothing found + y = ypos + self.title_H + self.spacing * 2 + renderUtf8Text(fb.bb, 20, y, self.face, self.fhash, + "Sorry, your keyword did not match any documents.", true) + renderUtf8Text(fb.bb, 20, y + self.spacing, self.face, self.fhash, + "Please try a different keyword.", true) + markerdirty = false + else -- found something, draw it + for c = 1, perpage do + 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, + self.result[i].name, true) + end end end @@ -144,7 +161,6 @@ function FileSearcher:choose(ypos, height, keywords) all_page = (math.floor(self.items / perpage)+1) renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, "Page "..self.page.." of "..all_page, true) - markerdirty = true end if markerdirty then @@ -196,7 +212,14 @@ function FileSearcher:choose(ypos, height, keywords) markerdirty = true end elseif ev.code == KEY_S then - input = InputBox:input(height-100, 100) + old_keywords = keywords + keywords = InputBox:input(height-100, 100, "Search:", old_keywords) + if keywords then + self:setSearchResult(keywords) + else + keywords = old_keywords + end + pagedirty = true elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then -- return full file path file_entry = self.files[perpage*(self.page-1)+self.current] diff --git a/inputbox.lua b/inputbox.lua index aaf2a5f9c..2c50d6882 100644 --- a/inputbox.lua +++ b/inputbox.lua @@ -4,84 +4,92 @@ require "graphics" InputBox = { -- Class vars: - - -- font for displaying input content - face = freetype.newBuiltinFace("mono", 25), - fhash = "m25", - fheight = 25, - -- font for input title display - tface = freetype.newBuiltinFace("sans", 28), - tfhash = "s28", - -- spacing between lines - spacing = 40, - input_start_x = 145, input_start_y = nil, - input_cur_x = nil, + input_cur_x = nil, -- points to the start of next input pos input_bg = 1, input_string = "", - -- state buffer - dirs = nil, - files = nil, - items = 0, - path = "", - page = 1, - current = 1, - oldcurrent = 0, + + -- font for displaying input content + face = freetype.newBuiltinFace("mono", 25), + fhash = "m25", + fheight = 25, + fwidth = 16, } -function InputBox:setPath(newPath) - self.path = newPath - self:readdir() - self.items = #self.dirs + #self.files - if self.items == 0 then - return nil +function InputBox:setDefaultInput(text) + self.input_string = "" + self:addString(text) + --renderUtf8Text(fb.bb, self.input_start_x, self.input_start_y, + --self.face, self.fhash, text, true) + --self.input_cur_x = self.input_start_x + (string.len(text) * self.fwidth) + --self.input_string = text +end + +function InputBox:addString(str) + for i = 1, #str do + self:addChar(str:sub(i,i)) end - self.page = 1 - self.current = 1 - return true end -function InputBox:addChar(text) - renderUtf8Text(fb.bb, self.input_cur_x, self.input_start_y, - self.face, self.fhash, text, true) - fb:refresh(1, self.input_cur_x, self.input_start_y-19, 16, self.fheight) - self.input_cur_x = self.input_cur_x + 16 - self.input_string = self.input_string .. text +function InputBox:addChar(char) + renderUtf8Text(fb.bb, self.input_cur_x, self.input_start_y, self.face, self.fhash, + char, true) + fb:refresh(1, self.input_cur_x, self.input_start_y-19, self.fwidth, self.fheight) + self.input_cur_x = self.input_cur_x + self.fwidth + self.input_string = self.input_string .. char end function InputBox:delChar() if self.input_start_x == self.input_cur_x then return end - self.input_cur_x = self.input_cur_x - 16 + self.input_cur_x = self.input_cur_x - self.fwidth --fill last character with blank rectangle - fb.bb:paintRect(self.input_cur_x, self.input_start_y-19, 16, self.fheight, self.input_bg) - fb:refresh(1, self.input_cur_x, self.input_start_y-19, 16, self.fheight) + fb.bb:paintRect(self.input_cur_x, self.input_start_y-19, + self.fwidth, self.fheight, self.input_bg) + fb:refresh(1, self.input_cur_x, self.input_start_y-19, self.fwidth, self.fheight) self.input_string = self.input_string:sub(0,-2) end -function InputBox:input(ypos, height, title) +function InputBox:drawBox(ypos, w, h, title) + -- draw input border + fb.bb:paintRect(20, ypos, w, h, 5) + -- draw input slot + fb.bb:paintRect(140, ypos + 10, w - 130, h - 20, self.input_bg) + -- draw input title + renderUtf8Text(fb.bb, 35, self.input_start_y, self.face, self.fhash, + title, true) +end + + +--[[ + || d_text default to nil (used to set default text in input slot) +--]] +function InputBox:input(ypos, height, title, d_text) local pagedirty = true + -- do some initilization self.input_start_y = ypos + 35 self.input_cur_x = self.input_start_x + if d_text then -- if specified default text, draw it + w = fb.bb:getWidth() - 40 + h = height - 45 + self:drawBox(ypos, w, h, title) + self:setDefaultInput(d_text) + fb:refresh(1, 20, ypos, w, h) + pagedirty = false + else -- otherwise, leave the draw task to the main loop + self.input_string = "" + end + while true do if pagedirty then w = fb.bb:getWidth() - 40 h = height - 45 - -- draw input border - fb.bb:paintRect(20, ypos, w, h, 5) - -- draw input slot - fb.bb:paintRect(140, ypos + 10, w - 130, h - 20, self.input_bg) - renderUtf8Text(fb.bb, 35, self.input_start_y, self.face, self.fhash, - title, true) - markerdirty = true - end - - if pagedirty then + self:drawBox(ypos, w, h, title) fb:refresh(1, 20, ypos, w, h) pagedirty = false end From e5769a4cc01fd0614f8d1f87ddd9ec17c8d8598a Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 19 Feb 2012 19:08:53 +0800 Subject: [PATCH 11/28] fix: a foolish bug that open wrong file --- filesearcher.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filesearcher.lua b/filesearcher.lua index 5193a9056..11ce1882b 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -223,7 +223,7 @@ function FileSearcher:choose(ypos, height, keywords) pagedirty = true elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then -- return full file path - file_entry = self.files[perpage*(self.page-1)+self.current] + file_entry = self.result[perpage*(self.page-1)+self.current] return file_entry.dir .. "/" .. file_entry.name elseif ev.code == KEY_BACK then return nil From 91dd1a13c8ca74f2c957e5313b19daffb2f6da50 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 19 Feb 2012 19:51:08 +0800 Subject: [PATCH 12/28] mod: add number keys in inputbox --- inputbox.lua | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/inputbox.lua b/inputbox.lua index 4ef3ee8d1..e88b934b8 100644 --- a/inputbox.lua +++ b/inputbox.lua @@ -12,6 +12,9 @@ InputBox = { input_string = "", + shiftmode = false, + altmode = false, + -- font for displaying input content face = freetype.newBuiltinFace("mono", 25), fhash = "m25", @@ -96,9 +99,13 @@ function InputBox:input(ypos, height, title, d_text) local ev = input.waitForEvent() if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then - --print("key code:"..ev.code) ev.code = adjustFWKey(ev.code) - if ev.code == KEY_FW_UP then + --local secs, usecs = util.gettime() + if ev.code == KEY_SHIFT then + self.shiftmode = true + elseif ev.code == KEY_ALT then + self.altmode = true + elseif ev.code == KEY_FW_UP then elseif ev.code == KEY_FW_DOWN then elseif ev.code == KEY_A then self:addChar("a") @@ -152,6 +159,26 @@ function InputBox:input(ypos, height, title, d_text) self:addChar("y") elseif ev.code == KEY_Z then self:addChar("z") + elseif ev.code == KEY_1 then + self:addChar("1") + elseif ev.code == KEY_2 then + self:addChar("2") + elseif ev.code == KEY_3 then + self:addChar("3") + elseif ev.code == KEY_4 then + self:addChar("4") + elseif ev.code == KEY_5 then + self:addChar("5") + elseif ev.code == KEY_6 then + self:addChar("6") + elseif ev.code == KEY_7 then + self:addChar("7") + elseif ev.code == KEY_8 then + self:addChar("8") + elseif ev.code == KEY_9 then + self:addChar("9") + elseif ev.code == KEY_0 then + self:addChar("0") elseif ev.code == KEY_SPACE then self:addChar(" ") elseif ev.code == KEY_PGFWD then @@ -167,6 +194,16 @@ function InputBox:input(ypos, height, title, d_text) elseif ev.code == KEY_BACK then return nil end + + --local nsecs, nusecs = util.gettime() + --local dur = (nsecs - secs) * 1000000 + nusecs - usecs + --print("E: T="..ev.type.." V="..ev.value.." C="..ev.code.." DUR="..dur) + elseif ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_RELEASE + and ev.code == KEY_SHIFT then + self.shiftmode = false + elseif ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_RELEASE + and ev.code == KEY_ALT then + self.altmode = false end end end From 83fa1485837e0e5017d4bccf1c15c19308132fd7 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 19 Feb 2012 22:30:59 +0800 Subject: [PATCH 13/28] mod: return to searcher if file is opened in searcher --- filesearcher.lua | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/filesearcher.lua b/filesearcher.lua index 11ce1882b..367486cd1 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -124,7 +124,11 @@ function FileSearcher:choose(ypos, height, keywords) end end - self:setSearchResult(keywords) + -- if given keywords, set new result according to keywords. + -- Otherwise, display the previous search result. + if keywords then + self:setSearchResult(keywords) + end while true do if pagedirty then @@ -222,9 +226,15 @@ function FileSearcher:choose(ypos, height, keywords) end pagedirty = true elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - -- return full file path file_entry = self.result[perpage*(self.page-1)+self.current] - return file_entry.dir .. "/" .. file_entry.name + file_path = file_entry.dir .. "/" .. file_entry.name + + if PDFReader:open(file_path,"") then -- TODO: query for password + PDFReader:goto(tonumber(PDFReader.settings:readsetting("last_page") or 1)) + PDFReader:inputloop() + end + + pagedirty = true elseif ev.code == KEY_BACK then return nil end From 9f69c4be20a38583cd928644c47c1f5165aae380 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Tue, 21 Feb 2012 21:27:47 +0800 Subject: [PATCH 14/28] fix: fill space above title background --- fontchooser.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/fontchooser.lua b/fontchooser.lua index 9084368f1..a1acf08cc 100644 --- a/fontchooser.lua +++ b/fontchooser.lua @@ -74,6 +74,7 @@ function FontChooser:choose(ypos, height) while true do if pagedirty then -- draw menu title + fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) x = fb.bb:getWidth() - 220 -- move text to the right y = ypos + self.title_H From e60242d3f6d85d4640446939f4525c5333259b77 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Tue, 21 Feb 2012 21:42:52 +0800 Subject: [PATCH 15/28] initial demo, only one level support --- pdf.c | 37 +++++++++++ pdfreader.lua | 11 ++++ tocmenu.lua | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 tocmenu.lua diff --git a/pdf.c b/pdf.c index 5841659c8..91b7ad523 100644 --- a/pdf.c +++ b/pdf.c @@ -87,6 +87,42 @@ static int getNumberOfPages(lua_State *L) { return 1; } +/* + * Return a table with (title,page) pair as entry: + * {"chapter1"=12, "chapter2"=20} + */ +static int getTableOfContent(lua_State *L) { + fz_outline *ol; + int i; + + PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); + ol = pdf_load_outline(doc->xref); + + lua_newtable(L); + i = 1; + while(ol) { + lua_pushnumber(L, i); + + /* set subtable */ + lua_newtable(L); + lua_pushstring(L, "page"); + lua_pushnumber(L, ol->dest.ld.gotor.page + 1); + lua_settable(L, -3); + lua_pushstring(L, "level"); + lua_pushnumber(L, 1); // level 1 + lua_settable(L, -3); + lua_pushstring(L, "title"); + lua_pushstring(L, ol->title); + lua_settable(L, -3); + + lua_settable(L, -3); + + i++; + ol = ol->next; + } + return 1; +} + static int newDrawContext(lua_State *L) { int rotate = luaL_optint(L, 1, 0); double zoom = luaL_optnumber(L, 2, (double) 1.0); @@ -309,6 +345,7 @@ static const struct luaL_reg pdf_func[] = { static const struct luaL_reg pdfdocument_meth[] = { {"openPage", openPage}, {"getPages", getNumberOfPages}, + {"getTOC", getTableOfContent}, {"close", closeDocument}, {"__gc", closeDocument}, {NULL, NULL} diff --git a/pdfreader.lua b/pdfreader.lua index c01d0473c..869170dea 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -1,5 +1,6 @@ require "keys" require "settings" +require "tocmenu" PDFReader = { -- "constants": @@ -335,6 +336,16 @@ function PDFReader:inputloop() self:setglobalzoommode(self.ZOOM_FIT_TO_PAGE_HEIGHT) end + elseif ev.code == KEY_T then + -- show table of content menu + toc = self.doc:getTOC() + toc_menu = TOCMenu:new(toc) + --toc_menu:dump() + no = toc_menu:choose(0, fb.bb:getHeight()) + if no then + self:goto(no) + end + elseif ev.code == KEY_J then self:setrotate( self.globalrotate + 10 ) elseif ev.code == KEY_K then diff --git a/tocmenu.lua b/tocmenu.lua new file mode 100644 index 000000000..d2146ba77 --- /dev/null +++ b/tocmenu.lua @@ -0,0 +1,169 @@ +require "rendertext" +require "keys" +require "graphics" + +TOCMenu = { + -- font for displaying file/dir names + face = freetype.newBuiltinFace("cjk", 25), + fhash = "s25", + -- font for page title + tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 25), + tfhash = "hbo25", + -- font for paging display + sface = freetype.newBuiltinFace("sans", 16), + sfhash = "s16", + -- title height + title_H = 40, + -- spacing between lines + spacing = 40, + -- foot height + foot_H = 27, + + -- state buffer + toc = {}, + items = 14, + page = 1, + current = 1, + oldcurrent = 0, +} + +function TOCMenu:new(toc) + --@TODO set font here in the future 21.02 2012 + --clearglyphcache() + instance = self + instance.toc = toc + instance.items = #toc + return instance +end + +function TOCMenu:dump() + for k,v in pairs(self.toc) do + print("TOC item: "..k) + for key,value in pairs(v) do + print(" "..key..": "..value) + end + end +end + +function TOCMenu:choose(ypos, height) + local perpage = math.floor(height / self.spacing) - 2 + local pagedirty = true + local markerdirty = false + + local prevItem = function () + if self.current == 1 then + if self.page > 1 then + self.current = perpage + self.page = self.page - 1 + pagedirty = true + end + else + self.current = self.current - 1 + markerdirty = true + end + end + + local nextItem = function () + if self.current == perpage then + if self.page < (self.items / perpage) then + self.current = 1 + self.page = self.page + 1 + pagedirty = true + end + else + if self.page ~= math.floor(self.items / perpage) + 1 + or self.current + (self.page-1)*perpage < self.items then + self.current = self.current + 1 + markerdirty = true + end + end + end + + + while true do + if pagedirty then + -- draw menu title + fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) + fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) + x = fb.bb:getWidth() - 260 -- move text to the right + y = ypos + self.title_H + renderUtf8Text(fb.bb, x, y, self.tface, self.tfhash, + "Table of Contents", true) + + -- draw font items + fb.bb:paintRect(0, ypos + self.title_H + 10, fb.bb:getWidth(), height - self.title_H, 0) + local c + for c = 1, perpage do + 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, + self.toc[i]["title"], true) + end + end + + -- draw footer + y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H + x = (fb.bb:getWidth() / 2) - 50 + renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, + "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) + markerdirty = true + end + + if markerdirty then + if not pagedirty then + if self.oldcurrent > 0 then + y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 10 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) + end + end + -- draw new marker line + y = ypos + self.title_H + (self.spacing * self.current) + 10 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) + if not pagedirty then + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) + end + self.oldcurrent = self.current + markerdirty = false + end + + if pagedirty then + fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) + pagedirty = false + end + + local ev = input.waitForEvent() + if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + ev.code = adjustFWKey(ev.code) + if ev.code == KEY_FW_UP then + prevItem() + elseif ev.code == KEY_FW_DOWN then + nextItem() + elseif ev.code == KEY_PGFWD then + if self.page < (self.items / perpage) then + if self.current + self.page*perpage > self.items then + self.current = self.items - self.page*perpage + end + self.page = self.page + 1 + pagedirty = true + else + self.current = self.items - (self.page-1)*perpage + markerdirty = true + end + elseif ev.code == KEY_PGBCK then + if self.page > 1 then + self.page = self.page - 1 + pagedirty = true + else + self.current = 1 + markerdirty = true + end + elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then + return self.toc[perpage*(self.page-1)+self.current]["page"] + elseif ev.code == KEY_BACK then + return nil + end + end + end +end From ea498e7a5a21628f591c623d67e7080397f51a19 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Tue, 21 Feb 2012 22:30:02 +0800 Subject: [PATCH 16/28] add: toc menu --- pdf.c | 41 ++++++++++++++++++++++++++--------------- pdfreader.lua | 2 ++ tocmenu.lua | 10 +++++----- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/pdf.c b/pdf.c index 91b7ad523..ea63fd8e3 100644 --- a/pdf.c +++ b/pdf.c @@ -88,28 +88,20 @@ static int getNumberOfPages(lua_State *L) { } /* - * Return a table with (title,page) pair as entry: - * {"chapter1"=12, "chapter2"=20} + * helper function for getTableOfContent() */ -static int getTableOfContent(lua_State *L) { - fz_outline *ol; - int i; - - PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); - ol = pdf_load_outline(doc->xref); - - lua_newtable(L); - i = 1; +static int walkTableOfContent(lua_State *L, fz_outline* ol, int *count, int depth) { + depth++; while(ol) { - lua_pushnumber(L, i); + lua_pushnumber(L, *count); /* set subtable */ lua_newtable(L); lua_pushstring(L, "page"); lua_pushnumber(L, ol->dest.ld.gotor.page + 1); lua_settable(L, -3); - lua_pushstring(L, "level"); - lua_pushnumber(L, 1); // level 1 + lua_pushstring(L, "depth"); + lua_pushnumber(L, depth); lua_settable(L, -3); lua_pushstring(L, "title"); lua_pushstring(L, ol->title); @@ -117,9 +109,28 @@ static int getTableOfContent(lua_State *L) { lua_settable(L, -3); - i++; + (*count)++; + if (ol->down) { + walkTableOfContent(L, ol->down, count, depth); + } ol = ol->next; } + return 0; +} + +/* + * Return a table with (title,page) pair as entry: + * {"chapter1"=12, "chapter2"=20} + */ +static int getTableOfContent(lua_State *L) { + fz_outline *ol; + int count = 1; + + PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); + ol = pdf_load_outline(doc->xref); + + lua_newtable(L); + walkTableOfContent(L, ol, &count, 0); return 1; } diff --git a/pdfreader.lua b/pdfreader.lua index 869170dea..f358f248b 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -344,6 +344,8 @@ function PDFReader:inputloop() no = toc_menu:choose(0, fb.bb:getHeight()) if no then self:goto(no) + else + self:goto(self.pageno) end elseif ev.code == KEY_J then diff --git a/tocmenu.lua b/tocmenu.lua index d2146ba77..168e61677 100644 --- a/tocmenu.lua +++ b/tocmenu.lua @@ -4,8 +4,8 @@ require "graphics" TOCMenu = { -- font for displaying file/dir names - face = freetype.newBuiltinFace("cjk", 25), - fhash = "s25", + face = freetype.newBuiltinFace("cjk", 22), + fhash = "s22", -- font for page title tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 25), tfhash = "hbo25", @@ -15,7 +15,7 @@ TOCMenu = { -- title height title_H = 40, -- spacing between lines - spacing = 40, + spacing = 36, -- foot height foot_H = 27, @@ -97,8 +97,8 @@ function TOCMenu:choose(ypos, height) 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, - self.toc[i]["title"], true) + renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + (" "):rep(self.toc[i]["depth"]-1)..self.toc[i]["title"], true) end end From 606ef840d04a81bdbc411b43dc6ada9472337abc Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Tue, 21 Feb 2012 23:02:48 +0800 Subject: [PATCH 17/28] fix: two fixes for TOC menu * adjusted font spacing, looks better * handle pdf with no table of content --- tocmenu.lua | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/tocmenu.lua b/tocmenu.lua index 168e61677..73e62ed1a 100644 --- a/tocmenu.lua +++ b/tocmenu.lua @@ -82,6 +82,7 @@ function TOCMenu:choose(ypos, height) while true do if pagedirty then + markerdirty = true -- draw menu title fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) @@ -90,36 +91,45 @@ function TOCMenu:choose(ypos, height) renderUtf8Text(fb.bb, x, y, self.tface, self.tfhash, "Table of Contents", true) - -- draw font items + -- draw toc items fb.bb:paintRect(0, ypos + self.title_H + 10, fb.bb:getWidth(), height - self.title_H, 0) - local c - for c = 1, perpage do - local i = (self.page - 1) * perpage + c - if i <= self.items then - y = ypos + self.title_H + (self.spacing * c) - renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, - (" "):rep(self.toc[i]["depth"]-1)..self.toc[i]["title"], true) + if self.items == 0 then + y = ypos + self.title_H + (self.spacing * 2) + renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + "Oops... Bad news for you:", true) + y = y + self.spacing + renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + "This document does not have a Table of Conent.", true) + markerdirty = false + else + local c + for c = 1, perpage do + local i = (self.page - 1) * perpage + c + if i <= self.items then + y = ypos + self.title_H + (self.spacing * c) + renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + (" "):rep(self.toc[i]["depth"]-1)..self.toc[i]["title"], true) + end end end -- draw footer - y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H + y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H + 5 x = (fb.bb:getWidth() / 2) - 50 renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) - markerdirty = true end if markerdirty then if not pagedirty then if self.oldcurrent > 0 then - y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 10 + y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 8 fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) end end -- draw new marker line - y = ypos + self.title_H + (self.spacing * self.current) + 10 + y = ypos + self.title_H + (self.spacing * self.current) + 8 fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) if not pagedirty then fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) From f26adf97f048219c3facaa33b7cf6e16fbaf072b Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Thu, 23 Feb 2012 12:44:49 +0800 Subject: [PATCH 18/28] trigger KEY_HOME after exit to refresh screen --- reader.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reader.lua b/reader.lua index 1a5d99174..afe55f19d 100755 --- a/reader.lua +++ b/reader.lua @@ -101,3 +101,6 @@ else PDFReader:goto(tonumber(optarg["g"]) or tonumber(PDFReader.settings:readsetting("last_page") or 1)) PDFReader:inputloop() end + +input.closeAll() +os.execute('test -e /proc/keypad && echo "send '..KEY_HOME..'" > /proc/keypad ') From 85cb570e8882b81bc919f4edf40b63938b66615b Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 24 Feb 2012 00:16:20 +0800 Subject: [PATCH 19/28] fix: unify font changes to all menus --- filechooser.lua | 46 +++++++++++++++++++++++++++++--------------- filesearcher.lua | 39 +++++++++++++++++++++++++++++-------- fontchooser.lua | 50 ++++++++++++++++++++++++++++++++++++++---------- tocmenu.lua | 43 ++++++++++++++++++++++++++++++----------- 4 files changed, 134 insertions(+), 44 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index afac047be..dc0f0e833 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -7,13 +7,20 @@ require "inputbox" FileChooser = { -- Class vars: - - -- font for displaying file/dir names - face = freetype.newBuiltinFace("sans", 25), - fhash = "s25", + -- font for displaying toc item names + fsize = 25, + face = nil, + fhash = nil, + --face = freetype.newBuiltinFace("sans", 25), + --fhash = "s25", + -- font for paging display - sface = freetype.newBuiltinFace("sans", 16), - sfhash = "s16", + ffsize = 16, + fface = nil, + ffhash = nil, + --sface = freetype.newBuiltinFace("sans", 16), + --sfhash = "s16", + -- spacing between lines spacing = 40, @@ -54,11 +61,23 @@ function FileChooser:setPath(newPath) return true 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) - 1 local pagedirty = true local markerdirty = false + self:updateFont() local prevItem = function () if self.current == 1 then @@ -103,7 +122,7 @@ function FileChooser:choose(ypos, height) renderUtf8Text(fb.bb, 50, ypos + self.spacing*c, self.face, self.fhash, self.files[i-#self.dirs], true) end end - renderUtf8Text(fb.bb, 39, ypos + self.spacing * perpage + 32, self.sface, self.sfhash, + renderUtf8Text(fb.bb, 39, ypos + self.spacing * perpage + 32, self.fface, self.ffhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) markerdirty = true end @@ -134,12 +153,9 @@ function FileChooser:choose(ypos, height) elseif ev.code == KEY_FW_DOWN then nextItem() elseif ev.code == KEY_F then -- invoke fontchooser menu - FontChooser:init() - newfont = FontChooser:choose(0, height) - if newfont ~= nil then - self.face = freetype.newBuiltinFace(newfont, 25) - clearglyphcache() - end + --FontChooser:init() + FontChooser:choose(0, height) + self:updateFont() pagedirty = true elseif ev.code == KEY_S then -- invoke search input keywords = InputBox:input(height-100, 100, "Search:") @@ -150,8 +166,8 @@ function FileChooser:choose(ypos, height) || to test search feature in EMU mode ---------------------------------------------------------------- --]] - --FileSearcher:init("/home/dave/documents/kindle/backup/documents") - FileSearcher:init() + FileSearcher:init("/home/dave/documents/kindle/backup/documents") + --FileSearcher:init() file = FileSearcher:choose(ypos, height, keywords) if file then return file diff --git a/filesearcher.lua b/filesearcher.lua index 367486cd1..316c3e33f 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -1,17 +1,22 @@ require "rendertext" require "keys" require "graphics" +require "fontchooser" FileSearcher = { - -- font for displaying file/dir names - face = freetype.newBuiltinFace("sans", 25), - fhash = "s25", + -- font for displaying toc item names + fsize = 25, + face = nil, + fhash = nil, -- font for page title - tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 32), - tfhash = "hbo32", + tfsize = 30, + tface = nil, + tfhash = nil, -- font for paging display - sface = freetype.newBuiltinFace("sans", 16), - sfhash = "s16", + ffsize = 16, + fface = nil, + ffhash = nil, + -- title height title_H = 45, -- spacing between lines @@ -65,6 +70,23 @@ 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 @@ -94,6 +116,7 @@ function FileSearcher:choose(ypos, height, keywords) local perpage = math.floor(height / self.spacing) - 2 local pagedirty = true local markerdirty = false + self:updateFont() local prevItem = function () if self.current == 1 then @@ -163,7 +186,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.sface, self.sfhash, + renderUtf8Text(fb.bb, x, y, self.fface, self.ffhash, "Page "..self.page.." of "..all_page, true) end diff --git a/fontchooser.lua b/fontchooser.lua index a1acf08cc..0cf6b4292 100644 --- a/fontchooser.lua +++ b/fontchooser.lua @@ -3,15 +3,27 @@ require "keys" require "graphics" FontChooser = { + -- font name for content + cfont = "sans", -- font for displaying file/dir names - face = freetype.newBuiltinFace("sans", 25), - fhash = "s25", + fsize = 25, + face = nil, + fhash = nil, + + -- font name for title + tfont = "Helvetica-BoldOblique", -- font for page title - tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 30), - tfhash = "hbo30", - -- font for paging display - sface = freetype.newBuiltinFace("sans", 16), - sfhash = "s16", + tfsize = 30, + tface = nil, + tfhash = nil, + + -- font name for footer + ffont = "sans", + -- font for page footer display + ffsize = 16, + fface = nil, + ffhash = nil, + -- title height title_H = 45, -- spacing between lines @@ -35,11 +47,28 @@ function FontChooser:init() self.items = #self.fonts end +function FontChooser: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 FontChooser: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 @@ -95,7 +124,7 @@ function FontChooser:choose(ypos, height) -- draw footer y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H x = (fb.bb:getWidth() / 2) - 50 - renderUtf8Text(fb.bb, x, y, self.sface, self.sfhash, + renderUtf8Text(fb.bb, x, y, self.fface, self.ffhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) markerdirty = true end @@ -150,8 +179,9 @@ function FontChooser:choose(ypos, height) markerdirty = true end elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - local newface = self.fonts[perpage*(self.page-1)+self.current] - return newface + self.cfont = self.fonts[perpage*(self.page-1)+self.current] + clearglyphcache() + return nil elseif ev.code == KEY_BACK then return nil end diff --git a/tocmenu.lua b/tocmenu.lua index 73e62ed1a..ee2d70d51 100644 --- a/tocmenu.lua +++ b/tocmenu.lua @@ -1,17 +1,22 @@ require "rendertext" require "keys" require "graphics" +require "fontchooser" TOCMenu = { - -- font for displaying file/dir names - face = freetype.newBuiltinFace("cjk", 22), - fhash = "s22", + -- font for displaying toc item names + fsize = 22, + face = nil, + fhash = nil, -- font for page title - tface = freetype.newBuiltinFace("Helvetica-BoldOblique", 25), - tfhash = "hbo25", + tfsize = 25, + tface = nil, + tfhash = nil, -- font for paging display - sface = freetype.newBuiltinFace("sans", 16), - sfhash = "s16", + ffsize = 16, + fface = nil, + ffhash = nil, + -- title height title_H = 40, -- spacing between lines @@ -28,8 +33,6 @@ TOCMenu = { } function TOCMenu:new(toc) - --@TODO set font here in the future 21.02 2012 - --clearglyphcache() instance = self instance.toc = toc instance.items = #toc @@ -45,10 +48,28 @@ function TOCMenu:dump() end end +function TOCMenu: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 TOCMenu: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 @@ -99,7 +120,7 @@ function TOCMenu:choose(ypos, height) "Oops... Bad news for you:", true) y = y + self.spacing renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, - "This document does not have a Table of Conent.", true) + "This document doesn't have a TOC.", true) markerdirty = false else local c @@ -116,7 +137,7 @@ function TOCMenu: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.sface, self.sfhash, + renderUtf8Text(fb.bb, x, y, self.fface, self.ffhash, "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) end From 0366e8b8c2e5c404cab08b46845e5664853a66bf Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 24 Feb 2012 00:30:02 +0800 Subject: [PATCH 20/28] mod: use settings module to save font configuration --- reader.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/reader.lua b/reader.lua index afe55f19d..1cff406ed 100755 --- a/reader.lua +++ b/reader.lua @@ -20,6 +20,7 @@ require "alt_getopt" require "pdfreader" require "filechooser" +require "settings" -- option parsing: longopts = { @@ -82,6 +83,14 @@ end fb = einkfb.open("/dev/fb0") width, height = fb:getSize() +-- set up reader's setting: font +reader_settings = DocSettings:open(".reader") +r_cfont = reader_settings:readsetting("cfont") +if r_cfont ~=nil then + FontChooser.cfont = r_cfont +end + + if lfs.attributes(ARGV[optind], "mode") == "directory" then local running = true FileChooser:setPath(ARGV[optind]) @@ -102,5 +111,9 @@ else PDFReader:inputloop() end +-- save reader settings +reader_settings:savesetting("cfont", FontChooser.cfont) +reader_settings:close() + input.closeAll() os.execute('test -e /proc/keypad && echo "send '..KEY_HOME..'" > /proc/keypad ') From 35340f27ce13b16f2da20367ac2ca5d4a2929960 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 24 Feb 2012 00:34:50 +0800 Subject: [PATCH 21/28] fix: typo --- filechooser.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index dc0f0e833..0662aedd9 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -166,8 +166,8 @@ function FileChooser:choose(ypos, height) || to test search feature in EMU mode ---------------------------------------------------------------- --]] - FileSearcher:init("/home/dave/documents/kindle/backup/documents") - --FileSearcher:init() + --FileSearcher:init("/home/dave/documents/kindle/backup/documents") + FileSearcher:init() file = FileSearcher:choose(ypos, height, keywords) if file then return file From cb982f5da67745d76ad4d02ac22419fa7ee6a297 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Fri, 24 Feb 2012 00:39:39 +0800 Subject: [PATCH 22/28] mod: error message for not found --- filesearcher.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filesearcher.lua b/filesearcher.lua index 316c3e33f..1c6199631 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -167,7 +167,7 @@ function FileSearcher:choose(ypos, height, keywords) if self.items == 0 then -- nothing found y = ypos + self.title_H + self.spacing * 2 renderUtf8Text(fb.bb, 20, y, self.face, self.fhash, - "Sorry, your keyword did not match any documents.", true) + "Sorry, no match found.", true) renderUtf8Text(fb.bb, 20, y + self.spacing, self.face, self.fhash, "Please try a different keyword.", true) markerdirty = false From 02713ae2abe72cbaba15533c06bd18480f22c67f Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 26 Feb 2012 08:28:03 +0800 Subject: [PATCH 23/28] add: demo for jumpstack --- pdfreader.lua | 67 ++++++++++++++-- selectmenu.lua | 203 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 selectmenu.lua diff --git a/pdfreader.lua b/pdfreader.lua index f358f248b..9570e651f 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -1,6 +1,7 @@ require "keys" require "settings" require "tocmenu" +require "selectmenu" PDFReader = { -- "constants": @@ -59,6 +60,7 @@ PDFReader = { -- tile cache state: cache_current_memsize = 0, cache = {}, + jump_stack = {}, } -- guarantee that we have enough memory in cache @@ -235,6 +237,36 @@ function PDFReader:goto(no) if no < 1 or no > self.doc:getPages() then return end + + -- for jump_stack + if self.pageno and math.abs(self.pageno - no) > 1 then + local jump_item = nil + -- add current page to jump_stack if no in + for _t,_v in ipairs(self.jump_stack) do + if _v.page == self.pageno then + jump_item = _v + table.remove(self.jump_stack, _t) + elseif _v.page == no then + -- the page we jumped to should not be show in stack + table.remove(self.jump_stack, _t) + end + end + -- create a new one if not found + if not jump_item then + jump_item = { + page = self.pageno, + datetime = os.date("%Y-%m-%d %H:%M:%S"), + } + end + -- insert at the start + table.insert(self.jump_stack, 1, jump_item) + if #self.jump_stack > 10 then + -- remove the last element to keep the size less than 10 + table.remove(self.jump_stack) + end + print('@add: '..jump_item.page..", current: "..self.pageno) + end + self.pageno = no self:show(no) if no < self.doc:getPages() then @@ -337,15 +369,34 @@ function PDFReader:inputloop() end elseif ev.code == KEY_T then - -- show table of content menu - toc = self.doc:getTOC() - toc_menu = TOCMenu:new(toc) - --toc_menu:dump() - no = toc_menu:choose(0, fb.bb:getHeight()) - if no then - self:goto(no) + if self.altmode then + -- show jump_stack + local menu_items = {} + for _k,_v in ipairs(self.jump_stack) do + table.insert(menu_items, + _v.datetime.." -> Page ".._v.page) + end + jump_menu = SelectMenu:new( + "Jump Keeper, Current page: "..self.pageno, menu_items) + jump_re = jump_menu:choose(0, fb.bb:getHeight()) + jump_menu = nil + if jump_re then + local jump_item = self.jump_stack[jump_re] + self:goto(jump_item.page) + else + self:goto(self.pageno) + end else - self:goto(self.pageno) + -- show table of content menu + toc = self.doc:getTOC() + toc_menu = TOCMenu:new(toc) + --toc_menu:dump() + no = toc_menu:choose(0, fb.bb:getHeight()) + if no then + self:goto(no) + else + self:goto(self.pageno) + end end elseif ev.code == KEY_J then diff --git a/selectmenu.lua b/selectmenu.lua new file mode 100644 index 000000000..7d6daf5d6 --- /dev/null +++ b/selectmenu.lua @@ -0,0 +1,203 @@ +require "rendertext" +require "keys" +require "graphics" +require "fontchooser" + +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, + + -- title height + title_H = 40, + -- spacing between lines + spacing = 36, + -- foot height + foot_H = 27, + + -- state buffer + menu_title = "None Title", + item_array = {}, + items = 14, + page = 1, + current = 1, + oldcurrent = 0, +} + +function SelectMenu:new(menu_title, item_array) + instance = self + instance.item_array = item_array + instance.menu_title = menu_title + instance.items = #item_array + instance.current = 1 + instance.oldcurrent = 0 + return instance +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 + +--[ +-- return the index of selected item +--] +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 + if self.page > 1 then + self.current = perpage + self.page = self.page - 1 + pagedirty = true + end + else + self.current = self.current - 1 + markerdirty = true + end + end + + local nextItem = function () + if self.current == perpage then + if self.page < (self.items / perpage) then + self.current = 1 + self.page = self.page + 1 + pagedirty = true + end + else + if self.page ~= math.floor(self.items / perpage) + 1 + or self.current + (self.page-1)*perpage < self.items then + self.current = self.current + 1 + markerdirty = true + end + end + end + + + while true do + if pagedirty then + markerdirty = true + -- draw menu title + fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) + fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) + --x = fb.bb:getWidth() - 260 -- move text to the right + x = 40 + y = ypos + self.title_H + renderUtf8Text(fb.bb, x, y, self.tface, self.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, + "Oops... Bad news for you:", true) + y = y + self.spacing + renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + "No items found.", true) + markerdirty = false + else + local c + for c = 1, perpage do + local i = (self.page - 1) * perpage + c + if i <= self.items then + y = ypos + self.title_H + (self.spacing * c) + renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, + self.item_array[i], true) + end + end + end + + -- 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, + "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) + end + + if markerdirty then + if not pagedirty then + if self.oldcurrent > 0 then + y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 8 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) + end + end + -- draw new marker line + y = ypos + self.title_H + (self.spacing * self.current) + 8 + fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) + if not pagedirty then + fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) + end + self.oldcurrent = self.current + markerdirty = false + end + + if pagedirty then + fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) + pagedirty = false + end + + local ev = input.waitForEvent() + if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then + ev.code = adjustFWKey(ev.code) + if ev.code == KEY_FW_UP then + prevItem() + elseif ev.code == KEY_FW_DOWN then + nextItem() + elseif ev.code == KEY_PGFWD then + if self.page < (self.items / perpage) then + if self.current + self.page*perpage > self.items then + self.current = self.items - self.page*perpage + end + self.page = self.page + 1 + pagedirty = true + else + self.current = self.items - (self.page-1)*perpage + markerdirty = true + end + elseif ev.code == KEY_PGBCK then + if self.page > 1 then + self.page = self.page - 1 + pagedirty = true + else + self.current = 1 + markerdirty = true + end + elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then + if self.items == 0 then + return nil + else + return (perpage*(self.page-1) + self.current) + end + elseif ev.code == KEY_BACK then + return nil + end + end + end +end From fa5b0c98748c17f69bf16867c0dc87317805af58 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 26 Feb 2012 09:47:54 +0800 Subject: [PATCH 24/28] mod: toc and jumpstack refactored --- pdfreader.lua | 104 +++++++++++++++---------- selectmenu.lua | 25 ++++--- tocmenu.lua | 200 ------------------------------------------------- 3 files changed, 80 insertions(+), 249 deletions(-) delete mode 100644 tocmenu.lua diff --git a/pdfreader.lua b/pdfreader.lua index 9570e651f..f22da6c98 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -1,6 +1,6 @@ require "keys" require "settings" -require "tocmenu" +--require "tocmenu" require "selectmenu" PDFReader = { @@ -243,6 +243,7 @@ function PDFReader:goto(no) local jump_item = nil -- add current page to jump_stack if no in for _t,_v in ipairs(self.jump_stack) do + --print(_v) if _v.page == self.pageno then jump_item = _v table.remove(self.jump_stack, _t) @@ -308,6 +309,51 @@ function PDFReader:setrotate(rotate) self:goto(self.pageno) end +function PDFReader:showTOC() + toc = self.doc:getTOC() + local menu_items = {} + -- build menu items + for _k,_v in ipairs(toc) do + table.insert(menu_items, + (" "):rep(_v.depth-1).._v.title) + end + toc_menu = SelectMenu:new{ + menu_title = "Table of Contents", + item_array = menu_items, + no_item_msg = + "This document does not have a Table of Contents.", + } + item_no = toc_menu:choose(0, fb.bb:getHeight()) + if item_no then + self:goto(toc[item_no].page) + else + self:goto(self.pageno) + end +end + +function PDFReader:showJumpStack() + local menu_items = {} + for _k,_v in ipairs(self.jump_stack) do + --print(_v.datetime.." -> Page ".._v.page) + table.insert(menu_items, + _v.datetime.." -> Page ".._v.page) + end + jump_menu = SelectMenu:new{ + menu_title = + "Jump Keeper, Current page: "..self.pageno, + item_array = menu_items, + no_item_msg = "No jump history.", + } + item_no = jump_menu:choose(0, fb.bb:getHeight()) + if item_no then + local jump_item = self.jump_stack[item_no] + self:goto(jump_item.page) + else + self:goto(self.pageno) + end +end + + -- wait for input and handle it function PDFReader:inputloop() while 1 do @@ -335,16 +381,24 @@ function PDFReader:inputloop() self:goto(self.pageno - 1) end elseif ev.code == KEY_BACK then - self:clearcache() - if self.doc ~= nil then - self.doc:close() - end - if self.settings ~= nil then - self.settings:savesetting("last_page", self.pageno) - self.settings:savesetting("gamma", self.globalgamma) - self.settings:close() + if self.altmode then + -- in altmode, back to last jump + if #self.jump_stack ~= 0 then + self:goto(self.jump_stack[1].page) + end + else + -- not altmode, exit pdfreader + self:clearcache() + if self.doc ~= nil then + self.doc:close() + end + if self.settings ~= nil then + self.settings:savesetting("last_page", self.pageno) + self.settings:savesetting("gamma", self.globalgamma) + self.settings:close() + end + return end - return elseif ev.code == KEY_VPLUS then self:modify_gamma( 1.25 ) elseif ev.code == KEY_VMINUS then @@ -367,38 +421,12 @@ function PDFReader:inputloop() else self:setglobalzoommode(self.ZOOM_FIT_TO_PAGE_HEIGHT) end - elseif ev.code == KEY_T then if self.altmode then - -- show jump_stack - local menu_items = {} - for _k,_v in ipairs(self.jump_stack) do - table.insert(menu_items, - _v.datetime.." -> Page ".._v.page) - end - jump_menu = SelectMenu:new( - "Jump Keeper, Current page: "..self.pageno, menu_items) - jump_re = jump_menu:choose(0, fb.bb:getHeight()) - jump_menu = nil - if jump_re then - local jump_item = self.jump_stack[jump_re] - self:goto(jump_item.page) - else - self:goto(self.pageno) - end + self:showJumpStack() else - -- show table of content menu - toc = self.doc:getTOC() - toc_menu = TOCMenu:new(toc) - --toc_menu:dump() - no = toc_menu:choose(0, fb.bb:getHeight()) - if no then - self:goto(no) - else - self:goto(self.pageno) - end + self:showTOC() end - elseif ev.code == KEY_J then self:setrotate( self.globalrotate + 10 ) elseif ev.code == KEY_K then diff --git a/selectmenu.lua b/selectmenu.lua index 7d6daf5d6..8c6219f60 100644 --- a/selectmenu.lua +++ b/selectmenu.lua @@ -24,23 +24,26 @@ SelectMenu = { -- foot height foot_H = 27, - -- state buffer - menu_title = "None Title", + menu_title = "None Titled", + no_item_msg = "No items found.", item_array = {}, items = 14, + + -- state buffer page = 1, current = 1, oldcurrent = 0, } -function SelectMenu:new(menu_title, item_array) - instance = self - instance.item_array = item_array - instance.menu_title = menu_title - instance.items = #item_array - instance.current = 1 - instance.oldcurrent = 0 - return instance +function SelectMenu:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + o.items = #o.item_array + o.page = 1 + o.current = 1 + o.oldcurrent = 0 + return o end function SelectMenu:updateFont() @@ -119,7 +122,7 @@ function SelectMenu:choose(ypos, height) "Oops... Bad news for you:", true) y = y + self.spacing renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, - "No items found.", true) + self.no_item_msg, true) markerdirty = false else local c diff --git a/tocmenu.lua b/tocmenu.lua deleted file mode 100644 index ee2d70d51..000000000 --- a/tocmenu.lua +++ /dev/null @@ -1,200 +0,0 @@ -require "rendertext" -require "keys" -require "graphics" -require "fontchooser" - -TOCMenu = { - -- font for displaying toc 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, - - -- title height - title_H = 40, - -- spacing between lines - spacing = 36, - -- foot height - foot_H = 27, - - -- state buffer - toc = {}, - items = 14, - page = 1, - current = 1, - oldcurrent = 0, -} - -function TOCMenu:new(toc) - instance = self - instance.toc = toc - instance.items = #toc - return instance -end - -function TOCMenu:dump() - for k,v in pairs(self.toc) do - print("TOC item: "..k) - for key,value in pairs(v) do - print(" "..key..": "..value) - end - end -end - -function TOCMenu: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 TOCMenu: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 - if self.page > 1 then - self.current = perpage - self.page = self.page - 1 - pagedirty = true - end - else - self.current = self.current - 1 - markerdirty = true - end - end - - local nextItem = function () - if self.current == perpage then - if self.page < (self.items / perpage) then - self.current = 1 - self.page = self.page + 1 - pagedirty = true - end - else - if self.page ~= math.floor(self.items / perpage) + 1 - or self.current + (self.page-1)*perpage < self.items then - self.current = self.current + 1 - markerdirty = true - end - end - end - - - while true do - if pagedirty then - markerdirty = true - -- draw menu title - fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) - fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) - x = fb.bb:getWidth() - 260 -- move text to the right - y = ypos + self.title_H - renderUtf8Text(fb.bb, x, y, self.tface, self.tfhash, - "Table of Contents", true) - - -- draw toc 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, - "Oops... Bad news for you:", true) - y = y + self.spacing - renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, - "This document doesn't have a TOC.", true) - markerdirty = false - else - local c - for c = 1, perpage do - local i = (self.page - 1) * perpage + c - if i <= self.items then - y = ypos + self.title_H + (self.spacing * c) - renderUtf8Text(fb.bb, 30, y, self.face, self.fhash, - (" "):rep(self.toc[i]["depth"]-1)..self.toc[i]["title"], true) - end - end - end - - -- 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, - "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) - end - - if markerdirty then - if not pagedirty then - if self.oldcurrent > 0 then - y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 8 - fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) - fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) - end - end - -- draw new marker line - y = ypos + self.title_H + (self.spacing * self.current) + 8 - fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) - if not pagedirty then - fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) - end - self.oldcurrent = self.current - markerdirty = false - end - - if pagedirty then - fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) - pagedirty = false - end - - local ev = input.waitForEvent() - if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then - ev.code = adjustFWKey(ev.code) - if ev.code == KEY_FW_UP then - prevItem() - elseif ev.code == KEY_FW_DOWN then - nextItem() - elseif ev.code == KEY_PGFWD then - if self.page < (self.items / perpage) then - if self.current + self.page*perpage > self.items then - self.current = self.items - self.page*perpage - end - self.page = self.page + 1 - pagedirty = true - else - self.current = self.items - (self.page-1)*perpage - markerdirty = true - end - elseif ev.code == KEY_PGBCK then - if self.page > 1 then - self.page = self.page - 1 - pagedirty = true - else - self.current = 1 - markerdirty = true - end - elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - return self.toc[perpage*(self.page-1)+self.current]["page"] - elseif ev.code == KEY_BACK then - return nil - end - end - end -end From 15b8f4d57422e7917e3c64e1f9f92a29d0bb0094 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 26 Feb 2012 10:42:04 +0800 Subject: [PATCH 25/28] mod: fontchooser and pdfreader code clean up --- filechooser.lua | 13 ++-- fontchooser.lua | 172 +----------------------------------------------- pdfreader.lua | 9 +-- 3 files changed, 11 insertions(+), 183 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index 0662aedd9..d7007f9ee 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -4,6 +4,7 @@ require "graphics" require "fontchooser" require "filesearcher" require "inputbox" +require "selectmenu" FileChooser = { -- Class vars: @@ -66,7 +67,6 @@ function FileChooser:updateFont() 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 @@ -77,7 +77,6 @@ function FileChooser:choose(ypos, height) local perpage = math.floor(height / self.spacing) - 1 local pagedirty = true local markerdirty = false - self:updateFont() local prevItem = function () if self.current == 1 then @@ -109,6 +108,7 @@ function FileChooser:choose(ypos, height) end while true do + self:updateFont() if pagedirty then fb.bb:paintRect(0, ypos, fb.bb:getWidth(), height, 0) local c @@ -153,9 +153,12 @@ function FileChooser:choose(ypos, height) elseif ev.code == KEY_FW_DOWN then nextItem() elseif ev.code == KEY_F then -- invoke fontchooser menu - --FontChooser:init() - FontChooser:choose(0, height) - self:updateFont() + FontChooser:init() + fonts_menu = SelectMenu:new{ + menu_title = "Fonts Menu", + item_array = FontChooser.fonts, + } + FontChooser.cfont = FontChooser.fonts[fonts_menu:choose(0, height)] pagedirty = true elseif ev.code == KEY_S then -- invoke search input keywords = InputBox:input(height-100, 100, "Search:") diff --git a/fontchooser.lua b/fontchooser.lua index 0cf6b4292..96e192319 100644 --- a/fontchooser.lua +++ b/fontchooser.lua @@ -1,190 +1,20 @@ -require "rendertext" -require "keys" -require "graphics" FontChooser = { - -- font name for content + -- font name for menu contents cfont = "sans", - -- font for displaying file/dir names - fsize = 25, - face = nil, - fhash = nil, - -- font name for title tfont = "Helvetica-BoldOblique", - -- font for page title - tfsize = 30, - tface = nil, - tfhash = nil, - -- font name for footer ffont = "sans", - -- font for page footer display - ffsize = 16, - fface = nil, - ffhash = nil, - - -- title height - title_H = 45, - -- spacing between lines - spacing = 40, - -- foot height - foot_H = 27, -- state buffer fonts = {"sans", "cjk", "mono", "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Helvetica", "Helvetica-Oblique", "Helvetica-BoldOblique", "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",}, - items = 14, - page = 1, - current = 1, - oldcurrent = 0, } function FontChooser:init() clearglyphcache() - self.items = #self.fonts end -function FontChooser: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 FontChooser: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 - if self.page > 1 then - self.current = perpage - self.page = self.page - 1 - pagedirty = true - end - else - self.current = self.current - 1 - markerdirty = true - end - end - - local nextItem = function () - if self.current == perpage then - if self.page < (self.items / perpage) then - self.current = 1 - self.page = self.page + 1 - pagedirty = true - end - else - if self.page ~= math.floor(self.items / perpage) + 1 - or self.current + (self.page-1)*perpage < self.items then - self.current = self.current + 1 - markerdirty = true - end - end - end - - - while true do - if pagedirty then - -- draw menu title - fb.bb:paintRect(0, ypos, fb.bb:getWidth(), self.title_H + 10, 0) - fb.bb:paintRect(30, ypos + 10, fb.bb:getWidth() - 60, self.title_H, 5) - x = fb.bb:getWidth() - 220 -- move text to the right - y = ypos + self.title_H - renderUtf8Text(fb.bb, x, y, self.tface, self.tfhash, - "Fonts Menu", true) - - -- draw font items - fb.bb:paintRect(0, ypos + self.title_H + 10, fb.bb:getWidth(), height - self.title_H, 0) - local c - for c = 1, perpage do - 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, self.fonts[i], true) - end - end - - -- draw footer - y = ypos + self.title_H + (self.spacing * perpage) + self.foot_H - x = (fb.bb:getWidth() / 2) - 50 - renderUtf8Text(fb.bb, x, y, self.fface, self.ffhash, - "Page "..self.page.." of "..(math.floor(self.items / perpage)+1), true) - markerdirty = true - end - - if markerdirty then - if not pagedirty then - if self.oldcurrent > 0 then - y = ypos + self.title_H + (self.spacing * self.oldcurrent) + 10 - fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 0) - fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) - end - end - -- draw new marker line - y = ypos + self.title_H + (self.spacing * self.current) + 10 - fb.bb:paintRect(30, y, fb.bb:getWidth() - 60, 3, 15) - if not pagedirty then - fb:refresh(1, 30, y, fb.bb:getWidth() - 60, 3) - end - self.oldcurrent = self.current - markerdirty = false - end - - if pagedirty then - fb:refresh(0, 0, ypos, fb.bb:getWidth(), height) - pagedirty = false - end - - local ev = input.waitForEvent() - if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then - ev.code = adjustFWKey(ev.code) - if ev.code == KEY_FW_UP then - prevItem() - elseif ev.code == KEY_FW_DOWN then - nextItem() - elseif ev.code == KEY_PGFWD then - if self.page < (self.items / perpage) then - if self.current + self.page*perpage > self.items then - self.current = self.items - self.page*perpage - end - self.page = self.page + 1 - pagedirty = true - else - self.current = self.items - (self.page-1)*perpage - markerdirty = true - end - elseif ev.code == KEY_PGBCK then - if self.page > 1 then - self.page = self.page - 1 - pagedirty = true - else - self.current = 1 - markerdirty = true - end - elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then - self.cfont = self.fonts[perpage*(self.page-1)+self.current] - clearglyphcache() - return nil - elseif ev.code == KEY_BACK then - return nil - end - end - end -end diff --git a/pdfreader.lua b/pdfreader.lua index f22da6c98..3d5fd04b0 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -243,7 +243,6 @@ function PDFReader:goto(no) local jump_item = nil -- add current page to jump_stack if no in for _t,_v in ipairs(self.jump_stack) do - --print(_v) if _v.page == self.pageno then jump_item = _v table.remove(self.jump_stack, _t) @@ -265,7 +264,6 @@ function PDFReader:goto(no) -- remove the last element to keep the size less than 10 table.remove(self.jump_stack) end - print('@add: '..jump_item.page..", current: "..self.pageno) end self.pageno = no @@ -320,8 +318,7 @@ function PDFReader:showTOC() toc_menu = SelectMenu:new{ menu_title = "Table of Contents", item_array = menu_items, - no_item_msg = - "This document does not have a Table of Contents.", + no_item_msg = "This document does not have a Table of Contents.", } item_no = toc_menu:choose(0, fb.bb:getHeight()) if item_no then @@ -334,13 +331,11 @@ end function PDFReader:showJumpStack() local menu_items = {} for _k,_v in ipairs(self.jump_stack) do - --print(_v.datetime.." -> Page ".._v.page) table.insert(menu_items, _v.datetime.." -> Page ".._v.page) end jump_menu = SelectMenu:new{ - menu_title = - "Jump Keeper, Current page: "..self.pageno, + menu_title = "Jump Keeper (current page: "..self.pageno..")", item_array = menu_items, no_item_msg = "No jump history.", } From e9f6ecfb868f1b0ceb818b7cff2b19b85faffe37 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 26 Feb 2012 11:08:58 +0800 Subject: [PATCH 26/28] fix: freetype version in Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 106b1e517..5f9de89ee 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ MUPDFLIBDIR=$(MUPDFDIR)/$(MUPDFTARGET) SQLITE3DIR=sqlite-amalgamation-3070900 LSQLITE3DIR=lsqlite3_svn08 -FREETYPEDIR=$(MUPDFDIR)/thirdparty/freetype-2.4.4 +FREETYPEDIR=$(MUPDFDIR)/thirdparty/freetype-2.4.8 LFSDIR=luafilesystem # set this to your ARM cross compiler: From b33720a567b5722321fd38771bf76716faa240d0 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 26 Feb 2012 11:39:36 +0800 Subject: [PATCH 27/28] mod: change shortcut for jumpstack & fix: inputbox --- inputbox.lua | 2 +- pdfreader.lua | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/inputbox.lua b/inputbox.lua index e88b934b8..3408567c7 100644 --- a/inputbox.lua +++ b/inputbox.lua @@ -8,7 +8,7 @@ InputBox = { input_start_y = nil, input_cur_x = nil, -- points to the start of next input pos - input_bg = 1, + input_bg = 0, input_string = "", diff --git a/pdfreader.lua b/pdfreader.lua index 3d5fd04b0..bc8b0b37d 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -382,7 +382,7 @@ function PDFReader:inputloop() self:goto(self.jump_stack[1].page) end else - -- not altmode, exit pdfreader + -- not shiftmode, exit pdfreader self:clearcache() if self.doc ~= nil then self.doc:close() @@ -417,11 +417,9 @@ function PDFReader:inputloop() self:setglobalzoommode(self.ZOOM_FIT_TO_PAGE_HEIGHT) end elseif ev.code == KEY_T then - if self.altmode then - self:showJumpStack() - else - self:showTOC() - end + self:showTOC() + elseif ev.code == KEY_B then + self:showJumpStack() elseif ev.code == KEY_J then self:setrotate( self.globalrotate + 10 ) elseif ev.code == KEY_K then @@ -488,6 +486,7 @@ function PDFReader:inputloop() local dur = (nsecs - secs) * 1000000 + nusecs - usecs print("E: T="..ev.type.." V="..ev.value.." C="..ev.code.." DUR="..dur) elseif ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_RELEASE and ev.code == KEY_SHIFT then + print "shift haha" self.shiftmode = false elseif ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_RELEASE and ev.code == KEY_ALT then self.altmode = false From e8fa2d50ea2f5d117675d5518e05dff539dd88f0 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Mon, 27 Feb 2012 22:17:17 +0800 Subject: [PATCH 28/28] mod:update comment in pdf.c --- pdf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pdf.c b/pdf.c index ea63fd8e3..15c6d3f8a 100644 --- a/pdf.c +++ b/pdf.c @@ -119,8 +119,11 @@ static int walkTableOfContent(lua_State *L, fz_outline* ol, int *count, int dept } /* - * Return a table with (title,page) pair as entry: - * {"chapter1"=12, "chapter2"=20} + * Return a table like this: + * { + * {page=12, depth=1, title="chapter1"}, + * {page=54, depth=1, title="chapter2"}, + * } */ static int getTableOfContent(lua_State *L) { fz_outline *ol;