Update Helper docs

This commit is contained in:
Insality 2023-06-08 00:06:05 +03:00
parent 65974e0b30
commit 7bf479e6c0
6 changed files with 130 additions and 57 deletions

View File

@ -143,7 +143,7 @@ function Scroll.init(self, view_node, content_node)
self.view_border = helper.get_border(self.view_node) self.view_border = helper.get_border(self.view_node)
self.content_node = self:get_node(content_node) self.content_node = self:get_node(content_node)
self.view_size = vmath.mul_per_elem(gui.get_size(self.view_node), gui.get_scale(self.view_node)) self.view_size = helper.get_scaled_size(self.view_node)
self.position = gui.get_position(self.content_node) self.position = gui.get_position(self.content_node)
self.target_position = vmath.vector3(self.position) self.target_position = vmath.vector3(self.position)
@ -693,7 +693,7 @@ end
function Scroll._update_size(self) function Scroll._update_size(self)
local content_border = helper.get_border(self.content_node) local content_border = helper.get_border(self.content_node)
local content_size = vmath.mul_per_elem(gui.get_size(self.content_node), gui.get_scale(self.content_node)) local content_size = helper.get_scaled_size(self.content_node)
self.available_pos = get_border_vector(self.view_border - content_border, self._offset) self.available_pos = get_border_vector(self.view_border - content_border, self._offset)
self.available_size = get_size_vector(self.available_pos) self.available_size = get_size_vector(self.available_pos)

View File

