diff --git a/docs_md/changelog.md b/docs_md/changelog.md index 7ad4ec3..fa31363 100644 --- a/docs_md/changelog.md +++ b/docs_md/changelog.md @@ -238,7 +238,12 @@ Have a good day. - Add Druid component interest: `component.ON_MESSAGE_INPUT` - Implement new interest via function `component:on_message_input(node_id, message)` - See **System: Message input** example -- **#111**: Add autocheck for input and stencil nodes. To enable this feature, add `druid.stencil_check = 1` to your game.project file. +- **#111** Add autocheck for input and stencil nodes. To enable this feature, add `druid.stencil_check = 1` to your game.project file. - Add `helper.get_closest_stencil_node` function to get closest parent non inverted stencil node - Add `component.ON_LATE_INIT` interest. If component with with interest, it will call `component.on_late_init` function once after component init on update step. This can be used to do something after all gui components are was initialized and setup. - - This feature is using for auto setup `component:set_click_zone` to restrict clicks outside scrolls zone for example. Now you can don't think about click zone and let Druid do it instead of you! \ No newline at end of file + - This feature is using for auto setup `component:set_click_zone` to restrict clicks outside scrolls zone for example. Now you can don't think about click zone and let Druid do it instead of you! +- **#110** Add `Button:set_check_function(check_function, failure_callback)` function to add your custom click condition to button. + - `Button:set_enabled` has more priority than this to check button availability + - The `check_function` should return _true_ of _false_. If true - button can be clicked + - The `failure_callback`will be called if `check_function` will return false. It's callback for you if button is not available + - Example with `set_check_function` exists in general:buttons example collection \ No newline at end of file diff --git a/druid/base/button.lua b/druid/base/button.lua index 0ef1f84..2e3f486 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -136,7 +136,20 @@ local function on_button_release(self) return false end - if not self.disabled then + local check_function_result = true + if self._check_function then + check_function_result = self._check_function(self:get_context()) + end + + if self.disabled then + self.style.on_click_disabled(self, self.anim_node) + return true + elseif not check_function_result then + if self._failure_callback then + self._failure_callback(self:get_context()) + end + return true + else if self.can_action then self.can_action = false @@ -158,9 +171,6 @@ local function on_button_release(self) self.last_released_time = time end return true - else - self.style.on_click_disabled(self, self.anim_node) - return false end end @@ -215,6 +225,9 @@ function Button.init(self, node, callback, params, anim_node) self.click_in_row = 0 self.key_trigger = nil + self._check_function = nil + self._failure_callback = nil + -- Event stubs self.on_click = Event(callback) self.on_repeated_click = Event() @@ -387,4 +400,14 @@ function Button.get_key_trigger(self) end +--- Set function for additional check for button click availability +-- @tparam[opt] function check_function Should return true or false. If true - button can be pressed. +-- @tparam[opt] function failure_callback Function what will be called on button click, if check function return false +-- @treturn Button Current button instance +function Button.set_check_function(self, check_function, failure_callback) + self._check_function = check_function + self._failure_callback = failure_callback +end + + return Button diff --git a/example/examples/general/buttons/buttons.gui b/example/examples/general/buttons/buttons.gui index 5aa4f1a..a1f6779 100644 --- a/example/examples/general/buttons/buttons.gui +++ b/example/examples/general/buttons/buttons.gui @@ -1304,6 +1304,293 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: 200.0 + y: 80.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_custom_check" + parent: "root" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + size { + x: 130.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "kenney/button_blue" + id: "button_custom_check/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_custom_check" + layer: "image" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.6 + y: 0.6 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Check func" + font: "game" + id: "button_custom_check/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_custom_check/button" + layer: "text" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 3 + overridden_fields: 8 + overridden_fields: 18 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 200.0 + y: 180.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.5 + z: 1.0 + w: 1.0 + } + size { + x: 400.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Button with additional check function." + font: "game" + id: "text_custom_check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: true + parent: "root" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 200.0 + y: -20.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.5 + z: 1.0 + w: 1.0 + } + size { + x: 400.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Failure callback: false" + font: "game" + id: "text_custom_result" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: true + parent: "root" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} layers { name: "image" } diff --git a/example/examples/general/buttons/buttons.gui_script b/example/examples/general/buttons/buttons.gui_script index 2de994a..04b3f1c 100644 --- a/example/examples/general/buttons/buttons.gui_script +++ b/example/examples/general/buttons/buttons.gui_script @@ -27,6 +27,28 @@ local function double_tap_callback(self, params, button, click_in_row) end +local function check_function(self) + self._some_test_value = self._some_test_value or 0 + self._some_test_value = self._some_test_value + 1 + + return self._some_test_value % 2 == 0 +end + + +local function failure_check_callback(self) + gui.set_text(gui.get_node("text_custom_result"), "Failure callback: true") +end + + +local function check_clicked_callback(self) + local node = gui.get_node("text_custom_result") + gui.set_text(node, "Failure callback: false") + + gui.set_scale(node, vmath.vector3(0.75)) + gui.animate(node, gui.PROP_SCALE, 0.5, gui.EASING_OUTSINE, 0.2) +end + + local function setup_buttons(self) self.druid:new_button("button_usual/button", usual_callback) @@ -48,6 +70,9 @@ local function setup_buttons(self) -- Button with another node for animating self.druid:new_button("button_anim/button", usual_callback, nil, "anim_node_icon") + + self.druid:new_button("button_custom_check/button", check_clicked_callback) + :set_check_function(check_function, failure_check_callback) end