diff --git a/druid/base/static_grid.lua b/druid/base/static_grid.lua index 0e39fe8..3056e9d 100644 --- a/druid/base/static_grid.lua +++ b/druid/base/static_grid.lua @@ -6,6 +6,7 @@ -- @table Events -- @tfield druid_event on_add_item On item add callback -- @tfield druid_event on_remove_item On item remove callback +-- @tfield druid_event on_change_items On item add or remove callback -- @tfield druid_event on_clear On grid clear callback -- @tfield druid_event on_update_positions On update item positions callback @@ -41,6 +42,9 @@ function M.init(self, parent, element, in_row) local pivot = helper.get_pivot_offset(gui.get_pivot(self.parent)) self.anchor = vmath.vector3(0.5 + pivot.x, 0.5 - pivot.y, 0) + self.first_index = nil + self.last_index = nil + self.in_row = in_row or 1 local node = self:get_node(element) self.node_size = gui.get_size(node) @@ -51,6 +55,7 @@ function M.init(self, parent, element, in_row) self.on_add_item = Event() self.on_remove_item = Event() + self.on_change_items = Event() self.on_clear = Event() self.on_update_positions = Event() @@ -58,6 +63,19 @@ function M.init(self, parent, element, in_row) end +local function _update_indexes(self) + self.first_index = nil + self.last_index = nil + for index in pairs(self.nodes) do + self.first_index = self.first_index or index + self.last_index = self.last_index or index + + self.first_index = math.min(self.first_index, index) + self.last_index = math.max(self.last_index, index) + end +end + + local function _update_border(self, pos, border) local size = self.node_size local pivot = self.node_pivot @@ -131,6 +149,21 @@ function M.get_index(self, pos) end +--- Return grid index by node +-- @function static_grid:get_index_by_node +-- @tparam node node The gui node in the grid +-- @treturn number The node index +function M.get_index_by_node(self, node) + for index, grid_node in pairs(self.nodes) do + if node == grid_node then + return index + end + end + + return nil +end + + function M.on_layout_change(self) update_pos(self, true) end @@ -159,30 +192,46 @@ end -- @tparam node item Gui node -- @tparam[opt] number index The item position. By default add as last item function M.add(self, item, index) - index = index or (#self.nodes + 1) + index = index or ((self.last_index or 0) + 1) + + if self.nodes[index] then + -- Move nodes to right + for i = self.last_index, index, -1 do + self.nodes[i + 1] = self.nodes[i] + end + end self.nodes[index] = item gui.set_parent(item, self.parent) local pos = self:get_pos(index) + -- Add new item instantly in new pos + gui.set_position(item, pos) + for i, _ in pairs(self.nodes) do update_border_offset(self, self:get_pos(i)) end - - -- Add new item instantly in new pos - gui.set_position(item, pos) update_pos(self) + _update_indexes(self) + self.on_add_item:trigger(self:get_context(), item, index) + self.on_change_items:trigger(self:get_context(), index) end -function M:remove(index) +function M:remove(index, is_shift_nodes) assert(self.nodes[index], "No grid item at given index " .. index) self.nodes[index] = nil + if is_shift_nodes then + for i = index, self.last_index do + self.nodes[i] = self.nodes[i + 1] + end + end + -- Recalculate borders self.border = vmath.vector4(0) update_border_offset(self, self:get_pos(1)) @@ -192,6 +241,10 @@ function M:remove(index) end update_pos(self) + _update_indexes(self) + + self.on_add_item:trigger(self:get_context(), index) + self.on_change_items:trigger(self:get_context(), index) end @@ -250,6 +303,7 @@ function M.clear(self) self.border.z = 0 self.nodes = {} + _update_indexes(self) end diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 9106251..e9b163b 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -151,24 +151,7 @@ end -- @function druid:create -- @tparam Component component Component module -- @tparam args ... Other component params to pass it to component:init function --- @deprecated -function Druid:create(component, ...) - helper.deprecated("The druid:create is deprecated. Please use druid:new instead") - local instance = create(self, component) - - if instance.init then - instance:init(...) - end - - return instance -end - - ---- Create new druid component --- @function druid:new --- @tparam Component component Component module --- @tparam args ... Other component params to pass it to component:init function -function Druid.new(self, component, ...) +function Druid.create(self, component, ...) local instance = create(self, component) if instance.init then diff --git a/example/gui/main/main.gui b/example/gui/main/main.gui index ba77057..c019288 100644 --- a/example/gui/main/main.gui +++ b/example/gui/main/main.gui @@ -10392,8 +10392,8 @@ nodes { } nodes { position { - x: 0.0 - y: 0.0 + x: 1.0 + y: 2.0 z: 0.0 w: 1.0 } @@ -10423,7 +10423,7 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "1" + text: "X" font: "game" id: "grid_nodes_text" xanchor: XANCHOR_NONE diff --git a/example/page/grid_page.lua b/example/page/grid_page.lua index b5330cf..7459879 100644 --- a/example/page/grid_page.lua +++ b/example/page/grid_page.lua @@ -1,23 +1,28 @@ local M = {} +local function remove_node(self, button) + gui.delete_node(button.node) + + self.druid:remove(button) + local index = self.grid_nodes:get_index_by_node(button.node) + self.grid_nodes:remove(index, true) + for i = 1, #self.grid_node_buttons do + if self.grid_node_buttons[i] == button then + table.remove(self.grid_node_buttons, i) + break + end + end +end + + local function add_node(self) local prefab = gui.get_node("grid_nodes_prefab") local cloned = gui.clone_tree(prefab) gui.set_enabled(cloned["grid_nodes_prefab"], true) - local index = #self.grid_nodes.nodes + 1 - gui.set_text(cloned["grid_nodes_text"], index) local button = self.druid:new_button(cloned["grid_nodes_prefab"], function(_, params, button) - gui.delete_node(button.node) - self.druid:remove(button) - self.grid_nodes:remove(index) - for i = 1, #self.grid_node_buttons do - if self.grid_node_buttons[i] == button then - table.remove(self.grid_node_buttons, i) - break - end - end + remove_node(self, button) end) table.insert(self.grid_node_buttons, button) @@ -40,11 +45,6 @@ local function clear_nodes(self) end -local function remove_node(self) - -- Remove is not implemented yet -end - - function M.setup_page(self) self.grid_nodes = self.druid:new_static_grid("grid_nodes", "grid_nodes_prefab", 5) self.grid_nodes:set_position_function(function(node, pos)