From b49a3381211a607c480a64850a6fe59b4b6da8e1 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 14 Aug 2013 05:17:25 -0400 Subject: [PATCH 1/4] add extend method to widget --- frontend/ui/widget/base.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/frontend/ui/widget/base.lua b/frontend/ui/widget/base.lua index 6d4d85cb4..b66b6e49d 100644 --- a/frontend/ui/widget/base.lua +++ b/frontend/ui/widget/base.lua @@ -43,10 +43,24 @@ rather than class variables. --]] Widget = EventListener:new() -function Widget:new(o) +--[[ +Use this method to define a class that's inherited from current class. +It only setup the metabale (or prototype chain) and will not initiatie +a real instance, i.e. call self:init() +--]] +function Widget:extend(o) local o = o or {} setmetatable(o, self) self.__index = self + return o +end + +--[[ +Use this method to initiatie a instance of a class, don't use it for class +definition. +--]] +function Widget:new(o) + o = self:extend(o) -- Both o._init and o.init are called on object create. But o._init is used -- for base widget initialization (basic component used to build other -- widgets). While o.init is for higher level widgets, for example Menu From c66429c903a846b2350e057b89bc5b250bb67660 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 14 Aug 2013 05:18:09 -0400 Subject: [PATCH 2/4] add is_popout and no_title to menu widget --- frontend/ui/widget/menu.lua | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index fc157a2df..41649daed 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -238,6 +238,9 @@ Menu = FocusManager:new{ -- set this to true to not paint as popup menu is_borderless = false, + -- if you want to embed the menu widget into another widget, set + -- this to false + is_popout = true, -- set this to true to add close button has_close_button = true, -- close_callback is a function, which is executed when menu is closed @@ -260,7 +263,7 @@ function Menu:_recalculateDimen() -- we need to substract border, margin and padding self.item_dimen.w = self.item_dimen.w - 14 end - self.perpage = math.floor(self.dimen.h / self.item_dimen.h) - 2 + self.perpage = math.floor((self.dimen.h - self.dimen.x) / self.item_dimen.h) - 2 self.page_num = math.ceil(#self.item_table / self.perpage) end @@ -310,12 +313,15 @@ function Menu:init() self.page_info_text, self.page_info_right_chev } + -- group for menu layout local content = VerticalGroup:new{ - self.title_bar, self.item_group, self.page_info, } + if not self.no_title then + table.insert(content, 1, self.title_bar) + end -- maintain reference to content so we can change it later self.content_group = content @@ -348,16 +354,19 @@ function Menu:init() menu = self, }) end - self.ges_events.TapCloseAllMenus = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = Screen:getHeight(), + -- watch for outer region if it's a self contained widget + if self.is_popout then + self.ges_events.TapCloseAllMenus = { + GestureRange:new{ + ges = "tap", + range = Geom:new{ + x = 0, y = 0, + w = Screen:getWidth(), + h = Screen:getHeight(), + } } } - } + end self.ges_events.Swipe = { GestureRange:new{ ges = "swipe", @@ -399,6 +408,11 @@ function Menu:updateItems(select_number) self.content_group:resetLayout() self:_recalculateDimen() + -- default to select the first item + if not select_number then + select_number = 1 + end + for c = 1, self.perpage do -- calculate index in item_table local i = (self.page - 1) * self.perpage + c From aef2c4123eb07a9394226df8c0b7108725aaedc8 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 14 Aug 2013 05:19:01 -0400 Subject: [PATCH 3/4] fix Menu widget initialization on inheritance bug in filechooser --- frontend/ui/widget/filechooser.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index 38d70bbff..fc17fd1fd 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -1,8 +1,9 @@ require "ui/widget/menu" -FileChooser = Menu:new{ +FileChooser = Menu:extend{ height = Screen:getHeight(), width = Screen:getWidth(), + no_title = true, path = lfs.currentdir(), parent = nil, show_hidden = false, @@ -10,7 +11,8 @@ FileChooser = Menu:new{ } function FileChooser:init() - self:changeToPath(self.path) + self:updateItemTableFromPath(self.path) + Menu.init(self) -- call parent's init() end function FileChooser:compressPath(item_path) @@ -22,11 +24,12 @@ function FileChooser:compressPath(item_path) return path end -function FileChooser:changeToPath(path) +function FileChooser:updateItemTableFromPath(path) path = self:compressPath(path) local dirs = {} local files = {} self.path = path + for f in lfs.dir(self.path) do if self.show_hidden or not string.match(f, "^%.[^.]") then local filename = self.path.."/"..f @@ -53,15 +56,16 @@ function FileChooser:changeToPath(path) for _, file in ipairs(files) do table.insert(self.item_table, { text = file, path = self.path.."/"..file }) end +end - Menu.init(self) -- call parent's init() +function FileChooser:changeToPath(path) + self:updateItemTableFromPath(path) + self:updateItems(1) end function FileChooser:onMenuSelect(item) if lfs.attributes(item.path, "mode") == "directory" then - UIManager:close(self) self:changeToPath(item.path) - UIManager:show(self) else self:onFileSelect(item.path) end From caf7ebb9aec04b71af8c1ce7a45d622b3a2f0712 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 14 Aug 2013 05:29:05 -0400 Subject: [PATCH 4/4] bug fix & rewrite filemanager --- frontend/apps/filemanager/fm.lua | 88 +++++++++++++++ frontend/apps/filemanager/fmhistory.lua | 73 +++++++++++++ frontend/apps/filemanager/fmmenu.lua | 131 ++++++++++++++++++++++ reader.lua | 137 ++---------------------- 4 files changed, 303 insertions(+), 126 deletions(-) create mode 100644 frontend/apps/filemanager/fm.lua create mode 100644 frontend/apps/filemanager/fmhistory.lua create mode 100644 frontend/apps/filemanager/fmmenu.lua diff --git a/frontend/apps/filemanager/fm.lua b/frontend/apps/filemanager/fm.lua new file mode 100644 index 000000000..ee1aae36e --- /dev/null +++ b/frontend/apps/filemanager/fm.lua @@ -0,0 +1,88 @@ +require "ui/widget/filechooser" +require "apps/filemanager/fmhistory" +require "apps/filemanager/fmmenu" + + +FileManager = InputContainer:extend{ + title = _("FileManager"), + width = Screen:getWidth(), + height = Screen:getHeight(), + root_path = './', + -- our own size + dimen = Geom:new{ w = 400, h = 600 }, + onExit = function() end, +} + +function FileManager:init() + local exclude_dirs = {"%.sdr$"} + + self.show_parent = self.show_parent or self + + local file_chooser = FileChooser:new{ + _name = 'fuck', + is_popout = false, + is_borderless = true, + has_close_button = true, + dir_filter = function(dirname) + for _, pattern in ipairs(exclude_dirs) do + if dirname:match(pattern) then return end + end + return true + end, + file_filter = function(filename) + if DocumentRegistry:getProvider(filename) then + return true + end + end + } + + function file_chooser:onFileSelect(file) + showReaderUI(file) + return true + end + + self.banner = FrameContainer:new{ + padding = 0, + bordersize = 0, + TextWidget:new{ + face = Font:getFace("tfont", 24), + text = self.title, + } + } + + self.layout = VerticalGroup:new{ + _name = 'fm', + self.banner, + file_chooser, + } + + local fm_ui = FrameContainer:new{ + padding = 0, + bordersize = 0, + padding = self.padding, + background = 0, + self.layout, + } + + self[1] = fm_ui + + self.menu = FileManagerMenu:new{ + ui = self + } + table.insert(self, self.menu) + table.insert(self, FileManagerHistory:new{ + ui = self, + menu = self.menu + }) + + self:handleEvent(Event:new("SetDimensions", self.dimen)) +end + + +function FileManager:onClose() + UIManager:close(self) + if self.onExit then + self:onExit() + end + return true +end diff --git a/frontend/apps/filemanager/fmhistory.lua b/frontend/apps/filemanager/fmhistory.lua new file mode 100644 index 000000000..2b9dcb265 --- /dev/null +++ b/frontend/apps/filemanager/fmhistory.lua @@ -0,0 +1,73 @@ +FileManagerHistory = InputContainer:extend{ + hist_menu_title = _("History"), +} + +function FileManagerHistory:init() + self.ui.menu:registerToMainMenu(self) +end + +function FileManagerHistory:onSetDimensions(dimen) + self.dimen = dimen +end + +function FileManagerHistory:onShowHist() + self:updateItemTable() + + local menu_container = CenterContainer:new{ + dimen = Screen:getSize(), + } + + local hist_menu = Menu:new{ + title = _("History"), + item_table = self.hist, + ui = self.ui, + width = Screen:getWidth()-50, + height = Screen:getHeight()-50, + show_parent = menu_container, + } + + table.insert(menu_container, hist_menu) + + hist_menu.close_callback = function() + UIManager:close(menu_container) + end + + UIManager:show(menu_container) + return true +end + +function FileManagerHistory:addToMainMenu(tab_item_table) + -- insert table to main reader menu + table.insert(tab_item_table.main, { + text = self.hist_menu_title, + callback = function() + self:onShowHist() + end, + }) +end + +function FileManagerHistory:updateItemTable() + function readHistDir(order_arg, re) + local pipe_out = io.popen("ls "..order_arg.." -1 ./history") + for f in pipe_out:lines() do + table.insert(re, { + dir = DocSettings:getPathFromHistory(f), + name = DocSettings:getNameFromHistory(f), + }) + end + end + + self.hist = {} + local last_files = {} + readHistDir("-c", last_files) + for _,v in pairs(last_files) do + table.insert(self.hist, { + text = v.name, + callback = function() + showReaderUI(v.dir .. "/" .. v.name) + end + }) + end +end + + diff --git a/frontend/apps/filemanager/fmmenu.lua b/frontend/apps/filemanager/fmmenu.lua new file mode 100644 index 000000000..b499fd9b9 --- /dev/null +++ b/frontend/apps/filemanager/fmmenu.lua @@ -0,0 +1,131 @@ +require "ui/widget/menu" +require "ui/widget/touchmenu" + +FileManagerMenu = InputContainer:extend{ + tab_item_table = nil, + registered_widgets = {}, +} + +function FileManagerMenu:init() + self.tab_item_table = { + main = { + icon = "resources/icons/appbar.pokeball.png", + }, + home = { + icon = "resources/icons/appbar.home.png", + callback = function() + UIManager:close(self.menu_container) + self.ui:onClose() + end, + }, + } + self.registered_widgets = {} + + if Device:hasKeyboard() then + self.key_events = { + ShowMenu = { { "Menu" }, doc = _("show menu") }, + } + end +end + +function FileManagerMenu:initGesListener() + self.ges_events = { + TapShowMenu = { + GestureRange:new{ + ges = "tap", + range = Geom:new{ + x = 0, + y = 0, + w = Screen:getWidth()*3/4, + h = Screen:getHeight()/4, + } + } + }, + } +end + +function FileManagerMenu:setUpdateItemTable() + for _, widget in pairs(self.registered_widgets) do + widget:addToMainMenu(self.tab_item_table) + end + + if Device:hasFrontlight() then + table.insert(self.tab_item_table.main, { + text = _("Frontlight settings"), + callback = function() + ReaderFrontLight:onShowFlDialog() + end + }) + end + table.insert(self.tab_item_table.main, { + text = _("Help"), + callback = function() + UIManager:show(InfoMessage:new{ + text = _("Please report bugs to https://github.com/koreader/ koreader/issues, Click at the bottom of the page for more options"), + }) + end + }) +end + +function FileManagerMenu:onShowMenu() + if #self.tab_item_table.main == 0 then + self:setUpdateItemTable() + end + + local menu_container = CenterContainer:new{ + ignore = "height", + dimen = Screen:getSize(), + } + + local main_menu = nil + if Device:isTouchDevice() then + main_menu = TouchMenu:new{ + width = Screen:getWidth(), + tab_item_table = { + self.tab_item_table.main, + self.tab_item_table.home, + }, + show_parent = menu_container, + } + else + main_menu = Menu:new{ + title = _("File manager menu"), + item_table = {}, + width = Screen:getWidth() - 100, + } + + for _,item_table in pairs(self.tab_item_table) do + for k,v in ipairs(item_table) do + table.insert(main_menu.item_table, v) + end + end + end + + main_menu.close_callback = function () + UIManager:close(menu_container) + end + + menu_container[1] = main_menu + -- maintain a reference to menu_container + self.menu_container = menu_container + UIManager:show(menu_container) + + return true +end + +function FileManagerMenu:onTapShowMenu() + self:onShowMenu() + return true +end + +function FileManagerMenu:onSetDimensions(dimen) + -- update listening according to new screen dimen + if Device:isTouchDevice() then + self:initGesListener() + end +end + +function FileManagerMenu:registerToMainMenu(widget) + table.insert(self.registered_widgets, widget) +end + diff --git a/reader.lua b/reader.lua index e90860bab..1687f5b08 100755 --- a/reader.lua +++ b/reader.lua @@ -4,34 +4,15 @@ require "defaults" package.path = "./frontend/?.lua" package.cpath = "/usr/lib/lua/?.so" require "ui/uimanager" -require "ui/widget/filechooser" require "ui/widget/infomessage" require "ui/readerui" require "document/document" require "settings" require "dbg" require "gettext" +require "apps/filemanager/fm" -HomeMenu = InputContainer:new{ - item_table = {}, - key_events = { - TapShowMenu = { {"Home"}, doc = _("Show Home Menu")}, - }, - ges_events = { - TapShowMenu = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = 25, - } - } - }, - }, -} - function exitReader() G_reader_settings:close() @@ -58,70 +39,7 @@ function exitReader() os.exit(0) end -function HomeMenu:setUpdateItemTable() - function readHistDir(order_arg, re) - local pipe_out = io.popen("ls "..order_arg.." -1 ./history") - for f in pipe_out:lines() do - table.insert(re, { - dir = DocSettings:getPathFromHistory(f), - name = DocSettings:getNameFromHistory(f), - }) - end - end - - local hist_sub_item_table = {} - local last_files = {} - readHistDir("-c", last_files) - for _,v in pairs(last_files) do - table.insert(hist_sub_item_table, { - text = v.name, - callback = function() - showReader(v.dir .. "/" .. v.name) - end - }) - end - table.insert(self.item_table, { - text = _("Last documents"), - sub_item_table = hist_sub_item_table, - }) - - table.insert(self.item_table, { - text = _("Exit"), - callback = function() - exitReader() - end - }) -end - -function HomeMenu:onTapShowMenu() - self.item_table = {} - self:setUpdateItemTable() - - local menu_container = CenterContainer:new{ - ignore = "height", - dimen = Screen:getSize(), - } - - local home_menu = Menu:new{ - show_parent = menu_container, - title = _("Home menu"), - item_table = self.item_table, - width = Screen:getWidth() - 100, - } - - menu_container[1] = home_menu - - home_menu.close_callback = function () - UIManager:close(menu_container) - end - - UIManager:show(menu_container) - - return true -end - - -function showReader(file, pass) +function showReaderUI(file, pass) local document = DocumentRegistry:openDocument(file) if not document then UIManager:show(InfoMessage:new{ @@ -141,47 +59,14 @@ function showReader(file, pass) end function showHomePage(path) - local exclude_dirs = {"%.sdr$"} - - local HomePage = InputContainer:new{ - } - - local FileManager = FileChooser:new{ - show_parent = HomePage, - title = _("FileManager"), - path = path, - width = Screen:getWidth(), - height = Screen:getHeight(), - is_borderless = true, - has_close_button = true, - dir_filter = function(dirname) - for _, pattern in ipairs(exclude_dirs) do - if dirname:match(pattern) then return end - end - return true - end, - file_filter = function(filename) - if DocumentRegistry:getProvider(filename) then - return true - end + UIManager:show(FileManager:new{ + dimen = Screen:getSize(), + root_path = path, + onExit = function() + exitReader() + UIManager:quit() end - } - - table.insert(HomePage, FileManager) - table.insert(HomePage, HomeMenu) - - function FileManager:onFileSelect(file) - showReader(file) - return true - end - - function FileManager:onClose() - exitReader() - --UIManager:quit() - return true - end - - UIManager:show(HomePage) + }) end @@ -243,11 +128,11 @@ if ARGV[argidx] and ARGV[argidx] ~= "" then if lfs.attributes(ARGV[argidx], "mode") == "directory" then showHomePage(ARGV[argidx]) elseif lfs.attributes(ARGV[argidx], "mode") == "file" then - showReader(ARGV[argidx]) + showReaderUI(ARGV[argidx]) end UIManager:run() elseif last_file and lfs.attributes(last_file, "mode") == "file" then - showReader(last_file) + showReaderUI(last_file) UIManager:run() else return showusage()