@ -118,7 +118,7 @@ function DynamicGrid.get_pos(self, index, node, origin_index)
assert(not self.first_index, "Dynamic Grid can't have gaps between nodes. Error on grid:add") assert(not self.first_index, "Dynamic Grid can't have gaps between nodes. Error on grid:add")
-- If not origin node, so it should be first element in the grid -- If not origin node, so it should be first element in the grid
local size = self:_get_node_size(node) local size = helper.get_scaled_size(node)
local pivot = const.PIVOTS[gui.get_pivot(node)] local pivot = const.PIVOTS[gui.get_pivot(node)]
return vmath.vector3( return vmath.vector3(
size.x * pivot.x - size.x * self.pivot.x, size.x * pivot.x - size.x * self.pivot.x,
@ -308,7 +308,7 @@ function DynamicGrid._add_node(self, node, index, origin_index)
self.nodes[index] = { self.nodes[index] = {
node = node, node = node,
pos = self:get_pos(index, node, origin_index), pos = self:get_pos(index, node, origin_index),
size = self:_get_node_size(node), size = helper.get_scaled_size(node),
pivot = const.PIVOTS[gui.get_pivot(node)] pivot = const.PIVOTS[gui.get_pivot(node)]
} }
@ -394,7 +394,7 @@ end
function DynamicGrid._get_next_node_pos(self, origin_node_index, new_node, place_side) function DynamicGrid._get_next_node_pos(self, origin_node_index, new_node, place_side)
local node = self.nodes[origin_node_index] local node = self.nodes[origin_node_index]
local new_node_size = self:_get_node_size(new_node) local new_node_size = helper.get_scaled_size(new_node)
local new_pivot = const.PIVOTS[gui.get_pivot(new_node)] local new_pivot = const.PIVOTS[gui.get_pivot(new_node)]
local dist_x = (node.size.x/2 + new_node_size.x/2) * place_side.x local dist_x = (node.size.x/2 + new_node_size.x/2) * place_side.x
@ -410,11 +410,6 @@ function DynamicGrid._get_next_node_pos(self, origin_node_index, new_node, place
end end
function DynamicGrid._get_node_size(self, node)
return vmath.mul_per_elem(gui.get_size(node), gui.get_scale(node))
end
--- Return side vector to correct node shifting --- Return side vector to correct node shifting
function DynamicGrid._get_side_vector(self, side, is_forward) function DynamicGrid._get_side_vector(self, side, is_forward)
if side == const.SIDE.X then if side == const.SIDE.X then

View File

@ -1,6 +1,6 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid helper module for gui layouts --- Helper module with various usefull GUI functions.
-- @module Helper -- @module Helper
-- @alias druid.helper -- @alias druid.helper
@ -9,7 +9,6 @@ local const = require("druid.const")
local M = {} local M = {}
--- Text node or icon node can be nil
local function get_text_width(text_node) local function get_text_width(text_node)
if text_node then if text_node then
local text_metrics = M.get_text_metrics_from_node(text_node) local text_metrics = M.get_text_metrics_from_node(text_node)
@ -31,6 +30,7 @@ local function get_icon_width(icon_node)
end end
--- Text node or icon node can be nil
local function get_width(node) local function get_width(node)
return gui.get_text(node) and get_text_width(node) or get_icon_width(node) return gui.get_text(node) and get_text_width(node) or get_icon_width(node)
end end
@ -43,6 +43,7 @@ end
-- @tparam[opt] text text_node Gui text node -- @tparam[opt] text text_node Gui text node
-- @tparam[opt] box icon_node Gui box node -- @tparam[opt] box icon_node Gui box node
-- @tparam number margin Offset between nodes -- @tparam number margin Offset between nodes
-- @local
function M.centrate_text_with_icon(text_node, icon_node, margin) function M.centrate_text_with_icon(text_node, icon_node, margin)
M.centrate_nodes(margin, text_node, icon_node) M.centrate_nodes(margin, text_node, icon_node)
end end
@ -55,6 +56,7 @@ end
-- @tparam[opt] box icon_node Gui box node -- @tparam[opt] box icon_node Gui box node
-- @tparam[opt] text text_node Gui text node -- @tparam[opt] text text_node Gui text node
-- @tparam[opt=0] number margin Offset between nodes -- @tparam[opt=0] number margin Offset between nodes
-- @local
function M.centrate_icon_with_text(icon_node, text_node, margin) function M.centrate_icon_with_text(icon_node, text_node, margin)
M.centrate_nodes(margin, icon_node, text_node) M.centrate_nodes(margin, icon_node, text_node)
end end
@ -98,6 +100,10 @@ function M.centrate_nodes(margin, ...)
end end
--- Get current screen stretch multiplier for each side
-- @function helper.get_screen_aspect_koef
-- @treturn number stretch_x
-- @treturn number stretch_y
function M.get_screen_aspect_koef() function M.get_screen_aspect_koef()
local window_x, window_y = window.get_size() local window_x, window_y = window.get_size()
local stretch_x = window_x / gui.get_width() local stretch_x = window_x / gui.get_width()
@ -107,6 +113,10 @@ function M.get_screen_aspect_koef()
end end
--- Get current GUI scale for each side
-- @function helper.get_gui_scale
-- @treturn number scale_x
-- @treturn number scale_y
function M.get_gui_scale() function M.get_gui_scale()
local window_x, window_y = window.get_size() local window_x, window_y = window.get_size()
return math.min(window_x / gui.get_width(), return math.min(window_x / gui.get_width(),
@ -114,6 +124,12 @@ function M.get_gui_scale()
end end
--- Move value from current to target value with step amount
-- @function helper.step
-- @tparam number current Current value
-- @tparam number target Target value
-- @tparam number step Step amount
-- @treturn number New value
function M.step(current, target, step) function M.step(current, target, step)
if current < target then if current < target then
return math.min(current + step, target) return math.min(current + step, target)
@ -123,6 +139,12 @@ function M.step(current, target, step)
end end
--- Clamp value between min and max
-- @function helper.clamp
-- @tparam number a Value
-- @tparam number min Min value
-- @tparam number max Max value
-- @treturn number Clamped value
function M.clamp(a, min, max) function M.clamp(a, min, max)
if min > max then if min > max then
min, max = max, min min, max = max, min
@ -138,11 +160,22 @@ function M.clamp(a, min, max)
end end
--- Calculate distance between two points
-- @function helper.distance
-- @tparam number x1 First point x
-- @tparam number y1 First point y
-- @tparam number x2 Second point x
-- @tparam number y2 Second point y
-- @treturn number Distance
function M.distance(x1, y1, x2, y2) function M.distance(x1, y1, x2, y2)
return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2) return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
end end
--- Return sign of value (-1, 0, 1)
-- @function helper.sign
-- @tparam number val Value
-- @treturn number Sign
function M.sign(val) function M.sign(val)
if val == 0 then if val == 0 then
return 0 return 0
@ -152,27 +185,47 @@ function M.sign(val)
end end
function M.round(num, numDecimalPlaces) --- Round number to specified decimal places
local mult = 10^(numDecimalPlaces or 0) -- @function helper.round
-- @tparam number num Number
-- @tparam[opt=0] number num_decimal_places Decimal places
-- @treturn number Rounded number
function M.round(num, num_decimal_places)
local mult = 10^(num_decimal_places or 0)
return math.floor(num * mult + 0.5) / mult return math.floor(num * mult + 0.5) / mult
end end
--- Lerp between two values
-- @function helper.lerp
-- @tparam number a First value
-- @tparam number b Second value
-- @tparam number t Lerp amount
-- @treturn number Lerped value
function M.lerp(a, b, t) function M.lerp(a, b, t)
return a + (b - a) * t return a + (b - a) * t
end end
--- Check if value is in array and return index of it
-- @function helper.contains
-- @tparam table t Array
-- @param value Value
-- @treturn number|nil Index of value or nil
function M.contains(t, value) function M.contains(t, value)
for i = 1, #t do for i = 1, #t do
if t[i] == value then if t[i] == value then
return i return i
end end
end end
return false return nil
end end
--- Make a copy table with all nested tables
-- @function helper.deepcopy
-- @tparam table orig_table Original table
-- @treturn table Copy of original table
function M.deepcopy(orig_table) function M.deepcopy(orig_table)
local orig_type = type(orig_table) local orig_type = type(orig_table)
local copy local copy
@ -188,35 +241,23 @@ function M.deepcopy(orig_table)
end end
--- Get text metric from gui node. Replacement of previous gui.get_text_metrics_from_node function --- Get node size adjusted by scale
-- @tparam Node text_node -- @function helper.get_scaled_size
-- @treturn table {width, height, max_ascent, max_descent} -- @tparam node node GUI node
function M.get_text_metrics_from_node(text_node) -- @treturn vector3 Scaled size
local font_name = gui.get_font(text_node) function M.get_scaled_size(node)
local font = gui.get_font_resource(font_name) return vmath.mul_per_elem(gui.get_size(node), gui.get_scale(node))
return resource.get_text_metrics(font, gui.get_text(text_node), {
width = gui.get_size(text_node).x,
leading = gui.get_leading(text_node),
tracking = gui.get_tracking(text_node),
line_break = gui.get_line_break(text_node),
})
end end
--- Check if node is enabled in gui hierarchy. --- Check if node is enabled in GUI hierarchy.
--
-- Return false, if node or any his parent is disabled -- Return false, if node or any his parent is disabled
-- @function helper.is_enabled -- @function helper.is_enabled
-- @tparam node node Gui node -- @tparam node node GUI node
-- @treturn bool Is enabled in hierarchy -- @treturn bool Is enabled in hierarchy
function M.is_enabled(node) function M.is_enabled(node)
local is_enabled = gui.is_enabled(node) return gui.is_enabled(node, true)
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 end
@ -237,10 +278,10 @@ function M.get_scene_scale(node, include_passed_node_scale)
end end
--- Return closest non inverted clipping parent node for node --- Return closest non inverted clipping parent node for given node
-- @function helper.get_closest_stencil_node -- @function helper.get_closest_stencil_node
-- @tparam node node Gui node -- @tparam node node GUI node
-- @treturn node|nil The clipping node -- @treturn node|nil The closest stencil node or nil
function M.get_closest_stencil_node(node) function M.get_closest_stencil_node(node)
if not node then if not node then
return nil return nil
@ -262,17 +303,20 @@ function M.get_closest_stencil_node(node)
end end
--- Get node offset for given gui pivot --- Get node offset for given GUI pivot.
--
-- Offset shown in [-0.5 .. 0.5] range, where -0.5 is left or bottom, 0.5 is right or top.
-- @function helper.get_pivot_offset -- @function helper.get_pivot_offset
-- @tparam gui.pivot pivot The node pivot -- @tparam gui.pivot pivot The node pivot
-- @treturn vector3 Vector offset with [-1..1] values -- @treturn vector3 Vector offset with [-0.5..0.5] values
function M.get_pivot_offset(pivot) function M.get_pivot_offset(pivot)
return const.PIVOTS[pivot] return const.PIVOTS[pivot]
end end
--- Check if device is mobile (Android or iOS) --- Check if device is native mobile (Android or iOS)
-- @function helper.is_mobile -- @function helper.is_mobile
-- @treturn bool Is mobile
function M.is_mobile() function M.is_mobile()
return const.CURRENT_SYSTEM_NAME == const.OS.IOS or return const.CURRENT_SYSTEM_NAME == const.OS.IOS or
const.CURRENT_SYSTEM_NAME == const.OS.ANDROID const.CURRENT_SYSTEM_NAME == const.OS.ANDROID
@ -281,12 +325,14 @@ end
--- Check if device is HTML5 --- Check if device is HTML5
-- @function helper.is_web -- @function helper.is_web
-- @treturn bool Is web
function M.is_web() function M.is_web()
return const.CURRENT_SYSTEM_NAME == const.OS.BROWSER return const.CURRENT_SYSTEM_NAME == const.OS.BROWSER
end end
--- Transform table to oneline string --- Simple table to one-line string converter
-- @function helper.table_to_string
-- @tparam table t -- @tparam table t
-- @treturn string -- @treturn string
function M.table_to_string(t) function M.table_to_string(t)
@ -309,13 +355,13 @@ end
--- Distance from node position to his borders --- Distance from node position to his borders
-- @function helper.get_border -- @function helper.get_border
-- @tparam node node The gui node to check -- @tparam node node GUI node
-- @tparam vector3 offset The offset to add to result -- @tparam[opt] vector3 offset Offset from node position. Pass current node position to get non relative border values
-- @return vector4 Vector with distance to node border: (left, top, right, down) -- @treturn vector4 Vector4 with border values (left, top, right, down)
function M.get_border(node, offset) function M.get_border(node, offset)
local pivot = gui.get_pivot(node) local pivot = gui.get_pivot(node)
local pivot_offset = M.get_pivot_offset(pivot) local pivot_offset = M.get_pivot_offset(pivot)
local size = vmath.mul_per_elem(gui.get_size(node), gui.get_scale(node)) local size = M.get_scaled_size(node)
local border = vmath.vector4( local border = vmath.vector4(
-size.x*(0.5 + pivot_offset.x), -size.x*(0.5 + pivot_offset.x),
size.y*(0.5 - pivot_offset.y), size.y*(0.5 - pivot_offset.y),
@ -334,9 +380,10 @@ function M.get_border(node, offset)
end end
--- Get text metric from gui node. Replacement of previous gui.get_text_metrics_from_node function --- Get text metric from GUI node.
-- @function helper.get_text_metrics_from_node
-- @tparam Node text_node -- @tparam Node text_node
-- @treturn table {width, height, max_ascent, max_descent} -- @treturn GUITextMetrics Fields: width, height, max_ascent, max_descent
function M.get_text_metrics_from_node(text_node) function M.get_text_metrics_from_node(text_node)
local font_resource = gui.get_font_resource(gui.get_font(text_node)) local font_resource = gui.get_font_resource(gui.get_font(text_node))
local options = { local options = {
@ -354,6 +401,15 @@ function M.get_text_metrics_from_node(text_node)
end end
--- Add value to array with shift policy
--
-- Shift policy can be: left, right, no_shift
-- @function helper.insert_with_shift
-- @tparam table array Array
-- @param item Item to insert
-- @tparam[opt] number index Index to insert. If nil, item will be inserted at the end of array
-- @tparam[opt] const.SHIFT shift_policy Shift policy
-- @treturn item Inserted item
function M.insert_with_shift(array, item, index, shift_policy) function M.insert_with_shift(array, item, index, shift_policy)
shift_policy = shift_policy or const.SHIFT.RIGHT shift_policy = shift_policy or const.SHIFT.RIGHT
@ -377,6 +433,14 @@ function M.insert_with_shift(array, item, index, shift_policy)
end end
--- Remove value from array with shift policy
--
-- Shift policy can be: left, right, no_shift
-- @function helper.remove_with_shift
-- @tparam table array Array
-- @tparam[opt] number index Index to remove. If nil, item will be removed from the end of array
-- @tparam[opt] const.SHIFT shift_policy Shift policy
-- @treturn item Removed item
function M.remove_with_shift(array, index, shift_policy) function M.remove_with_shift(array, index, shift_policy)
shift_policy = shift_policy or const.SHIFT.RIGHT shift_policy = shift_policy or const.SHIFT.RIGHT
@ -404,6 +468,7 @@ end
--- Show deprecated message. Once time per message --- Show deprecated message. Once time per message
-- @function helper.deprecated -- @function helper.deprecated
-- @tparam string message The deprecated message -- @tparam string message The deprecated message
-- @local
local _deprecated_messages = {} local _deprecated_messages = {}
function M.deprecated(message) function M.deprecated(message)
if _deprecated_messages[message] then if _deprecated_messages[message] then
@ -415,7 +480,8 @@ function M.deprecated(message)
end end
-- Show message to require extended component --- Show message to require extended component
-- @local
function M.extended_component(component_name) function M.extended_component(component_name)
print(string.format("[Druid]: The component %s is extended component. You have to register it via druid.register to use it", component_name)) print(string.format("[Druid]: The component %s is extended component. You have to register it via druid.register to use it", component_name))
print("[Druid]: Use next code:") print("[Druid]: Use next code:")

View File

@ -16,7 +16,7 @@
-- --
-- @{BaseComponent} - The parent class of all Druid components. You can find all default component methods there. -- @{BaseComponent} - The parent class of all Druid components. You can find all default component methods there.
-- --
-- Other important information: -- # Tech Info #
-- --
-- • To use Druid, you need to create a Druid instance first. This instance is used to spawn components. -- • To use Druid, you need to create a Druid instance first. This instance is used to spawn components.
-- --
@ -253,7 +253,7 @@ function DruidInstance.initialize(self, context, style)
end end
--- Create new component --- Create new component.
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam Component component Component module -- @tparam Component component Component module
-- @tparam args ... Other component params to pass it to component:init function -- @tparam args ... Other component params to pass it to component:init function
@ -271,8 +271,7 @@ function DruidInstance.new(self, component, ...)
end end
--- Call on final function on gui_script. It will call on_remove --- Call this in gui_script final function.
-- on all druid components
-- @tparam DruidInstance self -- @tparam DruidInstance self
function DruidInstance.final(self) function DruidInstance.final(self)
local components = self.components_all local components = self.components_all
@ -289,7 +288,8 @@ function DruidInstance.final(self)
end end
--- Remove component from druid instance. --- Remove component from Druid instance.
--
-- Component `on_remove` function will be invoked, if exist. -- Component `on_remove` function will be invoked, if exist.
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam Component component Component instance -- @tparam Component component Component instance
@ -333,7 +333,7 @@ function DruidInstance.remove(self, component)
end end
--- Druid late update function called after initialization and before the regular update step --- Druid late update function called after initialization and before the regular update step
-- This function is used to check the GUI state and perform actions after all components and nodes have been created. -- This function is used to check the GUI state and perform actions after all components and nodes have been created.
-- An example use case is performing an auto stencil check in the GUI hierarchy for input components. -- An example use case is performing an auto stencil check in the GUI hierarchy for input components.
-- @tparam DruidInstance self -- @tparam DruidInstance self
@ -353,6 +353,7 @@ end
--- Call this in gui_script update function. --- Call this in gui_script update function.
--
-- Used for: scroll, progress, timer components -- Used for: scroll, progress, timer components
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam number dt Delta time -- @tparam number dt Delta time
@ -370,6 +371,7 @@ end
--- Call this in gui_script on_input function. --- Call this in gui_script on_input function.
--
-- Used for almost all components -- Used for almost all components
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam hash action_id Action_id from on_input -- @tparam hash action_id Action_id from on_input
@ -390,6 +392,7 @@ end
--- Call this in gui_script on_message function. --- Call this in gui_script on_message function.
--
-- Used for special actions. See SPECIFIC_UI_MESSAGES table -- Used for special actions. See SPECIFIC_UI_MESSAGES table
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam hash message_id Message_id from on_message -- @tparam hash message_id Message_id from on_message

View File

@ -13,4 +13,5 @@ echo "Update EmmyLua annotations"
original_path=$(pwd) original_path=$(pwd)
bash $emmylua_generator_path/export.sh $original_path bash $emmylua_generator_path/export.sh $original_path
mv $emmylua_generator_path/annotations.lua $original_path/druid/annotations.lua mv $emmylua_generator_path/annotations.lua $original_path/druid/annotations.lua
cat ./utils/annotations_manual.lua >> $original_path/druid/annotations.lua
cp $original_path/utils/ldoc_fixed.css $original_path/docs/ldoc_fixed.css cp $original_path/utils/ldoc_fixed.css $original_path/docs/ldoc_fixed.css

View File

@ -1,3 +1,5 @@
-- Manual Annotations --
---@class druid.rich_text.metrics ---@class druid.rich_text.metrics
---@field width number ---@field width number
---@field height number ---@field height number
@ -49,3 +51,9 @@
---@field default_animation string ---@field default_animation string
---@field node_prefab Node ---@field node_prefab Node
---@field text_prefab Node ---@field text_prefab Node
---@class GUITextMetrics
---@field width number
---@field height number
---@field max_ascent number
---@field max_descent number