diff --git a/druid/base/button.lua b/druid/base/button.lua index 8733a39..7b940d9 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -18,7 +18,6 @@ -- @tfield vector3 scale_from Initial scale of anim_node -- @tfield vector3 pos Initial pos of anim_node -- @tfield any params Params to click callbacks --- @tfield boolean hover_anim Is hover anim enabled -- @tfield druid.hover hover Druid hover logic component -- @tfield[opt] node click_zone Restriction zone @@ -52,17 +51,17 @@ end local function on_button_hover(self, hover_state) - if not self.style.on_hover then + if not self._style.on_hover then return end - self.style.on_hover(self, self.anim_node, hover_state) + self._style.on_hover(self, self.anim_node, hover_state) end local function on_button_click(self) - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = 1 self.on_click:trigger(self:get_context(), self.params, self) @@ -75,29 +74,35 @@ local function on_button_repeated_click(self) self.is_repeated_started = true end - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = self.click_in_row + 1 - self.on_repeated_click:trigger(self:get_context(), self.params, self) + self.on_repeated_click:trigger(self:get_context(), self.params, self, self.click_in_row) end local function on_button_long_click(self) - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = 1 - self.on_long_click:trigger(self:get_context(), self.params, self) + local time = socket.gettime() - self.last_pressed_time + self.on_long_click:trigger(self:get_context(), self.params, self, time) end local function on_button_double_click(self) - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = self.click_in_row + 1 - self.on_double_click:trigger(self:get_context(), self.params, self) + self.on_double_click:trigger(self:get_context(), self.params, self, self.click_in_row) +end + + +local function on_button_hold(self, press_time) + self.on_hold_callback:trigger(self:get_context(), self.params, self, press_time) end @@ -111,10 +116,10 @@ local function on_button_release(self) self.can_action = false local time = socket.gettime() - local is_long_click = (time - self.last_pressed_time) > self.style.LONGTAP_TIME + local is_long_click = (time - self.last_pressed_time) > self._style.LONGTAP_TIME is_long_click = is_long_click and self.on_long_click:is_exist() - local is_double_click = (time - self.last_released_time) < self.style.DOUBLETAP_TIME + local is_double_click = (time - self.last_released_time) < self._style.DOUBLETAP_TIME is_double_click = is_double_click and self.on_double_click:is_exist() if is_long_click then @@ -129,8 +134,8 @@ local function on_button_release(self) end return true else - if self.style.on_click_disabled then - self.style.on_click_disabled(self, self.anim_node) + if self._style.on_click_disabled then + self._style.on_click_disabled(self, self.anim_node) end return false end @@ -147,14 +152,12 @@ end -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) self.druid = self:get_druid() - self.style = self:get_style() self.node = self:get_node(node) self.anim_node = anim_node and helper:get_node(anim_node) or self.node -- TODO: rename to start_scale self.scale_from = gui.get_scale(self.anim_node) self.params = params - self.hover_anim = self.style.IS_HOVER self.hover = self.druid:new_hover(node, on_button_hover) self.click_zone = nil self.is_repeated_started = false @@ -168,6 +171,7 @@ function M.init(self, node, callback, params, anim_node, event) self.on_repeated_click = Event() self.on_long_click = Event() self.on_double_click = Event() + self.on_hold_callback = Event() end @@ -219,6 +223,20 @@ function M.on_input(self, action_id, action) return on_button_release(self) end + if not self.disabled and self.can_action and self.on_long_click:is_exist() then + local press_time = socket.gettime() - self.last_pressed_time + + if self._style.AUTOHOLD_TRIGGER and self._style.AUTOHOLD_TRIGGER <= press_time then + on_button_release(self) + return true + end + + if press_time >= self._style.LONGTAP_TIME then + on_button_hold(self, press_time) + return true + end + end + return not self.disabled end @@ -230,8 +248,8 @@ end function M.set_enabled(self, state) self.disabled = not state - if self.style.on_set_enabled then - self.style.on_set_enabled(self, self.node, state) + if self._style.on_set_enabled then + self._style.on_set_enabled(self, self.node, state) end end @@ -241,14 +259,6 @@ function M.get_enabled(self) end ---- Disable all button animations --- @function button:disable_animation --- @tparam table self Component instance -function M.disable_animation(self) - self.hover_anim = false -end - - --- Strict button click area. Useful for -- no click events outside stencil node -- @function button:set_click_zone diff --git a/druid/component.lua b/druid/component.lua index bc49060..0e17adf 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -26,6 +26,7 @@ end -- @tparam table style Druid style module function Component.set_style(self, druid_style) self._meta.style = druid_style + self._style = self:get_style() end diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index 430c0fb..ee5d3ac 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -13,16 +13,15 @@ M["button"] = { DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), ENABLED_COLOR = vmath.vector4(1), LONGTAP_TIME = 0.4, + AUTOHOLD_TRIGGER = 0.8, DOUBLETAP_TIME = 0.4, IS_HOVER = true, on_hover = function(self, node, state) - if self.hover_anim then - local scale_to = self.scale_from + M.button.HOVER_SCALE + local scale_to = self.scale_from + M.button.HOVER_SCALE - local target_scale = state and scale_to or self.scale_from - anims.hover_scale(self, target_scale, M.button.HOVER_TIME) - end + local target_scale = state and scale_to or self.scale_from + anims.hover_scale(self, target_scale, M.button.HOVER_TIME) end, on_click = function(self, node) diff --git a/druid/styles/sprites/style.lua b/druid/styles/sprites/style.lua new file mode 100644 index 0000000..b99409d --- /dev/null +++ b/druid/styles/sprites/style.lua @@ -0,0 +1,52 @@ +local M = {} + + +M["button"] = { + BTN_SOUND = "click", + BTN_SOUND_DISABLED = "click", + DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), + ENABLED_COLOR = vmath.vector4(1), + LONGTAP_TIME = 0.4, + DOUBLETAP_TIME = 0.4, + HOVER_IMAGE = "button_yellow", + DEFAULT_IMAGE = "button_blue", + CLICK_IMAGE = "button_red", + + on_hover = function(self, node, state) + local anim = state and M.button.HOVER_IMAGE or M.button.DEFAULT_IMAGE + gui.play_flipbook(node, anim) + end +} + + +M["scroll"] = { + FRICT_HOLD = 0, -- mult. for inert, while touching + FRICT = 0, -- mult for free inert + INERT_THRESHOLD = 2, -- speed to stop inertion + INERT_SPEED = 0, -- koef. of inert speed + DEADZONE = 6, -- in px + SOFT_ZONE_SIZE = 20, -- size of outside zone (back move) + BACK_SPEED = 0, -- lerp speed + ANIM_SPEED = 0, -- gui.animation speed to point +} + + +M["progress"] = { + SPEED = 5, -- progress bar fill rate, more faster + MIN_DELTA = 1 +} + + +M["progress_rich"] = { + DELAY = 0, -- delay in seconds before main fill +} + + +M["checkbox"] = { + on_change_state = function(self, node, state) + gui.set_enabled(node, state) + end +} + + +return M diff --git a/example/kenney/page/button.lua b/example/kenney/page/button.lua index 3ff56ff..e736935 100644 --- a/example/kenney/page/button.lua +++ b/example/kenney/page/button.lua @@ -1,4 +1,4 @@ -local sprite_change_style = {} +local sprite_style = require("druid.styles.sprites.style") local M = {} @@ -7,16 +7,20 @@ local function usual_callback() print("Usual callback") end -local function long_tap_callback() - print("Long tap callback") +local function long_tap_callback(self, params, button, hold_time) + print("Long tap callback", hold_time) end -local function repeated_callback(self, params, button) - print("Repeated callback", button.click_in_row) +local function hold_callback(self, params, button, hold_time) + print("On hold callback", hold_time) end -local function double_tap_callback(self, params, button) - print("Double tap callback", button.click_in_row) +local function repeated_callback(self, params, button, click_in_row) + print("Repeated callback", click_in_row) +end + +local function double_tap_callback(self, params, button, click_in_row) + print("Double tap callback", click_in_row) end @@ -24,13 +28,11 @@ local function setup_buttons(self) self.druid:new_button("button_usual/button", usual_callback) local custom_style = self.druid:new_button("button_custom_style/button", usual_callback) - custom_style:set_style(sprite_change_style) - -- HOVER_IMAGE and DEFAULT_IMAGE - from our custom style params - custom_style.HOVER_IMAGE = "button_yellow" - custom_style.DEFAULT_IMAGE = "button_blue" + custom_style:set_style(sprite_style) - self.druid:new_button("button_long_tap/button", usual_callback) - .on_long_click:subscribe(long_tap_callback) + local long_button = self.druid:new_button("button_long_tap/button", usual_callback) + long_button.on_hold_callback:subscribe(hold_callback) + long_button.on_long_click:subscribe(long_tap_callback) self.druid:new_button("button_repeated_tap/button", usual_callback) .on_repeated_click:subscribe(repeated_callback) self.druid:new_button("button_double_tap/button", usual_callback)