diff --git a/.travis.yml b/.travis.yml index 86e299bd8..2ee0b22ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ env: - EMULATE_READER=1 cache: + apt: true directories: - $HOME/.ccache diff --git a/frontend/apps/reader/modules/readerconfig.lua b/frontend/apps/reader/modules/readerconfig.lua index 10c4c281a..6dd0d0ffe 100644 --- a/frontend/apps/reader/modules/readerconfig.lua +++ b/frontend/apps/reader/modules/readerconfig.lua @@ -13,6 +13,7 @@ local ReaderConfig = InputContainer:new{ } function ReaderConfig:init() + if not self.dimen then self.dimen = Geom:new{} end if Device:hasKeyboard() then self.key_events = { ShowConfigMenu = { { "AA" }, doc = "show config dialog" }, diff --git a/frontend/ui/font.lua b/frontend/ui/font.lua index 99b4ef381..b1b9d96f4 100644 --- a/frontend/ui/font.lua +++ b/frontend/ui/font.lua @@ -49,18 +49,17 @@ local Font = { function Font:getFace(font, size) - if not font then - -- default to content font - font = self.cfont - end + -- default to content font + if not font then font = self.cfont end -- original size before scaling by screen DPI local orig_size = size local size = Screen:scaleBySize(size) - local face = self.faces[font..size] + local hash = font..size + local face_obj = self.faces[hash] -- build face if not found - if not face then + if not face_obj then local realname = self.fontmap[font] if not realname then realname = font @@ -71,10 +70,16 @@ function Font:getFace(font, size) DEBUG("#! Font "..font.." ("..realname..") not supported: "..face) return nil end - self.faces[font..size] = face - --DEBUG("getFace, found: "..realname.." size:"..size) + face_obj = { + size = size, + orig_size = orig_size, + ftface = face, + hash = hash + } + self.faces[hash] = face_obj + -- DEBUG("getFace, found: "..realname.." size:"..size) end - return { size = size, orig_size = orig_size, ftface = face, hash = font..size } + return face_obj end function Font:_readList(target, dir) diff --git a/frontend/ui/widget/button.lua b/frontend/ui/widget/button.lua index 0a6881980..508d3b24d 100644 --- a/frontend/ui/widget/button.lua +++ b/frontend/ui/widget/button.lua @@ -66,9 +66,7 @@ function Button:init() } } if self.preselect then - self.frame.color = Blitbuffer.COLOR_BLACK - else - self.frame.color = Blitbuffer.gray(0.33) + self:onFocus() end self.dimen = self.frame:getSize() self[1] = self.frame @@ -105,12 +103,12 @@ function Button:setIcon(icon) end function Button:onFocus() - self[1].color = Blitbuffer.COLOR_BLACK + self.frame.invert = true return true end function Button:onUnfocus() - self[1].color = Blitbuffer.gray(0.33) + self.frame.invert = false return true end diff --git a/frontend/ui/widget/buttontable.lua b/frontend/ui/widget/buttontable.lua index 45a74a13f..cea718912 100644 --- a/frontend/ui/widget/buttontable.lua +++ b/frontend/ui/widget/buttontable.lua @@ -1,13 +1,16 @@ -local VerticalGroup = require("ui/widget/verticalgroup") local HorizontalGroup = require("ui/widget/horizontalgroup") +local VerticalGroup = require("ui/widget/verticalgroup") local VerticalSpan = require("ui/widget/verticalspan") +local FocusManager = require("ui/widget/focusmanager") local LineWidget = require("ui/widget/linewidget") -local Button = require("ui/widget/button") -local Screen = require("device").screen -local Geom = require("ui/geometry") local Blitbuffer = require("ffi/blitbuffer") +local Button = require("ui/widget/button") +local UIManager = require("ui/uimanager") +local Geom = require("ui/geometry") +local Device = require("device") +local Screen = Device.screen -local ButtonTable = VerticalGroup:new{ +local ButtonTable = FocusManager:new{ width = Screen:getWidth(), buttons = { { @@ -24,7 +27,8 @@ local ButtonTable = VerticalGroup:new{ } function ButtonTable:init() - --local vertical_group = VerticalGroup:new{} + self.container = VerticalGroup:new{ width = self.width } + table.insert(self, self.container) if self.zero_sep then self:addHorizontalSep() end @@ -53,28 +57,42 @@ function ButtonTable:init() h = button_dim.h, } } + self.buttons[i][j] = button table.insert(horizontal_group, button) if j < #line then table.insert(horizontal_group, vertical_sep) end end -- end for each button - table.insert(self, horizontal_group) + table.insert(self.container, horizontal_group) if i < #self.buttons then self:addHorizontalSep() end end -- end for each button line + if Device:hasKeys() then + self.layout = self.buttons + self.layout[1][1]:onFocus() + self.key_events.SelectByKeyPress = { {{"Press", "Enter"}} } + else + self.key_events = {} -- deregister all key press event listeners + end end function ButtonTable:addHorizontalSep() - table.insert(self, VerticalSpan:new{ width = Screen:scaleBySize(2) }) - table.insert(self, LineWidget:new{ + table.insert(self.container, + VerticalSpan:new{ width = Screen:scaleBySize(2) }) + table.insert(self.container, LineWidget:new{ background = Blitbuffer.gray(0.5), dimen = Geom:new{ w = self.width, h = self.sep_width, } }) - table.insert(self, VerticalSpan:new{ width = Screen:scaleBySize(2) }) + table.insert(self.container, + VerticalSpan:new{ width = Screen:scaleBySize(2) }) +end + +function ButtonTable:onSelectByKeyPress() + self:getFocusItem().callback() end return ButtonTable diff --git a/frontend/ui/widget/container/centercontainer.lua b/frontend/ui/widget/container/centercontainer.lua index afa054ea3..ff7b90034 100644 --- a/frontend/ui/widget/container/centercontainer.lua +++ b/frontend/ui/widget/container/centercontainer.lua @@ -6,18 +6,18 @@ CenterContainer centers its content (1 widget) within its own dimensions local CenterContainer = WidgetContainer:new() function CenterContainer:paintTo(bb, x, y) - local contentSize = self[1]:getSize() - if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then + local content_size = self[1]:getSize() + if content_size.w > self.dimen.w or content_size.h > self.dimen.h then -- throw error? paint to scrap buffer and blit partially? -- for now, we ignore this end local x_pos = x local y_pos = y if self.ignore ~= "height" then - y_pos = y + math.floor((self.dimen.h - contentSize.h)/2) + y_pos = y + math.floor((self.dimen.h - content_size.h)/2) end if self.ignore ~= "width" then - x_pos = x + math.floor((self.dimen.w - contentSize.w)/2) + x_pos = x + math.floor((self.dimen.w - content_size.w)/2) end self[1]:paintTo(bb, x_pos, y_pos) end diff --git a/frontend/ui/widget/container/inputcontainer.lua b/frontend/ui/widget/container/inputcontainer.lua index 8b00dc99f..95aa9727d 100644 --- a/frontend/ui/widget/container/inputcontainer.lua +++ b/frontend/ui/widget/container/inputcontainer.lua @@ -48,13 +48,12 @@ function InputContainer:_init() end end self.ges_events = new_ges_events - - if not self.dimen then - self.dimen = Geom:new{} - end end function InputContainer:paintTo(bb, x, y) + if not self.dimen then + self.dimen = self[1]:getSize() + end self.dimen.x = x self.dimen.y = y if self[1] then diff --git a/frontend/ui/widget/container/widgetcontainer.lua b/frontend/ui/widget/container/widgetcontainer.lua index 766df85a1..dd63ec34b 100644 --- a/frontend/ui/widget/container/widgetcontainer.lua +++ b/frontend/ui/widget/container/widgetcontainer.lua @@ -7,14 +7,13 @@ WidgetContainer is a container for another Widget local WidgetContainer = Widget:new() function WidgetContainer:init() - if not self.dimen then - self.dimen = Geom:new{} - end - if not self.dimen.w then - self.dimen.w = self[1].getSize().w - end - if not self.dimen.h then - self.dimen.h = self[1].getSize().h + if self.dimen then + if not self.dimen.w then + self.dimen.w = self[1].getSize().w + end + if not self.dimen.h then + self.dimen.h = self[1].getSize().h + end end end diff --git a/frontend/ui/widget/focusmanager.lua b/frontend/ui/widget/focusmanager.lua index a88200119..213ea4673 100644 --- a/frontend/ui/widget/focusmanager.lua +++ b/frontend/ui/widget/focusmanager.lua @@ -32,7 +32,9 @@ local FocusManager = InputContainer:new{ } function FocusManager:init() - self.selected = { x = 1, y = 1 } + if not self.selected then + self.selected = { x = 1, y = 1 } + end self.key_events = { -- these will all generate the same event, just with different arguments FocusUp = { {"Up"}, doc = "move focus up", event = "FocusMove", args = {0, -1} }, @@ -60,7 +62,7 @@ function FocusManager:onFocusMove(args) break -- abort when we run into horizontal borders end - -- move cyclic in vertical direction + -- call widget wrap callbacks in vertical direction if self.selected.y + dy > #self.layout then if not self:onWrapLast() then break @@ -99,4 +101,8 @@ function FocusManager:onWrapLast() return true end +function FocusManager:getFocusItem() + return self.layout[self.selected.y][self.selected.x] +end + return FocusManager diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index 596d7594b..77c375f78 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -274,6 +274,7 @@ local TouchMenu = InputContainer:new{ } function TouchMenu:init() + if not self.dimen then self.dimen = Geom:new{} end self.show_parent = self.show_parent or self if not self.close_callback then self.close_callback = function() diff --git a/frontend/ui/widget/widget.lua b/frontend/ui/widget/widget.lua index 6b7c19c0d..29f55a88a 100644 --- a/frontend/ui/widget/widget.lua +++ b/frontend/ui/widget/widget.lua @@ -31,8 +31,8 @@ definition. --]] function Widget:new(o) o = self:extend(o) - -- Both o._init and o.init are called on object create. But o._init is used - -- for base widget initialization (basic component used to build other + -- Both o._init and o.init are called on object creation. But o._init is + -- used for base widget initialization (basic component used to build other -- widgets). While o.init is for higher level widgets, for example Menu -- Widget if o._init then o:_init() end diff --git a/spec/unit/font_spec.lua b/spec/unit/font_spec.lua new file mode 100644 index 000000000..4d6c155bd --- /dev/null +++ b/spec/unit/font_spec.lua @@ -0,0 +1,15 @@ +require("commonrequire") +local DEBUG = require("dbg") +local Font = require("ui/font") + +describe("Font module", function() + local f = nil + it("should get face", function() + f = Font:getFace('cfont', 18) + assert.are_not.equals(f.ftface, nil) + f = Font:getFace('tfont', 16) + assert.are_not.equals(f.ftface, nil) + f = Font:getFace('hfont', 12) + assert.are_not.equals(f.ftface, nil) + end) +end)