Update UI layout code to use new SVG icons

- Add IconWidget, use it for icons instead of ImageWidget.
  Specify icons by name only, look for them (with either
  .svg or .png suffixes) in multiple directories (including
  koreader/settings/icons/ to allow customizing them).
  Don't crash when icon name not found, shown a black
  background warning icon instead.
- Don't trust the icons' native sizes: replace
  scale_for_dpi=true with width/height=DGENERIC_ICON_SIZE,
  so all icons get the same (tunable) size - except in
  a few specific use cases.
- Top and bottom menu bars: normalize, and have icons
  properly centered in them, extend vertical line
  separators up to the edges.
- TOC: adjust expand/collapse icons size to items size
reviewable/pr7012/r1
poire-z 3 years ago
parent f0b09fb4b3
commit 24424e505e

@ -18,6 +18,7 @@ read_globals = {
"DGLOBAL_CACHE_SIZE_MAXIMUM", "DGLOBAL_CACHE_SIZE_MAXIMUM",
"DBACKGROUND_COLOR", "DBACKGROUND_COLOR",
"DOUTER_PAGE_COLOR", "DOUTER_PAGE_COLOR",
"DGENERIC_ICON_SIZE",
"DCREREADER_VIEW_MODE", "DCREREADER_VIEW_MODE",
"DSHOWOVERLAP", "DSHOWOVERLAP",
"DSHOWHIDDENFILES", "DSHOWHIDDENFILES",

@ -41,6 +41,9 @@ DBACKGROUND_COLOR = 0
-- outer page colour in scroll mode: 8 = gray, 0 = white, 15 = black -- outer page colour in scroll mode: 8 = gray, 0 = white, 15 = black
DOUTER_PAGE_COLOR = 0 DOUTER_PAGE_COLOR = 0
-- generic icon size
DGENERIC_ICON_SIZE = 40
-- supported view mode includes: "scroll" and "page" -- supported view mode includes: "scroll" and "page"
DCREREADER_VIEW_MODE = "page" DCREREADER_VIEW_MODE = "page"

@ -98,10 +98,9 @@ function FileManager:init()
}) })
end end
self.show_parent = self.show_parent or self self.show_parent = self.show_parent or self
local icon_size = Screen:scaleBySize(35) local icon_size = Screen:scaleBySize(DGENERIC_ICON_SIZE)
local home_button = IconButton:new{ local home_button = IconButton:new{
icon_file = "resources/icons/appbar.home.png", icon = "home",
scale_for_dpi = false,
width = icon_size, width = icon_size,
height = icon_size, height = icon_size,
padding = Size.padding.default, padding = Size.padding.default,
@ -113,8 +112,7 @@ function FileManager:init()
} }
local plus_button = IconButton:new{ local plus_button = IconButton:new{
icon_file = "resources/icons/appbar.plus.png", icon = "plus",
scale_for_dpi = false,
width = icon_size, width = icon_size,
height = icon_size, height = icon_size,
padding = Size.padding.default, padding = Size.padding.default,
@ -342,7 +340,7 @@ function FileManager:init()
--- @note: Lua 5.1 returns the raw return value from the os's system call. Counteract this madness. --- @note: Lua 5.1 returns the raw return value from the os's system call. Counteract this madness.
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_("The script returned a non-zero status code: %1!"), bit.rshift(rv, 8)), text = T(_("The script returned a non-zero status code: %1!"), bit.rshift(rv, 8)),
icon_file = "resources/info-warn.png", icon = "notice-warning",
}) })
end end
end) end)

@ -117,7 +117,7 @@ function FileManagerCollection:onMenuHold(item)
else else
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_("The script returned a non-zero status code: %1!"), bit.rshift(rv, 8)), text = T(_("The script returned a non-zero status code: %1!"), bit.rshift(rv, 8)),
icon_file = "resources/info-warn.png", icon = "notice-warning",
}) })
end end
end) end)

