diff --git a/frontend/apps/reader/modules/readercropping.lua b/frontend/apps/reader/modules/readercropping.lua index 9e44df430..23015f32e 100644 --- a/frontend/apps/reader/modules/readercropping.lua +++ b/frontend/apps/reader/modules/readercropping.lua @@ -77,6 +77,7 @@ function PageCropDialog:onShow() return true end + local ReaderCropping = InputContainer:new{} function ReaderCropping:onPageCrop(mode) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index 356dcd5d7..e53084efc 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -1,4 +1,4 @@ -local InputContainer = require("ui/widget/container/inputcontainer") +local WidgetContainer = require("ui/widget/container/widgetcontainer") local RightContainer = require("ui/widget/container/rightcontainer") local BottomContainer = require("ui/widget/container/bottomcontainer") local FrameContainer = require("ui/widget/container/framecontainer") @@ -6,7 +6,6 @@ local ProgressWidget = require("ui/widget/progresswidget") local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalSpan = require("ui/widget/horizontalspan") local TextWidget = require("ui/widget/textwidget") -local GestureRange = require("ui/gesturerange") local Blitbuffer = require("ffi/blitbuffer") local UIManager = require("ui/uimanager") local Device = require("device") @@ -88,7 +87,7 @@ local footerTextGeneratorMap = { end, } -local ReaderFooter = InputContainer:new{ +local ReaderFooter = WidgetContainer:new{ mode = MODE.page_progress, pageno = nil, pages = nil, @@ -152,27 +151,31 @@ function ReaderFooter:init() last = nil, -- last will be initialized in self:updateFooterText } - local margin_span = HorizontalSpan:new{width = self.horizontal_margin} - self.horizontal_group = HorizontalGroup:new{margin_span} + local margin_span = HorizontalSpan:new{ width = self.horizontal_margin } + self.horizontal_group = HorizontalGroup:new{ margin_span } self.text_container = RightContainer:new{ - dimen = Geom:new{w = 0, h = self.height}, + dimen = Geom:new{ w = 0, h = self.height }, self.footer_text, } table.insert(self.horizontal_group, self.progress_bar) table.insert(self.horizontal_group, self.text_container) table.insert(self.horizontal_group, margin_span) - self[1] = BottomContainer:new{ + + self.footer_content = FrameContainer:new{ + self.horizontal_group, + background = Blitbuffer.COLOR_WHITE, + bordersize = 0, + padding = 0, + } + self.footer_container = BottomContainer:new{ + dimen = Geom:new{ w = 0, h = self.height*2 }, + self.footer_content, + } + self.footer_positioner = BottomContainer:new{ dimen = Geom:new{}, - BottomContainer:new{ - dimen = Geom:new{w = 0, h = self.height*2}, - FrameContainer:new{ - self.horizontal_group, - background = Blitbuffer.COLOR_WHITE, - bordersize = 0, - padding = 0, - } - } + self.footer_container, } + self[1] = self.footer_positioner self.mode = G_reader_settings:readSetting("reader_footer_mode") or self.mode if self.settings.all_at_once then @@ -181,7 +184,6 @@ function ReaderFooter:init() else self:applyFooterMode() end - self:resetLayout() if self.settings.auto_refresh_time then self:setupAutoRefreshTime() @@ -201,7 +203,30 @@ function ReaderFooter:setupAutoRefreshTime() UIManager:scheduleIn(61 - tonumber(os.date("%S")), self.autoRefreshTime) end --- call this method whenever the screen size changed +function ReaderFooter:setupTouchZones() + if not Device:isTouchDevice() then return end + local footer_screen_zone = { + ratio_x = DTAP_ZONE_MINIBAR.x, ratio_y = DTAP_ZONE_MINIBAR.y, + ratio_w = DTAP_ZONE_MINIBAR.w, ratio_h = DTAP_ZONE_MINIBAR.h, + } + self.ui:registerTouchZones({ + { + id = "footer_tap", + ges = "tap", + screen_zone = footer_screen_zone, + handler = function() return self:onTapFooter() end, + overrides = { 'tap_forward', 'tap_backward', }, + }, + { + id = "footer_hold", + ges = "hold", + screen_zone = footer_screen_zone, + handler = function() return self:onHoldFooter() end, + }, + }) +end + +-- call this method whenever the screen size changes function ReaderFooter:resetLayout() local new_screen_width = Screen:getWidth() if new_screen_width == self._saved_screen_width then return end @@ -209,34 +234,12 @@ function ReaderFooter:resetLayout() self.progress_bar.width = math.floor(new_screen_width - self.text_width - self.horizontal_margin*2) self.horizontal_group:resetLayout() - self[1].dimen.w = new_screen_width - self[1].dimen.h = new_screen_height - self[1][1].dimen.w = new_screen_width - self.dimen = self[1]:getSize() + self.footer_positioner.dimen.w = new_screen_width + self.footer_positioner.dimen.h = new_screen_height + self.footer_container.dimen.w = new_screen_width + self.dimen = self.footer_positioner:getSize() self._saved_screen_width = new_screen_width - if Device:isTouchDevice() then - local range = Geom:new{ - x = new_screen_width*DTAP_ZONE_MINIBAR.x, - y = new_screen_height*DTAP_ZONE_MINIBAR.y, - w = new_screen_width*DTAP_ZONE_MINIBAR.w, - h = new_screen_height*DTAP_ZONE_MINIBAR.h - } - self.ges_events = { - TapFooter = { - GestureRange:new{ - ges = "tap", - range = range, - }, - }, - HoldFooter = { - GestureRange:new{ - ges = "hold", - range = range, - }, - }, - } - end end function ReaderFooter:getHeight() @@ -481,7 +484,7 @@ function ReaderFooter:_updateFooterText() self._saved_screen_width - self.text_width - self.horizontal_margin*2) self.text_container.dimen.w = self.text_width self.horizontal_group:resetLayout() - UIManager:setDirty(self.view.dialog, "ui", self[1][1][1].dimen) + UIManager:setDirty(self.view.dialog, "ui", self.footer_content.dimen) end function ReaderFooter:onPageUpdate(pageno) @@ -501,6 +504,8 @@ end ReaderFooter.onUpdatePos = ReaderFooter.updateFooter function ReaderFooter:onReaderReady() + self:setupTouchZones() + self:resetLayout() -- set widget dimen self:setTocMarkers() self.updateFooterText = self._updateFooterText self:updateFooter() @@ -574,7 +579,7 @@ function ReaderFooter:onTapFooter(arg, ges) return true end -function ReaderFooter:onHoldFooter(arg, ges) +function ReaderFooter:onHoldFooter() if self.mode == MODE.off then return end self.ui:handleEvent(Event:new("ShowGotoDialog")) return true diff --git a/frontend/apps/reader/modules/readerpaging.lua b/frontend/apps/reader/modules/readerpaging.lua index 8e012adee..425ccc822 100644 --- a/frontend/apps/reader/modules/readerpaging.lua +++ b/frontend/apps/reader/modules/readerpaging.lua @@ -1,7 +1,6 @@ local InputContainer = require("ui/widget/container/inputcontainer") local Geom = require("ui/geometry") local Input = require("device").input -local GestureRange = require("ui/gesturerange") local Device = require("device") local Screen = Device.screen local Event = require("ui/event") @@ -11,6 +10,9 @@ local DEBUG = require("dbg") local _ = require("gettext") +local pan_rate = Screen.eink and 4.0 or 10.0 + + local function copyPageState(page_state) return { page = page_state.page, @@ -75,64 +77,77 @@ function ReaderPaging:init() self.ui.menu:registerToMainMenu(self) end --- This method will be called in onSetDimensions handler -function ReaderPaging:initGesListener() - self.ges_events = { - TapForward = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = Screen:getWidth()*DTAP_ZONE_FORWARD.x, - y = Screen:getHeight()*DTAP_ZONE_FORWARD.y, - w = Screen:getWidth()*DTAP_ZONE_FORWARD.w, - h = Screen:getHeight()*DTAP_ZONE_FORWARD.h, - } - } +function ReaderPaging:onReaderReady() + self:setupTouchZones() +end + +function ReaderPaging:setupTapTouchZones() + local forward_zone = { + ratio_x = DTAP_ZONE_FORWARD.x, ratio_y = DTAP_ZONE_FORWARD.y, + ratio_w = DTAP_ZONE_FORWARD.w, ratio_h = DTAP_ZONE_FORWARD.h, + } + local backward_zone = { + ratio_x = DTAP_ZONE_BACKWARD.x, ratio_y = DTAP_ZONE_BACKWARD.y, + ratio_w = DTAP_ZONE_BACKWARD.w, ratio_h = DTAP_ZONE_BACKWARD.h, + } + + if self.inverse_reading_order then + forward_zone.ratio_x = 1 - forward_zone.ratio_x - forward_zone.ratio_w + backward_zone.ratio_x = 1 - backward_zone.ratio_x - backward_zone.ratio_w + end + + self.ui:registerTouchZones({ + { + id = "tap_forward", + ges = "tap", + screen_zone = forward_zone, + handler = function() return self:onTapForward() end }, - TapBackward = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = Screen:getWidth()*DTAP_ZONE_BACKWARD.x, - y = Screen:getHeight()*DTAP_ZONE_BACKWARD.y, - w = Screen:getWidth()*DTAP_ZONE_BACKWARD.w, - h = Screen:getHeight()*DTAP_ZONE_BACKWARD.h, - } - } + { + id = "tap_backward", + ges = "tap", + screen_zone = backward_zone, + handler = function() return self:onTapBackward() end }, - Swipe = { - GestureRange:new{ - ges = "swipe", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = Screen:getHeight(), - } - } + }) +end + +-- This method will be called in onSetDimensions handler +function ReaderPaging:setupTouchZones() + -- deligate gesture listener to readerui + self.ges_events = {} + self.onGesture = nil + + if not Device:isTouchDevice() then return end + + self:setupTapTouchZones() + self.ui:registerTouchZones({ + { + id = "paging_swipe", + ges = "swipe", + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 1, ratio_h = 1, + }, + handler = function(ges) return self:onSwipe(nil, ges) end }, - Pan = { - GestureRange:new{ - ges = "pan", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = Screen:getHeight(), - }, - rate = Screen.eink and 4.0 or 10.0, - } + { + id = "paging_pan", + ges = "pan", + rate = pan_rate, + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 1, ratio_h = 1, + }, + handler = function(ges) return self:onPan(nil, ges) end }, - PanRelease = { - GestureRange:new{ - ges = "pan_release", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = Screen:getHeight(), - }, - } + { + id = "paging_pan_release", + ges = "pan_release", + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 1, ratio_h = 1, + }, + handler = function(ges) return self:onPanRelease(nil, ges) end }, - } - self:updateReadOrder() + }) end function ReaderPaging:onReadSettings(config) @@ -145,7 +160,6 @@ function ReaderPaging:onReadSettings(config) self.flipping_zoom_mode = config:readSetting("flipping_zoom_mode") or "page" self.flipping_scroll_mode = config:readSetting("flipping_scroll_mode") or false self.inverse_reading_order = config:readSetting("inverse_reading_order") or false - self:updateReadOrder() end function ReaderPaging:onSaveSettings() @@ -197,12 +211,12 @@ function ReaderPaging:addToMainMenu(tab_item_table) end, sub_item_table = page_overlap_menu, }) - table.insert(tab_item_table.typeset, { + table.insert(tab_item_table.setting, { text = _("Read from right to left"), checked_func = function() return self.inverse_reading_order end, callback = function() self.inverse_reading_order = not self.inverse_reading_order - self:updateReadOrder() + self:setupTapTouchZones() end, }) end @@ -335,7 +349,7 @@ function ReaderPaging:bookmarkFlipping(flipping_page, flipping_ges) UIManager:setDirty(self.view.dialog, "partial") end -function ReaderPaging:onSwipe(arg, ges) +function ReaderPaging:onSwipe(_, ges) if self.bookmark_flipping_mode then self:bookmarkFlipping(self.current_page, ges) elseif self.page_flipping_mode and self.original_page then @@ -358,7 +372,7 @@ function ReaderPaging:onSwipe(arg, ges) end end -function ReaderPaging:onPan(arg, ges) +function ReaderPaging:onPan(_, ges) if self.bookmark_flipping_mode then return true elseif self.page_flipping_mode then @@ -374,7 +388,7 @@ function ReaderPaging:onPan(arg, ges) return true end -function ReaderPaging:onPanRelease(arg, ges) +function ReaderPaging:onPanRelease(_, ges) if self.page_flipping_mode then if self.view.zoom_mode == "page" then self:updateFlippingPage(self.current_page) @@ -832,13 +846,6 @@ function ReaderPaging:onRedrawCurrentPage() return true end -function ReaderPaging:onSetDimensions() - -- update listening according to new screen dimen - if Device:isTouchDevice() then - self:initGesListener() - end -end - -- wrapper for bounds checking function ReaderPaging:_gotoPage(number, orig_mode) if number == self.current_page or not number then @@ -870,55 +877,4 @@ function ReaderPaging:onGotoPercentage(percentage) return true end -function ReaderPaging:updateReadOrder() - local width, height = Screen:getWidth(), Screen:getHeight() - if self.inverse_reading_order then - self.ges_events.TapForward = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = width * (1-DTAP_ZONE_FORWARD.x - DTAP_ZONE_FORWARD.w), - y = height * DTAP_ZONE_FORWARD.y, - w = width * DTAP_ZONE_FORWARD.w, - h = height * DTAP_ZONE_FORWARD.h, - } - } - } - self.ges_events.TapBackward = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = width * (1-DTAP_ZONE_BACKWARD.x - DTAP_ZONE_BACKWARD.w), - y = height * DTAP_ZONE_BACKWARD.y, - w = width * DTAP_ZONE_BACKWARD.w, - h = height * DTAP_ZONE_BACKWARD.h, - } - } - } - else - self.ges_events.TapForward = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = width * DTAP_ZONE_FORWARD.x, - y = height * DTAP_ZONE_FORWARD.y, - w = width * DTAP_ZONE_FORWARD.w, - h = height * DTAP_ZONE_FORWARD.h, - } - } - } - self.ges_events.TapBackward = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = width * DTAP_ZONE_BACKWARD.x, - y = height * DTAP_ZONE_BACKWARD.y, - w = width * DTAP_ZONE_BACKWARD.w, - h = height * DTAP_ZONE_BACKWARD.h, - } - } - } - end -end - return ReaderPaging diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index 015e23c6a..f2627c292 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -12,7 +12,6 @@ local Event = require("ui/event") local dbg = require("dbg") local Blitbuffer = require("ffi/blitbuffer") local _ = require("gettext") -local ReaderKoboLight = require("apps/reader/modules/readerkobolight") local ReaderView = OverlapGroup:new{ document = nil, @@ -115,13 +114,6 @@ function ReaderView:addWidgets() self[1] = self.dogear self[2] = self.footer self[3] = self.flipping - if (Device:isKobo() and Device:hasFrontlight()) then - self.kobolight = ReaderKoboLight:new{ - view = self, - ui = self.ui, - } - self[4] = self.kobolight - end end function ReaderView:resetLayout() @@ -609,7 +601,9 @@ function ReaderView:onSetScreenMode(new_mode, rotation) Screen:setScreenMode(new_mode) end UIManager:setDirty(self.dialog, "full") - self.ui:handleEvent(Event:new("SetDimensions", Screen:getSize())) + local new_screen_size = Screen:getSize() + self.ui:handleEvent(Event:new("SetDimensions", new_screen_size)) + self.ui:onScreenResize(new_screen_size) self.ui:handleEvent(Event:new("InitScrollPageStates")) end self.cur_rotation_mode = Screen.cur_rotation_mode diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 46c2fa97d..a21140b3a 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -317,7 +317,15 @@ function ReaderUI:init() }) end - --dbg(self.doc_settings) + local ReaderKoboLight = require("apps/reader/modules/readerkobolight") + if (Device:isKobo() and Device:hasFrontlight()) then + self:registerModule('kobolight', ReaderKoboLight:new{ + dialog = self.dialog, + view = self.view, + ui = self, + }) + end + -- we only read settings after all the widgets are initialized self:handleEvent(Event:new("ReadSettings", self.doc_settings)) @@ -445,8 +453,9 @@ function ReaderUI:closeDialog() UIManager:close(self.password_dialog) end -function ReaderUI:onSetDimensions(dimen) +function ReaderUI:onScreenResize(dimen) self.dimen = dimen + self:updateTouchZonesOnScreenResize(dimen) end function ReaderUI:saveSettings() diff --git a/frontend/device/gesturedetector.lua b/frontend/device/gesturedetector.lua index a99273ed5..9ff212ff4 100644 --- a/frontend/device/gesturedetector.lua +++ b/frontend/device/gesturedetector.lua @@ -4,7 +4,8 @@ local DEBUG = require("dbg") --[[ Current detectable gestures: - * tap + * touch (user touched screen) + * tap (touch action detected as single tap) * pan * hold * swipe diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index 342cd654e..8b03fa286 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -265,9 +265,7 @@ Check size of dimension/rectangle for equality @tparam Geom rect_b ]] function Geom:equalSize(rect_b) - if self.w == rect_b.w - and self.h == rect_b.h - then + if self.w == rect_b.w and self.h == rect_b.h then return true end return false @@ -279,12 +277,9 @@ Check if our size is smaller than the size of the given dimension/rectangle @tparam Geom rect_b ]] function Geom:__lt(rect_b) - DEBUG("lt:",self,rect_b) if self.w < rect_b.w and self.h < rect_b.h then -DEBUG("lt+") return true end -DEBUG("lt-") return false end diff --git a/frontend/ui/widget/container/inputcontainer.lua b/frontend/ui/widget/container/inputcontainer.lua index e688d9603..6a472dea7 100644 --- a/frontend/ui/widget/container/inputcontainer.lua +++ b/frontend/ui/widget/container/inputcontainer.lua @@ -1,17 +1,10 @@ -local WidgetContainer = require("ui/widget/container/widgetcontainer") -local UIManager = require("ui/uimanager") -local Geom = require("ui/geometry") -local Event = require("ui/event") -local _ = require("gettext") +--[[-- +An InputContainer is an WidgetContainer that handles user input events including multi touches +and key presses. -if require("device"):isAndroid() then - require("jit").off(true, true) -end - ---[[ -an InputContainer is an WidgetContainer that handles input events +See @{InputContainer:registerTouchZones} for example on how to listen for multi touch inputs. -an example for a key_event is this: +An example for listening on key press input event is this: PanBy20 = { { "Shift", Input.group.Cursor }, @@ -26,9 +19,23 @@ an example for a key_event is this: }, Quit = { {"Home"} }, -it is suggested to reference configurable sequences from another table +It is suggested to reference configurable sequences from another table and store that table as configuration setting ---]] + +]] + +local WidgetContainer = require("ui/widget/container/widgetcontainer") +local GestureRange = require("ui/gesturerange") +local UIManager = require("ui/uimanager") +local Screen = require("device").screen +local Geom = require("ui/geometry") +local Event = require("ui/event") +local _ = require("gettext") + +if require("device"):isAndroid() then + require("jit").off(true, true) +end + local InputContainer = WidgetContainer:new{ vertical_align = "top", } @@ -50,6 +57,8 @@ function InputContainer:_init() end end self.ges_events = new_ges_events + self._touch_zones = {} + self._touch_zone_pos_idx = {} end function InputContainer:paintTo(bb, x, y) @@ -71,6 +80,108 @@ function InputContainer:paintTo(bb, x, y) end end +--[[-- + +Register touch zones into this InputContainer. + +See gesturedetector for list of supported gestures. + +NOTE: You are responsible for calling self:@{updateTouchZonesOnScreenResize} with the new +screen dimension whenever the screen is rotated or resized. + +@tparam table zones list of touch zones to register + +@usage +local InputContainer = require("ui/widget/container/inputcontainer") +local test_widget = InputContainer:new{} +test_widget:registerTouchZones({ + { + id = "foo_tap", + ges = "tap", + -- This binds handler to the full screen + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 1, ratio_h = 1, + }, + handler = function(ges) + print('User tapped on screen!') + return true + end + }, + { + id = "foo_swipe", + ges = "swipe", + -- This binds handler to bottom half of the screen + screen_zone = { + ratio_x = 0, ratio_y = 0.5, ratio_w = 1, ratio_h = 0.5, + }, + handler = function(ges) + print("User swiped at the bottom with direction:", ges.direction) + return true + end + }, +}) +require("ui/uimanager"):show(test_widget) + +]] +function InputContainer:registerTouchZones(zones) + local screen_width, screen_height = Screen:getWidth(), Screen:getHeight() + for _, zone in ipairs(zones) do + if self._touch_zone_pos_idx[zone.id] then + table.remove(self._touch_zones, self._touch_zone_pos_idx[zone.id]) + self._touch_zone_pos_idx[zone.id] = nil + end + local tzone = { + def = zone, + handler = zone.handler, + gs_range = GestureRange:new{ + ges = zone.ges, + rate = zone.rate, + range = Geom:new{ + x = screen_width * zone.screen_zone.ratio_x, + y = screen_height * zone.screen_zone.ratio_y, + w = screen_width * zone.screen_zone.ratio_w, + h = screen_height * zone.screen_zone.ratio_h, + }, + }, + } + local insert_pos = #self._touch_zones + if insert_pos ~= 0 then + if zone.overrides then + for _, override_id in ipairs(zone.overrides) do + local zone_idx = self._touch_zone_pos_idx[override_id] + if zone_idx and zone_idx < insert_pos then + insert_pos = zone_idx + end + end + else + insert_pos = 0 + end + end + if insert_pos == 0 then + table.insert(self._touch_zones, tzone) + self._touch_zone_pos_idx[zone.id] = 1 + else + table.insert(self._touch_zones, insert_pos, tzone) + self._touch_zone_pos_idx[zone.id] = insert_pos + end + end +end + +--[[-- +Update touch zones based on new screen dimension. + +@tparam ui.geometry.Geom new_screen_dimen new screen dimension +]] +function InputContainer:updateTouchZonesOnScreenResize(new_screen_dimen) + for _, tzone in ipairs(self._touch_zones) do + local range = tzone.gs_range + range.x = new_screen_dimen.w * tzone.def.screen_zone.ratio_x + range.y = new_screen_dimen.h * tzone.def.screen_zone.ratio_y + range.w = new_screen_dimen.w * tzone.def.screen_zone.ratio_w + range.h = new_screen_dimen.h * tzone.def.screen_zone.ratio_h + end +end + --[[ the following handler handles keypresses and checks if they lead to a command. if this is the case, we retransmit another event within ourselves @@ -89,6 +200,11 @@ function InputContainer:onKeyPress(key) end function InputContainer:onGesture(ev) + for _, tzone in ipairs(self._touch_zones) do + if tzone.gs_range:match(ev) then + return tzone.handler(ev) + end + end for name, gsseq in pairs(self.ges_events) do for _, gs_range in ipairs(gsseq) do if gs_range:match(ev) then diff --git a/spec/unit/widget_inputcontainer_spec.lua b/spec/unit/widget_inputcontainer_spec.lua new file mode 100644 index 000000000..e0677a826 --- /dev/null +++ b/spec/unit/widget_inputcontainer_spec.lua @@ -0,0 +1,77 @@ +describe("InputContainer widget", function() + local InputContainer, Screen + setup(function() + require("commonrequire") + InputContainer = require("ui/widget/container/inputcontainer") + Screen = require("device").screen + end) + + it("should register touch zones", function() + local ic = InputContainer:new{} + assert.is.same(#ic._touch_zones, 0) + + ic:registerTouchZones({ + { + id = "foo", + ges = "swipe", + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 1, ratio_h = 1, + }, + handler = function() end, + }, + { + id = "bar", + ges = "tap", + screen_zone = { + ratio_x = 0, ratio_y = 0.1, ratio_w = 0.5, ratio_h = 1, + }, + handler = function() end, + }, + }) + + local screen_width, screen_height = Screen:getWidth(), Screen:getHeight() + assert.is.same(#ic._touch_zones, 2) + assert.is.same("foo", ic._touch_zones[1].def.id) + assert.is.same(ic._touch_zones[1].def.handler, ic._touch_zones[1].handler) + assert.is.same("bar", ic._touch_zones[2].def.id) + assert.is.same("tap", ic._touch_zones[2].gs_range.ges) + assert.is.same(0, ic._touch_zones[2].gs_range.range.x) + assert.is.same(screen_height * 0.1, ic._touch_zones[2].gs_range.range.y) + assert.is.same(screen_width / 2, ic._touch_zones[2].gs_range.range.w) + assert.is.same(screen_height, ic._touch_zones[2].gs_range.range.h) + end) + + it("should support overrides for touch zones", function() + local ic = InputContainer:new{} + ic:registerTouchZones({ + { + id = "foo", + ges = "tap", + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 1, ratio_h = 1, + }, + handler = function() end, + }, + { + id = "bar", + ges = "tap", + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 0.5, ratio_h = 1, + }, + handler = function() end, + }, + { + id = "baz", + ges = "tap", + screen_zone = { + ratio_x = 0, ratio_y = 0, ratio_w = 0.5, ratio_h = 1, + }, + overrides = { 'foo' }, + handler = function() end, + }, + }) + assert.is.same(ic._touch_zones[1].def.id, 'baz') + assert.is.same(ic._touch_zones[2].def.id, 'foo') + assert.is.same(ic._touch_zones[3].def.id, 'bar') + end) +end)