Skip to content

Commit

Permalink
Fix scroll events while animating
Browse files Browse the repository at this point in the history
Fix slider issue with negative distance
Add bunch of new functions to grid
More accurate progress bar scaling with 9-slice images
  • Loading branch information
Insality committed Sep 10, 2024
1 parent 986a469 commit d533e5e
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 17 deletions.
6 changes: 3 additions & 3 deletions druid/base/hover.lua
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ function Hover:_set_cursor(priority, cursor)
local priority = nil
local cursor_to_set = nil
for _, stack in pairs(cursor_stack) do
for priority, _ in pairs(stack) do
if priority > (priority or 0) then
priority = priority
for pr, _ in pairs(stack) do
if pr > (priority or 0) then
priority = pr
cursor_to_set = stack[priority]
end
end
Expand Down
10 changes: 9 additions & 1 deletion druid/base/scroll.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
-- @tfield node content_node

--- Flag, if scroll now moving by inertion
-- @tfield bool _is_inert
-- @tfield boolean _is_inert

--- Current inert speed
-- @tfield vector3 inertion
Expand Down Expand Up @@ -704,6 +704,10 @@ end


function Scroll._update_free_scroll(self, dt)
if self.is_animate then
return
end

local target = self.target_position

if self._is_inert and (self.inertion.x ~= 0 or self.inertion.y ~= 0) then
Expand All @@ -725,6 +729,10 @@ end


function Scroll._update_hand_scroll(self, dt)
if self.is_animate then
self:_cancel_animate()
end

local dx = self.target_position.x - self.position.x
local dy = self.target_position.y - self.position.y

Expand Down
46 changes: 46 additions & 0 deletions druid/base/static_grid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,23 @@ function StaticGrid.add(self, item, index, shift_policy, is_instant)
end


--- Set new items to the grid. All previous items will be removed
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam node[] nodes The new grid nodes
-- @tparam[opt=false] boolean is_instant If true, update node positions instantly
function StaticGrid.set_items(self, nodes, is_instant)
self.nodes = nodes
for index = 1, #nodes do
local item = nodes[index]
gui.set_parent(item, self.parent)
end

self:_update(is_instant)

self.on_change_items:trigger(self:get_context())
end


--- Remove the item from the grid. Note that gui node will be not deleted
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam number index The grid node index to remove
Expand Down Expand Up @@ -382,6 +399,35 @@ function StaticGrid.set_in_row(self, in_row)
end


--- Set new node size for grid
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam[opt] number width The new node width
-- @tparam[opt] number height The new node height
-- @treturn druid.static_grid Current grid instance
function StaticGrid.set_item_size(self, width, height)
if width then
self.node_size.x = width
end
if height then
self.node_size.y = height
end
self:_update()
self.on_change_items:trigger(self:get_context())

return self
end


--- Sort grid nodes by custom comparator function
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam function comparator The comparator function. (a, b) -> boolean
-- @treturn druid.static_grid Current grid instance
function StaticGrid.sort_nodes(self, comparator)
table.sort(self.nodes, comparator)
self:_update(true)
end


--- Update grid inner state
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback
Expand Down
40 changes: 30 additions & 10 deletions druid/extended/progress.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,29 @@ end

local function set_bar_to(self, set_to, is_silent)
local prev_value = self.last_value
local other_side = self.key == const.SIDE.X and const.SIDE.Y or const.SIDE.X
self.last_value = set_to

local total_width = set_to * self.max_size
local total_width = set_to * self.max_size[self.key]

local scale = math.min(total_width / self.slice_size, 1)
local size = math.max(total_width, self.slice_size)
local scale = 1
if self.slice_size[self.key] > 0 then
scale = math.min(total_width / self.slice_size[self.key], 1)
end
local size = math.max(total_width, self.slice_size[self.key])

do -- Scale other side
-- Decrease other side of progress bar to match the oppotize slice_size
local minimal_size = self.size[other_side] - self.slice_size[other_side]
local maximum_size = self.size[other_side]
local scale_diff = (maximum_size - minimal_size) / maximum_size
local other_scale = 1 - (scale_diff * (1 - scale))
self.scale[other_side] = other_scale
end

