[RFC] Pagination UI shenanigans (#7335)

* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
pull/7349/head
NiLuJe 3 years ago committed by GitHub
parent d243097d75
commit 525b1957b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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"),

@ -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

@ -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,

@ -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,

@ -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 = {

@ -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

@ -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"),

@ -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)

@ -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)

@ -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"),

@ -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

@ -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

@ -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

@ -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

Loading…
Cancel
Save