mirror of
https://github.com/Insality/druid.git
synced 2025-09-28 02:22:18 +02:00
Merge branch 'develop' into feature/D16-checkbox
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
local data = require("druid.data")
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
data.ON_INPUT
|
||||
}
|
||||
|
||||
|
||||
function M.init(self, callback, params)
|
||||
self.event = data.A_ANDR_BACK
|
||||
self.callback = callback
|
||||
self.params = params
|
||||
end
|
||||
|
||||
|
||||
--- input handler
|
||||
-- @param action_id - input action id
|
||||
-- @param action - input action
|
||||
function M.on_input(self, action_id, action)
|
||||
if action[data.RELEASED] then
|
||||
self.callback(self.parent.parent, self.params)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
return M
|
34
druid/base/back_handler.lua
Normal file
34
druid/base/back_handler.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
--- Component to handle back key
|
||||
-- @module base.back_handler
|
||||
|
||||
local const = require("druid.const")
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
const.ON_INPUT
|
||||
}
|
||||
|
||||
--- Component init function
|
||||
-- @tparam table self component instance
|
||||
-- @tparam callback callback on back button
|
||||
-- @tparam[opt] params callback argument
|
||||
function M.init(self, callback, params)
|
||||
self.event = const.ACTION_BACK
|
||||
self.callback = callback
|
||||
self.params = params
|
||||
end
|
||||
|
||||
|
||||
--- Input handler for component
|
||||
-- @tparam string action_id on_input action id
|
||||
-- @tparam table action on_input action
|
||||
function M.on_input(self, action_id, action)
|
||||
if action[const.RELEASED] then
|
||||
self.callback(self.parent.parent, self.params)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
return M
|
33
druid/base/blocker.lua
Normal file
33
druid/base/blocker.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
--- Component to block input on specify zone (node)
|
||||
-- @module base.blocker
|
||||
|
||||
local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
const.ON_SWIPE
|
||||
}
|
||||
|
||||
|
||||
function M.init(self, node)
|
||||
self.node = helper.get_node(node)
|
||||
self.event = const.ACTION_TOUCH
|
||||
end
|
||||
|
||||
|
||||
function M.on_input(self, action_id, action)
|
||||
if not helper.is_enabled(self.node) then
|
||||
return false
|
||||
end
|
||||
|
||||
if gui.pick_node(self.node, action.x, action.y) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
return M
|
@@ -1,4 +1,11 @@
|
||||
local data = require("druid.data")
|
||||
--- Component to handle basic GUI button
|
||||
-- @module base.button
|
||||
|
||||
-- TODO: Add button mode:
|
||||
-- Long tap
|
||||
-- Repeated tap
|
||||
|
||||
local const = require("druid.const")
|
||||
local ui_animate = require("druid.helper.druid_animate")
|
||||
local settings = require("druid.settings")
|
||||
local helper = require("druid.helper")
|
||||
@@ -6,18 +13,18 @@ local b_settings = settings.button
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
data.ON_INPUT
|
||||
const.ON_INPUT
|
||||
}
|
||||
|
||||
M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0)
|
||||
M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1)
|
||||
M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1)
|
||||
M.DEFAUL_ACTIVATION_TIME = 0.2
|
||||
M.DEFAULT_ACTIVATION_TIME = 0.2
|
||||
|
||||
|
||||
function M.init(self, node, callback, params, anim_node, event)
|
||||
self.node = helper.get_node(node)
|
||||
self.event = data.A_TOUCH
|
||||
self.event = const.ACTION_TOUCH
|
||||
self.anim_node = anim_node and helper.get_node(anim_node) or self.node
|
||||
self.scale_from = gui.get_scale(self.anim_node)
|
||||
self.scale_to = self.scale_from + b_settings.SCALE_CHANGE
|
||||
@@ -30,14 +37,23 @@ function M.init(self, node, callback, params, anim_node, event)
|
||||
self.hover_anim = b_settings.IS_HOVER
|
||||
self.sound = b_settings.BTN_SOUND
|
||||
self.sound_disable = b_settings.BTN_SOUND_DISABLED
|
||||
self.ext_zone = nil
|
||||
self.click_zone = nil
|
||||
|
||||
-- TODO: to separate component "block_input"?
|
||||
-- If callback is nil, so the buttons is stub and without anim
|
||||
-- Used for zones, what should dont pass the input to other UI elements
|
||||
if not callback then
|
||||
self.stub = true
|
||||
self.hover_anim = false
|
||||
self.callback = function() end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function set_hover(self, state)
|
||||
if self.hover_anim and self._is_hovered ~= state then
|
||||
local target_scale = state and self.scale_hover_to or self.scale_from
|
||||
ui_animate.scale(self, self.node, target_scale, b_settings.HOVER_TIME)
|
||||
ui_animate.scale(self, self.anim_node, target_scale, b_settings.HOVER_TIME)
|
||||
self._is_hovered = state
|
||||
end
|
||||
end
|
||||
@@ -47,15 +63,17 @@ local function on_button_release(self)
|
||||
if not self.disabled then
|
||||
if not self.stub and self.can_action then
|
||||
self.can_action = false
|
||||
self.tap_anim(self)
|
||||
settings.play_sound(self.sound)
|
||||
if self.tap_anim then
|
||||
self.tap_anim(self)
|
||||
end
|
||||
self.callback(self.parent.parent, self.params, self)
|
||||
settings.play_sound(self.sound)
|
||||
else
|
||||
set_hover(self, false)
|
||||
end
|
||||
return true
|
||||
else
|
||||
self.sound_disable()
|
||||
settings.play_sound(self.sound_disable)
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -70,30 +88,32 @@ function M.on_input(self, action_id, action)
|
||||
end
|
||||
|
||||
local is_pick = gui.pick_node(self.node, action.x, action.y)
|
||||
if self.ext_zone then
|
||||
is_pick = is_pick and gui.pick_node(self.ext_zone, action.x, action.y)
|
||||
if self.click_zone then
|
||||
is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y)
|
||||
end
|
||||
|
||||
if is_pick then
|
||||
if action.pressed then
|
||||
-- Can interact if start touch on the button
|
||||
self.can_action = true
|
||||
return true
|
||||
end
|
||||
|
||||
if action.released then
|
||||
set_hover(self, false)
|
||||
return on_button_release(self)
|
||||
else
|
||||
set_hover(self, true)
|
||||
end
|
||||
return not self.disabled
|
||||
else
|
||||
if not is_pick then
|
||||
-- Can't interact, if touch outside of button
|
||||
self.can_action = false
|
||||
set_hover(self, false)
|
||||
return false
|
||||
end
|
||||
|
||||
if action.pressed then
|
||||
-- Can interact if start touch on the button
|
||||
self.can_action = true
|
||||
self.repeated_counter = 0
|
||||
return true
|
||||
end
|
||||
|
||||
if action.released then
|
||||
set_hover(self, false)
|
||||
return on_button_release(self)
|
||||
else
|
||||
set_hover(self, true)
|
||||
end
|
||||
|
||||
return not self.disabled
|
||||
end
|
||||
|
||||
|
||||
@@ -123,21 +143,21 @@ end
|
||||
function M.deactivate(self, is_animate, callback)
|
||||
self.disabled = true
|
||||
if is_animate then
|
||||
local counter = 0
|
||||
local clbk = function()
|
||||
counter = counter + 1
|
||||
if counter == 3 and callback then
|
||||
-- callback call three times in gui.animation
|
||||
local clbk = helper.after(3, function()
|
||||
if callback then
|
||||
callback(self.parent.parent)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
ui_animate.color(self, self.node, M.DEFAULT_DEACTIVATE_COLOR,
|
||||
clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE)
|
||||
clbk, M.DEFAULT_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE)
|
||||
|
||||
ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.x,
|
||||
M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
|
||||
ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.y,
|
||||
M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
else
|
||||
gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR)
|
||||
gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE)
|
||||
@@ -150,24 +170,22 @@ end
|
||||
|
||||
function M.activate(self, is_animate, callback)
|
||||
if is_animate then
|
||||
local counter = 0
|
||||
local clbk = function()
|
||||
counter = counter + 1
|
||||
if counter == 3 then
|
||||
-- callback call three times in gui.animation
|
||||
local clbk = helper.after(3, function()
|
||||
self.disabled = false
|
||||
if callback then
|
||||
callback(self.parent.parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
ui_animate.color(self, self.node, ui_animate.TINT_SHOW,
|
||||
clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE)
|
||||
clbk, M.DEFAULT_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE)
|
||||
|
||||
ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.x,
|
||||
M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
|
||||
ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.y,
|
||||
M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE)
|
||||
else
|
||||
gui.set_color(self.node, ui_animate.TINT_SHOW)
|
||||
gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE)
|
||||
@@ -178,11 +196,19 @@ function M.activate(self, is_animate, callback)
|
||||
end
|
||||
end
|
||||
|
||||
--- Set additional node, what need to be clicked on button click
|
||||
-- Used, if need setup, what button can be clicked only in special zone
|
||||
function M.set_ext_zone(self, zone)
|
||||
self.ext_zone = helper.get_node(zone)
|
||||
|
||||
function M.disable_animation(self)
|
||||
self.hover_anim = false
|
||||
self.tap_anim = nil
|
||||
self.back_anim = nil
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
--- Set additional node, what need to be clicked on button click
|
||||
-- Used, if need setup, what button can be clicked only in special zone
|
||||
function M.set_click_zone(self, zone)
|
||||
self.click_zone = helper.get_node(zone)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
|
@@ -1,11 +1,11 @@
|
||||
--- Component to handle placing components by row and columns.
|
||||
-- Grid can anchor your elements, get content size and other
|
||||
-- @module base.grid
|
||||
|
||||
local helper = require("druid.helper")
|
||||
|
||||
local M = {}
|
||||
|
||||
--- Sort and placing nodes
|
||||
-- Plans: placing by max width, placing with max in_row
|
||||
-- Allow different node sizes, allow animation with node insert
|
||||
|
||||
|
||||
function M.init(self, parent, element, in_row)
|
||||
self.parent = helper.get_node(parent)
|
||||
@@ -111,4 +111,4 @@ function M.clear(self)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
return M
|
||||
|
@@ -1,4 +1,7 @@
|
||||
local data = require("druid.data")
|
||||
--- Component to handle progress bars
|
||||
-- @module base.progress
|
||||
|
||||
local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local settings = require("druid.settings")
|
||||
local p_settings = settings.progress
|
||||
@@ -6,7 +9,7 @@ local p_settings = settings.progress
|
||||
local M = {}
|
||||
|
||||
M.interest = {
|
||||
data.ON_UPDATE,
|
||||
const.ON_UPDATE,
|
||||
}
|
||||
|
||||
local PROP_Y = "y"
|
||||
@@ -147,4 +150,4 @@ function M.update(self, dt)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
return M
|
||||
|
@@ -1,5 +1,8 @@
|
||||
--- Component to handle scroll content
|
||||
-- @module base.scroll
|
||||
|
||||
local helper = require("druid.helper")
|
||||
local data = require("druid.data")
|
||||
local const = require("druid.const")
|
||||
local settings = require("druid.settings").scroll
|
||||
|
||||
local M = {}
|
||||
@@ -8,8 +11,8 @@ local SIDE_X = "x"
|
||||
local SIDE_Y = "y"
|
||||
|
||||
M.interest = {
|
||||
data.ON_UPDATE,
|
||||
data.ON_SWIPE,
|
||||
const.ON_UPDATE,
|
||||
const.ON_SWIPE,
|
||||
}
|
||||
|
||||
-- Global on all scrolls
|
||||
@@ -99,10 +102,7 @@ end
|
||||
|
||||
|
||||
local function get_zone_center(self)
|
||||
local pos = vmath.vector3(self.pos)
|
||||
pos.x = pos.x + self.center_offset.x
|
||||
pos.y = pos.y + self.center_offset.y
|
||||
return pos
|
||||
return self.pos + self.center_offset
|
||||
end
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ end
|
||||
|
||||
|
||||
function M.on_input(self, action_id, action)
|
||||
if action_id ~= data.A_TOUCH then
|
||||
if action_id ~= const.ACTION_TOUCH then
|
||||
return false
|
||||
end
|
||||
local inp = self.input
|
||||
@@ -289,18 +289,21 @@ function M.on_input(self, action_id, action)
|
||||
M.current_scroll = self
|
||||
end
|
||||
end
|
||||
if M.current_scroll == self then
|
||||
add_delta(self, action.dx, action.dy)
|
||||
result = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if inp.touch and not action.pressed then
|
||||
if M.current_scroll == self then
|
||||
add_delta(self, action.dx, action.dy)
|
||||
result = true
|
||||
end
|
||||
end
|
||||
|
||||
if action.released then
|
||||
inp.touch = false
|
||||
inp.side = false
|
||||
if M.current_scroll == self then
|
||||
M.current_scroll = nil
|
||||
inp.touch = false
|
||||
inp.side = false
|
||||
result = true
|
||||
end
|
||||
check_threshold(self)
|
||||
@@ -310,8 +313,12 @@ function M.on_input(self, action_id, action)
|
||||
end
|
||||
|
||||
|
||||
--- Start scroll to point (x, y, z)
|
||||
function M.scroll_to(self, point)
|
||||
--- Start scroll to target point
|
||||
-- @tparam point vector3 target point
|
||||
-- @tparam[opt] bool is_instant instant scroll flag
|
||||
-- @usage scroll:scroll_to(vmath.vector3(0, 50, 0))
|
||||
-- @usage scroll:scroll_to(vmath.vector3(0), true)
|
||||
function M.scroll_to(self, point, is_instant)
|
||||
local b = self.border
|
||||
local target = vmath.vector3(point)
|
||||
target.x = helper.clamp(point.x - self.center_offset.x, b.x, b.z)
|
||||
@@ -319,12 +326,18 @@ function M.scroll_to(self, point)
|
||||
|
||||
cancel_animate(self)
|
||||
|
||||
self.animate = true
|
||||
gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function()
|
||||
self.animate = false
|
||||
self.animate = not is_instant
|
||||
|
||||
if is_instant then
|
||||
self.target = target
|
||||
set_pos(self, target)
|
||||
end)
|
||||
else
|
||||
gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function()
|
||||
self.animate = false
|
||||
self.target = target
|
||||
set_pos(self, target)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -384,4 +397,4 @@ function M.set_border(self, border)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
return M
|
||||
|
93
druid/base/slider.lua
Normal file
93
druid/base/slider.lua
Normal file
@@ -0,0 +1,93 @@
|
||||
--- Druid slider component
|
||||
-- @module base.slider
|
||||
|
||||
local helper = require("druid.helper")
|
||||
local const = require("druid.const")
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
const.ON_SWIPE
|
||||
}
|
||||
|
||||
|
||||
local function on_change_value(self)
|
||||
if self.callback then
|
||||
self.callback(self.parent.parent, self.value)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function M.init(self, node, end_pos, callback)
|
||||
self.node = helper.get_node(node)
|
||||
|
||||
self.start_pos = gui.get_position(self.node)
|
||||
self.pos = gui.get_position(self.node)
|
||||
self.target_pos = self.pos
|
||||
self.end_pos = end_pos
|
||||
|
||||
self.dist = self.end_pos - self.start_pos
|
||||
self.is_drag = false
|
||||
self.value = 0
|
||||
self.callback = callback
|
||||
|
||||
assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal")
|
||||
end
|
||||
|
||||
|
||||
function M.on_input(self, action_id, action)
|
||||
if action_id ~= const.ACTION_TOUCH then
|
||||
return false
|
||||
end
|
||||
|
||||
if gui.pick_node(self.node, action.x, action.y) then
|
||||
if action.pressed then
|
||||
self.pos = gui.get_position(self.node)
|
||||
self.is_drag = true
|
||||
end
|
||||
end
|
||||
|
||||
if self.is_drag and not action.pressed then
|
||||
-- move
|
||||
self.pos.x = self.pos.x + action.dx
|
||||
self.pos.y = self.pos.y + action.dy
|
||||
|
||||
local prev_x = self.target_pos.x
|
||||
local prev_y = self.target_pos.y
|
||||
|
||||
self.target_pos.x = helper.clamp(self.pos.x, self.start_pos.x, self.end_pos.x)
|
||||
self.target_pos.y = helper.clamp(self.pos.y, self.start_pos.y, self.end_pos.y)
|
||||
|
||||
gui.set_position(self.node, self.target_pos)
|
||||
|
||||
if prev_x ~= self.target_pos.x or prev_y ~= self.target_pos.y then
|
||||
|
||||
if self.dist.x > 0 then
|
||||
self.value = (self.target_pos.x - self.start_pos.x) / self.dist.x
|
||||
end
|
||||
|
||||
if self.dist.y > 0 then
|
||||
self.value = (self.target_pos.y - self.start_pos.y) / self.dist.y
|
||||
end
|
||||
|
||||
on_change_value(self)
|
||||
end
|
||||
end
|
||||
|
||||
if action.released then
|
||||
self.is_drag = false
|
||||
end
|
||||
|
||||
return self.is_drag
|
||||
end
|
||||
|
||||
|
||||
function M.set(self, value)
|
||||
value = helper.clamp(value, 0, 1)
|
||||
|
||||
gui.set_position(self.node, self.start_pos + self.dist * value)
|
||||
self.value = value
|
||||
on_change_value(self)
|
||||
end
|
||||
|
||||
|
||||
return M
|
@@ -1,10 +1,14 @@
|
||||
local data = require("druid.data")
|
||||
--- Component to handle all GUI texts
|
||||
-- Good working with localization system
|
||||
-- @module base.text
|
||||
|
||||
local const = require("druid.const")
|
||||
local settings = require("druid.settings")
|
||||
local helper = require("druid.helper")
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
data.ON_CHANGE_LANGUAGE,
|
||||
const.ON_CHANGE_LANGUAGE,
|
||||
}
|
||||
|
||||
|
||||
@@ -81,4 +85,4 @@ function M.set_scale(self, scale)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
return M
|
||||
|
@@ -1,14 +1,18 @@
|
||||
local data = require("druid.data")
|
||||
--- Component to handle GUI timers
|
||||
-- @module base.timer
|
||||
|
||||
local const = require("druid.const")
|
||||
local formats = require("druid.helper.formats")
|
||||
local helper = require("druid.helper")
|
||||
|
||||
local M = {}
|
||||
M.interest = {
|
||||
data.ON_UPDATE
|
||||
const.ON_UPDATE
|
||||
}
|
||||
|
||||
local empty = function() end
|
||||
|
||||
|
||||
function M.init(self, node, seconds_from, seconds_to, callback)
|
||||
self.node = helper.get_node(node)
|
||||
seconds_from = math.max(seconds_from, 0)
|
||||
|
@@ -1,31 +1,32 @@
|
||||
--- Druid constants
|
||||
-- @module constants
|
||||
|
||||
local M = {}
|
||||
|
||||
-- actions
|
||||
|
||||
M.A_TOUCH = hash("touch")
|
||||
M.A_TEXT = hash("text")
|
||||
M.A_BACKSPACE = hash("backspace")
|
||||
M.A_ENTER = hash("enter")
|
||||
M.A_ANDR_BACK = hash("back")
|
||||
-- Actions
|
||||
M.ACTION_TOUCH = hash("touch")
|
||||
M.ACTION_TEXT = hash("text")
|
||||
M.ACTION_BACKSPACE = hash("backspace")
|
||||
M.ACTION_ENTER = hash("enter")
|
||||
M.ACTION_BACK = hash("back")
|
||||
|
||||
M.RELEASED = "released"
|
||||
M.PRESSED = "pressed"
|
||||
|
||||
--- interests
|
||||
|
||||
--- Interests
|
||||
M.ON_MESSAGE = hash("on_message")
|
||||
M.ON_UPDATE = hash("on_update")
|
||||
|
||||
-- input
|
||||
-- Input
|
||||
M.ON_SWIPE = hash("on_swipe")
|
||||
M.ON_INPUT = hash("on_input")
|
||||
|
||||
M.ui_input = {
|
||||
[M.ON_SWIPE] = true,
|
||||
[M.ON_INPUT] = true
|
||||
|
||||
}
|
||||
-- ui messages
|
||||
|
||||
-- UI messages
|
||||
M.ON_CHANGE_LANGUAGE = hash("on_change_language")
|
||||
M.ON_LAYOUT_CHANGED = hash("on_layout_changed")
|
||||
|
@@ -1,4 +1,10 @@
|
||||
local data = require("druid.data")
|
||||
--- Druid UI Library.
|
||||
-- Component based UI library to make your life easier.
|
||||
-- Contains a lot of base components and give API
|
||||
-- to create your own rich components.
|
||||
-- @module druid
|
||||
|
||||
local const = require("druid.const")
|
||||
local druid_input = require("druid.helper.druid_input")
|
||||
local settings = require("druid.settings")
|
||||
|
||||
@@ -7,9 +13,11 @@ local M = {}
|
||||
local log = settings.log
|
||||
local _fct_metatable = {}
|
||||
|
||||
--- Basic components
|
||||
M.comps = {
|
||||
button = require("druid.base.button"),
|
||||
android_back = require("druid.base.android_back"),
|
||||
back_handler = require("druid.base.back_handler"),
|
||||
blocker = require("druid.base.blocker"),
|
||||
text = require("druid.base.text"),
|
||||
timer = require("druid.base.timer"),
|
||||
progress = require("druid.base.progress"),
|
||||
@@ -17,6 +25,7 @@ M.comps = {
|
||||
scroll = require("druid.base.scroll"),
|
||||
checkbox = require("druid.base.checkbox"),
|
||||
checkbox_group = require("druid.base.checkbox_group"),
|
||||
slider = require("druid.base.slider"),
|
||||
|
||||
progress_rich = require("druid.rich.progress_rich"),
|
||||
}
|
||||
@@ -33,6 +42,9 @@ local function register_basic_components()
|
||||
end
|
||||
|
||||
|
||||
--- Register external module
|
||||
-- @tparam string name module name
|
||||
-- @tparam table module lua table with module
|
||||
function M.register(name, module)
|
||||
-- TODO: Find better solution to creating elements?
|
||||
_fct_metatable["new_" .. name] = function(self, ...)
|
||||
@@ -78,7 +90,7 @@ local function create(self, module)
|
||||
end
|
||||
self[v][#self[v] + 1] = instance
|
||||
|
||||
if data.ui_input[v] then
|
||||
if const.ui_input[v] then
|
||||
input_init(self)
|
||||
end
|
||||
end
|
||||
@@ -122,7 +134,7 @@ end
|
||||
|
||||
--- Called on_message
|
||||
function _fct_metatable.on_message(self, message_id, message, sender)
|
||||
local specific_ui_message = data.specific_ui_messages[message_id]
|
||||
local specific_ui_message = const.specific_ui_messages[message_id]
|
||||
if specific_ui_message then
|
||||
local array = self[message_id]
|
||||
if array then
|
||||
@@ -133,7 +145,7 @@ function _fct_metatable.on_message(self, message_id, message, sender)
|
||||
end
|
||||
end
|
||||
else
|
||||
local array = self[data.ON_MESSAGE]
|
||||
local array = self[const.ON_MESSAGE]
|
||||
if array then
|
||||
for i = 1, #array do
|
||||
array[i]:on_message(message_id, message, sender)
|
||||
@@ -144,10 +156,10 @@ end
|
||||
|
||||
|
||||
local function notify_input_on_swipe(self)
|
||||
if self[data.ON_INPUT] then
|
||||
local len = #self[data.ON_INPUT]
|
||||
if self[const.ON_INPUT] then
|
||||
local len = #self[const.ON_INPUT]
|
||||
for i = len, 1, -1 do
|
||||
local comp = self[data.ON_INPUT][i]
|
||||
local comp = self[const.ON_INPUT][i]
|
||||
if comp.on_swipe then
|
||||
comp:on_swipe()
|
||||
end
|
||||
@@ -171,7 +183,7 @@ end
|
||||
|
||||
--- Called ON_INPUT
|
||||
function _fct_metatable.on_input(self, action_id, action)
|
||||
local array = self[data.ON_SWIPE]
|
||||
local array = self[const.ON_SWIPE]
|
||||
if array then
|
||||
local v, result
|
||||
local len = #array
|
||||
@@ -184,7 +196,7 @@ function _fct_metatable.on_input(self, action_id, action)
|
||||
return true
|
||||
end
|
||||
end
|
||||
array = self[data.ON_INPUT]
|
||||
array = self[const.ON_INPUT]
|
||||
if array then
|
||||
local v
|
||||
local len = #array
|
||||
@@ -202,7 +214,7 @@ end
|
||||
|
||||
--- Called on_update
|
||||
function _fct_metatable.update(self, dt)
|
||||
local array = self[data.ON_UPDATE]
|
||||
local array = self[const.ON_UPDATE]
|
||||
if array then
|
||||
for i = 1, #array do
|
||||
array[i]:update(dt)
|
||||
@@ -211,4 +223,4 @@ function _fct_metatable.update(self, dt)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
return M
|
||||
|
@@ -1,20 +1,81 @@
|
||||
--- Druid helper module
|
||||
-- @module helper
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.centrate_text_with_icon(text_node, icon_node, offset_x)
|
||||
offset_x = offset_x or 0
|
||||
local metr = gui.get_text_metrics_from_node(text_node)
|
||||
local scl = gui.get_scale(text_node).x
|
||||
local pos = gui.get_position(text_node)
|
||||
local scl_i = gui.get_scale(icon_node).x
|
||||
local pos_i = gui.get_position(icon_node)
|
||||
local w = metr.width * scl -- text width
|
||||
local icon_w = gui.get_size(icon_node).x * scl_i -- icon width
|
||||
local width = w + icon_w
|
||||
--- Text node or icon node can be nil
|
||||
local function get_text_width(text_node)
|
||||
if text_node then
|
||||
local text_metrics = gui.get_text_metrics_from_node(text_node)
|
||||
local text_scale = gui.get_scale(text_node).x
|
||||
return text_metrics.width * text_scale
|
||||
end
|
||||
|
||||
pos.x = -width/2 + w + offset_x
|
||||
gui.set_position(text_node, pos)
|
||||
pos_i.x = width/2 - icon_w + offset_x
|
||||
gui.set_position(icon_node, pos_i)
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
local function get_icon_width(icon_node)
|
||||
if icon_node then
|
||||
local icon_scale_x = gui.get_scale(icon_node).x
|
||||
return gui.get_size(icon_node).x * icon_scale_x -- icon width
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
--- Text node or icon node can be nil
|
||||
function M.centrate_text_with_icon(text_node, icon_node, margin)
|
||||
margin = margin or 0
|
||||
local text_width = get_text_width(text_node)
|
||||
local icon_width = get_icon_width(icon_node)
|
||||
local width = text_width + icon_width
|
||||
|
||||
if text_node then
|
||||
local pos = gui.get_position(text_node)
|
||||
pos.x = -width/2 + text_width - margin/2
|
||||
gui.set_position(text_node, pos)
|
||||
end
|
||||
|
||||
if icon_node then
|
||||
local icon_pos = gui.get_position(icon_node)
|
||||
icon_pos.x = width/2 - icon_width + margin/2
|
||||
gui.set_position(icon_node, icon_pos)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Icon node or text node can be nil
|
||||
function M.centrate_icon_with_text(icon_node, text_node, margin)
|
||||
margin = margin or 0
|
||||
local icon_width = get_icon_width(icon_node)
|
||||
local text_width = get_text_width(text_node)
|
||||
local width = text_width + icon_width
|
||||
|
||||
if text_node then
|
||||
local pos = gui.get_position(text_node)
|
||||
pos.x = width/2 - text_width + margin/2
|
||||
gui.set_position(text_node, pos)
|
||||
end
|
||||
|
||||
if icon_node then
|
||||
local icon_pos = gui.get_position(icon_node)
|
||||
icon_pos.x = -width/2 + icon_width - margin/2
|
||||
gui.set_position(icon_node, icon_pos)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- call callback after count calls
|
||||
function M.after(count, callback)
|
||||
local closure = function()
|
||||
count = count - 1
|
||||
if count <= 0 then
|
||||
callback()
|
||||
end
|
||||
end
|
||||
return closure
|
||||
end
|
||||
|
||||
|
||||
@@ -96,4 +157,5 @@ function M.get_pivot_offset(pivot)
|
||||
return pivots[pivot]
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
return M
|
||||
|
@@ -1,3 +1,6 @@
|
||||
--- Druid helper module for animating GUI nodes
|
||||
-- @module helper.animate
|
||||
|
||||
local M = {}
|
||||
|
||||
local PROP_SCALE = gui.PROP_SCALE
|
||||
|
@@ -1,3 +1,7 @@
|
||||
--- Druid inner module to acquire/release input
|
||||
-- @module helper.input
|
||||
-- @local
|
||||
|
||||
local M = {}
|
||||
|
||||
local ADD_FOCUS = hash("acquire_input_focus")
|
||||
|
@@ -1,10 +1,13 @@
|
||||
--- Druid module with utils on string formats
|
||||
-- @module helper.formats
|
||||
|
||||
local M = {}
|
||||
|
||||
local ZERO = "0"
|
||||
|
||||
-- Return number with zero number prefix
|
||||
-- @param num - number for conversion
|
||||
-- @param count - count of numerals
|
||||
--- Return number with zero number prefix
|
||||
-- @param num number for conversion
|
||||
-- @param count count of numerals
|
||||
-- @return string with need count of zero (1,3) -> 001
|
||||
function M.add_prefix_zeros(num, count)
|
||||
local result = tostring(num)
|
||||
@@ -15,8 +18,8 @@ function M.add_prefix_zeros(num, count)
|
||||
end
|
||||
|
||||
|
||||
-- Convert seconds to string minutes:seconds
|
||||
-- @param num - number of seconds
|
||||
--- Convert seconds to string minutes:seconds
|
||||
-- @param num number of seconds
|
||||
-- @return string minutes:seconds
|
||||
function M.second_string_min(sec)
|
||||
local mins = math.floor(sec / 60)
|
||||
@@ -25,11 +28,11 @@ function M.second_string_min(sec)
|
||||
end
|
||||
|
||||
|
||||
-- Interpolate string with named Parameters in Table
|
||||
-- @param s - string for interpolate
|
||||
-- @param tab - table with parameters
|
||||
--- Interpolate string with named Parameters in Table
|
||||
-- @param s string for interpolate
|
||||
-- @param tab table with parameters
|
||||
-- @return string with replaced parameters
|
||||
function M.interpolate_strinng(s, tab)
|
||||
function M.interpolate_string(s, tab)
|
||||
return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end))
|
||||
end
|
||||
|
||||
|
@@ -1,7 +1,10 @@
|
||||
--- Druid settings file
|
||||
-- @module settings
|
||||
|
||||
local M = {}
|
||||
|
||||
-- TODO: to JSON?
|
||||
M.is_debug = false
|
||||
|
||||
M.button = {
|
||||
IS_HOVER = true,
|
||||
IS_HOLD = true,
|
||||
@@ -33,13 +36,13 @@ M.scroll = {
|
||||
}
|
||||
|
||||
function M.get_text(name)
|
||||
-- override to get text for localized text
|
||||
return "locales not inited"
|
||||
-- override to get text for localized text
|
||||
return "[Druid]: locales not inited"
|
||||
end
|
||||
|
||||
|
||||
function M.play_sound(name)
|
||||
-- override to play sound with name
|
||||
-- override to play sound with name
|
||||
end
|
||||
|
||||
|
||||
@@ -50,4 +53,4 @@ function M.log(...)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
return M
|
||||
|
Reference in New Issue
Block a user