self.scale[self.key] = scale
gui.set_scale(self.node, self.scale)

self.size[self.key] = size
gui.set_size(self.node, self.size)

Expand Down Expand Up @@ -125,15 +139,15 @@ function Progress.init(self, node, key, init_value)
self.node = self:get_node(node)
self.scale = gui.get_scale(self.node)
self.size = gui.get_size(self.node)
self.max_size = self.size[self.key]
self.max_size = gui.get_size(self.node)
self.slice = gui.get_slice9(self.node)
self.last_value = self._init_value

if self.key == const.SIDE.X then
self.slice_size = self.slice.x + self.slice.z
else
self.slice_size = self.slice.y + self.slice.w
end
self.slice_size = vmath.vector3(
self.slice.x + self.slice.z,
self.slice.y + self.slice.w,
0
)

self.on_change = Event()

Expand All @@ -146,6 +160,12 @@ function Progress.on_layout_change(self)
end


function Progress.on_remove(self)
-- Return default size
gui.set_size(self.node, self.max_size)
end


function Progress.update(self, dt)
if self.target then
local prev_value = self.last_value
Expand Down Expand Up @@ -231,7 +251,7 @@ end
-- @tparam vector3 max_size The new node maximum (full) size
-- @treturn Progress @{Progress}
function Progress.set_max_size(self, max_size)
self.max_size = max_size[self.key]
self.max_size[self.key] = max_size[self.key]
self:set_to(self.last_value)
return self
end
Expand Down
27 changes: 24 additions & 3 deletions druid/extended/slider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
-- @tfield vector3 end_pos

--- Length between start and end position
-- @tfield number dist
-- @tfield vector3 dist

--- Current drag state
-- @tfield boolean is_drag
Expand Down Expand Up @@ -68,6 +68,7 @@ function Slider.init(self, node, end_pos, callback)
self.pos = gui.get_position(self.node)
self.target_pos = vmath.vector3(self.pos)
self.end_pos = end_pos
self._is_enabled = true

self.dist = self.end_pos - self.start_pos
self.is_drag = false
Expand Down Expand Up @@ -104,6 +105,10 @@ function Slider.on_input(self, action_id, action)
return false
end

if not self._is_enabled or not gui.is_enabled(self.node, true) 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)
Expand Down Expand Up @@ -138,11 +143,11 @@ function Slider.on_input(self, action_id, action)
if prev_x ~= self.target_pos.x or prev_y ~= self.target_pos.y then
local prev_value = self.value

if self.dist.x > 0 then
if math.abs(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
if math.abs(self.dist.y) > 0 then
self.value = (self.target_pos.y - self.start_pos.y) / self.dist.y
end

Expand Down Expand Up @@ -216,4 +221,20 @@ function Slider.set_input_node(self, input_node)
end


--- Set Slider input enabled or disabled
-- @tparam Slider self @{Slider}
-- @tparam boolean is_enabled
function Slider.set_enabled(self, is_enabled)
self._is_enabled = is_enabled
end


--- Check if Slider component is enabled
-- @tparam Slider self @{Slider}
-- @treturn boolean
function Slider.is_enabled(self)
return self._is_enabled
end


return Slider
19 changes: 19 additions & 0 deletions druid/helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,25 @@ function M.is_web()
end


--- Check if device is HTML5 mobile
-- @function helper.is_web_mobile
-- @treturn boolean Is web mobile
function M.is_web_mobile()
if html5 then
return html5.run("(typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);") == "true"
end
return false
end


--- Check if device is mobile and can support multitouch
-- @function helper.is_multitouch_supported
-- @treturn boolean Is multitouch supported
function M.is_multitouch_supported()
return M.is_mobile() or M.is_web_mobile()
end


--- Simple table to one-line string converter
-- @function helper.table_to_string
-- @tparam table t
Expand Down

0 comments on commit d533e5e

Please sign in to comment.