diff --git a/docs_md/changelog.md b/docs_md/changelog.md index 4fc0160..f4f2d46 100644 --- a/docs_md/changelog.md +++ b/docs_md/changelog.md @@ -152,3 +152,8 @@ _after:_ ```lua local Drag = component.create("drag", { component.ON_INPUT }, const.PRIORITY_INPUT_HIGH) ``` +- **#123** Add scroll for Scroll component via mouse wheel or touchpad: +-- Added Scroll style params: WHEEL_SCROLL_SPEED, WHEEL_SCROLL_INVERTED +-- Mouse scroll working when cursor is hover on scroll view node +-- Vertical scroll have more priority than horizontal +-- Fix: When Hover component node became disabled, reset hover state (throw on_hover and on_mouse_hover events) diff --git a/druid/base/hover.lua b/druid/base/hover.lua index b426f58..1fe9ddf 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -40,11 +40,14 @@ function Hover.on_input(self, action_id, action) return false end + -- Disable nil (it's mouse) hover or mobile platforms if not action_id and helper.is_mobile() then return false end if not helper.is_enabled(self.node) or not self._is_enabled then + self:set_hover(false) + self:set_mouse_hover(false) return false end diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index fa41434..5dcf2c8 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -54,10 +54,11 @@ local Event = require("druid.event") +local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Scroll = component.create("scroll", { component.ON_UPDATE, component.ON_LAYOUT_CHANGE }) +local Scroll = component.create("scroll", { component.ON_INPUT, component.ON_UPDATE, component.ON_LAYOUT_CHANGE }) local function inverse_lerp(min, max, current) @@ -102,6 +103,8 @@ end -- @tfield[opt=0.2] number ANIM_SPEED Scroll gui.animation speed for scroll_to function -- @tfield[opt=0] number EXTRA_STRETCH_SIZE extra size in pixels outside of scroll (stretch effect) -- @tfield[opt=false] bool SMALL_CONTENT_SCROLL If true, content node with size less than view node size can be scrolled +-- @tfield[opt=25] bool WHEEL_SCROLL_SPEED The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling +-- @tfield[opt=false] bool SMALL_CONTENT_SCROLL If true, invert direction for touchpad and mouse wheel scroll function Scroll.on_style_change(self, style) self.style = {} self.style.EXTRA_STRETCH_SIZE = style.EXTRA_STRETCH_SIZE or 0 @@ -115,6 +118,8 @@ function Scroll.on_style_change(self, style) self.style.INERT_SPEED = style.INERT_SPEED or 30 self.style.POINTS_DEADZONE = style.POINTS_DEADZONE or 20 self.style.SMALL_CONTENT_SCROLL = style.SMALL_CONTENT_SCROLL or false + self.style.WHEEL_SCROLL_SPEED = style.WHEEL_SCROLL_SPEED or 25 + self.style.WHEEL_SCROLL_INVERTED = style.WHEEL_SCROLL_INVERTED or false self._is_inert = not (self.style.FRICT == 0 or self.style.FRICT_HOLD == 0 or @@ -142,6 +147,10 @@ function Scroll.init(self, view_node, content_node) self.drag.on_touch_start:subscribe(self._on_touch_start) self.drag.on_touch_end:subscribe(self._on_touch_end) + self.hover = self.druid:new_hover(view_node) + self.hover.on_mouse_hover:subscribe(self._on_mouse_hover) + self._is_mouse_hover = false + self.on_scroll = Event() self.on_scroll_to = Event() self.on_point_scroll = Event() @@ -175,6 +184,11 @@ function Scroll.update(self, dt) end +function Scroll.on_input(self, action_id, action) + return self:_process_scroll_wheel(action_id, action) +end + + function Scroll.on_remove(self) self:bind_grid(nil) end @@ -703,4 +717,33 @@ function Scroll._update_params(self, dt) end +function Scroll._process_scroll_wheel(self, action_id, action) + if not self._is_mouse_hover or self.style.WHEEL_SCROLL_SPEED == 0 then + return false + end + + if action_id ~= const.ACTION_SCROLL_UP and action_id ~= const.ACTION_SCROLL_DOWN then + return false + end + + local koef = (action_id == const.ACTION_SCROLL_UP) and 1 or -1 + if self.style.WHEEL_SCROLL_INVERTED then + koef = -koef + end + + if self.drag.can_y then + self.inertion.y = (self.inertion.y + self.style.WHEEL_SCROLL_SPEED * koef) * self.style.FRICT_HOLD + else + self.inertion.x = (self.inertion.x + self.style.WHEEL_SCROLL_SPEED * koef) * self.style.FRICT_HOLD + end + + return true +end + + +function Scroll._on_mouse_hover(self, state) + self._is_mouse_hover = state +end + + return Scroll