diff --git a/druid/base/grid.lua b/druid/base/grid.lua new file mode 100644 index 0000000..485b15f --- /dev/null +++ b/druid/base/grid.lua @@ -0,0 +1,86 @@ +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(instance, parent, element, in_row) + instance.parent = helper.get_node(parent) + instance.nodes = {} + + instance.offset = vmath.vector3(0) + instance.anchor = vmath.vector3(0) + instance.in_row = in_row or 1 + instance.node_size = gui.get_size(helper.get_node(element)) + instance.border = vmath.vector4(0) +end + + +local function check_border(instance, pos) + local size = instance.node_size + local W = pos.x - size.x/2 + local E = pos.x + size.x/2 + local N = pos.y + size.y/2 + local S = pos.y - size.y/2 + + instance.border.x = math.min(instance.border.x, W) + instance.border.y = math.max(instance.border.y, N) + instance.border.z = math.max(instance.border.z, E) + instance.border.w = math.min(instance.border.w, S) +end + + +local temp_pos = vmath.vector3(0) +local function get_pos(instance, index) + local row = math.ceil(index / instance.in_row) - 1 + local col = (index - row * instance.in_row) - 1 + + temp_pos.x = col * (instance.node_size.x + instance.offset.x) + temp_pos.x = temp_pos.x + (0.5 - instance.anchor.x) * instance.node_size.x + temp_pos.y = -row * (instance.node_size.y + instance.offset.y) + temp_pos.y = temp_pos.y - (0.5 - instance.anchor.y) * instance.node_size.y + + return temp_pos +end + + +local function update_pos(instance) + for i = 1, #instance.nodes do + local node = instance.nodes[i] + gui.set_position(node, get_pos(instance, i)) + end +end + + +function M.set_offset(instance, offset) + instance.offset = offset + update_pos(instance) +end + + +function M.set_anchor(instance, anchor) + instance.anchor = anchor + update_pos(instance) +end + + +function M.add(instance, item, index) + index = index or (#instance.nodes + 1) + table.insert(instance.nodes, index, item) + gui.set_parent(item, instance.parent) + + local pos = get_pos(instance, index) + check_border(instance, pos) + gui.set_position(item, pos) +end + + +function M.get_size(instance) + return instance.border +end + + +return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index b85147e..98a1338 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -13,6 +13,7 @@ M.comps = { text = require("druid.base.text"), timer = require("druid.base.timer"), progress = require("druid.base.progress"), + grid = require("druid.base.grid"), progress_rich = require("druid.rich.progress_rich"), } diff --git a/example/example.gui b/example/example.gui index 5669836..4c938ae 100644 --- a/example/example.gui +++ b/example/example.gui @@ -1380,6 +1380,281 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: 1200.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: 1.0 + y: 1.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: "gui/empty" + id: "grids" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "center" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 5.0 + y: -591.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: 80.0 + y: 80.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.0 + y: 0.0 + z: 1.0 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "" + id: "prefab" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "grids" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: -291.0 + y: 292.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: 1.0 + y: 1.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: "gui/empty" + id: "grid_1" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "grids" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 167.0 + y: 97.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: 1.0 + y: 1.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: "gui/empty" + id: "grid_2" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "grids" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: -277.0 + y: -216.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: 1.0 + y: 1.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: "gui/empty" + id: "grid_3" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "grids" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_AUTO +} material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_PARENT max_nodes: 512 diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 1b4bc7a..e8ff623 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -7,7 +7,7 @@ local lang = { local start_x = 300 local page_width = 600 local cur_page = 1 -local max_page = 2 +local max_page = 3 @@ -73,11 +73,10 @@ local function init_progress(self) vert:to(val) end) - local rich = self.druid:new_progress_rich("rich_fill", "rich_red", "rich_green", "x") rich:set_to(0.3) - + local rich_val = 0.3 self.druid:new_button("rich_add", function() rich_val = rich_val + 0.1 @@ -90,6 +89,45 @@ local function init_progress(self) end +local function init_grid(self) + local prefab = gui.get_node("prefab") + + -- 4 items per row + local grid = self.druid:new_grid("grid_1", prefab, 4) + grid:set_offset(vmath.vector3(2, 2, 0)) + for i = 1, 16 do + local node = gui.clone(prefab) + grid:add(node) + end + + local val = 0 + timer.delay(0.1, true, function() + val = val + 0.5 + grid:set_offset(vmath.vector3(val)) + if val > 4 then + val = 0 + end + end) + + + -- 1 item per row + local grid2 = self.druid:new_grid("grid_2", prefab, 1) + grid2:set_offset(vmath.vector3(0, 10, 0)) + for i = 1, 4 do + local node = gui.clone(prefab) + grid2:add(node) + end + + + local grid3 = self.druid:new_grid("grid_3", prefab, 10) + grid3:set_offset(vmath.vector3(5, 0, 0)) + for i = 1, 4 do + local node = gui.clone(prefab) + grid3:add(node) + end +end + + function init(self) setup_druid(self) self.druid = druid.new(self) @@ -97,6 +135,7 @@ function init(self) init_pages(self) init_buttons(self) init_progress(self) + init_grid(self) self.druid:new_android_back(log, "some") end