diff --git a/crereader.lua b/crereader.lua index 4ff8c1d0d..3d9999523 100644 --- a/crereader.lua +++ b/crereader.lua @@ -9,15 +9,15 @@ CREReader = UniReader:new{ gamma_index = 15, font_face = nil, - -- NuPogodi, 17.05.12: to store fontsize changes font_zoom = 0, line_space_percent = 100, - -- NuPogodi, 17.05.12: insert new parameter to store old doc height before rescaling. - -- One needs it to change font(face & size) and / or interline spacig without - -- appreciable changing of the current position in document + -- NuPogodi, 15.05.12: insert the parameter to store old doc height before rescaling. + -- One needs it to change font(face, size, bold) without appreciable changing of the + -- current position in document old_doc_height = 0, + -- end of changes (NuPogodi) } function CREReader:init() @@ -32,7 +32,6 @@ function CREReader:init() end end end - -- NuPogodi, 20.05.12: inspect the zipfile content function CREReader:ZipContentExt(fname) local outfile = "./data/zip_content" @@ -52,18 +51,15 @@ end function CREReader:open(filename) local ok local file_type = string.lower(string.match(filename, ".+%.([^.]+)")) - if file_type == "zip" then -- NuPogodi, 20.05.12: read the content of zip-file -- and return extention of the 1st file file_type = self:ZipContentExt(filename) end - -- these two format use the same css file if file_type == "html" then file_type = "htm" end - -- if native css-file doesn't exist, one needs to use default cr3.css if not io.open("./data/"..file_type..".css") then file_type = "cr3" @@ -74,9 +70,7 @@ function CREReader:open(filename) if not ok then return false, self.doc -- will contain error message end - self.doc:setDefaultInterlineSpace(self.line_space_percent) - return true end @@ -94,8 +88,7 @@ function CREReader:loadSpecialSettings() local line_space_percent = self.settings:readSetting("line_space_percent") self.line_space_percent = line_space_percent or self.line_space_percent - - -- NuPogodi, 17.05.12: reading & setting the font size + self.font_zoom = self.settings:readSetting("font_zoom") or 0 if self.font_zoom ~= 0 then local i = math.abs(self.font_zoom) @@ -110,7 +103,7 @@ function CREReader:loadSpecialSettings() end function CREReader:getLastPageOrPos() - local last_percent = self.settings:readSetting("last_percent") + local last_percent = self.settings:readSetting("last_percent") if last_percent then return math.floor((last_percent * self.doc:getFullHeight()) / 10000) else @@ -122,7 +115,6 @@ function CREReader:saveSpecialSettings() self.settings:saveSetting("font_face", self.font_face) self.settings:saveSetting("gamma_index", self.gamma_index) self.settings:saveSetting("line_space_percent", self.line_space_percent) - -- NuPogodi, 17.05.12: saving the font size self.settings:saveSetting("font_zoom", self.font_zoom) end @@ -142,8 +134,8 @@ function CREReader:redrawCurrentPage() -- NuPogodi, 15.05.12: Something was wrong here! -- self:goto(self.pos) -- after changing the font(face, size or boldface) or interline spacing - -- the position inside document HAS TO REMAIN CONSTANT! it was NOT! - -- Fixed the problem by the following correction to new document height + -- the position inside document HAS TO REMAIN NEARLY CONSTANT! it was NOT! + -- SEEMS TO BE FIXED by relacing self:goto(self.pos) on self:goto(self.pos * (self.doc:getFullHeight() - G_height) / (self.old_doc_height - G_height)) end @@ -158,7 +150,7 @@ end function CREReader:goto(pos, is_ignore_jump, pos_type) local prev_xpointer = self.doc:getXPointer() local width, height = G_width, G_height - + if pos_type == "xpointer" then self.doc:gotoXPointer(pos) pos = self.doc:getCurrentPos() @@ -167,17 +159,16 @@ function CREReader:goto(pos, is_ignore_jump, pos_type) pos = math.max(pos, 0) self.doc:gotoPos(pos) end - -- add to jump history, distinguish jump from normal page turn -- NOTE: - -- even though we have called gotoPos() or gotoXPointer() previously, + -- even though we have called gotoPos() or gotoXPointer() previously, -- self.pos hasn't been updated yet here, so we can still make use of it. if not is_ignore_jump then if self.pos and math.abs(self.pos - pos) > height then self:addJump(prev_xpointer) end end - + self.doc:drawCurrentPage(self.nulldc, fb.bb) debug("## self.show_overlap "..self.show_overlap) @@ -344,13 +335,10 @@ function CREReader:_drawReadingInfo() renderUtf8Text(fb.bb, gapx, ypos+6, face, "...", true) end -- end of changes (NuPogodi) - ypos = ypos + 15 blitbuffer.progressBar(fb.bb, 10, ypos, G_width - 20, 15, 5, 4, load_percent/100, 8) end - - function CREReader:adjustCreReaderCommands() -- delete commands self.commands:delGroup("[joypad]") @@ -376,14 +364,6 @@ function CREReader:adjustCreReaderCommands() self.commands:del(KEY_N, MOD_SHIFT, "N") -- show highlights -- overwrite commands - - self.commands:add(KEY_P, MOD_SHIFT, "P", - "make screenshot", - function(cr) - Screen:screenshot() - end - ) - self.commands:addGroup(MOD_SHIFT.."< >",{ Keydef:new(KEY_PGBCK,MOD_SHIFT),Keydef:new(KEY_PGFWD,MOD_SHIFT), Keydef:new(KEY_LPGBCK,MOD_SHIFT),Keydef:new(KEY_LPGFWD,MOD_SHIFT)}, @@ -421,8 +401,9 @@ function CREReader:adjustCreReaderCommands() end InfoMessage:show("line spacing "..self.line_space_percent.."\%", 0) debug("line spacing set to", self.line_space_percent) - -- NuPogodi, 17.05.12: storing old document height + -- NuPogodi, 15.05.12: storing old document height self.old_doc_height = self.doc:getFullHeight() + -- end of changes (NuPogodi) self.doc:setDefaultInterlineSpace(self.line_space_percent) self:redrawCurrentPage() -- NuPogodi, 18.05.12: storing new height of document & refreshing TOC @@ -430,8 +411,8 @@ function CREReader:adjustCreReaderCommands() end ) local numeric_keydefs = {} - for i=1,10 do - numeric_keydefs[i]=Keydef:new(KEY_1+i-1, nil, tostring(i%10)) + for i=1,10 do + numeric_keydefs[i]=Keydef:new(KEY_1+i-1, nil, tostring(i%10)) end self.commands:addGroup("[1..0]", numeric_keydefs, "jump to *10% of document", @@ -458,11 +439,12 @@ function CREReader:adjustCreReaderCommands() item_array = face_list, current_entry = item_no - 1, } - - local item_no = fonts_menu:choose(0, G_height) + item_no = nil + item_no = fonts_menu:choose(0, G_height) debug(face_list[item_no]) - -- NuPogodi, 17.05.12: storing old document height + -- NuPogodi, 15.05.12: storing old document height self.old_doc_height = self.doc:getFullHeight() + -- end of changes (NuPogodi) if item_no then Screen:restoreFromSavedBB() self.doc:setFontFace(face_list[item_no]) @@ -477,8 +459,9 @@ function CREReader:adjustCreReaderCommands() self.commands:add(KEY_F, MOD_ALT, "F", "Toggle font bolder attribute", function(self) - -- NuPogodi, 17.05.12: storing old document height + -- NuPogodi, 15.05.12: storing old document height self.old_doc_height = self.doc:getFullHeight() + -- end of changes (NuPogodi) self.doc:toggleFontBolder() self:redrawCurrentPage() -- NuPogodi, 18.05.12: storing new height of document & refreshing TOC diff --git a/filechooser.lua b/filechooser.lua index eb79507d0..185879097 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -29,15 +29,13 @@ FileChooser = { current = 1, oldcurrent = 0, exception_message = nil, - -- NuPogodi, 20.05.12: added new parameters + -- NuPogodi, 20.05.12: added new parameters to make helppage available pagedirty = true, markerdirty = false, perpage, + clipboard = lfs.currentdir() .. "/clipboard", -- NO finishing slash } --- NuPogodi: some new auxiliary functions - --- make long headers for fit in title width by removing first characters function getProperTitleLength(txt,font_face,max_width) local tw = TextWidget:new({ text = txt, face = font_face}) -- 1st approximation for a point where to start title @@ -50,7 +48,7 @@ function getProperTitleLength(txt,font_face,max_width) end return string.sub(txt,n-1,-1) end --- return the battery level - either "XY%" or "?" (if error) + function BatteryLevel() local fn, battery = "./data/temporary", "?" -- NuPogodi, 18.05.12: This command seems to work even without Amazon Kindle framework @@ -62,39 +60,39 @@ function BatteryLevel() end return battery end --- draw the text-header for menues and add the clock & battery level + function DrawTitle(text,lmargin,y,height,color,font_face) - fb.bb:paintRect(lmargin, y+10, fb.bb:getWidth() - lmargin*2, height, color) + -- radius for round corners + local r = 6 + -- redefine to ignore the input for background color + color = 3 + fb.bb:paintRect(1, 1, fb.bb:getWidth() - 2, height - r, color) + blitbuffer.paintBorder(fb.bb, 1, height/2, fb.bb:getWidth() - 2, height/2, height/2, color, r) -- to have a horisontal gap between text & background rectangle - lmargin = lmargin + 10 t = BatteryLevel() .. os.date(" %H:%M") local tw = TextWidget:new({ text = t, face = font_face}) twidth = tw:getSize().w - renderUtf8Text(fb.bb, fb.bb:getWidth()-twidth-lmargin, y + height, font_face, t, true) + renderUtf8Text(fb.bb, fb.bb:getWidth()-twidth-lmargin, height-10, font_face, t, true) tw:free() tw = TextWidget:new({ text = text, face = font_face}) - local max_width = fb.bb:getWidth() - 2 * lmargin - twidth + local max_width = fb.bb:getWidth() - 2*lmargin - twidth if tw:getSize().w < max_width then - renderUtf8Text(fb.bb, lmargin, y + height, font_face, text, true) + renderUtf8Text(fb.bb, lmargin, height-10, font_face, text, true) else - tw:free() - -- separately draw the title prefix = ... - local tw = TextWidget:new({ text = "...", face = font_face}) - renderUtf8Text(fb.bb, lmargin, y + height, font_face, "...", true) - -- then define proper text length and draw it - local txt = getProperTitleLength(text,font_face,max_width-tw:getSize().w) - renderUtf8Text(fb.bb, lmargin+tw:getSize().w, y + height, font_face, txt, true) + local w = renderUtf8Text(fb.bb, lmargin, height-10, font_face, "...", true) + local txt = getProperTitleLength(text, font_face, max_width-w) + renderUtf8Text(fb.bb, w+lmargin, height-10, font_face, txt, true) end + tw:free() end --- just a footer + function DrawFooter(text,font_face,h) local y = G_height - 7 local x = (G_width / 2) - 50 renderUtf8Text(fb.bb, x, y, font_face, text, true) end --- to draw items in filechooser, filesearcher & filehistory --- TODO?: one can consider replacing icons by hotkeys (requires to redefine existing hotkeys) + function DrawFileItem(name,x,y,image) -- define icon file for if name == ".." then image = "upfolder" end @@ -105,7 +103,7 @@ function DrawFileItem(name,x,y,image) iw:paintTo(fb.bb, x, y - iw:getSize().h + 1) -- then drawing filenames local cface = Font:getFace("cfont", 22) - local xleft = x + iw:getSize().w + 9 -- 8-10 pixels = the gap between icon & filename + local xleft = x + iw:getSize().w + 9 -- the gap between icon & filename local width = fb.bb:getWidth() - xleft - x -- now printing the name if sizeUtf8Text(xleft, fb.bb:getWidth() - x, cface, name, true).x < width then @@ -116,7 +114,7 @@ function DrawFileItem(name,x,y,image) renderUtf8Text(fb.bb, handle.x + lgap + x, y, cface, " ...", true) end end --- end of NuPogodi's functions +-- end of old NuPogodi's functions function getAbsolutePath(aPath) local abs_path @@ -179,8 +177,8 @@ function FileChooser:setPath(newPath) end end --- NuPogodi, 20.05.12: rewrote this function in common way --- (with help page, AddAllCommands, etc.) +-- NuPogodi, 20.05.12: FileChooser:choose is totally rewritten +-- to make helppage with hotkeys available for users function FileChooser:choose(ypos, height) self.perpage = math.floor(height / self.spacing) - 2 @@ -263,8 +261,7 @@ function FileChooser:choose(ypos, height) end -- while end --- NuPogodi, 20.05.12: common-way addAllCommands() - +-- NuPogodi, 20.05.12: add available commands function FileChooser:addAllCommands() self.commands = Commands:new{} @@ -286,8 +283,8 @@ function FileChooser:addAllCommands() else self.current = self.items - (self.page-1)*self.perpage self.markerdirty = true - end -- if - end -- function + end + end ) self.commands:add({KEY_PGBCK, KEY_LPGBCK}, nil, "<", "goto previous page", @@ -298,8 +295,8 @@ function FileChooser:addAllCommands() else self.current = 1 self.markerdirty = true - end -- if - end -- function + end + end ) self.commands:add(KEY_FW_DOWN, nil, "joypad down", "goto next item", @@ -316,8 +313,8 @@ function FileChooser:addAllCommands() self.current = self.current + 1 self.markerdirty = true end - end -- if - end -- function + end + end ) self.commands:add(KEY_FW_UP, nil, "joypad up", "goto previous item", @@ -331,25 +328,20 @@ function FileChooser:addAllCommands() else self.current = self.current - 1 self.markerdirty = true - end -- if - end -- function + end + end ) self.commands:add({KEY_FW_RIGHT, KEY_I}, nil, "joypad right", "show document information", function(self) - local newdir = self.dirs[self.perpage*(self.page-1)+self.current] - if newdir == ".." then - showInfoMsgWithDelay("",1000,1) - elseif newdir then - showInfoMsgWithDelay("",1000,1) - else + if self:FullFileName() then FileInfo:show(self.path,self.files[self.perpage*(self.page-1)+self.current - #self.dirs]) self.pagedirty = true end - end -- function + end ) self.commands:add({KEY_ENTER, KEY_FW_PRESS}, nil, "Enter", - "open document", + "open document / goto folder", function(self) local newdir = self.dirs[self.perpage*(self.page-1)+self.current] if newdir == ".." then @@ -364,36 +356,57 @@ function FileChooser:addAllCommands() self.pagedirty = true end ) +-- NuPogodi, 23.05.12: modified to delete both files and empty folders self.commands:add(KEY_DEL, nil, "Del", - "delete document", + "delete selected item", function(self) - local dir_to_del = self.dirs[self.perpage*(self.page-1)+self.current] - if dir_to_del == ".." then - showInfoMsgWithDelay("",1000,1) - elseif dir_to_del then - showInfoMsgWithDelay("",1000,1) - else - local file_to_del=self.path.."/"..self.files[self.perpage*(self.page-1)+self.current - #self.dirs] + local folder = self.dirs[self.perpage*(self.page-1)+self.current] + if folder == ".." then + showInfoMsgWithDelay(" can not be deleted! ",2000,1) + elseif folder then InfoMessage:show("Press \'Y\' to confirm deleting... ",0) - while true do - ev = input.saveWaitForEvent() - ev.code = adjustKeyEvents(ev) - if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then - if ev.code == KEY_Y then - -- delete the file itself - os.execute("rm \""..file_to_del.."\"") - -- and its history file, if any - os.execute("rm \""..DocToHistory(file_to_del).."\"") - -- to avoid showing just deleted file - self:setPath(self.path) - end - self.pagedirty = true - break + if self:ReturnKey() == KEY_Y then + if lfs.rmdir(self.path.."/"..folder) then + self:setPath(self.path) + else + showInfoMsgWithDelay("This folder can not be deleted! ",2000,1) end - end -- while - end -- if + end + self.pagedirty = true + else + local file_to_del = self.path.."/"..self.files[self.perpage*(self.page-1)+self.current - #self.dirs] + InfoMessage:show("Press \'Y\' to confirm deleting... ",0) + if self:ReturnKey() == KEY_Y then + -- delete the file itself + os.execute("rm "..self:InQuotes(file_to_del)) + -- and its history file, if any + os.execute("rm "..self:InQuotes(DocToHistory(file_to_del))) + -- to avoid showing just deleted file + self:setPath(self.path) + end + self.pagedirty = true + end -- if folder == ".." end -- function ) +-- NuPogodi, 24.05.12: Added function to rename documents (extention comes from the old file) + self.commands:add(KEY_R, MOD_SHIFT, "R", + "rename document", + function(self) + local oldname = self:FullFileName() + if oldname then + local newname = InputBox:input(0, 0, "New filename:", "without extention", true) + if newname then + local ext = string.lower(string.match(oldname, ".+%.([^.]+)") or "") + newname = self.path.."/"..newname..'.'..ext + os.rename(oldname, newname) + os.rename(DocToHistory(oldname), DocToHistory(newname)) + self:setPath(self.path) + end + self.pagedirty = true + end + end + ) +-- end of changes (NuPogodi) self.commands:add({KEY_F, KEY_AA}, nil, "F", "goto font menu", function(self) @@ -428,31 +441,96 @@ function FileChooser:addAllCommands() self.commands:add(KEY_L, nil, "L", "show last documents", function(self) + lfs.mkdir("./history/") FileHistory:init() FileHistory:choose("") self.pagedirty = true return nil end - ) + ) self.commands:add(KEY_S, nil, "S", "search among files", function(self) - local keywords = InputBox:input(fb.bb:getHeight()-100, 100, "Search:") + local keywords = InputBox:input(0, 0, "Search:") if keywords then InfoMessage:show("Searching... ",0) FileSearcher:init( self.path ) FileSearcher:choose(keywords) end - self.pagedirty = true + self.pagedirty = true end -- function ) + +-- NuPogodi, 23.05.12: new functions to manipulate (copy & move) files via clipboard + self.commands:add(KEY_C, MOD_SHIFT, "C", + "copy document to \'clipboard\'", + function(self) + local file = self:FullFileName() + if file then + lfs.mkdir(self.clipboard) + os.execute("cp "..self:InQuotes(file).." "..self.clipboard) + local fn = self.files[self.perpage*(self.page-1)+self.current - #self.dirs] + os.execute("cp "..self:InQuotes(DocToHistory(file)).." " + ..self:InQuotes(DocToHistory(self.clipboard.."/"..fn)) ) + showInfoMsgWithDelay("file is copied to clipboard ", 1000, 1) + end + end + ) + self.commands:add(KEY_X, MOD_SHIFT, "X", + "move document to \'clipboard\'", + function(self) + local file = self:FullFileName() + if file then + lfs.mkdir(self.clipboard) + os.execute("mv "..self:InQuotes(file).." "..self.clipboard) + local fn = self.files[self.perpage*(self.page-1)+self.current - #self.dirs] + os.rename(DocToHistory(file), DocToHistory(self.clipboard.."/"..fn)) + InfoMessage:show("file is moved to clipboard ", 0) + self:setPath(self.path) + self.pagedirty = true + end + end + ) + self.commands:add(KEY_V, MOD_SHIFT, "V", + "paste documents from \'clipboard\'", + function(self) + InfoMessage:show("moving file(s) from clipboard ", 0) + for f in lfs.dir(self.clipboard) do + if lfs.attributes(self.clipboard.."/"..f, "mode") == "file" then + os.rename(self.clipboard.."/"..f, self.path.."/"..f) + os.rename(DocToHistory(self.clipboard.."/"..f), DocToHistory(self.path.."/"..f)) + end + end + self:setPath(self.path) + self.pagedirty = true + end + ) + self.commands:add(KEY_B, MOD_SHIFT, "B", + "show content of \'clipboard\'", + function(self) + lfs.mkdir(self.clipboard) + self:setPath(self.clipboard) + -- TODO: exit back from clipboard to last folder - Redefine Exit on FW_Right? + self.pagedirty = true + end + ) + self.commands:add(KEY_N, MOD_SHIFT, "N", + "make new folder", + function(self) + local folder = InputBox:input(0, 0, "New Folder:") + if folder then + if lfs.mkdir(self.path.."/"..folder) then + self:setPath(self.path) + end + end + self.pagedirty = true + end + ) +-- end of changes (NuPogodi) self.commands:add(KEY_P, MOD_SHIFT, "P", "make screenshot", function(self) - os.execute("mkdir ".."/mnt/us/kindlepdfviewer/screenshots") - local d = os.date("%Y%m%d%H%M%S") - showInfoMsgWithDelay("making screenshot... ", 1000, 1) - os.execute("dd ".."if=/dev/fb0 ".."of=/mnt/us/kindlepdfviewer/screenshots/" .. d .. ".raw") + Screen:screenshot() end ) self.commands:add({KEY_BACK, KEY_HOME}, nil, "Back", @@ -461,5 +539,35 @@ function FileChooser:addAllCommands() return "break" end ) - end + +-- NuPogodi, 23.05.12: returns full filename or nil (if folder) +function FileChooser:FullFileName() + local file + local folder = self.dirs[self.perpage*(self.page-1)+self.current] + if folder == ".." then + showInfoMsgWithDelay(" ",1000,1) + elseif folder then + showInfoMsgWithDelay(" ",1000,1) + else + file=self.path.."/"..self.files[self.perpage*(self.page-1)+self.current - #self.dirs] + end + return file +end +-- returns the keycode of released key and (if debug) shows the keycode on screen +function FileChooser:ReturnKey(debug) + while true do + ev = input.saveWaitForEvent() + ev.code = adjustKeyEvents(ev) + if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then + break + end + end + if debug then showInfoMsgWithDelay("Keycode = "..ev.code,1000,1) end + return ev.code +end + +function FileChooser:InQuotes(text) + return "\""..text.."\"" +end + diff --git a/fileinfo.lua b/fileinfo.lua index 9e220a330..aee24d955 100644 --- a/fileinfo.lua +++ b/fileinfo.lua @@ -16,7 +16,6 @@ FileInfo = { foot_H = 28, -- horisontal margin margin_H = 10, - -- state buffer result = {}, files = {}, @@ -30,37 +29,54 @@ FileInfo = { function FileInfo:FileCreated(fname,attr) return os.date("%d %b %Y, %H:%M:%S", lfs.attributes(fname,attr)) end - -function FileInfo:FileSize(fname) - local size = lfs.attributes(fname,"size") +-- NuPogodi, 26.05.12: a bit changed to return string from size +function FileInfo:FileSize(size) if size < 1024 then return size.." Bytes" - elseif size < 1048576 then - return string.format("%.2f", size/1024).."KB \("..size.." Bytes\)" + elseif size < 2^20 then + return string.format("%.2f", size/2^10).."KB \("..size.." Bytes\)" else - return string.format("%.2f", size/1048576).."MB \("..size.." Bytes\)" + return string.format("%.2f", size/2^20).."MB \("..size.." Bytes\)" end -end +end -- end of changes (NuPogodi, 26.05.12) function FileInfo:init(path,fname) self.pathfile = path.."/"..fname self.result = {} self:addAllCommands() - + local info_entry = {dir = "Name", name = fname} table.insert(self.result, info_entry) info_entry = {dir = "Path", name = path} table.insert(self.result, info_entry) - info_entry = {dir = "Size", name = FileInfo:FileSize(self.pathfile)} + -- NuPogodi, 26.05.12: now one has to call FileInfo:FileSize(integer) + info_entry = {dir = "Size", name = FileInfo:FileSize(lfs.attributes(self.pathfile,"size"))} table.insert(self.result, info_entry) - -- empty line - --info_entry = {dir = " ", name = " "} - --table.insert(self.result, info_entry) + -- NuPogodi, 26.05.12: size & filename of unzipped entry for zips + if string.lower(string.match(fname, ".+%.([^.]+)")) == "zip" then + local outfile = "./data/zip_content" + local l, s = 1, "" + os.execute("unzip ".."-l \""..self.pathfile.."\" > "..outfile) + if io.open(outfile, "r") then + for lines in io.lines(outfile) do + if l == 4 then s = lines break else l = l + 1 end + end + -- due to rewriting FileInfo:FileSize(integer), one can use it now + info_entry = { dir = "Unpacked", name = FileInfo:FileSize(tonumber(string.sub(s,1,11))) } + table.insert(self.result, info_entry) + --[[ TODO: When the fileentry inside zips is encoded as ANSI (codes 128-255) + any attempt to print such fileentry causes crash by drawing!!! When fileentries + are encoded as UTF8, everything seems fine + info_entry = { dir = "Content", name = string.sub(s,29,-1) } + table.insert(self.result, info_entry) ]] + end + end -- end of changes (NuPogodi, 26.05.12) + info_entry = {dir = "Created", name = FileInfo:FileCreated(self.pathfile,"change")} table.insert(self.result, info_entry) info_entry = {dir = "Modified", name = FileInfo:FileCreated(self.pathfile,"modification")} table.insert(self.result, info_entry) - + -- if the document was already opened local history = DocToHistory(self.pathfile) local file, msg = io.open(history,"r") @@ -85,7 +101,7 @@ function FileInfo:init(path,fname) end end end - + self.items = #self.result -- now calculating the horizontal space for left column local tw, width @@ -102,12 +118,11 @@ function FileInfo:show(path,name) -- it's necessary for last documents if not io.open(path.."/"..name,"r") then return nil end -- then goto main functions - self.perpage = math.floor(G_height / self.spacing) - 2 + self.perpage = math.floor(G_height / self.spacing) - 2 self.pagedirty = true self.markerdirty = false FileInfo:init(path,name) - while true do local cface = Font:getFace("cfont", 22) local lface = Font:getFace("tfont", 22) @@ -117,51 +132,28 @@ function FileInfo:show(path,name) if self.pagedirty then self.markerdirty = true -- gap between title rectangle left & left text drawing point - local xgap = 10 fb.bb:paintRect(0, 0, G_width, G_height, 0) -- draw menu title - DrawTitle("Document Information",self.margin_H,0,self.title_H,3,tface) - local c + DrawTitle("Document Information",self.margin_H,0,self.title_H,4,tface) -- position of left column - local x1 = self.margin_H + xgap + local x1 = self.margin_H -- position of right column + its width + a small gap between columns local x2 = x1 + self.lcolumn_width + 15 -- y-position correction because of the multiline drawing - local dy = 5 + local dy, c = 5, 1 for c = 1, self.perpage do local i = (self.page - 1) * self.perpage + c if i <= self.items then y = self.title_H + self.spacing * c + dy renderUtf8Text(fb.bb, x1, y, lface, self.result[i].dir, true) - -- set interline spacing = 1.65 of the char height - -- or directly in pixels (if it exceeds 5) dy = dy + renderUtf8Multiline(fb.bb, x2, y, cface, self.result[i].name, true, - G_width - self.margin_H - x2 - xgap, 1.65).y - y + G_width - self.margin_H - x2, 1.65).y - y end end -- draw footer all_page = math.ceil(self.items/self.perpage) DrawFooter("Page "..self.page.." of "..all_page,fface,self.foot_H) end - ---[[ -- may be used in future for selecting some of displayed items - if self.markerdirty then - if not self.pagedirty then - if self.oldcurrent > 0 then - y = self.title_H + (self.spacing * self.oldcurrent) + 12 - fb.bb:paintRect(self.margin_H, y, G_width - 2 * self.margin_H, 3, 15) - fb:refresh(1, self.margin_H, y, G_width - 2 * self.margin_H, 3) - end - end - -- draw new marker line - y = self.title_H + (self.spacing * self.current) + 12 - fb.bb:paintRect(self.margin_H, y, G_width - 2 * self.margin_H, 3, 15) - if not self.pagedirty then - fb:refresh(1, self.margin_H, y, G_width - 2 * self.margin_H, 3) - end - self.oldcurrent = self.current - self.markerdirty = false - end ]] if self.pagedirty then fb:refresh(0) @@ -195,7 +187,13 @@ end function FileInfo:addAllCommands() self.commands = Commands:new{} - -- show help page + + self.commands:add({KEY_SPACE}, nil, "Space", + "refresh page manually", + function(self) + self.pagedirty = true + end + ) self.commands:add(KEY_H,nil,"H", "show help page", function(self) @@ -203,14 +201,6 @@ function FileInfo:addAllCommands() self.pagedirty = true end ) - -- make screenshot - self.commands:add(KEY_P, MOD_SHIFT, "P", - "make screenshot", - function(self) - Screen:screenshot() - end - ) - -- recent documents self.commands:add(KEY_L, nil, "L", "last documents", function(self) @@ -219,11 +209,9 @@ function FileInfo:addAllCommands() self.pagedirty = true end ) - -- fonts self.commands:add({KEY_F, KEY_AA}, nil, "F", "font menu", function(self) - -- NuPogodi, 18.05.12: define the number of the current font in face_list local item_no = 0 local face_list = Font:getFontList() while face_list[item_no] ~= Font.fontmap.cfont and item_no < #face_list do @@ -233,7 +221,6 @@ function FileInfo:addAllCommands() local fonts_menu = SelectMenu:new{ menu_title = "Fonts Menu", item_array = face_list, - -- NuPogodi, 18.05.12: define selected item current_entry = item_no - 1, } local re, font = fonts_menu:choose(0, G_height) @@ -278,24 +265,17 @@ function FileInfo:addAllCommands() self.pagedirty = true end ) - self.commands:add({KEY_BACK, KEY_HOME, KEY_FW_LEFT}, nil, "Back", + -- make screenshot + self.commands:add(KEY_P, MOD_SHIFT, "P", + "make screenshot", + function(self) + Screen:screenshot() + end + ) + self.commands:add({KEY_BACK, KEY_FW_LEFT}, nil, "Back", "back", function(self) return "break" end ) - self.commands:add({KEY_SPACE}, nil, "Space", - "refresh page manually", - function(self) - self.pagedirty = true - end - ) ---[[ self.commands:add({KEY_B}, nil, "B", - "file browser", - function(self) - --FileChooser:setPath(".") - FileChooser:choose(0, G_height) - self.pagedirty = true - end - )]] end diff --git a/inputbox.lua b/inputbox.lua index 5a5379e61..904333428 100644 --- a/inputbox.lua +++ b/inputbox.lua @@ -3,7 +3,6 @@ require "rendertext" require "keys" require "graphics" - ---------------------------------------------------- -- General inputbox ---------------------------------------------------- @@ -12,17 +11,12 @@ InputBox = { -- Class vars: h = 100, input_slot_w = nil, - input_start_x = 145, + input_start_x = nil, input_start_y = nil, input_cur_x = nil, -- points to the start of next input pos input_bg = 0, - input_string = "", - - shiftmode = false, - altmode = false, - cursor = nil, -- font for displaying input content @@ -32,6 +26,21 @@ InputBox = { fwidth = 15, commands = nil, initialized = false, + + -- NuPogodi, 25.05.12: for full UTF8 support + vk_bg = 3, + charlist = {}, -- table to store input string + charpos = 1, + INPUT_KEYS = {}, -- table to store layouts + -- values to control layouts: min & max + min_layout = 2, + max_layout = 9, + -- default layout = 2, i.e. shiftmode = symbolmode = utf8mode = false + layout = 2, + -- now bits to toggle the layout mode + shiftmode = false, -- toggle chars <> capitals, lowest bit in (layout-2) + symbolmode = false, -- toggle chars <> symbols, middle bit in (layout-2) + utf8mode = false, -- toggle english <> national, highest bit in (layout-2) } function InputBox:new(o) @@ -41,153 +50,118 @@ function InputBox:new(o) return o end -function InputBox:init() - if not self.initialized then - self:addAllCommands() - self.initialized = true - end -end - function InputBox:refreshText() -- clear previous painted text - fb.bb:paintRect(140, self.input_start_y-19, - self.input_slot_w, self.fheight, self.input_bg) + fb.bb:paintRect(self.input_start_x-5, self.input_start_y-19, self.input_slot_w, self.fheight, self.input_bg) -- paint new text - renderUtf8Text(fb.bb, self.input_start_x, self.input_start_y, - self.face, - self.input_string, 0) + renderUtf8Text(fb.bb, self.input_start_x, self.input_start_y, self.face, self.input_string, true) end function InputBox:addChar(char) self.cursor:clear() - -- draw new text - local cur_index = (self.cursor.x_pos + 3 - self.input_start_x) - / self.fwidth - self.input_string = self.input_string:sub(1, cur_index)..char.. - self.input_string:sub(cur_index+1) + local cur_index = (self.cursor.x_pos + 3 - self.input_start_x) / self.fwidth + table.insert(self.charlist, self.charpos, char) + self.charpos = self.charpos + 1 + self.input_string = self:CharlistToString() self:refreshText() self.input_cur_x = self.input_cur_x + self.fwidth -- draw new cursor self.cursor:moveHorizontal(self.fwidth) self.cursor:draw() - - fb:refresh(1, self.input_start_x-5, self.input_start_y-25, - self.input_slot_w, self.h-25) + fb:refresh(1, self.input_start_x-5, self.input_start_y-25, self.input_slot_w, self.h-25) end function InputBox:delChar() - if self.input_start_x == self.input_cur_x then - return - end - - local cur_index = (self.cursor.x_pos + 3 - self.input_start_x) - / self.fwidth + if self.input_start_x == self.input_cur_x then return end + local cur_index = (self.cursor.x_pos + 3 - self.input_start_x) / self.fwidth if cur_index == 0 then return end - self.cursor:clear() - -- draw new text - self.input_string = self.input_string:sub(1, cur_index-1).. - self.input_string:sub(cur_index+1, -1) + self.charpos = self.charpos - 1 + table.remove(self.charlist, self.charpos) + self.input_string = self:CharlistToString() self:refreshText() 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, - self.fwidth, self.fheight, self.input_bg) + -- fill last character with blank rectangle + 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) - -- draw new cursor self.cursor:moveHorizontal(-self.fwidth) self.cursor:draw() - - fb:refresh(1, self.input_start_x-5, self.input_start_y-25, - self.input_slot_w, self.h-25) + fb:refresh(1, self.input_start_x-5, self.input_start_y-25, self.input_slot_w, self.h-25) end function InputBox:clearText() self.cursor:clear() self.input_string = "" + self.charlist = {} + self.charpos = 1 self:refreshText() self.cursor.x_pos = self.input_start_x - 3 self.cursor:draw() - - fb:refresh(1, self.input_start_x-5, self.input_start_y-25, - self.input_slot_w, self.h-25) -end - -function InputBox:drawHelpMsg(ypos, w, h) - return + fb:refresh(1, self.input_start_x-5, self.input_start_y-25, self.input_slot_w, self.h-25) end 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) + local r = 6 -- round corners + fb.bb:paintRect(1, ypos+r, w, h - r, self.vk_bg) + blitbuffer.paintBorder(fb.bb, 1, ypos, fb.bb:getWidth() - 2, r, r, self.vk_bg, r) -- draw input title - renderUtf8Text(fb.bb, 35, self.input_start_y, self.face, - title, true) + self.input_start_y = ypos + 37 + -- draw the box title > estimate the start point for future text & the text slot width + self.input_start_x = 25 + renderUtf8Text(fb.bb, 15, self.input_start_y, self.face, title, true) + self.input_slot_w = fb.bb:getWidth() - self.input_start_x - 5 + -- draw input slot + fb.bb:paintRect(self.input_start_x - 5, ypos + 10, self.input_slot_w, h - 20, self.input_bg) end - ---------------------------------------------------------------------- -- InputBox:input() -- -- @title: input prompt for the box -- @d_text: default to nil (used to set default text in input slot) --- @is_hint: if this arg is true, default text will be used as hint --- message for input +-- @is_hint: if this arg is true, default text will be used as hint +-- message for input ---------------------------------------------------------------------- function InputBox:input(ypos, height, title, d_text, is_hint) - self:init() + -- To avoid confusion with old ypos & height parameters, I'd better define + -- my own position, at the bottom screen edge (NuPogodi, 26.05.12) + ypos = fb.bb:getHeight() - 165 + -- at first, draw titled box and content + local h, w = 55, fb.bb:getWidth() - 2 + self:drawBox(ypos, w, h, title) -- do some initilization self.ypos = ypos - self.h = height - self.input_start_y = ypos + 35 + self.h = 100 self.input_cur_x = self.input_start_x - self.input_slot_w = fb.bb:getWidth() - 170 - + self:addAllCommands() self.cursor = Cursor:new { x_pos = self.input_start_x - 3, y_pos = ypos + 13, h = 30, } - - - -- draw box and content - w = fb.bb:getWidth() - 40 - h = height - 45 - self:drawHelpMsg(ypos, w, h) - self:drawBox(ypos, w, h, title) if d_text then if is_hint then - -- print hint text - fb.bb:paintRect(140, self.input_start_y-19, - self.input_slot_w, self.fheight, self.input_bg) - renderUtf8Text(fb.bb, self.input_start_x+5, self.input_start_y, - self.face, - d_text, 0) - fb.bb:dimRect(140, self.input_start_y-19, - self.input_slot_w, self.fheight, self.input_bg) + -- print hint text + fb.bb:paintRect(self.input_start_x-5, self.input_start_y-19, self.input_slot_w, self.fheight, self.input_bg) + renderUtf8Text(fb.bb, self.input_start_x+5, self.input_start_y, self.face, d_text, 0) + fb.bb:dimRect(self.input_start_x-5, self.input_start_y-19, self.input_slot_w, self.fheight, self.input_bg) else - self.input_string = d_text - self.input_cur_x = self.input_cur_x + (self.fwidth * d_text:len()) - self.cursor.x_pos = self.cursor.x_pos + (self.fwidth * d_text:len()) + self.input_cur_x = self.input_cur_x + (self.fwidth * #self.charlist) + self.cursor.x_pos = self.cursor.x_pos + (self.fwidth * #self.charlist) self:refreshText() end end self.cursor:draw() - fb:refresh(1, 20, ypos, w, h) - + fb:refresh(1, 1, ypos, w, h) while true do local ev = input.saveWaitForEvent() ev.code = adjustKeyEvents(ev) if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then keydef = Keydef:new(ev.code, getKeyModifier()) debug("key pressed: "..tostring(keydef)) - command = self.commands:getByKeydef(keydef) if command ~= nil then debug("command to execute: "..tostring(command)) @@ -195,60 +169,184 @@ function InputBox:input(ypos, height, title, d_text, is_hint) else debug("command not found: "..tostring(command)) end - if ret_code == "break" then ret_code = nil break end end -- if end -- while - local return_str = self.input_string self.input_string = "" + self.charlist = {} + self.charpos = 1 return return_str end -function InputBox:addAllCommands() - if self.commands then - -- we only initialize once - return +function InputBox:setLayoutsTable() + -- trying to read the layout from the user-defined file "mykeyboard.lua" + local ok, stored = pcall(dofile,"./mykeyboard.lua") + if ok then + self.INPUT_KEYS = stored + else -- if an error happens, we use the default layout + self.INPUT_KEYS = { + { KEY_Q, "Q", "q", "1", "!", "Я", "я", "1", "!", }, + { KEY_W, "W", "w", "2", "?", "Ж", "ж", "2", "?", }, + { KEY_E, "E", "e", "3", "#", "Е", "е", "3", "«", }, + { KEY_R, "R", "r", "4", "@", "Р", "р", "4", "»", }, + { KEY_T, "T", "t", "5", "\%", "Т", "т", "5", ":", }, + { KEY_Y, "Y", "y", "6", "‰", "Ы", "ы", "6", ";", }, + { KEY_U, "U", "u", "7", "\'", "У", "у", "7", "~", }, + { KEY_I, "I", "i", "8", "`", "И", "и", "8", "\(",}, + { KEY_O, "O", "o", "9", ":", "О", "о", "9", "\)",}, + { KEY_P, "P", "p", "0", ";", "П", "п", "0", "=", }, + -- middle raw + { KEY_A, "A", "a", "+", "…", "А", "а", "Ш", "ш", }, + { KEY_S, "S", "s", "-", "_", "С", "с", "Ѕ", "ѕ", }, + { KEY_D, "D", "d", "*", "¦", "Д", "д", "Э", "э", }, + { KEY_F, "F", "f", "/", "|", "Ф", "ф", "Ю", "ю", }, + { KEY_G, "G", "g", "\\", "„", "Г", "г", "Ґ", "ґ", }, + { KEY_H, "H", "h", "=", "“", "Ч", "ч", "Ј", "ј", }, + { KEY_J, "J", "j", "<", "”", "Й", "й", "І", "і", }, + { KEY_K, "K", "k", "ˆ", "\"", "К", "к", "Ќ", "ќ", }, + { KEY_L, "L", "l", ">", "~", "Л", "л", "Љ", "љ", }, + -- lowest raw + { KEY_Z, "Z", "z", "\(", "$", "З", "з", "Щ", "щ", }, + { KEY_X, "X", "x", "\)", "€", "Х", "х", "№", "@", }, + { KEY_C, "C", "c", "\{", "¥", "Ц", "ц", "Џ", "џ", }, + { KEY_V, "V", "v", "\}", "£", "В", "в", "Ў", "ў", }, + { KEY_B, "B", "b", "\[", "‚", "Б", "б", "Ћ", "ћ", }, + { KEY_N, "N", "n", "\]", "‘", "Н", "н", "Њ", "њ", }, + { KEY_M, "M", "m", "&", "’", "М", "м", "Ї", "ї", }, + { KEY_DOT, ".", ",", ".", ",", ".", ",", "Є", "є", }, + -- Let us make key 'Space' the same for all layouts + { KEY_SPACE," ", " ", " ", " ", " ", " ", " ", " ", }, + -- Simultaneous pressing Alt + Q..P should also work properly + { KEY_1, "1", " ", " ", " ", "1", " ", " ", " ", }, + { KEY_2, "2", " ", " ", " ", "2", " ", " ", " ", }, + { KEY_3, "3", " ", " ", " ", "3", " ", " ", " ", }, + { KEY_4, "4", " ", " ", " ", "4", " ", " ", " ", }, + { KEY_5, "5", " ", " ", " ", "5", " ", " ", " ", }, + { KEY_6, "6", " ", " ", " ", "6", " ", " ", " ", }, + { KEY_7, "7", " ", " ", " ", "7", " ", " ", " ", }, + { KEY_8, "8", " ", " ", " ", "8", " ", " ", " ", }, + { KEY_9, "9", " ", " ", " ", "9", " ", " ", " ", }, + { KEY_0, "0", " ", " ", " ", "0", " ", " ", " ", }, + -- DXG keys + { KEY_SLASH,"/", "\\", "/", "\\", "/", "\\", "/", "\\", }, + } + end -- if ok +end + +function InputBox:DrawVKey(key,x,y,face,rx,ry,t,c) + blitbuffer.paintBorder(fb.bb, x-11, y-ry-8, rx, ry, t, c, ry) + renderUtf8Text(fb.bb, x, y, face, key, true) +end + +-- this function is designed for K3 keyboard, portrait mode +-- TODO: support for other Kindle models & orientations? + +function InputBox:DrawVirtualKeyboard() + local vy = fb.bb:getHeight()-15 + -- dx, dy = xy-distance between the button rows + -- lx - position of left button column + -- r, c, t = radius, color and thickness of circles around chars + -- h = y-correction to adjust cicles & chars + local dx, dy, lx, r, c, bg, t = 51, 36, 20, 17, 6, self.vk_bg, 2 + + fb.bb:paintRect(1, fb.bb:getHeight()-120, fb.bb:getWidth()-2, 120, bg) + -- font to draw characters - MUST have UTF8-support + local vkfont = Font:getFace("infont", 22) + for k,v in ipairs(self.INPUT_KEYS) do + if v[1] >= KEY_Q and v[1] <= KEY_P then -- upper raw + self:DrawVKey(v[self.layout], lx+(v[1]-KEY_Q)*dx, vy-2*dy, vkfont, r, r, t, c) + elseif v[1] >= KEY_A and v[1] <= KEY_L then -- middle raw + self:DrawVKey(v[self.layout], lx+(v[1]-KEY_A)*dx, vy-dy, vkfont, r, r, t, c) + elseif v[1] >= KEY_Z and v[1] <= KEY_M then -- lower raw + self:DrawVKey(v[self.layout], lx+(v[1]-KEY_Z)*dx, vy, vkfont, r, r, t, c) + elseif v[1] == KEY_DOT then + self:DrawVKey(v[self.layout], lx + 7*dx, vy, vkfont, r, r, t, c) + end end - self.commands = Commands:new{} - - INPUT_KEYS = { - {KEY_Q, "q"}, {KEY_W, "w"}, {KEY_E, "e"}, {KEY_R, "r"}, {KEY_T, "t"}, - {KEY_Y, "y"}, {KEY_U, "u"}, {KEY_I, "i"}, {KEY_O, "o"}, {KEY_P, "p"}, + -- the rest symbols (manually) + local smfont = Font:getFace("infont", 14) + -- Del + blitbuffer.paintBorder(fb.bb, lx+9*dx-10, vy-dy-r-8, r, r, t, c, r) + renderUtf8Text(fb.bb, lx-5+9*dx, vy-dy-3, smfont, "Del", true) + -- Sym + blitbuffer.paintBorder(fb.bb, lx+8*dx-10, vy-r-8, r, r, t + (r-t)*number(self.symbolmode), c, r) + renderUtf8Text(fb.bb, lx-5+8*dx, vy-3, smfont, "Sym", true) + -- Enter + blitbuffer.paintBorder(fb.bb, lx+9*dx-10, vy-r-8, r, r, t, c, r) + renderUtf8Text(fb.bb, lx+9*dx, vy-2, vkfont, "«", true) + -- Menu + blitbuffer.paintBorder(fb.bb, lx+10*dx-8, vy-2*dy-r-8, r+50, r, t+(r-t)*number(self.utf8mode), c, r) + renderUtf8Text(fb.bb, lx+10*dx+11, vy-2*dy-3, smfont, "Menu", true) + -- fiveway + local h=dy+2*r-2 + blitbuffer.paintBorder(fb.bb, lx+10*dx-8, vy-dy-r-6, h, h, 9, c, r) + renderUtf8Text(fb.bb, lx+10*dx+22, vy-20, smfont, (self.layout-1), true) + fb:refresh(1, 1, fb.bb:getHeight()-120, fb.bb:getWidth()-2, 120) +end - {KEY_A, "a"}, {KEY_S, "s"}, {KEY_D, "d"}, {KEY_F, "f"}, {KEY_G, "g"}, - {KEY_H, "h"}, {KEY_J, "j"}, {KEY_K, "k"}, {KEY_L, "l"}, - - {KEY_Z, "z"}, {KEY_X, "x"}, {KEY_C, "c"}, {KEY_V, "v"}, {KEY_B, "b"}, - {KEY_N, "n"}, {KEY_M, "m"}, - - {KEY_1, "1"}, {KEY_2, "2"}, {KEY_3, "3"}, {KEY_4, "4"}, {KEY_5, "5"}, - {KEY_6, "6"}, {KEY_7, "7"}, {KEY_8, "8"}, {KEY_9, "9"}, {KEY_0, "0"}, - - {KEY_SPACE, " "}, - - -- DXG keys - {KEY_DOT, "."}, {KEY_SLASH, "/"}, - } - for k,v in ipairs(INPUT_KEYS) do - self.commands:add(v[1], nil, "", - "input "..v[2], +function InputBox:addCharCommands(layout) + -- at first, let's define self.layout and extract separate bits as layout modes + if layout then + -- to be sure layout is selected properly + layout = math.max(layout, self.min_layout) + layout = math.min(layout, self.max_layout) + self.layout = layout + -- fill the layout modes + layout = (layout - 2) % 4 + self.shiftmode = (layout == 1 or layout == 3) + self.symbolmode = (layout == 2 or layout == 3) + self.utf8mode = (self.layout > 5) + else -- or, without input parameter, restore layout from current layout modes + self.layout = 2 + number(self.shiftmode) + 2 * number(self.symbolmode) + 4 * number(self.utf8mode) + end + -- adding the commands + for k,v in ipairs(self.INPUT_KEYS) do + -- seems to work without removing old commands, + self.commands:del(v[1], nil, "") + -- just redefining existing ones + self.commands:add(v[1], nil, "", "input "..v[self.layout], function(self) - self:addChar(v[2]) + self:addChar(v[self.layout]) end ) end + self:DrawVirtualKeyboard() +end +function InputBox:CharlistToString() + local s, i = "" + for i=1, #self.charlist do + s = s .. self.charlist[i] + end + return s +end + +function number(bool) + return bool and 1 or 0 +end + +function InputBox:addAllCommands() + -- we only initialize once + if self.commands then + self:DrawVirtualKeyboard() + return + end + self:setLayoutsTable() + self.commands = Commands:new{} + -- adding command to enter character commands + self:addCharCommands() + -- adding the rest commands (independent of the selected layout) self.commands:add(KEY_FW_LEFT, nil, "", "move cursor left", function(self) if (self.cursor.x_pos + 3) > self.input_start_x then self.cursor:moveHorizontalAndDraw(-self.fwidth) - fb:refresh(1, self.input_start_x-5, self.ypos, - self.input_slot_w, self.h) + self.charpos = self.charpos - 1 + fb:refresh(1, self.input_start_x-5, self.ypos, self.input_slot_w, self.h) end end ) @@ -257,8 +355,8 @@ function InputBox:addAllCommands() function(self) if (self.cursor.x_pos + 3) < self.input_cur_x then self.cursor:moveHorizontalAndDraw(self.fwidth) - fb:refresh(1, self.input_start_x-5, self.ypos, - self.input_slot_w, self.h) + self.charpos = self.charpos + 1 + fb:refresh(1, self.input_start_x-5, self.ypos, self.input_slot_w, self.h) end end ) @@ -290,112 +388,56 @@ function InputBox:addAllCommands() return "break" end ) + self.commands:add(KEY_P, MOD_SHIFT, "P", + "make screenshot", + function(self) + Screen:screenshot() + end + ) + self.commands:add(KEY_FW_DOWN, nil, "joypad down", + "goto next keyboard layout", + function(self) + if self.layout == self.max_layout then self:addCharCommands(self.min_layout) + else self:addCharCommands(self.layout+1) end + end + ) + self.commands:add(KEY_FW_UP, nil, "joypad up", + "goto previous keyboard layout", + function(self) + if self.layout == self.min_layout then self:addCharCommands(self.max_layout) + else self:addCharCommands(self.layout-1) end + end + ) + self.commands:add(KEY_AA, nil, "Aa", + "toggle layout: chars <> CHARS", + function(self) + self.shiftmode = not self.shiftmode + self:addCharCommands() + end + ) + self.commands:add(KEY_SYM, nil, "Sym", + "toggle layout: chars <> symbols", + function(self) + self.symbolmode = not self.symbolmode + self:addCharCommands() + end + ) + self.commands:add(KEY_MENU, nil, "Menu", + "toggle layout: english <> national", + function(self) + self.utf8mode = not self.utf8mode + self:addCharCommands() + end + ) end - ---------------------------------------------------- -- Inputbox for numbers only -- Designed by eLiNK ---------------------------------------------------- NumInputBox = InputBox:new{ - initialized = false, - commands = Commands:new{}, + symbolmode = true, + layout = 4, + charlist = {} } - -function NumInputBox:addAllCommands() - self.commands = Commands:new{} - - INPUT_NUM_KEYS = { - {KEY_Q, "1"}, {KEY_W, "2"}, {KEY_E, "3"}, {KEY_R, "4"}, {KEY_T, "5"}, - {KEY_Y, "6"}, {KEY_U, "7"}, {KEY_I, "8"}, {KEY_O, "9"}, {KEY_P, "0"}, - - {KEY_1, "1"}, {KEY_2, "2"}, {KEY_3, "3"}, {KEY_4, "4"}, {KEY_5, "5"}, - {KEY_6, "6"}, {KEY_7, "7"}, {KEY_8, "8"}, {KEY_9, "9"}, {KEY_0, "0"}, - } - for k,v in ipairs(INPUT_NUM_KEYS) do - self.commands:add(v[1], nil, "", - "input "..v[2], - function(self) - self:addChar(v[2]) - end - ) - end -- for - - self.commands:add(KEY_FW_LEFT, nil, "", - "move cursor left", - function(self) - if (self.cursor.x_pos + 3) > self.input_start_x then - self.cursor:moveHorizontalAndDraw(-self.fwidth) - fb:refresh(1, self.input_start_x-5, self.ypos, - self.input_slot_w, self.h) - end - end - ) - self.commands:add(KEY_FW_RIGHT, nil, "", - "move cursor right", - function(self) - if (self.cursor.x_pos + 3) < self.input_cur_x then - self.cursor:moveHorizontalAndDraw(self.fwidth) - fb:refresh(1, self.input_start_x-5, self.ypos, - self.input_slot_w, self.h) - end - end - ) - self.commands:add({KEY_ENTER, KEY_FW_PRESS}, nil, "", - "submit input content", - function(self) - if self.input_string == "" then - self.input_string = nil - end - return "break" - end - ) - self.commands:add(KEY_DEL, nil, "", - "delete one character", - function(self) - self:delChar() - end - ) - self.commands:add(KEY_DEL, MOD_SHIFT, "", - "empty inputbox", - function(self) - self:clearText() - end - ) - self.commands:add({KEY_BACK, KEY_HOME}, nil, "", - "cancel inputbox", - function(self) - self.input_string = nil - return "break" - end - ) -end - -function NumInputBox:drawHelpMsg(ypos, w, h) - local w = 415 - local y = ypos - 60 - local x = (G_width - w) / 2 - local h = 50 - local bw = 2 - local face = Font:getFace("scfont", 22) - - fb.bb:paintRect(x, y, w, h, 15) - fb.bb:paintRect(x+bw, y+bw, w-2*bw, h-2*bw, 0) - - local font_y = y + 22 - local font_x = x + 22 - INPUT_NUM_KEYS = { - {"Q", "1"}, {"W", "2"}, {"E", "3"}, {"R", "4"}, {"T", "5"}, - {"Y", "6"}, {"U", "7"}, {"I", "8"}, {"O", "9"}, {"P", "0"}, - } - for k,v in ipairs(INPUT_NUM_KEYS) do - renderUtf8Text(fb.bb, font_x, font_y, face, - v[1], true) - renderUtf8Text(fb.bb, font_x, font_y + 22, face, - v[2], true) - font_x = font_x + 40 - end - - fb:refresh(1, x, y, w, h) -end diff --git a/screen.lua b/screen.lua index 0d2dc35aa..8c25fa96a 100644 --- a/screen.lua +++ b/screen.lua @@ -108,10 +108,8 @@ function Screen:restoreFromBB(bb) end function Screen:screenshot() - --@TODO convert bitmap to png or jpeg 30.04 2012 (houqp) - os.execute("mkdir ".."/mnt/us/kindlepdfviewer/screenshots") - local d = os.date("%Y%m%d%H%M%S") - os.execute("dd if=/dev/fb0 of=/mnt/us/kindlepdfviewer/screenshots/" .. d .. ".raw") - showInfoMsgWithDelay("screenshot "..d.." created", 1000, 1) + lfs.mkdir("./screenshots") + local d = os.date("%Y%m%d%H%M%S") + showInfoMsgWithDelay("making screenshot... ", 1000, 1) + os.execute("dd ".."if=/dev/fb0 ".."of=/mnt/us/kindlepdfviewer/screenshots/" .. d .. ".raw") end -