@ -30,19 +30,19 @@ function FileManagerMenu:init()
}, },
-- items in top menu -- items in top menu
filemanager_settings = { filemanager_settings = {
icon = "resources/icons/appbar.cabinet.files.png", icon = "appbar.filebrowser",
}, },
setting = { setting = {
icon = "resources/icons/appbar.settings.png", icon = "appbar.settings",
}, },
tools = { tools = {
icon = "resources/icons/appbar.tools.png", icon = "appbar.tools",
}, },
search = { search = {
icon = "resources/icons/appbar.magnify.browse.png", icon = "appbar.search",
}, },
main = { main = {
icon = "resources/icons/menu-icon.png", icon = "appbar.menu",
}, },
} }
@ -563,10 +563,10 @@ function FileManagerMenu:setUpdateItemTable()
self.menu_items.restart_koreader = nil self.menu_items.restart_koreader = nil
end end
if not Device:isTouchDevice() then if not Device:isTouchDevice() then
--add a shortcut on non touch-device -- add a shortcut on non touch-device
--because this menu is not accessible otherwise -- because this menu is not accessible otherwise
self.menu_items.plus_menu = { self.menu_items.plus_menu = {
icon = "resources/icons/appbar.plus.png", icon = "plus",
remember = false, remember = false,
callback = function() callback = function()
self:onCloseFileManagerMenu() self:onCloseFileManagerMenu()

@ -1,7 +1,7 @@
local BD = require("ui/bidi") local BD = require("ui/bidi")
local Device = require("device") local Device = require("device")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local RightContainer = require("ui/widget/container/rightcontainer") local RightContainer = require("ui/widget/container/rightcontainer")
local Screen = Device.screen local Screen = Device.screen
@ -32,8 +32,8 @@ function ReaderDogear:setupDogear(new_dogear_size)
end end
self[1] = RightContainer:new{ self[1] = RightContainer:new{
dimen = Geom:new{w = Screen:getWidth(), h = self.dogear_size}, dimen = Geom:new{w = Screen:getWidth(), h = self.dogear_size},
ImageWidget:new{ IconWidget:new{
file = "resources/icons/dogear.png", icon = "dogear.opaque",
rotation_angle = BD.mirroredUILayout() and 90 or 0, rotation_angle = BD.mirroredUILayout() and 90 or 0,
width = self.dogear_size, width = self.dogear_size,
height = self.dogear_size, height = self.dogear_size,

@ -1,5 +1,5 @@
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local LeftContainer = require("ui/widget/container/leftcontainer") local LeftContainer = require("ui/widget/container/leftcontainer")
local Screen = require("device").screen local Screen = require("device").screen
@ -9,8 +9,11 @@ local ReaderFlipping = InputContainer:new{
} }
function ReaderFlipping:init() function ReaderFlipping:init()
local widget = ImageWidget:new{ local icon_size = Screen:scaleBySize(32)
file = "resources/icons/appbar.book.open.png", local widget = IconWidget:new{
icon = "book.opened",
width = icon_size,
height = icon_size,
} }
self[1] = LeftContainer:new{ self[1] = LeftContainer:new{
dimen = Geom:new{w = Screen:getWidth(), h = widget:getSize().h}, dimen = Geom:new{w = Screen:getWidth(), h = widget:getSize().h},

@ -26,22 +26,22 @@ function ReaderMenu:init()
}, },
-- items in top menu -- items in top menu
navi = { navi = {
icon = "resources/icons/appbar.page.corner.bookmark.png", icon = "appbar.navigation",
}, },
typeset = { typeset = {
icon = "resources/icons/appbar.page.text.png", icon = "appbar.typeset",
}, },
setting = { setting = {
icon = "resources/icons/appbar.settings.png", icon = "appbar.settings",
}, },
tools = { tools = {
icon = "resources/icons/appbar.tools.png", icon = "appbar.tools",
}, },
search = { search = {
icon = "resources/icons/appbar.magnify.browse.png", icon = "appbar.search",
}, },
filemanager = { filemanager = {
icon = "resources/icons/appbar.cabinet.files.png", icon = "appbar.filebrowser",
remember = false, remember = false,
callback = function() callback = function()
self:onTapCloseMenu() self:onTapCloseMenu()
@ -50,7 +50,7 @@ function ReaderMenu:init()
end, end,
}, },
main = { main = {
icon = "resources/icons/menu-icon.png", icon = "appbar.menu",
} }
} }

@ -561,22 +561,31 @@ function ReaderToc:onShowToc()
end end
end end
-- update collapsible state -- Estimate expand/collapse icon size
local items_per_page = G_reader_settings:readSetting("items_per_page") or 14
-- *2/5 to acount for Menu top title and bottom icons, and add some air between consecutive icons
local icon_size = math.floor(Screen:getHeight() / items_per_page * 2/5)
local button_width = icon_size * 2
self.expand_button = Button:new{ self.expand_button = Button:new{
icon = "resources/icons/appbar.control.expand.png", icon = "control.expand",
icon_rotation_angle = BD.mirroredUILayout() and 180 or 0, icon_rotation_angle = BD.mirroredUILayout() and 180 or 0,
width = Screen:scaleBySize(30), width = button_width,
icon_width = icon_size,
icon_height = icon_size,
bordersize = 0, bordersize = 0,
show_parent = self, show_parent = self,
} }
self.collapse_button = Button:new{ self.collapse_button = Button:new{
icon = "resources/icons/appbar.control.collapse.png", icon = "control.collapse",
width = Screen:scaleBySize(30), width = button_width,
icon_width = icon_size,
icon_height = icon_size,
bordersize = 0, bordersize = 0,
show_parent = self, show_parent = self,
} }
-- update collapsible state
if #self.toc > 0 and #self.collapsed_toc == 0 then if #self.toc > 0 and #self.collapsed_toc == 0 then
local depth = 0 local depth = 0
for i = #self.toc, 1, -1 do for i = #self.toc, 1, -1 do
@ -608,7 +617,7 @@ function ReaderToc:onShowToc()
cface = Font:getFace("x_smallinfofont"), cface = Font:getFace("x_smallinfofont"),
single_line = true, single_line = true,
align_baselines = true, align_baselines = true,
perpage = G_reader_settings:readSetting("items_per_page") or 14, perpage = items_per_page,
line_color = require("ffi/blitbuffer").COLOR_WHITE, line_color = require("ffi/blitbuffer").COLOR_WHITE,
on_close_ges = { on_close_ges = {
GestureRange:new{ GestureRange:new{

@ -8,7 +8,7 @@ local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device") local Device = require("device")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local Event = require("ui/event") local Event = require("ui/event")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local OverlapGroup = require("ui/widget/overlapgroup") local OverlapGroup = require("ui/widget/overlapgroup")
local ReaderDogear = require("apps/reader/modules/readerdogear") local ReaderDogear = require("apps/reader/modules/readerdogear")
@ -104,10 +104,13 @@ function ReaderView:addWidgets()
view = self, view = self,
ui = self.ui, ui = self.ui,
} }
local arrow_size = Screen:scaleBySize(16)
self.arrow = AlphaContainer:new{ self.arrow = AlphaContainer:new{
alpha = 0.6, alpha = 0.6,
ImageWidget:new{ IconWidget:new{
file = "resources/icons/appbar.control.expand.png", icon = "control.expand",
width = arrow_size,
height = arrow_size,
} }
} }
self[1] = self.dogear self[1] = self.dogear
@ -124,7 +127,7 @@ Register a view UI widget module for document browsing.
@usage @usage
local ImageWidget = require("ui/widget/imagewidget") local ImageWidget = require("ui/widget/imagewidget")
local dummy_image = ImageWidget:new{ local dummy_image = ImageWidget:new{
file = "resources/icons/appbar.control.expand.png", file = "resources/koreader.png",
} }
-- the image will be painted on all book pages -- the image will be painted on all book pages
readerui.view:registerViewModule('dummy_image', dummy_image) readerui.view:registerViewModule('dummy_image', dummy_image)

@ -17,7 +17,7 @@ end
local CreOptions = { local CreOptions = {
prefix = 'copt', prefix = 'copt',
{ {
icon = "resources/icons/appbar.transform.rotate.right.large.png", icon = "appbar.rotation",
options = { options = {
{ {
name = "rotation_mode", name = "rotation_mode",
@ -59,7 +59,7 @@ Note that this may not be ensured under some conditions: in scroll mode, when a
} }
}, },
{ {
icon = "resources/icons/appbar.crop.large.png", icon = "appbar.crop",
options = { options = {
{ {
name = "h_page_margins", name = "h_page_margins",
@ -181,7 +181,7 @@ In the top menu → Settings → Status bar, you can choose whether the bottom m
} }
}, },
{ {
icon = "resources/icons/appbar.column.two.large.png", icon = "appbar.pageview",
options = { options = {
{ {
name = "view_mode", name = "view_mode",
@ -286,7 +286,7 @@ Note that your selected font size is not affected by this setting.]]),
} }
}, },
{ {
icon = "resources/icons/appbar.text.size.large.png", icon = "appbar.textsize",
options = { options = {
{ {
name = "font_size", name = "font_size",
@ -406,7 +406,7 @@ Note that your selected font size is not affected by this setting.]]),
} }
}, },
{ {
icon = "resources/icons/appbar.grade.b.large.png", icon = "appbar.contrast",
options = { options = {
{ {
name = "font_weight", name = "font_weight",
@ -480,7 +480,7 @@ Note that your selected font size is not affected by this setting.]]),
} }
}, },
{ {
icon = "resources/icons/appbar.settings.large.png", icon = "appbar.settings",
options = { options = {
{ {
name = "status_line", name = "status_line",

@ -24,7 +24,7 @@ local KoptOptions = {
prefix = 'kopt', prefix = 'kopt',
needs_redraw_on_change = true, needs_redraw_on_change = true,
{ {
icon = "resources/icons/appbar.transform.rotate.right.large.png", icon = "appbar.rotation",
options = { options = {
{ {
name = "rotation_mode", name = "rotation_mode",
@ -41,7 +41,7 @@ local KoptOptions = {
} }
}, },
{ {
icon = "resources/icons/appbar.crop.large.png", icon = "appbar.crop",
options = { options = {
{ {
name = "trim_page", name = "trim_page",
@ -78,7 +78,7 @@ In 'semi-auto' and 'manual' modes, you may need to define areas once on an odd p
} }
}, },
{ {
icon = "resources/icons/appbar.page.fit.png", icon = "appbar.pagefit",
options = { options = {
{ {
name = "zoom_overlap_h", name = "zoom_overlap_h",
@ -188,11 +188,11 @@ In 'semi-auto' and 'manual' modes, you may need to define areas once on an odd p
name_text = _("Zoom to"), name_text = _("Zoom to"),
-- toggle = {_("page"), _("content"), _("columns"), _("rows"), _("manual")}, -- toggle = {_("page"), _("content"), _("columns"), _("rows"), _("manual")},
item_icons = { item_icons = {
"resources/icons/zoom.page.png", "zoom.page",
"resources/icons/zoom.content.png", "zoom.content",
"resources/icons/zoom.direction.column.png", "zoom.column",
"resources/icons/zoom.direction.row.png", "zoom.row",
"resources/icons/zoom.manual.png", "zoom.manual",
}, },
alternate = false, alternate = false,
values = {4, 3, 2, 1, 0}, values = {4, 3, 2, 1, 0},
@ -208,14 +208,14 @@ In 'semi-auto' and 'manual' modes, you may need to define areas once on an odd p
return config.zoom_mode_genus < 3 return config.zoom_mode_genus < 3
end, end,
item_icons = { item_icons = {
"resources/icons/direction.LRTB.png", "direction.LRTB",
"resources/icons/direction.TBLR.png", "direction.TBLR",
"resources/icons/direction.LRBT.png", "direction.LRBT",
"resources/icons/direction.BTLR.png", "direction.BTLR",
"resources/icons/direction.BTRL.png", "direction.BTRL",
"resources/icons/direction.RLBT.png", "direction.RLBT",
"resources/icons/direction.TBRL.png", "direction.TBRL",
"resources/icons/direction.RLTB.png", "direction.RLTB",
}, },
alternate = false, alternate = false,
values = {7, 6, 5, 4, 3, 2, 1, 0}, values = {7, 6, 5, 4, 3, 2, 1, 0},
@ -229,7 +229,7 @@ left to right or reverse, top to bottom or reverse.]]),
} }
}, },
{ {
icon = "resources/icons/appbar.column.two.large.png", icon = "appbar.pageview",
options = { options = {
{ {
name = "page_scroll", name = "page_scroll",
@ -287,11 +287,11 @@ left to right or reverse, top to bottom or reverse.]]),
--- @translators Text alignment. Options given as icons: left, right, center, justify. --- @translators Text alignment. Options given as icons: left, right, center, justify.
name_text = _("Alignment"), name_text = _("Alignment"),
item_icons = { item_icons = {
"resources/icons/appbar.align.auto.png", "align.auto",
"resources/icons/appbar.align.left.png", "align.left",
"resources/icons/appbar.align.center.png", "align.center",
"resources/icons/appbar.align.right.png", "align.right",
"resources/icons/appbar.align.justify.png", "align.justify",
}, },
values = {-1,0,1,2,3}, values = {-1,0,1,2,3},
default_value = DKOPTREADER_CONFIG_JUSTIFICATION, default_value = DKOPTREADER_CONFIG_JUSTIFICATION,
@ -313,7 +313,7 @@ The first option ("auto") tries to automatically align reflowed text as it is in
} }
}, },
{ {
icon = "resources/icons/appbar.text.size.large.png", icon = "appbar.textsize",
options = { options = {
{ {
name = "font_size", name = "font_size",
@ -391,7 +391,7 @@ Some of the other settings are only available when reflow mode is enabled.]]),
} }
}, },
{ {
icon = "resources/icons/appbar.grade.b.large.png", icon = "appbar.contrast",
options = { options = {
{ {
name = "contrast", name = "contrast",
@ -445,7 +445,7 @@ This can also be used to remove some gray background or to convert a grayscale o
} }
}, },
{ {
icon = "resources/icons/appbar.settings.large.png", icon = "appbar.settings",
options = { options = {
{ {
name="doc_language", name="doc_language",
@ -530,9 +530,9 @@ This can also be used to remove some gray background or to convert a grayscale o
name = "max_columns", name = "max_columns",
name_text = _("Document Columns"), name_text = _("Document Columns"),
item_icons = { item_icons = {
"resources/icons/appbar.column.one.png", "column.one",
"resources/icons/appbar.column.two.png", "column.two",
"resources/icons/appbar.column.three.png", "column.three",
}, },
values = {1,2,3}, values = {1,2,3},
default_value = DKOPTREADER_CONFIG_MAX_COLUMNS, default_value = DKOPTREADER_CONFIG_MAX_COLUMNS,

@ -46,8 +46,7 @@ common_info.about = {
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_("KOReader %1\n\nA document viewer for E Ink devices.\n\nLicensed under Affero GPL v3. All dependencies are free software.\n\nhttp://koreader.rocks/"), BD.ltr(Version:getCurrentRevision())), text = T(_("KOReader %1\n\nA document viewer for E Ink devices.\n\nLicensed under Affero GPL v3. All dependencies are free software.\n\nhttp://koreader.rocks/"), BD.ltr(Version:getCurrentRevision())),
icon_file = "resources/ko-icon.png", icon = "koreader",
alpha = true,
}) })
end end
} }

@ -38,11 +38,11 @@ Turning pages can be done either by swiping left and right or by single taps on
### Main <a id="main-menu"></a> ### Main <a id="main-menu"></a>
![Menu](../resources/icons/menu-icon.png) You can always view this quickstart guide again through *Help* *Quickstart guide* in the top right menu. ![Menu](../resources/icons/mdlight/appbar.menu.svg) You can always view this quickstart guide again through *Help* *Quickstart guide* in the top right menu.
### Settings <a id="settings"></a> ### Settings <a id="settings"></a>
![Settings](../resources/icons/appbar.settings.png) You can change the language and other settings through the gear icon. ![Settings](../resources/icons/mdlight/appbar.settings.svg) You can change the language and other settings through the gear icon.
## File browser <a id="file-browser"></a> ## File browser <a id="file-browser"></a>

@ -248,7 +248,7 @@ function RenderImage:renderSVGImageFileWithNanoSVG(filename, width, height, zoom
local bb = Blitbuffer.new(width, height, Blitbuffer.TYPE_BBRGB32) local bb = Blitbuffer.new(width, height, Blitbuffer.TYPE_BBRGB32)
svg_image:drawTo(bb, zoom, offset_x, offset_y) svg_image:drawTo(bb, zoom, offset_x, offset_y)
svg_image:free() svg_image:free()
return bb return bb, true -- is_straight_alpha=true
end end
function RenderImage:renderSVGImageFileWithMupdf(filename, width, height, zoom) function RenderImage:renderSVGImageFileWithMupdf(filename, width, height, zoom)
@ -293,7 +293,7 @@ function RenderImage:renderSVGImageFileWithMupdf(filename, width, height, zoom)
end end
page:close() page:close()
document:close() document:close()
return bb return bb -- pre-multiplied alpha: no is_straight_alpha=true
end end
return RenderImage return RenderImage

@ -6,7 +6,7 @@ local bit = require("bit")
local Font = require("ui/font") local Font = require("ui/font")
local Cache = require("cache") local Cache = require("cache")
local CacheItem = require("cacheitem") local CacheItem = require("cacheitem")
local BlitBuffer = require("ffi/blitbuffer") local Blitbuffer = require("ffi/blitbuffer")
local Device = require("device") local Device = require("device")
local logger = require("logger") local logger = require("logger")
@ -207,7 +207,7 @@ end
-- @string text text to render -- @string text text to render
-- @bool[opt=false] kerning whether the text should be measured with kerning -- @bool[opt=false] kerning whether the text should be measured with kerning
-- @bool[opt=false] bold whether the text should be measured as bold -- @bool[opt=false] bold whether the text should be measured as bold
-- @tparam[opt=BlitBuffer.COLOR_BLACK] BlitBuffer.COLOR fgcolor foreground color -- @tparam[opt=Blitbuffer.COLOR_BLACK] Blitbuffer.COLOR fgcolor foreground color
-- @int[opt=nil] width maximum rendering width -- @int[opt=nil] width maximum rendering width
-- @tparam[opt] table char_pads array of integers, nb of pixels to add, one for each utf8 char in text -- @tparam[opt] table char_pads array of integers, nb of pixels to add, one for each utf8 char in text
-- @return int width of rendered bitmap -- @return int width of rendered bitmap
@ -218,7 +218,7 @@ function RenderText:renderUtf8Text(dest_bb, x, baseline, face, text, kerning, bo
end end
if not fgcolor then if not fgcolor then
fgcolor = BlitBuffer.COLOR_BLACK fgcolor = Blitbuffer.COLOR_BLACK
end end
-- may still need more adaptive pen placement when kerning, -- may still need more adaptive pen placement when kerning,

@ -34,6 +34,7 @@ local Size = {
thin = Screen:scaleBySize(0.5), thin = Screen:scaleBySize(0.5),
button = Screen:scaleBySize(1.5), button = Screen:scaleBySize(1.5),
window = Screen:scaleBySize(1.5), window = Screen:scaleBySize(1.5),
thick = Screen:scaleBySize(2),
inputtext = Screen:scaleBySize(2), inputtext = Screen:scaleBySize(2),
}, },
margin = { margin = {

@ -91,7 +91,7 @@ function BookStatusWidget:init()
end end
self.star = Button:new{ self.star = Button:new{
icon = "resources/icons/stats.star.empty.png", icon = "star.empty",
bordersize = 0, bordersize = 0,
radius = 0, radius = 0,
margin = 0, margin = 0,
@ -256,7 +256,7 @@ function BookStatusWidget:setStar(num)
for i = 1, num do for i = 1, num do
table.insert(stars_group, self.star:new{ table.insert(stars_group, self.star:new{
icon = "resources/icons/stats.star.full.png", icon = "star.full",
callback = function() self:setStar(i) end callback = function() self:setStar(i) end
}) })
end end

@ -22,17 +22,20 @@ local Font = require("ui/font")
local FrameContainer = require("ui/widget/container/framecontainer") local FrameContainer = require("ui/widget/container/framecontainer")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local Size = require("ui/size") local Size = require("ui/size")
local TextWidget = require("ui/widget/textwidget") local TextWidget = require("ui/widget/textwidget")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local _ = require("gettext") local _ = require("gettext")
local Screen = Device.screen
local Button = InputContainer:new{ local Button = InputContainer:new{
text = nil, -- mandatory text = nil, -- mandatory
text_func = nil, text_func = nil,
icon = nil, icon = nil,
icon_width = Screen:scaleBySize(DGENERIC_ICON_SIZE), -- our icons are square
icon_height = Screen:scaleBySize(DGENERIC_ICON_SIZE),
icon_rotation_angle = 0, icon_rotation_angle = 0,
preselect = false, preselect = false,
callback = nil, callback = nil,
@ -74,11 +77,12 @@ function Button:init()
face = Font:getFace(self.text_font_face, self.text_font_size) face = Font:getFace(self.text_font_face, self.text_font_size)
} }
else else
self.label_widget = ImageWidget:new{ self.label_widget = IconWidget:new{
file = self.icon, icon = self.icon,
rotation_angle = self.icon_rotation_angle, rotation_angle = self.icon_rotation_angle,
dim = not self.enabled, dim = not self.enabled,
scale_for_dpi = true, width = self.icon_width,
height = self.icon_height,
} }
end end
local widget_size = self.label_widget:getSize() local widget_size = self.label_widget:getSize()

@ -15,7 +15,7 @@ local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local IconButton = require("ui/widget/iconbutton") local IconButton = require("ui/widget/iconbutton")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local LineWidget = require("ui/widget/linewidget") local LineWidget = require("ui/widget/linewidget")
local RightContainer = require("ui/widget/container/rightcontainer") local RightContainer = require("ui/widget/container/rightcontainer")
@ -180,6 +180,7 @@ function ConfigOption:init()
local default_item_font_size = 16 -- font size for letters, toggles and buttonprogress local default_item_font_size = 16 -- font size for letters, toggles and buttonprogress
local default_items_spacing = 40 -- spacing between letters (font sizes) and icons local default_items_spacing = 40 -- spacing between letters (font sizes) and icons
local default_option_height = 50 -- height of each line local default_option_height = 50 -- height of each line
local max_icon_height = Screen:scaleBySize(DGENERIC_ICON_SIZE) -- max height of icons
-- The next ones are already scaleBySize()'d: -- The next ones are already scaleBySize()'d:
local default_option_vpadding = Size.padding.large -- vertical padding at top and bottom local default_option_vpadding = Size.padding.large -- vertical padding at top and bottom
local default_option_hpadding = Size.padding.fullscreen local default_option_hpadding = Size.padding.fullscreen
@ -486,7 +487,7 @@ function ConfigOption:init()
-- Icons (ex: columns, text align, with PDF) -- Icons (ex: columns, text align, with PDF)
if self.options[c].item_icons then if self.options[c].item_icons then
local items_count = #self.options[c].item_icons local items_count = #self.options[c].item_icons
local icon_max_height = option_height local icon_max_height = math.min(option_height, max_icon_height)
local icon_max_width = math.floor(option_widget_width / items_count) local icon_max_width = math.floor(option_widget_width / items_count)
local icon_size = math.min(icon_max_height, icon_max_width) local icon_size = math.min(icon_max_height, icon_max_width)
local max_item_spacing = (option_widget_width - icon_size * items_count) / items_count local max_item_spacing = (option_widget_width - icon_size * items_count) / items_count
@ -497,12 +498,11 @@ function ConfigOption:init()
local underline_padding = - math.floor(0.05 * icon_size) local underline_padding = - math.floor(0.05 * icon_size)
for d = 1, #self.options[c].item_icons do for d = 1, #self.options[c].item_icons do
local option_item = OptionIconItem:new{ local option_item = OptionIconItem:new{
icon = ImageWidget:new{ icon = IconWidget:new{
file = self.options[c].item_icons[d], icon = self.options[c].item_icons[d],
dim = not enabled, dim = not enabled,
width = icon_size, width = icon_size,
height = icon_size, height = icon_size,
scale_factor = 0, -- scale to fit width and height
}, },
underline_padding = underline_padding, underline_padding = underline_padding,
padding_left = d > 1 and horizontal_half_padding, padding_left = d > 1 and horizontal_half_padding,
@ -677,17 +677,16 @@ function MenuBar:init()
local line_thickness = Size.line.thick local line_thickness = Size.line.thick
local config_options = self.config_dialog.config_options local config_options = self.config_dialog.config_options
local menu_items = {} local menu_items = {}
local icon_width = Screen:scaleBySize(40) local icon_width = Screen:scaleBySize(DGENERIC_ICON_SIZE)
local icon_height = icon_width local icon_height = icon_width
local icons_width = (icon_width + 2*icon_sep_width) * #config_options local icons_width = (icon_width + 2*icon_sep_width) * #config_options
local icons_height = icon_height local bar_height = icon_height + 2*Size.padding.default
for c = 1, #config_options do for c = 1, #config_options do
local menu_icon = IconButton:new{ local menu_icon = IconButton:new{
show_parent = self.config_dialog, show_parent = self.config_dialog,
icon_file = config_options[c].icon, icon = config_options[c].icon,
width = icon_width, width = icon_width,
height = icon_height, height = icon_height,
scale_for_dpi = false,
callback = function() callback = function()
self.config_dialog:handleEvent(Event:new("ShowConfigPanel", c)) self.config_dialog:handleEvent(Event:new("ShowConfigPanel", c))
end, end,
@ -713,14 +712,14 @@ function MenuBar:init()
background = Blitbuffer.COLOR_BLACK, background = Blitbuffer.COLOR_BLACK,
dimen = Geom:new{ dimen = Geom:new{
w = icon_sep_width, w = icon_sep_width,
h = icons_height, h = bar_height,
} }
} }
local icon_sep_white = LineWidget:new{ local icon_sep_white = LineWidget:new{
background = Blitbuffer.COLOR_WHITE, background = Blitbuffer.COLOR_WHITE,
dimen = Geom:new{ dimen = Geom:new{
w = icon_sep_width, w = icon_sep_width,
h = icons_height, h = bar_height,
} }
} }
local spacing = HorizontalSpan:new{ local spacing = HorizontalSpan:new{
@ -774,7 +773,7 @@ function MenuBar:init()
table.insert(menu_bar, spacing) table.insert(menu_bar, spacing)
table.insert(line_bar, spacing_line) table.insert(line_bar, spacing_line)
self.dimen = Geom:new{ w = Screen:getWidth(), h = icons_height} self.dimen = Geom:new{ w = Screen:getWidth(), h = bar_height}
local vertical_menu = VerticalGroup:new{ local vertical_menu = VerticalGroup:new{
line_bar, line_bar,
menu_bar, menu_bar,
@ -864,6 +863,7 @@ function ConfigDialog:update()
} }
self.dialog_frame = FrameContainer:new{ self.dialog_frame = FrameContainer:new{
background = Blitbuffer.COLOR_WHITE, background = Blitbuffer.COLOR_WHITE,
padding_bottom = 0, -- ensured by MenuBar
VerticalGroup:new{ VerticalGroup:new{
self.config_panel, self.config_panel,
self.config_menubar, self.config_menubar,

@ -27,7 +27,7 @@ local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local MovableContainer = require("ui/widget/container/movablecontainer") local MovableContainer = require("ui/widget/container/movablecontainer")
local Size = require("ui/size") local Size = require("ui/size")
@ -80,9 +80,8 @@ function ConfirmBox:init()
} }
local content = HorizontalGroup:new{ local content = HorizontalGroup:new{
align = "center", align = "center",
ImageWidget:new{ IconWidget:new{
file = "resources/info-i.png", icon = "notice-question",
scale_for_dpi = true,
}, },
HorizontalSpan:new{ width = Size.span.horizontal_default }, HorizontalSpan:new{ width = Size.span.horizontal_default },
text_widget, text_widget,

@ -17,7 +17,7 @@ Example:
} }
--]] --]]
local BlitBuffer = require("ffi/blitbuffer") local Blitbuffer = require("ffi/blitbuffer")
local WidgetContainer = require("ui/widget/container/widgetcontainer") local WidgetContainer = require("ui/widget/container/widgetcontainer")
local AlphaContainer = WidgetContainer:new{ local AlphaContainer = WidgetContainer:new{
@ -48,7 +48,7 @@ function AlphaContainer:paintTo(bb, x, y)
private_bb:free() -- free the one we're going to replace private_bb:free() -- free the one we're going to replace
end end
-- create private blitbuffer for our child widget to paint to -- create private blitbuffer for our child widget to paint to
private_bb = BlitBuffer.new(contentSize.w, contentSize.h, bb:getType()) private_bb = Blitbuffer.new(contentSize.w, contentSize.h, bb:getType())
self.private_bb = private_bb self.private_bb = private_bb
-- save what is below our painting area -- save what is below our painting area
@ -59,13 +59,13 @@ function AlphaContainer:paintTo(bb, x, y)
if self.background_bb then if self.background_bb then
self.background_bb:free() -- free the one we're going to replace self.background_bb:free() -- free the one we're going to replace
end end
self.background_bb = BlitBuffer.new(contentSize.w, contentSize.h, bb:getType()) self.background_bb = Blitbuffer.new(contentSize.w, contentSize.h, bb:getType())
end end
self.background_bb:blitFrom(bb, 0, 0, x, y) self.background_bb:blitFrom(bb, 0, 0, x, y)
end end
-- now have our childs paint to the private blitbuffer -- now have our childs paint to the private blitbuffer
--- @todo should we clean before painting? private_bb:fill(Blitbuffer.COLOR_WHITE)
self[1]:paintTo(private_bb, 0, 0) self[1]:paintTo(private_bb, 0, 0)
-- blit the private blitbuffer to our parent blitbuffer -- blit the private blitbuffer to our parent blitbuffer

@ -13,7 +13,7 @@ position, Hold will toggle between full opacity and 0.7 transparency.
This container's content is expected to not change its width and height. This container's content is expected to not change its width and height.
]] ]]
local BlitBuffer = require("ffi/blitbuffer") local Blitbuffer = require("ffi/blitbuffer")
local Device = require("device") local Device = require("device")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
@ -114,8 +114,8 @@ function MovableContainer:paintTo(bb, x, y)
if self.alpha then if self.alpha then
-- Create private blitbuffer for our child widget to paint to -- Create private blitbuffer for our child widget to paint to
local private_bb = BlitBuffer.new(bb:getWidth(), bb:getHeight(), bb:getType()) local private_bb = Blitbuffer.new(bb:getWidth(), bb:getHeight(), bb:getType())
private_bb:fill(BlitBuffer.COLOR_WHITE) -- for round corners' outside to not stay black private_bb:fill(Blitbuffer.COLOR_WHITE) -- for round corners' outside to not stay black
self[1]:paintTo(private_bb, self.dimen.x, self.dimen.y) self[1]:paintTo(private_bb, self.dimen.x, self.dimen.y)
-- And blend our private blitbuffer over the original bb -- And blend our private blitbuffer over the original bb
bb:addblitFrom(private_bb, self.dimen.x, self.dimen.y, self.dimen.x, self.dimen.y, bb:addblitFrom(private_bb, self.dimen.x, self.dimen.y, self.dimen.x, self.dimen.y,

@ -6,20 +6,20 @@ local Device = require("device")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local VerticalGroup = require("ui/widget/verticalgroup") local VerticalGroup = require("ui/widget/verticalgroup")
local VerticalSpan = require("ui/widget/verticalspan") local VerticalSpan = require("ui/widget/verticalspan")
local Screen = Device.screen
local IconButton = InputContainer:new{ local IconButton = InputContainer:new{
icon_file = "resources/info-confirm.png", icon = "notice-warning",
dimen = nil, dimen = nil,
-- show_parent is used for UIManager:setDirty, so we can trigger repaint -- show_parent is used for UIManager:setDirty, so we can trigger repaint
show_parent = nil, show_parent = nil,
width = nil, width = Screen:scaleBySize(DGENERIC_ICON_SIZE), -- our icons are square
height = nil, height = Screen:scaleBySize(DGENERIC_ICON_SIZE),
scale_for_dpi = true,
padding = 0, padding = 0,
padding_top = nil, padding_top = nil,
padding_right = nil, padding_right = nil,
@ -30,9 +30,8 @@ local IconButton = InputContainer:new{
} }
function IconButton:init() function IconButton:init()
self.image = ImageWidget:new{ self.image = IconWidget:new{
file = self.icon_file, icon = self.icon,
scale_for_dpi = self.scale_for_dpi,
width = self.width, width = self.width,
height = self.height, height = self.height,
} }

@ -0,0 +1,70 @@
--[[
Subclass of ImageWidget to show icons
]]
local DataStorage = require("datastorage")
local ImageWidget = require("ui/widget/imagewidget")
local Screen = require("device").screen
-- Directories to look for icons by name, with any of the accepted suffixes
local ICONS_DIRS = {}
local user_icons_dir = DataStorage:getSettingsDir() .. "/icons"
if lfs.attributes(user_icons_dir, "mode") == "directory" then
table.insert(ICONS_DIRS, user_icons_dir)
end
-- Default icons (material design light)
table.insert(ICONS_DIRS, "resources/icons/mdlight")
-- Fallback directories
table.insert(ICONS_DIRS, "resources/icons")
table.insert(ICONS_DIRS, "resources")
-- Supported icon suffixes
local ICONS_EXTS = { ".svg", ".png" }
-- Show this icon instead of crashing if we can't find any icon
local ICON_NOT_FOUND = "resources/icons/icon-not-found.svg"
-- Icon filepath location cache
local ICONS_PATH = {}
local IconWidget = ImageWidget:extend{
-- The icon filename should be provided without any path
icon = ICON_NOT_FOUND, -- show this if not provided
-- See ImageWidget for other available options,
-- we only start with a few different defaults, that can
-- be overriden by callers.
width = Screen:scaleBySize(DGENERIC_ICON_SIZE), -- our icons are square
height = Screen:scaleBySize(DGENERIC_ICON_SIZE),
alpha = true, -- our icons have a transparent background
is_icon = true, -- avoid dithering in ImageWidget:paintTo()
}
function IconWidget:init()
if self.image or self.file then
-- In case we're created with one of these: just be an ImageWidget.
return
end
-- See if already seen and full path cached
self.file = ICONS_PATH[self.icon]
if not self.file then
-- Not yet seen, look for it
for _, dir in ipairs(ICONS_DIRS) do
for __, ext in ipairs(ICONS_EXTS) do
local path = dir .. "/" .. self.icon .. ext
if lfs.attributes(path, "mode") == "file" then
self.file = path
break
end
end
if self.file then
break
end
end
if not self.file then
self.file = ICON_NOT_FOUND
end
ICONS_PATH[self.icon] = self.file
end
end
return IconWidget

@ -4,7 +4,7 @@ ImageWidget shows an image from a file or memory
Show image from file example: Show image from file example:
UIManager:show(ImageWidget:new{ UIManager:show(ImageWidget:new{
file = "resources/info-i.png", file = "resources/koreader.png",
-- Make sure alpha is set to true if png has transparent background -- Make sure alpha is set to true if png has transparent background
-- alpha = true, -- alpha = true,
}) })
@ -29,7 +29,6 @@ local Screen = require("device").screen
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local Widget = require("ui/widget/widget") local Widget = require("ui/widget/widget")
local logger = require("logger") local logger = require("logger")
local util = require("util")
-- DPI_SCALE can't change without a restart, so let's compute it now -- DPI_SCALE can't change without a restart, so let's compute it now
local function get_dpi_scale() local function get_dpi_scale()
@ -80,6 +79,7 @@ local ImageWidget = Widget:new{
invert = nil, invert = nil,
dim = nil, dim = nil,
alpha = false, -- honors alpha values from the image alpha = false, -- honors alpha values from the image
is_icon = false, -- set to true by sub-class IconWidget
-- When rotation_angle is not 0, native image is rotated by this angle -- When rotation_angle is not 0, native image is rotated by this angle
-- before scaling. -- before scaling.
@ -127,29 +127,7 @@ function ImageWidget:_loadimage()
self._bb_disposable = self.image_disposable self._bb_disposable = self.image_disposable
end end
local ICONS_ALT_SVG_DIR = false
-- Uncomment to use SVG icons from one of these directories
-- ICONS_ALT_SVG_DIR = "resources/icons/src/"
-- ICONS_ALT_SVG_DIR = "resources/icons/svg/"
function ImageWidget:_loadfile() function ImageWidget:_loadfile()
if ICONS_ALT_SVG_DIR then
-- Pick the SVG version if one exists when a png icon file path is provided
local dir, name = self.file:match("^(resources/icons/)([^/]*).png$")
if dir and name then
local svg_file = ICONS_ALT_SVG_DIR .. name .. ".svg"
if lfs.attributes(svg_file, "mode") ~= "file" then
svg_file = svg_file:gsub(".large", "") -- Try with this removed
if lfs.attributes(svg_file, "mode") ~= "file" then
svg_file = nil -- no alt svg available
end
end
if svg_file then
logger.dbg("using alt SVG", svg_file)
self.file = svg_file
end
end
end
local itype = string.lower(string.match(self.file, ".+%.([^.]+)") or "") local itype = string.lower(string.match(self.file, ".+%.([^.]+)") or "")
if itype == "svg" or itype == "png" or itype == "jpg" or itype == "jpeg" if itype == "svg" or itype == "png" or itype == "jpg" or itype == "jpeg"
or itype == "gif" or itype == "tiff" or itype == "tif" then or itype == "gif" or itype == "tiff" or itype == "tif" then
@ -178,6 +156,7 @@ function ImageWidget:_loadfile()
-- hit cache -- hit cache
self._bb = cache.bb self._bb = cache.bb
self._bb_disposable = false -- don't touch or free a cached _bb self._bb_disposable = false -- don't touch or free a cached _bb
self._is_straight_alpha = cache.is_straight_alpha
else else
if itype == "svg" then if itype == "svg" then
local zoom local zoom
@ -188,9 +167,10 @@ function ImageWidget:_loadfile()
width = self.width width = self.width
height = self.height height = self.height
end end
-- local start_ts = require("ffi/util").getTimestamp() -- Uncomment for timing things -- If NanoSVG is used by renderSVGImageFile, we'll get self._is_straight_alpha=true,
self._bb = RenderImage:renderSVGImageFile(self.file, width, height, zoom) -- and paintTo() must use alphablitFrom() instead of pmulalphablitFrom() (which is
-- logger.info(string.format(" SVG rendering %.6f s", require("ffi/util").getDuration(start_ts)), self.file, zoom or "", width, height) -- fine for everything MuPDF renders out)
self._bb, self._is_straight_alpha = RenderImage:renderSVGImageFile(self.file, width, height, zoom)
else else
self._bb = RenderImage:renderImageFile(self.file, false, width, height) self._bb = RenderImage:renderImageFile(self.file, false, width, height)
if scale_for_dpi_here then if scale_for_dpi_here then
@ -204,7 +184,10 @@ function ImageWidget:_loadfile()
self._bb_disposable = false -- don't touch or free a cached _bb self._bb_disposable = false -- don't touch or free a cached _bb
-- cache this image -- cache this image
logger.dbg("cache", hash) logger.dbg("cache", hash)
cache = ImageCacheItem:new{ bb = self._bb } cache = ImageCacheItem:new{
bb = self._bb,
is_straight_alpha = self._is_straight_alpha,
}
cache.size = tonumber(cache.bb.stride) * cache.bb.h cache.size = tonumber(cache.bb.stride) * cache.bb.h
ImageCache:insert(hash, cache) ImageCache:insert(hash, cache)
end end
@ -392,27 +375,29 @@ function ImageWidget:paintTo(bb, x, y)
h = size.h h = size.h
} }
logger.dbg("blitFrom", x, y, self._offset_x, self._offset_y, size.w, size.h) logger.dbg("blitFrom", x, y, self._offset_x, self._offset_y, size.w, size.h)
-- Figure out if we're trying to render one of our own icons... local do_alpha = false
local is_icon = self.file and util.stringStartsWith(self.file, "resources/")
if self.alpha == true then if self.alpha == true then
-- Only actually try to alpha-blend if the image really has an alpha channel... -- Only actually try to alpha-blend if the image really has an alpha channel...
local bbtype = self._bb:getType() local bbtype = self._bb:getType()
if bbtype == Blitbuffer.TYPE_BB8A or bbtype == Blitbuffer.TYPE_BBRGB32 then if bbtype == Blitbuffer.TYPE_BB8A or bbtype == Blitbuffer.TYPE_BBRGB32 then
-- NOTE: MuPDF feeds us premultiplied alpha (and we don't care w/ GifLib, as alpha is all or nothing). do_alpha = true
if Screen.sw_dithering and not is_icon then end
end
if do_alpha then
-- NOTE: MuPDF feeds us premultiplied alpha (and we don't care w/ GifLib, as alpha is all or nothing),
-- but NanoSVG feeds us straight alpha
if self._is_straight_alpha then
--- @todo if Screen.sw_dithering then use bb:ditheralphablitFrom() when it's available
bb:alphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else
if Screen.sw_dithering then
bb:ditherpmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) bb:ditherpmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else else
bb:pmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) bb:pmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
end end
else
if Screen.sw_dithering and not is_icon then
bb:ditherblitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else
bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
end
end end
else else
if Screen.sw_dithering and not is_icon then if Screen.sw_dithering then
bb:ditherblitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) bb:ditherblitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else else
bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
@ -428,7 +413,7 @@ function ImageWidget:paintTo(bb, x, y)
-- displayed when the whole screen is inverted by night mode. -- displayed when the whole screen is inverted by night mode.
-- Except for our black & white icon files, that we do want inverted -- Except for our black & white icon files, that we do want inverted
-- in night mode. -- in night mode.
if Screen.night_mode and not is_icon then if Screen.night_mode and not self.is_icon then
bb:invertRect(x, y, size.w, size.h) bb:invertRect(x, y, size.w, size.h)
end end
end end

@ -31,6 +31,7 @@ local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local IconWidget = require("ui/widget/iconwidget")
local ImageWidget = require("ui/widget/imagewidget") local ImageWidget = require("ui/widget/imagewidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local MovableContainer = require("ui/widget/container/movablecontainer") local MovableContainer = require("ui/widget/container/movablecontainer")
@ -57,8 +58,8 @@ local InfoMessage = InputContainer:new{
image_height = nil, -- The image height if image is used. Keep it nil to use original height. image_height = nil, -- The image height if image is used. Keep it nil to use original height.
-- Whether the icon should be shown. If it is false, self.image will be ignored. -- Whether the icon should be shown. If it is false, self.image will be ignored.
show_icon = true, show_icon = true,
icon_file = nil, -- use this file instead of "resources/info-i.png" icon = "notice-info",
alpha = false, -- does that icon have an alpha channel? alpha = nil, -- if image or icon have an alpha channel (default to true for icons, false for images
dismiss_callback = function() end, dismiss_callback = function() end,
-- In case we'd like to use it to display some text we know a few more things about: -- In case we'd like to use it to display some text we know a few more things about:
lang = nil, lang = nil,
@ -98,13 +99,12 @@ function InfoMessage:init()
image = self.image, image = self.image,
width = self.image_width, width = self.image_width,
height = self.image_height, height = self.image_height,
alpha = self.alpha, alpha = self.alpha ~= nil and self.alpha or false, -- default to false
} }
else else
image_widget = ImageWidget:new{ image_widget = IconWidget:new{
file = self.icon_file or "resources/info-i.png", icon = self.icon,
scale_for_dpi = true, alpha = self.alpha == nil and true or self.alpha, -- default to true
alpha = self.alpha,
} }
end end
else else

@ -352,16 +352,16 @@ function KeyValuePage:init()
-- return button -- return button
--- @todo: alternative icon if BD.mirroredUILayout() --- @todo: alternative icon if BD.mirroredUILayout()
self.page_return_arrow = Button:new{ self.page_return_arrow = Button:new{
icon = "resources/icons/appbar.arrow.left.up.png", icon = "back.top",
callback = function() self:onReturn() end, callback = function() self:onReturn() end,
bordersize = 0, bordersize = 0,
show_parent = self, show_parent = self,
} }
-- group for page info -- group for page info
local chevron_left = "resources/icons/appbar.chevron.left.png" local chevron_left = "chevron.left"
local chevron_right = "resources/icons/appbar.chevron.right.png" local chevron_right = "chevron.right"
local chevron_first = "resources/icons/appbar.chevron.first.png" local chevron_first = "chevron.first"
local chevron_last = "resources/icons/appbar.chevron.last.png" local chevron_last = "chevron.last"
if BD.mirroredUILayout() then if BD.mirroredUILayout() then
chevron_left, chevron_right = chevron_right, chevron_left chevron_left, chevron_right = chevron_right, chevron_left
chevron_first, chevron_last = chevron_last, chevron_first chevron_first, chevron_last = chevron_last, chevron_first

@ -658,10 +658,10 @@ function Menu:init()
-- group for items -- group for items
self.item_group = VerticalGroup:new{} self.item_group = VerticalGroup:new{}
-- group for page info -- group for page info
local chevron_left = "resources/icons/appbar.chevron.left.png" local chevron_left = "chevron.left"
local chevron_right = "resources/icons/appbar.chevron.right.png" local chevron_right = "chevron.right"
local chevron_first = "resources/icons/appbar.chevron.first.png" local chevron_first = "chevron.first"
local chevron_last = "resources/icons/appbar.chevron.last.png" local chevron_last = "chevron.last"
if BD.mirroredUILayout() then if BD.mirroredUILayout() then
chevron_left, chevron_right = chevron_right, chevron_left chevron_left, chevron_right = chevron_right, chevron_left
chevron_first, chevron_last = chevron_last, chevron_first chevron_first, chevron_last = chevron_last, chevron_first
@ -777,7 +777,7 @@ function Menu:init()
-- return button -- return button
self.page_return_arrow = Button:new{ self.page_return_arrow = Button:new{
icon = "resources/icons/appbar.arrow.left.up.png", icon = "back.top",
callback = function() callback = function()
if self.onReturn then self:onReturn() end if self.onReturn then self:onReturn() end
end, end,

@ -26,7 +26,7 @@ local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local MovableContainer = require("ui/widget/container/movablecontainer") local MovableContainer = require("ui/widget/container/movablecontainer")
local Size = require("ui/size") local Size = require("ui/size")
@ -79,9 +79,8 @@ function MultiConfirmBox:init()
end end
local content = HorizontalGroup:new{ local content = HorizontalGroup:new{
align = "center", align = "center",
ImageWidget:new{ IconWidget:new{
file = "resources/info-i.png", icon = "notice-question",
scale_for_dpi = true,
}, },
HorizontalSpan:new{ width = Size.span.horizontal_default }, HorizontalSpan:new{ width = Size.span.horizontal_default },
TextBoxWidget:new{ TextBoxWidget:new{

@ -44,7 +44,7 @@ local FrameContainer = require("ui/widget/container/framecontainer")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local ImageWidget = require("ui/widget/imagewidget") local IconWidget = require("ui/widget/iconwidget")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
local InputDialog = require("ui/widget/inputdialog") local InputDialog = require("ui/widget/inputdialog")
@ -103,6 +103,7 @@ function MinimalPaginator:setProgress(progress) self.progress = progress end
local NetworkItem = InputContainer:new{ local NetworkItem = InputContainer:new{
dimen = nil, dimen = nil,
height = Screen:scaleBySize(44), height = Screen:scaleBySize(44),
icon_size = Screen:scaleBySize(32),
width = nil, width = nil,
info = nil, info = nil,
background = Blitbuffer.COLOR_WHITE, background = Blitbuffer.COLOR_WHITE,
@ -114,17 +115,17 @@ function NetworkItem:init()
self.info.ssid = "[hidden]" self.info.ssid = "[hidden]"
end end
local wifi_icon_path local wifi_icon
if string.find(self.info.flags, "WPA") then if string.find(self.info.flags, "WPA") then
wifi_icon_path = "resources/icons/koicon.wifi.secure.%d.medium.png" wifi_icon = "wifi.secure.%d"
else else
wifi_icon_path = "resources/icons/koicon.wifi.open.%d.medium.png" wifi_icon = "wifi.open.%d"
end end
if self.info.signal_quality == 0 or self.info.signal_quality == 100 then if self.info.signal_quality == 0 or self.info.signal_quality == 100 then
wifi_icon_path = string.format(wifi_icon_path, self.info.signal_quality) wifi_icon = string.format(wifi_icon, self.info.signal_quality)
else else
wifi_icon_path = string.format( wifi_icon = string.format(
wifi_icon_path, wifi_icon,
self.info.signal_quality + 25 - self.info.signal_quality % 25) self.info.signal_quality + 25 - self.info.signal_quality % 25)
end end
local horizontal_space = HorizontalSpan:new{width = Size.span.horizontal_default} local horizontal_space = HorizontalSpan:new{width = Size.span.horizontal_default}
@ -134,9 +135,10 @@ function NetworkItem:init()
dimen = self.dimen:copy(), dimen = self.dimen:copy(),
HorizontalGroup:new{ HorizontalGroup:new{
horizontal_space, horizontal_space,
ImageWidget:new{ IconWidget:new{
alpha = true, icon = wifi_icon,
file = wifi_icon_path, width = self.icon_size,
height = self.icon_size,
}, },
horizontal_space, horizontal_space,
TextWidget:new{ TextWidget:new{

@ -227,13 +227,13 @@ function TouchMenuBar:init()
local icon_sep_width = Size.span.vertical_default local icon_sep_width = Size.span.vertical_default
local icons_sep_width = icon_sep_width * (#self.icons + 1) local icons_sep_width = icon_sep_width * (#self.icons + 1)
-- we assume all icons are of the same width -- we assume all icons are of the same width
local icon_width = Screen:scaleBySize(40) local icon_width = Screen:scaleBySize(DGENERIC_ICON_SIZE)
local icon_height = icon_width local icon_height = icon_width
-- content_width is the width of all the icon images -- content_width is the width of all the icon images
local content_width = icon_width * #self.icons + icons_sep_width local content_width = icon_width * #self.icons + icons_sep_width
local spacing_width = (self.width - content_width)/(#self.icons*2) local spacing_width = (self.width - content_width)/(#self.icons*2)
local icon_padding = math.min(spacing_width, Screen:scaleBySize(16)) local icon_padding = math.min(spacing_width, Screen:scaleBySize(16))
self.height = icon_height + Size.span.vertical_large self.height = icon_height + 2*Size.padding.default
self.show_parent = self.show_parent or self self.show_parent = self.show_parent or self
self.bar_icon_group = HorizontalGroup:new{} self.bar_icon_group = HorizontalGroup:new{}
-- build up image widget for menu icon bar -- build up image widget for menu icon bar
@ -252,10 +252,9 @@ function TouchMenuBar:init()
for k, v in ipairs(self.icons) do for k, v in ipairs(self.icons) do
local ib = IconButton:new{ local ib = IconButton:new{
show_parent = self.show_parent, show_parent = self.show_parent,
icon_file = v, icon = v,
width = icon_width, width = icon_width,
height = icon_height, height = icon_height,
scale_for_dpi = false,
callback = nil, callback = nil,
padding_left = icon_padding, padding_left = icon_padding,
padding_right = icon_padding, padding_right = icon_padding,
@ -381,6 +380,11 @@ function TouchMenuBar:switchToTab(index)
if index > #self.icon_widgets then if index > #self.icon_widgets then
index = #self.icon_widgets index = #self.icon_widgets
end end
if self.menu.tab_item_table[index] and self.menu.tab_item_table[index].remember == false then
-- Don't auto-activate those that should not be
-- remembered (FM plus menu on non-touch devices)
index = 1
end
self.icon_widgets[index].callback() self.icon_widgets[index].callback()
end end
@ -394,7 +398,7 @@ local TouchMenu = FocusManager:new{
item_table = nil, item_table = nil,
item_height = Size.item.height_large, item_height = Size.item.height_large,
bordersize = Size.border.window, bordersize = Size.border.window,
padding = Size.padding.default, padding = Size.padding.default, -- (not used at top)
fface = Font:getFace("ffont"), fface = Font:getFace("ffont"),
width = nil, width = nil,
height = nil, height = nil,
@ -462,8 +466,8 @@ function TouchMenu:init()
align = "center", align = "center",
} }
-- group for page info -- group for page info
local chevron_left = "resources/icons/appbar.chevron.left.png" local chevron_left = "chevron.left"
local chevron_right = "resources/icons/appbar.chevron.right.png" local chevron_right = "chevron.right"
if BD.mirroredUILayout() then if BD.mirroredUILayout() then
chevron_left, chevron_right = chevron_right, chevron_left chevron_left, chevron_right = chevron_right, chevron_left
end end
@ -502,7 +506,7 @@ function TouchMenu:init()
} }
local footer_width = self.width - self.padding*2 local footer_width = self.width - self.padding*2
local up_button = IconButton:new{ local up_button = IconButton:new{
icon_file = "resources/icons/appbar.chevron.up.png", icon = "chevron.up",
show_parent = self.show_parent, show_parent = self.show_parent,
padding_left = math.floor(footer_width*0.33*0.1), padding_left = math.floor(footer_width*0.33*0.1),
padding_right = math.floor(footer_width*0.33*0.1), padding_right = math.floor(footer_width*0.33*0.1),
@ -528,6 +532,7 @@ function TouchMenu:init()
self.menu_frame = FrameContainer:new{ self.menu_frame = FrameContainer:new{
padding = self.padding, padding = self.padding,
padding_top = 0, -- ensured by TouchMenuBar
bordersize = self.bordersize, bordersize = self.bordersize,
background = Blitbuffer.COLOR_WHITE, background = Blitbuffer.COLOR_WHITE,
-- menubar and footer will be inserted in -- menubar and footer will be inserted in
@ -678,7 +683,7 @@ function TouchMenu:updateItems()
-- recalculate dimen based on new layout -- recalculate dimen based on new layout
self.dimen.w = self.width self.dimen.w = self.width
self.dimen.h = self.item_group:getSize().h + self.bordersize*2 + self.padding*2 self.dimen.h = self.item_group:getSize().h + self.bordersize*2 + self.padding -- (no padding at top)
self.selected = { x = self.cur_tab, y = 1 } -- reset the position of the focusmanager self.selected = { x = self.cur_tab, y = 1 } -- reset the position of the focusmanager
-- NOTE: We use a slightly ugly hack to detect a brand new menu vs. a tab switch, -- NOTE: We use a slightly ugly hack to detect a brand new menu vs. a tab switch,

@ -9,6 +9,7 @@ local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local IconWidget = require("ui/widget/iconwidget")
local ImageWidget = require("ui/widget/imagewidget") local ImageWidget = require("ui/widget/imagewidget")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
@ -203,7 +204,7 @@ function ListMenuItem:update()
-- We'll draw a border around cover images, it may not be -- We'll draw a border around cover images, it may not be
-- needed with some covers, but it's nicer when cover is -- needed with some covers, but it's nicer when cover is
-- a pure white background (like rendered text page) -- a pure white background (like rendered text page)
local border_size = 1 local border_size = Size.border.thin
local max_img_w = dimen.h - 2*border_size -- width = height, squared local max_img_w = dimen.h - 2*border_size -- width = height, squared
local max_img_h = dimen.h - 2*border_size local max_img_h = dimen.h - 2*border_size
local cover_specs = { local cover_specs = {
@ -478,8 +479,8 @@ function ListMenuItem:update()
if corner_mark then if corner_mark then
corner_mark:free() corner_mark:free()
end end
corner_mark = ImageWidget:new{ corner_mark = IconWidget:new{
file = "resources/icons/dogear.png", icon = "dogear.opaque",
rotation_angle = BD.mirroredUILayout() and 180 or 270, rotation_angle = BD.mirroredUILayout() and 180 or 270,
width = corner_mark_size, width = corner_mark_size,
height = corner_mark_size, height = corner_mark_size,

@ -10,6 +10,7 @@ local Geom = require("ui/geometry")
local GestureRange = require("ui/gesturerange") local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan") local HorizontalSpan = require("ui/widget/horizontalspan")
local IconWidget = require("ui/widget/iconwidget")
local ImageWidget = require("ui/widget/imagewidget") local ImageWidget = require("ui/widget/imagewidget")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer") local InputContainer = require("ui/widget/container/inputcontainer")
@ -97,7 +98,7 @@ local FakeCover = FrameContainer:new{
height = nil, height = nil,
margin = 0, margin = 0,
padding = 0, padding = 0,
bordersize = Size.line.thin, bordersize = Size.border.thin,
dim = nil, dim = nil,
-- Provided filename, title and authors should not be BD wrapped -- Provided filename, title and authors should not be BD wrapped
filename = nil, filename = nil,
@ -437,7 +438,7 @@ function MosaicMenuItem:update()
-- We'll draw a border around cover images, it may not be -- We'll draw a border around cover images, it may not be
-- needed with some covers, but it's nicer when cover is -- needed with some covers, but it's nicer when cover is
-- a pure white background (like rendered text page) -- a pure white background (like rendered text page)
local border_size = 1 local border_size = Size.border.thin
local max_img_w = dimen.w - 2*border_size local max_img_w = dimen.w - 2*border_size
local max_img_h = dimen.h - 2*border_size local max_img_h = dimen.h - 2*border_size
local cover_specs = { local cover_specs = {
@ -459,7 +460,7 @@ function MosaicMenuItem:update()
-- Directory : rounded corners -- Directory : rounded corners
local margin = Screen:scaleBySize(5) -- make directories less wide local margin = Screen:scaleBySize(5) -- make directories less wide
local padding = Screen:scaleBySize(5) local padding = Screen:scaleBySize(5)
border_size = Screen:scaleBySize(2) -- make directories' borders larger border_size = Size.border.thick -- make directories' borders larger
local dimen_in = Geom:new{ local dimen_in = Geom:new{
w = dimen.w - (margin + padding + border_size)*2, w = dimen.w - (margin + padding + border_size)*2,
h = dimen.h - (margin + padding + border_size)*2 h = dimen.h - (margin + padding + border_size)*2
@ -848,8 +849,8 @@ function MosaicMenu:_recalculateDimen()
if corner_mark then if corner_mark then
corner_mark:free() corner_mark:free()
end end
corner_mark = ImageWidget:new{ corner_mark = IconWidget:new{
file = "resources/icons/dogear.png", icon = "dogear.opaque",
rotation_angle = BD.mirroredUILayout() and 180 or 270, rotation_angle = BD.mirroredUILayout() and 180 or 270,
width = corner_mark_size, width = corner_mark_size,
height = corner_mark_size, height = corner_mark_size,

@ -240,8 +240,8 @@ function DoubleKeyValuePage:init()
text_font_bold = false, text_font_bold = false,
} }
-- group for page info -- group for page info
local chevron_left = "resources/icons/appbar.chevron.left.png" local chevron_left = "chevron.left"
local chevron_right = "resources/icons/appbar.chevron.right.png" local chevron_right = "chevron.right"
if BD.mirroredUILayout() then if BD.mirroredUILayout() then
chevron_left, chevron_right = chevron_right, chevron_left chevron_left, chevron_right = chevron_right, chevron_left
end end

@ -465,10 +465,10 @@ function CalendarView:init()
end end
-- group for page info -- group for page info
local chevron_left = "resources/icons/appbar.chevron.left.png" local chevron_left = "chevron.left"
local chevron_right = "resources/icons/appbar.chevron.right.png" local chevron_right = "chevron.right"
local chevron_first = "resources/icons/appbar.chevron.first.png" local chevron_first = "chevron.first"
local chevron_last = "resources/icons/appbar.chevron.last.png" local chevron_last = "chevron.last"
if BD.mirroredUILayout() then if BD.mirroredUILayout() then
chevron_left, chevron_right = chevron_right, chevron_left chevron_left, chevron_right = chevron_right, chevron_left
chevron_first, chevron_last = chevron_last, chevron_first chevron_first, chevron_last = chevron_last, chevron_first

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="48"
height="48"
viewBox="0 0 48 48"
enable-background="new 0 0 24.00 24.00"
xml:space="preserve"
id="svg4"
sodipodi:docname="icon-not-found.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
inkscape:export-xdpi="48"
inkscape:export-ydpi="48"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1914"
inkscape:window-height="932"
id="namedview8"
showgrid="true"
inkscape:zoom="15.3125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-x="0"
inkscape:window-y="126"
inkscape:window-maximized="0"
inkscape:current-layer="svg4"
inkscape:document-rotation="0"><inkscape:grid
type="xygrid"
id="grid13"
originx="0"
originy="0"
empspacing="4" /></sodipodi:namedview><metadata
id="metadata10"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs8" />
<rect
style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:2"
id="rect830"
width="144"
height="144"
x="0"
y="0" />
<path
style="fill:none;stroke:#FFFFFF;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 24,15 V 30.333333"
id="path840"
sodipodi:nodetypes="cc" /><path
style="fill:none;stroke:#FFFFFF;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 24,33.666666 V 36"
id="path850"
sodipodi:nodetypes="cc" /><path
style="fill:none;stroke:#FFFFFF;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 43.43746,40 H 4.56254 L 24,6.3333333 Z"
id="path853" />
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

@ -8,7 +8,7 @@ describe("defaults module", function()
it("should load all defaults from defaults.lua", function() it("should load all defaults from defaults.lua", function()
Defaults:init() Defaults:init()
assert.is_same(100, #Defaults.defaults_name) assert.is_same(101, #Defaults.defaults_name)
end) end)
it("should save changes to defaults.persistent.lua", function() it("should save changes to defaults.persistent.lua", function()
@ -16,7 +16,7 @@ describe("defaults module", function()
os.remove(persistent_filename) os.remove(persistent_filename)
-- To see indices and help updating this when new settings are added: -- To see indices and help updating this when new settings are added:
-- for i=1, 100 do print(i.." ".. Defaults.defaults_name[i]) end -- for i=1, 101 do print(i.." ".. Defaults.defaults_name[i]) end
-- not in persistent but checked in defaults -- not in persistent but checked in defaults
Defaults.changed[20] = true Defaults.changed[20] = true
@ -24,8 +24,8 @@ describe("defaults module", function()
Defaults.changed[56] = true Defaults.changed[56] = true
Defaults.changed[85] = true Defaults.changed[85] = true
Defaults:saveSettings() Defaults:saveSettings()
assert.is_same(100, #Defaults.defaults_name) assert.is_same(101, #Defaults.defaults_name)
assert.is_same("DTAP_ZONE_BACKWARD", Defaults.defaults_name[85]) assert.is_same("DTAP_ZONE_BACKWARD", Defaults.defaults_name[86])
assert.is_same("DCREREADER_CONFIG_WORD_SPACING_LARGE", Defaults.defaults_name[50]) assert.is_same("DCREREADER_CONFIG_WORD_SPACING_LARGE", Defaults.defaults_name[50])
assert.is_same("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE", Defaults.defaults_name[20]) assert.is_same("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE", Defaults.defaults_name[20])
dofile(persistent_filename) dofile(persistent_filename)
@ -43,8 +43,8 @@ describe("defaults module", function()
h = 0.25, h = 0.25,
w = 0.75 w = 0.75
} }
Defaults.changed[85] = true Defaults.changed[86] = true
Defaults.defaults_value[85] = { Defaults.defaults_value[86] = {
y = 10, y = 10,
x = 10.125, x = 10.125,
h = 20.25, h = 20.25,
@ -85,8 +85,8 @@ DHINTCOUNT = 2
-- in persistent -- in persistent
Defaults:init() Defaults:init()
Defaults.changed[57] = true Defaults.changed[58] = true
Defaults.defaults_value[57] = 1 Defaults.defaults_value[58] = 1
Defaults:saveSettings() Defaults:saveSettings()
dofile(persistent_filename) dofile(persistent_filename)
assert.Equals(DCREREADER_VIEW_MODE, "page") assert.Equals(DCREREADER_VIEW_MODE, "page")

@ -18,11 +18,11 @@ Welcome to KOreader. You can activate the menu by swiping down from the top of t
**Main menu** **Main menu**
![Menu](../resources/icons/menu-icon.png) You can always view this quickstart guide again through *Help* *Quickstart guide* in the top right menu. ![Menu](../resources/menu.svg) You can always view this quickstart guide again through *Help* *Quickstart guide* in the top right menu.
**Settings** **Settings**
![Settings](../resources/icons/appbar.settings.png) You can change the language and other settings through the gear icon. ![Settings](../resources/settings.svg) You can change the language and other settings through the gear icon.
------------ ------------
@ -38,9 +38,9 @@ Generated by KOReader v2015.11-982-g704d4238.
<h1>KOReader Quickstart Guide</h1> <h1>KOReader Quickstart Guide</h1>
<p>Welcome to KOreader. You can activate the menu by swiping down from the top of the screen. Clicking outside the menu or swiping up on the menu will discard it. Turning pages can be done either by swiping left and right or by single taps on the left or right side of the screen.</p> <p>Welcome to KOreader. You can activate the menu by swiping down from the top of the screen. Clicking outside the menu or swiping up on the menu will discard it. Turning pages can be done either by swiping left and right or by single taps on the left or right side of the screen.</p>
<p><strong>Main menu</strong></p> <p><strong>Main menu</strong></p>
<p><img alt="Menu" src="../resources/icons/menu-icon.png"> You can always view this quickstart guide again through <em>Help</em> <em>Quickstart guide</em> in the top right menu.</p> <p><img alt="Menu" src="../resources/menu.svg"> You can always view this quickstart guide again through <em>Help</em> <em>Quickstart guide</em> in the top right menu.</p>
<p><strong>Settings</strong></p> <p><strong>Settings</strong></p>
<p><img alt="Settings" src="../resources/icons/appbar.settings.png"> You can change the language and other settings through the gear icon.</p> <p><img alt="Settings" src="../resources/settings.svg"> You can change the language and other settings through the gear icon.</p>
<hr> <hr>
<p>Generated by KOReader v2015.11-982-g704d4238.</p> <p>Generated by KOReader v2015.11-982-g704d4238.</p>
</body> </body>

@ -7,7 +7,7 @@ describe("ImageWidget module", function()
it("should render without error", function() it("should render without error", function()
local imgw = ImageWidget:new{ local imgw = ImageWidget:new{
file = "resources/icons/appbar.chevron.up.png" file = "resources/koreader.png"
} }
imgw:_render() imgw:_render()
assert(imgw._bb) assert(imgw._bb)

@ -271,7 +271,7 @@ touch_menu = TouchMenu:new{
width = Screen:getWidth(), width = Screen:getWidth(),
tab_item_table = { tab_item_table = {
{ {
icon = "resources/icons/appbar.pokeball.png", icon = "appbar.pokeball",
{ {
text = "item1", text = "item1",
callback = function() end, callback = function() end,
@ -310,7 +310,7 @@ touch_menu = TouchMenu:new{
}, },
}, },
{ {
icon = "resources/icons/appbar.page.corner.bookmark.png", icon = "appbar.page.corner.bookmark",
{ {
text = "item10", text = "item10",
callback = function() end, callback = function() end,
@ -321,7 +321,7 @@ touch_menu = TouchMenu:new{
}, },
}, },
{ {
icon = "resources/icons/appbar.home.png", icon = "home",
callback = function() DEBUG("hello world!") end callback = function() DEBUG("hello world!") end
} }
}, },

Loading…
Cancel
Save