diff --git a/frontend/apps/filemanager/filemanagerfilesearcher.lua b/frontend/apps/filemanager/filemanagerfilesearcher.lua index f00a1d01a..a5898af7a 100644 --- a/frontend/apps/filemanager/filemanagerfilesearcher.lua +++ b/frontend/apps/filemanager/filemanagerfilesearcher.lua @@ -5,6 +5,7 @@ local InfoMessage = require("ui/widget/infomessage") local InputContainer = require("ui/widget/container/inputcontainer") local InputDialog = require("ui/widget/inputdialog") local Menu = require("ui/widget/menu") +local Size = require("ui/size") local UIManager = require("ui/uimanager") local lfs = require("libs/libkoreader-lfs") local BaseUtil = require("ffi/util") @@ -165,8 +166,8 @@ function FileSearcher:showSearchResults() dimen = Screen:getSize(), } self.search_menu = Menu:new{ - width = Screen:getWidth()-15, - height = Screen:getHeight()-15, + width = Screen:getWidth() - (Size.margin.fullscreen_popout * 2), + height = Screen:getHeight() - (Size.margin.fullscreen_popout * 2), show_parent = menu_container, onMenuHold = self.onMenuHold, cface = Font:getFace("smallinfofont"), diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index 054814438..f9a2caf99 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -8,6 +8,7 @@ local FFIUtil = require("ffi/util") local InputContainer = require("ui/widget/container/inputcontainer") local PluginLoader = require("pluginloader") local SetDefaults = require("apps/filemanager/filemanagersetdefaults") +local Size = require("ui/size") local UIManager = require("ui/uimanager") local Screen = Device.screen local dbg = require("dbg") @@ -130,7 +131,9 @@ function FileManagerMenu:onOpenLastDoc() end local FileManager = require("apps/filemanager/filemanager") - FileManager.instance:onClose() + if FileManager.instance then + FileManager.instance:onClose() + end end function FileManagerMenu:setUpdateItemTable() @@ -738,7 +741,7 @@ function FileManagerMenu:onShowMenu(tab_index) main_menu = Menu:new{ title = _("File manager menu"), item_table = Menu.itemTableFromTouchMenu(self.tab_item_table), - width = Screen:getWidth()-10, + width = Screen:getWidth() - (Size.margin.fullscreen_popout * 2), show_parent = menu_container, } end diff --git a/frontend/apps/filemanager/filemanagersetdefaults.lua b/frontend/apps/filemanager/filemanagersetdefaults.lua index 9573374fe..d30b311ed 100644 --- a/frontend/apps/filemanager/filemanagersetdefaults.lua +++ b/frontend/apps/filemanager/filemanagersetdefaults.lua @@ -8,6 +8,7 @@ local InputContainer = require("ui/widget/container/inputcontainer") local InputDialog = require("ui/widget/inputdialog") local Menu = require("ui/widget/menu") local MultiInputDialog = require("ui/widget/multiinputdialog") +local Size = require("ui/size") local UIManager = require("ui/uimanager") local dump = require("dump") local isAndroid, android = pcall(require, "android") @@ -89,8 +90,8 @@ function SetDefaults:init() end self.defaults_menu = Menu:new{ - width = Screen:getWidth()-15, - height = Screen:getHeight()-15, + width = Screen:getWidth() - (Size.margin.fullscreen_popout * 2), + height = Screen:getHeight() - (Size.margin.fullscreen_popout * 2), cface = Font:getFace("smallinfofont"), show_parent = menu_container, _manager = self, diff --git a/frontend/apps/reader/modules/readergoto.lua b/frontend/apps/reader/modules/readergoto.lua index c50cdc9f0..7ac134f4a 100644 --- a/frontend/apps/reader/modules/readergoto.lua +++ b/frontend/apps/reader/modules/readergoto.lua @@ -47,7 +47,7 @@ function ReaderGoto:onShowGotoDialog() input_hint = T("@%1 (1 - %2)", curr_page, self.document:getPageCount()) end self.goto_dialog = InputDialog:new{ - title = _("Go to page"), + title = _("Enter page number"), input_hint = input_hint, description = self.document:hasHiddenFlows() and _([[ @@ -65,7 +65,7 @@ x for an absolute page number end, }, { - text = _("Skim mode"), + text = _("Skim"), enabled = true, callback = function() self:close() @@ -82,7 +82,7 @@ x for an absolute page number end, }, { - text = _("Page"), + text = _("Go to page"), enabled = true, is_enter_default = true, callback = function() self:gotoPage() end, diff --git a/frontend/ui/size.lua b/frontend/ui/size.lua index 526318f45..ddb648583 100644 --- a/frontend/ui/size.lua +++ b/frontend/ui/size.lua @@ -43,6 +43,7 @@ local Size = { small = Screen:scaleBySize(2), title = Screen:scaleBySize(2), fine_tune = Screen:scaleBySize(3), + fullscreen_popout = Screen:scaleBySize(3), -- Size.border.window * 2 button = 0, }, padding = { diff --git a/frontend/ui/widget/button.lua b/frontend/ui/widget/button.lua index 44f85b74a..4a862d915 100644 --- a/frontend/ui/widget/button.lua +++ b/frontend/ui/widget/button.lua @@ -64,6 +64,11 @@ function Button:init() self.text = self.text_func() end + -- Point tap_input to hold_input if requested + if self.call_hold_input_on_tap then + self.tap_input = self.hold_input + end + if not self.padding_h then self.padding_h = self.padding end @@ -198,6 +203,17 @@ function Button:disable() end end +-- This is used by pagination buttons with a hold_input registered that we want to *sometimes* inhibit, +-- meaning we want the Button disabled, but *without* dimming the text... +function Button:disableWithoutDimming() + self.enabled = false + if self.text then + self.label_widget.fgcolor = Blitbuffer.COLOR_BLACK + else + self.label_widget.dim = false + end +end + function Button:enableDisable(enable) if enable then self:enable() @@ -286,72 +302,74 @@ function Button:_undoFeedbackHighlight(is_translucent) end function Button:onTapSelectButton() - if self.enabled and self.callback then - if G_reader_settings:isFalse("flash_ui") then - self.callback() - else - -- NOTE: We have a few tricks up our sleeve in case our parent is inside a translucent MovableContainer... - local is_translucent = self.show_parent and self.show_parent.movable and self.show_parent.movable.alpha - - -- Highlight - -- - self:_doFeedbackHighlight() - - -- Force the refresh by draining the refresh queue *now*, so we have a chance to see the highlight on its own, before whatever the callback will do. - if not self.vsync then - -- NOTE: Except when a Button is flagged vsync, in which case we *want* to bundle the highlight with the callback, to prevent further delays - UIManager:forceRePaint() - - -- NOTE: Yield to the kernel for a tiny slice of time, otherwise, writing to the same fb region as the refresh we've just requested may be race-y, - -- causing mild variants of our friend the papercut refresh glitch ;). - -- Remember that the whole eInk refresh dance is completely asynchronous: we *request* a refresh from the kernel, - -- but it's up to the EPDC to schedule that however it sees fit... - -- The other approach would be to *ask* the EPDC to block until it's *completely* done, - -- but that's too much (because we only care about it being done *reading* the fb), - -- and that could take upwards of 300ms, which is also way too much ;). - UIManager:yieldToEPDC() - end - - -- Unhighlight - -- - -- We'll *paint* the unhighlight now, because at this point we can still be sure that our widget exists, - -- and that anything we do will not impact whatever the callback does (i.e., that we draw *below* whatever the callback might show). - -- We won't *fence* the refresh (i.e., it's queued, but we don't actually drain the queue yet), though, to ensure that we do not delay the callback, and that the unhighlight essentially blends into whatever the callback does. - -- Worst case scenario, we'll simply have "wasted" a tiny subwidget repaint if the callback closed us, - -- but doing it this way allows us to avoid a large array of potential interactions with whatever the callback may paint/refresh if we were to handle the unhighlight post-callback, - -- which would require a number of possibly brittle heuristics to handle. - -- NOTE: If a Button is marked vsync, we want to keep it highlighted for now (in order for said highlight to be visible during the callback refresh), we'll remove the highlight post-callback. - if not self.vsync then - self:_undoFeedbackHighlight(is_translucent) - end - - -- Callback - -- - self.callback() - - -- Check if the callback reset transparency... - is_translucent = is_translucent and self.show_parent.movable.alpha - - UIManager:forceRePaint() -- Ensures whatever the callback wanted to paint will be shown *now*... - if self.vsync then - -- NOTE: This is mainly useful when the callback caused a REAGL update that we do not explicitly fence via MXCFB_WAIT_FOR_UPDATE_COMPLETE already, (i.e., Kobo Mk. 7). - UIManager:waitForVSync() -- ...and that the EPDC will not wait to coalesce it with the *next* update, - -- because that would have a chance to noticeably delay it until the unhighlight. - end - - -- Unhighlight - -- - -- NOTE: If a Button is marked vsync, we have a guarantee from the programmer that the widget it belongs to is still alive and top-level post-callback, - -- so we can do this safely without risking UI glitches. - if self.vsync then - self:_undoFeedbackHighlight(is_translucent) - UIManager:forceRePaint() + if self.enabled or self.allow_tap_when_disabled then + if self.callback then + if G_reader_settings:isFalse("flash_ui") then + self.callback() + else + -- NOTE: We have a few tricks up our sleeve in case our parent is inside a translucent MovableContainer... + local is_translucent = self.show_parent and self.show_parent.movable and self.show_parent.movable.alpha + + -- Highlight + -- + self:_doFeedbackHighlight() + + -- Force the refresh by draining the refresh queue *now*, so we have a chance to see the highlight on its own, before whatever the callback will do. + if not self.vsync then + -- NOTE: Except when a Button is flagged vsync, in which case we *want* to bundle the highlight with the callback, to prevent further delays + UIManager:forceRePaint() + + -- NOTE: Yield to the kernel for a tiny slice of time, otherwise, writing to the same fb region as the refresh we've just requested may be race-y, + -- causing mild variants of our friend the papercut refresh glitch ;). + -- Remember that the whole eInk refresh dance is completely asynchronous: we *request* a refresh from the kernel, + -- but it's up to the EPDC to schedule that however it sees fit... + -- The other approach would be to *ask* the EPDC to block until it's *completely* done, + -- but that's too much (because we only care about it being done *reading* the fb), + -- and that could take upwards of 300ms, which is also way too much ;). + UIManager:yieldToEPDC() + end + + -- Unhighlight + -- + -- We'll *paint* the unhighlight now, because at this point we can still be sure that our widget exists, + -- and that anything we do will not impact whatever the callback does (i.e., that we draw *below* whatever the callback might show). + -- We won't *fence* the refresh (i.e., it's queued, but we don't actually drain the queue yet), though, to ensure that we do not delay the callback, and that the unhighlight essentially blends into whatever the callback does. + -- Worst case scenario, we'll simply have "wasted" a tiny subwidget repaint if the callback closed us, + -- but doing it this way allows us to avoid a large array of potential interactions with whatever the callback may paint/refresh if we were to handle the unhighlight post-callback, + -- which would require a number of possibly brittle heuristics to handle. + -- NOTE: If a Button is marked vsync, we want to keep it highlighted for now (in order for said highlight to be visible during the callback refresh), we'll remove the highlight post-callback. + if not self.vsync then + self:_undoFeedbackHighlight(is_translucent) + end + + -- Callback + -- + self.callback() + + -- Check if the callback reset transparency... + is_translucent = is_translucent and self.show_parent.movable.alpha + + UIManager:forceRePaint() -- Ensures whatever the callback wanted to paint will be shown *now*... + if self.vsync then + -- NOTE: This is mainly useful when the callback caused a REAGL update that we do not explicitly fence via MXCFB_WAIT_FOR_UPDATE_COMPLETE already, (i.e., Kobo Mk. 7). + UIManager:waitForVSync() -- ...and that the EPDC will not wait to coalesce it with the *next* update, + -- because that would have a chance to noticeably delay it until the unhighlight. + end + + -- Unhighlight + -- + -- NOTE: If a Button is marked vsync, we have a guarantee from the programmer that the widget it belongs to is still alive and top-level post-callback, + -- so we can do this safely without risking UI glitches. + if self.vsync then + self:_undoFeedbackHighlight(is_translucent) + UIManager:forceRePaint() + end end + elseif self.tap_input then + self:onInput(self.tap_input) + elseif type(self.tap_input_func) == "function" then + self:onInput(self.tap_input_func()) end - elseif self.tap_input then - self:onInput(self.tap_input) - elseif type(self.tap_input_func) == "function" then - self:onInput(self.tap_input_func()) end if self.readonly ~= true then diff --git a/frontend/ui/widget/container/inputcontainer.lua b/frontend/ui/widget/container/inputcontainer.lua index 6ae9bec71..8ec0375cf 100644 --- a/frontend/ui/widget/container/inputcontainer.lua +++ b/frontend/ui/widget/container/inputcontainer.lua @@ -275,7 +275,7 @@ function InputContainer:onInput(input, ignore_first_hold_release) input = input.input_func and input.input_func() or input.input, input_hint = input.hint_func and input.hint_func() or input.hint or "", input_type = input.type or "number", - buttons = input.buttons or { + buttons = input.buttons or { { { text = input.cancel_text or _("Cancel"), diff --git a/frontend/ui/widget/keyvaluepage.lua b/frontend/ui/widget/keyvaluepage.lua index 5546d50fa..3b54ccf29 100644 --- a/frontend/ui/widget/keyvaluepage.lua +++ b/frontend/ui/widget/keyvaluepage.lua @@ -41,6 +41,7 @@ local TextWidget = require("ui/widget/textwidget") local UIManager = require("ui/uimanager") local VerticalGroup = require("ui/widget/verticalgroup") local VerticalSpan = require("ui/widget/verticalspan") +local WidgetContainer = require("ui/widget/container/widgetcontainer") local Input = Device.input local Screen = Device.screen local T = require("ffi/util").template @@ -406,15 +407,18 @@ function KeyValuePage:init() self.page_info_spacer = HorizontalSpan:new{ width = Screen:scaleBySize(32), } - self.page_return_spacer = HorizontalSpan:new{ - width = self.page_return_arrow:getSize().w - } if self.callback_return == nil and self.return_button == nil then self.page_return_arrow:hide() elseif self.callback_return == nil then self.page_return_arrow:disable() end + self.return_button = HorizontalGroup:new{ + HorizontalSpan:new{ + width = Size.span.horizontal_small, + }, + self.page_return_arrow, + } self.page_info_left_chev:hide() self.page_info_right_chev:hide() @@ -435,31 +439,47 @@ function KeyValuePage:init() self:goToPage(page) end end, + ok_text = "Go to page", }, + call_hold_input_on_tap = true, bordersize = 0, - margin = Screen:scaleBySize(20), text_font_face = "pgfont", text_font_bold = false, } self.page_info = HorizontalGroup:new{ - self.page_return_arrow, self.page_info_first_chev, self.page_info_spacer, self.page_info_left_chev, + self.page_info_spacer, self.page_info_text, + self.page_info_spacer, self.page_info_right_chev, self.page_info_spacer, self.page_info_last_chev, - self.page_return_spacer, } + local padding = Size.padding.large + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2 * padding, + h = self.dimen.h - padding, -- no bottom padding + } + self.item_width = self.inner_dimen.w + local footer = BottomContainer:new{ - dimen = self.dimen:copy(), + dimen = self.inner_dimen:copy(), self.page_info, } + local page_return = BottomContainer:new{ + dimen = self.inner_dimen:copy(), + WidgetContainer:new{ + dimen = Geom:new{ + w = self.inner_dimen.w, + h = self.return_button:getSize().h, + }, + self.return_button, + } + } - local padding = Size.padding.large - self.item_width = self.dimen.w - 2 * padding -- setup title bar self.title_bar = KeyValueTitle:new{ title = self.title, @@ -468,9 +488,11 @@ function KeyValuePage:init() use_top_page_count = self.use_top_page_count, kv_page = self, } + -- setup main content - local available_height = self.dimen.h + local available_height = self.inner_dimen.h - self.title_bar:getSize().h + - Size.span.vertical_large -- for above page_info (as title_bar adds one itself) - self.page_info:getSize().h - 2*Size.line.thick -- account for possibly 2 separator lines added @@ -478,7 +500,7 @@ function KeyValuePage:init() self.items_per_page = G_reader_settings:readSetting("keyvalues_per_page") or self:getDefaultKeyValuesPerPage() self.item_height = math.floor(available_height / self.items_per_page) -- Put half of the pixels lost by floor'ing between title and content - local span_height = math.floor((available_height - (self.items_per_page * (self.item_height ))) / 2) + local span_height = math.floor((available_height - (self.items_per_page * (self.item_height))) / 2) -- Font size is not configurable: we can get a good one from the following local TextBoxWidget = require("ui/widget/textboxwidget") @@ -496,20 +518,23 @@ function KeyValuePage:init() self:_populateItems() local content = OverlapGroup:new{ - dimen = self.dimen:copy(), allow_mirroring = false, + dimen = self.inner_dimen:copy(), VerticalGroup:new{ align = "left", self.title_bar, VerticalSpan:new{ width = span_height }, self.main_content, }, + page_return, footer, } -- assemble page self[1] = FrameContainer:new{ height = self.dimen.h, padding = padding, + padding_bottom = 0, + margin = 0, bordersize = 0, background = Blitbuffer.COLOR_WHITE, content @@ -549,6 +574,7 @@ end -- make sure self.item_margin and self.item_height are set before calling this function KeyValuePage:_populateItems() self.page_info:resetLayout() + self.return_button:resetLayout() self.main_content:clear() local idx_offset = (self.show_page - 1) * self.items_per_page for idx = 1, self.items_per_page do @@ -597,11 +623,18 @@ function KeyValuePage:_populateItems() end end end + + -- update page information self.page_info_text:setText(T(_("Page %1 of %2"), self.show_page, self.pages)) - self.page_info_left_chev:showHide(self.pages > 1) - self.page_info_right_chev:showHide(self.pages > 1) - self.page_info_first_chev:showHide(self.pages > 2) - self.page_info_last_chev:showHide(self.pages > 2) + if self.pages > 1 then + self.page_info_text:enable() + else + self.page_info_text:disableWithoutDimming() + end + self.page_info_left_chev:show() + self.page_info_right_chev:show() + self.page_info_first_chev:show() + self.page_info_last_chev:show() self.page_info_left_chev:enableDisable(self.show_page > 1) self.page_info_right_chev:enableDisable(self.show_page < self.pages) diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index 269bc45b3..69758d587 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -51,7 +51,7 @@ function ItemShortCutIcon:init() local radius = 0 local background = Blitbuffer.COLOR_WHITE if self.style == "rounded_corner" then - radius = math.floor(self.width/2) + radius = math.floor(self.width / 2) elseif self.style == "grey_square" then background = Blitbuffer.COLOR_LIGHT_GRAY end @@ -100,7 +100,7 @@ function MenuCloseButton:init() -- diagonally aligned with the top right corner (assuming padding_right=0, -- or padding_right = padding_top so the diagonal aligment is preserved). local text_size = text_widget:getSize() - local text_width_pad = (text_size.h - text_size.w) / 2 + local text_width_pad = math.floor((text_size.h - text_size.w) / 2) self[1] = FrameContainer:new{ bordersize = 0, @@ -157,7 +157,7 @@ function MenuItem:init() self.content_width = self.dimen.w - 2 * Size.padding.fullscreen local shortcut_icon_dimen = Geom:new() if self.shortcut then - shortcut_icon_dimen.w = math.floor(self.dimen.h*4/5) + shortcut_icon_dimen.w = math.floor(self.dimen.h * 4/5) shortcut_icon_dimen.h = shortcut_icon_dimen.w self.content_width = self.content_width - shortcut_icon_dimen.w - Size.span.horizontal_default end @@ -216,7 +216,7 @@ function MenuItem:init() } local state_indent = self.state and self.state.indent or "" local state_container = LeftContainer:new{ - dimen = Geom:new{w = self.content_width/2, h = self.dimen.h}, + dimen = Geom:new{w = math.floor(self.content_width / 2), h = self.dimen.h}, HorizontalGroup:new{ TextWidget:new{ text = state_indent, @@ -457,8 +457,8 @@ end function MenuItem:getGesPosition(ges) local dimen = self[1].dimen return { - x = (ges.pos.x - dimen.x)/dimen.w, - y = (ges.pos.y - dimen.y)/dimen.h, + x = math.floor((ges.pos.x - dimen.x) / dimen.w), + y = math.floor((ges.pos.y - dimen.y) / dimen.h), } end @@ -590,8 +590,12 @@ function Menu:_recalculateDimen() if self.dimen.h > Screen:getHeight() or self.dimen.h == nil then self.dimen.h = Screen:getHeight() end + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2 * self.border_size, + h = self.dimen.h - 2 * self.border_size, + } self.item_dimen = Geom:new{ - w = self.dimen.w, + w = self.inner_dimen.w, h = Screen:scaleBySize(46), } local height_dim @@ -602,11 +606,11 @@ function Menu:_recalculateDimen() + 2 * Size.padding.button end if self.menu_title and not self.no_title then - top_height = self.menu_title_group:getSize().h + 2 * Size.padding.small + top_height = self.menu_title_group:getSize().h + self.header_padding end - height_dim = self.dimen.h - bottom_height - top_height + height_dim = self.inner_dimen.h - bottom_height - top_height self.item_dimen.h = math.floor(height_dim / self.perpage) - self.span_width = math.floor((height_dim - (self.perpage * (self.item_dimen.h ))) / 2 -1 ) + self.span_width = math.floor((height_dim - (self.perpage * (self.item_dimen.h ))) / 2 - 1) self.page_num = math.ceil(#self.item_table / self.perpage) -- fix current page if out of range if self.page_num > 0 and self.page > self.page_num then self.page = self.page_num end @@ -620,6 +624,13 @@ function Menu:init() if self.dimen.h > Screen:getHeight() or self.dimen.h == nil then self.dimen.h = Screen:getHeight() end + + self.border_size = self.is_borderless and 0 or Size.border.window + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2 * self.border_size, + h = self.dimen.h - 2 * self.border_size, + } + self.page = 1 self.paths = {} -- per instance table to trace navigation path @@ -634,7 +645,7 @@ function Menu:init() } local menu_title_container = CenterContainer:new{ dimen = Geom:new{ - w = self.dimen.w, + w = self.inner_dimen.w, h = self.menu_title:getSize().h, }, self.menu_title, @@ -645,12 +656,12 @@ function Menu:init() self.path_text = TextWidget:new{ face = Font:getFace("xx_smallinfofont"), text = BD.directory(self.path), - max_width = self.dimen.w - 2*Size.padding.small, + max_width = self.inner_dimen.w - 2*Size.padding.small, truncate_left = true, } path_text_container = CenterContainer:new{ dimen = Geom:new{ - w = self.dimen.w, + w = self.inner_dimen.w, h = self.path_text:getSize().h, }, self.path_text, @@ -668,7 +679,7 @@ function Menu:init() end -- group for title bar self.title_bar = OverlapGroup:new{ - dimen = {w = self.dimen.w, h = self.menu_title_group:getSize().h}, + dimen = {w = self.inner_dimen.w, h = self.menu_title_group:getSize().h}, self.menu_title_group, } -- group for items @@ -776,6 +787,7 @@ function Menu:init() hint_func = hint_func, buttons = buttons, }, + call_hold_input_on_tap = true, bordersize = 0, text_font_face = "cfont", text_font_size = 20, @@ -785,7 +797,9 @@ function Menu:init() self.page_info_first_chev, self.page_info_spacer, self.page_info_left_chev, + self.page_info_spacer, self.page_info_text, + self.page_info_spacer, self.page_info_right_chev, self.page_info_spacer, self.page_info_last_chev, @@ -815,11 +829,11 @@ function Menu:init() } local body = self.item_group local footer = BottomContainer:new{ - dimen = self.dimen:copy(), + dimen = self.inner_dimen:copy(), self.page_info, } local page_return = BottomContainer:new{ - dimen = self.dimen:copy(), + dimen = self.inner_dimen:copy(), WidgetContainer:new{ dimen = Geom:new{ w = Screen:getWidth(), @@ -852,7 +866,7 @@ function Menu:init() -- to have this complex Menu, and all widgets based on it, -- be mirrored correctly with RTL languages allow_mirroring = false, - dimen = self.dimen:copy(), + dimen = self.inner_dimen:copy(), self.content_group, page_return, footer, @@ -860,10 +874,10 @@ function Menu:init() self[1] = FrameContainer:new{ background = Blitbuffer.COLOR_WHITE, - bordersize = self.is_borderless and 0 or Size.border.window, + bordersize = self.border_size, padding = 0, margin = 0, - radius = self.is_popout and math.floor(self.dimen.w/20) or 0, + radius = self.is_popout and math.floor(self.dimen.w / 20) or 0, content } ------------------------------------------ @@ -967,16 +981,16 @@ function Menu:updatePageInfo(select_number) self.selected = { x = 1, y = select_number } end -- update page information + self.page_info_text:setText(FFIUtil.template(_("Page %1 of %2"), self.page, self.page_num)) if self.page_num > 1 then - self.page_info_text:setText(FFIUtil.template(_("Page %1 of %2"), self.page, self.page_num)) self.page_info_text:enable() else - self.page_info_text:setText(""); + self.page_info_text:disableWithoutDimming() end - self.page_info_left_chev:showHide(self.page_num > 1) - self.page_info_right_chev:showHide(self.page_num > 1) - self.page_info_first_chev:showHide(self.page_num > 2) - self.page_info_last_chev:showHide(self.page_num > 2) + self.page_info_left_chev:show() + self.page_info_right_chev:show() + self.page_info_first_chev:show() + self.page_info_last_chev:show() self.page_return_arrow:showHide(self.onReturn ~= nil) self.page_info_left_chev:enableDisable(self.page > 1) @@ -986,7 +1000,7 @@ function Menu:updatePageInfo(select_number) self.page_return_arrow:enableDisable(#self.paths > 0) else self.page_info_text:setText(_("No choices available")) - self.page_info_text:disable() + self.page_info_text:disableWithoutDimming() end end @@ -1069,12 +1083,6 @@ function Menu:updateItems(select_number) local refresh_dimen = old_dimen and old_dimen:combine(self.dimen) or self.dimen - if not self.is_borderless then - refresh_dimen = refresh_dimen:copy() - local bordersize = Size.border.window - refresh_dimen.w = refresh_dimen.w + bordersize*2 - refresh_dimen.h = refresh_dimen.h + bordersize*2 - end return "ui", refresh_dimen end) end @@ -1353,7 +1361,7 @@ end function Menu.getItemFontSize(perpage) -- Get adjusted font size for the given nb of items per page: -- item font size between 14 and 24 for better matching - return math.floor(24 - ((perpage - 6)/ 18) * 10 ) + return math.floor(24 - ((perpage - 6) / 18) * 10) end function Menu.getItemMandatoryFontSize(perpage) diff --git a/plugins/calibre.koplugin/search.lua b/plugins/calibre.koplugin/search.lua index 156f6961f..61ea76e57 100644 --- a/plugins/calibre.koplugin/search.lua +++ b/plugins/calibre.koplugin/search.lua @@ -15,6 +15,7 @@ local InputContainer = require("ui/widget/container/inputcontainer") local Menu = require("ui/widget/menu") local Persist = require("persist") local Screen = require("device").screen +local Size = require("ui/size") local UIManager = require("ui/uimanager") local logger = require("logger") local socket = require("socket") @@ -384,8 +385,8 @@ function CalibreSearch:browse(option, run, chosen) dimen = Screen:getSize(), } self.search_menu = Menu:new{ - width = Screen:getWidth()-15, - height = Screen:getHeight()-15, + width = Screen:getWidth() - (Size.margin.fullscreen_popout * 2), + height = Screen:getHeight() - (Size.margin.fullscreen_popout * 2), show_parent = menu_container, onMenuHold = self.onMenuHold, cface = Font:getFace("smallinfofont"), @@ -444,8 +445,8 @@ function CalibreSearch:showresults(t, title) dimen = Screen:getSize(), } self.search_menu = Menu:new{ - width = Screen:getWidth()-15, - height = Screen:getHeight()-15, + width = Screen:getWidth() - (Size.margin.fullscreen_popout * 2), + height = Screen:getHeight() - (Size.margin.fullscreen_popout * 2), show_parent = menu_container, onMenuHold = self.onMenuHold, cface = Font:getFace("smallinfofont"), diff --git a/plugins/calibre.koplugin/wireless.lua b/plugins/calibre.koplugin/wireless.lua index 1a3aece1b..2f84fdf63 100644 --- a/plugins/calibre.koplugin/wireless.lua +++ b/plugins/calibre.koplugin/wireless.lua @@ -43,7 +43,11 @@ end local function updateDir(dir) local FileManager = require("apps/filemanager/filemanager") if FileManager:getCurrentDir() == dir then - FileManager.instance:reinit(dir) + -- getCurrentDir() will return nil (well, nothing, technically) if there isn't an FM instance, so, + -- unless we were passed a nil, this is technically redundant. + if FileManager.instance then + FileManager.instance:reinit(dir) + end end end diff --git a/plugins/coverbrowser.koplugin/listmenu.lua b/plugins/coverbrowser.koplugin/listmenu.lua index 4511b1be1..b8966d5d9 100644 --- a/plugins/coverbrowser.koplugin/listmenu.lua +++ b/plugins/coverbrowser.koplugin/listmenu.lua @@ -883,6 +883,11 @@ local ListMenu = {} function ListMenu:_recalculateDimen() self.dimen.w = self.width self.dimen.h = self.height or Screen:getHeight() + -- NOTE: inner_dimen should match dimen because we're generally (always?) borderless + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2 * self.border_size, + h = self.dimen.h - 2 * self.border_size, + } -- Find out available height from other UI elements made in Menu self.others_height = 0 @@ -908,7 +913,7 @@ function ListMenu:_recalculateDimen() self.itemnum_orig = self.path_items[self.path] self.focused_path_orig = self.focused_path end - local available_height = self.dimen.h - self.others_height - Size.line.thin + local available_height = self.inner_dimen.h - self.others_height - Size.line.thin -- (Note: we can't assign directly to self.perpage and expect it to -- be 'nil' if it was not defined, as we'll find instead the value @@ -943,7 +948,7 @@ function ListMenu:_recalculateDimen() -- menu item height based on number of items per page -- add space for the separator self.item_height = math.floor(available_height / self.perpage) - Size.line.thin - self.item_width = self.dimen.w + self.item_width = self.inner_dimen.w self.item_dimen = Geom:new{ w = self.item_width, h = self.item_height diff --git a/plugins/coverbrowser.koplugin/mosaicmenu.lua b/plugins/coverbrowser.koplugin/mosaicmenu.lua index e5023aa65..3a1e29661 100644 --- a/plugins/coverbrowser.koplugin/mosaicmenu.lua +++ b/plugins/coverbrowser.koplugin/mosaicmenu.lua @@ -799,6 +799,11 @@ local MosaicMenu = {} function MosaicMenu:_recalculateDimen() self.dimen.w = self.width self.dimen.h = self.height or Screen:getHeight() + -- NOTE: inner_dimen should match dimen because we're generally (always?) borderless + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2 * self.border_size, + h = self.dimen.h - 2 * self.border_size, + } local portrait_mode = true if Screen:getWidth() > Screen:getHeight() then @@ -834,8 +839,8 @@ function MosaicMenu:_recalculateDimen() -- Set our items target size self.item_margin = Screen:scaleBySize(10) - self.item_height = math.floor((self.dimen.h - self.others_height - (1+self.nb_rows)*self.item_margin) / self.nb_rows) - self.item_width = math.floor((self.dimen.w - (1+self.nb_cols)*self.item_margin) / self.nb_cols) + self.item_height = math.floor((self.inner_dimen.h - self.others_height - (1+self.nb_rows)*self.item_margin) / self.nb_rows) + self.item_width = math.floor((self.inner_dimen.w - (1+self.nb_cols)*self.item_margin) / self.nb_cols) self.item_dimen = Geom:new{ w = self.item_width, h = self.item_height @@ -873,7 +878,7 @@ function MosaicMenu:_updateItemsBuildUI() local container = self._do_center_partial_rows and CenterContainer or LeftContainer table.insert(self.item_group, container:new{ dimen = Geom:new{ - w = self.dimen.w, + w = self.inner_dimen.w, h = self.item_height }, cur_row diff --git a/plugins/statistics.koplugin/calendarview.lua b/plugins/statistics.koplugin/calendarview.lua index cefbe0cc4..643830088 100644 --- a/plugins/statistics.koplugin/calendarview.lua +++ b/plugins/statistics.koplugin/calendarview.lua @@ -443,14 +443,19 @@ function CalendarView:init() } end - local outer_padding = Size.padding.large + self.outer_padding = Size.padding.large self.inner_padding = Size.padding.small -- 7 days in a week - self.day_width = math.floor((self.dimen.w - 2*outer_padding - 6*self.inner_padding) / 7) + self.day_width = math.floor((self.dimen.w - 2*self.outer_padding - 6*self.inner_padding) / 7) -- Put back the possible 7px lost in rounding into outer_padding - outer_padding = math.floor((self.dimen.w - 7*self.day_width - 6*self.inner_padding) / 2) - self.content_width = self.dimen.w - 2*outer_padding + self.outer_padding = math.floor((self.dimen.w - 7*self.day_width - 6*self.inner_padding) / 2) + + self.inner_dimen = Geom:new{ + w = self.dimen.w - 2*self.outer_padding, + h = self.dimen.h - self.outer_padding, -- no bottom padding + } + self.content_width = self.inner_dimen.w local now_ts = os.time() if not MIN_MONTH then @@ -523,8 +528,8 @@ function CalendarView:init() }) end, }, + call_hold_input_on_tap = true, bordersize = 0, - margin = Screen:scaleBySize(20), text_font_face = "pgfont", text_font_bold = false, } @@ -532,7 +537,9 @@ function CalendarView:init() self.page_info_first_chev, self.page_info_spacer, self.page_info_left_chev, + self.page_info_spacer, self.page_info_text, + self.page_info_spacer, self.page_info_right_chev, self.page_info_spacer, self.page_info_last_chev, @@ -540,8 +547,8 @@ function CalendarView:init() local footer = BottomContainer:new{ dimen = Geom:new{ - w = self.content_width, - h = self.dimen.h, + w = self.inner_dimen.w, + h = self.inner_dimen.h, }, self.page_info, } @@ -575,9 +582,9 @@ function CalendarView:init() end -- At most 6 weeks in a month - local available_height = self.dimen.h - self.title_bar:getSize().h + local available_height = self.inner_dimen.h - self.title_bar:getSize().h - self.page_info:getSize().h - self.day_names:getSize().h - self.week_height = math.floor((available_height - 5*self.inner_padding) / 6) + self.week_height = math.floor((available_height - 7*self.inner_padding) / 6) self.day_border = Size.border.default if self.show_hourly_histogram then -- day num + nb_book_spans + histogram: ceil() as histogram rarely @@ -611,8 +618,8 @@ function CalendarView:init() local content = OverlapGroup:new{ dimen = Geom:new{ - w = self.content_width, - h = self.dimen.h, + w = self.inner_dimen.w, + h = self.inner_dimen.h, }, allow_mirroring = false, VerticalGroup:new{ @@ -627,7 +634,9 @@ function CalendarView:init() self[1] = FrameContainer:new{ width = self.dimen.w, height = self.dimen.h, - padding = outer_padding, + padding = self.outer_padding, + padding_bottom = 0, + margin = 0, bordersize = 0, background = Blitbuffer.COLOR_WHITE, content