-- Druid helper module for gui layouts -- @module helper local const = require("druid.const") local M = {} --- 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 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 --- Center two nodes. -- Nodes will be center around 0 x position -- text_node will be first (at left side) -- @function helper.centrate_text_with_icon -- @tparam[opt] text text_node Gui text node -- @tparam[opt] box icon_node Gui box node -- @tparam number margin Offset between nodes 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 --- Center two nodes. -- Nodes will be center around 0 x position -- icon_node will be first (at left side) -- @function helper.centrate_icon_with_text -- @tparam[opt] box icon_node Gui box node -- @tparam[opt] text text_node Gui text node -- @tparam[opt=0] number margin Offset between nodes 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 function M.step(current, target, step) if current < target then return math.min(current + step, target) else return math.max(target, current - step) end end function M.clamp(a, min, max) if min > max then min, max = max, min end if a >= min and a <= max then return a elseif a < min then return min else return max end end function M.distance(x1, y1, x2, y2) return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2) end function M.sign(val) if val == 0 then return 0 end return (val < 0) and -1 or 1 end function M.round(num, numDecimalPlaces) local mult = 10^(numDecimalPlaces or 0) return math.floor(num * mult + 0.5) / mult end --- Check if node is enabled in gui hierarchy. -- Return false, if node or any his parent is disabled -- @function helper.is_enabled -- @tparam node node Gui node -- @treturn bool Is enabled in hierarchy function M.is_enabled(node) local is_enabled = gui.is_enabled(node) local parent = gui.get_parent(node) while parent and is_enabled do is_enabled = is_enabled and gui.is_enabled(parent) parent = gui.get_parent(parent) end return is_enabled end --- Get node offset for given gui pivot -- @function helper.get_pivot_offset -- @tparam gui.pivot pivot The node pivot -- @treturn vector3 Vector offset with [-1..1] values function M.get_pivot_offset(pivot) return const.PIVOTS[pivot] end --- Check if device is mobile (Android or iOS) -- @function helper..is_mobile function M.is_mobile() local system_name = sys.get_sys_info().system_name return system_name == const.OS.IOS or system_name == const.OS.ANDROID end --- Check if device is HTML5 -- @function helper.is_web function M.is_web() local system_name = sys.get_sys_info().system_name return system_name == const.OS.BROWSER end function M.get_border(node) local pivot = gui.get_pivot(node) local pivot_offset = M.get_pivot_offset(pivot) local size = vmath.mul_per_elem(gui.get_size(node), gui.get_scale(node)) return vmath.vector4( -size.x*(0.5 - pivot_offset.x), size.y*(0.5 + pivot_offset.y), size.x*(0.5 + pivot_offset.x), -size.y*(0.5 - pivot_offset.y) ) end return M