diff --git a/druid/base/hover.lua b/druid/base/hover.lua index cd147f7..97758c3 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -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 diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 4d22d9b..fa99ce1 100755 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -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 @@ -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 @@ -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 diff --git a/druid/base/static_grid.lua b/druid/base/static_grid.lua index 02b3f2a..e66813c 100644 --- a/druid/base/static_grid.lua +++ b/druid/base/static_grid.lua @@ -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 @@ -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 diff --git a/druid/extended/progress.lua b/druid/extended/progress.lua index 2689057..163b017 100644 --- a/druid/extended/progress.lua +++ b/druid/extended/progress.lua @@ -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) @@ -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() @@ -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 @@ -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 diff --git a/druid/extended/slider.lua b/druid/extended/slider.lua index e050df1..22bd4e4 100644 --- a/druid/extended/slider.lua +++ b/druid/extended/slider.lua @@ -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 @@ -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 @@ -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) @@ -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 @@ -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 diff --git a/druid/helper.lua b/druid/helper.lua index 9ed9420..827e9cf 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -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