From 162bbd0ed982215e5a51515f4fb5f53150ec5fd3 Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 23:36:44 +0300 Subject: [PATCH] Add more events on button (long_tap, repeated_tap, double_tap) --- druid/base/button.lua | 78 +++++++++++++++++++++++-- druid/event.lua | 15 +++++ druid/styles/default/style.lua | 2 + druid/styles/empty/style.lua | 2 + example/kenney/gui/main/main.gui_script | 5 +- example/kenney/page/button.lua | 30 +++++++++- 6 files changed, 122 insertions(+), 10 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index 4bcf9f6..abe994f 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -47,14 +47,67 @@ local function on_button_hover(self, hover_state) end +local function on_button_click(self) + 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) +end + + +local function on_button_repeated_click(self) + 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) +end + + +local function on_button_long_click(self) + 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) +end + + +local function on_button_double_click(self) + 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) +end + + local function on_button_release(self) + if self.is_repeated_started then + return false + end + if not self.disabled then - if not self.stub and self.can_action then + if self.can_action then self.can_action = false - if self.style.on_click then - self.style.on_click(self, self.anim_node) + + local time = socket.gettime() + 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 + is_double_click = is_double_click and self.on_double_click:is_exist() + + if is_long_click then + on_button_long_click(self) + elseif is_double_click then + on_button_double_click(self) + else + on_button_click(self) end - self.on_click:trigger(self:get_context(), self.params, self) + + self.last_released_time = time end return true else @@ -86,6 +139,10 @@ function M.init(self, node, callback, params, anim_node, event) 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 + self.last_pressed_time = 0 + self.last_released_time = 0 + self.click_in_row = 0 -- Event stubs self.on_click = Event(callback) @@ -118,10 +175,20 @@ function M.on_input(self, action_id, action) if action.pressed then -- Can interact if start touch on the button self.can_action = true - self.repeated_counter = 0 + self.is_repeated_started = false + self.last_pressed_time = socket.gettime() return true end + -- While hold button, repeat rate pick from input.repeat_interval + if action.repeated then + if not self.disabled and self.on_repeated_click:is_exist() and self.can_action then + self.is_repeated_started = true + on_button_repeated_click(self) + return true + end + end + if action.released then return on_button_release(self) end @@ -166,7 +233,6 @@ function M.set_click_zone(self, zone) end --- TODO: implement them all! --- Set key-code to trigger this button function M.set_key_trigger(self, key) diff --git a/druid/event.lua b/druid/event.lua index d38761e..1d6c289 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -43,6 +43,21 @@ function M.unsubscribe(self, callback) end +--- Return true, if event have at lease one handler +-- @function event:is_exist +-- @treturn boolean True if event have handlers +function M.is_exist(self) + return #self._callbacks > 0 +end + + +--- Clear the all event handlers +-- @function event:clear +function M.clear(self) + self._callbacks = {} +end + + --- Trigger the event and call all subscribed callbacks -- @function event:trigger -- @param ... All event params diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index d9a7d46..430c0fb 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -12,6 +12,8 @@ M["button"] = { 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, IS_HOVER = true, on_hover = function(self, node, state) diff --git a/druid/styles/empty/style.lua b/druid/styles/empty/style.lua index 2ef9698..27a9a43 100644 --- a/druid/styles/empty/style.lua +++ b/druid/styles/empty/style.lua @@ -6,6 +6,8 @@ M["button"] = { 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, IS_HOVER = false, } diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 8760379..bd472e3 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -42,11 +42,14 @@ function init(self) self.druid = druid.new(self) init_top_panel(self) - self.page = 1 + self.page = 3 main_page.setup_page(self) text_page.setup_page(self) button_page.setup_page(self) scroll_page.setup_page(self) + + -- Refresh state + on_control_button(self, 0) end diff --git a/example/kenney/page/button.lua b/example/kenney/page/button.lua index 308b1eb..cdfad37 100644 --- a/example/kenney/page/button.lua +++ b/example/kenney/page/button.lua @@ -3,15 +3,39 @@ local sprite_change_style = {} local M = {} +local function usual_callback() + print("Usual callback") +end + +local function long_tap_callback() + print("Long tap callback") +end + +local function repeated_callback(self, params, button) + print("Repeated callback", button.click_in_row) +end + +local function double_tap_callback(self, params, button) + print("Double tap callback", button.click_in_row) +end + + local function setup_buttons(self) - self.druid:new_button("button_usual/button") + self.druid:new_button("button_usual/button", usual_callback) - local custom_style = self.druid:new_button("button_custom_style/button") + 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" + + + self.druid:new_button("button_long_tap/button", usual_callback) + .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) + .on_double_click:subscribe(double_tap_callback) end