From c894c16ed9d0146132bdb94a3c31ce373dcf022f Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 00:45:56 +0300 Subject: [PATCH 001/136] remove components from main factory --- druid/base/android_back.lua | 11 ++ druid/base/button.lua | 139 +++++++++++++++++ druid/base/text.lua | 42 +++++ druid/base/timer.lua | 53 +++++++ druid/druid.lua | 296 ------------------------------------ example/example.gui | 121 +++++++++++++++ game.project | 4 +- 7 files changed, 368 insertions(+), 298 deletions(-) create mode 100644 druid/base/android_back.lua create mode 100644 druid/base/button.lua create mode 100644 druid/base/text.lua create mode 100644 druid/base/timer.lua diff --git a/druid/base/android_back.lua b/druid/base/android_back.lua new file mode 100644 index 0000000..a237675 --- /dev/null +++ b/druid/base/android_back.lua @@ -0,0 +1,11 @@ +local M = {} + +--- input handler +-- @param action_id - input action id +-- @param action - input action +function M.on_input(instance, action_id, action) + instance.callback(instance.parent.parent) + return true +end + +return M diff --git a/druid/base/button.lua b/druid/base/button.lua new file mode 100644 index 0000000..9b3b722 --- /dev/null +++ b/druid/base/button.lua @@ -0,0 +1,139 @@ +local data = require("druid.data") +local ui_animate = require "druid.help_modules.druid_animate" + +local M = {} +M.interest = { + data.ON_INPUT +} + +M.DEFAULT_SCALE_CHANGE = vmath.vector3(-0.05, - 0.1, 1) +M.DEFAULT_POS_CHANGE = vmath.vector3(0, - 10, 0) +M.DEFAULT_MOVE_SPEED = 5 +M.DEFAULT_ALPHA_DOWN = 0.8 +M.DEFAULT_TIME_ANIM = 0.1 +M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) +M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1) +M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) +M.DEFAUL_ACTIVATION_TIME = 0.2 + + +function M.init(instance, callback, event, action, animate_node_name, sound) + instance.event = event or data.A_TOUCH + instance.action = action or data.RELEASED + instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node + instance.scale_from = gui.get_scale(instance.anim_node) + instance.scale_to = instance.scale_from + M.DEFAULT_SCALE_CHANGE + instance.pos = gui.get_position(instance.anim_node) + instance.callback = callback + -- instance.params = params + instance.tap_anim = M.tap_scale_animation + instance.back_anim = M.back_scale_animation + -- instance.sound = sound or M.BTN_SOUND_FUNC + -- instance.sound_disable = sound_disable or M.BTN_SOUND_DISABLE_FUNC +end + +--- Set text to text field +-- @param action_id - input action id +-- @param action - input action +function M.on_input(instance, action_id, action) + if gui.is_enabled(instance.node) and gui.pick_node(instance.node, action.x, action.y) then + if not instance.disabled then + instance.tap_anim(instance) + return true + else + -- instance.sound_disable() + return false + end + end + return false +end + +function M.tap_scale_animation(instance) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, + function() + if instance.back_anim then + instance.back_anim(instance) + end + -- instance.sound() + instance.callback(instance.parent.parent, instance.params, instance) + end + ) +end + +function M.back_scale_animation(instance) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) +end + +function M.tap_tab_animation(instance, force) + ui_animate.alpha(instance, instance.anim_node, M.DEFAULT_ALPHA_DOWN, nil, M.DEFAULT_TIME_ANIM) + ui_animate.fly_to(instance, instance.anim_node, instance.pos + M.DEFAULT_POS_CHANGE, M.DEFAULT_MOVE_SPEED) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, + function() + if instance.back_anim then + instance.back_anim(instance) + end + instance.callback(instance.parent.parent, instance.params, force) + end + ) +end + +function M.back_tab_animation(instance) + ui_animate.alpha(instance, instance.anim_node, 1, nil, M.DEFAULT_TIME_ANIM) + ui_animate.fly_to(instance, instance.anim_node, instance.pos, M.DEFAULT_MOVE_SPEED) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) +end + +function M.deactivate(instance, is_animate, callback) + instance.disabled = true + if is_animate then + local counter = 0 + local clbk = function() + counter = counter + 1 + if counter == 3 and callback then + callback(instance.parent.parent) + end + end + ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, + gui.EASING_OUTBOUNCE) + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + else + gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) + gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) + if callback then + callback(instance.parent.parent) + end + end +end + +function M.activate(instance, is_animate, callback) + if is_animate then + local counter = 0 + local clbk = function() + counter = counter + 1 + if counter == 3 then + instance.disabled = false + if callback then + callback(instance.parent.parent) + end + end + end + ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, + gui.EASING_OUTBOUNCE) + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + else + gui.set_color(instance.node, ui_animate.TINT_SHOW) + gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) + instance.disabled = false + if callback then + callback(instance.parent.parent) + end + end +end + +return M diff --git a/druid/base/text.lua b/druid/base/text.lua new file mode 100644 index 0000000..fbc6eb1 --- /dev/null +++ b/druid/base/text.lua @@ -0,0 +1,42 @@ +local M = {} + +local ui_animate = require "druid.help_modules.druid_animate" + +--- Bounce text field +function M.bounce(instance, callback) + gui.set_scale(instance.node, instance.scale_from) + ui_animate.bounce(nil, instance.node, instance.scale_to, callback) +end + +--- Set text to text field +-- @param set_to - set value to text field +function M.set_to(instance, set_to) + instance.last_value = set_to + gui.set_text(instance.node, set_to) +end + +--- Set color +-- @param color +function M.set_color(instance, color) + instance.last_color = color + gui.set_color(instance.node, color) +end + +--- Set scale +-- @param scale +function M.set_scale(instance, scale) + instance.last_scale = scale + gui.set_scale(instance.node, scale) +end + +--- Called when layout updated (rotate for example) +function M.on_layout_updated(instance) + if instance.last_color then + M.set_color(instance, instance.last_color) + end + if instance.last_scale then + M.set_scale(instance, instance.last_scale) + end +end + +return M diff --git a/druid/base/timer.lua b/druid/base/timer.lua new file mode 100644 index 0000000..3f7329d --- /dev/null +++ b/druid/base/timer.lua @@ -0,0 +1,53 @@ +local M = {} + +local formats = require "druid.help_modules.formats" + +--- Set text to text field +-- @param set_to - set value in seconds +function M.set_to(instance, set_to) + instance.last_value = set_to + gui.set_text(instance.node, formats.second_string_min(set_to)) +end + +--- Called when layout updated (rotate for example) +function M.on_layout_updated(instance) + M.set_to(instance, instance.last_value) +end + +--- Called when update +-- @param is_on - boolean is timer on +function M.set_work_mode(instance, is_on) + instance.is_on = is_on +end + +--- Set time interval +-- @param from - "from" time in seconds +-- @param to - "to" time in seconds +function M.set_interval(instance, from, to) + instance.second_from = from + instance.seconds_counter = from + instance.seconds_temp = 0 + instance.seconds_to = to + instance.second_step = from < to and 1 or - 1 + M.set_work_mode(instance, true) + M.set_to(instance, from) +end + +--- Called when update +-- @param dt - delta time +function M.on_updated(instance, dt) + if instance.is_on then + instance.seconds_temp = instance.seconds_temp + dt + if instance.seconds_temp > 1 then + instance.seconds_temp = instance.seconds_temp - 1 + instance.seconds_counter = instance.seconds_counter + instance.second_step + M.set_to(instance, instance.seconds_counter) + if instance.seconds_counter == instance.seconds_to then + instance.is_on = false + instance.callback(instance) + end + end + end +end + +return M diff --git a/druid/druid.lua b/druid/druid.lua index 4c34465..ab31684 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -3,20 +3,7 @@ local M = {} local druid_input = require "druid.help_modules.druid_input" M.input = druid_input -local pie_progress_bar = require "druid.components.pie_progress_bar" -local progress_bar = require "druid.components.progress_bar" -local flying_particles = require "druid.components.flying_particles" -local text_field = require "druid.components.text_field" -local counter = require "druid.components.counter" -local image = require "druid.components.image" -local button = require "druid.components.button" -local timer = require "druid.components.timer" -local tab_page = require "druid.components.tab_page" -local tabs_container = require "druid.components.tabs_container" -local spine_anim = require "druid.components.spine_anim" -local scrolling_box = require "druid.components.scrolling_box" -local andr_back_btn = require "druid.components.andr_back_btn" local LAYOUT_CHANGED = hash("layout_changed") local ON_MESSAGE = hash("on_message") @@ -27,24 +14,6 @@ M.TRANSLATABLE = hash("TRANSLATABLE") local STRING = "string" ---- Call this method when you need to update translations. -function M.translate(factory) - if factory[M.TRANSLATABLE] then - local key, result - for i, v in ipairs(factory[M.TRANSLATABLE]) do - key = v.lang_key or v.name - if key then - if v.lang_params then - result = lang.txp(key, v.lang_params) - else - result = lang.txt(key) - end - if result then - lang.set_node_properties(v.node, key) - end - result = result or v.last_value - v:set_to(result) - end end end end @@ -142,279 +111,14 @@ local function create(meta, factory, name, ...) factory[v] = {} end factory[v][#factory[v] + 1] = instance - end - return instance -end ---- Create new instance of a text_field --- @param factory - parent factory --- @param name - name of text node --- @param init_value - init ui object with this value --- @return instance of a text_field -function M.new_text_field(factory, name, init_value, bounce_in) - local instance = create(text_field, factory, name, M.TRANSLATABLE, LAYOUT_CHANGED) - instance.scale_from = gui.get_scale(instance.node) - instance.scale_to = bounce_in and vmath.mul_per_elem(instance.scale_from, bounce_in) or instance.scale_from - instance:set_to(init_value or 0) - return instance -end - ---- Create new instance of a counter --- @param factory - parent factory --- @param name - name of text node --- @param init_value - init ui object with this value --- @return instance of a text_field -function M.new_counter(factory, name, init_value) - local instance = create(counter, factory, name, LAYOUT_CHANGED, ON_UPDATE) - instance.scale_from = gui.get_scale(instance.node) - instance.scale_to = instance.scale_from * 1.2 - instance:set_to(init_value or 0) - return instance -end - ---- Create new instance of an image --- @param factory - parent factory --- @param name - name of image node --- @param anim_table - table with animations or frames --- @param init_frame - init with this frame --- @return instance of an image -function M.new_image(factory, name, anim_table, init_frame, bounce_in) - local instance = create(image, factory, name, LAYOUT_CHANGED) - instance.scale_from = gui.get_scale(instance.node) - instance.scale_to = bounce_in and vmath.mul_per_elem(instance.scale_from, bounce_in) or instance.scale_from - instance.anim_table = anim_table - if init_frame then - instance:set_to(init_frame) - elseif anim_table then - instance:set_to(1) - end - return instance -end - ---- Create new instance of a timer --- @param factory - parent factory --- @param name - name of image node --- @param second_from - start time --- @param seconds_to - end time --- @param callback - call when timer finished --- @return instance of a timer -function M.new_timer(factory, name, second_from, seconds_to, callback) - local instance = create(timer, factory, name, LAYOUT_CHANGED, ON_UPDATE) - instance:set_to(second_from) - instance:set_interval(second_from, seconds_to) - instance.is_on = true - instance.callback = callback - return instance -end - ---- Add new pie progress component for handling --- @param factory - parent factory --- @param name - a node name for a pie progress instance --- @param init_value - init ui object with this value --- @return instance with pie_progress -function M.new_pie_progress(factory, name, init_value) - local instance = create(pie_progress_bar, factory, name, LAYOUT_CHANGED) - instance:set_to(init_value or 1) - return instance -end - ---- Add new progress bar component for handling --- @param factory - parent factory --- @param name - name of the fill node --- @param key - x or y - key for scale --- @param init_value - init ui object with this value --- @return instance with pie_progress -function M.new_progress_bar(factory, name, key, init_value) - local instance = create(progress_bar, factory, name, LAYOUT_CHANGED) - instance.prop = hash("scale."..key) - instance.key = key - instance.node = gui.get_node(name) - instance.scale = gui.get_scale(instance.node) - instance:set_to(init_value or 1) - return instance -end - ---- Create new instance of a flying particles --- @param factory - parent factory --- @param name - name of prototype --- @param count - how many particles need to cache --- @param get_pos_func - function that returns target pos for flying --- @return instance of a flying particles -function M.new_flying_particles(factory, name, count, get_pos_func) - local instance = create(flying_particles, factory, name, LAYOUT_CHANGED) - instance.get_pos_func = get_pos_func - local node = instance.node - instance.node = node - instance.fly_particles = {} - instance.fly_particles[1] = node - for i = 2, count do - instance.fly_particles[i] = gui.clone(node) - end - instance.scale = gui.get_scale(node) - instance.last_particle = 0 - return instance -end - -M.BTN_SOUND_FUNC = function() end -M.BTN_SOUND_DISABLE_FUNC = function()end - ---- Add new button component for handling --- @param factory - parent factory --- @param name - a node name for a button instance --- @param callback - click button callback --- @param params - callback parameters, will be returned with self callback(self, params) --- @param animate_node_name - node for animation, if it's not a main node --- @return instance of button -function M.new_button(factory, name, callback, params, animate_node_name, event, action, sound, sound_disable) - input_init(factory) - local instance = create(button, factory, name, ON_INPUT) - instance.event = event or druid_input.A_CLICK - instance.action = action or druid_input.RELEASED - instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node - instance.scale_from = gui.get_scale(instance.anim_node) - instance.scale_to = instance.scale_from + button.DEFAULT_SCALE_CHANGE - instance.pos = gui.get_position(instance.anim_node) - instance.callback = callback - instance.params = params - instance.tap_anim = button.tap_scale_animation - instance.back_anim = button.back_scale_animation - instance.sound = sound or M.BTN_SOUND_FUNC - instance.sound_disable = sound_disable or M.BTN_SOUND_DISABLE_FUNC - return instance -end - ---- Add reaction for back btn (on Android for example) --- @param factory - parent factory --- @param callback - tap button callback -function M.new_back_handler(factory, callback) - input_init(factory) - local instance = create(andr_back_btn, factory, nil, ON_INPUT) - instance.event = druid_input.A_ANDR_BACK - instance.action = druid_input.RELEASED - instance.callback = callback - return instance -end - ---- Create new tab page instance --- @param factory - parent factory --- @param name - name of parental node that represents tab page content --- @param easing - easing for tab page --- @param duration - duration of animation for tab page --- @param callback - call when change page --- @return instance that represents the tab page -function M.new_tab_page(factory, name, easing, duration, callback) - local instance = create(tab_page, factory, name, M.EVENTS.ON_MESSAGE) - instance.in_pos = gui.get_position(instance.node) - instance.out_pos = gui.get_position(instance.node) - instance.easing = easing or tab_page.DEFAULT_EASING - instance.duration = duration or tab_page.DEFAULT_DURATION - instance.callback = callback - return instance -end - ---- Create new tab btns container instance --- @param factory - parent factory --- @param name - name of parental node that represents tab btns container --- @return instance that represents the tab btns container -function M.new_tabs_container(factory, name, callback) - local instance = create(tabs_container, factory, name, LAYOUT_CHANGED) - instance:update_sizes() - instance.url = msg.url() - --- Create new tab btn instance - -- @param name - name of parental node that represents tab btn - -- @return instance that represents the tab btn - function instance.new_tab_btn(_instance, _name, url, index) - local params = {url = url, index = index, name = _name} - local btn = M.new_button(factory, _name, nil, params) - btn.back_anim = nil - btn.manual_back = button.back_tab_animation - btn.tap_anim = button.tap_tab_animation - btn.callback = function(_, _, force) - instance.switch_tab(instance, params, force) - if callback then - callback(factory.parent, index, force) - end end - instance[_name] = params - if not instance.btns then - instance.btns = {} - end - instance.btns[index] = btn - return btn end - return instance end ---- Add new spine animation --- @param factory - parent factory --- @param name - a node name for a spine anim --- @param idle_table - table with idle animations --- @param active_table - table with active animations --- @param init_idle - init idle animation name or index in idle table --- @return instance with spine anim -function M.new_spine_anim(factory, name, idle_table, active_table, init_idle) - local instance = create(spine_anim, factory, name, LAYOUT_CHANGED) - instance.idle_table = idle_table - instance.active_table = active_table - instance:play_idle(init_idle) - return instance -end ---- Add new scrolling box --- @param factory - parent factory --- @param name - a node name for a spine anim --- @param zone_name - node name of zone for tap --- @param speed_coef - vector3 coef. of speed for scrolling --- @param maximum - vector3 maximum position for scrolling --- @param points_of_interest - table with vector3 point of interes --- @param callback - scrolling events callback --- @return instance with scrolling box -function M.new_scrolling_box(factory, name, zone_name, speed_coef, maximum, points_of_interest, callback) - local instance = create(scrolling_box, factory, name, ON_UPDATE, ON_SWIPE) - instance.pos = gui.get_position(instance.node) - instance.start_pos = vmath.vector3(instance.pos) - instance.maximum = maximum - instance.points_of_interest = points_of_interest - instance.callback = callback - if instance.start_pos.x > instance.maximum.x then - instance.start_pos.x, instance.maximum.x = instance.maximum.x, instance.start_pos.x end - if instance.start_pos.y > instance.maximum.y then - instance.start_pos.y, instance.maximum.y = instance.maximum.y, instance.start_pos.y - end - if type(name) == STRING then - instance.scrolling_zone = gui.get_node(zone_name) - else - instance.scrolling_zone = zone_name - end - instance.swipe = { - minSwipeDistance = 40, - speed_down_coef = 1.1, - speed_up_coef = speed_coef or vmath.vector3(1.1, 1.1, 0), - speed = vmath.vector3(0, 0, 0), - maximum = vmath.vector3(0, 0, 0), - min_speed = 2, - beginX = 0, - beginY = 0, - endX = 0, - endY = 0, - xDistance = nil, - yDistance = nil, - totalSwipeDistanceLeft = nil, - totalSwipeDistanceRight = nil, - totalSwipeDistanceUp = nil, - totalSwipeDistanceDown = nil, - is_swipe = nil, - end_move_coef_x = 1, - end_move_coef_y = 1, - back_slow_coef = 0.4, - end_position_x = nil, - end_position_y = nil, - is_x = instance.start_pos.x ~= instance.maximum.x, - is_y = instance.start_pos.y ~= instance.maximum.y - } - return instance end return M diff --git a/example/example.gui b/example/example.gui index 12b1015..b01879a 100644 --- a/example/example.gui +++ b/example/example.gui @@ -1,10 +1,131 @@ script: "/example/example.gui.gui_script" +fonts { + name: "system_font" + font: "/builtins/fonts/system_font.font" +} background_color { x: 0.0 y: 0.0 z: 0.0 w: 0.0 } +nodes { + position { + x: 200.0 + y: 200.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: 200.0 + y: 100.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: "" + id: "button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: 0.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: 2.0 + y: 2.0 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "button text" + font: "system_font" + id: "text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_PARENT max_nodes: 512 diff --git a/game.project b/game.project index a165b1d..adf34bf 100644 --- a/game.project +++ b/game.project @@ -5,8 +5,8 @@ main_collection = /example/example.collectionc shared_state = 1 [display] -width = 960 -height = 640 +width = 400 +height = 400 [project] title = druid From e986b2c3b8c007501b74492b7af0d1cd6ada1936 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 00:46:58 +0300 Subject: [PATCH 002/136] register base components in factory, interest moved to druid.data --- druid/data.lua | 18 ++++++++ druid/druid.lua | 72 ++++++++++++++++++++---------- druid/help_modules/druid_input.lua | 9 ---- 3 files changed, 66 insertions(+), 33 deletions(-) create mode 100644 druid/data.lua diff --git a/druid/data.lua b/druid/data.lua new file mode 100644 index 0000000..e0d4650 --- /dev/null +++ b/druid/data.lua @@ -0,0 +1,18 @@ +local M = {} + +M.A_TOUCH = hash("touch") +M.A_TEXT = hash("text") +M.A_BACKSPACE = hash("backspace") +M.A_ENTER = hash("enter") +M.A_ANDR_BACK = hash("back") + +M.LAYOUT_CHANGED = hash("layout_changed") +M.ON_MESSAGE = hash("on_message") +M.ON_INPUT = hash("on_input") +M.ON_SWIPE = hash("on_swipe") +M.ON_UPDATE = hash("on_update") + +M.RELEASED = "released" +M.PRESSED = "pressed" + +return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index ab31684..1419f78 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,37 +1,53 @@ local M = {} -local druid_input = require "druid.help_modules.druid_input" +local druid_input = require("druid.help_modules.druid_input") +local data = require("druid.data") + M.input = druid_input - - -local LAYOUT_CHANGED = hash("layout_changed") -local ON_MESSAGE = hash("on_message") -local ON_INPUT = hash("on_input") -local ON_SWIPE = hash("on_swipe") -local ON_UPDATE = hash("on_update") M.TRANSLATABLE = hash("TRANSLATABLE") local STRING = "string" +--- New druid era, registering components +-- temporary make components outside + + + +local components = { + -- base + button = require("druid.base.button"), + -- text = require("druid.base.text"), + -- android_back = require("druid.base.android_back"), + -- timer = require("druid.base.timer"), +} + +local function register_components() + for k, v in pairs(components) do + -- TODO: Find better solution to creating elements? + M["new_" .. k] = function(factory, name, ...) + M.create(factory, v, name, ...) end + print("[Druid]: register component", k) end end +register_components() + --- Called on_message function M.on_message(factory, message_id, message, sender) - if message_id == LAYOUT_CHANGED then - if factory[LAYOUT_CHANGED] then + if message_id == data.LAYOUT_CHANGED then + if factory[data.LAYOUT_CHANGED] then M.translate(factory) - for i, v in ipairs(factory[LAYOUT_CHANGED]) do + for i, v in ipairs(factory[data.LAYOUT_CHANGED]) do v:on_layout_updated(message) end end elseif message_id == M.TRANSLATABLE then M.translate(factory) else - if factory[ON_MESSAGE] then - for i, v in ipairs(factory[ON_MESSAGE]) do + if factory[data.ON_MESSAGE] then + for i, v in ipairs(factory[data.ON_MESSAGE]) do v:on_message(message_id, message, sender) end end @@ -40,22 +56,22 @@ end --- Called ON_INPUT function M.on_input(factory, action_id, action) - if factory[ON_SWIPE] then + if factory[data.ON_SWIPE] then local v, result - local len = #factory[ON_SWIPE] + local len = #factory[data.ON_SWIPE] for i = 1, len do - v = factory[ON_SWIPE][i] + v = factory[data.ON_SWIPE][i] result = result or v:on_input(action_id, action) end if result then return true end end - if factory[ON_INPUT] then + if factory[data.ON_INPUT] then local v - local len = #factory[ON_INPUT] + local len = #factory[data.ON_INPUT] for i = 1, len do - v = factory[ON_INPUT][i] + v = factory[data.ON_INPUT][i] if action_id == v.event and action[v.action] and v:on_input(action_id, action) then return true end @@ -66,10 +82,10 @@ function M.on_input(factory, action_id, action) end --- Called on_update -function M.on_update(factory, dt) - if factory[ON_UPDATE] then - for i, v in ipairs(factory[ON_UPDATE]) do - v:on_updated(dt) +function M.update(factory, dt) + if factory[data.ON_UPDATE] then + for i, v in ipairs(factory[data.ON_UPDATE]) do + v:update(dt) end end end @@ -105,19 +121,27 @@ local function create(meta, factory, name, ...) end end factory[#factory + 1] = instance - local register_to = {...} + + local register_to = meta.interest or {} for i, v in ipairs(register_to) do if not factory[v] then factory[v] = {} end factory[v][#factory[v] + 1] = instance + if v == data.ON_INPUT then + input_init(factory) end end return instance end +function M.create(factory, meta, name, ...) + local instance = create(meta, factory, name) + instance.factory = factory + if instance.init then + instance:init(...) end end diff --git a/druid/help_modules/druid_input.lua b/druid/help_modules/druid_input.lua index 21ac43a..bc2665a 100644 --- a/druid/help_modules/druid_input.lua +++ b/druid/help_modules/druid_input.lua @@ -4,15 +4,6 @@ local ADD_FOCUS = hash("acquire_input_focus") local REMOVE_FOCUS = hash("release_input_focus") local PATH_OBJ = "." -M.A_CLICK = hash("click") -M.A_TEXT = hash("text") -M.A_BACKSPACE = hash("backspace") -M.A_ENTER = hash("enter") -M.A_ANDR_BACK = hash("back") - -M.RELEASED = "released" -M.PRESSED = "pressed" - function M.focus() msg.post(PATH_OBJ, ADD_FOCUS) end From da1e75fa89a214de5741c7dc59aa64f7a26723ee Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 00:48:08 +0300 Subject: [PATCH 003/136] add simple usage of button --- example/example.gui.gui_script | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index ce07f4f..c7ea0d3 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -1,29 +1,21 @@ local druid = require "druid.druid" function init(self) -end + self.druid = druid.new(self) -function final(self) - -- Add finalization code here - -- Remove this function if not needed + self.button = self.druid:new_button("button", function() + print("New click") + end) end function update(self, dt) - -- Add update code here - -- Remove this function if not needed + self.druid:update(dt) end function on_message(self, message_id, message, sender) - -- Add message-handling code here - -- Remove this function if not needed + self.druid:on_message(message_id, message, sender) end function on_input(self, action_id, action) - -- Add input-handling code here - -- Remove this function if not needed -end - -function on_reload(self) - -- Add input-handling code here - -- Remove this function if not needed -end + self.druid:on_input(action_id, action) +end \ No newline at end of file From 9af3046ca4ed435659df5fce6207131fbf38d24c Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 00:50:46 +0300 Subject: [PATCH 004/136] translatable should be in data --- druid/data.lua | 2 ++ druid/druid.lua | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/druid/data.lua b/druid/data.lua index e0d4650..5fa1129 100644 --- a/druid/data.lua +++ b/druid/data.lua @@ -6,11 +6,13 @@ M.A_BACKSPACE = hash("backspace") M.A_ENTER = hash("enter") M.A_ANDR_BACK = hash("back") +-- interest M.LAYOUT_CHANGED = hash("layout_changed") M.ON_MESSAGE = hash("on_message") M.ON_INPUT = hash("on_input") M.ON_SWIPE = hash("on_swipe") M.ON_UPDATE = hash("on_update") +M.TRANSLATABLE = hash("TRANSLATABLE") M.RELEASED = "released" M.PRESSED = "pressed" diff --git a/druid/druid.lua b/druid/druid.lua index 1419f78..1707406 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,19 +1,11 @@ -local M = {} - -local druid_input = require("druid.help_modules.druid_input") local data = require("druid.data") +local druid_input = require("druid.help_modules.druid_input") -M.input = druid_input - -M.TRANSLATABLE = hash("TRANSLATABLE") +local M = {} local STRING = "string" --- New druid era, registering components --- temporary make components outside - - - local components = { -- base button = require("druid.base.button"), @@ -22,6 +14,7 @@ local components = { -- timer = require("druid.base.timer"), } + local function register_components() for k, v in pairs(components) do -- TODO: Find better solution to creating elements? @@ -43,7 +36,7 @@ function M.on_message(factory, message_id, message, sender) v:on_layout_updated(message) end end - elseif message_id == M.TRANSLATABLE then + elseif message_id == data.TRANSLATABLE then M.translate(factory) else if factory[data.ON_MESSAGE] then @@ -54,6 +47,7 @@ function M.on_message(factory, message_id, message, sender) end end + --- Called ON_INPUT function M.on_input(factory, action_id, action) if factory[data.ON_SWIPE] then @@ -81,6 +75,7 @@ function M.on_input(factory, action_id, action) return false end + --- Called on_update function M.update(factory, dt) if factory[data.ON_UPDATE] then @@ -90,6 +85,7 @@ function M.update(factory, dt) end end + --- Create UI instance for ui elements -- @return instance with all ui components function M.new(self) @@ -98,6 +94,7 @@ function M.new(self) return factory end + local function input_init(factory) if not factory.input_inited then factory.input_inited = true @@ -136,6 +133,7 @@ local function create(meta, factory, name, ...) return instance end + function M.create(factory, meta, name, ...) local instance = create(meta, factory, name) instance.factory = factory @@ -145,4 +143,5 @@ function M.create(factory, meta, name, ...) end end -return M + +return M \ No newline at end of file From 0d98e435b62893763f88db088b6c61fcbd293491 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 00:57:50 +0300 Subject: [PATCH 005/136] ability to extend components, stubs for sounds and locale --- druid/druid.lua | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index 1707406..f95655d 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -7,7 +7,7 @@ local STRING = "string" --- New druid era, registering components local components = { - -- base + -- basic button = require("druid.base.button"), -- text = require("druid.base.text"), -- android_back = require("druid.base.android_back"), @@ -15,18 +15,22 @@ local components = { } -local function register_components() +local function register_basic_components() for k, v in pairs(components) do - -- TODO: Find better solution to creating elements? - M["new_" .. k] = function(factory, name, ...) - M.create(factory, v, name, ...) - end - print("[Druid]: register component", k) + M.register(k, v) end end -register_components() +register_basic_components() +function M.register(name, module) + -- TODO: Find better solution to creating elements? + M["new_" .. name] = function(factory, node_name, ...) + M.create(factory, module, node_name, ...) + end + print("[Druid]: register component", name) +end + --- Called on_message function M.on_message(factory, message_id, message, sender) if message_id == data.LAYOUT_CHANGED then @@ -104,8 +108,8 @@ end -------------------------------------------------------------------------------- -local function create(meta, factory, name, ...) - local instance = setmetatable({}, {__index = meta}) +local function create(module, factory, name, ...) + local instance = setmetatable({}, {__index = module}) instance.parent = factory if name then if type(name) == STRING then @@ -119,7 +123,7 @@ local function create(meta, factory, name, ...) end factory[#factory + 1] = instance - local register_to = meta.interest or {} + local register_to = module.interest or {} for i, v in ipairs(register_to) do if not factory[v] then factory[v] = {} @@ -134,9 +138,8 @@ local function create(meta, factory, name, ...) end -function M.create(factory, meta, name, ...) - local instance = create(meta, factory, name) - instance.factory = factory +function M.create(factory, module, name, ...) + local instance = create(module, factory, name) if instance.init then instance:init(...) @@ -144,4 +147,14 @@ function M.create(factory, meta, name, ...) end +function M.get_text(name) + -- override to get text for localized text +end + + +function M.play_sound(name) + -- override to play sound with name +end + + return M \ No newline at end of file From 10d84670b9c141e994d4cd4e51a2179d73fa81e9 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 01:10:10 +0300 Subject: [PATCH 006/136] all actions now passed to components --- druid/druid.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index f95655d..255039c 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -20,7 +20,6 @@ local function register_basic_components() M.register(k, v) end end -register_basic_components() function M.register(name, module) @@ -70,7 +69,7 @@ function M.on_input(factory, action_id, action) local len = #factory[data.ON_INPUT] for i = 1, len do v = factory[data.ON_INPUT][i] - if action_id == v.event and action[v.action] and v:on_input(action_id, action) then + if action_id == v.event and v:on_input(action_id, action) then return true end end @@ -156,5 +155,5 @@ function M.play_sound(name) -- override to play sound with name end - +register_basic_components() return M \ No newline at end of file From a0a171df55b181887e821f156a00b01318f639e4 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 01:11:33 +0300 Subject: [PATCH 007/136] dirty button changes. Hover animations. Call button, if only touch start and ended on this button --- druid/base/button.lua | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index 9b3b722..738e268 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -2,10 +2,15 @@ local data = require("druid.data") local ui_animate = require "druid.help_modules.druid_animate" local M = {} + M.interest = { data.ON_INPUT } +local BTN_SOUND = "button_click" +local BTN_SOUND_DISABLED = "button_click_disabled" +local HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1) + M.DEFAULT_SCALE_CHANGE = vmath.vector3(-0.05, - 0.1, 1) M.DEFAULT_POS_CHANGE = vmath.vector3(0, - 10, 0) M.DEFAULT_MOVE_SPEED = 5 @@ -17,35 +22,66 @@ M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) M.DEFAUL_ACTIVATION_TIME = 0.2 -function M.init(instance, callback, event, action, animate_node_name, sound) +function M.init(instance, callback, params, animate_node_name, event) instance.event = event or data.A_TOUCH - instance.action = action or data.RELEASED instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node instance.scale_from = gui.get_scale(instance.anim_node) instance.scale_to = instance.scale_from + M.DEFAULT_SCALE_CHANGE + instance.scale_hover_to = instance.scale_from + HOVER_SCALE instance.pos = gui.get_position(instance.anim_node) instance.callback = callback - -- instance.params = params + instance.params = params instance.tap_anim = M.tap_scale_animation instance.back_anim = M.back_scale_animation - -- instance.sound = sound or M.BTN_SOUND_FUNC - -- instance.sound_disable = sound_disable or M.BTN_SOUND_DISABLE_FUNC + instance.hover_anim = true + -- instance.sound = sound or BTN_SOUND + -- instance.sound_disable = sound_disable or BTN_SOUND_DISABLED end --- Set text to text field -- @param action_id - input action id -- @param action - input action function M.on_input(instance, action_id, action) - if gui.is_enabled(instance.node) and gui.pick_node(instance.node, action.x, action.y) then - if not instance.disabled then - instance.tap_anim(instance) + if gui.pick_node(instance.node, action.x, action.y) then + if action.pressed then + instance.can_action = true + instance.repeated_counter = 0 return true - else - -- instance.sound_disable() - return false end + + if action.released then + if not instance.disabled then + if not instance.stub and instance.can_action then + instance.can_action = false + instance.tap_anim(instance) + -- instance.sound() + instance.callback(instance.parent.parent, instance.params, instance) + else + if instance.hover_anim then + gui.animate(instance.node, "scale", instance.scale_from, gui.EASING_OUTSINE, 0.05) + end + end + return true + else + instance.sound_disable() + return false + end + else + -- scale in + if instance.hover_anim then + gui.animate(instance.node, "scale", instance.scale_hover_to, gui.EASING_OUTSINE, 0.05) + end + end + return not instance.disabled + else + -- scale back + -- bad solition, remake with flag + instance.can_action = false + if instance.hover_anim then + gui.animate(instance.node, "scale", instance.scale_from, gui.EASING_OUTSINE, 0.05) + end + return false end - return false end function M.tap_scale_animation(instance) @@ -55,7 +91,6 @@ function M.tap_scale_animation(instance) instance.back_anim(instance) end -- instance.sound() - instance.callback(instance.parent.parent, instance.params, instance) end ) end From e4c8b65cc166e654412c439f4ed6084371dbdb46 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 09:09:05 +0300 Subject: [PATCH 008/136] rename help_modules to helper --- druid/base/button.lua | 2 +- druid/base/text.lua | 2 +- druid/base/timer.lua | 2 +- druid/components/button.lua | 2 +- druid/components/flying_particles.lua | 2 +- druid/components/image.lua | 2 +- druid/components/scrolling_box.lua | 4 ++-- druid/components/text_field.lua | 2 +- druid/components/timer.lua | 2 +- druid/druid.lua | 2 +- druid/{help_modules => helper}/druid_animate.lua | 4 ++++ druid/{help_modules => helper}/druid_input.lua | 0 druid/{help_modules => helper}/formats.lua | 0 druid/{help_modules => helper}/ui_helper.lua | 0 14 files changed, 15 insertions(+), 11 deletions(-) rename druid/{help_modules => helper}/druid_animate.lua (97%) rename druid/{help_modules => helper}/druid_input.lua (100%) rename druid/{help_modules => helper}/formats.lua (100%) rename druid/{help_modules => helper}/ui_helper.lua (100%) diff --git a/druid/base/button.lua b/druid/base/button.lua index 738e268..5ca069b 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,5 +1,5 @@ local data = require("druid.data") -local ui_animate = require "druid.help_modules.druid_animate" +local ui_animate = require "druid.helper.druid_animate" local M = {} diff --git a/druid/base/text.lua b/druid/base/text.lua index fbc6eb1..9d800f6 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,6 +1,6 @@ local M = {} -local ui_animate = require "druid.help_modules.druid_animate" +local ui_animate = require "druid.helper.druid_animate" --- Bounce text field function M.bounce(instance, callback) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 3f7329d..7802a49 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,6 +1,6 @@ local M = {} -local formats = require "druid.help_modules.formats" +local formats = require "druid.helper.formats" --- Set text to text field -- @param set_to - set value in seconds diff --git a/druid/components/button.lua b/druid/components/button.lua index d57f388..9160de6 100644 --- a/druid/components/button.lua +++ b/druid/components/button.lua @@ -1,6 +1,6 @@ local M = {} -local ui_animate = require "druid.help_modules.druid_animate" +local ui_animate = require "druid.helper.druid_animate" M.DEFAULT_SCALE_CHANGE = vmath.vector3(-0.05, - 0.1, 1) M.DEFAULT_POS_CHANGE = vmath.vector3(0, - 10, 0) diff --git a/druid/components/flying_particles.lua b/druid/components/flying_particles.lua index 0c0edcd..5a63cb3 100644 --- a/druid/components/flying_particles.lua +++ b/druid/components/flying_particles.lua @@ -1,6 +1,6 @@ local M = {} -local ui_animate = require "druid.help_modules.druid_animate" +local ui_animate = require "druid.helper.druid_animate" local function fly_to(instance, pos_from, speed, callback) local pos_to = instance.get_pos_func() diff --git a/druid/components/image.lua b/druid/components/image.lua index 97af383..cfdf6db 100644 --- a/druid/components/image.lua +++ b/druid/components/image.lua @@ -1,6 +1,6 @@ local M = {} -local ui_animate = require "druid.help_modules.druid_animate" +local ui_animate = require "druid.helper.druid_animate" --- Bounce image function M.bounce(instance) diff --git a/druid/components/scrolling_box.lua b/druid/components/scrolling_box.lua index 8618335..4982194 100644 --- a/druid/components/scrolling_box.lua +++ b/druid/components/scrolling_box.lua @@ -1,7 +1,7 @@ local M = {} -local druid_input = require "druid.help_modules.druid_input" -local ui_animate = require "druid.help_modules.druid_animate" +local druid_input = require "druid.helper.druid_input" +local ui_animate = require "druid.helper.druid_animate" M.START = hash("START") M.FINISH = hash("FINISH") diff --git a/druid/components/text_field.lua b/druid/components/text_field.lua index fbc6eb1..9d800f6 100644 --- a/druid/components/text_field.lua +++ b/druid/components/text_field.lua @@ -1,6 +1,6 @@ local M = {} -local ui_animate = require "druid.help_modules.druid_animate" +local ui_animate = require "druid.helper.druid_animate" --- Bounce text field function M.bounce(instance, callback) diff --git a/druid/components/timer.lua b/druid/components/timer.lua index 3f7329d..7802a49 100644 --- a/druid/components/timer.lua +++ b/druid/components/timer.lua @@ -1,6 +1,6 @@ local M = {} -local formats = require "druid.help_modules.formats" +local formats = require "druid.helper.formats" --- Set text to text field -- @param set_to - set value in seconds diff --git a/druid/druid.lua b/druid/druid.lua index 255039c..2f3a106 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,5 +1,5 @@ local data = require("druid.data") -local druid_input = require("druid.help_modules.druid_input") +local druid_input = require("druid.helper.druid_input") local M = {} diff --git a/druid/help_modules/druid_animate.lua b/druid/helper/druid_animate.lua similarity index 97% rename from druid/help_modules/druid_animate.lua rename to druid/helper/druid_animate.lua index 394c153..0e76f68 100644 --- a/druid/help_modules/druid_animate.lua +++ b/druid/helper/druid_animate.lua @@ -130,6 +130,10 @@ function M.scale_to(self, node, to, callback, time, delay, easing) ) end +function M.scale(self, node, to, time) + gui.animate(node, "scale", to, gui.EASING_OUTSINE, time) +end + function M.scale_x_from_to(self, node, from, to, callback, time, easing, delay, playback) easing = easing or gui.EASING_INSINE time = time or M.SCALE_ANIMATION_TIME diff --git a/druid/help_modules/druid_input.lua b/druid/helper/druid_input.lua similarity index 100% rename from druid/help_modules/druid_input.lua rename to druid/helper/druid_input.lua diff --git a/druid/help_modules/formats.lua b/druid/helper/formats.lua similarity index 100% rename from druid/help_modules/formats.lua rename to druid/helper/formats.lua diff --git a/druid/help_modules/ui_helper.lua b/druid/helper/ui_helper.lua similarity index 100% rename from druid/help_modules/ui_helper.lua rename to druid/helper/ui_helper.lua From 5f2541c7570d35946e96aad9a463618e5490ed6a Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 09:09:49 +0300 Subject: [PATCH 009/136] refactor button, add factory settings --- druid/base/button.lua | 255 ++++++++++++++++++++---------------------- druid/settings.lua | 15 +++ 2 files changed, 134 insertions(+), 136 deletions(-) create mode 100644 druid/settings.lua diff --git a/druid/base/button.lua b/druid/base/button.lua index 5ca069b..2edc135 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,21 +1,14 @@ local data = require("druid.data") local ui_animate = require "druid.helper.druid_animate" +local settings = require("druid.settings") +local b_settings = settings.button local M = {} M.interest = { - data.ON_INPUT + data.ON_INPUT } -local BTN_SOUND = "button_click" -local BTN_SOUND_DISABLED = "button_click_disabled" -local HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1) - -M.DEFAULT_SCALE_CHANGE = vmath.vector3(-0.05, - 0.1, 1) -M.DEFAULT_POS_CHANGE = vmath.vector3(0, - 10, 0) -M.DEFAULT_MOVE_SPEED = 5 -M.DEFAULT_ALPHA_DOWN = 0.8 -M.DEFAULT_TIME_ANIM = 0.1 M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1) M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) @@ -23,152 +16,142 @@ M.DEFAUL_ACTIVATION_TIME = 0.2 function M.init(instance, callback, params, animate_node_name, event) - instance.event = event or data.A_TOUCH - instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node - instance.scale_from = gui.get_scale(instance.anim_node) - instance.scale_to = instance.scale_from + M.DEFAULT_SCALE_CHANGE - instance.scale_hover_to = instance.scale_from + HOVER_SCALE - instance.pos = gui.get_position(instance.anim_node) - instance.callback = callback - instance.params = params - instance.tap_anim = M.tap_scale_animation - instance.back_anim = M.back_scale_animation - instance.hover_anim = true - -- instance.sound = sound or BTN_SOUND - -- instance.sound_disable = sound_disable or BTN_SOUND_DISABLED + instance.event = data.A_TOUCH + instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node + instance.scale_from = gui.get_scale(instance.anim_node) + instance.scale_to = instance.scale_from + b_settings.SCALE_CHANGE + instance.scale_hover_to = instance.scale_from + b_settings.HOVER_SCALE + instance.pos = gui.get_position(instance.anim_node) + instance.callback = callback + instance.params = params + instance.tap_anim = M.tap_scale_animation + instance.back_anim = M.back_scale_animation + instance.hover_anim = b_settings.IS_HOVER + -- instance.sound = sound or BTN_SOUND + -- instance.sound_disable = sound_disable or BTN_SOUND_DISABLED end + +local function set_hover(instance, state) + if instance.hover_anim and instance._is_hovered ~= state then + local target_scale = state and instance.scale_hover_to or instance.scale_from + ui_animate.scale(instance, instance.node, target_scale, b_settings.HOVER_TIME) + instance._is_hovered = state + end +end + +local function on_button_release(instance) + if not instance.disabled then + if not instance.stub and instance.can_action then + instance.can_action = false + instance.tap_anim(instance) + -- instance.sound() + instance.callback(instance.parent.parent, instance.params, instance) + else + set_hover(instance, false) + end + return true + else + instance.sound_disable() + return false + end +end + + --- Set text to text field -- @param action_id - input action id -- @param action - input action function M.on_input(instance, action_id, action) - if gui.pick_node(instance.node, action.x, action.y) then - if action.pressed then - instance.can_action = true - instance.repeated_counter = 0 - return true - end + if gui.pick_node(instance.node, action.x, action.y) then + if action.pressed then + -- Can interact if start touch on the button + instance.can_action = true + return true + end - if action.released then - if not instance.disabled then - if not instance.stub and instance.can_action then - instance.can_action = false - instance.tap_anim(instance) - -- instance.sound() - instance.callback(instance.parent.parent, instance.params, instance) - else - if instance.hover_anim then - gui.animate(instance.node, "scale", instance.scale_from, gui.EASING_OUTSINE, 0.05) - end - end - return true - else - instance.sound_disable() - return false - end - else - -- scale in - if instance.hover_anim then - gui.animate(instance.node, "scale", instance.scale_hover_to, gui.EASING_OUTSINE, 0.05) - end - end - return not instance.disabled - else - -- scale back - -- bad solition, remake with flag - instance.can_action = false - if instance.hover_anim then - gui.animate(instance.node, "scale", instance.scale_from, gui.EASING_OUTSINE, 0.05) - end - return false - end + if action.released then + return on_button_release(instance) + else + set_hover(instance, true) + end + return not instance.disabled + else + -- Can't interact, if touch outside of button + instance.can_action = false + set_hover(instance, false) + return false + end end function M.tap_scale_animation(instance) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, - function() - if instance.back_anim then - instance.back_anim(instance) - end - -- instance.sound() - end - ) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, + function() + if instance.back_anim then + instance.back_anim(instance) + end + -- instance.sound() + end + ) end + function M.back_scale_animation(instance) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) end -function M.tap_tab_animation(instance, force) - ui_animate.alpha(instance, instance.anim_node, M.DEFAULT_ALPHA_DOWN, nil, M.DEFAULT_TIME_ANIM) - ui_animate.fly_to(instance, instance.anim_node, instance.pos + M.DEFAULT_POS_CHANGE, M.DEFAULT_MOVE_SPEED) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, - function() - if instance.back_anim then - instance.back_anim(instance) - end - instance.callback(instance.parent.parent, instance.params, force) - end - ) -end - -function M.back_tab_animation(instance) - ui_animate.alpha(instance, instance.anim_node, 1, nil, M.DEFAULT_TIME_ANIM) - ui_animate.fly_to(instance, instance.anim_node, instance.pos, M.DEFAULT_MOVE_SPEED) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) -end function M.deactivate(instance, is_animate, callback) - instance.disabled = true - if is_animate then - local counter = 0 - local clbk = function() - counter = counter + 1 - if counter == 3 and callback then - callback(instance.parent.parent) - end - end - ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, - gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - else - gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) - gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) - if callback then - callback(instance.parent.parent) - end - end + instance.disabled = true + if is_animate then + local counter = 0 + local clbk = function() + counter = counter + 1 + if counter == 3 and callback then + callback(instance.parent.parent) + end + end + ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, + gui.EASING_OUTBOUNCE) + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + else + gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) + gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) + if callback then + callback(instance.parent.parent) + end + end end + function M.activate(instance, is_animate, callback) - if is_animate then - local counter = 0 - local clbk = function() - counter = counter + 1 - if counter == 3 then - instance.disabled = false - if callback then - callback(instance.parent.parent) - end - end - end - ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, - gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - else - gui.set_color(instance.node, ui_animate.TINT_SHOW) - gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) - instance.disabled = false - if callback then - callback(instance.parent.parent) - end - end + if is_animate then + local counter = 0 + local clbk = function() + counter = counter + 1 + if counter == 3 then + instance.disabled = false + if callback then + callback(instance.parent.parent) + end + end + end + ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, + gui.EASING_OUTBOUNCE) + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + else + gui.set_color(instance.node, ui_animate.TINT_SHOW) + gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) + instance.disabled = false + if callback then + callback(instance.parent.parent) + end + end end return M diff --git a/druid/settings.lua b/druid/settings.lua new file mode 100644 index 0000000..cf86a14 --- /dev/null +++ b/druid/settings.lua @@ -0,0 +1,15 @@ +local M = {} + + +M.button = { + IS_HOVER = true, + IS_HOLD = true, + BTN_SOUND = "button_click", + BTN_SOUND_DISABLED = "button_click_disabled", + HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), + HOVER_TIME = 0.05, + SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), +} + + +return M \ No newline at end of file From c241f26ae1c00ff9e3ffc53c58e90bef28b4414f Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 09:13:12 +0300 Subject: [PATCH 010/136] three buttons in example.gui --- example/example.gui | 244 ++++++++++++++++++++++++++++++++- example/example.gui.gui_script | 10 +- 2 files changed, 247 insertions(+), 7 deletions(-) diff --git a/example/example.gui b/example/example.gui index b01879a..c283e40 100644 --- a/example/example.gui +++ b/example/example.gui @@ -12,7 +12,7 @@ background_color { nodes { position { x: 200.0 - y: 200.0 + y: 325.0 z: 0.0 w: 1.0 } @@ -43,7 +43,7 @@ nodes { type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA texture: "" - id: "button" + id: "button_1" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER @@ -96,9 +96,9 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "button text" + text: "Button 1" font: "system_font" - id: "text" + id: "text_1" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER @@ -116,7 +116,241 @@ nodes { } adjust_mode: ADJUST_MODE_FIT line_break: false - parent: "button" + parent: "button_1" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 200.0 + y: 200.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: 200.0 + y: 100.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: "" + id: "button_2" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: 0.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: 2.0 + y: 2.0 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Button 2" + font: "system_font" + id: "text_2" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_2" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 200.0 + y: 75.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: 200.0 + y: 100.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: "" + id: "button_3" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: 0.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: 2.0 + y: 2.0 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Button 3" + font: "system_font" + id: "text_3" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_3" layer: "" inherit_alpha: true alpha: 1.0 diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index c7ea0d3..3c347cd 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -3,8 +3,14 @@ local druid = require "druid.druid" function init(self) self.druid = druid.new(self) - self.button = self.druid:new_button("button", function() - print("New click") + self.druid:new_button("button_1", function() + print("On button 1") + end) + self.druid:new_button("button_2", function() + print("On button 2") + end) + self.druid:new_button("button_3", function() + print("On button 3") end) end From 9d13837cf081ac823b46a883d62785c423404cb6 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 09:40:57 +0300 Subject: [PATCH 011/136] add simple example resources --- example/example.collection | 40 ++++++++++++++ example/example.gui | 98 +++++++++++++++++---------------- example/example.gui.gui_script | 11 +++- example/game.font | 17 ++++++ example/gui.atlas | 9 +++ example/res/click.ogg | Bin 0 -> 4880 bytes example/res/exo2.ttf | Bin 0 -> 110068 bytes example/res/gray_long.png | Bin 0 -> 12428 bytes example/res/green_long.png | Bin 0 -> 15809 bytes 9 files changed, 127 insertions(+), 48 deletions(-) create mode 100644 example/game.font create mode 100644 example/gui.atlas create mode 100755 example/res/click.ogg create mode 100755 example/res/exo2.ttf create mode 100644 example/res/gray_long.png create mode 100644 example/res/green_long.png diff --git a/example/example.collection b/example/example.collection index 42fe135..270fc16 100644 --- a/example/example.collection +++ b/example/example.collection @@ -35,3 +35,43 @@ embedded_instances { z: 1.0 } } +embedded_instances { + id: "sounds" + data: "embedded_components {\n" + " id: \"click\"\n" + " type: \"sound\"\n" + " data: \"sound: \\\"/example/res/click.ogg\\\"\\n" + "looping: 0\\n" + "group: \\\"master\\\"\\n" + "gain: 0.4\\n" + "\"\n" + " position {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " }\n" + " rotation {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " w: 1.0\n" + " }\n" + "}\n" + "" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale3 { + x: 1.0 + y: 1.0 + z: 1.0 + } +} diff --git a/example/example.gui b/example/example.gui index c283e40..eb5d5b0 100644 --- a/example/example.gui +++ b/example/example.gui @@ -1,7 +1,11 @@ script: "/example/example.gui.gui_script" fonts { - name: "system_font" - font: "/builtins/fonts/system_font.font" + name: "game" + font: "/example/game.font" +} +textures { + name: "gui" + texture: "/example/gui.atlas" } background_color { x: 0.0 @@ -23,14 +27,14 @@ nodes { w: 1.0 } scale { - x: 1.0 - y: 1.0 + x: 0.5 + y: 0.5 z: 1.0 w: 1.0 } size { - x: 200.0 - y: 100.0 + x: 426.0 + y: 190.0 z: 0.0 w: 1.0 } @@ -42,7 +46,7 @@ nodes { } type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA - texture: "" + texture: "gui/green_long" id: "button_1" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE @@ -66,7 +70,7 @@ nodes { nodes { position { x: 0.0 - y: 0.0 + y: 20.0 z: 0.0 w: 1.0 } @@ -77,8 +81,8 @@ nodes { w: 1.0 } scale { - x: 2.0 - y: 2.0 + x: 1.0 + y: 1.0 z: 1.0 w: 1.0 } @@ -89,15 +93,15 @@ nodes { w: 1.0 } color { - x: 0.0 - y: 0.0 - z: 0.0 + x: 1.0 + y: 1.0 + z: 1.0 w: 1.0 } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA text: "Button 1" - font: "system_font" + font: "game" id: "text_1" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE @@ -109,9 +113,9 @@ nodes { w: 1.0 } shadow { - x: 1.0 - y: 1.0 - z: 1.0 + x: 0.0 + y: 0.0 + z: 0.0 w: 1.0 } adjust_mode: ADJUST_MODE_FIT @@ -140,14 +144,14 @@ nodes { w: 1.0 } scale { - x: 1.0 - y: 1.0 + x: 0.5 + y: 0.5 z: 1.0 w: 1.0 } size { - x: 200.0 - y: 100.0 + x: 426.0 + y: 190.0 z: 0.0 w: 1.0 } @@ -159,7 +163,7 @@ nodes { } type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA - texture: "" + texture: "gui/green_long" id: "button_2" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE @@ -183,7 +187,7 @@ nodes { nodes { position { x: 0.0 - y: 0.0 + y: 20.0 z: 0.0 w: 1.0 } @@ -194,8 +198,8 @@ nodes { w: 1.0 } scale { - x: 2.0 - y: 2.0 + x: 1.0 + y: 1.0 z: 1.0 w: 1.0 } @@ -206,15 +210,15 @@ nodes { w: 1.0 } color { - x: 0.0 - y: 0.0 - z: 0.0 + x: 1.0 + y: 1.0 + z: 1.0 w: 1.0 } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA text: "Button 2" - font: "system_font" + font: "game" id: "text_2" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE @@ -226,9 +230,9 @@ nodes { w: 1.0 } shadow { - x: 1.0 - y: 1.0 - z: 1.0 + x: 0.0 + y: 0.0 + z: 0.0 w: 1.0 } adjust_mode: ADJUST_MODE_FIT @@ -257,14 +261,14 @@ nodes { w: 1.0 } scale { - x: 1.0 - y: 1.0 + x: 0.5 + y: 0.5 z: 1.0 w: 1.0 } size { - x: 200.0 - y: 100.0 + x: 426.0 + y: 190.0 z: 0.0 w: 1.0 } @@ -276,7 +280,7 @@ nodes { } type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA - texture: "" + texture: "gui/green_long" id: "button_3" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE @@ -300,7 +304,7 @@ nodes { nodes { position { x: 0.0 - y: 0.0 + y: 20.0 z: 0.0 w: 1.0 } @@ -311,8 +315,8 @@ nodes { w: 1.0 } scale { - x: 2.0 - y: 2.0 + x: 1.0 + y: 1.0 z: 1.0 w: 1.0 } @@ -323,15 +327,15 @@ nodes { w: 1.0 } color { - x: 0.0 - y: 0.0 - z: 0.0 + x: 1.0 + y: 1.0 + z: 1.0 w: 1.0 } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA text: "Button 3" - font: "system_font" + font: "game" id: "text_3" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE @@ -343,9 +347,9 @@ nodes { w: 1.0 } shadow { - x: 1.0 - y: 1.0 - z: 1.0 + x: 0.0 + y: 0.0 + z: 0.0 w: 1.0 } adjust_mode: ADJUST_MODE_FIT diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 3c347cd..e7bc075 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -1,8 +1,17 @@ -local druid = require "druid.druid" +local druid = require("druid.druid") +local druid_settings = require("druid.settings") + +local function setup_druid(self) + druid_settings.play_sound = function(name) + sound.play("sounds#" .. name) + end +end function init(self) + setup_druid(self) self.druid = druid.new(self) + self.druid:new_button("button_1", function() print("On button 1") end) diff --git a/example/game.font b/example/game.font new file mode 100644 index 0000000..2b014d6 --- /dev/null +++ b/example/game.font @@ -0,0 +1,17 @@ +font: "/example/res/exo2.ttf" +material: "/builtins/fonts/font.material" +size: 64 +antialias: 1 +alpha: 1.0 +outline_alpha: 0.0 +outline_width: 0.0 +shadow_alpha: 1.0 +shadow_blur: 0 +shadow_x: 3.0 +shadow_y: -5.0 +extra_characters: "" +output_format: TYPE_BITMAP +all_chars: false +cache_width: 0 +cache_height: 0 +render_mode: MODE_MULTI_LAYER diff --git a/example/gui.atlas b/example/gui.atlas new file mode 100644 index 0000000..0170ec5 --- /dev/null +++ b/example/gui.atlas @@ -0,0 +1,9 @@ +images { + image: "/example/res/gray_long.png" +} +images { + image: "/example/res/green_long.png" +} +margin: 0 +extrude_borders: 0 +inner_padding: 0 diff --git a/example/res/click.ogg b/example/res/click.ogg new file mode 100755 index 0000000000000000000000000000000000000000..5d223f37eea2a29857ca36b536a6190d7afede79 GIT binary patch literal 4880 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 literal 0 HcmV?d00001 diff --git a/example/res/exo2.ttf b/example/res/exo2.ttf new file mode 100755 index 0000000000000000000000000000000000000000..49f0b491d9e3e5581aac064ce8f3134ba5302488 GIT binary patch literal 110068 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 literal 0 HcmV?d00001 diff --git a/example/res/gray_long.png b/example/res/gray_long.png new file mode 100644 index 0000000000000000000000000000000000000000..cc29967043b7264a3656ac885c1640b15976add2 GIT binary patch literal 12428 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 AVE_OC literal 0 HcmV?d00001 From 349f73c515f44c73df4cbc4424b3b2370be44a42 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 27 Mar 2019 09:41:13 +0300 Subject: [PATCH 012/136] play sound example. Setup via settings --- druid/base/button.lua | 7 +++---- druid/druid.lua | 9 --------- druid/settings.lua | 13 ++++++++++++- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index 2edc135..1283f55 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -27,8 +27,8 @@ function M.init(instance, callback, params, animate_node_name, event) instance.tap_anim = M.tap_scale_animation instance.back_anim = M.back_scale_animation instance.hover_anim = b_settings.IS_HOVER - -- instance.sound = sound or BTN_SOUND - -- instance.sound_disable = sound_disable or BTN_SOUND_DISABLED + instance.sound = b_settings.BTN_SOUND + instance.sound_disable = b_settings.BTN_SOUND_DISABLED end @@ -45,7 +45,7 @@ local function on_button_release(instance) if not instance.stub and instance.can_action then instance.can_action = false instance.tap_anim(instance) - -- instance.sound() + settings.play_sound(instance.sound) instance.callback(instance.parent.parent, instance.params, instance) else set_hover(instance, false) @@ -89,7 +89,6 @@ function M.tap_scale_animation(instance) if instance.back_anim then instance.back_anim(instance) end - -- instance.sound() end ) end diff --git a/druid/druid.lua b/druid/druid.lua index 2f3a106..62c2b6a 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -146,14 +146,5 @@ function M.create(factory, module, name, ...) end -function M.get_text(name) - -- override to get text for localized text -end - - -function M.play_sound(name) - -- override to play sound with name -end - register_basic_components() return M \ No newline at end of file diff --git a/druid/settings.lua b/druid/settings.lua index cf86a14..701da36 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -4,7 +4,7 @@ local M = {} M.button = { IS_HOVER = true, IS_HOLD = true, - BTN_SOUND = "button_click", + BTN_SOUND = "click", BTN_SOUND_DISABLED = "button_click_disabled", HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), HOVER_TIME = 0.05, @@ -12,4 +12,15 @@ M.button = { } + +function M.get_text(name) + -- override to get text for localized text +end + + +function M.play_sound(name) + -- override to play sound with name +end + + return M \ No newline at end of file From 1123d09e5d723f63e886c77f9027c77b83cae2ca Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Wed, 27 Mar 2019 11:08:40 +0300 Subject: [PATCH 013/136] Feature/component register (#1) * remove components from main factory * register base components in factory, interest moved to druid.data * add simple usage of button * translatable should be in data * ability to extend components, stubs for sounds and locale --- druid/base/android_back.lua | 11 + druid/base/button.lua | 139 ++++++++++ druid/base/text.lua | 42 +++ druid/base/timer.lua | 53 ++++ druid/data.lua | 20 ++ druid/druid.lua | 398 +++++------------------------ druid/help_modules/druid_input.lua | 9 - example/example.gui | 121 +++++++++ example/example.gui.gui_script | 24 +- game.project | 4 +- 10 files changed, 465 insertions(+), 356 deletions(-) create mode 100644 druid/base/android_back.lua create mode 100644 druid/base/button.lua create mode 100644 druid/base/text.lua create mode 100644 druid/base/timer.lua create mode 100644 druid/data.lua diff --git a/druid/base/android_back.lua b/druid/base/android_back.lua new file mode 100644 index 0000000..a237675 --- /dev/null +++ b/druid/base/android_back.lua @@ -0,0 +1,11 @@ +local M = {} + +--- input handler +-- @param action_id - input action id +-- @param action - input action +function M.on_input(instance, action_id, action) + instance.callback(instance.parent.parent) + return true +end + +return M diff --git a/druid/base/button.lua b/druid/base/button.lua new file mode 100644 index 0000000..9b3b722 --- /dev/null +++ b/druid/base/button.lua @@ -0,0 +1,139 @@ +local data = require("druid.data") +local ui_animate = require "druid.help_modules.druid_animate" + +local M = {} +M.interest = { + data.ON_INPUT +} + +M.DEFAULT_SCALE_CHANGE = vmath.vector3(-0.05, - 0.1, 1) +M.DEFAULT_POS_CHANGE = vmath.vector3(0, - 10, 0) +M.DEFAULT_MOVE_SPEED = 5 +M.DEFAULT_ALPHA_DOWN = 0.8 +M.DEFAULT_TIME_ANIM = 0.1 +M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) +M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1) +M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) +M.DEFAUL_ACTIVATION_TIME = 0.2 + + +function M.init(instance, callback, event, action, animate_node_name, sound) + instance.event = event or data.A_TOUCH + instance.action = action or data.RELEASED + instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node + instance.scale_from = gui.get_scale(instance.anim_node) + instance.scale_to = instance.scale_from + M.DEFAULT_SCALE_CHANGE + instance.pos = gui.get_position(instance.anim_node) + instance.callback = callback + -- instance.params = params + instance.tap_anim = M.tap_scale_animation + instance.back_anim = M.back_scale_animation + -- instance.sound = sound or M.BTN_SOUND_FUNC + -- instance.sound_disable = sound_disable or M.BTN_SOUND_DISABLE_FUNC +end + +--- Set text to text field +-- @param action_id - input action id +-- @param action - input action +function M.on_input(instance, action_id, action) + if gui.is_enabled(instance.node) and gui.pick_node(instance.node, action.x, action.y) then + if not instance.disabled then + instance.tap_anim(instance) + return true + else + -- instance.sound_disable() + return false + end + end + return false +end + +function M.tap_scale_animation(instance) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, + function() + if instance.back_anim then + instance.back_anim(instance) + end + -- instance.sound() + instance.callback(instance.parent.parent, instance.params, instance) + end + ) +end + +function M.back_scale_animation(instance) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) +end + +function M.tap_tab_animation(instance, force) + ui_animate.alpha(instance, instance.anim_node, M.DEFAULT_ALPHA_DOWN, nil, M.DEFAULT_TIME_ANIM) + ui_animate.fly_to(instance, instance.anim_node, instance.pos + M.DEFAULT_POS_CHANGE, M.DEFAULT_MOVE_SPEED) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, + function() + if instance.back_anim then + instance.back_anim(instance) + end + instance.callback(instance.parent.parent, instance.params, force) + end + ) +end + +function M.back_tab_animation(instance) + ui_animate.alpha(instance, instance.anim_node, 1, nil, M.DEFAULT_TIME_ANIM) + ui_animate.fly_to(instance, instance.anim_node, instance.pos, M.DEFAULT_MOVE_SPEED) + ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) +end + +function M.deactivate(instance, is_animate, callback) + instance.disabled = true + if is_animate then + local counter = 0 + local clbk = function() + counter = counter + 1 + if counter == 3 and callback then + callback(instance.parent.parent) + end + end + ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, + gui.EASING_OUTBOUNCE) + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + else + gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) + gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) + if callback then + callback(instance.parent.parent) + end + end +end + +function M.activate(instance, is_animate, callback) + if is_animate then + local counter = 0 + local clbk = function() + counter = counter + 1 + if counter == 3 then + instance.disabled = false + if callback then + callback(instance.parent.parent) + end + end + end + ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, + gui.EASING_OUTBOUNCE) + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, + M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + else + gui.set_color(instance.node, ui_animate.TINT_SHOW) + gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) + instance.disabled = false + if callback then + callback(instance.parent.parent) + end + end +end + +return M diff --git a/druid/base/text.lua b/druid/base/text.lua new file mode 100644 index 0000000..fbc6eb1 --- /dev/null +++ b/druid/base/text.lua @@ -0,0 +1,42 @@ +local M = {} + +local ui_animate = require "druid.help_modules.druid_animate" + +--- Bounce text field +function M.bounce(instance, callback) + gui.set_scale(instance.node, instance.scale_from) + ui_animate.bounce(nil, instance.node, instance.scale_to, callback) +end + +--- Set text to text field +-- @param set_to - set value to text field +function M.set_to(instance, set_to) + instance.last_value = set_to + gui.set_text(instance.node, set_to) +end + +--- Set color +-- @param color +function M.set_color(instance, color) + instance.last_color = color + gui.set_color(instance.node, color) +end + +--- Set scale +-- @param scale +function M.set_scale(instance, scale) + instance.last_scale = scale + gui.set_scale(instance.node, scale) +end + +--- Called when layout updated (rotate for example) +function M.on_layout_updated(instance) + if instance.last_color then + M.set_color(instance, instance.last_color) + end + if instance.last_scale then + M.set_scale(instance, instance.last_scale) + end +end + +return M diff --git a/druid/base/timer.lua b/druid/base/timer.lua new file mode 100644 index 0000000..3f7329d --- /dev/null +++ b/druid/base/timer.lua @@ -0,0 +1,53 @@ +local M = {} + +local formats = require "druid.help_modules.formats" + +--- Set text to text field +-- @param set_to - set value in seconds +function M.set_to(instance, set_to) + instance.last_value = set_to + gui.set_text(instance.node, formats.second_string_min(set_to)) +end + +--- Called when layout updated (rotate for example) +function M.on_layout_updated(instance) + M.set_to(instance, instance.last_value) +end + +--- Called when update +-- @param is_on - boolean is timer on +function M.set_work_mode(instance, is_on) + instance.is_on = is_on +end + +--- Set time interval +-- @param from - "from" time in seconds +-- @param to - "to" time in seconds +function M.set_interval(instance, from, to) + instance.second_from = from + instance.seconds_counter = from + instance.seconds_temp = 0 + instance.seconds_to = to + instance.second_step = from < to and 1 or - 1 + M.set_work_mode(instance, true) + M.set_to(instance, from) +end + +--- Called when update +-- @param dt - delta time +function M.on_updated(instance, dt) + if instance.is_on then + instance.seconds_temp = instance.seconds_temp + dt + if instance.seconds_temp > 1 then + instance.seconds_temp = instance.seconds_temp - 1 + instance.seconds_counter = instance.seconds_counter + instance.second_step + M.set_to(instance, instance.seconds_counter) + if instance.seconds_counter == instance.seconds_to then + instance.is_on = false + instance.callback(instance) + end + end + end +end + +return M diff --git a/druid/data.lua b/druid/data.lua new file mode 100644 index 0000000..5fa1129 --- /dev/null +++ b/druid/data.lua @@ -0,0 +1,20 @@ +local M = {} + +M.A_TOUCH = hash("touch") +M.A_TEXT = hash("text") +M.A_BACKSPACE = hash("backspace") +M.A_ENTER = hash("enter") +M.A_ANDR_BACK = hash("back") + +-- interest +M.LAYOUT_CHANGED = hash("layout_changed") +M.ON_MESSAGE = hash("on_message") +M.ON_INPUT = hash("on_input") +M.ON_SWIPE = hash("on_swipe") +M.ON_UPDATE = hash("on_update") +M.TRANSLATABLE = hash("TRANSLATABLE") + +M.RELEASED = "released" +M.PRESSED = "pressed" + +return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index 4c34465..f95655d 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,92 +1,75 @@ +local data = require("druid.data") +local druid_input = require("druid.help_modules.druid_input") + local M = {} -local druid_input = require "druid.help_modules.druid_input" -M.input = druid_input - -local pie_progress_bar = require "druid.components.pie_progress_bar" -local progress_bar = require "druid.components.progress_bar" -local flying_particles = require "druid.components.flying_particles" -local text_field = require "druid.components.text_field" -local counter = require "druid.components.counter" -local image = require "druid.components.image" -local button = require "druid.components.button" -local timer = require "druid.components.timer" -local tab_page = require "druid.components.tab_page" -local tabs_container = require "druid.components.tabs_container" -local spine_anim = require "druid.components.spine_anim" -local scrolling_box = require "druid.components.scrolling_box" - -local andr_back_btn = require "druid.components.andr_back_btn" - -local LAYOUT_CHANGED = hash("layout_changed") -local ON_MESSAGE = hash("on_message") -local ON_INPUT = hash("on_input") -local ON_SWIPE = hash("on_swipe") -local ON_UPDATE = hash("on_update") -M.TRANSLATABLE = hash("TRANSLATABLE") - local STRING = "string" ---- Call this method when you need to update translations. -function M.translate(factory) - if factory[M.TRANSLATABLE] then - local key, result - for i, v in ipairs(factory[M.TRANSLATABLE]) do - key = v.lang_key or v.name - if key then - if v.lang_params then - result = lang.txp(key, v.lang_params) - else - result = lang.txt(key) - end - if result then - lang.set_node_properties(v.node, key) - end - result = result or v.last_value - v:set_to(result) - end - end +--- New druid era, registering components +local components = { + -- basic + button = require("druid.base.button"), + -- text = require("druid.base.text"), + -- android_back = require("druid.base.android_back"), + -- timer = require("druid.base.timer"), +} + + +local function register_basic_components() + for k, v in pairs(components) do + M.register(k, v) end end +register_basic_components() + + +function M.register(name, module) + -- TODO: Find better solution to creating elements? + M["new_" .. name] = function(factory, node_name, ...) + M.create(factory, module, node_name, ...) + end + print("[Druid]: register component", name) +end --- Called on_message function M.on_message(factory, message_id, message, sender) - if message_id == LAYOUT_CHANGED then - if factory[LAYOUT_CHANGED] then + if message_id == data.LAYOUT_CHANGED then + if factory[data.LAYOUT_CHANGED] then M.translate(factory) - for i, v in ipairs(factory[LAYOUT_CHANGED]) do + for i, v in ipairs(factory[data.LAYOUT_CHANGED]) do v:on_layout_updated(message) end end - elseif message_id == M.TRANSLATABLE then + elseif message_id == data.TRANSLATABLE then M.translate(factory) else - if factory[ON_MESSAGE] then - for i, v in ipairs(factory[ON_MESSAGE]) do + if factory[data.ON_MESSAGE] then + for i, v in ipairs(factory[data.ON_MESSAGE]) do v:on_message(message_id, message, sender) end end end end + --- Called ON_INPUT function M.on_input(factory, action_id, action) - if factory[ON_SWIPE] then + if factory[data.ON_SWIPE] then local v, result - local len = #factory[ON_SWIPE] + local len = #factory[data.ON_SWIPE] for i = 1, len do - v = factory[ON_SWIPE][i] + v = factory[data.ON_SWIPE][i] result = result or v:on_input(action_id, action) end if result then return true end end - if factory[ON_INPUT] then + if factory[data.ON_INPUT] then local v - local len = #factory[ON_INPUT] + local len = #factory[data.ON_INPUT] for i = 1, len do - v = factory[ON_INPUT][i] + v = factory[data.ON_INPUT][i] if action_id == v.event and action[v.action] and v:on_input(action_id, action) then return true end @@ -96,15 +79,17 @@ function M.on_input(factory, action_id, action) return false end + --- Called on_update -function M.on_update(factory, dt) - if factory[ON_UPDATE] then - for i, v in ipairs(factory[ON_UPDATE]) do - v:on_updated(dt) +function M.update(factory, dt) + if factory[data.ON_UPDATE] then + for i, v in ipairs(factory[data.ON_UPDATE]) do + v:update(dt) end end end + --- Create UI instance for ui elements -- @return instance with all ui components function M.new(self) @@ -113,6 +98,7 @@ function M.new(self) return factory end + local function input_init(factory) if not factory.input_inited then factory.input_inited = true @@ -122,8 +108,8 @@ end -------------------------------------------------------------------------------- -local function create(meta, factory, name, ...) - local instance = setmetatable({}, {__index = meta}) +local function create(module, factory, name, ...) + local instance = setmetatable({}, {__index = module}) instance.parent = factory if name then if type(name) == STRING then @@ -136,285 +122,39 @@ local function create(meta, factory, name, ...) end end factory[#factory + 1] = instance - local register_to = {...} + + local register_to = module.interest or {} for i, v in ipairs(register_to) do if not factory[v] then factory[v] = {} end factory[v][#factory[v] + 1] = instance - end - return instance -end ---- Create new instance of a text_field --- @param factory - parent factory --- @param name - name of text node --- @param init_value - init ui object with this value --- @return instance of a text_field -function M.new_text_field(factory, name, init_value, bounce_in) - local instance = create(text_field, factory, name, M.TRANSLATABLE, LAYOUT_CHANGED) - instance.scale_from = gui.get_scale(instance.node) - instance.scale_to = bounce_in and vmath.mul_per_elem(instance.scale_from, bounce_in) or instance.scale_from - instance:set_to(init_value or 0) - return instance -end - ---- Create new instance of a counter --- @param factory - parent factory --- @param name - name of text node --- @param init_value - init ui object with this value --- @return instance of a text_field -function M.new_counter(factory, name, init_value) - local instance = create(counter, factory, name, LAYOUT_CHANGED, ON_UPDATE) - instance.scale_from = gui.get_scale(instance.node) - instance.scale_to = instance.scale_from * 1.2 - instance:set_to(init_value or 0) - return instance -end - ---- Create new instance of an image --- @param factory - parent factory --- @param name - name of image node --- @param anim_table - table with animations or frames --- @param init_frame - init with this frame --- @return instance of an image -function M.new_image(factory, name, anim_table, init_frame, bounce_in) - local instance = create(image, factory, name, LAYOUT_CHANGED) - instance.scale_from = gui.get_scale(instance.node) - instance.scale_to = bounce_in and vmath.mul_per_elem(instance.scale_from, bounce_in) or instance.scale_from - instance.anim_table = anim_table - if init_frame then - instance:set_to(init_frame) - elseif anim_table then - instance:set_to(1) - end - return instance -end - ---- Create new instance of a timer --- @param factory - parent factory --- @param name - name of image node --- @param second_from - start time --- @param seconds_to - end time --- @param callback - call when timer finished --- @return instance of a timer -function M.new_timer(factory, name, second_from, seconds_to, callback) - local instance = create(timer, factory, name, LAYOUT_CHANGED, ON_UPDATE) - instance:set_to(second_from) - instance:set_interval(second_from, seconds_to) - instance.is_on = true - instance.callback = callback - return instance -end - ---- Add new pie progress component for handling --- @param factory - parent factory --- @param name - a node name for a pie progress instance --- @param init_value - init ui object with this value --- @return instance with pie_progress -function M.new_pie_progress(factory, name, init_value) - local instance = create(pie_progress_bar, factory, name, LAYOUT_CHANGED) - instance:set_to(init_value or 1) - return instance -end - ---- Add new progress bar component for handling --- @param factory - parent factory --- @param name - name of the fill node --- @param key - x or y - key for scale --- @param init_value - init ui object with this value --- @return instance with pie_progress -function M.new_progress_bar(factory, name, key, init_value) - local instance = create(progress_bar, factory, name, LAYOUT_CHANGED) - instance.prop = hash("scale."..key) - instance.key = key - instance.node = gui.get_node(name) - instance.scale = gui.get_scale(instance.node) - instance:set_to(init_value or 1) - return instance -end - ---- Create new instance of a flying particles --- @param factory - parent factory --- @param name - name of prototype --- @param count - how many particles need to cache --- @param get_pos_func - function that returns target pos for flying --- @return instance of a flying particles -function M.new_flying_particles(factory, name, count, get_pos_func) - local instance = create(flying_particles, factory, name, LAYOUT_CHANGED) - instance.get_pos_func = get_pos_func - local node = instance.node - instance.node = node - instance.fly_particles = {} - instance.fly_particles[1] = node - for i = 2, count do - instance.fly_particles[i] = gui.clone(node) - end - instance.scale = gui.get_scale(node) - instance.last_particle = 0 - return instance -end - -M.BTN_SOUND_FUNC = function() end -M.BTN_SOUND_DISABLE_FUNC = function()end - ---- Add new button component for handling --- @param factory - parent factory --- @param name - a node name for a button instance --- @param callback - click button callback --- @param params - callback parameters, will be returned with self callback(self, params) --- @param animate_node_name - node for animation, if it's not a main node --- @return instance of button -function M.new_button(factory, name, callback, params, animate_node_name, event, action, sound, sound_disable) - input_init(factory) - local instance = create(button, factory, name, ON_INPUT) - instance.event = event or druid_input.A_CLICK - instance.action = action or druid_input.RELEASED - instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node - instance.scale_from = gui.get_scale(instance.anim_node) - instance.scale_to = instance.scale_from + button.DEFAULT_SCALE_CHANGE - instance.pos = gui.get_position(instance.anim_node) - instance.callback = callback - instance.params = params - instance.tap_anim = button.tap_scale_animation - instance.back_anim = button.back_scale_animation - instance.sound = sound or M.BTN_SOUND_FUNC - instance.sound_disable = sound_disable or M.BTN_SOUND_DISABLE_FUNC - return instance -end - ---- Add reaction for back btn (on Android for example) --- @param factory - parent factory --- @param callback - tap button callback -function M.new_back_handler(factory, callback) - input_init(factory) - local instance = create(andr_back_btn, factory, nil, ON_INPUT) - instance.event = druid_input.A_ANDR_BACK - instance.action = druid_input.RELEASED - instance.callback = callback - return instance -end - ---- Create new tab page instance --- @param factory - parent factory --- @param name - name of parental node that represents tab page content --- @param easing - easing for tab page --- @param duration - duration of animation for tab page --- @param callback - call when change page --- @return instance that represents the tab page -function M.new_tab_page(factory, name, easing, duration, callback) - local instance = create(tab_page, factory, name, M.EVENTS.ON_MESSAGE) - instance.in_pos = gui.get_position(instance.node) - instance.out_pos = gui.get_position(instance.node) - instance.easing = easing or tab_page.DEFAULT_EASING - instance.duration = duration or tab_page.DEFAULT_DURATION - instance.callback = callback - return instance -end - ---- Create new tab btns container instance --- @param factory - parent factory --- @param name - name of parental node that represents tab btns container --- @return instance that represents the tab btns container -function M.new_tabs_container(factory, name, callback) - local instance = create(tabs_container, factory, name, LAYOUT_CHANGED) - instance:update_sizes() - instance.url = msg.url() - --- Create new tab btn instance - -- @param name - name of parental node that represents tab btn - -- @return instance that represents the tab btn - function instance.new_tab_btn(_instance, _name, url, index) - local params = {url = url, index = index, name = _name} - local btn = M.new_button(factory, _name, nil, params) - btn.back_anim = nil - btn.manual_back = button.back_tab_animation - btn.tap_anim = button.tap_tab_animation - btn.callback = function(_, _, force) - instance.switch_tab(instance, params, force) - if callback then - callback(factory.parent, index, force) - end + if v == data.ON_INPUT then + input_init(factory) end - instance[_name] = params - if not instance.btns then - instance.btns = {} - end - instance.btns[index] = btn - return btn end - return instance end ---- Add new spine animation --- @param factory - parent factory --- @param name - a node name for a spine anim --- @param idle_table - table with idle animations --- @param active_table - table with active animations --- @param init_idle - init idle animation name or index in idle table --- @return instance with spine anim -function M.new_spine_anim(factory, name, idle_table, active_table, init_idle) - local instance = create(spine_anim, factory, name, LAYOUT_CHANGED) - instance.idle_table = idle_table - instance.active_table = active_table - instance:play_idle(init_idle) - return instance + +function M.create(factory, module, name, ...) + local instance = create(module, factory, name) + + if instance.init then + instance:init(...) + end end ---- Add new scrolling box --- @param factory - parent factory --- @param name - a node name for a spine anim --- @param zone_name - node name of zone for tap --- @param speed_coef - vector3 coef. of speed for scrolling --- @param maximum - vector3 maximum position for scrolling --- @param points_of_interest - table with vector3 point of interes --- @param callback - scrolling events callback --- @return instance with scrolling box -function M.new_scrolling_box(factory, name, zone_name, speed_coef, maximum, points_of_interest, callback) - local instance = create(scrolling_box, factory, name, ON_UPDATE, ON_SWIPE) - instance.pos = gui.get_position(instance.node) - instance.start_pos = vmath.vector3(instance.pos) - instance.maximum = maximum - instance.points_of_interest = points_of_interest - instance.callback = callback - if instance.start_pos.x > instance.maximum.x then - instance.start_pos.x, instance.maximum.x = instance.maximum.x, instance.start_pos.x - end - if instance.start_pos.y > instance.maximum.y then - instance.start_pos.y, instance.maximum.y = instance.maximum.y, instance.start_pos.y - end - if type(name) == STRING then - instance.scrolling_zone = gui.get_node(zone_name) - else - instance.scrolling_zone = zone_name - end - instance.swipe = { - minSwipeDistance = 40, - speed_down_coef = 1.1, - speed_up_coef = speed_coef or vmath.vector3(1.1, 1.1, 0), - speed = vmath.vector3(0, 0, 0), - maximum = vmath.vector3(0, 0, 0), - min_speed = 2, - beginX = 0, - beginY = 0, - endX = 0, - endY = 0, - xDistance = nil, - yDistance = nil, - totalSwipeDistanceLeft = nil, - totalSwipeDistanceRight = nil, - totalSwipeDistanceUp = nil, - totalSwipeDistanceDown = nil, - is_swipe = nil, - end_move_coef_x = 1, - end_move_coef_y = 1, - back_slow_coef = 0.4, - end_position_x = nil, - end_position_y = nil, - is_x = instance.start_pos.x ~= instance.maximum.x, - is_y = instance.start_pos.y ~= instance.maximum.y - } - return instance + +function M.get_text(name) + -- override to get text for localized text end -return M + +function M.play_sound(name) + -- override to play sound with name +end + + +return M \ No newline at end of file diff --git a/druid/help_modules/druid_input.lua b/druid/help_modules/druid_input.lua index 21ac43a..bc2665a 100644 --- a/druid/help_modules/druid_input.lua +++ b/druid/help_modules/druid_input.lua @@ -4,15 +4,6 @@ local ADD_FOCUS = hash("acquire_input_focus") local REMOVE_FOCUS = hash("release_input_focus") local PATH_OBJ = "." -M.A_CLICK = hash("click") -M.A_TEXT = hash("text") -M.A_BACKSPACE = hash("backspace") -M.A_ENTER = hash("enter") -M.A_ANDR_BACK = hash("back") - -M.RELEASED = "released" -M.PRESSED = "pressed" - function M.focus() msg.post(PATH_OBJ, ADD_FOCUS) end diff --git a/example/example.gui b/example/example.gui index 12b1015..b01879a 100644 --- a/example/example.gui +++ b/example/example.gui @@ -1,10 +1,131 @@ script: "/example/example.gui.gui_script" +fonts { + name: "system_font" + font: "/builtins/fonts/system_font.font" +} background_color { x: 0.0 y: 0.0 z: 0.0 w: 0.0 } +nodes { + position { + x: 200.0 + y: 200.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: 200.0 + y: 100.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: "" + id: "button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: 0.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: 2.0 + y: 2.0 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "button text" + font: "system_font" + id: "text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} 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 ce07f4f..c7ea0d3 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -1,29 +1,21 @@ local druid = require "druid.druid" function init(self) -end + self.druid = druid.new(self) -function final(self) - -- Add finalization code here - -- Remove this function if not needed + self.button = self.druid:new_button("button", function() + print("New click") + end) end function update(self, dt) - -- Add update code here - -- Remove this function if not needed + self.druid:update(dt) end function on_message(self, message_id, message, sender) - -- Add message-handling code here - -- Remove this function if not needed + self.druid:on_message(message_id, message, sender) end function on_input(self, action_id, action) - -- Add input-handling code here - -- Remove this function if not needed -end - -function on_reload(self) - -- Add input-handling code here - -- Remove this function if not needed -end + self.druid:on_input(action_id, action) +end \ No newline at end of file diff --git a/game.project b/game.project index a165b1d..adf34bf 100644 --- a/game.project +++ b/game.project @@ -5,8 +5,8 @@ main_collection = /example/example.collectionc shared_state = 1 [display] -width = 960 -height = 640 +width = 400 +height = 400 [project] title = druid From 3996ba4b040f1554025e0a2062a7173de096eaba Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Wed, 27 Mar 2019 22:19:47 +0300 Subject: [PATCH 014/136] Feature/timer (#3) * add timer component * remov old components folder --- druid/base/timer.lua | 65 +++++-- druid/components/button.lua | 119 ------------- druid/components/counter.lua | 67 ------- druid/components/flying_particles.lua | 52 ------ druid/components/image.lua | 46 ----- druid/components/pie_progress_bar.lua | 51 ------ druid/components/progress_bar.lua | 93 ---------- druid/components/scrolling_box.lua | 241 -------------------------- druid/components/spine_anim.lua | 62 ------- druid/components/tab_page.lua | 92 ---------- druid/components/tabs_container.lua | 50 ------ druid/components/text_field.lua | 42 ----- druid/components/timer.lua | 53 ------ druid/druid.lua | 2 +- druid/helper/ui_helper.lua | 8 + example/example.gui.gui_script | 4 + 16 files changed, 61 insertions(+), 986 deletions(-) delete mode 100644 druid/components/button.lua delete mode 100644 druid/components/counter.lua delete mode 100644 druid/components/flying_particles.lua delete mode 100644 druid/components/image.lua delete mode 100644 druid/components/pie_progress_bar.lua delete mode 100644 druid/components/progress_bar.lua delete mode 100644 druid/components/scrolling_box.lua delete mode 100644 druid/components/spine_anim.lua delete mode 100644 druid/components/tab_page.lua delete mode 100644 druid/components/tabs_container.lua delete mode 100644 druid/components/text_field.lua delete mode 100644 druid/components/timer.lua diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 7802a49..5f2a6ab 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,6 +1,32 @@ +local data = require("druid.data") +local formats = require("druid.helper.formats") +local helper = require("druid.helper.ui_helper") + local M = {} -local formats = require "druid.helper.formats" +M.interest = { + data.LAYOUT_CHANGED, + data.ON_UPDATE +} + +local empty = function() end + +function M.init(instance, seconds_from, seconds_to, callback) + seconds_from = math.max(seconds_from, 0) + seconds_to = math.max(seconds_to or 0, 0) + callback = callback or empty + + instance:set_to(seconds_from) + instance:set_interval(seconds_from, seconds_to) + instance.callback = callback + + if seconds_to - seconds_from == 0 then + instance:set_state(false) + instance.callback(instance.parent.parent, instance) + end + return instance +end + --- Set text to text field -- @param set_to - set value in seconds @@ -9,42 +35,47 @@ function M.set_to(instance, set_to) gui.set_text(instance.node, formats.second_string_min(set_to)) end + --- Called when layout updated (rotate for example) function M.on_layout_updated(instance) M.set_to(instance, instance.last_value) end + --- Called when update -- @param is_on - boolean is timer on -function M.set_work_mode(instance, is_on) +function M.set_state(instance, is_on) instance.is_on = is_on end + --- Set time interval -- @param from - "from" time in seconds -- @param to - "to" time in seconds function M.set_interval(instance, from, to) - instance.second_from = from - instance.seconds_counter = from - instance.seconds_temp = 0 - instance.seconds_to = to - instance.second_step = from < to and 1 or - 1 - M.set_work_mode(instance, true) + instance.from = from + instance.value = from + instance.temp = 0 + instance.target = to + M.set_state(instance, true) M.set_to(instance, from) end + --- Called when update -- @param dt - delta time -function M.on_updated(instance, dt) +function M.update(instance, dt) if instance.is_on then - instance.seconds_temp = instance.seconds_temp + dt - if instance.seconds_temp > 1 then - instance.seconds_temp = instance.seconds_temp - 1 - instance.seconds_counter = instance.seconds_counter + instance.second_step - M.set_to(instance, instance.seconds_counter) - if instance.seconds_counter == instance.seconds_to then - instance.is_on = false - instance.callback(instance) + instance.temp = instance.temp + dt + local dist = math.min(1, math.abs(instance.value - instance.target)) + + if instance.temp > dist then + instance.temp = instance.temp - dist + instance.value = helper.step(instance.value, instance.target, 1) + M.set_to(instance, instance.value) + if instance.value == instance.target then + instance:set_state(false) + instance.callback(instance.parent.parent, instance) end end end diff --git a/druid/components/button.lua b/druid/components/button.lua deleted file mode 100644 index 9160de6..0000000 --- a/druid/components/button.lua +++ /dev/null @@ -1,119 +0,0 @@ -local M = {} - -local ui_animate = require "druid.helper.druid_animate" - -M.DEFAULT_SCALE_CHANGE = vmath.vector3(-0.05, - 0.1, 1) -M.DEFAULT_POS_CHANGE = vmath.vector3(0, - 10, 0) -M.DEFAULT_MOVE_SPEED = 5 -M.DEFAULT_ALPHA_DOWN = 0.8 -M.DEFAULT_TIME_ANIM = 0.1 -M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) -M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1) -M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) -M.DEFAUL_ACTIVATION_TIME = 0.2 - ---- Set text to text field --- @param action_id - input action id --- @param action - input action -function M.on_input(instance, action_id, action) - if gui.is_enabled(instance.node) and gui.pick_node(instance.node, action.x, action.y) then - if not instance.disabled then - instance.tap_anim(instance) - return true - else - instance.sound_disable() - return false - end - end - return false -end - -function M.tap_scale_animation(instance) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, - function() - if instance.back_anim then - instance.back_anim(instance) - end - instance.sound() - instance.callback(instance.parent.parent, instance.params, instance) - end - ) -end - -function M.back_scale_animation(instance) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) -end - -function M.tap_tab_animation(instance, force) - ui_animate.alpha(instance, instance.anim_node, M.DEFAULT_ALPHA_DOWN, nil, M.DEFAULT_TIME_ANIM) - ui_animate.fly_to(instance, instance.anim_node, instance.pos + M.DEFAULT_POS_CHANGE, M.DEFAULT_MOVE_SPEED) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, - function() - if instance.back_anim then - instance.back_anim(instance) - end - instance.callback(instance.parent.parent, instance.params, force) - end - ) -end - -function M.back_tab_animation(instance) - ui_animate.alpha(instance, instance.anim_node, 1, nil, M.DEFAULT_TIME_ANIM) - ui_animate.fly_to(instance, instance.anim_node, instance.pos, M.DEFAULT_MOVE_SPEED) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) -end - -function M.deactivate(instance, is_animate, callback) - instance.disabled = true - if is_animate then - local counter = 0 - local clbk = function() - counter = counter + 1 - if counter == 3 and callback then - callback(instance.parent.parent) - end - end - ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, - gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - else - gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) - gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) - if callback then - callback(instance.parent.parent) - end - end -end - -function M.activate(instance, is_animate, callback) - if is_animate then - local counter = 0 - local clbk = function() - counter = counter + 1 - if counter == 3 then - instance.disabled = false - if callback then - callback(instance.parent.parent) - end - end - end - ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, - gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - else - gui.set_color(instance.node, ui_animate.TINT_SHOW) - gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) - instance.disabled = false - if callback then - callback(instance.parent.parent) - end - end -end - -return M diff --git a/druid/components/counter.lua b/druid/components/counter.lua deleted file mode 100644 index 35b1389..0000000 --- a/druid/components/counter.lua +++ /dev/null @@ -1,67 +0,0 @@ -local M = {} - -local text_field = require "druid.components.text_field" - -local FRAMES = 60 - ---- Bounce text field -M.bounce = text_field.bounce - ---- Set text to text field --- @param set_to - set value to text field -M.set_to = text_field.set_to - ---- Set color --- @param color -M.set_color = text_field.set_color - ---- Set scale --- @param scale -M.set_scale = text_field.set_scale - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - text_field.on_layout_updated(instance) - if instance.last_value then - text_field.set_to(instance, instance.last_value) - end -end - ---- Animate counter --- @param set_to - set value to text field -function M.animate_to(instance, set_to, frames) - if set_to == instance.last_value then - text_field.set_to(instance, set_to) - elseif not instance.is_animate then - frames = frames or FRAMES - instance.end_anim_value = set_to - local diff = set_to - instance.last_value - instance.anim_step = math.floor((set_to - instance.last_value) / frames) - if diff ~= 0 and instance.anim_step == 0 then - instance.anim_step = diff > 0 and 1 or - 1 - end - instance.is_animate = true - else - instance.end_anim_value = set_to - end -end - ---- Called when update --- @param dt - delta time -function M.on_updated(instance, dt) - if instance.is_animate then - instance.last_value = instance.last_value + instance.anim_step - text_field.set_to(instance, instance.last_value) - if not instance.is_in_bounce then - instance.is_in_bounce = true - text_field.bounce(instance, function() instance.is_in_bounce = false end) - end - if instance.anim_step > 0 and instance.last_value >= instance.end_anim_value or - instance.anim_step < 0 and instance.last_value <= instance.end_anim_value then - instance.is_animate = false - text_field.set_to(instance, instance.end_anim_value) - end - end -end - -return M diff --git a/druid/components/flying_particles.lua b/druid/components/flying_particles.lua deleted file mode 100644 index 5a63cb3..0000000 --- a/druid/components/flying_particles.lua +++ /dev/null @@ -1,52 +0,0 @@ -local M = {} - -local ui_animate = require "druid.helper.druid_animate" - -local function fly_to(instance, pos_from, speed, callback) - local pos_to = instance.get_pos_func() - instance.last_speed = speed - instance.last_callback = callback - - instance.last_particle = instance.last_particle + 1 - if instance.last_particle > #instance.fly_particles then - instance.last_particle = 1 - end - local fly_particle = instance.fly_particles[instance.last_particle] - if pos_from then - gui.set_position(fly_particle, pos_from) - end - gui.play_particlefx(fly_particle) - instance.is_anim = true - ui_animate.fly_to(nil, fly_particle, pos_to, speed, - function() - instance.is_anim = false - gui.stop_particlefx(fly_particle) - if callback then - callback(instance.parent.parent) - instance.last_callback = nil - end - end, - 0, gui.EASING_INSINE) -end - ---- Start animation of a flying particles --- @param pos_from - fly from this position --- @param speed - speed of flying --- @param callback - callback when progress ended if need -function M.fly_to(instance, pos_from, speed, callback) - fly_to(instance, pos_from, speed, callback) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if instance.is_anim then - instance.last_particle = instance.last_particle - 1 - if instance.last_particle < 1 then - instance.last_particle = #instance.fly_particles - end - fly_to(instance, nil, instance.last_speed, instance.last_callback) - end -end - - -return M diff --git a/druid/components/image.lua b/druid/components/image.lua deleted file mode 100644 index cfdf6db..0000000 --- a/druid/components/image.lua +++ /dev/null @@ -1,46 +0,0 @@ -local M = {} - -local ui_animate = require "druid.helper.druid_animate" - ---- Bounce image -function M.bounce(instance) - gui.set_scale(instance.node, instance.scale_from) - ui_animate.bounce(nil, instance.node, instance.scale_to) -end - ---- Set image anim --- @param set_to - index of animation or animation name -function M.set_to(instance, set_to) - instance.last_value = set_to - gui.play_flipbook(instance.node, instance.anim_table and instance.anim_table[set_to] or set_to) -end - ---- Set position to the image --- @param pos - set position of the image -function M.set_pos(instance, pos) - instance.last_pos = pos - gui.set_position(instance.node, pos) -end - ---- Set tint to the image --- @param color - set color of the image -function M.set_color(instance, color) - instance.last_color = color - gui.set_color(instance.node, color) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if instance.last_value then - M.set_to(instance, instance.last_value) - end - if instance.last_pos then - M.set_pos(instance, instance.last_pos) - end - if instance.last_color then - M.set_color(instance, instance.last_color) - end -end - - -return M diff --git a/druid/components/pie_progress_bar.lua b/druid/components/pie_progress_bar.lua deleted file mode 100644 index ec8533b..0000000 --- a/druid/components/pie_progress_bar.lua +++ /dev/null @@ -1,51 +0,0 @@ -local M = {} - -local FULL_FILL = 360 - -local function set_bar_to(instance, set_to) - instance.last_value = set_to - gui.cancel_animation(instance.node, gui.PROP_FILL_ANGLE) - gui.set_fill_angle(instance.node, FULL_FILL * set_to) -end - ---- Fill a pie progress bar and stop progress animation -function M.fill_bar(instance) - set_bar_to(instance, 1) -end - ---- To empty a pie progress bar -function M.empty_bar(instance) - set_bar_to(instance, 0) -end - ---- Set fill a pie progress bar to value --- @param to - value between 0..1 -function M.set_to(instance, to) - set_bar_to(instance, to) -end - ---- Start animation of a pie progress bar --- @param to - value between 0..1 --- @param duration - time of animation --- @param callback - callback when progress ended if need -function M.start_progress_to(instance, to, duration, callback) - instance.is_anim = true - instance.last_value = to - gui.animate(instance.node, gui.PROP_FILL_ANGLE, FULL_FILL * to, gui.EASING_LINEAR, duration, 0, - function() - instance.is_anim = false - if callback then - callback(instance.parent.parent) - end - end - ) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if not instance.is_anim then - set_bar_to(instance, instance.last_value) - end -end - -return M diff --git a/druid/components/progress_bar.lua b/druid/components/progress_bar.lua deleted file mode 100644 index bb60693..0000000 --- a/druid/components/progress_bar.lua +++ /dev/null @@ -1,93 +0,0 @@ -local M = {} - -local function set_bar_to(instance, set_to) - instance.last_value = set_to - gui.cancel_animation(instance.node, instance.prop) - instance.scale[instance.key] = set_to - gui.set_scale(instance.node, instance.scale) -end - -local function circle_anim(instance, full, steps, num, full_duration, callback) - local duration = (math.abs(steps[num - 1] - steps[num]) / full) * full_duration - local to = steps[num] - gui.animate(instance.node, instance.prop, to, gui.EASING_LINEAR, duration, 0, - function() - callback(num, callback) - end - ) -end - ---- Fill a progress bar and stop progress animation -function M.fill_bar(instance) - set_bar_to(instance, 1) -end - ---- To empty a progress bar -function M.empty_bar(instance) - set_bar_to(instance, 0) -end - ---- Set fill a progress bar to value --- @param to - value between 0..1 -function M.set_to(instance, to) - set_bar_to(instance, to) -end - ---- Start animation of a progress bar --- @param to - value between 0..1 --- @param duration - time of animation --- @param callback - callback when progress ended if need --- @param callback_values - whitch values should callback -function M.start_progress_to(instance, to, duration, callback, callback_values) - instance.is_anim = true - local steps - if callback_values then - steps = {instance.last_value} - if instance.last_value > to then - table.sort(callback_values, function(a, b) return a > b end) - else - table.sort(callback_values, function(a, b) return a < b end) - end - for i, v in ipairs(callback_values) do - if (instance.last_value > v and to < v) or (instance.last_value < v and to > v) then - steps[#steps + 1] = v - end - end - steps[#steps + 1] = to - end - if not steps then - gui.animate(instance.node, instance.prop, to, gui.EASING_LINEAR, duration, 0, - function() - set_bar_to(instance, to) - instance.is_anim = false - if callback then - callback(instance.parent.parent, to) - end - end - ) - else - local full = math.abs(steps[1] - steps[#steps]) - local _callback = function (num, _callback) - if num == #steps then - set_bar_to(instance, steps[num]) - instance.is_anim = false - callback(instance.parent.parent, steps[num]) - else - callback(instance.parent.parent, steps[num]) - num = num + 1 - circle_anim(instance, full, steps, num, duration, _callback) - end - end - circle_anim(instance, full, steps, 2, duration, _callback) - end -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if not instance.is_anim then - set_bar_to(instance, instance.last_value) - end -end - - -return M diff --git a/druid/components/scrolling_box.lua b/druid/components/scrolling_box.lua deleted file mode 100644 index 4982194..0000000 --- a/druid/components/scrolling_box.lua +++ /dev/null @@ -1,241 +0,0 @@ -local M = {} - -local druid_input = require "druid.helper.druid_input" -local ui_animate = require "druid.helper.druid_animate" - -M.START = hash("START") -M.FINISH = hash("FINISH") - -M.SCROLLING = hash("SCROLLING") -M.INTEREST_MOVE = hash("INTEREST_MOVE") -M.OUT_OF_ZONE_MOVE = hash("OUT_OF_ZONE_MOVE") - -M.BACK_TIME = 0.2 -M.ANIM_TIME = 0.4 - -local function callback(instance, event, type, param) - if instance.callback then - instance.callback(instance.parent.parent, event, type, param) - end -end - -local function checkSwipeDirection(swipe, action) - swipe.xDistance = math.abs(swipe.endX - swipe.beginX) - swipe.yDistance = math.abs(swipe.endY - swipe.beginY) - if swipe.is_x and swipe.xDistance > swipe.yDistance then - if swipe.beginX > swipe.endX then - swipe.totalSwipeDistanceLeft = swipe.beginX - swipe.endX - if swipe.totalSwipeDistanceLeft > swipe.minSwipeDistance then - swipe.speed.x = action.dx * swipe.speed_up_coef.x * swipe.end_move_coef_x - return true - else - return false - end - else - swipe.totalSwipeDistanceRight = swipe.endX - swipe.beginX - if swipe.totalSwipeDistanceRight > swipe.minSwipeDistance then - swipe.speed.x = action.dx * swipe.speed_up_coef.x * swipe.end_move_coef_x - return true - else - return false - end - end - elseif swipe.is_y and swipe.xDistance < swipe.yDistance then - if swipe.beginY > swipe.endY then - swipe.totalSwipeDistanceUp = swipe.beginY - swipe.endY - if swipe.totalSwipeDistanceUp > swipe.minSwipeDistance then - swipe.speed.y = action.dy * swipe.speed_up_coef.y * swipe.end_move_coef_y - return true - else - return false - end - else - swipe.totalSwipeDistanceDown = swipe.endY - swipe.beginY - if swipe.totalSwipeDistanceDown > swipe.minSwipeDistance then - swipe.speed.y = action.dy * swipe.speed_up_coef.y * swipe.end_move_coef_y - return true - else - return false - end - end - end -end - -function lenght(x1, y1, x2, y2) - local a, b = x1 - x2, y1 - y2 - return math.sqrt(a * a + b * b) -end - -local function back_move(instance) - if not instance.swipe.end_position_x and not instance.swipe.end_position_y then - if instance.points_of_interest then - local min_index, min_lenght = 0, math.huge - local len - for k, v in pairs(instance.points_of_interest) do - len = lenght(instance.pos.x, instance.pos.y, v.x, v.y) - if len < min_lenght then - min_lenght = len - min_index = k - end - end - instance.swipe.speed.x = 0 - instance.swipe.speed.y = 0 - gui.cancel_animation(instance.node, gui.PROP_POSITION) - instance.swipe.special_move = true - callback(instance, M.START, M.INTEREST_MOVE, instance.points_of_interest[min_index]) - gui.animate(instance.node, gui.PROP_POSITION, instance.points_of_interest[min_index], - gui.EASING_LINEAR, M.ANIM_TIME, 0, - function() - instance.swipe.special_move = false - instance.pos.x = instance.points_of_interest[min_index].x - instance.pos.y = instance.points_of_interest[min_index].y - callback(instance, M.FINISH, M.SCROLLING, instance.pos) - callback(instance, M.FINISH, M.INTEREST_MOVE, instance.pos) - end - ) - else - callback(instance, M.FINISH, M.SCROLLING, instance.pos) - end - end - - if instance.swipe.end_position_x then - local swipe = instance.swipe - swipe.speed.x = 0 - instance.pos.x = swipe.end_position_x - swipe.special_move = true - callback(instance, M.START, M.OUT_OF_ZONE_MOVE, instance.pos) - gui.animate(instance.node, ui_animate.PROP_POS_X, swipe.end_position_x, gui.EASING_INSINE, M.BACK_TIME, 0, - function() - swipe.special_move = false - callback(instance, M.FINISH, M.SCROLLING, instance.pos) - callback(instance, M.FINISH, M.OUT_OF_ZONE_MOVE, instance.pos) - end - ) - swipe.end_position_x = nil - end - if instance.swipe.end_position_y then - local swipe = instance.swipe - swipe.speed.y = 0 - instance.pos.y = swipe.end_position_y - swipe.special_move = true - callback(instance, M.START, M.OUT_OF_ZONE_MOVE, instance.pos) - gui.animate(instance.node, ui_animate.PROP_POS_Y, swipe.end_position_y, gui.EASING_INSINE, M.BACK_TIME, 0, - function() - swipe.special_move = false - callback(instance, M.FINISH, M.SCROLLING, instance.pos) - callback(instance, M.FINISH, M.OUT_OF_ZONE_MOVE, instance.pos) - end - ) - swipe.end_position_y = nil - end -end - ---- Set text to text field --- @param action_id - input action id --- @param action - input action -function M.on_input(instance, action_id, action) - if action_id == druid_input.A_CLICK then - if gui.pick_node(instance.scrolling_zone, action.x, action.y) then - local swipe = instance.swipe - if action.pressed then - swipe.pressed = true - swipe.beginX = action.x - swipe.beginY = action.y - druid_input.is_swipe = false - swipe.end_move_coef_x = 1 - elseif not action.released and not action.pressed and not swipe.special_move then - swipe.endX = action.x - swipe.endY = action.y - local before = swipe.is_swipe - swipe.is_swipe = checkSwipeDirection(swipe, action) - if not before and swipe.is_swipe and not swipe.special_move and not swipe.waiting_for_back_move then - callback(instance, M.START, M.SCROLLING, instance.pos) - end - return swipe.is_swipe or swipe.special_move - elseif action.released then - swipe.beginX = 0 - swipe.beginY = 0 - swipe.endX = 0 - swipe.endY = 0 - swipe.pressed = false - if swipe.waiting_for_back_move then - back_move(instance) - swipe.waiting_for_back_move = false - end - return swipe.is_swipe or swipe.special_move - end - elseif action.released then - instance.swipe.pressed = false - if instance.swipe.waiting_for_back_move then - back_move(instance) - instance.swipe.waiting_for_back_move = false - end - end - end -end - ---- Called when update --- @param dt - delta time -function M.on_updated(instance, dt) - if instance.swipe.speed.x ~= 0 or instance.swipe.speed.y ~= 0 then - local swipe = instance.swipe - instance.pos.x = instance.pos.x + swipe.speed.x - instance.pos.y = instance.pos.y + swipe.speed.y - if instance.pos.x < instance.start_pos.x then - swipe.end_move_coef_x = swipe.back_slow_coef - swipe.end_position_x = instance.start_pos.x - elseif instance.pos.x > instance.maximum.x then - swipe.end_move_coef_x = swipe.back_slow_coef - swipe.end_position_x = instance.maximum.x - else - swipe.end_move_coef_x = 1 - swipe.end_position_x = nil - end - if instance.pos.y < instance.start_pos.y then - swipe.end_move_coef_y = swipe.back_slow_coef - swipe.end_position_y = instance.start_pos.y - elseif instance.pos.y > instance.maximum.y then - swipe.end_move_coef_y = swipe.back_slow_coef - swipe.end_position_y = instance.maximum.y - else - swipe.end_move_coef_y = 1 - swipe.end_position_y = nil - end - gui.set_position(instance.node, instance.pos) - swipe.speed.x = swipe.speed.x / swipe.speed_down_coef * swipe.end_move_coef_x - swipe.speed.y = swipe.speed.y / swipe.speed_down_coef * swipe.end_move_coef_y - if swipe.speed.x < swipe.min_speed and swipe.speed.x > - swipe.min_speed then - swipe.speed.x = 0 - if not swipe.pressed then - back_move(instance) - else - swipe.waiting_for_back_move = true - end - if swipe.speed.y < swipe.min_speed and swipe.speed.y > - swipe.min_speed then - swipe.speed.y = 0 - end - if swipe.speed.y == 0 and swipe.speed.x == 0 then - swipe.is_swipe = false - end - end - end -end - ---- Scroll position to --- @param pos - positon for set --- @param is_animate - is animated set -function M.scroll_to(instance, pos, is_animate, cb, time_scrolling) - local time = is_animate and M.ANIM_TIME or 0 - time = time_scrolling or time - instance.pos.x = pos.x - instance.pos.y = pos.y - gui.animate(instance.node, gui.PROP_POSITION, instance.pos, gui.EASING_INSINE, time, 0, - function() - if cb then - cb(instance.parent.parent) - end - end - ) -end - -return M diff --git a/druid/components/spine_anim.lua b/druid/components/spine_anim.lua deleted file mode 100644 index 40861c2..0000000 --- a/druid/components/spine_anim.lua +++ /dev/null @@ -1,62 +0,0 @@ -local M = {} - ---- Set animation scene --- @param scene - animations scene -function M.set_scene(instance, scene) - instance.last_scene = scene - gui.set_spine_scene(instance.node, scene) -end - - ---- Set idle animation --- @param anim - idle animation name or index in idle table --- @param properties - properties of the animation -function M.play_idle(instance, anim, properties) - if not anim then - return - end - anim = (instance.idle_table and instance.idle_table[anim]) and instance.idle_table[anim] or anim - instance.last_value = anim - properties = properties or {} - gui.play_spine_anim(instance.node, anim, gui.PLAYBACK_LOOP_FORWARD, properties) -end - ---- Set active animation --- @param anim - active animation name or index in active table --- @param callback - call when animation done --- @param idle_after - set idle after active anim -function M.play_active(instance, anim, callback, idle_after) - instance.is_play_now = true - anim = instance.active_table and instance.active_table[anim] or anim - instance.last_value = anim - instance.callback = callback - M.play_idle(instance, idle_after) - gui.play_spine_anim(instance.node, anim, gui.PLAYBACK_ONCE_FORWARD, {}, - function() - M.play_idle(instance, idle_after) - instance.is_play_now = false - if callback then - callback(instance.parent.parent) - end - end - ) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if instance.last_scene then - M.set_scene(instance, instance.last_scene) - end - if instance.last_value then - M.play_idle(instance, instance.last_value) - end - if instance.is_play_now then - instance.is_play_now = false - if instance.callback then - instance.callback(instance.parent.parent) - end - end -end - - -return M diff --git a/druid/components/tab_page.lua b/druid/components/tab_page.lua deleted file mode 100644 index f6771ce..0000000 --- a/druid/components/tab_page.lua +++ /dev/null @@ -1,92 +0,0 @@ ---[[ Single tab screen module. Assumed to be used with Tab Bar module. - --- Create tab screen with parental gui node: -self.tab = tab.create "tab_bkg" - --- Show and hide tab manually: -self.tab.slide_in(self, vmath.vector3(0, -540, 0)) -self.tab.slide_out(self, vmath.vector3(0, -540, 0)) - --- Or receive show and hide messages: -function on_message(self, message_id, message, sender) - self.tab.on_message(self, message_id, message) -end - -]] - -local M = {} -M.T_SLIDE_IN = hash("t_slide_in") -M.T_SLIDE_OUT = hash("t_slide_out") - -M.STATE_START = hash("state_start") -M.STATE_FINISH = hash("state_finish") - -local ENABLE = hash("enable") -local DISABLE = hash("disable") -local PATH_COMP = "#" - -M.DEFAULT_EASING = gui.EASING_INOUTQUAD -M.DEFAULT_DURATION = 0.3 - -function M.slide_in(instance, out_pos, is_force) - msg.post(PATH_COMP, ENABLE) - if instance.callback then - instance.callback(instance.parent.parent, instance, M.T_SLIDE_IN, M.STATE_START) - end - if is_force then - gui.set_position(instance.node, instance.in_pos) - if instance.callback then - instance.callback(instance.parent.parent, instance, M.T_SLIDE_IN, M.STATE_FINISH) - end - else - instance.in_action = true - out_pos = out_pos or instance.put_pos - gui.set_position(instance.node, out_pos or instance.out_pos) - gui.animate(instance.node, gui.PROP_POSITION, instance.in_pos, instance.easing, instance.duration, 0, - function() - instance.in_action = false - if instance.callback then - instance.callback(instance.parent.parent, instance, M.T_SLIDE_IN, M.STATE_FINISH) - end - end - ) - end -end - -function M.slide_out(instance, out_pos, is_force) - out_pos = out_pos or instance.put_pos - if instance.callback then - instance.callback(instance.parent.parent, instance, M.T_SLIDE_OUT, M.STATE_START) - end - if is_force then - gui.set_position(instance.node, out_pos) - if instance.callback then - instance.callback(instance.parent.parent, instance, M.T_SLIDE_OUT, M.STATE_FINISH) - end - msg.post(PATH_COMP, DISABLE) - else - instance.in_action = true - gui.set_position(instance.node, instance.in_pos) - gui.animate(instance.node, gui.PROP_POSITION, out_pos, instance.easing, instance.duration, 0, - function() - instance.in_action = false - if instance.callback then - instance.callback(instance.parent.parent, instance, M.T_SLIDE_OUT, M.STATE_FINISH) - end - msg.post(PATH_COMP, DISABLE) - end - ) - end -end - -function M.on_message(instance, message_id, message, sender) - if message_id == M.T_SLIDE_IN then - M.slide_in(instance, message.out_pos, message.is_force) - return true - elseif message_id == M.T_SLIDE_OUT then - M.slide_out(instance, message.out_pos, message.is_force) - return true - end -end - -return M diff --git a/druid/components/tabs_container.lua b/druid/components/tabs_container.lua deleted file mode 100644 index 4a45820..0000000 --- a/druid/components/tabs_container.lua +++ /dev/null @@ -1,50 +0,0 @@ -local M = {} - ---local helper = require "modules.render.helper" -local tab_page = require "druid.components.tab_page" - -local DISABLE = hash("disable") - -function M.update_sizes(instance, width) - -- width = width or helper.config_x - instance.left = vmath.vector3(width * - 1, 0, 0) - instance.right = vmath.vector3(width * 1, 0, 0) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance, message) - -- local width = helper.settings_x - M.update_sizes(instance, width) -end - -function M.switch_tab(instance, params, force) - if instance.current == params then - return - end - if instance.current then - instance.btns[instance.current.index]:manual_back() - end - local out_pos - if instance.current and instance.current.url then - out_pos = (instance.current and instance.current.index < params.index) and instance.left or instance.right - msg.post(instance.current.url, tab_page.T_SLIDE_OUT, { out_pos = out_pos, is_force = force }) - end - if params and params.url then - out_pos = (instance.current and instance.current.index > params.index) and instance.left or instance.right - msg.post(params.url, tab_page.T_SLIDE_IN, { out_pos = out_pos, is_force = force }) - instance.current = params - end -end - ---- Select current tab manually -function M.select(instance, node_name) - for k, v in pairs(instance.btns) do - if k == instance[node_name].index then - v:tap_anim(true) - else - msg.post(instance[v.name].url, DISABLE) - end - end -end - -return M diff --git a/druid/components/text_field.lua b/druid/components/text_field.lua deleted file mode 100644 index 9d800f6..0000000 --- a/druid/components/text_field.lua +++ /dev/null @@ -1,42 +0,0 @@ -local M = {} - -local ui_animate = require "druid.helper.druid_animate" - ---- Bounce text field -function M.bounce(instance, callback) - gui.set_scale(instance.node, instance.scale_from) - ui_animate.bounce(nil, instance.node, instance.scale_to, callback) -end - ---- Set text to text field --- @param set_to - set value to text field -function M.set_to(instance, set_to) - instance.last_value = set_to - gui.set_text(instance.node, set_to) -end - ---- Set color --- @param color -function M.set_color(instance, color) - instance.last_color = color - gui.set_color(instance.node, color) -end - ---- Set scale --- @param scale -function M.set_scale(instance, scale) - instance.last_scale = scale - gui.set_scale(instance.node, scale) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if instance.last_color then - M.set_color(instance, instance.last_color) - end - if instance.last_scale then - M.set_scale(instance, instance.last_scale) - end -end - -return M diff --git a/druid/components/timer.lua b/druid/components/timer.lua deleted file mode 100644 index 7802a49..0000000 --- a/druid/components/timer.lua +++ /dev/null @@ -1,53 +0,0 @@ -local M = {} - -local formats = require "druid.helper.formats" - ---- Set text to text field --- @param set_to - set value in seconds -function M.set_to(instance, set_to) - instance.last_value = set_to - gui.set_text(instance.node, formats.second_string_min(set_to)) -end - ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - M.set_to(instance, instance.last_value) -end - ---- Called when update --- @param is_on - boolean is timer on -function M.set_work_mode(instance, is_on) - instance.is_on = is_on -end - ---- Set time interval --- @param from - "from" time in seconds --- @param to - "to" time in seconds -function M.set_interval(instance, from, to) - instance.second_from = from - instance.seconds_counter = from - instance.seconds_temp = 0 - instance.seconds_to = to - instance.second_step = from < to and 1 or - 1 - M.set_work_mode(instance, true) - M.set_to(instance, from) -end - ---- Called when update --- @param dt - delta time -function M.on_updated(instance, dt) - if instance.is_on then - instance.seconds_temp = instance.seconds_temp + dt - if instance.seconds_temp > 1 then - instance.seconds_temp = instance.seconds_temp - 1 - instance.seconds_counter = instance.seconds_counter + instance.second_step - M.set_to(instance, instance.seconds_counter) - if instance.seconds_counter == instance.seconds_to then - instance.is_on = false - instance.callback(instance) - end - end - end -end - -return M diff --git a/druid/druid.lua b/druid/druid.lua index 62c2b6a..057eff1 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -9,9 +9,9 @@ local STRING = "string" local components = { -- basic button = require("druid.base.button"), + timer = require("druid.base.timer"), -- text = require("druid.base.text"), -- android_back = require("druid.base.android_back"), - -- timer = require("druid.base.timer"), } diff --git a/druid/helper/ui_helper.lua b/druid/helper/ui_helper.lua index 89e5aa5..e592a37 100644 --- a/druid/helper/ui_helper.lua +++ b/druid/helper/ui_helper.lua @@ -13,4 +13,12 @@ function M.centrate_text_with_icon(text_node, icon_node) gui.set_position(icon_node, pos_i) 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 + return M diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index e7bc075..fa028f4 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -21,6 +21,10 @@ function init(self) self.druid:new_button("button_3", function() print("On button 3") end) + + self.druid:new_timer("text_1", 0.5, 0, function() + print("On timer end") + end) end function update(self, dt) From 5709975ed44ffaf4f81213af90bab89c725427a5 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Wed, 27 Mar 2019 22:20:50 +0300 Subject: [PATCH 015/136] add text component (#4) --- druid/base/text.lua | 40 +++++++++++++++++++++++++++++----- druid/druid.lua | 2 +- druid/settings.lua | 1 + example/example.gui.gui_script | 13 +++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/druid/base/text.lua b/druid/base/text.lua index 9d800f6..1ddb28f 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,13 +1,32 @@ +local data = require("druid.data") +local settings = require("druid.settings") + local M = {} +M.interest = { + data.TRANSLATABLE, + data.LAYOUT_CHANGED +} -local ui_animate = require "druid.helper.druid_animate" ---- Bounce text field -function M.bounce(instance, callback) - gui.set_scale(instance.node, instance.scale_from) - ui_animate.bounce(nil, instance.node, instance.scale_to, callback) +function M.init(instance, value, is_locale) + instance.last_color = gui.get_color(instance.node) + if is_locale then + instance.text_id = value + instance:translate() + else + instance:set_to(value or 0) + end + return instance end + +function M.translate(instance) + if instance.text_id then + instance:set_to(settings.get_text(instance.text_id)) + end +end + + --- Set text to text field -- @param set_to - set value to text field function M.set_to(instance, set_to) @@ -15,6 +34,7 @@ function M.set_to(instance, set_to) gui.set_text(instance.node, set_to) end + --- Set color -- @param color function M.set_color(instance, color) @@ -22,6 +42,15 @@ function M.set_color(instance, color) gui.set_color(instance.node, color) end + +--- Set alpha +-- @param alpha, number [0-1] +function M.set_alpha(instance, alpha) + instance.last_color.w = alpha + gui.set_color(instance.node, instance.last_color) +end + + --- Set scale -- @param scale function M.set_scale(instance, scale) @@ -29,6 +58,7 @@ function M.set_scale(instance, scale) gui.set_scale(instance.node, scale) end + --- Called when layout updated (rotate for example) function M.on_layout_updated(instance) if instance.last_color then diff --git a/druid/druid.lua b/druid/druid.lua index 057eff1..8f1da78 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -9,8 +9,8 @@ local STRING = "string" local components = { -- basic button = require("druid.base.button"), + text = require("druid.base.text"), timer = require("druid.base.timer"), - -- text = require("druid.base.text"), -- android_back = require("druid.base.android_back"), } diff --git a/druid/settings.lua b/druid/settings.lua index 701da36..25a02bb 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -15,6 +15,7 @@ M.button = { function M.get_text(name) -- override to get text for localized text + return "locales not inited" end diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index fa028f4..34b54fe 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -1,10 +1,18 @@ local druid = require("druid.druid") local druid_settings = require("druid.settings") +local lang = { + locale_text = "Localized" +} + local function setup_druid(self) druid_settings.play_sound = function(name) sound.play("sounds#" .. name) end + + druid_settings.get_text = function(text_id) + return lang[text_id] + end end function init(self) @@ -22,9 +30,14 @@ function init(self) print("On button 3") end) + self.druid:new_text("text_2", "Simple text") + self.druid:new_text("text_3", "locale_text", true) + self.druid:new_timer("text_1", 0.5, 0, function() print("On timer end") end) + + end function update(self, dt) From 5e2dc3443721d59ed1de8b5015a7db24b734cca1 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Wed, 27 Mar 2019 22:23:22 +0300 Subject: [PATCH 016/136] add android_back component (#5) --- druid/base/android_back.lua | 23 +++++++++++++++++++++-- druid/druid.lua | 2 +- example/example.gui.gui_script | 6 +++++- input/game.input_binding | 8 ++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/druid/base/android_back.lua b/druid/base/android_back.lua index a237675..4202811 100644 --- a/druid/base/android_back.lua +++ b/druid/base/android_back.lua @@ -1,11 +1,30 @@ +local data = require("druid.data") + local M = {} +M.interest = { + data.ON_INPUT +} + + +function M.init(instance, params) + -- TODO: first arg store as node. Find way to escape this + local callback = instance.node + instance.event = data.A_ANDR_BACK + instance.callback = callback + instance.params = params +end + + --- input handler -- @param action_id - input action id -- @param action - input action function M.on_input(instance, action_id, action) - instance.callback(instance.parent.parent) - return true + if action[data.RELEASED] then + instance.callback(instance.parent.parent, instance.params) + end + return true end + return M diff --git a/druid/druid.lua b/druid/druid.lua index 8f1da78..4d734de 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -9,9 +9,9 @@ local STRING = "string" local components = { -- basic button = require("druid.base.button"), + android_back = require("druid.base.android_back"), text = require("druid.base.text"), timer = require("druid.base.timer"), - -- android_back = require("druid.base.android_back"), } diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 34b54fe..41cee78 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -30,6 +30,11 @@ function init(self) print("On button 3") end) + + self.druid:new_android_back(function(self, params) + print("On android back", params) + end, 2) + self.druid:new_text("text_2", "Simple text") self.druid:new_text("text_3", "locale_text", true) @@ -37,7 +42,6 @@ function init(self) print("On timer end") end) - end function update(self, dt) diff --git a/input/game.input_binding b/input/game.input_binding index 8ed1d4e..4d43ca9 100644 --- a/input/game.input_binding +++ b/input/game.input_binding @@ -1,3 +1,11 @@ +key_trigger { + input: KEY_BACKSPACE + action: "back" +} +key_trigger { + input: KEY_BACK + action: "back" +} mouse_trigger { input: MOUSE_BUTTON_1 action: "touch" From cb82acd5da864161a5e5a92914f49363a97a60f6 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Wed, 27 Mar 2019 21:30:58 +0100 Subject: [PATCH 017/136] - new log function for debug - clear metatable for the factory --- druid/druid.lua | 228 +++++++++++++++++---------------- druid/settings.lua | 8 ++ example/example.gui.gui_script | 3 +- 3 files changed, 126 insertions(+), 113 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index 4d734de..9ba84aa 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,150 +1,154 @@ local data = require("druid.data") local druid_input = require("druid.helper.druid_input") +local settings = require("druid.settings") local M = {} +local log = settings.log +local _factory = {} + local STRING = "string" --- New druid era, registering components local components = { - -- basic - button = require("druid.base.button"), - android_back = require("druid.base.android_back"), - text = require("druid.base.text"), - timer = require("druid.base.timer"), + -- basic + button = require("druid.base.button"), + android_back = require("druid.base.android_back"), + text = require("druid.base.text"), + timer = require("druid.base.timer"), } local function register_basic_components() - for k, v in pairs(components) do - M.register(k, v) - end + for k, v in pairs(components) do + M.register(k, v) + end end function M.register(name, module) - -- TODO: Find better solution to creating elements? - M["new_" .. name] = function(factory, node_name, ...) - M.create(factory, module, node_name, ...) - end - print("[Druid]: register component", name) + -- TODO: Find better solution to creating elements? + _factory["new_" .. name] = function(factory, node_name, ...) + M.create(factory, module, node_name, ...) + end + log("Register component", name) end ---- Called on_message -function M.on_message(factory, message_id, message, sender) - if message_id == data.LAYOUT_CHANGED then - if factory[data.LAYOUT_CHANGED] then - M.translate(factory) - for i, v in ipairs(factory[data.LAYOUT_CHANGED]) do - v:on_layout_updated(message) - end - end - elseif message_id == data.TRANSLATABLE then - M.translate(factory) - else - if factory[data.ON_MESSAGE] then - for i, v in ipairs(factory[data.ON_MESSAGE]) do - v:on_message(message_id, message, sender) - end - end - end -end - - ---- Called ON_INPUT -function M.on_input(factory, action_id, action) - if factory[data.ON_SWIPE] then - local v, result - local len = #factory[data.ON_SWIPE] - for i = 1, len do - v = factory[data.ON_SWIPE][i] - result = result or v:on_input(action_id, action) - end - if result then - return true - end - end - if factory[data.ON_INPUT] then - local v - local len = #factory[data.ON_INPUT] - for i = 1, len do - v = factory[data.ON_INPUT][i] - if action_id == v.event and v:on_input(action_id, action) then - return true - end - end - return false - end - return false -end - - ---- Called on_update -function M.update(factory, dt) - if factory[data.ON_UPDATE] then - for i, v in ipairs(factory[data.ON_UPDATE]) do - v:update(dt) - end - end -end - - --- Create UI instance for ui elements -- @return instance with all ui components function M.new(self) - local factory = setmetatable({}, {__index = M}) - factory.parent = self - return factory -end - - -local function input_init(factory) - if not factory.input_inited then - factory.input_inited = true - druid_input.focus() - end + local factory = setmetatable({}, {__index = _factory}) + factory.parent = self + return factory end -------------------------------------------------------------------------------- +local function input_init(factory) + if not factory.input_inited then + factory.input_inited = true + druid_input.focus() + end +end + + local function create(module, factory, name, ...) - local instance = setmetatable({}, {__index = module}) - instance.parent = factory - if name then - if type(name) == STRING then - instance.name = name - instance.node = gui.get_node(name) - else - --name already is node - instance.name = nil - instance.node = name - end - end - factory[#factory + 1] = instance + local instance = setmetatable({}, {__index = module}) + instance.parent = factory + if name then + if type(name) == STRING then + instance.name = name + instance.node = gui.get_node(name) + else + --name already is node + instance.name = nil + instance.node = name + end + end + factory[#factory + 1] = instance - local register_to = module.interest or {} - for i, v in ipairs(register_to) do - if not factory[v] then - factory[v] = {} - end - factory[v][#factory[v] + 1] = instance + local register_to = module.interest or {} + for i, v in ipairs(register_to) do + if not factory[v] then + factory[v] = {} + end + factory[v][#factory[v] + 1] = instance - if v == data.ON_INPUT then - input_init(factory) - end - end - return instance + if v == data.ON_INPUT then + input_init(factory) + end + end + return instance end function M.create(factory, module, name, ...) - local instance = create(module, factory, name) + local instance = create(module, factory, name) - if instance.init then - instance:init(...) - end + if instance.init then + instance:init(...) + end +end + +register_basic_components() +-------------------------------------------------------------------------------- + +--- Called on_message +function _factory.on_message(factory, message_id, message, sender) + if message_id == data.LAYOUT_CHANGED then + if factory[data.LAYOUT_CHANGED] then + M.translate(factory) + for i, v in ipairs(factory[data.LAYOUT_CHANGED]) do + v:on_layout_updated(message) + end + end + elseif message_id == data.TRANSLATABLE then + M.translate(factory) + else + if factory[data.ON_MESSAGE] then + for i, v in ipairs(factory[data.ON_MESSAGE]) do + v:on_message(message_id, message, sender) + end + end + end end -register_basic_components() +--- Called ON_INPUT +function _factory.on_input(factory, action_id, action) + if factory[data.ON_SWIPE] then + local v, result + local len = #factory[data.ON_SWIPE] + for i = 1, len do + v = factory[data.ON_SWIPE][i] + result = result or v:on_input(action_id, action) + end + if result then + return true + end + end + if factory[data.ON_INPUT] then + local v + local len = #factory[data.ON_INPUT] + for i = 1, len do + v = factory[data.ON_INPUT][i] + if action_id == v.event and v:on_input(action_id, action) then + return true + end + end + return false + end + return false +end + + +--- Called on_update +function _factory.update(factory, dt) + if factory[data.ON_UPDATE] then + for i, v in ipairs(factory[data.ON_UPDATE]) do + v:update(dt) + end + end +end + return M \ No newline at end of file diff --git a/druid/settings.lua b/druid/settings.lua index 25a02bb..0b20797 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -1,5 +1,6 @@ local M = {} +M.is_debug = false M.button = { IS_HOVER = true, @@ -23,5 +24,12 @@ function M.play_sound(name) -- override to play sound with name end +function M.log(...) + if M.is_debug then + print("[Druid]: ", ...) + end +end + + return M \ No newline at end of file diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 41cee78..d17b88c 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -6,6 +6,8 @@ local lang = { } local function setup_druid(self) + druid_settings.is_debug = true + druid_settings.play_sound = function(name) sound.play("sounds#" .. name) end @@ -19,7 +21,6 @@ function init(self) setup_druid(self) self.druid = druid.new(self) - self.druid:new_button("button_1", function() print("On button 1") end) From d5c3aae7458fadb9fadc5e336be63e8e06dd6026 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Wed, 27 Mar 2019 22:00:02 +0100 Subject: [PATCH 018/136] add create as _factory method --- druid/components/andr_back_btn.lua | 11 ----------- druid/druid.lua | 16 ++++++++-------- example/example.gui.gui_script | 8 ++++++-- 3 files changed, 14 insertions(+), 21 deletions(-) delete mode 100644 druid/components/andr_back_btn.lua diff --git a/druid/components/andr_back_btn.lua b/druid/components/andr_back_btn.lua deleted file mode 100644 index a237675..0000000 --- a/druid/components/andr_back_btn.lua +++ /dev/null @@ -1,11 +0,0 @@ -local M = {} - ---- input handler --- @param action_id - input action id --- @param action - input action -function M.on_input(instance, action_id, action) - instance.callback(instance.parent.parent) - return true -end - -return M diff --git a/druid/druid.lua b/druid/druid.lua index 9ba84aa..e5c5bf6 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -10,7 +10,7 @@ local _factory = {} local STRING = "string" --- New druid era, registering components -local components = { +M.comps = { -- basic button = require("druid.base.button"), android_back = require("druid.base.android_back"), @@ -20,7 +20,7 @@ local components = { local function register_basic_components() - for k, v in pairs(components) do + for k, v in pairs(M.comps) do M.register(k, v) end end @@ -28,8 +28,8 @@ end function M.register(name, module) -- TODO: Find better solution to creating elements? - _factory["new_" .. name] = function(factory, node_name, ...) - M.create(factory, module, node_name, ...) + _factory["new_" .. name] = function(factory, node_or_name, ...) + _factory.create(factory, module, node_or_name, ...) end log("Register component", name) end @@ -82,16 +82,14 @@ local function create(module, factory, name, ...) end -function M.create(factory, module, name, ...) - local instance = create(module, factory, name) +function _factory.create(factory, module, node_or_name, ...) + local instance = create(module, factory, node_or_name) if instance.init then instance:init(...) end end -register_basic_components() --------------------------------------------------------------------------------- --- Called on_message function _factory.on_message(factory, message_id, message, sender) @@ -151,4 +149,6 @@ function _factory.update(factory, dt) end end +register_basic_components() + return M \ No newline at end of file diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index d17b88c..4c645fe 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -24,14 +24,18 @@ function init(self) self.druid:new_button("button_1", function() print("On button 1") end) - self.druid:new_button("button_2", function() + + --alternative way of component registration + self.druid:create(druid.comps.button, "button_2", function() print("On button 2") end) + self.druid:new_button("button_3", function() print("On button 3") end) - + druid.register("my_custom_component", {}) + self.druid:new_android_back(function(self, params) print("On android back", params) end, 2) From 832ebe56744e0693bab8ade906d242259a3f1774 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Wed, 27 Mar 2019 22:07:28 +0100 Subject: [PATCH 019/136] New way of component registration --- druid/druid.lua | 8 +++++--- example/example.gui.gui_script | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index e5c5bf6..d91f781 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -19,7 +19,7 @@ M.comps = { } -local function register_basic_components() +local register_basic_components = function () for k, v in pairs(M.comps) do M.register(k, v) end @@ -37,6 +37,10 @@ end --- Create UI instance for ui elements -- @return instance with all ui components function M.new(self) + if register_basic_components then + register_basic_components() + register_basic_components = false + end local factory = setmetatable({}, {__index = _factory}) factory.parent = self return factory @@ -149,6 +153,4 @@ function _factory.update(factory, dt) end end -register_basic_components() - return M \ No newline at end of file diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 4c645fe..dc5bd03 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -6,6 +6,11 @@ local lang = { } local function setup_druid(self) + + -- two different way of exernal component regesstration + druid.comps["my_mega_test_comp"] = require "druid.base.text" + druid.register("my_custom_component", {}) + druid_settings.is_debug = true druid_settings.play_sound = function(name) @@ -33,8 +38,6 @@ function init(self) self.druid:new_button("button_3", function() print("On button 3") end) - - druid.register("my_custom_component", {}) self.druid:new_android_back(function(self, params) print("On android back", params) From 87e6f6ef1fa8754a3764ca5a85dd9c6ce0a7f608 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Wed, 27 Mar 2019 22:13:45 +0100 Subject: [PATCH 020/136] rename create() to new() --- druid/druid.lua | 4 ++-- example/example.gui.gui_script | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index d91f781..78ce5ae 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -29,7 +29,7 @@ end function M.register(name, module) -- TODO: Find better solution to creating elements? _factory["new_" .. name] = function(factory, node_or_name, ...) - _factory.create(factory, module, node_or_name, ...) + _factory.new(factory, module, node_or_name, ...) end log("Register component", name) end @@ -86,7 +86,7 @@ local function create(module, factory, name, ...) end -function _factory.create(factory, module, node_or_name, ...) +function _factory.new(factory, module, node_or_name, ...) local instance = create(module, factory, node_or_name) if instance.init then diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index dc5bd03..84ba19e 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -30,8 +30,8 @@ function init(self) print("On button 1") end) - --alternative way of component registration - self.druid:create(druid.comps.button, "button_2", function() + --alternative way of component creation + self.druid:new(druid.comps.button, "button_2", function() print("On button 2") end) From c38354e532be554c6afc8e7cb7f9e67ce7963126 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Thu, 28 Mar 2019 07:55:18 +0100 Subject: [PATCH 021/136] Whitespace fixes --- druid/druid.lua | 2 +- example/example.gui.gui_script | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index 78ce5ae..769e603 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -37,7 +37,7 @@ end --- Create UI instance for ui elements -- @return instance with all ui components function M.new(self) - if register_basic_components then + if register_basic_components then register_basic_components() register_basic_components = false end diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 84ba19e..fbf0574 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -29,16 +29,16 @@ function init(self) self.druid:new_button("button_1", function() print("On button 1") end) - + --alternative way of component creation self.druid:new(druid.comps.button, "button_2", function() print("On button 2") end) - + self.druid:new_button("button_3", function() print("On button 3") end) - + self.druid:new_android_back(function(self, params) print("On android back", params) end, 2) From 235476fee49718bb8ef7bd73b8fb3551ed42bb42 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 28 Mar 2019 10:19:58 +0300 Subject: [PATCH 022/136] little fixes: returing new instance --- druid/druid.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index 769e603..d0089c2 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -29,9 +29,9 @@ end function M.register(name, module) -- TODO: Find better solution to creating elements? _factory["new_" .. name] = function(factory, node_or_name, ...) - _factory.new(factory, module, node_or_name, ...) - end - log("Register component", name) + return _factory.new(factory, module, node_or_name, ...) + end + log("Register component", name) end --- Create UI instance for ui elements @@ -92,6 +92,8 @@ function _factory.new(factory, module, node_or_name, ...) if instance.init then instance:init(...) end + + return instance end From 12f5f22b694a84be09c61143738b763a217d06a0 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Fri, 29 Mar 2019 00:45:46 +0300 Subject: [PATCH 023/136] check project code style. add .luacheckrc (#7) --- .luacheckrc | 51 +++++++ README.md | 15 +- druid/base/android_back.lua | 3 +- druid/base/button.lua | 35 +++-- druid/base/text.lua | 57 ++++---- druid/base/timer.lua | 76 +++++----- druid/druid.lua | 7 +- druid/helper/druid_animate.lua | 257 +++++++++++++++++---------------- druid/helper/druid_input.lua | 7 +- druid/helper/formats.lua | 23 +-- druid/helper/ui_helper.lua | 40 ++--- druid/settings.lua | 4 +- 12 files changed, 328 insertions(+), 247 deletions(-) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..a99ebbd --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,51 @@ +std = "max" +files['.luacheckrc'].global = false +unused_args = false + +max_code_line_length = 90 +max_comment_line_length = false + +globals = { + "sys", + "go", + "gui", + "label", + "render", + "crash", + "sprite", + "sound", + "tilemap", + "spine", + "particlefx", + "physics", + "factory", + "collectionfactory", + "iac", + "msg", + "vmath", + "url", + "http", + "image", + "json", + "zlib", + "iap", + "push", + "facebook", + "hash", + "hash_to_hex", + "pprint", + "init", + "final", + "update", + "on_input", + "on_message", + "on_reload", + "socket", + "table", + "debug", + "timer", + "window", + "buffer", + "resource", + "defos", +} diff --git a/README.md b/README.md index dc028cf..689d149 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ -# druid +# Defold Druid Defold UI library +-- -This project was created from the "empty" project template. +# Install -The settings in ["game.project"](defold://open?path=/game.project) are all the default. A bootstrap empty ["main.collection"](defold://open?path=/main/main.collection) is included. +# Setup -Check out [the documentation pages](https://defold.com/learn) for examples, tutorials, manuals and API docs. +# Usage -If you run into trouble, help is available in [our forum](https://forum.defold.com). +# API -Happy Defolding! +# Authors ---- \ No newline at end of file +# License diff --git a/druid/base/android_back.lua b/druid/base/android_back.lua index 4202811..5637b12 100644 --- a/druid/base/android_back.lua +++ b/druid/base/android_back.lua @@ -1,7 +1,6 @@ local data = require("druid.data") local M = {} - M.interest = { data.ON_INPUT } @@ -27,4 +26,4 @@ function M.on_input(instance, action_id, action) end -return M +return M \ No newline at end of file diff --git a/druid/base/button.lua b/druid/base/button.lua index 1283f55..df0ea53 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -4,7 +4,6 @@ local settings = require("druid.settings") local b_settings = settings.button local M = {} - M.interest = { data.ON_INPUT } @@ -15,9 +14,9 @@ M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) M.DEFAUL_ACTIVATION_TIME = 0.2 -function M.init(instance, callback, params, animate_node_name, event) +function M.init(instance, callback, params, anim_node) instance.event = data.A_TOUCH - instance.anim_node = animate_node_name and gui.get_node(animate_node_name) or instance.node + instance.anim_node = anim_node and gui.get_node(anim_node) or instance.node instance.scale_from = gui.get_scale(instance.anim_node) instance.scale_to = instance.scale_from + b_settings.SCALE_CHANGE instance.scale_hover_to = instance.scale_from + b_settings.HOVER_SCALE @@ -40,6 +39,7 @@ local function set_hover(instance, state) end end + local function on_button_release(instance) if not instance.disabled then if not instance.stub and instance.can_action then @@ -83,6 +83,7 @@ function M.on_input(instance, action_id, action) end end + function M.tap_scale_animation(instance) ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, function() @@ -109,12 +110,14 @@ function M.deactivate(instance, is_animate, callback) callback(instance.parent.parent) end end - ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, - gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, + clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) + + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, + M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, + M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) else gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) @@ -137,12 +140,14 @@ function M.activate(instance, is_animate, callback) end end end - ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, - gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, - M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, + clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) + + ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, + M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + + ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, + M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) else gui.set_color(instance.node, ui_animate.TINT_SHOW) gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) diff --git a/druid/base/text.lua b/druid/base/text.lua index 1ddb28f..466daf1 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -3,70 +3,71 @@ local settings = require("druid.settings") local M = {} M.interest = { - data.TRANSLATABLE, - data.LAYOUT_CHANGED + data.TRANSLATABLE, + data.LAYOUT_CHANGED } function M.init(instance, value, is_locale) - instance.last_color = gui.get_color(instance.node) - if is_locale then - instance.text_id = value - instance:translate() - else - instance:set_to(value or 0) - end - return instance + instance.last_color = gui.get_color(instance.node) + if is_locale then + instance.text_id = value + instance:translate() + else + instance:set_to(value or 0) + end + return instance end function M.translate(instance) - if instance.text_id then - instance:set_to(settings.get_text(instance.text_id)) - end + if instance.text_id then + instance:set_to(settings.get_text(instance.text_id)) + end end --- Set text to text field -- @param set_to - set value to text field function M.set_to(instance, set_to) - instance.last_value = set_to - gui.set_text(instance.node, set_to) + instance.last_value = set_to + gui.set_text(instance.node, set_to) end --- Set color -- @param color function M.set_color(instance, color) - instance.last_color = color - gui.set_color(instance.node, color) + instance.last_color = color + gui.set_color(instance.node, color) end --- Set alpha -- @param alpha, number [0-1] function M.set_alpha(instance, alpha) - instance.last_color.w = alpha - gui.set_color(instance.node, instance.last_color) + instance.last_color.w = alpha + gui.set_color(instance.node, instance.last_color) end --- Set scale -- @param scale function M.set_scale(instance, scale) - instance.last_scale = scale - gui.set_scale(instance.node, scale) + instance.last_scale = scale + gui.set_scale(instance.node, scale) end --- Called when layout updated (rotate for example) function M.on_layout_updated(instance) - if instance.last_color then - M.set_color(instance, instance.last_color) - end - if instance.last_scale then - M.set_scale(instance, instance.last_scale) - end + if instance.last_color then + M.set_color(instance, instance.last_color) + end + if instance.last_scale then + M.set_scale(instance, instance.last_scale) + end end -return M + +return M \ No newline at end of file diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 5f2a6ab..8439778 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -3,49 +3,48 @@ local formats = require("druid.helper.formats") local helper = require("druid.helper.ui_helper") local M = {} - M.interest = { - data.LAYOUT_CHANGED, - data.ON_UPDATE + data.LAYOUT_CHANGED, + data.ON_UPDATE } local empty = function() end function M.init(instance, seconds_from, seconds_to, callback) - seconds_from = math.max(seconds_from, 0) - seconds_to = math.max(seconds_to or 0, 0) - callback = callback or empty + seconds_from = math.max(seconds_from, 0) + seconds_to = math.max(seconds_to or 0, 0) + callback = callback or empty - instance:set_to(seconds_from) - instance:set_interval(seconds_from, seconds_to) - instance.callback = callback + instance:set_to(seconds_from) + instance:set_interval(seconds_from, seconds_to) + instance.callback = callback - if seconds_to - seconds_from == 0 then - instance:set_state(false) - instance.callback(instance.parent.parent, instance) - end - return instance + if seconds_to - seconds_from == 0 then + instance:set_state(false) + instance.callback(instance.parent.parent, instance) + end + return instance end --- Set text to text field -- @param set_to - set value in seconds function M.set_to(instance, set_to) - instance.last_value = set_to - gui.set_text(instance.node, formats.second_string_min(set_to)) + instance.last_value = set_to + gui.set_text(instance.node, formats.second_string_min(set_to)) end --- Called when layout updated (rotate for example) function M.on_layout_updated(instance) - M.set_to(instance, instance.last_value) + M.set_to(instance, instance.last_value) end --- Called when update -- @param is_on - boolean is timer on function M.set_state(instance, is_on) - instance.is_on = is_on + instance.is_on = is_on end @@ -53,32 +52,33 @@ end -- @param from - "from" time in seconds -- @param to - "to" time in seconds function M.set_interval(instance, from, to) - instance.from = from - instance.value = from - instance.temp = 0 - instance.target = to - M.set_state(instance, true) - M.set_to(instance, from) + instance.from = from + instance.value = from + instance.temp = 0 + instance.target = to + M.set_state(instance, true) + M.set_to(instance, from) end --- Called when update -- @param dt - delta time function M.update(instance, dt) - if instance.is_on then - instance.temp = instance.temp + dt - local dist = math.min(1, math.abs(instance.value - instance.target)) + if instance.is_on then + instance.temp = instance.temp + dt + local dist = math.min(1, math.abs(instance.value - instance.target)) - if instance.temp > dist then - instance.temp = instance.temp - dist - instance.value = helper.step(instance.value, instance.target, 1) - M.set_to(instance, instance.value) - if instance.value == instance.target then - instance:set_state(false) - instance.callback(instance.parent.parent, instance) - end - end - end + if instance.temp > dist then + instance.temp = instance.temp - dist + instance.value = helper.step(instance.value, instance.target, 1) + M.set_to(instance, instance.value) + if instance.value == instance.target then + instance:set_state(false) + instance.callback(instance.parent.parent, instance) + end + end + end end -return M + +return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index d0089c2..7d6e8cc 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -9,9 +9,7 @@ local _factory = {} local STRING = "string" ---- New druid era, registering components M.comps = { - -- basic button = require("druid.base.button"), android_back = require("druid.base.android_back"), text = require("druid.base.text"), @@ -34,6 +32,7 @@ function M.register(name, module) log("Register component", name) end + --- Create UI instance for ui elements -- @return instance with all ui components function M.new(self) @@ -46,7 +45,6 @@ function M.new(self) return factory end --------------------------------------------------------------------------------- local function input_init(factory) if not factory.input_inited then @@ -56,7 +54,7 @@ local function input_init(factory) end -local function create(module, factory, name, ...) +local function create(module, factory, name) local instance = setmetatable({}, {__index = module}) instance.parent = factory if name then @@ -155,4 +153,5 @@ function _factory.update(factory, dt) end end + return M \ No newline at end of file diff --git a/druid/helper/druid_animate.lua b/druid/helper/druid_animate.lua index 0e76f68..12828b4 100644 --- a/druid/helper/druid_animate.lua +++ b/druid/helper/druid_animate.lua @@ -2,13 +2,14 @@ local M = {} local PROP_SCALE = gui.PROP_SCALE local PROP_POSITION = gui.PROP_POSITION -M.PROP_POS_X = hash("position.x") -M.PROP_POS_Y = hash("position.y") -M.PROP_ALPHA = hash("color.w") local PROP_COLOR = hash("color") local PROP_SCALE_X = "scale.x" local PROP_SCALE_Y = "scale.y" +M.PROP_POS_X = hash("position.x") +M.PROP_POS_Y = hash("position.y") +M.PROP_ALPHA = hash("color.w") + M.TINT_HIDE = vmath.vector4(1, 1, 1, 0) M.TINT_SHOW = vmath.vector4(1, 1, 1, 1) @@ -19,155 +20,167 @@ M.SCALE_ANIMATION_TIME = 0.1 M.BOUNCE_ANIMATION_TIME = 0.25 M.ALPHA_ANIMATION_TIME = 0.25 + function M.alpha(self, node, alpha, callback, time, delay, easing, playback) - time = time or M.ALPHA_ANIMATION_TIME - delay = delay or 0 - easing = easing or gui.EASING_LINEAR - playback = playback or gui.PLAYBACK_ONCE_FORWARD - gui.animate(node, M.PROP_ALPHA, alpha, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) + time = time or M.ALPHA_ANIMATION_TIME + delay = delay or 0 + easing = easing or gui.EASING_LINEAR + playback = playback or gui.PLAYBACK_ONCE_FORWARD + gui.animate(node, M.PROP_ALPHA, alpha, easing, time, delay, + function() + if callback then + callback(self, node) + end + end, + playback) end + function M.color(self, node, color, callback, time, delay, easing, playback) - time = time or M.ALPHA_ANIMATION_TIME - delay = delay or 0 - easing = easing or gui.EASING_LINEAR - playback = playback or gui.PLAYBACK_ONCE_FORWARD - gui.animate(node, PROP_COLOR, color, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) + time = time or M.ALPHA_ANIMATION_TIME + delay = delay or 0 + easing = easing or gui.EASING_LINEAR + playback = playback or gui.PLAYBACK_ONCE_FORWARD + gui.animate(node, PROP_COLOR, color, easing, time, delay, + function() + if callback then + callback(self, node) + end + end, + playback) end + function M.shake(self, node, callback, str, time) - str = str or - 30 - time = time or 0.25 - local pos = gui.get_position(node) - pos.x = pos.x + str - gui.animate(node, PROP_POSITION, pos, gui.EASING_INELASTIC, time, - 0, - function() - if callback then - callback(self) - end - end, - gui.PLAYBACK_ONCE_BACKWARD - ) + str = str or - 30 + time = time or 0.25 + local pos = gui.get_position(node) + pos.x = pos.x + str + gui.animate(node, PROP_POSITION, pos, gui.EASING_INELASTIC, time, + 0, + function() + if callback then + callback(self) + end + end, + gui.PLAYBACK_ONCE_BACKWARD + ) end + function M.bounce(self, node, change_to, callback, time, easing, playback, delaly) - time = time or M.BOUNCE_ANIMATION_TIME - delaly = delaly or 0 - easing = easing or gui.EASING_OUTSINE - playback = playback or gui.PLAYBACK_ONCE_PINGPONG - gui.animate(node, PROP_SCALE, change_to, easing, time, delaly, - function() - if callback then - callback(self) - end - end, - playback) + time = time or M.BOUNCE_ANIMATION_TIME + delaly = delaly or 0 + easing = easing or gui.EASING_OUTSINE + playback = playback or gui.PLAYBACK_ONCE_PINGPONG + gui.animate(node, PROP_SCALE, change_to, easing, time, delaly, + function() + if callback then + callback(self) + end + end, + playback) end + function M.fly_to(self, node, to_pos, speed, callback, delay, easing) - easing = easing or gui.EASING_OUTSINE - delay = delay or 0 - local time = vmath.length(to_pos - gui.get_position(node)) / 100 / speed - gui.animate(node, gui.PROP_POSITION, to_pos, easing, time, delay, - function() - if callback then - callback(self, node) - end - end) + easing = easing or gui.EASING_OUTSINE + delay = delay or 0 + local time = vmath.length(to_pos - gui.get_position(node)) / 100 / speed + gui.animate(node, gui.PROP_POSITION, to_pos, easing, time, delay, + function() + if callback then + callback(self, node) + end + end) end + function M.fly_by_x(self, node, to_x, time, callback, delay, easing, playback) - playback = playback or gui.PLAYBACK_ONCE_FORWARD - easing = easing or gui.EASING_OUTSINE - delay = delay or 0 - gui.animate(node, M.PROP_POS_X, to_x, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) + playback = playback or gui.PLAYBACK_ONCE_FORWARD + easing = easing or gui.EASING_OUTSINE + delay = delay or 0 + gui.animate(node, M.PROP_POS_X, to_x, easing, time, delay, + function() + if callback then + callback(self, node) + end + end, + playback) end + function M.fly_by_y(self, node, to_y, time, callback, delay, easing, playback) - playback = playback or gui.PLAYBACK_ONCE_FORWARD - easing = easing or gui.EASING_OUTSINE - delay = delay or 0 - time = time or 0.25 - gui.animate(node, M.PROP_POS_Y, to_y, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) + playback = playback or gui.PLAYBACK_ONCE_FORWARD + easing = easing or gui.EASING_OUTSINE + delay = delay or 0 + time = time or 0.25 + gui.animate(node, M.PROP_POS_Y, to_y, easing, time, delay, + function() + if callback then + callback(self, node) + end + end, + playback) end + function M.scale_to(self, node, to, callback, time, delay, easing) - easing = easing or gui.EASING_INSINE - time = time or M.SCALE_ANIMATION_TIME - delay = delay or 0 - time = time or 0.25 - gui.animate(node, PROP_SCALE, to, easing, time, delay, - function() - if callback then - callback(self, node) - end - end - ) + easing = easing or gui.EASING_INSINE + time = time or M.SCALE_ANIMATION_TIME + delay = delay or 0 + time = time or 0.25 + gui.animate(node, PROP_SCALE, to, easing, time, delay, + function() + if callback then + callback(self, node) + end + end + ) end + function M.scale(self, node, to, time) - gui.animate(node, "scale", to, gui.EASING_OUTSINE, time) + gui.animate(node, "scale", to, gui.EASING_OUTSINE, time) end + function M.scale_x_from_to(self, node, from, to, callback, time, easing, delay, playback) - easing = easing or gui.EASING_INSINE - time = time or M.SCALE_ANIMATION_TIME - delay = delay or 0 - playback = playback or gui.PLAYBACK_ONCE_FORWARD - local scale = gui.get_scale(node) - scale.x = from - gui.set_scale(node, scale) - gui.animate(node, PROP_SCALE_X, to, easing, time, delay, - function() - if callback then - callback(self) - end - end, - playback - ) + easing = easing or gui.EASING_INSINE + time = time or M.SCALE_ANIMATION_TIME + delay = delay or 0 + playback = playback or gui.PLAYBACK_ONCE_FORWARD + local scale = gui.get_scale(node) + scale.x = from + gui.set_scale(node, scale) + gui.animate(node, PROP_SCALE_X, to, easing, time, delay, + function() + if callback then + callback(self) + end + end, + playback + ) end + function M.scale_y_from_to(self, node, from, to, callback, time, easing, delay, playback) - easing = easing or gui.EASING_INSINE - time = time or M.SCALE_ANIMATION_TIME - delay = delay or 0 - playback = playback or gui.PLAYBACK_ONCE_FORWARD - local scale = gui.get_scale(node) - scale.y = from - gui.set_scale(node, scale) - gui.animate(node, PROP_SCALE_Y, to, easing, time, delay, - function() - if callback then - callback(self) - end - end, - playback - ) + easing = easing or gui.EASING_INSINE + time = time or M.SCALE_ANIMATION_TIME + delay = delay or 0 + playback = playback or gui.PLAYBACK_ONCE_FORWARD + local scale = gui.get_scale(node) + scale.y = from + gui.set_scale(node, scale) + gui.animate(node, PROP_SCALE_Y, to, easing, time, delay, + function() + if callback then + callback(self) + end + end, + playback + ) end -return M + +return M \ No newline at end of file diff --git a/druid/helper/druid_input.lua b/druid/helper/druid_input.lua index bc2665a..89ca0af 100644 --- a/druid/helper/druid_input.lua +++ b/druid/helper/druid_input.lua @@ -4,12 +4,15 @@ local ADD_FOCUS = hash("acquire_input_focus") local REMOVE_FOCUS = hash("release_input_focus") local PATH_OBJ = "." + function M.focus() - msg.post(PATH_OBJ, ADD_FOCUS) + msg.post(PATH_OBJ, ADD_FOCUS) end + function M.remove() - msg.post(PATH_OBJ, REMOVE_FOCUS) + msg.post(PATH_OBJ, REMOVE_FOCUS) end + return M diff --git a/druid/helper/formats.lua b/druid/helper/formats.lua index b32ffaa..040c274 100644 --- a/druid/helper/formats.lua +++ b/druid/helper/formats.lua @@ -7,28 +7,31 @@ local ZERO = "0" -- @param count - count of numerals -- @return string with need count of zero (1,3) -> 001 function M.add_prefix_zeros(num, count) - local result = tostring(num) - for i = string.len(result), count - 1 do - result = ZERO..result - end - return result + local result = tostring(num) + for i = string.len(result), count - 1 do + result = ZERO..result + end + return result end + -- Convert seconds to string minutes:seconds -- @param num - number of seconds -- @return string minutes:seconds function M.second_string_min(sec) - local mins = math.floor(sec / 60) - local seconds = math.floor(sec - mins * 60) - return string.format("%.2d:%.2d", mins, seconds) + local mins = math.floor(sec / 60) + local seconds = math.floor(sec - mins * 60) + return string.format("%.2d:%.2d", mins, seconds) end + -- Interpolate string with named Parameters in Table -- @param s - string for interpolate -- @param tab - table with parameters -- @return string with replaced parameters function M.interpolate_strinng(s, tab) - return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end)) + return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end)) end -return M + +return M \ No newline at end of file diff --git a/druid/helper/ui_helper.lua b/druid/helper/ui_helper.lua index e592a37..976a63a 100644 --- a/druid/helper/ui_helper.lua +++ b/druid/helper/ui_helper.lua @@ -1,24 +1,30 @@ local M = {} -function M.centrate_text_with_icon(text_node, icon_node) - local metr = gui.get_text_metrics_from_node(text_node) - local scl = gui.get_scale(text_node).x - local scl_i = gui.get_scale(icon_node).x - local pos_i = gui.get_position(icon_node) - local pos = gui.get_position(text_node) - local w = metr.width * scl * scl_i - local icon_w = gui.get_size(icon_node).x * scl_i - local width = w + icon_w + (math.abs(pos.x) - icon_w / 2) * scl_i - pos_i.x = width / 2 - (icon_w / 2) - gui.set_position(icon_node, pos_i) +function M.centrate_text_with_icon(text_node, icon_node, offset_x) + offset_x = offset_x or 0 + local metr = gui.get_text_metrics_from_node(text_node) + local scl = gui.get_scale(text_node).x + local pos = gui.get_position(text_node) + local scl_i = gui.get_scale(icon_node).x + local pos_i = gui.get_position(icon_node) + local w = metr.width * scl -- text width + local icon_w = gui.get_size(icon_node).x * scl_i -- icon width + local width = w + icon_w + + pos.x = -width/2 + w + offset_x + gui.set_position(text_node, pos) + pos_i.x = width/2 - icon_w + offset_x + gui.set_position(icon_node, pos_i) 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 + if current < target then + return math.min(current + step, target) + else + return math.max(target, current - step) + end end -return M + +return M \ No newline at end of file diff --git a/druid/settings.lua b/druid/settings.lua index 0b20797..4cf4fbc 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -6,7 +6,7 @@ M.button = { IS_HOVER = true, IS_HOLD = true, BTN_SOUND = "click", - BTN_SOUND_DISABLED = "button_click_disabled", + BTN_SOUND_DISABLED = "click_disabled", HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), HOVER_TIME = 0.05, SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), @@ -24,6 +24,7 @@ function M.play_sound(name) -- override to play sound with name end + function M.log(...) if M.is_debug then print("[Druid]: ", ...) @@ -31,5 +32,4 @@ function M.log(...) end - return M \ No newline at end of file From 7395f029e080cc062623c194b03748678a184860 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Fri, 29 Mar 2019 00:51:37 +0300 Subject: [PATCH 024/136] move settings node from factory to component (#8) --- druid/base/button.lua | 6 ++++-- druid/base/text.lua | 4 +++- druid/base/timer.lua | 5 +++-- druid/druid.lua | 22 +++++----------------- druid/helper/{ui_helper.lua => helper.lua} | 9 +++++++++ example/example.gui.gui_script | 2 +- 6 files changed, 25 insertions(+), 23 deletions(-) rename druid/helper/{ui_helper.lua => helper.lua} (82%) diff --git a/druid/base/button.lua b/druid/base/button.lua index df0ea53..38a6fa2 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,6 +1,7 @@ local data = require("druid.data") -local ui_animate = require "druid.helper.druid_animate" +local ui_animate = require("druid.helper.druid_animate") local settings = require("druid.settings") +local helper = require("druid.helper.helper") local b_settings = settings.button local M = {} @@ -14,7 +15,8 @@ M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) M.DEFAUL_ACTIVATION_TIME = 0.2 -function M.init(instance, callback, params, anim_node) +function M.init(instance, node, callback, params, anim_node, event) + instance.node = helper.get_node(node) instance.event = data.A_TOUCH instance.anim_node = anim_node and gui.get_node(anim_node) or instance.node instance.scale_from = gui.get_scale(instance.anim_node) diff --git a/druid/base/text.lua b/druid/base/text.lua index 466daf1..13ee774 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,5 +1,6 @@ local data = require("druid.data") local settings = require("druid.settings") +local helper = require("druid.helper.helper") local M = {} M.interest = { @@ -8,7 +9,8 @@ M.interest = { } -function M.init(instance, value, is_locale) +function M.init(instance, node, value, is_locale) + instance.node = helper.get_node(node) instance.last_color = gui.get_color(instance.node) if is_locale then instance.text_id = value diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 8439778..38deb1c 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,6 +1,6 @@ local data = require("druid.data") local formats = require("druid.helper.formats") -local helper = require("druid.helper.ui_helper") +local helper = require("druid.helper.helper") local M = {} M.interest = { @@ -10,7 +10,8 @@ M.interest = { local empty = function() end -function M.init(instance, seconds_from, seconds_to, callback) +function M.init(instance, node, seconds_from, seconds_to, callback) + instance.node = helper.get_node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) callback = callback or empty diff --git a/druid/druid.lua b/druid/druid.lua index 7d6e8cc..1dbd7a8 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -7,8 +7,6 @@ local M = {} local log = settings.log local _factory = {} -local STRING = "string" - M.comps = { button = require("druid.base.button"), android_back = require("druid.base.android_back"), @@ -26,8 +24,8 @@ end function M.register(name, module) -- TODO: Find better solution to creating elements? - _factory["new_" .. name] = function(factory, node_or_name, ...) - return _factory.new(factory, module, node_or_name, ...) + _factory["new_" .. name] = function(factory, ...) + return _factory.new(factory, module, ...) end log("Register component", name) end @@ -54,19 +52,9 @@ local function input_init(factory) end -local function create(module, factory, name) +local function create(module, factory) local instance = setmetatable({}, {__index = module}) instance.parent = factory - if name then - if type(name) == STRING then - instance.name = name - instance.node = gui.get_node(name) - else - --name already is node - instance.name = nil - instance.node = name - end - end factory[#factory + 1] = instance local register_to = module.interest or {} @@ -84,8 +72,8 @@ local function create(module, factory, name) end -function _factory.new(factory, module, node_or_name, ...) - local instance = create(module, factory, node_or_name) +function _factory.new(factory, module, ...) + local instance = create(module, factory) if instance.init then instance:init(...) diff --git a/druid/helper/ui_helper.lua b/druid/helper/helper.lua similarity index 82% rename from druid/helper/ui_helper.lua rename to druid/helper/helper.lua index 976a63a..fe150da 100644 --- a/druid/helper/ui_helper.lua +++ b/druid/helper/helper.lua @@ -18,6 +18,15 @@ function M.centrate_text_with_icon(text_node, icon_node, offset_x) end +local STRING = "string" +function M.get_node(node_or_name) + if type(node_or_name) == STRING then + return gui.get_node(node_or_name) + end + return node_or_name +end + + function M.step(current, target, step) if current < target then return math.min(current + step, target) diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index fbf0574..b92ea02 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -46,7 +46,7 @@ function init(self) self.druid:new_text("text_2", "Simple text") self.druid:new_text("text_3", "locale_text", true) - self.druid:new_timer("text_1", 0.5, 0, function() + self.druid:new_timer("text_1", 5, 0, function() print("On timer end") end) From e6ac9e5725dffd32db0725a1621ddf4b5a65160e Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 29 Mar 2019 09:51:11 +0300 Subject: [PATCH 025/136] fix android back params --- druid/base/android_back.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/druid/base/android_back.lua b/druid/base/android_back.lua index 5637b12..d40892c 100644 --- a/druid/base/android_back.lua +++ b/druid/base/android_back.lua @@ -6,9 +6,7 @@ M.interest = { } -function M.init(instance, params) - -- TODO: first arg store as node. Find way to escape this - local callback = instance.node +function M.init(instance, callback, params) instance.event = data.A_ANDR_BACK instance.callback = callback instance.params = params From 8be103111bb73091c148a35eeb4873b6271f7b02 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Sat, 30 Mar 2019 01:01:24 +0300 Subject: [PATCH 026/136] can setup text max width (#14) --- druid/base/text.lua | 23 ++++++++++++++++++++++- example/example.gui.gui_script | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/druid/base/text.lua b/druid/base/text.lua index 13ee774..f107589 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -9,9 +9,12 @@ M.interest = { } -function M.init(instance, node, value, is_locale) +function M.init(instance, node, value, is_locale, max_width) + instance.max_width = max_width instance.node = helper.get_node(node) + instance.start_scale = gui.get_scale(instance.node) instance.last_color = gui.get_color(instance.node) + if is_locale then instance.text_id = value instance:translate() @@ -29,11 +32,29 @@ function M.translate(instance) end +--- Setup scale x, but can only be smaller, than start text scale +local function setup_max_width(instance) + local metrics = gui.get_text_metrics_from_node(instance.node) + local cur_scale = gui.get_scale(instance.node) + + if metrics.width * cur_scale.x > instance.max_width then + local scale_modifier = instance.max_width / metrics.width + scale_modifier = math.min(scale_modifier, instance.start_scale.x) + local new_scale = vmath.vector3(scale_modifier, scale_modifier, cur_scale.z) + gui.set_scale(instance.node, new_scale) + end +end + + --- Set text to text field -- @param set_to - set value to text field function M.set_to(instance, set_to) instance.last_value = set_to gui.set_text(instance.node, set_to) + + if instance.max_width then + setup_max_width(instance) + end end diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index b92ea02..ec37096 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -43,7 +43,7 @@ function init(self) print("On android back", params) end, 2) - self.druid:new_text("text_2", "Simple text") + self.druid:new_text("text_2", "Simple text", false, 400) self.druid:new_text("text_3", "locale_text", true) self.druid:new_timer("text_1", 5, 0, function() From a56c691e86aac9b3bb78900d49bf614b52b8d8e3 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 30 Mar 2019 17:10:00 +0300 Subject: [PATCH 027/136] input check from later node first --- druid/druid.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index 1dbd7a8..e079791 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -109,7 +109,7 @@ function _factory.on_input(factory, action_id, action) if factory[data.ON_SWIPE] then local v, result local len = #factory[data.ON_SWIPE] - for i = 1, len do + for i = len, 1, -1 do v = factory[data.ON_SWIPE][i] result = result or v:on_input(action_id, action) end @@ -120,7 +120,7 @@ function _factory.on_input(factory, action_id, action) if factory[data.ON_INPUT] then local v local len = #factory[data.ON_INPUT] - for i = 1, len do + for i = len, 1, -1 do v = factory[data.ON_INPUT][i] if action_id == v.event and v:on_input(action_id, action) then return true From c80ea350608b7ef849f1af0398d8984f5e026fdf Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 30 Mar 2019 17:16:51 +0300 Subject: [PATCH 028/136] dont activate button, if disabled --- druid/base/button.lua | 4 ++++ druid/helper/helper.lua | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/druid/base/button.lua b/druid/base/button.lua index 38a6fa2..001f1a1 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -64,6 +64,10 @@ end -- @param action_id - input action id -- @param action - input action function M.on_input(instance, action_id, action) + if not helper.is_enabled(instance.node) then + return false + end + if gui.pick_node(instance.node, action.x, action.y) then if action.pressed then -- Can interact if start touch on the button diff --git a/druid/helper/helper.lua b/druid/helper/helper.lua index fe150da..a23f5c9 100644 --- a/druid/helper/helper.lua +++ b/druid/helper/helper.lua @@ -36,4 +36,15 @@ function M.step(current, target, step) end +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 + + return M \ No newline at end of file From 6f41f70803438fd0fce981496711ff52371eedd2 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 31 Mar 2019 19:11:48 +0300 Subject: [PATCH 029/136] dont override already declined components with basic comps --- druid/druid.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index e079791..a7592b0 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -15,9 +15,13 @@ M.comps = { } -local register_basic_components = function () +local function register_basic_components() for k, v in pairs(M.comps) do - M.register(k, v) + if not _factory["new_" .. k] then + M.register(k, v) + else + log("Basic component", k, "already registered") + end end end From d49cd2777efc5a541bac3c07fc2e3cb5cf272ec2 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Wed, 3 Apr 2019 23:23:06 +0300 Subject: [PATCH 030/136] Feature/progress (#17) * improve example gui. Add simple pages * return old progress bar with example * base progress with steps, there is bug with step? 1 ~= 1, small delta? * polish progress, check float error case * add callback on end of "to" function, value check * start of green/red in progress * add first version of rich progress bar * make green bar darker * rich bar fixes * add delay, before filling in rich progress * PR fixes * remove dublicate of 'progress_rich' --- druid/base/button.lua | 4 +- druid/base/progress.lua | 150 ++++ druid/base/text.lua | 14 +- druid/base/timer.lua | 9 +- druid/druid.lua | 3 + druid/{helper => }/helper.lua | 21 + druid/rich/progress_rich.lua | 55 ++ druid/settings.lua | 8 + example/example.gui | 1034 ++++++++++++++++++++++++++- example/example.gui.gui_script | 103 ++- example/gui.atlas | 19 +- example/res/custom.texture_profiles | 18 + example/res/empty.png | Bin 0 -> 14525 bytes example/res/progress_back.png | Bin 0 -> 1790 bytes example/res/progress_green.png | Bin 0 -> 15890 bytes example/res/progress_red.png | Bin 0 -> 15883 bytes example/res/progress_yellow.png | Bin 0 -> 1447 bytes game.project | 7 +- 18 files changed, 1382 insertions(+), 63 deletions(-) create mode 100644 druid/base/progress.lua rename druid/{helper => }/helper.lua (79%) create mode 100644 druid/rich/progress_rich.lua create mode 100644 example/res/custom.texture_profiles create mode 100755 example/res/empty.png create mode 100755 example/res/progress_back.png create mode 100755 example/res/progress_green.png create mode 100755 example/res/progress_red.png create mode 100755 example/res/progress_yellow.png diff --git a/druid/base/button.lua b/druid/base/button.lua index 001f1a1..f7ebb6c 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,7 +1,7 @@ local data = require("druid.data") local ui_animate = require("druid.helper.druid_animate") local settings = require("druid.settings") -local helper = require("druid.helper.helper") +local helper = require("druid.helper") local b_settings = settings.button local M = {} @@ -18,7 +18,7 @@ M.DEFAUL_ACTIVATION_TIME = 0.2 function M.init(instance, node, callback, params, anim_node, event) instance.node = helper.get_node(node) instance.event = data.A_TOUCH - instance.anim_node = anim_node and gui.get_node(anim_node) or instance.node + instance.anim_node = anim_node and helper.get_node(anim_node) or instance.node instance.scale_from = gui.get_scale(instance.anim_node) instance.scale_to = instance.scale_from + b_settings.SCALE_CHANGE instance.scale_hover_to = instance.scale_from + b_settings.HOVER_SCALE diff --git a/druid/base/progress.lua b/druid/base/progress.lua new file mode 100644 index 0000000..69eebe3 --- /dev/null +++ b/druid/base/progress.lua @@ -0,0 +1,150 @@ +local data = require("druid.data") +local helper = require("druid.helper") +local settings = require("druid.settings") +local p_settings = settings.progress + +local M = {} + +M.interest = { + data.ON_UPDATE, +} + +local PROP_Y = "y" +local PROP_X = "x" + + +function M.init(instance, name, key, init_value) + if key ~= PROP_X and key ~= PROP_Y then + settings.log("progress component: key must be 'x' or 'y'. Passed:", key) + key = PROP_X + end + + instance.prop = hash("scale."..key) + instance.key = key + + instance.node = helper.get_node(name) + instance.scale = gui.get_scale(instance.node) + instance.size = gui.get_size(instance.node) + instance.max_size = instance.size[instance.key] + instance.slice = gui.get_slice9(instance.node) + if key == PROP_X then + instance.slice_size = instance.slice.x + instance.slice.z + else + instance.slice_size = instance.slice.y + instance.slice.w + end + + instance:set_to(init_value or 1) +end + + +local function check_steps(instance, from, to, exactly) + if not instance.steps then + return + end + + for i = 1, #instance.steps do + local step = instance.steps[i] + local v1, v2 = from, to + if v1 > v2 then + v1, v2 = v2, v1 + end + + if v1 < step and step < v2 then + instance.step_callback(instance.parent.parent, step) + end + if exactly and exactly == step then + instance.step_callback(instance.parent.parent, step) + end + end +end + + +local function set_bar_to(instance, set_to, is_silence) + local prev_value = instance.last_value + instance.last_value = set_to + + local total_width = set_to * instance.max_size + + local scale = math.min(total_width / instance.slice_size, 1) + local size = math.max(total_width, instance.slice_size) + + instance.scale[instance.key] = scale + gui.set_scale(instance.node, instance.scale) + instance.size[instance.key] = size + gui.set_size(instance.node, instance.size) + + if not is_silence then + check_steps(instance, prev_value, set_to) + end +end + + +--- Fill a progress bar and stop progress animation +function M.fill(instance) + set_bar_to(instance, 1, true) +end + + +--- To empty a progress bar +function M.empty(instance) + set_bar_to(instance, 0, true) +end + + +--- Set fill a progress bar to value +-- @param to - value between 0..1 +function M.set_to(instance, to) + set_bar_to(instance, to) +end + + +function M.get(instance) + return instance.last_value +end + + +function M.set_steps(instance, steps, step_callback) + instance.steps = steps + instance.step_callback = step_callback +end + + +--- Start animation of a progress bar +-- @param to - value between 0..1 +-- @param callback - callback when progress ended if need +function M.to(instance, to, callback) + to = helper.clamp(to, 0, 1) + -- cause of float error + local value = helper.round(to, 5) + if value ~= instance.last_value then + instance.target = value + instance.target_callback = callback + else + if callback then + callback(instance.parent.parent, to) + end + end +end + + +function M.update(instance, dt) + if instance.target then + local prev_value = instance.last_value + local step = math.abs(instance.last_value - instance.target) * (p_settings.SPEED*dt) + step = math.max(step, p_settings.MIN_DELTA) + instance:set_to(helper.step(instance.last_value, instance.target, step)) + + if instance.last_value == instance.target then + check_steps(instance, prev_value, instance.target, instance.target) + + if instance.target_callback then + instance.target_callback(instance.parent.parent, instance.target) + end + + instance.target = nil + end + end +end + + +return M \ No newline at end of file diff --git a/druid/base/text.lua b/druid/base/text.lua index f107589..3f3993f 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,11 +1,10 @@ local data = require("druid.data") local settings = require("druid.settings") -local helper = require("druid.helper.helper") +local helper = require("druid.helper") local M = {} M.interest = { data.TRANSLATABLE, - data.LAYOUT_CHANGED } @@ -82,15 +81,4 @@ function M.set_scale(instance, scale) end ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - if instance.last_color then - M.set_color(instance, instance.last_color) - end - if instance.last_scale then - M.set_scale(instance, instance.last_scale) - end -end - - return M \ No newline at end of file diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 38deb1c..14cb8c6 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,10 +1,9 @@ local data = require("druid.data") local formats = require("druid.helper.formats") -local helper = require("druid.helper.helper") +local helper = require("druid.helper") local M = {} M.interest = { - data.LAYOUT_CHANGED, data.ON_UPDATE } @@ -36,12 +35,6 @@ function M.set_to(instance, set_to) end ---- Called when layout updated (rotate for example) -function M.on_layout_updated(instance) - M.set_to(instance, instance.last_value) -end - - --- Called when update -- @param is_on - boolean is timer on function M.set_state(instance, is_on) diff --git a/druid/druid.lua b/druid/druid.lua index a7592b0..b85147e 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -12,6 +12,9 @@ M.comps = { android_back = require("druid.base.android_back"), text = require("druid.base.text"), timer = require("druid.base.timer"), + progress = require("druid.base.progress"), + + progress_rich = require("druid.rich.progress_rich"), } diff --git a/druid/helper/helper.lua b/druid/helper.lua similarity index 79% rename from druid/helper/helper.lua rename to druid/helper.lua index a23f5c9..0e01c65 100644 --- a/druid/helper/helper.lua +++ b/druid/helper.lua @@ -36,6 +36,27 @@ function M.step(current, target, step) 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.round(num, numDecimalPlaces) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(num * mult + 0.5) / mult +end + + function M.is_enabled(node) local is_enabled = gui.is_enabled(node) local parent = gui.get_parent(node) diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua new file mode 100644 index 0000000..8785794 --- /dev/null +++ b/druid/rich/progress_rich.lua @@ -0,0 +1,55 @@ +local settings = require("druid.settings") +local pr_settings = settings.progress_rich + +local M = {} + +function M.init(instance, name, red, green, key) + instance.red = instance.parent:new_progress(red, key) + instance.green = instance.parent:new_progress(green, key) + instance.fill = instance.parent:new_progress(name, key) +end + + +function M.set_to(instance, value) + instance.red:set_to(value) + instance.green:set_to(value) + instance.fill:set_to(value) +end + + +function M.empty(instance) + instance.red:empty() + instance.green:empty() + instance.fill:empty() +end + + +function M.to(instance, to, callback) + if instance.timer then + timer.cancel(instance.timer) + instance.timer = nil + end + + if instance.fill.last_value < to then + instance.red:to(instance.fill.last_value) + instance.green:to(to, function() + instance.timer = timer.delay(pr_settings.DELAY, false, function() + instance.red:to(to) + instance.fill:to(to, callback) + end) + end) + end + + if instance.fill.last_value > to then + instance.green:to(instance.red.last_value) + instance.fill:to(to, function() + instance.timer = timer.delay(pr_settings.DELAY, false, function() + instance.green:to(to) + instance.red:to(to, callback) + end) + end) + end +end + + +return M \ No newline at end of file diff --git a/druid/settings.lua b/druid/settings.lua index 4cf4fbc..323ab3e 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -12,6 +12,14 @@ M.button = { SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), } +M.progress = { + SPEED = 5, -- progress bar fill rate, more faster + MIN_DELTA = 0.005 +} + +M.progress_rich = { + DELAY = 1, -- delay in seconds before main fill +} function M.get_text(name) diff --git a/example/example.gui b/example/example.gui index eb5d5b0..5669836 100644 --- a/example/example.gui +++ b/example/example.gui @@ -15,8 +15,407 @@ background_color { } nodes { position { + x: 300.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: "control" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: -150.0 + y: 50.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.5 + z: 1.0 + w: 1.0 + } + size { + x: 426.0 + y: 190.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/green_long" + id: "prev" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "control" + 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: 0.0 + y: 20.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: 200.0 - y: 325.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Prev" + font: "game" + id: "prev_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "prev" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: 50.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.5 + z: 1.0 + w: 1.0 + } + size { + x: 426.0 + y: 190.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/green_long" + id: "next" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "control" + 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: 0.0 + y: 20.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Next" + font: "game" + id: "next_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "next" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 300.0 + y: 400.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: "center" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: 0.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: "buttons" + 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: 0.0 + y: 254.0 z: 0.0 w: 1.0 } @@ -52,6 +451,7 @@ nodes { yanchor: YANCHOR_NONE pivot: PIVOT_CENTER adjust_mode: ADJUST_MODE_FIT + parent: "buttons" layer: "" inherit_alpha: true slice9 { @@ -132,8 +532,8 @@ nodes { } nodes { position { - x: 200.0 - y: 200.0 + x: 0.0 + y: 129.0 z: 0.0 w: 1.0 } @@ -169,6 +569,7 @@ nodes { yanchor: YANCHOR_NONE pivot: PIVOT_CENTER adjust_mode: ADJUST_MODE_FIT + parent: "buttons" layer: "" inherit_alpha: true slice9 { @@ -249,8 +650,503 @@ nodes { } nodes { position { - x: 200.0 - y: 75.0 + x: 600.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: "progress" + 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: 0.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: 391.0 + y: 40.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/progress_back" + id: "simple_back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "progress" + 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: -194.5 + y: 2.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: 389.0 + y: 35.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/progress_yellow" + id: "simple_fill" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "simple_back" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 0.0 + z: 15.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: 0.0 + y: 106.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: 391.0 + y: 40.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/progress_back" + id: "simple_vert" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "progress" + 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: 0.0 + y: -17.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: 389.0 + y: 35.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/progress_yellow" + id: "simple_vert_fill" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_S + adjust_mode: ADJUST_MODE_FIT + parent: "simple_vert" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 0.0 + z: 15.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: 0.0 + y: -130.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: 391.0 + y: 40.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/progress_back" + id: "rich_back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "progress" + 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: -194.5 + y: 2.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: 389.0 + y: 35.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.6 + y: 0.6 + z: 0.6 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "gui/progress_green" + id: "rich_green" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "rich_back" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 0.0 + z: 15.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: -194.5 + y: 2.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: 389.0 + y: 35.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/progress_red" + id: "rich_red" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "rich_back" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 0.0 + z: 15.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: -194.5 + y: 2.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: 389.0 + y: 35.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/progress_yellow" + id: "rich_fill" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "rich_back" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 0.0 + z: 15.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: 110.0 + y: 250.0 z: 0.0 w: 1.0 } @@ -281,11 +1177,12 @@ nodes { type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA texture: "gui/green_long" - id: "button_3" + id: "rich_add" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER adjust_mode: ADJUST_MODE_FIT + parent: "progress" layer: "" inherit_alpha: true slice9 { @@ -334,9 +1231,9 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "Button 3" + text: "add rich" font: "game" - id: "text_3" + id: "rich_add_text" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER @@ -354,7 +1251,126 @@ nodes { } adjust_mode: ADJUST_MODE_FIT line_break: false - parent: "button_3" + parent: "rich_add" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -110.0 + y: 250.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.5 + z: 1.0 + w: 1.0 + } + size { + x: 426.0 + y: 190.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/green_long" + id: "rich_dec" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "progress" + 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: 0.0 + y: 20.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "dec rich\n" + "" + font: "game" + id: "rich_dec_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "rich_dec" layer: "" inherit_alpha: true alpha: 1.0 diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index ec37096..1b4bc7a 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -4,52 +4,101 @@ local druid_settings = require("druid.settings") local lang = { locale_text = "Localized" } +local start_x = 300 +local page_width = 600 +local cur_page = 1 +local max_page = 2 + + + +local function log(self, params) + print(params) +end + local function setup_druid(self) - -- two different way of exernal component regesstration druid.comps["my_mega_test_comp"] = require "druid.base.text" druid.register("my_custom_component", {}) - + druid_settings.is_debug = true - druid_settings.play_sound = function(name) sound.play("sounds#" .. name) end - druid_settings.get_text = function(text_id) return lang[text_id] end end + +local function change_page(self, delta) + cur_page = cur_page + delta + cur_page = math.max(1, cur_page) + cur_page = math.min(cur_page, max_page) + + gui.animate(gui.get_node("center"), "position.x", + start_x - (page_width * (cur_page - 1)), gui.EASING_OUTSINE, 0.1) +end + +local function init_pages(self) + self.druid:new_button("prev", change_page, -1) + self.druid:new_button("next", change_page, 1) +end + + +local function init_buttons(self) + self.druid:new_button("button_1", log, "button 1") + + self.druid:new(druid.comps.button, "button_2", log, "button 2") +end + + +local function init_progress(self) + local val = 0.4 + local simple = self.druid:new_progress("simple_fill", "x", val) + local vert = self.druid:new_progress("simple_vert_fill", "y", val) + + simple:set_steps({0, 0.3, 0.6, 1}, function(self, step) + print("STEP:", step) + end) + + timer.delay(0.4, true, function() + val = val + 0.1 + if val > 1 then + simple:empty() + vert:empty() + val = 0 + end + simple:to(val) + 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 + rich:to(rich_val) + end) + self.druid:new_button("rich_dec", function() + rich_val = rich_val - 0.1 + rich:to(rich_val) + end) +end + + function init(self) setup_druid(self) self.druid = druid.new(self) - self.druid:new_button("button_1", function() - print("On button 1") - end) - - --alternative way of component creation - self.druid:new(druid.comps.button, "button_2", function() - print("On button 2") - end) - - self.druid:new_button("button_3", function() - print("On button 3") - end) - - self.druid:new_android_back(function(self, params) - print("On android back", params) - end, 2) - - self.druid:new_text("text_2", "Simple text", false, 400) - self.druid:new_text("text_3", "locale_text", true) - - self.druid:new_timer("text_1", 5, 0, function() - print("On timer end") - end) + init_pages(self) + init_buttons(self) + init_progress(self) + self.druid:new_android_back(log, "some") end function update(self, dt) diff --git a/example/gui.atlas b/example/gui.atlas index 0170ec5..6cb5a3a 100644 --- a/example/gui.atlas +++ b/example/gui.atlas @@ -4,6 +4,21 @@ images { images { image: "/example/res/green_long.png" } -margin: 0 -extrude_borders: 0 +images { + image: "/example/res/progress_back.png" +} +images { + image: "/example/res/progress_green.png" +} +images { + image: "/example/res/progress_red.png" +} +images { + image: "/example/res/progress_yellow.png" +} +images { + image: "/example/res/empty.png" +} +margin: 2 +extrude_borders: 2 inner_padding: 0 diff --git a/example/res/custom.texture_profiles b/example/res/custom.texture_profiles new file mode 100644 index 0000000..5b0d776 --- /dev/null +++ b/example/res/custom.texture_profiles @@ -0,0 +1,18 @@ +path_settings { + path: "**" + profile: "Default" +} +profiles { + name: "Default" + platforms { + os: OS_ID_GENERIC + formats { + format: TEXTURE_FORMAT_RGBA + compression_level: BEST + compression_type: COMPRESSION_TYPE_DEFAULT + } + mipmaps: false + max_texture_size: 0 + premultiply_alpha: true + } +} diff --git a/example/res/empty.png b/example/res/empty.png new file mode 100755 index 0000000000000000000000000000000000000000..5da9ec0922e6066d3284b286ec892cc4f6745636 GIT binary patch literal 14525 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 literal 0 HcmV?d00001 diff --git a/example/res/progress_yellow.png b/example/res/progress_yellow.png new file mode 100755 index 0000000000000000000000000000000000000000..3e4e38d959eef9831526d07b6b37b60934767ff9 GIT binary patch literal 1447 zcmV;Y1z7rtP)B#u+WAz7C<7=*odN03k!V7YUzJ~B$D6;E!>1?EY!b%Eu}H| z-XNltB$y2y&|qRC6d)AB?#!HHo^#KgxibuEx9rUClT3E@&MZ53nLNLF?z#6I`~9oO zF#`)md&X~pnGJ!N+3J3)ZTT?+Fj~L?;CWy_up8J8Y(+#w*4i!LCU6C~0GtKRk?18L z#YC^0=yoEVmBi;~4&C!|+qu@8(P|m3cA&k%#s$Jd7)OA&fnEA<7ZG_NZ7sJ)fER%U z;7^PtOMFVO>#bb%0}#i){*a4)AP0bV3Ntwj`hl>)jN=$rfny2;5s`IgSFYd2RWsiA zy6*Me>-;#u4;@ucs6rv%Z{$(M-^Ey9H4uue`9}IpA zEe_;BF!t#^AR;nBjC}^bdYvD)Q^5lvwCXU(9l}8~`yOMP-UlKg6Uf+RWgX$9&(?d}A5$>nU8{~YiHOKFghIX~fxTuNt+!RDq#8Rd*n%k$L`0@axp;Zu$V;bp zQm$a|&4>G^ohleaM5e=_-fseX$M4wnvwPYbH@E(nnGL)AI)!kbb5}(~Wb(wGPkWK* zti)?~|L#5Pox(FI=}Ki0k!h9^e)#CQP)%-^27ijA_l1baR2ZuF`I{F)is^}zs@e0B z0zpJ%sx<3=ifM01iN|8SA*oRi5t$aL4uu3I2j)VIY>&NaupyWy96n;yQ{)3%Pq}Pqr6Qaf#L_{V+8k~Mwg+R>pz77S?ffUn4zj*COKekk* zMx?u%@+$w`P9qplFo=k(TdC0@bgTNF>-=g}_j~2+Q{arR>;FqiTqCj5pFCLMzgq1- zr9i7yt+`-6dy=L`5)oNH%Aj%{Lnt5qJrFvpaq!{4>LRWIKY8Wv0w?n*bpJ3?%s;TY z;+@0b2YbDd(^l0zh=@E`((vh~gRz6Eo_k$y212Y38~HArTw0#*w#&|Z1{_W?ZHnFs zl#ao>gcKv~XvA2S?euk=W0`|nU4w|o1E)VjMgPLI!Ju+AhHy_H+$lLg9SYtyoB$Sc z$AFPKDF;IGKpU~yt; zdERrN9}4ah;0<7JexgCI%!lD!La#gM6!MzR)rxI-m4^IPp&%l%c2XS-sXv!dJ%v#- z9P(L4X=nn}i>3Z&%}`hY-UQAATkF=tO4nePsvz)AAu!Y_s7nwLS$lP%?{^C2@X*kt zr^EBx-SWD>v^>93Z)lI~#bw|%;5%Sr{~s@f-xJ0{qDLJFiP9{Hh{#%N%urMp|1q6G z?XK7RrRDj{&5fg>;LZXs1E+y)^~Sn$pbRqSV@r(|LAf9zvUY~o%Sp{Ig-ezk#)hx5Z(eVjeD`-U-rO%;7Q*rNA{h{&3|4cq{(02j&_@i`v_{$H;Q_y>2k4O4<+oVfr1002ovPDHLkV1gvO BzJCA! literal 0 HcmV?d00001 diff --git a/game.project b/game.project index adf34bf..c62a018 100644 --- a/game.project +++ b/game.project @@ -5,8 +5,8 @@ main_collection = /example/example.collectionc shared_state = 1 [display] -width = 400 -height = 400 +width = 600 +height = 900 [project] title = druid @@ -14,3 +14,6 @@ title = druid [library] include_dirs = druid +[graphics] +texture_profiles = /example/res/custom.texture_profiles + From bd2c06d81b6a9ce014480fc0501074a56e6648b7 Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Thu, 4 Apr 2019 23:10:03 +0300 Subject: [PATCH 031/136] basic implementation of grid (#19) * basic implementation of grid * add dirty example of grid --- druid/base/grid.lua | 86 +++++++++++ druid/druid.lua | 1 + example/example.gui | 275 +++++++++++++++++++++++++++++++++ example/example.gui.gui_script | 45 +++++- 4 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 druid/base/grid.lua 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 From 19a9d2763503db3eee2ddb71e5f900cd2c95133a Mon Sep 17 00:00:00 2001 From: Maxim Tuprikov Date: Sun, 7 Apr 2019 12:10:16 +0300 Subject: [PATCH 032/136] Feature/scroll (#22) * base scroll implementation * add scroll collection example mofidy scrolls, fix callback calls * unhover button if start swipe notify input components on swipe * add node center offset, calc by pivots modify with with node center scroll (to correct scroll to point) * Refactor, add some docs * fix: set_pos on end on scroll * add gui.animate speed in settings --- druid/base/button.lua | 8 + druid/base/grid.lua | 10 + druid/base/scroll.lua | 384 +++++++++++++++ druid/druid.lua | 17 +- druid/helper.lua | 28 ++ druid/settings.lua | 10 + example/scroll.collection | 37 ++ example/scroll/scroll.gui | 821 +++++++++++++++++++++++++++++++ example/scroll/scroll.gui_script | 86 ++++ game.project | 2 +- 10 files changed, 1401 insertions(+), 2 deletions(-) create mode 100644 druid/base/scroll.lua create mode 100644 example/scroll.collection create mode 100644 example/scroll/scroll.gui create mode 100644 example/scroll/scroll.gui_script diff --git a/druid/base/button.lua b/druid/base/button.lua index f7ebb6c..e36802d 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -76,6 +76,7 @@ function M.on_input(instance, action_id, action) end if action.released then + set_hover(instance, false) return on_button_release(instance) else set_hover(instance, true) @@ -90,6 +91,13 @@ function M.on_input(instance, action_id, action) end +function M.on_swipe(instance) + -- unhover button if start swipe + instance.can_action = false + set_hover(instance, false) +end + + function M.tap_scale_animation(instance) ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, function() diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 485b15f..b164018 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -83,4 +83,14 @@ function M.get_size(instance) end +function M.get_all_pos(instance) + local result = {} + for i = 1, #instance.nodes do + table.insert(result, gui.get_position(instance.nodes[i])) + end + + return result +end + + return M \ No newline at end of file diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua new file mode 100644 index 0000000..af09c81 --- /dev/null +++ b/druid/base/scroll.lua @@ -0,0 +1,384 @@ +local helper = require("druid.helper") +local data = require("druid.data") +local settings = require("druid.settings").scroll + +local M = {} + +local SIDE_X = "x" +local SIDE_Y = "y" + +M.interest = { + data.ON_UPDATE, + data.ON_SWIPE, +} + + +function M.init(self, scroll_parent, input_zone, border) + self.node = helper.get_node(scroll_parent) + self.input_zone = helper.get_node(input_zone) + self.zone_size = gui.get_size(self.input_zone) + self:set_border(border) + self.soft_size = settings.SOFT_ZONE_SIZE + + -- Distance from node to node's center + local offset = helper.get_pivot_offset(gui.get_pivot(self.input_zone)) + self.center_offset = vmath.vector3(self.zone_size) + self.center_offset.x = self.center_offset.x * offset.x + self.center_offset.y = self.center_offset.y * offset.y + + self.is_inert = true + self.inert = vmath.vector3(0) + self.pos = gui.get_position(self.node) + self.target = vmath.vector3(self.pos) + + self.input = { + touch = false, + scroll = false, + start_x = 0, + start_y = 0, + side = false, + } +end + + +local function set_pos(self, pos) + self.pos.x = pos.x + self.pos.y = pos.y + + gui.set_position(self.node, self.pos) +end + + +--- Return scroll, if it outside of scroll area +-- Using the lerp with BACK_SPEED koef +local function check_soft_target(self) + local t = self.target + local b = self.border + + if t.y < b.y then + t.y = helper.step(t.y, b.y, math.abs(t.y - b.y) * settings.BACK_SPEED) + end + if t.x < b.x then + t.x = helper.step(t.x, b.x, math.abs(t.x - b.x) * settings.BACK_SPEED) + end + if t.y > b.w then + t.y = helper.step(t.y, b.w, math.abs(t.y - b.w) * settings.BACK_SPEED) + end + if t.x > b.z then + t.x = helper.step(t.x, b.z, math.abs(t.x - b.z) * settings.BACK_SPEED) + end +end + + +--- Free inert update function +local function update_hand_scroll(self, dt) + local inert = self.inert + local delta_x = self.target.x - self.pos.x + local delta_y = self.target.y - self.pos.y + + if helper.sign(delta_x) ~= helper.sign(inert.x) then + inert.x = 0 + end + if helper.sign(delta_y) ~= helper.sign(inert.y) then + inert.y = 0 + end + + inert.x = inert.x + delta_x + inert.y = inert.y + delta_y + + inert.x = math.abs(inert.x) * helper.sign(delta_x) + inert.y = math.abs(inert.y) * helper.sign(delta_y) + + inert.x = inert.x * settings.FRICT_HOLD + inert.y = inert.y * settings.FRICT_HOLD + + set_pos(self, self.target) +end + + +local function get_zone_center(self) + local pos = vmath.vector3(self.pos) + pos.x = pos.x + self.center_offset.x + pos.y = pos.y + self.center_offset.y + return pos +end + + +--- Find closer point of interest +-- if no inert, scroll to next point by scroll direction +-- if inert, find next point by scroll director +local function check_points(self) + if not self.points then + return + end + + local inert = self.inert + if not self.is_inert then + if math.abs(inert.x) > settings.DEADZONE then + self:scroll_to_index(self.selected - helper.sign(inert.x)) + return + end + if math.abs(inert.y) > settings.DEADZONE then + self:scroll_to_index(self.selected + helper.sign(inert.y)) + return + end + end + + -- Find closest point and point by scroll direction + -- Scroll to one of them (by scroll direction in priority) + local temp_dist = math.huge + local temp_dist_on_inert = math.huge + local index = false + local index_on_inert = false + local pos = get_zone_center(self) + for i = 1, #self.points do + local p = self.points[i] + local dist = helper.distance(pos.x, pos.y, p.x, p.y) + local on_inert = true + -- If inert ~= 0, scroll only by move direction + if inert.x ~= 0 and helper.sign(inert.x) ~= helper.sign(p.x - pos.x) then + on_inert = false + end + if inert.y ~= 0 and helper.sign(inert.y) ~= helper.sign(p.y - pos.y) then + on_inert = false + end + + if dist < temp_dist then + index = i + temp_dist = dist + end + if on_inert and dist < temp_dist_on_inert then + index_on_inert = i + temp_dist_on_inert = dist + end + end + self:scroll_to_index(index_on_inert or index) +end + + +local function check_threshold(self) + local inert = self.inert + if not self.is_inert or vmath.length(inert) < settings.INERT_THRESHOLD then + check_points(self) + inert.x = 0 + inert.y = 0 + end +end + + +local function update_free_inert(self, dt) + local inert = self.inert + if inert.x ~= 0 or inert.y ~= 0 then + self.target.x = self.pos.x + (inert.x * dt * settings.INERT_SPEED) + self.target.y = self.pos.y + (inert.y * dt * settings.INERT_SPEED) + + inert.x = inert.x * settings.FRICT + inert.y = inert.y * settings.FRICT + + -- Stop, when low inert speed and go to points + check_threshold(self) + end + + check_soft_target(self) + set_pos(self, self.target) +end + + +--- Cancel animation on other animation or input touch +local function cancel_animate(self) + if self.animate then + self.target = gui.get_position(self.node) + self.pos.x = self.target.x + self.pos.y = self.target.y + gui.cancel_animation(self.node, gui.PROP_POSITION) + self.animate = false + end +end + + +function M.update(self, dt) + if self.input.touch then + if self.input.scroll then + update_hand_scroll(self, dt) + end + else + update_free_inert(self, dt) + end +end + + +local function add_delta(self, dx, dy) + local t = self.target + local b = self.border + local soft = self.soft_size + -- TODO: Can we calc it more easier? + -- A lot of calculations for every side of border + + -- Handle soft zones + -- Percent - multiplier for delta. Less if outside of scroll zone + local x_perc = 1 + local y_perc = 1 + + if t.x < b.x and dx < 0 then + x_perc = (soft - (b.x - t.x)) / soft + end + if t.x > b.z and dx > 0 then + x_perc = (soft - (t.x - b.z)) / soft + end + -- If disabled scroll by x + if not self.can_x then + x_perc = 0 + end + + if t.y < b.y and dy < 0 then + y_perc = (soft - (b.y - t.y)) / soft + end + if t.y > b.w and dy > 0 then + y_perc = (soft - (t.y - b.w)) / soft + end + -- If disabled scroll by y + if not self.can_y then + y_perc = 0 + end + + -- Reset inert if outside of scroll zone + if x_perc ~= 1 then + self.inert.x = 0 + end + if y_perc ~= 1 then + self.inert.y = 0 + end + + t.x = t.x + dx * x_perc + t.y = t.y + dy * y_perc +end + + +function M.on_input(self, action_id, action) + if action_id ~= data.A_TOUCH then + return false + end + local inp = self.input + local inert = self.inert + local result = false + + if gui.pick_node(self.input_zone, action.x, action.y) then + if action.pressed then + cancel_animate(self) + inp.touch = true + inp.start_x = action.x + inp.start_y = action.y + inert.x = 0 + inert.y = 0 + self.target.x = self.pos.x + self.target.y = self.pos.y + else + local dist = helper.distance(action.x, action.y, inp.start_x, inp.start_y) + if not inp.scroll and dist >= settings.DEADZONE then + local dx = math.abs(inp.start_x - action.x) + local dy = math.abs(inp.start_y - action.y) + if dx > dy then + inp.side = SIDE_X + else + inp.side = SIDE_Y + end + -- Check scroll side if we can scroll + if self.can_x and inp.side == SIDE_X or + self.can_y and inp.side == SIDE_Y then + inp.scroll = true + end + end + if inp.scroll then + add_delta(self, action.dx, action.dy) + result = true + end + end + end + + if action.released then + if inp.scroll then + inp.touch = false + inp.scroll = false + inp.side = false + result = true + end + check_threshold(self) + end + + return result +end + + +--- Start scroll to point (x, y, z) +function M.scroll_to(self, point) + local b = self.border + local target = vmath.vector3(point) + target.x = helper.clamp(point.x - self.center_offset.x, b.x, b.z) + target.y = helper.clamp(point.y - self.center_offset.y, b.y, b.w) + + cancel_animate(self) + + self.animate = true + gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function() + self.animate = false + self.target = target + set_pos(self, target) + end) +end + + +--- Scroll to item in scroll by points index +function M.scroll_to_index(self, index, skip_cb) + index = helper.clamp(index, 1, #self.points) + + if self.selected ~= index then + self.selected = index + + if not skip_cb and self.on_point_callback then + self.on_point_callback(self.parent.parent, index, self.points[index]) + end + end + + self:scroll_to(self.points[index]) +end + + +--- Set points of interest +-- Scroll will always centered on closer points +function M.set_points(self, points) + self.points = points + -- cause of parent move in other side by y + for i = 1, #self.points do + self.points[i].y = -self.points[i].y + end + + table.sort(self.points, function(a, b) + return a.x > b.x or a.y < b.y + end) + check_threshold(self) +end + + +--- Enable or disable scroll inert +-- If disabled, scroll through points (if exist) +-- If no points, just simple drag without inertion +function M.set_inert(self, state) + self.is_inert = state +end + + +--- Set the callback on scrolling to point (if exist) +function M.on_point_move(self, callback) + self.on_point_callback = callback +end + + +--- Set the scroll possibly area +function M.set_border(self, border) + self.border = border + self.can_x = (border.x ~= border.z) + self.can_y = (border.y ~= border.w) +end + + +return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index 98a1338..23f63eb 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -14,6 +14,7 @@ M.comps = { timer = require("druid.base.timer"), progress = require("druid.base.progress"), grid = require("druid.base.grid"), + scroll = require("druid.base.scroll"), progress_rich = require("druid.rich.progress_rich"), } @@ -72,7 +73,7 @@ local function create(module, factory) end factory[v][#factory[v] + 1] = instance - if v == data.ON_INPUT then + if v == data.ON_INPUT or v == data.ON_SWIPE then input_init(factory) end end @@ -112,6 +113,19 @@ function _factory.on_message(factory, message_id, message, sender) end +local function notify_input_on_swipe(factory) + if factory[data.ON_INPUT] then + local len = #factory[data.ON_INPUT] + for i = len, 1, -1 do + local comp = factory[data.ON_INPUT][i] + if comp.on_swipe then + comp:on_swipe() + end + end + end +end + + --- Called ON_INPUT function _factory.on_input(factory, action_id, action) if factory[data.ON_SWIPE] then @@ -122,6 +136,7 @@ function _factory.on_input(factory, action_id, action) result = result or v:on_input(action_id, action) end if result then + notify_input_on_swipe(factory) return true end end diff --git a/druid/helper.lua b/druid/helper.lua index 0e01c65..05d6695 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -51,6 +51,19 @@ function M.clamp(a, min, max) 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 @@ -68,4 +81,19 @@ function M.is_enabled(node) end +local pivots = { + [gui.PIVOT_CENTER] = vmath.vector3(0), + [gui.PIVOT_N] = vmath.vector3(0, 0.5, 0), + [gui.PIVOT_NE] = vmath.vector3(0.5, 0.5, 0), + [gui.PIVOT_E] = vmath.vector3(0.5, 0, 0), + [gui.PIVOT_SE] = vmath.vector3(0.5, -0.5, 0), + [gui.PIVOT_S] = vmath.vector3(0, -0.5, 0), + [gui.PIVOT_SW] = vmath.vector3(-0.5, -0.5, 0), + [gui.PIVOT_W] = vmath.vector3(-0.5, 0, 0), + [gui.PIVOT_NW] = vmath.vector3(-0.5, -0.5, 0), +} +function M.get_pivot_offset(pivot) + return pivots[pivot] +end + return M \ No newline at end of file diff --git a/druid/settings.lua b/druid/settings.lua index 323ab3e..bd2b31c 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -21,6 +21,16 @@ M.progress_rich = { DELAY = 1, -- delay in seconds before main fill } +M.scroll = { + FRICT_HOLD = 0.8, -- mult. for inert, while touching + FRICT = 0.93, -- mult for free inert + INERT_THRESHOLD = 2, -- speed to stop inertion + INERT_SPEED = 25, -- koef. of inert speed + DEADZONE = 6, -- in px + SOFT_ZONE_SIZE = 160, -- size of outside zone (back move) + BACK_SPEED = 0.2, -- lerp speed + ANIM_SPEED = 0.3, -- gui.animation speed to point +} function M.get_text(name) -- override to get text for localized text diff --git a/example/scroll.collection b/example/scroll.collection new file mode 100644 index 0000000..c54a758 --- /dev/null +++ b/example/scroll.collection @@ -0,0 +1,37 @@ +name: "default" +scale_along_z: 0 +embedded_instances { + id: "scroll" + data: "components {\n" + " id: \"scroll\"\n" + " component: \"/example/scroll/scroll.gui\"\n" + " position {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " }\n" + " rotation {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " w: 1.0\n" + " }\n" + "}\n" + "" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale3 { + x: 1.0 + y: 1.0 + z: 1.0 + } +} diff --git a/example/scroll/scroll.gui b/example/scroll/scroll.gui new file mode 100644 index 0000000..c9fab11 --- /dev/null +++ b/example/scroll/scroll.gui @@ -0,0 +1,821 @@ +script: "/example/scroll/scroll.gui_script" +fonts { + name: "game" + font: "/example/game.font" +} +textures { + name: "gui" + texture: "/example/gui.atlas" +} +background_color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 +} +nodes { + position { + x: 300.0 + y: 450.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: 600.0 + y: 900.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: "input_zone" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + 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: 0.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: "parent" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "input_zone" + 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: 0.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: "main_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "parent" + 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: 0.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Main scroll page" + font: "game" + id: "main_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "main_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -600.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: "left_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "parent" + 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: 0.0 + y: 330.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Left text\n" + "" + font: "game" + id: "left_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "left_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: 554.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: 400.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: "left_page" + layer: "" + inherit_alpha: false + 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: 0.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "1" + font: "game" + id: "number" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "prefab" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: -150.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: 600.0 + y: 600.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: "" + id: "page_input" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "left_page" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_STENCIL + clipping_visible: true + clipping_inverted: false + alpha: 0.3 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 300.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: 600.0 + y: 600.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: "page_parent" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_STRETCH + parent: "page_input" + 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: 600.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: "right_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "parent" + 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: 0.0 + y: 330.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Right text\n" + "" + font: "game" + id: "right_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "right_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: 150.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: 600.0 + y: 600.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: "" + id: "right_input" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_STRETCH + parent: "right_page" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_STENCIL + clipping_visible: true + clipping_inverted: false + alpha: 0.3 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.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: 600.0 + y: 600.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: "right_parent" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_STRETCH + parent: "right_input" + 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 +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT +max_nodes: 512 diff --git a/example/scroll/scroll.gui_script b/example/scroll/scroll.gui_script new file mode 100644 index 0000000..5fa69d6 --- /dev/null +++ b/example/scroll/scroll.gui_script @@ -0,0 +1,86 @@ +local druid = require("druid.druid") + + +local function init_left_page(self) + local prefab = gui.get_node("prefab") + self.left_grid = self.druid:new_grid("page_parent", prefab, 1) + self.left_grid:set_offset(vmath.vector3(0, 5, 0)) + self.left_grid:set_anchor(vmath.vector3(0.5, 0, 0)) + + for i = 1, 30 do + local nodes = gui.clone_tree(prefab) + gui.set_text(nodes["number"], i) + self.left_grid:add(nodes["prefab"]) + end + + local size = self.left_grid:get_size() + local view_size = gui.get_size(gui.get_node("page_parent")) + + self.left_scroll = self.druid:new_scroll("page_parent", "page_input", + vmath.vector4(0, view_size.y/2, 0, -size.w - view_size.y/2)) + + self.left_scroll:set_points(self.left_grid:get_all_pos()) +end + + +local function log(self, index) + print("Click on", index) +end + + +local function init_right_page(self) + local prefab = gui.get_node("prefab") + self.right_grid = self.druid:new_grid("right_parent", prefab, 1) + self.right_grid:set_offset(vmath.vector3(0, 5, 0)) + self.right_grid:set_anchor(vmath.vector3(0.5, 0, 0)) + + for i = 1, 20 do + local nodes = gui.clone_tree(prefab) + gui.set_text(nodes["number"], i) + self.druid:new_button(nodes["prefab"], log, i) + self.right_grid:add(nodes["prefab"]) + end + + local size = self.right_grid:get_size() + local view_size = gui.get_size(gui.get_node("right_parent")) + + -- TODO: Should we calc scrolle size with parent size? + -- If yes, we will pass only content size to correct scrolling + self.right_scroll = self.druid:new_scroll("right_parent", "right_input", + vmath.vector4(0, 0, 0, -size.w - view_size.y)) + + self.right_scroll:set_points(self.right_grid:get_all_pos()) + + self.right_scroll:on_point_move(function(self, index, pos) + print("Point to element:", index) + end) +end + + +function init(self) + self.druid = druid.new(self) + + -- -600 to 600 - left and right pos.x pages + -- border is vmath.vector4(left_x, top_y, right_x, bot_y) + self.main_scroll = self.druid:new_scroll("parent", "input_zone", + vmath.vector4(-600, 0, 600, 0)) + + self.main_scroll:set_points({ + vmath.vector3(600, 0, 0), + vmath.vector3(0, 0, 0), + vmath.vector3(-600, 0, 0), + }) + -- Disable free inert and we only scroll via points, if exist + self.main_scroll:set_inert(false) + + init_left_page(self) + init_right_page(self) +end + +function update(self, dt) + self.druid:update(dt) +end + +function on_input(self, action_id, action) + self.druid:on_input(action_id, action) +end diff --git a/game.project b/game.project index c62a018..16e04b5 100644 --- a/game.project +++ b/game.project @@ -1,5 +1,5 @@ [bootstrap] -main_collection = /example/example.collectionc +main_collection = /example/scroll.collectionc [script] shared_state = 1 From 82b15243fc0eb23d9d47b7042a3a23e7e3e817a8 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 7 Apr 2019 12:14:43 +0300 Subject: [PATCH 033/136] Can setup additional zone to check button click --- druid/base/button.lua | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index e36802d..48a1d2b 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -30,6 +30,7 @@ function M.init(instance, node, callback, params, anim_node, event) instance.hover_anim = b_settings.IS_HOVER instance.sound = b_settings.BTN_SOUND instance.sound_disable = b_settings.BTN_SOUND_DISABLED + instance.ext_zone = nil end @@ -68,7 +69,12 @@ function M.on_input(instance, action_id, action) return false end - if gui.pick_node(instance.node, action.x, action.y) then + local is_pick = gui.pick_node(instance.node, action.x, action.y) + if instance.ext_zone then + is_pick = is_pick and gui.pick_node(instance.ext_zone, action.x, action.y) + end + + if is_pick then if action.pressed then -- Can interact if start touch on the button instance.can_action = true @@ -172,4 +178,11 @@ function M.activate(instance, is_animate, callback) end end -return M +--- Set additional node, what need to be clicked on button click +-- Used, if need setup, what button can be clicked only in special zone +function M.set_ext_zone(instance, zone) + instance.ext_zone = helper.get_node(zone) +end + + +return M \ No newline at end of file From 263197eb8dd2521d6e01828ef5c14a55be896369 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 7 Apr 2019 15:14:06 +0300 Subject: [PATCH 034/136] disable scroll if scroll zone <= items zone --- druid/base/scroll.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index af09c81..fd56fe2 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -376,6 +376,8 @@ end --- Set the scroll possibly area function M.set_border(self, border) self.border = border + border.z = math.max(border.x, border.z) + border.w = math.max(border.y, border.w) self.can_x = (border.x ~= border.z) self.can_y = (border.y ~= border.w) end From 636df146c9a134d508accf60a75829a590bda129 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 7 Apr 2019 15:16:18 +0300 Subject: [PATCH 035/136] grid: add clear function, add grid anchoring and correct posing update examples --- druid/base/grid.lua | 48 ++++++++++++++++++++++---------- example/scroll/scroll.gui_script | 8 ++---- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/druid/base/grid.lua b/druid/base/grid.lua index b164018..e7e9a80 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -12,24 +12,33 @@ function M.init(instance, parent, element, in_row) instance.nodes = {} instance.offset = vmath.vector3(0) - instance.anchor = vmath.vector3(0) + instance.anchor = vmath.vector3(0.5, 0, 0) instance.in_row = in_row or 1 instance.node_size = gui.get_size(helper.get_node(element)) instance.border = vmath.vector4(0) + instance.border_offset = vmath.vector3(0) end local function check_border(instance, pos) + local border = instance.border 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) + local W = pos.x - size.x/2 + instance.border_offset.x + local E = pos.x + size.x/2 + instance.border_offset.x + local N = pos.y + size.y/2 + instance.border_offset.y + local S = pos.y - size.y/2 + instance.border_offset.y + + border.x = math.min(border.x, W) + border.y = math.max(border.y, N) + border.z = math.max(border.z, E) + border.w = math.min(border.w, S) + + instance.border_offset = vmath.vector3( + (border.x + (border.z - border.x) * instance.anchor.x), + (border.y + (border.w - border.y) * instance.anchor.y), + 0 + ) end @@ -38,10 +47,8 @@ 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 + temp_pos.x = col * (instance.node_size.x + instance.offset.x) - instance.border_offset.x + temp_pos.y = -row * (instance.node_size.y + instance.offset.y) - instance.border_offset.y return temp_pos end @@ -74,12 +81,15 @@ function M.add(instance, item, index) local pos = get_pos(instance, index) check_border(instance, pos) - gui.set_position(item, pos) + update_pos(instance) end function M.get_size(instance) - return instance.border + return vmath.vector3( + instance.border.z - instance.border.x, + instance.border.w - instance.border.y, + 0) end @@ -93,4 +103,12 @@ function M.get_all_pos(instance) end +function M.clear(instance) + for i = 1, #instance.nodes do + gui.delete_node(instance.nodes[i]) + end + instance.nodes = {} +end + + return M \ No newline at end of file diff --git a/example/scroll/scroll.gui_script b/example/scroll/scroll.gui_script index 5fa69d6..259b9be 100644 --- a/example/scroll/scroll.gui_script +++ b/example/scroll/scroll.gui_script @@ -5,9 +5,8 @@ local function init_left_page(self) local prefab = gui.get_node("prefab") self.left_grid = self.druid:new_grid("page_parent", prefab, 1) self.left_grid:set_offset(vmath.vector3(0, 5, 0)) - self.left_grid:set_anchor(vmath.vector3(0.5, 0, 0)) - for i = 1, 30 do + for i = 1, 7 do local nodes = gui.clone_tree(prefab) gui.set_text(nodes["number"], i) self.left_grid:add(nodes["prefab"]) @@ -17,7 +16,7 @@ local function init_left_page(self) local view_size = gui.get_size(gui.get_node("page_parent")) self.left_scroll = self.druid:new_scroll("page_parent", "page_input", - vmath.vector4(0, view_size.y/2, 0, -size.w - view_size.y/2)) + vmath.vector4(0, view_size.y/2, 0, -size.y - view_size.y/2)) self.left_scroll:set_points(self.left_grid:get_all_pos()) end @@ -32,7 +31,6 @@ local function init_right_page(self) local prefab = gui.get_node("prefab") self.right_grid = self.druid:new_grid("right_parent", prefab, 1) self.right_grid:set_offset(vmath.vector3(0, 5, 0)) - self.right_grid:set_anchor(vmath.vector3(0.5, 0, 0)) for i = 1, 20 do local nodes = gui.clone_tree(prefab) @@ -47,7 +45,7 @@ local function init_right_page(self) -- TODO: Should we calc scrolle size with parent size? -- If yes, we will pass only content size to correct scrolling self.right_scroll = self.druid:new_scroll("right_parent", "right_input", - vmath.vector4(0, 0, 0, -size.w - view_size.y)) + vmath.vector4(0, 0, 0, -size.y - view_size.y)) self.right_scroll:set_points(self.right_grid:get_all_pos()) From 08eae3800c8e086585d552985232edad34aa832c Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 7 Apr 2019 15:19:39 +0300 Subject: [PATCH 036/136] rename instance to self, update example --- druid/base/android_back.lua | 12 +-- druid/base/button.lua | 144 ++++++++++++++++----------------- druid/base/grid.lua | 102 +++++++++++------------ druid/base/progress.lua | 108 ++++++++++++------------- druid/base/text.lua | 66 +++++++-------- druid/base/timer.lua | 62 +++++++------- example/example.gui.gui_script | 2 + 7 files changed, 249 insertions(+), 247 deletions(-) diff --git a/druid/base/android_back.lua b/druid/base/android_back.lua index d40892c..775b01e 100644 --- a/druid/base/android_back.lua +++ b/druid/base/android_back.lua @@ -6,19 +6,19 @@ M.interest = { } -function M.init(instance, callback, params) - instance.event = data.A_ANDR_BACK - instance.callback = callback - instance.params = params +function M.init(self, callback, params) + self.event = data.A_ANDR_BACK + self.callback = callback + self.params = params end --- input handler -- @param action_id - input action id -- @param action - input action -function M.on_input(instance, action_id, action) +function M.on_input(self, action_id, action) if action[data.RELEASED] then - instance.callback(instance.parent.parent, instance.params) + self.callback(self.parent.parent, self.params) end return true end diff --git a/druid/base/button.lua b/druid/base/button.lua index 48a1d2b..f5bfab2 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -15,47 +15,47 @@ M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) M.DEFAUL_ACTIVATION_TIME = 0.2 -function M.init(instance, node, callback, params, anim_node, event) - instance.node = helper.get_node(node) - instance.event = data.A_TOUCH - instance.anim_node = anim_node and helper.get_node(anim_node) or instance.node - instance.scale_from = gui.get_scale(instance.anim_node) - instance.scale_to = instance.scale_from + b_settings.SCALE_CHANGE - instance.scale_hover_to = instance.scale_from + b_settings.HOVER_SCALE - instance.pos = gui.get_position(instance.anim_node) - instance.callback = callback - instance.params = params - instance.tap_anim = M.tap_scale_animation - instance.back_anim = M.back_scale_animation - instance.hover_anim = b_settings.IS_HOVER - instance.sound = b_settings.BTN_SOUND - instance.sound_disable = b_settings.BTN_SOUND_DISABLED - instance.ext_zone = nil +function M.init(self, node, callback, params, anim_node, event) + self.node = helper.get_node(node) + self.event = data.A_TOUCH + self.anim_node = anim_node and helper.get_node(anim_node) or self.node + self.scale_from = gui.get_scale(self.anim_node) + self.scale_to = self.scale_from + b_settings.SCALE_CHANGE + self.scale_hover_to = self.scale_from + b_settings.HOVER_SCALE + self.pos = gui.get_position(self.anim_node) + self.callback = callback + self.params = params + self.tap_anim = M.tap_scale_animation + self.back_anim = M.back_scale_animation + self.hover_anim = b_settings.IS_HOVER + self.sound = b_settings.BTN_SOUND + self.sound_disable = b_settings.BTN_SOUND_DISABLED + self.ext_zone = nil end -local function set_hover(instance, state) - if instance.hover_anim and instance._is_hovered ~= state then - local target_scale = state and instance.scale_hover_to or instance.scale_from - ui_animate.scale(instance, instance.node, target_scale, b_settings.HOVER_TIME) - instance._is_hovered = state +local function set_hover(self, state) + if self.hover_anim and self._is_hovered ~= state then + local target_scale = state and self.scale_hover_to or self.scale_from + ui_animate.scale(self, self.node, target_scale, b_settings.HOVER_TIME) + self._is_hovered = state end end -local function on_button_release(instance) - if not instance.disabled then - if not instance.stub and instance.can_action then - instance.can_action = false - instance.tap_anim(instance) - settings.play_sound(instance.sound) - instance.callback(instance.parent.parent, instance.params, instance) +local function on_button_release(self) + if not self.disabled then + if not self.stub and self.can_action then + self.can_action = false + self.tap_anim(self) + settings.play_sound(self.sound) + self.callback(self.parent.parent, self.params, self) else - set_hover(instance, false) + set_hover(self, false) end return true else - instance.sound_disable() + self.sound_disable() return false end end @@ -64,124 +64,124 @@ end --- Set text to text field -- @param action_id - input action id -- @param action - input action -function M.on_input(instance, action_id, action) - if not helper.is_enabled(instance.node) then +function M.on_input(self, action_id, action) + if not helper.is_enabled(self.node) then return false end - local is_pick = gui.pick_node(instance.node, action.x, action.y) - if instance.ext_zone then - is_pick = is_pick and gui.pick_node(instance.ext_zone, action.x, action.y) + local is_pick = gui.pick_node(self.node, action.x, action.y) + if self.ext_zone then + is_pick = is_pick and gui.pick_node(self.ext_zone, action.x, action.y) end if is_pick then if action.pressed then -- Can interact if start touch on the button - instance.can_action = true + self.can_action = true return true end if action.released then - set_hover(instance, false) - return on_button_release(instance) + set_hover(self, false) + return on_button_release(self) else - set_hover(instance, true) + set_hover(self, true) end - return not instance.disabled + return not self.disabled else -- Can't interact, if touch outside of button - instance.can_action = false - set_hover(instance, false) + self.can_action = false + set_hover(self, false) return false end end -function M.on_swipe(instance) +function M.on_swipe(self) -- unhover button if start swipe - instance.can_action = false - set_hover(instance, false) + self.can_action = false + set_hover(self, false) end -function M.tap_scale_animation(instance) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_to, +function M.tap_scale_animation(self) + ui_animate.scale_to(self, self.anim_node, self.scale_to, function() - if instance.back_anim then - instance.back_anim(instance) + if self.back_anim then + self.back_anim(self) end end ) end -function M.back_scale_animation(instance) - ui_animate.scale_to(instance, instance.anim_node, instance.scale_from) +function M.back_scale_animation(self) + ui_animate.scale_to(self, self.anim_node, self.scale_from) end -function M.deactivate(instance, is_animate, callback) - instance.disabled = true +function M.deactivate(self, is_animate, callback) + self.disabled = true if is_animate then local counter = 0 local clbk = function() counter = counter + 1 if counter == 3 and callback then - callback(instance.parent.parent) + callback(self.parent.parent) end end - ui_animate.color(instance, instance.node, M.DEFAULT_DEACTIVATE_COLOR, + ui_animate.color(self, self.node, M.DEFAULT_DEACTIVATE_COLOR, clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.x, + ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.x, M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_ACTIVATE_SCALE.y, + ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.y, M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) else - gui.set_color(instance.node, M.DEFAULT_DEACTIVATE_COLOR) - gui.set_scale(instance.node, M.DEFAULT_DEACTIVATE_SCALE) + gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR) + gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE) if callback then - callback(instance.parent.parent) + callback(self.parent.parent) end end end -function M.activate(instance, is_animate, callback) +function M.activate(self, is_animate, callback) if is_animate then local counter = 0 local clbk = function() counter = counter + 1 if counter == 3 then - instance.disabled = false + self.disabled = false if callback then - callback(instance.parent.parent) + callback(self.parent.parent) end end end - ui_animate.color(instance, instance.node, ui_animate.TINT_SHOW, + ui_animate.color(self, self.node, ui_animate.TINT_SHOW, clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) - ui_animate.scale_y_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.x, + ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.x, M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - ui_animate.scale_x_from_to(instance, instance.node, M.DEFAULT_DEACTIVATE_SCALE.y, + ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.y, M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) else - gui.set_color(instance.node, ui_animate.TINT_SHOW) - gui.set_scale(instance.node, M.DEFAULT_ACTIVATE_SCALE) - instance.disabled = false + gui.set_color(self.node, ui_animate.TINT_SHOW) + gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE) + self.disabled = false if callback then - callback(instance.parent.parent) + callback(self.parent.parent) end end end --- Set additional node, what need to be clicked on button click -- Used, if need setup, what button can be clicked only in special zone -function M.set_ext_zone(instance, zone) - instance.ext_zone = helper.get_node(zone) +function M.set_ext_zone(self, zone) + self.ext_zone = helper.get_node(zone) end diff --git a/druid/base/grid.lua b/druid/base/grid.lua index e7e9a80..496aea3 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -7,107 +7,107 @@ local M = {} -- 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 = {} +function M.init(self, parent, element, in_row) + self.parent = helper.get_node(parent) + self.nodes = {} - instance.offset = vmath.vector3(0) - instance.anchor = vmath.vector3(0.5, 0, 0) - instance.in_row = in_row or 1 - instance.node_size = gui.get_size(helper.get_node(element)) - instance.border = vmath.vector4(0) - instance.border_offset = vmath.vector3(0) + self.offset = vmath.vector3(0) + self.anchor = vmath.vector3(0.5, 0, 0) + self.in_row = in_row or 1 + self.node_size = gui.get_size(helper.get_node(element)) + self.border = vmath.vector4(0) + self.border_offset = vmath.vector3(0) end -local function check_border(instance, pos) - local border = instance.border - local size = instance.node_size +local function check_border(self, pos) + local border = self.border + local size = self.node_size - local W = pos.x - size.x/2 + instance.border_offset.x - local E = pos.x + size.x/2 + instance.border_offset.x - local N = pos.y + size.y/2 + instance.border_offset.y - local S = pos.y - size.y/2 + instance.border_offset.y + local W = pos.x - size.x/2 + self.border_offset.x + local E = pos.x + size.x/2 + self.border_offset.x + local N = pos.y + size.y/2 + self.border_offset.y + local S = pos.y - size.y/2 + self.border_offset.y border.x = math.min(border.x, W) border.y = math.max(border.y, N) border.z = math.max(border.z, E) border.w = math.min(border.w, S) - instance.border_offset = vmath.vector3( - (border.x + (border.z - border.x) * instance.anchor.x), - (border.y + (border.w - border.y) * instance.anchor.y), + self.border_offset = vmath.vector3( + (border.x + (border.z - border.x) * self.anchor.x), + (border.y + (border.w - border.y) * self.anchor.y), 0 ) 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 +local function get_pos(self, index) + local row = math.ceil(index / self.in_row) - 1 + local col = (index - row * self.in_row) - 1 - temp_pos.x = col * (instance.node_size.x + instance.offset.x) - instance.border_offset.x - temp_pos.y = -row * (instance.node_size.y + instance.offset.y) - instance.border_offset.y + temp_pos.x = col * (self.node_size.x + self.offset.x) - self.border_offset.x + temp_pos.y = -row * (self.node_size.y + self.offset.y) - self.border_offset.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)) +local function update_pos(self) + for i = 1, #self.nodes do + local node = self.nodes[i] + gui.set_position(node, get_pos(self, i)) end end -function M.set_offset(instance, offset) - instance.offset = offset - update_pos(instance) +function M.set_offset(self, offset) + self.offset = offset + update_pos(self) end -function M.set_anchor(instance, anchor) - instance.anchor = anchor - update_pos(instance) +function M.set_anchor(self, anchor) + self.anchor = anchor + update_pos(self) 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) +function M.add(self, item, index) + index = index or (#self.nodes + 1) + table.insert(self.nodes, index, item) + gui.set_parent(item, self.parent) - local pos = get_pos(instance, index) - check_border(instance, pos) - update_pos(instance) + local pos = get_pos(self, index) + check_border(self, pos) + update_pos(self) end -function M.get_size(instance) +function M.get_size(self) return vmath.vector3( - instance.border.z - instance.border.x, - instance.border.w - instance.border.y, + self.border.z - self.border.x, + self.border.w - self.border.y, 0) end -function M.get_all_pos(instance) +function M.get_all_pos(self) local result = {} - for i = 1, #instance.nodes do - table.insert(result, gui.get_position(instance.nodes[i])) + for i = 1, #self.nodes do + table.insert(result, gui.get_position(self.nodes[i])) end return result end -function M.clear(instance) - for i = 1, #instance.nodes do - gui.delete_node(instance.nodes[i]) +function M.clear(self) + for i = 1, #self.nodes do + gui.delete_node(self.nodes[i]) end - instance.nodes = {} + self.nodes = {} end diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 69eebe3..2df0663 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -13,135 +13,135 @@ local PROP_Y = "y" local PROP_X = "x" -function M.init(instance, name, key, init_value) +function M.init(self, name, key, init_value) if key ~= PROP_X and key ~= PROP_Y then settings.log("progress component: key must be 'x' or 'y'. Passed:", key) key = PROP_X end - instance.prop = hash("scale."..key) - instance.key = key + self.prop = hash("scale."..key) + self.key = key - instance.node = helper.get_node(name) - instance.scale = gui.get_scale(instance.node) - instance.size = gui.get_size(instance.node) - instance.max_size = instance.size[instance.key] - instance.slice = gui.get_slice9(instance.node) + self.node = helper.get_node(name) + self.scale = gui.get_scale(self.node) + self.size = gui.get_size(self.node) + self.max_size = self.size[self.key] + self.slice = gui.get_slice9(self.node) if key == PROP_X then - instance.slice_size = instance.slice.x + instance.slice.z + self.slice_size = self.slice.x + self.slice.z else - instance.slice_size = instance.slice.y + instance.slice.w + self.slice_size = self.slice.y + self.slice.w end - instance:set_to(init_value or 1) + self:set_to(init_value or 1) end -local function check_steps(instance, from, to, exactly) - if not instance.steps then +local function check_steps(self, from, to, exactly) + if not self.steps then return end - for i = 1, #instance.steps do - local step = instance.steps[i] + for i = 1, #self.steps do + local step = self.steps[i] local v1, v2 = from, to if v1 > v2 then v1, v2 = v2, v1 end if v1 < step and step < v2 then - instance.step_callback(instance.parent.parent, step) + self.step_callback(self.parent.parent, step) end if exactly and exactly == step then - instance.step_callback(instance.parent.parent, step) + self.step_callback(self.parent.parent, step) end end end -local function set_bar_to(instance, set_to, is_silence) - local prev_value = instance.last_value - instance.last_value = set_to +local function set_bar_to(self, set_to, is_silence) + local prev_value = self.last_value + self.last_value = set_to - local total_width = set_to * instance.max_size + local total_width = set_to * self.max_size - local scale = math.min(total_width / instance.slice_size, 1) - local size = math.max(total_width, instance.slice_size) + local scale = math.min(total_width / self.slice_size, 1) + local size = math.max(total_width, self.slice_size) - instance.scale[instance.key] = scale - gui.set_scale(instance.node, instance.scale) - instance.size[instance.key] = size - gui.set_size(instance.node, instance.size) + self.scale[self.key] = scale + gui.set_scale(self.node, self.scale) + self.size[self.key] = size + gui.set_size(self.node, self.size) if not is_silence then - check_steps(instance, prev_value, set_to) + check_steps(self, prev_value, set_to) end end --- Fill a progress bar and stop progress animation -function M.fill(instance) - set_bar_to(instance, 1, true) +function M.fill(self) + set_bar_to(self, 1, true) end --- To empty a progress bar -function M.empty(instance) - set_bar_to(instance, 0, true) +function M.empty(self) + set_bar_to(self, 0, true) end --- Set fill a progress bar to value -- @param to - value between 0..1 -function M.set_to(instance, to) - set_bar_to(instance, to) +function M.set_to(self, to) + set_bar_to(self, to) end -function M.get(instance) - return instance.last_value +function M.get(self) + return self.last_value end -function M.set_steps(instance, steps, step_callback) - instance.steps = steps - instance.step_callback = step_callback +function M.set_steps(self, steps, step_callback) + self.steps = steps + self.step_callback = step_callback end --- Start animation of a progress bar -- @param to - value between 0..1 -- @param callback - callback when progress ended if need -function M.to(instance, to, callback) +function M.to(self, to, callback) to = helper.clamp(to, 0, 1) -- cause of float error local value = helper.round(to, 5) - if value ~= instance.last_value then - instance.target = value - instance.target_callback = callback + if value ~= self.last_value then + self.target = value + self.target_callback = callback else if callback then - callback(instance.parent.parent, to) + callback(self.parent.parent, to) end end end -function M.update(instance, dt) - if instance.target then - local prev_value = instance.last_value - local step = math.abs(instance.last_value - instance.target) * (p_settings.SPEED*dt) +function M.update(self, dt) + if self.target then + local prev_value = self.last_value + local step = math.abs(self.last_value - self.target) * (p_settings.SPEED*dt) step = math.max(step, p_settings.MIN_DELTA) - instance:set_to(helper.step(instance.last_value, instance.target, step)) + self:set_to(helper.step(self.last_value, self.target, step)) - if instance.last_value == instance.target then - check_steps(instance, prev_value, instance.target, instance.target) + if self.last_value == self.target then + check_steps(self, prev_value, self.target, self.target) - if instance.target_callback then - instance.target_callback(instance.parent.parent, instance.target) + if self.target_callback then + self.target_callback(self.parent.parent, self.target) end - instance.target = nil + self.target = nil end end end diff --git a/druid/base/text.lua b/druid/base/text.lua index 3f3993f..6ff27fb 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -8,76 +8,76 @@ M.interest = { } -function M.init(instance, node, value, is_locale, max_width) - instance.max_width = max_width - instance.node = helper.get_node(node) - instance.start_scale = gui.get_scale(instance.node) - instance.last_color = gui.get_color(instance.node) +function M.init(self, node, value, is_locale, max_width) + self.max_width = max_width + self.node = helper.get_node(node) + self.start_scale = gui.get_scale(self.node) + self.last_color = gui.get_color(self.node) if is_locale then - instance.text_id = value - instance:translate() + self.text_id = value + self:translate() else - instance:set_to(value or 0) + self:set_to(value or 0) end - return instance + return self end -function M.translate(instance) - if instance.text_id then - instance:set_to(settings.get_text(instance.text_id)) +function M.translate(self) + if self.text_id then + self:set_to(settings.get_text(self.text_id)) end end --- Setup scale x, but can only be smaller, than start text scale -local function setup_max_width(instance) - local metrics = gui.get_text_metrics_from_node(instance.node) - local cur_scale = gui.get_scale(instance.node) +local function setup_max_width(self) + local metrics = gui.get_text_metrics_from_node(self.node) + local cur_scale = gui.get_scale(self.node) - if metrics.width * cur_scale.x > instance.max_width then - local scale_modifier = instance.max_width / metrics.width - scale_modifier = math.min(scale_modifier, instance.start_scale.x) + if metrics.width * cur_scale.x > self.max_width then + local scale_modifier = self.max_width / metrics.width + scale_modifier = math.min(scale_modifier, self.start_scale.x) local new_scale = vmath.vector3(scale_modifier, scale_modifier, cur_scale.z) - gui.set_scale(instance.node, new_scale) + gui.set_scale(self.node, new_scale) end end --- Set text to text field -- @param set_to - set value to text field -function M.set_to(instance, set_to) - instance.last_value = set_to - gui.set_text(instance.node, set_to) +function M.set_to(self, set_to) + self.last_value = set_to + gui.set_text(self.node, set_to) - if instance.max_width then - setup_max_width(instance) + if self.max_width then + setup_max_width(self) end end --- Set color -- @param color -function M.set_color(instance, color) - instance.last_color = color - gui.set_color(instance.node, color) +function M.set_color(self, color) + self.last_color = color + gui.set_color(self.node, color) end --- Set alpha -- @param alpha, number [0-1] -function M.set_alpha(instance, alpha) - instance.last_color.w = alpha - gui.set_color(instance.node, instance.last_color) +function M.set_alpha(self, alpha) + self.last_color.w = alpha + gui.set_color(self.node, self.last_color) end --- Set scale -- @param scale -function M.set_scale(instance, scale) - instance.last_scale = scale - gui.set_scale(instance.node, scale) +function M.set_scale(self, scale) + self.last_scale = scale + gui.set_scale(self.node, scale) end diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 14cb8c6..73fb49e 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -9,66 +9,66 @@ M.interest = { local empty = function() end -function M.init(instance, node, seconds_from, seconds_to, callback) - instance.node = helper.get_node(node) +function M.init(self, node, seconds_from, seconds_to, callback) + self.node = helper.get_node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) callback = callback or empty - instance:set_to(seconds_from) - instance:set_interval(seconds_from, seconds_to) - instance.callback = callback + self:set_to(seconds_from) + self:set_interval(seconds_from, seconds_to) + self.callback = callback if seconds_to - seconds_from == 0 then - instance:set_state(false) - instance.callback(instance.parent.parent, instance) + self:set_state(false) + self.callback(self.parent.parent, self) end - return instance + return self end --- Set text to text field -- @param set_to - set value in seconds -function M.set_to(instance, set_to) - instance.last_value = set_to - gui.set_text(instance.node, formats.second_string_min(set_to)) +function M.set_to(self, set_to) + self.last_value = set_to + gui.set_text(self.node, formats.second_string_min(set_to)) end --- Called when update -- @param is_on - boolean is timer on -function M.set_state(instance, is_on) - instance.is_on = is_on +function M.set_state(self, is_on) + self.is_on = is_on end --- Set time interval -- @param from - "from" time in seconds -- @param to - "to" time in seconds -function M.set_interval(instance, from, to) - instance.from = from - instance.value = from - instance.temp = 0 - instance.target = to - M.set_state(instance, true) - M.set_to(instance, from) +function M.set_interval(self, from, to) + self.from = from + self.value = from + self.temp = 0 + self.target = to + M.set_state(self, true) + M.set_to(self, from) end --- Called when update -- @param dt - delta time -function M.update(instance, dt) - if instance.is_on then - instance.temp = instance.temp + dt - local dist = math.min(1, math.abs(instance.value - instance.target)) +function M.update(self, dt) + if self.is_on then + self.temp = self.temp + dt + local dist = math.min(1, math.abs(self.value - self.target)) - if instance.temp > dist then - instance.temp = instance.temp - dist - instance.value = helper.step(instance.value, instance.target, 1) - M.set_to(instance, instance.value) - if instance.value == instance.target then - instance:set_state(false) - instance.callback(instance.parent.parent, instance) + if self.temp > dist then + self.temp = self.temp - dist + self.value = helper.step(self.value, self.target, 1) + M.set_to(self, self.value) + if self.value == self.target then + self:set_state(false) + self.callback(self.parent.parent, self) end end end diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index e8ff623..1acb004 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -94,6 +94,7 @@ local function init_grid(self) -- 4 items per row local grid = self.druid:new_grid("grid_1", prefab, 4) + grid:set_anchor(vmath.vector3(0)) grid:set_offset(vmath.vector3(2, 2, 0)) for i = 1, 16 do local node = gui.clone(prefab) @@ -120,6 +121,7 @@ local function init_grid(self) local grid3 = self.druid:new_grid("grid_3", prefab, 10) + grid3:set_anchor(vmath.vector3(0)) grid3:set_offset(vmath.vector3(5, 0, 0)) for i = 1, 4 do local node = gui.clone(prefab) From 205253c98d46cd6b47844379db0c6f7de4619669 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 7 Apr 2019 16:40:27 +0300 Subject: [PATCH 037/136] add factory.remove method --- druid/druid.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/druid/druid.lua b/druid/druid.lua index 23f63eb..872b632 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -81,6 +81,25 @@ local function create(module, factory) end +function _factory.remove(factory, instance) + for i = #factory, 1, -1 do + if factory[i] == instance then + table.remove(factory, i) + end + end + local interest = instance.interest + if interest then + for i, v in ipairs(interest) do + for j = #factory[v], 1, -1 do + if factory[v][j] == instance then + table.remove(factory[v], j) + end + end + end + end +end + + function _factory.new(factory, module, ...) local instance = create(module, factory) From 80e2392d249f888ea612dac53986a4d266e2cdaf Mon Sep 17 00:00:00 2001 From: Insality Date: Tue, 23 Apr 2019 23:40:06 +0300 Subject: [PATCH 038/136] fix: Now you can scroll only one scroll by one (without input race). Removed local scroll param. case: Double scroll at one place, start scrolling on one direction, you can scroll another scroll on top of first scroll --- druid/base/scroll.lua | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index fd56fe2..3fe6571 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -12,6 +12,9 @@ M.interest = { data.ON_SWIPE, } +-- Global on all scrolls +M.current_scroll = nil + function M.init(self, scroll_parent, input_zone, border) self.node = helper.get_node(scroll_parent) @@ -33,7 +36,6 @@ function M.init(self, scroll_parent, input_zone, border) self.input = { touch = false, - scroll = false, start_x = 0, start_y = 0, side = false, @@ -198,7 +200,7 @@ end function M.update(self, dt) if self.input.touch then - if self.input.scroll then + if M.current_scroll == self then update_hand_scroll(self, dt) end else @@ -274,7 +276,7 @@ function M.on_input(self, action_id, action) self.target.y = self.pos.y else local dist = helper.distance(action.x, action.y, inp.start_x, inp.start_y) - if not inp.scroll and dist >= settings.DEADZONE then + if not M.current_scroll and dist >= settings.DEADZONE then local dx = math.abs(inp.start_x - action.x) local dy = math.abs(inp.start_y - action.y) if dx > dy then @@ -283,12 +285,12 @@ function M.on_input(self, action_id, action) inp.side = SIDE_Y end -- Check scroll side if we can scroll - if self.can_x and inp.side == SIDE_X or - self.can_y and inp.side == SIDE_Y then - inp.scroll = true + if (self.can_x and inp.side == SIDE_X or + self.can_y and inp.side == SIDE_Y) then + M.current_scroll = self end end - if inp.scroll then + if M.current_scroll == self then add_delta(self, action.dx, action.dy) result = true end @@ -296,9 +298,9 @@ function M.on_input(self, action_id, action) end if action.released then - if inp.scroll then + if M.current_scroll == self then inp.touch = false - inp.scroll = false + M.current_scroll = nil inp.side = false result = true end From 33c36f4967e959e70d9c96b6f58217fe24045d04 Mon Sep 17 00:00:00 2001 From: Insality Date: Tue, 23 Apr 2019 23:58:04 +0300 Subject: [PATCH 039/136] fix: don't cancel gui.animate on touch pressed. It leads to some problems. Inert scroll still can be stopped by touch --- druid/base/scroll.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 3fe6571..f8387e4 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -266,7 +266,6 @@ function M.on_input(self, action_id, action) if gui.pick_node(self.input_zone, action.x, action.y) then if action.pressed then - cancel_animate(self) inp.touch = true inp.start_x = action.x inp.start_y = action.y @@ -299,8 +298,8 @@ function M.on_input(self, action_id, action) if action.released then if M.current_scroll == self then - inp.touch = false M.current_scroll = nil + inp.touch = false inp.side = false result = true end From fdbacd033d262630dc43143489f49e9775a4af0e Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 24 Apr 2019 23:16:44 +0300 Subject: [PATCH 040/136] feature: event can be now list of events --- druid/druid.lua | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/druid/druid.lua b/druid/druid.lua index 872b632..c6ada27 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -145,6 +145,19 @@ local function notify_input_on_swipe(factory) end +local function match_event(action_id, events) + if type(events) == "table" then + for i = 1, #events do + if action_id == events[i] then + return true + end + end + else + return action_id == events + end +end + + --- Called ON_INPUT function _factory.on_input(factory, action_id, action) if factory[data.ON_SWIPE] then @@ -164,7 +177,7 @@ function _factory.on_input(factory, action_id, action) local len = #factory[data.ON_INPUT] for i = len, 1, -1 do v = factory[data.ON_INPUT][i] - if action_id == v.event and v:on_input(action_id, action) then + if match_event(action_id, v.event) and v:on_input(action_id, action) then return true end end From 4ce8e85d157e2b6d71fd7dd5f29957df333c71c4 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Sun, 4 Aug 2019 22:15:22 +0200 Subject: [PATCH 041/136] Refactoring: step 1 druid.lua: - `factory` replaced with `self` - set new name for metatable - replaced `ipairs` with `for `i loop data.lua: - renamed custom messages --- druid/base/text.lua | 2 +- druid/data.lua | 33 ++++++++--- druid/druid.lua | 130 ++++++++++++++++++++++++-------------------- 3 files changed, 97 insertions(+), 68 deletions(-) diff --git a/druid/base/text.lua b/druid/base/text.lua index 6ff27fb..63708b8 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -4,7 +4,7 @@ local helper = require("druid.helper") local M = {} M.interest = { - data.TRANSLATABLE, + data.ON_CHANGE_LANGUAGE, } diff --git a/druid/data.lua b/druid/data.lua index 5fa1129..e785252 100644 --- a/druid/data.lua +++ b/druid/data.lua @@ -1,20 +1,37 @@ local M = {} +-- actions + M.A_TOUCH = hash("touch") M.A_TEXT = hash("text") M.A_BACKSPACE = hash("backspace") M.A_ENTER = hash("enter") M.A_ANDR_BACK = hash("back") --- interest -M.LAYOUT_CHANGED = hash("layout_changed") -M.ON_MESSAGE = hash("on_message") -M.ON_INPUT = hash("on_input") -M.ON_SWIPE = hash("on_swipe") -M.ON_UPDATE = hash("on_update") -M.TRANSLATABLE = hash("TRANSLATABLE") - M.RELEASED = "released" M.PRESSED = "pressed" +--- interests + +M.ON_MESSAGE = hash("on_message") +M.ON_UPDATE = hash("on_update") + + -- input +M.ON_SWIPE = hash("on_swipe") +M.ON_INPUT = hash("on_input") + +M.ui_input = { + [M.ON_SWIPE] = true, + [M.ON_INPUT] = true + +} + -- ui messages +M.ON_CHANGE_LANGUAGE = hash("on_change_language") +M.ON_LAYOUT_CHANGED = hash("on_layout_changed") + +M.specific_ui_messages = { + [M.ON_CHANGE_LANGUAGE] = "on_change_language", + [M.ON_LAYOUT_CHANGED] = "on_layout_changed" +} + return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index c6ada27..ad3618c 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -5,7 +5,7 @@ local settings = require("druid.settings") local M = {} local log = settings.log -local _factory = {} +local _fct_metatable = {} M.comps = { button = require("druid.base.button"), @@ -22,7 +22,7 @@ M.comps = { local function register_basic_components() for k, v in pairs(M.comps) do - if not _factory["new_" .. k] then + if not _fct_metatable["new_" .. k] then M.register(k, v) else log("Basic component", k, "already registered") @@ -33,8 +33,8 @@ end function M.register(name, module) -- TODO: Find better solution to creating elements? - _factory["new_" .. name] = function(factory, ...) - return _factory.new(factory, module, ...) + _fct_metatable["new_" .. name] = function(self, ...) + return _fct_metatable.new(self, module, ...) end log("Register component", name) end @@ -42,57 +42,64 @@ end --- Create UI instance for ui elements -- @return instance with all ui components -function M.new(self) +function M.new(component_script) if register_basic_components then register_basic_components() register_basic_components = false end - local factory = setmetatable({}, {__index = _factory}) - factory.parent = self - return factory + local self = setmetatable({}, {__index = _fct_metatable}) + self.parent = component_script + return self end -local function input_init(factory) - if not factory.input_inited then - factory.input_inited = true +local function input_init(self) + if not self.input_inited then + self.input_inited = true druid_input.focus() end end -local function create(module, factory) +local function create(self, module) local instance = setmetatable({}, {__index = module}) - instance.parent = factory - factory[#factory + 1] = instance + instance.parent = self + self[#self + 1] = instance - local register_to = module.interest or {} - for i, v in ipairs(register_to) do - if not factory[v] then - factory[v] = {} - end - factory[v][#factory[v] + 1] = instance + local register_to = module.interest + if register_to then + local v + for i = 1, #register_to do + v = register_to[i] + if not self[v] then + self[v] = {} + end + self[v][#self[v] + 1] = instance - if v == data.ON_INPUT or v == data.ON_SWIPE then - input_init(factory) + if data.ui_input[v] then + input_init(self) + end end end return instance end -function _factory.remove(factory, instance) - for i = #factory, 1, -1 do - if factory[i] == instance then - table.remove(factory, i) +function _fct_metatable.remove(self, instance) + for i = #self, 1, -1 do + if self[i] == instance then + table.remove(self, i) end end local interest = instance.interest if interest then - for i, v in ipairs(interest) do - for j = #factory[v], 1, -1 do - if factory[v][j] == instance then - table.remove(factory[v], j) + local v + for i = 1, #interest do + v = interest[i] + local array = self[v] + for j = #array, 1, -1 do + if array[j] == instance then + table.remove(array, j) end end end @@ -100,8 +107,8 @@ function _factory.remove(factory, instance) end -function _factory.new(factory, module, ...) - local instance = create(module, factory) +function _fct_metatable.new(self, module, ...) + local instance = create(self, module) if instance.init then instance:init(...) @@ -112,31 +119,33 @@ end --- Called on_message -function _factory.on_message(factory, message_id, message, sender) - if message_id == data.LAYOUT_CHANGED then - if factory[data.LAYOUT_CHANGED] then - M.translate(factory) - for i, v in ipairs(factory[data.LAYOUT_CHANGED]) do - v:on_layout_updated(message) +function _fct_metatable.on_message(self, message_id, message, sender) + local specific_ui_message = data.specific_ui_messages[message_id] + if specific_ui_message then + local array = self[message_id] + if array then + local item + for i = 1, #array do + item = array[i] + item[specific_ui_message](item, message, sender) end end - elseif message_id == data.TRANSLATABLE then - M.translate(factory) else - if factory[data.ON_MESSAGE] then - for i, v in ipairs(factory[data.ON_MESSAGE]) do - v:on_message(message_id, message, sender) + local array = self[data.ON_MESSAGE] + if array then + for i = 1, #array do + array[i]:on_message(message_id, message, sender) end end end end -local function notify_input_on_swipe(factory) - if factory[data.ON_INPUT] then - local len = #factory[data.ON_INPUT] +local function notify_input_on_swipe(self) + if self[data.ON_INPUT] then + local len = #self[data.ON_INPUT] for i = len, 1, -1 do - local comp = factory[data.ON_INPUT][i] + local comp = self[data.ON_INPUT][i] if comp.on_swipe then comp:on_swipe() end @@ -159,24 +168,26 @@ end --- Called ON_INPUT -function _factory.on_input(factory, action_id, action) - if factory[data.ON_SWIPE] then +function _fct_metatable.on_input(self, action_id, action) + local array = self[data.ON_SWIPE] + if array then local v, result - local len = #factory[data.ON_SWIPE] + local len = #array for i = len, 1, -1 do - v = factory[data.ON_SWIPE][i] + v = array[i] result = result or v:on_input(action_id, action) end if result then - notify_input_on_swipe(factory) + notify_input_on_swipe(self) return true end end - if factory[data.ON_INPUT] then + array = self[data.ON_INPUT] + if array then local v - local len = #factory[data.ON_INPUT] + local len = #array for i = len, 1, -1 do - v = factory[data.ON_INPUT][i] + v = array[i] if match_event(action_id, v.event) and v:on_input(action_id, action) then return true end @@ -188,10 +199,11 @@ end --- Called on_update -function _factory.update(factory, dt) - if factory[data.ON_UPDATE] then - for i, v in ipairs(factory[data.ON_UPDATE]) do - v:update(dt) +function _fct_metatable.update(self, dt) + local array = self[data.ON_UPDATE] + if array then + for i = 1, #array do + array[i]:update(dt) end end end From 099eaa1e1024ee5db1a47f9b960d40dc97313a2a Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 20:12:52 +0300 Subject: [PATCH 042/136] update scroll and helper --- druid/base/scroll.lua | 40 ++++++++++++---------- druid/data.lua | 12 +++---- druid/helper.lua | 78 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 91 insertions(+), 39 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index f8387e4..2c651a9 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -99,10 +99,7 @@ end local function get_zone_center(self) - local pos = vmath.vector3(self.pos) - pos.x = pos.x + self.center_offset.x - pos.y = pos.y + self.center_offset.y - return pos + return self.pos + self.center_offset end @@ -257,7 +254,7 @@ end function M.on_input(self, action_id, action) - if action_id ~= data.A_TOUCH then + if action_id ~= data.ACTION_TOUCH then return false end local inp = self.input @@ -289,18 +286,21 @@ function M.on_input(self, action_id, action) M.current_scroll = self end end - if M.current_scroll == self then - add_delta(self, action.dx, action.dy) - result = true - end + end + end + + if inp.touch and not action.pressed then + if M.current_scroll == self then + add_delta(self, action.dx, action.dy) + result = true end end if action.released then + inp.touch = false + inp.side = false if M.current_scroll == self then M.current_scroll = nil - inp.touch = false - inp.side = false result = true end check_threshold(self) @@ -311,7 +311,7 @@ end --- Start scroll to point (x, y, z) -function M.scroll_to(self, point) +function M.scroll_to(self, point, is_instant) local b = self.border local target = vmath.vector3(point) target.x = helper.clamp(point.x - self.center_offset.x, b.x, b.z) @@ -319,12 +319,18 @@ function M.scroll_to(self, point) cancel_animate(self) - self.animate = true - gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function() - self.animate = false + self.animate = not is_instant + + if is_instant then self.target = target set_pos(self, target) - end) + else + gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function() + self.animate = false + self.target = target + set_pos(self, target) + end) + end end @@ -384,4 +390,4 @@ function M.set_border(self, border) end -return M \ No newline at end of file +return M diff --git a/druid/data.lua b/druid/data.lua index e785252..b169895 100644 --- a/druid/data.lua +++ b/druid/data.lua @@ -1,7 +1,6 @@ local M = {} --- actions - +-- Actions M.A_TOUCH = hash("touch") M.A_TEXT = hash("text") M.A_BACKSPACE = hash("backspace") @@ -11,21 +10,20 @@ M.A_ANDR_BACK = hash("back") M.RELEASED = "released" M.PRESSED = "pressed" ---- interests - +--- Interests M.ON_MESSAGE = hash("on_message") M.ON_UPDATE = hash("on_update") - -- input +-- Input M.ON_SWIPE = hash("on_swipe") M.ON_INPUT = hash("on_input") M.ui_input = { [M.ON_SWIPE] = true, [M.ON_INPUT] = true - } - -- ui messages + +-- UI messages M.ON_CHANGE_LANGUAGE = hash("on_change_language") M.ON_LAYOUT_CHANGED = hash("on_layout_changed") diff --git a/druid/helper.lua b/druid/helper.lua index 05d6695..7e36f75 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,23 +1,70 @@ local M = {} -function M.centrate_text_with_icon(text_node, icon_node, offset_x) - offset_x = offset_x or 0 - local metr = gui.get_text_metrics_from_node(text_node) - local scl = gui.get_scale(text_node).x - local pos = gui.get_position(text_node) - local scl_i = gui.get_scale(icon_node).x - local pos_i = gui.get_position(icon_node) - local w = metr.width * scl -- text width - local icon_w = gui.get_size(icon_node).x * scl_i -- icon width - local width = w + icon_w +--- 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 - pos.x = -width/2 + w + offset_x - gui.set_position(text_node, pos) - pos_i.x = width/2 - icon_w + offset_x - gui.set_position(icon_node, pos_i) + 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 + + +--- Text node or icon node can be nil +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 + + +--- Icon node or text node can be nil +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 + + + local STRING = "string" function M.get_node(node_or_name) if type(node_or_name) == STRING then @@ -96,4 +143,5 @@ function M.get_pivot_offset(pivot) return pivots[pivot] end -return M \ No newline at end of file + +return M From a4bc3bb5a154c30080d8ca4f92444cab6a55162b Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 20:13:05 +0300 Subject: [PATCH 043/136] rename android_back to back_handler --- druid/base/{android_back.lua => back_handler.lua} | 0 druid/druid.lua | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename druid/base/{android_back.lua => back_handler.lua} (100%) diff --git a/druid/base/android_back.lua b/druid/base/back_handler.lua similarity index 100% rename from druid/base/android_back.lua rename to druid/base/back_handler.lua diff --git a/druid/druid.lua b/druid/druid.lua index ad3618c..22b274a 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -9,7 +9,7 @@ local _fct_metatable = {} M.comps = { button = require("druid.base.button"), - android_back = require("druid.base.android_back"), + back_handler = require("druid.base.back_handler"), text = require("druid.base.text"), timer = require("druid.base.timer"), progress = require("druid.base.progress"), From 4d424a34c22055ca864f90d8d64a2a6c1d72499d Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 20:13:12 +0300 Subject: [PATCH 044/136] add config for LDoc --- config.ld | 8 ++ docs/index.html | 49 ++++++++ docs/ldoc_pale.css | 303 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100644 config.ld create mode 100644 docs/index.html create mode 100644 docs/ldoc_pale.css diff --git a/config.ld b/config.ld new file mode 100644 index 0000000..92f8231 --- /dev/null +++ b/config.ld @@ -0,0 +1,8 @@ +project='Druid' +title='Defold Druid UI Library' +description='Documentation for Druid Library' +format='lunamark' +file={"./druid"} +dir='./docs' +style='!pale' +no_space_before_args=true \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..a695fc9 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,49 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ + +

Documentation for Druid Library

+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-09-25 19:57:43 +
+
+ + diff --git a/docs/ldoc_pale.css b/docs/ldoc_pale.css new file mode 100644 index 0000000..4202bd3 --- /dev/null +++ b/docs/ldoc_pale.css @@ -0,0 +1,303 @@ +/* BEGIN RESET + +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 +*/ +html { + color: #000; + background: #FFF; +} +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { + margin: 0; + padding: 0; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +fieldset,img { + border: 0; +} +address,caption,cite,code,dfn,em,strong,th,var,optgroup { + font-style: inherit; + font-weight: inherit; +} +del,ins { + text-decoration: none; +} +li { + margin-left: 20px; +} +caption,th { + text-align: left; +} +h1,h2,h3,h4,h5,h6 { + font-size: 100%; + font-weight: bold; +} +q:before,q:after { + content: ''; +} +abbr,acronym { + border: 0; + font-variant: normal; +} +sup { + vertical-align: baseline; +} +sub { + vertical-align: baseline; +} +legend { + color: #000; +} +input,button,textarea,select,optgroup,option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; +} +input,button,textarea,select {*font-size:100%; +} +/* END RESET */ + +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color: #ffffff; margin: 0px; +} + +code, tt { font-family: monospace; font-size: 1.1em; } +span.parameter { font-family:monospace; } +span.parameter:after { content:":"; } +span.types:before { content:"("; } +span.types:after { content:")"; } +.type { font-weight: bold; font-style:italic } + +body, p, td, th { font-size: .95em; line-height: 1.2em;} + +p, ul { margin: 10px 0 0 0px;} + +strong { font-weight: bold;} + +em { font-style: italic;} + +h1 { + font-size: 1.5em; + margin: 0 0 20px 0; +} +h2, h3, h4 { margin: 15px 0 10px 0; } +h2 { font-size: 1.25em; } +h3 { font-size: 1.15em; } +h4 { font-size: 1.06em; } + +a:link { font-weight: bold; color: #004080; text-decoration: none; } +a:visited { font-weight: bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration: underline; } + +hr { + color:#cccccc; + background: #00007f; + height: 1px; +} + +blockquote { margin-left: 3em; } + +ul { list-style-type: disc; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; +} + +pre { + background-color: rgb(245, 245, 245); + border: 1px solid #C0C0C0; /* silver */ + padding: 10px; + margin: 10px 0 10px 0; + overflow: auto; + font-family: "Andale Mono", monospace; +} + +pre.example { + font-size: .85em; +} + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } + +#container { + margin-left: 1em; + margin-right: 1em; + background-color: #ffffff; +} + +#product { + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#main { + background-color:#FFFFFF; // #f0f0f0; + //border-left: 2px solid #cccccc; +} + +#navigation { + float: left; + width: 14em; + vertical-align: top; + background-color:#FFFFFF; // #f0f0f0; + border-right: 2px solid #cccccc; + overflow: visible; +} + +#navigation h2 { + background-color:#FFFFFF;//:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align: left; + padding:0.2em; + //border-top:1px solid #dddddd; + border-bottom:1px solid #dddddd; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + margin: 1px 1px 10px 1px; +} + +#navigation li { + text-indent: -1em; + display: block; + margin: 3px 0px 0px 22px; +} + +#navigation li li a { + margin: 0px 3px 0px -1em; +} + +#content { + margin-left: 14em; + padding: 1em; + width: 700px; + border-left: 2px solid #cccccc; + // border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about { + clear: both; + padding: 5px; + border-top: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight: bold; color: #004080; text-decoration: underline; } + + #main { + background-color: #ffffff; + border-left: 0px; + } + + #container { + margin-left: 2%; + margin-right: 2%; + background-color: #ffffff; + } + + #content { + padding: 1em; + background-color: #ffffff; + } + + #navigation { + display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.module_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; ; min-width: 200px; } +table.module_list td.summary { width: 100%; } + +table.function_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f6f6ff; ; min-width: 200px; } +table.function_list td.summary { width: 100%; } + +dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} +dl.table h3, dl.function h3 {font-size: .95em;} + +ul.nowrap { + overflow:auto; + whitespace:nowrap; +} + +/* stop sublists from having initial vertical space */ +ul ul { margin-top: 0px; } +ol ul { margin-top: 0px; } +ol ol { margin-top: 0px; } +ul ol { margin-top: 0px; } + +/* make the target distinct; helps when we're navigating to a function */ +a:target + * { + background-color: #FF9; +} + + +/* styles for prettification of source */ +pre .comment { color: #558817; } +pre .constant { color: #a8660d; } +pre .escape { color: #844631; } +pre .keyword { color: #aa5050; font-weight: bold; } +pre .library { color: #0e7c6b; } +pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } +pre .string { color: #8080ff; } +pre .number { color: #f8660d; } +pre .operator { color: #2239a8; font-weight: bold; } +pre .preprocessor, pre .prepro { color: #a33243; } +pre .global { color: #800080; } +pre .user-keyword { color: #800080; } +pre .prompt { color: #558817; } +pre .url { color: #272fc2; text-decoration: underline; } + From b72e7451e1814b0b278717d4ed1180cc6733b07e Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 20:40:41 +0300 Subject: [PATCH 045/136] Add example docs for LDoc --- druid/base/back_handler.lua | 17 ++++++++++++----- druid/base/button.lua | 7 +++++-- druid/base/grid.lua | 10 +++++----- druid/base/progress.lua | 5 ++++- druid/base/scroll.lua | 9 ++++++++- druid/base/text.lua | 6 +++++- druid/base/timer.lua | 4 ++++ druid/data.lua | 13 ++++++++----- druid/druid.lua | 12 +++++++++++- druid/helper.lua | 3 +++ druid/helper/druid_animate.lua | 3 +++ druid/helper/druid_input.lua | 4 ++++ druid/helper/formats.lua | 21 ++++++++++++--------- druid/settings.lua | 13 ++++++++----- 14 files changed, 92 insertions(+), 35 deletions(-) diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 775b01e..9afa864 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -1,3 +1,6 @@ +--- Component to handle back key +-- @module base.back_handler + local data = require("druid.data") local M = {} @@ -5,21 +8,25 @@ M.interest = { data.ON_INPUT } - +--- Component init function +-- @tparam table self component instance +-- @tparam callback callback on back button +-- @tparam[opt] params callback argument function M.init(self, callback, params) - self.event = data.A_ANDR_BACK + self.event = data.ACTION_BACK self.callback = callback self.params = params end ---- input handler --- @param action_id - input action id --- @param action - input action +--- Input handler for component +-- @tparam string action_id on_input action id +-- @tparam table action on_input action function M.on_input(self, action_id, action) if action[data.RELEASED] then self.callback(self.parent.parent, self.params) end + return true end diff --git a/druid/base/button.lua b/druid/base/button.lua index f5bfab2..8015fb3 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,3 +1,6 @@ +--- Component to handle basic GUI button +-- @module base.button + local data = require("druid.data") local ui_animate = require("druid.helper.druid_animate") local settings = require("druid.settings") @@ -17,7 +20,7 @@ M.DEFAUL_ACTIVATION_TIME = 0.2 function M.init(self, node, callback, params, anim_node, event) self.node = helper.get_node(node) - self.event = data.A_TOUCH + self.event = data.ACTION_TOUCH self.anim_node = anim_node and helper.get_node(anim_node) or self.node self.scale_from = gui.get_scale(self.anim_node) self.scale_to = self.scale_from + b_settings.SCALE_CHANGE @@ -185,4 +188,4 @@ function M.set_ext_zone(self, zone) end -return M \ No newline at end of file +return M diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 496aea3..acdfcbd 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -1,11 +1,11 @@ +--- Component to handle placing components by row and columns. +-- Grid can anchor your elements, get content size and other +-- @module base.grid + 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(self, parent, element, in_row) self.parent = helper.get_node(parent) @@ -111,4 +111,4 @@ function M.clear(self) end -return M \ No newline at end of file +return M diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 2df0663..e0d2b88 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -1,3 +1,6 @@ +--- Component to handle progress bars +-- @module base.progress + local data = require("druid.data") local helper = require("druid.helper") local settings = require("druid.settings") @@ -147,4 +150,4 @@ function M.update(self, dt) end -return M \ No newline at end of file +return M diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 2c651a9..d561e5d 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -1,3 +1,6 @@ +--- Component to handle scroll content +-- @module base.scroll + local helper = require("druid.helper") local data = require("druid.data") local settings = require("druid.settings").scroll @@ -310,7 +313,11 @@ function M.on_input(self, action_id, action) end ---- Start scroll to point (x, y, z) +--- Start scroll to target point +-- @tparam point vector3 target point +-- @tparam[opt] bool is_instant instant scroll flag +-- @usage scroll:scroll_to(vmath.vector3(0, 50, 0)) +-- @usage scroll:scroll_to(vmath.vector3(0), true) function M.scroll_to(self, point, is_instant) local b = self.border local target = vmath.vector3(point) diff --git a/druid/base/text.lua b/druid/base/text.lua index 63708b8..297ddc4 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,3 +1,7 @@ +--- Component to handle all GUI texts +-- Good working with localization system +-- @module base.text + local data = require("druid.data") local settings = require("druid.settings") local helper = require("druid.helper") @@ -81,4 +85,4 @@ function M.set_scale(self, scale) end -return M \ No newline at end of file +return M diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 73fb49e..801cc7e 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,3 +1,6 @@ +--- Component to handle GUI timers +-- @module base.timer + local data = require("druid.data") local formats = require("druid.helper.formats") local helper = require("druid.helper") @@ -9,6 +12,7 @@ M.interest = { local empty = function() end + function M.init(self, node, seconds_from, seconds_to, callback) self.node = helper.get_node(node) seconds_from = math.max(seconds_from, 0) diff --git a/druid/data.lua b/druid/data.lua index b169895..eb870dd 100644 --- a/druid/data.lua +++ b/druid/data.lua @@ -1,11 +1,14 @@ +--- Druid constants +-- @module constants + local M = {} -- Actions -M.A_TOUCH = hash("touch") -M.A_TEXT = hash("text") -M.A_BACKSPACE = hash("backspace") -M.A_ENTER = hash("enter") -M.A_ANDR_BACK = hash("back") +M.ACTION_TOUCH = hash("touch") +M.ACTION_TEXT = hash("text") +M.ACTION_BACKSPACE = hash("backspace") +M.ACTION_ENTER = hash("enter") +M.ACTION_BACK = hash("back") M.RELEASED = "released" M.PRESSED = "pressed" diff --git a/druid/druid.lua b/druid/druid.lua index 22b274a..f24a12e 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,3 +1,9 @@ +--- Druid UI Library. +-- Component based UI library to make your life easier. +-- Contains a lot of base components and give API +-- to create your own rich components. +-- @module druid + local data = require("druid.data") local druid_input = require("druid.helper.druid_input") local settings = require("druid.settings") @@ -7,6 +13,7 @@ local M = {} local log = settings.log local _fct_metatable = {} +--- Basic components M.comps = { button = require("druid.base.button"), back_handler = require("druid.base.back_handler"), @@ -31,6 +38,9 @@ local function register_basic_components() end +--- Register external module +-- @tparam string name module name +-- @tparam table module lua table with module function M.register(name, module) -- TODO: Find better solution to creating elements? _fct_metatable["new_" .. name] = function(self, ...) @@ -209,4 +219,4 @@ function _fct_metatable.update(self, dt) end -return M \ No newline at end of file +return M diff --git a/druid/helper.lua b/druid/helper.lua index 7e36f75..d428eb5 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,3 +1,6 @@ +--- Druid helper module +-- @module helper + local M = {} --- Text node or icon node can be nil diff --git a/druid/helper/druid_animate.lua b/druid/helper/druid_animate.lua index 12828b4..fa58cc4 100644 --- a/druid/helper/druid_animate.lua +++ b/druid/helper/druid_animate.lua @@ -1,3 +1,6 @@ +--- Druid helper module for animating GUI nodes +-- @module helper.animate + local M = {} local PROP_SCALE = gui.PROP_SCALE diff --git a/druid/helper/druid_input.lua b/druid/helper/druid_input.lua index 89ca0af..6a447c8 100644 --- a/druid/helper/druid_input.lua +++ b/druid/helper/druid_input.lua @@ -1,3 +1,7 @@ +--- Druid inner module to acquire/release input +-- @module helper.input +-- @local + local M = {} local ADD_FOCUS = hash("acquire_input_focus") diff --git a/druid/helper/formats.lua b/druid/helper/formats.lua index 040c274..96aa487 100644 --- a/druid/helper/formats.lua +++ b/druid/helper/formats.lua @@ -1,10 +1,13 @@ +--- Druid module with utils on string formats +-- @module helper.formats + local M = {} local ZERO = "0" --- Return number with zero number prefix --- @param num - number for conversion --- @param count - count of numerals +--- Return number with zero number prefix +-- @param num number for conversion +-- @param count count of numerals -- @return string with need count of zero (1,3) -> 001 function M.add_prefix_zeros(num, count) local result = tostring(num) @@ -15,8 +18,8 @@ function M.add_prefix_zeros(num, count) end --- Convert seconds to string minutes:seconds --- @param num - number of seconds +--- Convert seconds to string minutes:seconds +-- @param num number of seconds -- @return string minutes:seconds function M.second_string_min(sec) local mins = math.floor(sec / 60) @@ -25,11 +28,11 @@ function M.second_string_min(sec) end --- Interpolate string with named Parameters in Table --- @param s - string for interpolate --- @param tab - table with parameters +--- Interpolate string with named Parameters in Table +-- @param s string for interpolate +-- @param tab table with parameters -- @return string with replaced parameters -function M.interpolate_strinng(s, tab) +function M.interpolate_string(s, tab) return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end)) end diff --git a/druid/settings.lua b/druid/settings.lua index bd2b31c..d0b51d5 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -1,7 +1,10 @@ +--- Druid settings file +-- @module settings + local M = {} +-- TODO: to JSON? M.is_debug = false - M.button = { IS_HOVER = true, IS_HOLD = true, @@ -33,13 +36,13 @@ M.scroll = { } function M.get_text(name) - -- override to get text for localized text - return "locales not inited" + -- override to get text for localized text + return "[Druid]: locales not inited" end function M.play_sound(name) - -- override to play sound with name + -- override to play sound with name end @@ -50,4 +53,4 @@ function M.log(...) end -return M \ No newline at end of file +return M From 711b28ede1f26f3e8e0a277b88ff901d0db05730 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 20:53:32 +0300 Subject: [PATCH 046/136] refactor button --- README.md | 6 +++ druid/base/button.lua | 107 +++++++++++++++++++++++++----------------- druid/helper.lua | 11 +++++ 3 files changed, 82 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 689d149..2a8006a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ Defold UI library # API +# LDoc + +Generate with `ldoc .` with `config.ld` file + +Insctruction here: https://github.com/stevedonovan/LDoc + # Authors # License diff --git a/druid/base/button.lua b/druid/base/button.lua index 8015fb3..58f1821 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,6 +1,10 @@ --- Component to handle basic GUI button -- @module base.button +-- TODO: Add button mode: +-- Long tap +-- Repeated tap + local data = require("druid.data") local ui_animate = require("druid.helper.druid_animate") local settings = require("druid.settings") @@ -15,7 +19,7 @@ M.interest = { M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1) M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) -M.DEFAUL_ACTIVATION_TIME = 0.2 +M.DEFAULT_ACTIVATION_TIME = 0.2 function M.init(self, node, callback, params, anim_node, event) @@ -33,14 +37,23 @@ function M.init(self, node, callback, params, anim_node, event) self.hover_anim = b_settings.IS_HOVER self.sound = b_settings.BTN_SOUND self.sound_disable = b_settings.BTN_SOUND_DISABLED - self.ext_zone = nil + self.click_zone = nil + + -- TODO: to separate component "block_input"? + -- If callback is nil, so the buttons is stub and without anim + -- Used for zones, what should dont pass the input to other UI elements + if not callback then + self.stub = true + self.hover_anim = false + self.callback = function() end + end end local function set_hover(self, state) if self.hover_anim and self._is_hovered ~= state then local target_scale = state and self.scale_hover_to or self.scale_from - ui_animate.scale(self, self.node, target_scale, b_settings.HOVER_TIME) + ui_animate.scale(self, self.anim_node, target_scale, b_settings.HOVER_TIME) self._is_hovered = state end end @@ -50,15 +63,17 @@ local function on_button_release(self) if not self.disabled then if not self.stub and self.can_action then self.can_action = false - self.tap_anim(self) - settings.play_sound(self.sound) + if self.tap_anim then + self.tap_anim(self) + end self.callback(self.parent.parent, self.params, self) + settings.play_sound(self.sound) else set_hover(self, false) end return true else - self.sound_disable() + settings.play_sound(self.sound_disable) return false end end @@ -73,30 +88,32 @@ function M.on_input(self, action_id, action) end local is_pick = gui.pick_node(self.node, action.x, action.y) - if self.ext_zone then - is_pick = is_pick and gui.pick_node(self.ext_zone, action.x, action.y) + if self.click_zone then + is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y) end - if is_pick then - if action.pressed then - -- Can interact if start touch on the button - self.can_action = true - return true - end - - if action.released then - set_hover(self, false) - return on_button_release(self) - else - set_hover(self, true) - end - return not self.disabled - else + if not is_pick then -- Can't interact, if touch outside of button self.can_action = false set_hover(self, false) return false end + + if action.pressed then + -- Can interact if start touch on the button + self.can_action = true + self.repeated_counter = 0 + return true + end + + if action.released then + set_hover(self, false) + return on_button_release(self) + else + set_hover(self, true) + end + + return not self.disabled end @@ -126,21 +143,21 @@ end function M.deactivate(self, is_animate, callback) self.disabled = true if is_animate then - local counter = 0 - local clbk = function() - counter = counter + 1 - if counter == 3 and callback then + -- callback call three times in gui.animation + local clbk = helper.after(3, function() + if callback then callback(self.parent.parent) end - end + end) + ui_animate.color(self, self.node, M.DEFAULT_DEACTIVATE_COLOR, - clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) + clbk, M.DEFAULT_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.x, - M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.y, - M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) else gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR) gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE) @@ -153,24 +170,22 @@ end function M.activate(self, is_animate, callback) if is_animate then - local counter = 0 - local clbk = function() - counter = counter + 1 - if counter == 3 then + -- callback call three times in gui.animation + local clbk = helper.after(3, function() self.disabled = false if callback then callback(self.parent.parent) end - end - end + end) + ui_animate.color(self, self.node, ui_animate.TINT_SHOW, - clbk, M.DEFAUL_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) + clbk, M.DEFAULT_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.x, - M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.y, - M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAUL_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) + M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) else gui.set_color(self.node, ui_animate.TINT_SHOW) gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE) @@ -181,10 +196,18 @@ function M.activate(self, is_animate, callback) end end + +function M.disable_animation(self) + self.hover_anim = false + self.tap_anim = nil + self.back_anim = nil +end + + --- Set additional node, what need to be clicked on button click -- Used, if need setup, what button can be clicked only in special zone -function M.set_ext_zone(self, zone) - self.ext_zone = helper.get_node(zone) +function M.set_click_zone(self, zone) + self.click_zone = helper.get_node(zone) end diff --git a/druid/helper.lua b/druid/helper.lua index d428eb5..1ef342f 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -67,6 +67,17 @@ function M.centrate_icon_with_text(icon_node, text_node, margin) end +-- call callback after count calls +function M.after(count, callback) + local closure = function() + count = count - 1 + if count <= 0 then + callback() + end + end + return closure +end + local STRING = "string" function M.get_node(node_or_name) From aaac514a3d3014aa64b3b446e5387f124a6961ea Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 20:54:50 +0300 Subject: [PATCH 047/136] rename data to const --- druid/base/back_handler.lua | 8 ++++---- druid/base/button.lua | 6 +++--- druid/base/progress.lua | 4 ++-- druid/base/scroll.lua | 8 ++++---- druid/base/text.lua | 4 ++-- druid/base/timer.lua | 4 ++-- druid/{data.lua => const.lua} | 0 druid/druid.lua | 20 ++++++++++---------- 8 files changed, 27 insertions(+), 27 deletions(-) rename druid/{data.lua => const.lua} (100%) diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 9afa864..4f82c86 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -1,11 +1,11 @@ --- Component to handle back key -- @module base.back_handler -local data = require("druid.data") +local const = require("druid.const") local M = {} M.interest = { - data.ON_INPUT + const.ON_INPUT } --- Component init function @@ -13,7 +13,7 @@ M.interest = { -- @tparam callback callback on back button -- @tparam[opt] params callback argument function M.init(self, callback, params) - self.event = data.ACTION_BACK + self.event = const.ACTION_BACK self.callback = callback self.params = params end @@ -23,7 +23,7 @@ end -- @tparam string action_id on_input action id -- @tparam table action on_input action function M.on_input(self, action_id, action) - if action[data.RELEASED] then + if action[const.RELEASED] then self.callback(self.parent.parent, self.params) end diff --git a/druid/base/button.lua b/druid/base/button.lua index 58f1821..2f87afd 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -5,7 +5,7 @@ -- Long tap -- Repeated tap -local data = require("druid.data") +local const = require("druid.const") local ui_animate = require("druid.helper.druid_animate") local settings = require("druid.settings") local helper = require("druid.helper") @@ -13,7 +13,7 @@ local b_settings = settings.button local M = {} M.interest = { - data.ON_INPUT + const.ON_INPUT } M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) @@ -24,7 +24,7 @@ M.DEFAULT_ACTIVATION_TIME = 0.2 function M.init(self, node, callback, params, anim_node, event) self.node = helper.get_node(node) - self.event = data.ACTION_TOUCH + self.event = const.ACTION_TOUCH self.anim_node = anim_node and helper.get_node(anim_node) or self.node self.scale_from = gui.get_scale(self.anim_node) self.scale_to = self.scale_from + b_settings.SCALE_CHANGE diff --git a/druid/base/progress.lua b/druid/base/progress.lua index e0d2b88..d8cc122 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -1,7 +1,7 @@ --- Component to handle progress bars -- @module base.progress -local data = require("druid.data") +local const = require("druid.const") local helper = require("druid.helper") local settings = require("druid.settings") local p_settings = settings.progress @@ -9,7 +9,7 @@ local p_settings = settings.progress local M = {} M.interest = { - data.ON_UPDATE, + const.ON_UPDATE, } local PROP_Y = "y" diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index d561e5d..7febced 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -2,7 +2,7 @@ -- @module base.scroll local helper = require("druid.helper") -local data = require("druid.data") +local const = require("druid.const") local settings = require("druid.settings").scroll local M = {} @@ -11,8 +11,8 @@ local SIDE_X = "x" local SIDE_Y = "y" M.interest = { - data.ON_UPDATE, - data.ON_SWIPE, + const.ON_UPDATE, + const.ON_SWIPE, } -- Global on all scrolls @@ -257,7 +257,7 @@ end function M.on_input(self, action_id, action) - if action_id ~= data.ACTION_TOUCH then + if action_id ~= const.ACTION_TOUCH then return false end local inp = self.input diff --git a/druid/base/text.lua b/druid/base/text.lua index 297ddc4..fff35e5 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -2,13 +2,13 @@ -- Good working with localization system -- @module base.text -local data = require("druid.data") +local const = require("druid.const") local settings = require("druid.settings") local helper = require("druid.helper") local M = {} M.interest = { - data.ON_CHANGE_LANGUAGE, + const.ON_CHANGE_LANGUAGE, } diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 801cc7e..2ab6cb7 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,13 +1,13 @@ --- Component to handle GUI timers -- @module base.timer -local data = require("druid.data") +local const = require("druid.const") local formats = require("druid.helper.formats") local helper = require("druid.helper") local M = {} M.interest = { - data.ON_UPDATE + const.ON_UPDATE } local empty = function() end diff --git a/druid/data.lua b/druid/const.lua similarity index 100% rename from druid/data.lua rename to druid/const.lua diff --git a/druid/druid.lua b/druid/druid.lua index f24a12e..f271681 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -4,7 +4,7 @@ -- to create your own rich components. -- @module druid -local data = require("druid.data") +local const = require("druid.const") local druid_input = require("druid.helper.druid_input") local settings = require("druid.settings") @@ -86,7 +86,7 @@ local function create(self, module) end self[v][#self[v] + 1] = instance - if data.ui_input[v] then + if const.ui_input[v] then input_init(self) end end @@ -130,7 +130,7 @@ end --- Called on_message function _fct_metatable.on_message(self, message_id, message, sender) - local specific_ui_message = data.specific_ui_messages[message_id] + local specific_ui_message = const.specific_ui_messages[message_id] if specific_ui_message then local array = self[message_id] if array then @@ -141,7 +141,7 @@ function _fct_metatable.on_message(self, message_id, message, sender) end end else - local array = self[data.ON_MESSAGE] + local array = self[const.ON_MESSAGE] if array then for i = 1, #array do array[i]:on_message(message_id, message, sender) @@ -152,10 +152,10 @@ end local function notify_input_on_swipe(self) - if self[data.ON_INPUT] then - local len = #self[data.ON_INPUT] + if self[const.ON_INPUT] then + local len = #self[const.ON_INPUT] for i = len, 1, -1 do - local comp = self[data.ON_INPUT][i] + local comp = self[const.ON_INPUT][i] if comp.on_swipe then comp:on_swipe() end @@ -179,7 +179,7 @@ end --- Called ON_INPUT function _fct_metatable.on_input(self, action_id, action) - local array = self[data.ON_SWIPE] + local array = self[const.ON_SWIPE] if array then local v, result local len = #array @@ -192,7 +192,7 @@ function _fct_metatable.on_input(self, action_id, action) return true end end - array = self[data.ON_INPUT] + array = self[const.ON_INPUT] if array then local v local len = #array @@ -210,7 +210,7 @@ end --- Called on_update function _fct_metatable.update(self, dt) - local array = self[data.ON_UPDATE] + local array = self[const.ON_UPDATE] if array then for i = 1, #array do array[i]:update(dt) From f447afb4f7c424da9e4148b4a2178a3bc4be705c Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 22:10:44 +0300 Subject: [PATCH 048/136] add kenney assets and start gui screen --- druid/base/text.lua | 32 +- example/kenney/assets/fonts/exo2.ttf | Bin 0 -> 110068 bytes example/kenney/assets/fonts/game.font | 17 + .../kenney/assets/images/back/back_blue.png | Bin 0 -> 438 bytes .../kenney/assets/images/back/back_gray.png | Bin 0 -> 585 bytes .../kenney/assets/images/back/back_green.png | Bin 0 -> 440 bytes .../kenney/assets/images/back/back_red.png | Bin 0 -> 442 bytes .../assets/images/buttons/button_blue.png | Bin 0 -> 480 bytes .../assets/images/buttons/button_green.png | Bin 0 -> 474 bytes .../assets/images/buttons/button_red.png | Bin 0 -> 480 bytes .../assets/images/buttons/button_yellow.png | Bin 0 -> 452 bytes example/kenney/assets/images/empty.png | Bin 0 -> 14525 bytes example/kenney/assets/images/kenney.atlas | 60 ++ .../assets/images/progress/progress_back.png | Bin 0 -> 439 bytes .../images/progress/progress_fill_green.png | Bin 0 -> 471 bytes .../images/progress/progress_fill_red.png | Bin 0 -> 479 bytes .../images/progress/progress_fill_yellow.png | Bin 0 -> 458 bytes .../assets/images/radio/check_back_circle.png | Bin 0 -> 817 bytes .../assets/images/radio/check_back_square.png | Bin 0 -> 535 bytes .../kenney/assets/images/radio/checkmark.png | Bin 0 -> 366 bytes example/kenney/assets/images/radio/tick.png | Bin 0 -> 293 bytes .../assets/images/slider/slider_back.png | Bin 0 -> 153 bytes .../assets/images/slider/slider_move.png | Bin 0 -> 897 bytes example/kenney/assets/sounds/click.ogg | Bin 0 -> 6952 bytes example/kenney/gui/main/main.gui | 561 ++++++++++++++++++ example/kenney/gui/main/main.gui_script | 35 ++ example/kenney/init.script | 24 + example/kenney/kenney.collection | 107 ++++ example/kenney/lang.lua | 12 + example/kenney/templates/button.gui | 135 +++++ game.project | 2 +- 31 files changed, 970 insertions(+), 15 deletions(-) create mode 100755 example/kenney/assets/fonts/exo2.ttf create mode 100644 example/kenney/assets/fonts/game.font create mode 100755 example/kenney/assets/images/back/back_blue.png create mode 100755 example/kenney/assets/images/back/back_gray.png create mode 100755 example/kenney/assets/images/back/back_green.png create mode 100755 example/kenney/assets/images/back/back_red.png create mode 100755 example/kenney/assets/images/buttons/button_blue.png create mode 100755 example/kenney/assets/images/buttons/button_green.png create mode 100755 example/kenney/assets/images/buttons/button_red.png create mode 100755 example/kenney/assets/images/buttons/button_yellow.png create mode 100755 example/kenney/assets/images/empty.png create mode 100644 example/kenney/assets/images/kenney.atlas create mode 100755 example/kenney/assets/images/progress/progress_back.png create mode 100755 example/kenney/assets/images/progress/progress_fill_green.png create mode 100755 example/kenney/assets/images/progress/progress_fill_red.png create mode 100755 example/kenney/assets/images/progress/progress_fill_yellow.png create mode 100755 example/kenney/assets/images/radio/check_back_circle.png create mode 100755 example/kenney/assets/images/radio/check_back_square.png create mode 100755 example/kenney/assets/images/radio/checkmark.png create mode 100755 example/kenney/assets/images/radio/tick.png create mode 100755 example/kenney/assets/images/slider/slider_back.png create mode 100755 example/kenney/assets/images/slider/slider_move.png create mode 100755 example/kenney/assets/sounds/click.ogg create mode 100644 example/kenney/gui/main/main.gui create mode 100644 example/kenney/gui/main/main.gui_script create mode 100644 example/kenney/init.script create mode 100644 example/kenney/kenney.collection create mode 100644 example/kenney/lang.lua create mode 100644 example/kenney/templates/button.gui diff --git a/druid/base/text.lua b/druid/base/text.lua index fff35e5..b60a141 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -16,36 +16,40 @@ function M.init(self, node, value, is_locale, max_width) self.max_width = max_width self.node = helper.get_node(node) self.start_scale = gui.get_scale(self.node) + self.scale = self.start_scale self.last_color = gui.get_color(self.node) if is_locale then - self.text_id = value - self:translate() + self:translate(value) else self:set_to(value or 0) end + return self end -function M.translate(self) - if self.text_id then - self:set_to(settings.get_text(self.text_id)) - end +function M.translate(self, locale_id) + self.last_locale = locale_id or self.last_locale + self:set_to(settings.get_text(self.last_locale)) +end + + +function M.on_change_language(self) + M.translate(self) end --- Setup scale x, but can only be smaller, than start text scale local function setup_max_width(self) - local metrics = gui.get_text_metrics_from_node(self.node) - local cur_scale = gui.get_scale(self.node) + local metrics = gui.get_text_metrics_from_node(self.node) + local cur_scale = gui.get_scale(self.node) - if metrics.width * cur_scale.x > self.max_width then - local scale_modifier = self.max_width / metrics.width - scale_modifier = math.min(scale_modifier, self.start_scale.x) - local new_scale = vmath.vector3(scale_modifier, scale_modifier, cur_scale.z) - gui.set_scale(self.node, new_scale) - end + local scale_modifier = self.max_width / metrics.width + scale_modifier = math.min(scale_modifier, self.start_scale.x) + local new_scale = vmath.vector3(scale_modifier, scale_modifier, cur_scale.z) + gui.set_scale(self.node, new_scale) + self.scale = new_scale end diff --git a/example/kenney/assets/fonts/exo2.ttf b/example/kenney/assets/fonts/exo2.ttf new file mode 100755 index 0000000000000000000000000000000000000000..49f0b491d9e3e5581aac064ce8f3134ba5302488 GIT binary patch literal 110068 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 literal 0 HcmV?d00001 diff --git a/example/kenney/assets/fonts/game.font b/example/kenney/assets/fonts/game.font new file mode 100644 index 0000000..5bc9993 --- /dev/null +++ b/example/kenney/assets/fonts/game.font @@ -0,0 +1,17 @@ +font: "/example/kenney/assets/fonts/exo2.ttf" +material: "/builtins/fonts/font-df.material" +size: 40 +antialias: 1 +alpha: 1.0 +outline_alpha: 1.0 +outline_width: 2.0 +shadow_alpha: 1.0 +shadow_blur: 0 +shadow_x: 3.0 +shadow_y: -4.0 +extra_characters: "" +output_format: TYPE_DISTANCE_FIELD +all_chars: false +cache_width: 0 +cache_height: 0 +render_mode: MODE_MULTI_LAYER diff --git a/example/kenney/assets/images/back/back_blue.png b/example/kenney/assets/images/back/back_blue.png new file mode 100755 index 0000000000000000000000000000000000000000..73dcfd099a9a353f4a10e5c72b6f004a69484ab8 GIT binary patch literal 438 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr1|*B;ILa_EFuHiUIEGZ*dOOSB>qvmWvF9pr z2d>>?j;Lt4bKu^+>LuPzVFD_lEmxHU);Rq$-JNtJ=wL<5_MeNC1x2<`GXG%vBjMT7 zpMNES&Is?%DkKVoJ{oy`STtRbufQ{K+O~zh7=PeO+XXeM;)m5uzbx(eM@X9{EJrCISPf4{j zpPn6kJNQGB^q)zoH?K#mS<_hhx4R+!l1Zs+phdSn*8$$T&c{DwUFSXb`_F%$*$=Ez z;uunK>+MzBzFP?*ZGrC- zrcF>iGig&xq*K&&v10*Ci`u8CZfKdf;>C(PM#oI1={)%nRU>%0M?}-&?9NNZ_6}d= z7$d(Gy#D&@ciQHkp`lmpZsl!X{I53i{*7Har?=ajkC&6(v`8avx%ix(ulF15!d741 zE~#AdsIg+vy4N2IEP8w|pV|35=9c-kzO(N&-W#9za=gFg;`hB<#rEB>S$HJeZJOOG zzvY+zG$l$Ld;Qg_EY^J9`E=WbH_XiX);>=9ZP4+4icW3c((K#UGPp&fmwWTgcgWj5 zd!g7n?+F&ljEqby9SsbE0t!q_E)ES0j7ka)EKm`L1`ZAZMu-RpQ~_9oEG^ zy~6J`z|i`!eBJAf?|)y^t=?FfBhQvN@oD8hqmy$UHQvoLH}g$i+NuW(rOU@dBT@=o z1NR(be)-$wv{~+dIkuaR@7~w6Kd8ekC?8yZPxA6#wjU=I{leW!R|8{Ox5PD~Bsf2< zq&%@Gl_9B8FDWNKKP9D7FS)3)pd?=}GdD3kRS%d}j7(hflJiqii&n7JzXNJy@O1Ta JS?83{1OU}w?F|3` literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/back/back_green.png b/example/kenney/assets/images/back/back_green.png new file mode 100755 index 0000000000000000000000000000000000000000..8ec8548257fd83bae5e6556e0e2962713ab54f4d GIT binary patch literal 440 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr1|*B;ILa_EFuHlVIEGZ*dOK^a-w_9q*7vhN zGH{6WE%D!wCCk=%K*4bKEZ^H#5>{nhn{wsAIluZZTug0CYz|!r{x)fnLxgMEB;%8w z@AjJBpFVq)5#7MrIT zrv5B>6+4A@&gQo+mrCb4ZoU;;&G|3-0C(O8?ylVL5>p!7wkt-Rv7a@a-JGYnobmcn zOMAaV?u=(I&R)Qxs^Q4#70@I!1v~Rce&_Y=>H4e(zAkPtOw(GoP2BPB^+xeK52o*0 zw>&L3zj+da{*HtCu7NdcRi|Vp?EU9@K)-U{?p3Q|I`p{?@YZ=={vzudInD1s|9xh^ z4^7g4CZ*oAofW`b=P{>MXQIl<=h?FZRrpG{KW=~Sv^da&?|b8c_Xk(Mk)QqU+eNWR zpKf5l>Xx`hlmzFem6RtIr7|Q{>Lumm=clAp>LnLd7L?@cW#%TPr|JQt#>m7qFF8LY VwP*!f{X3vW22WQ%mvv4FO#ru7*LYr1&e zfm^yaZtiONvVO~jr~<*Vmy;$OQ)^wak&}g+_vhxz9G@PDN=+{~+u7$5P;>P$-yClC zG_|we4VUZ+fAZSIxA?}k+=%O6c`tq6`&suCo8O01pAuduf2n8uu46Eh)vBiF+}+bh zFU~oeb$+*ow1xO>&LyvRah)yL`AO){`Udek55z_Izi(g0VzP_(V$#o#U*Fy8ef%Q! zz*ftf_x%pJGoHORdjX58h9jp}K$FlE?93ZmkKF!s)0?s2uU25_)tEKs`F!qPZv+}W zeUr}fXPP#qs*G_3&GDObe#doB%}&_+&-H+Q=B!5^$Xn+*=?Pcw)dqQ?Tp$lYK+@O?!sw(>wIq z@6_u6gI2f1HKHUqKdq!Zu_%=xsZuW~CqF+WrBW}ssIs6WUoSH^F+Eie7&%5Ju6fD% XDXB#(*y`T_H8Oa*`njxgN@xNABP+qD literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/buttons/button_blue.png b/example/kenney/assets/images/buttons/button_blue.png new file mode 100755 index 0000000000000000000000000000000000000000..5ec356abdb80c8e4f9d6982e17c2b36363e60814 GIT binary patch literal 480 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr1|*B;ILa_EFy?u>IEGZ*dV9;(i`h})*vIc2 zjFUZ+5|y*G9FN>mu4uWkD=RfoHS>&;N5NLn#R?pCOF7m#cFQ>G=&W%G5Ych5Ibd=A zNMuMy)VTwjKOB0q?B`#}ptBt{c0a4E);{{2W@z_1=~TAt+uIh>b3UB9&Msf;^53-J zc7v1c+Fkw1*4L~4JUMvo%F*5Bk8=vFjQ<4nUDnVdjV$H9o-|Sz! z+`sC_i$H$aJJsd|2cNIWGe4sHp>WgZXR806AGm4GBL5a zpQK6ey=~T-u~;&R;m-Ya+`KNHp{^%m1sIQUuHRhGAYLW5OZ;eEJ}?4wOI#yLg7ec# z$`gxH8ImgXl5+C%Q&KARl8Y(}O7itGa}(23^?*@mWa65aoS%|fw1Tbv9Z(~Kr>mdK II;Vst0E(^9rvLx| literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/buttons/button_green.png b/example/kenney/assets/images/buttons/button_green.png new file mode 100755 index 0000000000000000000000000000000000000000..1da6a098e69127a23e17fc1ff8aa851d7912e8e5 GIT binary patch literal 474 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr1|*B;ILa_EFlKnVIEGZ*dOPc&my@GN+xgof zMaoTF>sf?mIx2d#2u|C6PeDLQX>qo|+NiDjFPH@_VlNP7Q53qd%=Igq?V%_3WlNY= zKjrzuY(K|%^G`dz&9el5#z>zvh|W!&wDxt0bZ4H?v8@`?76-NC#m!<{{%Jqh#x(U= z&XU=?%TF)6r+s_Q-dt<(ROaPI&HL?JH*}}HU-&}h$BKq>gWe6=8fAIU+uGUphHm~J zVYKyJS23gbk13(c6{8Y9e_8rU<}4)WGT?w_;K_wBw1S6^#_xSDhP`Hnw2ZM?zmztV&0OD7+g zGCA|{<9?=s=6JEk4`f|mCY^fmx4`xRi~f#-`a9h&I6cljpucnR#zp6aK7Z{zm_PeZ zq1MMhhCBE7aqAv=9BAjaw~F!pbC&g+>KVR?t5u|0eozJmy>5wXL`iUdT1k0gQ7S`H zrCw4_ett?yrCxGTWkE^4US@7$da52U@{CMe^OEyZQj1ow)xQI3WbkzLb6Mw<&;$Sw CXUqNo literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/buttons/button_red.png b/example/kenney/assets/images/buttons/button_red.png new file mode 100755 index 0000000000000000000000000000000000000000..7263038f44aabaa2d43b06114e99893c461ed46a GIT binary patch literal 480 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr1|*B;ILa_EFy?u>IEGZ*dOK^c7qg>C>wD%I zZ~UZkMR<}D6CZN_V320rcwvLruLzcUE^fz~NhP~(ahOeG)D{+Q97|$5ccAfS=DvRG;Jbo9W%mBM@yItSv;6Xo<~zAzYw`ol3Yxw)r*{K{MN3WXks@BQC=_vXa6 z=eE>l`rdl}Y)3g`_`dMcIr;3Lk6KT>-D`2&iI+WEIF2jh!16U!OI_5f9&B!C6PmJs zMODL*(<`6}2lKyT;an+mM}8jm7o9(KK5R~BuiF_V?`gAbm1C*@LGHW{r;m1No@&~b zi37gHwf=}z_veS>kFCg0OmSNKd;^i zst4ZNtxWOUDVrkNcIW;+?zz`awMPnlJ>1a$>p|!@{_q5|==n26UjZXPx5PD~Bsf2< zq&%@Gl_9B8FDWNKKP9D7FS)3)pd?=}GdD3kRSy`2MkcO#$@wX%MJw3q-vKo;c)I$z JtaD0e0swMb&0+um literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/buttons/button_yellow.png b/example/kenney/assets/images/buttons/button_yellow.png new file mode 100755 index 0000000000000000000000000000000000000000..e00e7e3e7f53f821720bbcd24cbb30a84a55aa19 GIT binary patch literal 452 zcmeAS@N?(olHy`uVBq!ia0vp^h9Jzr1|*B;ILa_EFa~+LIEGZ*dOK^cACsd zzTfAzROQ`ciyc7ee|P-OoKH7-mSU*E#<@@TiK_X}gGrZcBjjhuSec)*{ND7zN$*qY zntx^wx>Fwi)$sYTU-5Yu=dq?E=Vni6QBhIk^z?8NnuLRSXWJ#VZ*Sw<{=Arb@T>mYziJ65eCu46M{L@$ z-{byt){3G@)9*ZS4>_)@9_CzkC!{bbYSFB}+g@I~utCG&UGICRK;Eepg=s8xZgJ=T z@m3TRR=#A2dI=0<-4fS`lHmNblJdl&REDHVy`-G{{FIbRz2u_Gf|7i_%-qEER6Src d8JW1|CFiH47Oh~be+Sga;OXk;vd$@?2>@K%!|4D3 literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/empty.png b/example/kenney/assets/images/empty.png new file mode 100755 index 0000000000000000000000000000000000000000..5da9ec0922e6066d3284b286ec892cc4f6745636 GIT binary patch literal 14525 zcmeI3O>g5w7{{lqgu0dXgjPsg*7AaQb;eHOw6UC2B`LHL?pAFO>7JO_lh$ft8{65W zJs~*l4NiOlBu*T-a^S)TK;nSJC*Z~vBt)69Q|C#Vbav4mCsN|a z@Zr6U*ESGB_xAVNN9?%9zw0lv-v{@9e##DaqrH=a9pB{NwRi4*{RpA0*Zod6?K&S> zZa6FvFYM9MWEe38LiY9~BJMd&l^#9ygNFL&k3Xr3?={p zOXEr@j8Cyquh+3&#^tic6k2i-q-3H6$-_L!b)Gg&+}Mv&KMWL}m-NC>+E7(qsQ66p zYZw)Uf@I2$QN$AxVWXtuWhT!pJkcl~WL@)IOb2vGgEV12W2rAX3)3(;3s;mZF0U-i z#>8=o+DrR894;-Lq`OZTf+^Ca&ZKh@QG7&`a1^_A_X)d|hs*9h_4~8Inajkltn53T z_$zGuN^Z-hLOwz^yH~3fQ<8>pCkzM8e3l(vBUD-~KC3pBw;ba70q6R*jTcR`5ufFw zZIaR^^KNN+S<}r z$RjCvrYukk@_4S*591+8oBoiTQXB=RHl8&CWihX;RyYV_)-Bqs*mzkpaAkAN+7FVH z1TNigH(5i;_dUz2dVT59Z=s3`RBXv7;M|{0Z zQ+v;u8rW~7eiZv`uOkDX;k|#}5=+wDD7EJ&Y=&Ndnak#HwwoQ(&*odNFAV%_SBglS zP`>6G>h+>4wy|QD;+|~nTEyl1S<~f9f_gTdYn^qga87Oh{~f?QKd`T^F+QWgZ3`+- zm8n)INy2_QCNbSPWpm=$R(qaz-ndx6#{3^(;Li_5-a0=**K_vfh}wK(v)F84JtNsD z7&gAqHmjWLyL?m!qg=1E4>tJk)CsRHI!|tO!mEqUnepSmPn+dwv4v*f;(KqtEgZAQ z1lp{bX2rDeV)LTo(4Wvjx9zj_oA6o5cx0Bv_NBg)6+X~D_2t6^{?4;e%v;&R0((xu z#e>TH02j;P1qZVmdclcdI#~qL5XKUh5D^qeT#$w^mbiq7pg`h+G=#ClB}4=T5*MT) zj3q81A}El!APr$GaS0JYfy4!A2xEy$hzJTKE=WTdOI$)kP#|$Z8p2rO5+Z^Ei3`#Y z#uAqh5fn&VkcKdpxP*wHK;nWlgt5dWL<9vA7o;JKB`zT%D3G`y4Ph*C2@yeo#06;x zV~Im3(^qA5|T3HAJHNWRgVz6f>EBsFrZLF19!mz@gYWfraJhv(ETSj@GYK?4KWGOir7>`s5qYqeh{jdvmtm z-o8o4-s!T5u+6S3#am>1#lH)i%L<)Wh?>86zb)_VlFhGoy{xf2-*YlC=={ZRch?_S zw&L|KV>=l>_T?#?=4IGK^*`(0k#YOmap5AXxyv4ZesaJA7X#l{K4^uLXChOhdesB|3fPbVO8=c`A2AI?NQhJ-#?2_ zKYi43;?&n)t+vbd>TBDVzwW#Jw=Q3I-pQ&(A65T+uUuSN^*8!wX3?BPiEE+r6Ymz} zZMO8^e$(dc+hf^(z86}gNd3vXm$C1RdGCii-m)z*%R!-A;u=vBoS#-wo>-L1kW{Ic zl#`#Il2WOcTvS<5lCPJUo0y)e2aFjb6W6@t{FKz96>RnIfEpP*UHx3vIVCg!03Afe A<^TWy literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/progress/progress_fill_green.png b/example/kenney/assets/images/progress/progress_fill_green.png new file mode 100755 index 0000000000000000000000000000000000000000..195fa3b5c826478d705a92cf713f4311ed5a01c5 GIT binary patch literal 471 zcmeAS@N?(olHy`uVBq!ia0vp^`+!)NgAGUuv|TJx3ba4!+xb^m~trxSSM8iYd zsXrYzgu4ies;FHQ)?jftV$$?T*QPP@2y+BylZU{f)&(EgUr#UsGNFnT|E8=hkOhFA@+yO9~^%u z)CkyNa36BZLlIUbKMsG0uKcTPrmo-n=^d*)di&y!iXYLX7IO=4?~FE+ z><{Wb*1hn2rK-N#tmV(|pYT8R;>%V`*{_nzgwOe!J-_d3=AUi7{>{;P`RUG<&FlHP zJD*Md%6YnBVo3%=|5H%tm$*ih1m~xflqVLYG9*>%CFSJjr=(QsB^Ol|l;rDW<|d}6 g>H%ZU$iy`-IX@+}Xa!sSJD^4ePgg&ebxsLQ0B6L|WB>pF literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/progress/progress_fill_red.png b/example/kenney/assets/images/progress/progress_fill_red.png new file mode 100755 index 0000000000000000000000000000000000000000..32f5f4c823ad80b6ed6af7573f68e6963fa760f6 GIT binary patch literal 479 zcmeAS@N?(olHy`uVBq!ia0vp^`+!)NgAGUuv|TJ^+{O!!M4H+?Cy8jr(BooDZhm`xGV1HS`LVfAAOD!-cQm8?;DHrWGpxSOjVs^uMbXwk zIj;}3-z0Xq(K?n7>QD8f+kaQz|w)eTAZ0X7}Aj%==T_sDFm zdwW3Zu)lTQ`)c3WA6IP6*c0_n?Do9NnjNJbY%X{A%v~40+HSS&cC*=^_04B5&%QA8 zHE;Kya|J6F|IoL7^CW%ccmCvuO|Q3F_-lh=p~N+!Bsf2PCYmvgxm_mj4yo=?@f6XCZCDWTOtG?ILFfUe4MJ;Jx>u*qkEzk+hs`Hd zu0BjRy6d^p_Hp7X-?o=2C9~EYej9me!%MI87t2iM)y>5&DiyJx6Rk!of-Rfyq6X!?b=q)YcC;W`s;J2eoYJiA@+yO9~^%u)Ckyd$fI-n zKeU1oF9&u-KlXoEe)x-!c>d{o*Qa;)DF#kY-JWSJl^6YO1-3<{QQ)ZO1n>pYtyH-)1YEgO<<4Mm z;;mNe6PL&hObEo|0o`s_4F&_{x~`f|r-?ouk5#|lSGH|yU|_CRt35vq1pn;+$cR6P z17@?C%3_DZK}{x;2ryjGdQc|;E4^MX0_1wVs^jsfw%e^*tybTBy) z&Nk9TGX+NK2yzLtt^5z@?*WQu8LFo#K&R8`dzP`oW3n?*rKPjcqM_@~k5rR=45&?j zK_ue+OwZ2v1LhN&iCV-OB*qY1HdjZ6t?2e4+XllG=tpcAB@SnD{w-R}f}K&)EbYi9 zTU6I)s>|6r!cKhk!AG2n(ERcQh50-_EvBwS%s9+O6djnt*qN7zVaRCC(?9P2KukT6 zDS&#kKH)Ol%>YU;uWD@o{xmI&YgoragKyWQ$(PSYbV>kc; zP4f5}&1@o=ho5Os4!8h-Eeui;*gX#oWQ79$^_x++vwg@nALt9Lp+qD(bs~VciK%V+ z(F%;@4&>I`Q3$S_Z)9b1s0M%T00000NkvXXu0mjf12}Fm literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/radio/check_back_square.png b/example/kenney/assets/images/radio/check_back_square.png new file mode 100755 index 0000000000000000000000000000000000000000..f17bb8f1c3b230bb63fa035a524b48d66b946ecc GIT binary patch literal 535 zcmV+y0_gpTP)b;@5Ji2193e-@QF4SFAxB6{hh!Nrl`A?+Y2CS^L!zZ~<;s$684yUewees1ubkkJ zM3{w0JJJ+*SMwjcv&DSN>IvJnpJub!TazJkKA($Av#FD@p6j~rlgZ@Oahyl%r@*G6 zApQvKjYgvf>&z)-+#H6Xh@wcuaV&F)I3ACx-e$8AK@fD|qTbVM7S`C{`@SfOLgpEK~Ikhl8l=T591pw7~!t1%^h% z$JJ`3pipE8m~)xuxzs{H8w_CSUZdJ<;zuIY(R!CC?}s z)?n;4_L+K}cX?t4%zzm%17^Ssm;p0j2F!r{e=v+yx}c!NDg6YDQ#h>vj8wYEH)yxx zTi6Bj@Nv0ZY8`l?!3haoNeedax;)Rc2sreXWjUBN(3hwU4O#@eMwmNaO_h+Q3jGTm z0WD~r*aLkw6iyB{(KP{48yXyP(dXZKWLUV7aW}Sp6X-b{YuCuT0!##;lb&kh1Jp*k zLKL&8p8x;=Ep$a#bW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)oM=~@; ZZewp`Wpbznf9?PP002ovPDHLkV1oWj>|+1` literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/radio/checkmark.png b/example/kenney/assets/images/radio/checkmark.png new file mode 100755 index 0000000000000000000000000000000000000000..3ad298eb9edd4736467b46deca80533553925983 GIT binary patch literal 366 zcmV-!0g?WRP)20002|NklTgDT#unK_mr!B;c3tN=n(+oBZnhamjZ(Y zB?v&Ag3})Ju_*x2*uoLr>nIKZ#U3_SfGmN8Bf>IV7?i}2!pU<#KE=cs2#P$C10S!q zfsVo&tDqPo%Rpd+;!K<1hyW@e$w2go!3ID{i8OB$naF{WQcsM57!gBGz9uSS@Bw@| z2XDj>;o5v`hEiO1q9-$wOCOxc3>plu>`D~?F0p_SN2)#mB<}3~V;LW)0000jbVXQn zQ*UN;cVTj60AhJAVr*}3WMp|RV{&KQKGBibQV{c?-a;OG>?f?J) M07*qoM6N<$f|??c=Kufz literal 0 HcmV?d00001 diff --git a/example/kenney/assets/images/radio/tick.png b/example/kenney/assets/images/radio/tick.png new file mode 100755 index 0000000000000000000000000000000000000000..f0c945d3c71e288e259a904740c04f7f40f5eb16 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn1|+R>-G2e8&7LlfAr-fh6AmzL>bE-id|uI3 z_hURqn)Y0N_pf!i?R)Y0U;p*uDzNS_QGR^L_}=?szg;hrB?2lg zDbJH&e!w>OlTH64r3vC5h730qTC_j3Fgi9j*d;Lh?2Tb|*zsb^^QwS^Yr#nz9Q;bo zCwe8PNHD49d+{);222XlGUF*?vDw@>$>`;}4{zK(zb*LUF!Z!aBj<5dfu4h0U47w$*5hcO-X(i=}MX3x)m3m1z x`S~d+m3qlVl?5gFdYQS2>8W}^yNyg-^OEyZQj1ow)xQJj^mO%eS?83{1OPx5Fy82_iaK76ZA-rZ2gZ>Pu2V&KUaHMF>^E@&_|xHAvl2r%d`mtLq9 zP;Ub{{cK0|%znrmeUCmF@O;O`rCpQqTud=dI1yij6XyXEk5lz+b!qvRq>)T@Pxx2U z!RU&>gZ=k51x#L6T1D^NM@b_jAn9vWf#@4};KcO0IR(Br{QP?%U~Hz4db}HQ2&=D= zsvDFozJS~p3C0FR_E9j2dO~NlQ-xE2;xYgs&Mtftk(+j)D>~BE$qvgKC0!O6>WLyp ze={s$)JV?>JFp9O;w+)#bHs$~1k-kz7cJzp9z`v&i<`8W8DohVoz?{)1ls_`-7yth z@i-z_>Ok%a5VB!N(8F4)jdYPdS72-%K`!Bp8$SZ{{{f0u89a?EKvn-|LY0LR9?s51 zm$rk076V--zwyl090O_>V33KXc_!Xj{{j9)rm%xv#2!Q&60x<^5z|)o_^`(Y(`ED{ zfV7pQIpc$6iko64JFv}79*rz<$d)zrS?ad8j<6G7eee){5r$uppy1ErZZUNwV#UE5 zaoB<>*v_IvY~-LTTKx23`#%s}&_Vn*n`+HMEGN5S{$JifJU4w(CnPFj72_7I#Mg7hdf(#i5r7DW5-9YjWDh zG7v)m001p?MObuGZ)S9NVRB^vVtFoNY;SL5WO*)Qa(QrcZ!T$VVP|D7P) XZ)9b1s0M%T00000NkvXXu0mjfT`89A literal 0 HcmV?d00001 diff --git a/example/kenney/assets/sounds/click.ogg b/example/kenney/assets/sounds/click.ogg new file mode 100755 index 0000000000000000000000000000000000000000..4f17f1cdd3f3554546329fb2d84f330e7c17263b GIT binary patch literal 6952 zcmbU_2{@Ep+YiZ>BxEURgqIQ3Fk)m&gs~4JYZ7BGF(@=r4K)Zcwy`fmqj*bMi@eEF zma%1`q*8<;#3X6{Gt~RN-}hhF_g~k49LKrubD#5^d%q7WZ*NP?DJ~o zkmd*r3_j(HXQMa`Z~r2h-5{>xuww80yRmn20ElN~DM84P^=~a`)5bwauztkqFw8yB zF4P|8ta=cEIEYk5y22Dsx#Mx3u)s4g2j8le#74WbC-&6MM--ok5!m)YdjC}@2 z?KvP`fI*nUTBCcDu@EE#K_}(lf~j7na4NY_F+7uO!k)DrBxRCGtr8vyh_>GY4C%Q8 zg1De)MZU!12~)owl(&RJVsHV<*HW_##uI1r2F3Sy=?{-HrT0ty&-B3MdAB-l2JA!n zCNeRi81``LnoO(&7_LeMcgU3G1oJE1EV#_C+5x*_t~yncYN<7Kvp7*}TJe6b!4{SK z{b+NpQ{8Q%~! zy(`*zSE{>D&T2u~Mnt_&&B)fy0t;HG>+vugBP^5=MsUoGajqjc*2Or#h;e1cxJ$(T z>fZ=sOm<&q9mW9_$fDB6;YE9Q7QI6iZ6e0r=7c=iB7yOx?1iTko0fX{Rr+Sv_}r>F z-C3pFStYPe0+h?ez7161ODX+d-ODi@_kVYNpAIERAIP#jNUA+Z&Ilvd9<0o>F5wOc z=u{u0+!~BD#v|MD+MpYU7(OMNcYihC_FD;TwL_3TLaH@L>M4*0Mr9ya{WxBSfwy1) zQLrWQ-`k~idjX8d^<4b_xTH$*brI)hUjS{4MD4>aE z5Bx>4%T}nTWoEByFrY_r9Ox4MEUUF3tCxcBF%_UtH)i3&**q1ret?sl%n@vpbO&_4 z{S+SBumjlZ*h`tXSuYA^ByzSwb-mrjdB4npb|RMB_bE}CQkhigkR-v>0z?PAMEZK-F*NOpHAYf_8ghA^a~K2> zh1RY3_polt8&+JB5~uV`@m`l|r!srE-O{5qbEiejtFLLzlyZipp>GM)H!t$W^sjAqj z>0s@!$HPuLW`w@1jd6VuI>sQ3F|NCb$Nr~b{p~pra2n#ePm)h1Alh@TSQ_wcDEPPM z1c|oaka~JU&a6t#qF=dt0co{}>=QAvL0Z`EaP8X>Iv|F#J>)u|jvK(@o`>OvYjDoB z1jm|R4zuAlV~o&$cn;e|_M#HUO;Wi2-XPxmHKXjyqvv?Bih z@Eo7Gvdp-$YjKm;5*115z9dR{eNn)(%9)1$v;XZm#=&x+1J5xEmive2G$W*r0&l8P zwpiTYQKt_GG{i{!p9+AW=41i0^*CaKQF)G0e~wYX+Ufjvj{&RCkro3;AlNhrk_4d; z-bx`_ryQ|Fe=_oIgYi^we}EGuQeVVRWg2wYSSxu7NWRy9I*5oBT0G@ZCTh?XKTpLc z968WdhcQt6ix-4FF31LgxJ~z(%9$=8i%h=Cb<4(SZ;zIX&`z2(&Ffe^FAbTBhD*~^ z4R1`&YlEc1AqalO3<_oTaYk!$K=E?n(xwaADeuFP7NRn7DW#;nbTx}SuQ+pCY+?B? zkfK0Y2lEuml|Yy*pK9=YS>xXM3oM;(2pF!Bc?sNJ&dSz;;zdDrBS}Sm23YxSHSBMY zW`NbP4RI}}YWW|hta z;~ZmEBL4ha<%+PR?{dn~p4W%=4!7B5mxjJ`^B1cIJclrNEznUb2H! z0ow@lO`zzOAZ0T^zGw(sDRtZ-eUen92+~5i5;&2*?qCCU*mSCIo^Qn=2SGz48vz$Bn1rPPnX+j8)UJBvj1Mf^@NV5kpWJMYKI13B1TCbY*T=so6Q^$tohiDZoXre`L{aqK_#4! zgj9PK5S)1*QpL0%X(MU`1Z9@O7KDvDHVx;?77maM5DO43+i<7DOKIgGK-eAs3Jluy zc>2Gj!U4VE6NL0PAG)1*7K0RX@aaH9Fkn;&ZW&JjgANIzr~xmWDkKa+2j74y>7;?A zBGOYHO6CX2u9yr`mMPWX8e$Sg?#ILkdGs7nq*8Ap+F;}qjK7UX!VyJz>QIrt3;@v; zMhpWs=oF7Bw?q3?v`SFzXk-8)&@?<6fF5KFlk60KcSw;Mq6(_5if+`TC#buewm|wm zpfo&u$32voT6DJ=sEZQ{2ie{L&92IXWT+AzU5Km67;%ZJmow4!Ao7XKnKImLec0uL9uBi_a67XS(igSsASo4$OQJnHY8K3 z1lzb^M0Pz$Mg!LHJx6$C0I0~ey7d{zdDfWeOuQgF`?2Y$gTHqG5U2x)YGZ*&#{8ZE zI#3Y*-a!@yti%AEJW&|UD_=s!@UwTosYHwcD4c=SP|4P4cp(`u5A4T4aUGOr=X-f} z&X)(PV1bNQEM(JB$!uiW`T_>c2VfvGHVRBO#&r~&3O)po>nLF~yF$mH*H8XUhvsLa z;8dVb;Fr;mtdhzTOSMXEPGeD3bN!gu+guO^SU>wdfJ{BXX8jX!QXA*4Z)Fecn`|8P zH|qZfax{;M3r6dT{F{G)=flBRpt9f|6czXourIO+9N3p78m`0EM=p^Zv92gMd`aS{ zq6`qu%-vW^Ene#VLH}(sM6#0~jVY~qQ<0j2nbWDZ#`wY8UPqeA-|KhsZ=8H>rUY*r ziI_vxreMrf#GsSHZ=vYAlP%M{3Pv86fCxCDQ^0wS3K*Dd@c8%3=3j3d1P2ri;sV5B ze`nvl`+miBwA6TmnTu<~-VdcDqorS%>05MJbUU)3U9QzR+GZ!@Z{v zCgwM}Q=WXd98Ba(G zVX?GWZ&{yM??UFEaFi(SwkeNv)pmzu-hTP=V_sE_q!|{YKQC-(lDYNjkI;L&!sKh-H1nI>|G{$Iub|F05CL=&b6w=PvuBbhe$7{YXQZzp|hmeX%Ha*g!Zh!Y zgkVDw->&MI+aF32%)dT()Cyy;%~YMpcpXXk5n^wUMiR4SPG*u!u*c<1PS-L}a&F?blN zPL$(lb)PJsAt7j_;(e6*lWm{(%?;=#_6?4tvVvb*U2WPXmPSkcknmKNkvgLe3-x5yViC4cAuBNqlwAYd&4%j_O3<#5hm*s$B)Z!aHN@+1l*0v>^#kb zewe{)bhX|1`Mf5UE?GwSth;tzqHIEcN6~8ayX;yVqnc4k_UiIpTm9)}|LV_+wc?#m zN6w8An4@zYdy1b2(`AV}gD$N3Y1DC1FAshck<-zmuflMppR`ufoCLGH1srXLYzNOP z%v}3?r|4s>FnO)i_VZtA8!@{@!qOuEF(! zpjs+_xk^3yjD-vw^I|1r*lOX}#q__j63;Yl@EnkMU;5a1`u3FWy?}FvDxTN82pT6ZapkfWf)u-) zt#>=j`*%q%5-}~H*UmwDyW>CUA{yg*_OHE35bQ@_C#1RhCz8GX4d(yKraVkle%kD4WJ(rDf)S z#GFGHN{vwU`o^N7+?r<0Pu^I|^{H5})BX0~L8V4kOV8(rFPn1qFe2VfUChh<_F(n? zXvMw!yR697JNunu55(90z`NY&yKy)8f)=&kZF)+v_yD6QL+jP_GdDlds#)lVNL=IX z${_nh=T~lLT9!u3+MPplKe#AK*PflpSnVHBT4K^gX05m%uB_B+L`H>S1yG3$=0XaB zS++`Zo6Z{BpQ~CqqcNA{((X*4eEi z*S9Ee?n9o@lg2`()Qr@wt(kuqZ~79k>0_SuffExBj}gL9^hi|E>!I3R74+-gctY=C z`ZHQ_FkDdD?eceyiqKV0rQEuQexk1$$8w1)B5C%pLX_SaidI}k&{6)=z59Dy(y%ID z20z^{oGH|ptepHIp{wydhd`)oy_(f?r>C-U#XcZiPa%-m3%{A_f_+wQdm%89Usp@@ zo$>d9t4+_b^sqVl@yQaRK zYl;`&?U<2Py>RYv*zyw+>Euy??!)&q?q-PVSB5^-klW3Yw%j)SRE9ItCCT9?%hIdwWvrU^MSl!^ie6ZX$R)G{oly}FbZfUAR~hCSRKf<4sNptd z;<=6Xchpu&&g=NRihi=_;osj9GXa|=kZ@Kjs@2D^=ZDifI|=p=aOGYQ3mT8ucMoOo}CcokLcl~q9YjZzazZaQ$?l7UZUA^KLnzD%} zp&QL#UO3IM%t;8z7Rnf9IPbIliQ1XjmDAs+mQ#k#oNeJg7)dz0DSGoso{!6I%UbhF zrXUo+LYxP@FFdY#;x&Zqd4aon{$0Cn#moSKWxF%3=|srdv4o3OErlaY17m&-%iYfX zKD!Sr4HbO4IN?j*(=SnZZ+DG#%J>8y_vx<_^);oJ7PvzXbx*v+4d~;WUJQ1t-Jzg7 znEQ2e97@vLxsw@}x*uc|MO36L`m;oNb+&I`G|zZ-aZW**xyrL!zcF1ql`!$}qIcl8 zuiy_lWf>yCk_c1Ck{k{TjObp)6`tpr9}(JW&_DD2#bTD>R6DDH2xI1{ zg;&;JTos?&9k_boP^4gb{+Wn5?U6l#f8Aop&6ye8EgK7}`;o7G;}QX;5iyx0p0gpTG&*idncnou3}c^@>=g&*b(-vo$3lTx#K|j~d z)Lf@@mH3N?hFH<_C(9NGUb^YYdrM>th0=jgfv1Dl>q z5*%K4j_7;J>8DyNF&L3D;x8Vt0-=JkaMw-cbC2|rrl%vA*U`gK+FGkWz&Wg+Uz1lK zzW$S0)la>vJL@_iDe0ZRbun^wcfHGjImT+x#aG*&dwRZ?_c+P=>Dt&$M>#{QOx7BG zmPC}sAL**=f^DXyr-AP^0$M3 z6MdK&ecG%$w2-|PIXiH)ZPDYdLHZcsxI7_j&;0W8 i#251BV^a%a)*Q-rnv1>p3tT3m85$r~J3Bkzq5lD5lpv}A literal 0 HcmV?d00001 diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui new file mode 100644 index 0000000..87559e7 --- /dev/null +++ b/example/kenney/gui/main/main.gui @@ -0,0 +1,561 @@ +script: "/example/kenney/gui/main/main.gui_script" +fonts { + name: "game" + font: "/example/kenney/assets/fonts/game.font" +} +textures { + name: "kenney" + texture: "/example/kenney/assets/images/kenney.atlas" +} +background_color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 +} +nodes { + position { + x: 300.0 + y: 450.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: "kenney/empty" + id: "root" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + 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: 0.0 + y: 450.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: "kenney/empty" + id: "N_Anchor" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "root" + 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: 0.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: 600.0 + y: 100.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: "kenney/back_gray" + id: "panel_top" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_STRETCH + parent: "N_Anchor" + layer: "" + inherit_alpha: true + slice9 { + x: 20.0 + y: 20.0 + z: 20.0 + w: 20.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: -200.0 + y: -50.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_left" + parent: "panel_top" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_left/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_left" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Tap me!" + font: "game" + id: "button_left/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_left/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 200.0 + y: -50.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_right" + parent: "panel_top" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_right/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_right" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Tap me!" + font: "game" + id: "button_right/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_right/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: -43.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Title" + font: "game" + id: "text_header" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "panel_top" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT +max_nodes: 512 diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script new file mode 100644 index 0000000..4ed09fd --- /dev/null +++ b/example/kenney/gui/main/main.gui_script @@ -0,0 +1,35 @@ +local druid = require("druid.druid") + + +local function on_control_button(self, side) + print("Click on button side", side) +end + + +local function init_top_panel(self) + self.druid:new_button("button_left/button", on_control_button, "left") + self.druid:new_button("button_right/button", on_control_button, "right") + self.header = self.druid:new_text("text_header", "main_page", true) +end + + +function init(self) + self.druid = druid.new(self) + + init_top_panel(self) +end + + +function update(self, dt) + self.druid:update(dt) +end + + +function on_message(self, message_id, message, sender) + self.druid:on_message(message_id, message, sender) +end + + +function on_input(self, action_id, action) + self.druid:on_input(action_id, action) +end diff --git a/example/kenney/init.script b/example/kenney/init.script new file mode 100644 index 0000000..6362a95 --- /dev/null +++ b/example/kenney/init.script @@ -0,0 +1,24 @@ +local const = require("druid.const") +local settings = require("druid.settings") +local lang = require("example.kenney.lang") + + +local function setup_druid() + settings.play_sound = function(name) + sound.play("kenney:/sound#" .. name) + end + + settings.get_text = function(lang_id) + return lang.get_locale(lang_id) + end + + -- TODO: Call druid.finish_setup? + -- Need to update all gui, in case, when gui init was befure this init + msg.post("/gui#main", const.ON_CHANGE_LANGUAGE) +end + + +function init(self) + setup_druid() + msg.post("@render:", "clear_color", { color = vmath.vector4(0.8, 0.9, 0.85, 1) }) +end diff --git a/example/kenney/kenney.collection b/example/kenney/kenney.collection new file mode 100644 index 0000000..3b0225f --- /dev/null +++ b/example/kenney/kenney.collection @@ -0,0 +1,107 @@ +name: "kenney" +scale_along_z: 0 +embedded_instances { + id: "gui" + data: "components {\n" + " id: \"main\"\n" + " component: \"/example/kenney/gui/main/main.gui\"\n" + " position {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " }\n" + " rotation {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " w: 1.0\n" + " }\n" + "}\n" + "" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale3 { + x: 1.0 + y: 1.0 + z: 1.0 + } +} +embedded_instances { + id: "system" + data: "components {\n" + " id: \"init\"\n" + " component: \"/example/kenney/init.script\"\n" + " position {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " }\n" + " rotation {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " w: 1.0\n" + " }\n" + "}\n" + "" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale3 { + x: 1.0 + y: 1.0 + z: 1.0 + } +} +embedded_instances { + id: "sound" + data: "components {\n" + " id: \"click\"\n" + " component: \"/example/kenney/assets/sounds/click.ogg\"\n" + " position {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " }\n" + " rotation {\n" + " x: 0.0\n" + " y: 0.0\n" + " z: 0.0\n" + " w: 1.0\n" + " }\n" + "}\n" + "" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale3 { + x: 1.0 + y: 1.0 + z: 1.0 + } +} diff --git a/example/kenney/lang.lua b/example/kenney/lang.lua new file mode 100644 index 0000000..8125cb0 --- /dev/null +++ b/example/kenney/lang.lua @@ -0,0 +1,12 @@ +local M = {} + +local data = { + main_page = "Main page", +} + + +function M.get_locale(lang_id) + return data[lang_id] or lang_id +end + +return M \ No newline at end of file diff --git a/example/kenney/templates/button.gui b/example/kenney/templates/button.gui new file mode 100644 index 0000000..4beda9c --- /dev/null +++ b/example/kenney/templates/button.gui @@ -0,0 +1,135 @@ +script: "" +fonts { + name: "game" + font: "/example/kenney/assets/fonts/game.font" +} +textures { + name: "kenney" + texture: "/example/kenney/assets/images/kenney.atlas" +} +background_color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.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: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Tap me!" + font: "game" + id: "text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT +max_nodes: 512 diff --git a/game.project b/game.project index 16e04b5..c918863 100644 --- a/game.project +++ b/game.project @@ -1,5 +1,5 @@ [bootstrap] -main_collection = /example/scroll.collectionc +main_collection = /example/kenney/kenney.collectionc [script] shared_state = 1 From ffb6debff1183de7d0d1ce5c9e8292313172aa9c Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 23:10:47 +0300 Subject: [PATCH 049/136] Main page on kenney example --- druid/base/scroll.lua | 12 +- druid/base/text.lua | 4 +- example/example.collection | 2 + example/kenney/gui/main/main.gui | 795 ++++++++++++++++++++++++ example/kenney/gui/main/main.gui_script | 2 + example/kenney/page/main.lua | 47 ++ 6 files changed, 859 insertions(+), 3 deletions(-) create mode 100644 example/kenney/page/main.lua diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 7febced..622b18d 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -23,7 +23,6 @@ function M.init(self, scroll_parent, input_zone, border) self.node = helper.get_node(scroll_parent) self.input_zone = helper.get_node(input_zone) self.zone_size = gui.get_size(self.input_zone) - self:set_border(border) self.soft_size = settings.SOFT_ZONE_SIZE -- Distance from node to node's center @@ -34,7 +33,8 @@ function M.init(self, scroll_parent, input_zone, border) self.is_inert = true self.inert = vmath.vector3(0) - self.pos = gui.get_position(self.node) + self.start_pos = gui.get_position(self.node) + self.pos = self.start_pos self.target = vmath.vector3(self.pos) self.input = { @@ -43,6 +43,8 @@ function M.init(self, scroll_parent, input_zone, border) start_y = 0, side = false, } + + self:set_border(border) end @@ -390,6 +392,12 @@ end --- Set the scroll possibly area function M.set_border(self, border) self.border = border + + self.border.x = self.border.x + self.start_pos.x + self.border.z = self.border.z + self.start_pos.x + self.border.y = self.border.y + self.start_pos.y + self.border.w = self.border.w + self.start_pos.y + border.z = math.max(border.x, border.z) border.w = math.max(border.y, border.w) self.can_x = (border.x ~= border.z) diff --git a/druid/base/text.lua b/druid/base/text.lua index b60a141..b3fbe0a 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -36,7 +36,9 @@ end function M.on_change_language(self) - M.translate(self) + if self.last_locale then + M.translate(self) + end end diff --git a/example/example.collection b/example/example.collection index 270fc16..3b0c850 100644 --- a/example/example.collection +++ b/example/example.collection @@ -44,6 +44,8 @@ embedded_instances { "looping: 0\\n" "group: \\\"master\\\"\\n" "gain: 0.4\\n" + "pan: 0.0\\n" + "speed: 1.0\\n" "\"\n" " position {\n" " x: 0.0\n" diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index 87559e7..6062eb6 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -67,6 +67,801 @@ nodes { template_node_child: false size_mode: SIZE_MODE_AUTO } +nodes { + position { + x: 0.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: "kenney/empty" + id: "C_Anchor" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "root" + 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: 0.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: 600.0 + y: 900.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: "kenney/empty" + id: "main_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "C_Anchor" + 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: 0.0 + y: 450.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: 600.0 + y: 900.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: "kenney/empty" + id: "scroll_content" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_FIT + parent: "main_page" + 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: -150.0 + y: -261.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_template" + parent: "scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_template/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_template" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Tap me!" + font: "game" + id: "button_template/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_template/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: -261.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: 130.0 + y: 60.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: "kenney/button_green" + id: "button_simple" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 5.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: 150.0 + y: -261.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Just text" + font: "game" + id: "text_simple" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 40.0 + y: -411.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: 190.0 + y: 45.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: "kenney/progress_back" + id: "progress_back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: 0.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: 190.0 + y: 45.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: "kenney/progress_fill_yellow" + id: "progress_fill" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "progress_back" + layer: "" + inherit_alpha: true + slice9 { + x: 10.0 + y: 0.0 + z: 10.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: 95.0 + y: 2.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 100.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "15%" + font: "game" + id: "text_progress" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "progress_back" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -120.0 + y: -406.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Simple progress" + font: "game" + id: "text_progress_bar" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: -511.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: "kenney/empty" + id: "grid" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: 0.0 + y: -161.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Timer" + font: "game" + id: "text_timer" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} nodes { position { x: 0.0 diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 4ed09fd..9734c99 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -1,5 +1,6 @@ local druid = require("druid.druid") +local main_page = require("example.kenney.page.main") local function on_control_button(self, side) print("Click on button side", side) @@ -17,6 +18,7 @@ function init(self) self.druid = druid.new(self) init_top_panel(self) + main_page.setup_page(self) end diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua new file mode 100644 index 0000000..45e46ea --- /dev/null +++ b/example/kenney/page/main.lua @@ -0,0 +1,47 @@ +local M = {} + +local function empty_callback(self, param) + print("Empty callback. Param", param) +end + + +local function random_progress(progress, text) + local rnd = math.random() + + gui.set_text(text, math.ceil(rnd * 100)) + progress:to(rnd) +end + + +function M.setup_page(self) + self.druid:new_button("button_simple", empty_callback, "button_param") + + self.druid:new_button("button_template/button", empty_callback, "button_param") + + + local progress = self.druid:new_progress("progress_fill", "x", 0.4) + random_progress(progress, gui.get_node("text_progress")) + timer.delay(2, true, function() + random_progress(progress, gui.get_node("text_progress")) + end) + + + local grid = self.druid:new_grid("grid", "button_template/button", 3) + + for i = 1, 12 do + local nodes = gui.clone_tree(gui.get_node("button_template/button")) + + local root = nodes["button_template/button"] + self.druid:new_button(root, empty_callback, "Grid"..i) + self.druid:new_text(nodes["button_template/text"], "Grid"..i) + grid:add(root) + end + + + self.timer = self.druid:new_timer("text_timer", 120, 0, empty_callback) + + self.scroll = self.druid:new_scroll("scroll_content", "main_page", vmath.vector4(0, 0, 0, 200)) +end + + +return M From 528170f46240b50567b8208be8ffe7b2c69e6d09 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 23:19:08 +0300 Subject: [PATCH 050/136] main page polish --- example/kenney/page/main.lua | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 45e46ea..30acacf 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -13,35 +13,63 @@ local function random_progress(progress, text) end -function M.setup_page(self) +local function setup_button(self) self.druid:new_button("button_simple", empty_callback, "button_param") - self.druid:new_button("button_template/button", empty_callback, "button_param") +end +local function setup_progress(self) local progress = self.druid:new_progress("progress_fill", "x", 0.4) random_progress(progress, gui.get_node("text_progress")) timer.delay(2, true, function() random_progress(progress, gui.get_node("text_progress")) end) +end +local function setup_grid(self) local grid = self.druid:new_grid("grid", "button_template/button", 3) for i = 1, 12 do local nodes = gui.clone_tree(gui.get_node("button_template/button")) local root = nodes["button_template/button"] - self.druid:new_button(root, empty_callback, "Grid"..i) + self.druid:new_button(root, function(context, param) + grid:set_offset(vmath.vector3(param)) + end, i) self.druid:new_text(nodes["button_template/text"], "Grid"..i) grid:add(root) + + end +end +local function setup_timer(self) self.timer = self.druid:new_timer("text_timer", 120, 0, empty_callback) +end + +local function setup_scroll(self) self.scroll = self.druid:new_scroll("scroll_content", "main_page", vmath.vector4(0, 0, 0, 200)) end +local function setup_back_handler(self) + self.druid:new_back_handler(empty_callback, "back button") +end + + + +function M.setup_page(self) + setup_button(self) + setup_progress(self) + setup_grid(self) + setup_timer(self) + setup_scroll(self) + setup_back_handler(self) +end + + return M From 6d8d0e822a7d1e3a1427b9effeeb9409489fa7f4 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 23:42:35 +0300 Subject: [PATCH 051/136] work on main example page --- example/kenney/assets/fonts/game.font | 2 +- example/kenney/gui/main/main.gui | 2213 +++++++++++++++++++++++-- example/kenney/lang.lua | 33 +- example/kenney/page/main.lua | 27 +- example/kenney/templates/checkbox.gui | 123 ++ example/kenney/templates/radio.gui | 123 ++ 6 files changed, 2408 insertions(+), 113 deletions(-) create mode 100644 example/kenney/templates/checkbox.gui create mode 100644 example/kenney/templates/radio.gui diff --git a/example/kenney/assets/fonts/game.font b/example/kenney/assets/fonts/game.font index 5bc9993..5cc90eb 100644 --- a/example/kenney/assets/fonts/game.font +++ b/example/kenney/assets/fonts/game.font @@ -11,7 +11,7 @@ shadow_x: 3.0 shadow_y: -4.0 extra_characters: "" output_format: TYPE_DISTANCE_FIELD -all_chars: false +all_chars: true cache_width: 0 cache_height: 0 render_mode: MODE_MULTI_LAYER diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index 6062eb6..ebfca92 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -234,8 +234,126 @@ nodes { } nodes { position { - x: -150.0 - y: -261.0 + x: 0.0 + y: -170.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: "kenney/empty" + id: "section_button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Button:" + font: "game" + id: "text_button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 6.0 + y: 0.0 z: 0.0 w: 1.0 } @@ -265,7 +383,7 @@ nodes { } type: TYPE_TEMPLATE id: "button_template" - parent: "scroll_content" + parent: "section_button" layer: "" inherit_alpha: true alpha: 1.0 @@ -392,8 +510,8 @@ nodes { } nodes { position { - x: 0.0 - y: -261.0 + x: 156.0 + y: 0.0 z: 0.0 w: 1.0 } @@ -429,7 +547,7 @@ nodes { yanchor: YANCHOR_NONE pivot: PIVOT_CENTER adjust_mode: ADJUST_MODE_FIT - parent: "scroll_content" + parent: "section_button" layer: "" inherit_alpha: true slice9 { @@ -447,8 +565,63 @@ nodes { } nodes { position { - x: 150.0 - y: -261.0 + x: 0.0 + y: -260.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: "kenney/empty" + id: "section_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.0 + y: 0.0 z: 0.0 w: 1.0 } @@ -478,7 +651,133 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "Just text" + text: "Text:" + font: "game" + id: "text_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_text" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Translated" + font: "game" + id: "text_translated" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_text" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "SImple" font: "game" id: "text_simple" xanchor: XANCHOR_NONE @@ -498,7 +797,7 @@ nodes { } adjust_mode: ADJUST_MODE_FIT line_break: false - parent: "scroll_content" + parent: "section_text" layer: "" inherit_alpha: true alpha: 1.0 @@ -510,8 +809,307 @@ nodes { } nodes { position { - x: 40.0 - y: -411.0 + x: 0.0 + y: -350.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: "kenney/empty" + id: "section_timer" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Timer:" + font: "game" + id: "text_timer" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_timer" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 220.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "12:20" + font: "game" + id: "timer" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_E + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_timer" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 0.0 + y: -440.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: "kenney/empty" + id: "section_progress" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Progress bar:" + font: "game" + id: "text_progress" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_progress" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 30.0 + y: 0.0 z: 0.0 w: 1.0 } @@ -547,7 +1145,7 @@ nodes { yanchor: YANCHOR_NONE pivot: PIVOT_W adjust_mode: ADJUST_MODE_FIT - parent: "scroll_content" + parent: "section_progress" layer: "" inherit_alpha: true slice9 { @@ -653,7 +1251,7 @@ nodes { blend_mode: BLEND_MODE_ALPHA text: "15%" font: "game" - id: "text_progress" + id: "text_progress_amount" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER @@ -683,71 +1281,8 @@ nodes { } nodes { position { - x: -120.0 - y: -406.0 - z: 0.0 - w: 1.0 - } - rotation { x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.7 - y: 0.7 - z: 1.0 - w: 1.0 - } - size { - x: 300.0 - y: 60.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Simple progress" - font: "game" - id: "text_progress_bar" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "scroll_content" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 0.0 - y: -511.0 + y: -530.0 z: 0.0 w: 1.0 } @@ -778,7 +1313,1481 @@ nodes { type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA texture: "kenney/empty" - id: "grid" + id: "section_slider" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Slider:" + font: "game" + id: "text_slider" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_slider" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 130.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: 190.0 + y: 4.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: "kenney/slider_back" + id: "slider_back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "section_slider" + 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: -95.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 36.0 + y: 36.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: "kenney/slider_move" + id: "slider_pin" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "slider_back" + 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: 0.0 + y: -620.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: "kenney/empty" + id: "section_radio" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Radio:" + font: "game" + id: "text_radio" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_radio" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 60.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: "kenney/empty" + id: "radio_group" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "section_radio" + 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: 0.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "radio1" + parent: "radio_group" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/radio.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 36.0 + y: 36.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: "kenney/check_back_circle" + id: "radio1/back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "radio1" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: -0.5 + y: 0.5 + 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: 17.0 + y: 17.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: "kenney/tick" + id: "radio1/check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "radio1/back" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 70.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "radio2" + parent: "radio_group" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/radio.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 36.0 + y: 36.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: "kenney/check_back_circle" + id: "radio2/back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "radio2" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: -0.5 + y: 0.5 + 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: 17.0 + y: 17.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: "kenney/tick" + id: "radio2/check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "radio2/back" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 140.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "radio3" + parent: "radio_group" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/radio.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 36.0 + y: 36.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: "kenney/check_back_circle" + id: "radio3/back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "radio3" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: -0.5 + y: 0.5 + 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: 17.0 + y: 17.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: "kenney/tick" + id: "radio3/check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "radio3/back" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 0.0 + y: -710.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: "kenney/empty" + id: "section_checkbox" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + 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: -250.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Checkbox:" + font: "game" + id: "text_checkbox" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "section_checkbox" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 60.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: "kenney/empty" + id: "checkbox_group" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "section_checkbox" + 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: 0.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "checkbox1" + parent: "checkbox_group" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/checkbox.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 38.0 + y: 36.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: "kenney/check_back_square" + id: "checkbox1/back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "checkbox1" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 0.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: 21.0 + y: 20.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: "kenney/checkmark" + id: "checkbox1/check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "checkbox1/back" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 70.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "checkbox2" + parent: "checkbox_group" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/checkbox.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 38.0 + y: 36.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: "kenney/check_back_square" + id: "checkbox2/back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "checkbox2" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 0.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: 21.0 + y: 20.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: "kenney/checkmark" + id: "checkbox2/check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "checkbox2/back" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 140.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "checkbox3" + parent: "checkbox_group" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/checkbox.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 38.0 + y: 36.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: "kenney/check_back_square" + id: "checkbox3/back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "checkbox3" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 0.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: 21.0 + y: 20.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: "kenney/checkmark" + id: "checkbox3/check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "checkbox3/back" + 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: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + x: 0.0 + y: -800.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: "kenney/empty" + id: "section_grid" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER @@ -802,7 +2811,7 @@ nodes { nodes { position { x: 0.0 - y: -161.0 + y: 0.0 z: 0.0 w: 1.0 } @@ -813,14 +2822,14 @@ nodes { w: 1.0 } scale { - x: 0.7 - y: 0.7 + x: 1.0 + y: 1.0 z: 1.0 w: 1.0 } size { - x: 200.0 - y: 100.0 + x: 400.0 + y: 400.0 z: 0.0 w: 1.0 } @@ -830,37 +2839,29 @@ nodes { z: 1.0 w: 1.0 } - type: TYPE_TEXT + type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA - text: "Timer" - font: "game" - id: "text_timer" + texture: "kenney/empty" + id: "grid" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_FIT + parent: "section_grid" + layer: "" + inherit_alpha: true + slice9 { x: 0.0 y: 0.0 z: 0.0 - w: 1.0 + w: 0.0 } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "scroll_content" - layer: "" - inherit_alpha: true + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 0.0 template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 + size_mode: SIZE_MODE_MANUAL } nodes { position { diff --git a/example/kenney/lang.lua b/example/kenney/lang.lua index 8125cb0..00ca698 100644 --- a/example/kenney/lang.lua +++ b/example/kenney/lang.lua @@ -1,12 +1,43 @@ +local const = require("druid.const") + local M = {} -local data = { +local en = { main_page = "Main page", + ui_section_button = "Button", + ui_section_text = "Text", + ui_section_timer = "Timer", + ui_section_progress = "Progress", + ui_section_slider = "Slider", + ui_section_radio = "Radio", + ui_section_checkbox = "Checkbox", + ui_text_example = "Translated", } +local ru = { + main_page = "Основное", + ui_section_button = "Кнопка", + ui_section_text = "Текст", + ui_section_timer = "Таймер", + ui_section_progress = "Прогресс", + ui_section_slider = "Слайдер", + ui_section_radio = "Выбор", + ui_section_checkbox = "Мн. выбор", + ui_text_example = "Переведен", +} + + +local data = en + function M.get_locale(lang_id) return data[lang_id] or lang_id end + +function M.toggle_locale() + data = data == en and ru or en + msg.post("/gui#main", const.ON_CHANGE_LANGUAGE) +end + return M \ No newline at end of file diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 30acacf..f27689c 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -1,5 +1,8 @@ +local lang = require("example.kenney.lang") + local M = {} + local function empty_callback(self, param) print("Empty callback. Param", param) end @@ -14,16 +17,30 @@ end local function setup_button(self) - self.druid:new_button("button_simple", empty_callback, "button_param") + self.druid:new_button("button_simple", lang.toggle_locale, "button_param") self.druid:new_button("button_template/button", empty_callback, "button_param") end +local function setup_texts(self) + self.druid:new_text("text_button", "ui_section_button", true) + self.druid:new_text("text_text", "ui_section_text", true) + self.druid:new_text("text_timer", "ui_section_timer", true) + self.druid:new_text("text_progress", "ui_section_progress", true) + self.druid:new_text("text_slider", "ui_section_slider", true) + self.druid:new_text("text_radio", "ui_section_radio", true) + self.druid:new_text("text_checkbox", "ui_section_checkbox", true) + + self.druid:new_text("text_simple", "Simple") + self.druid:new_text("text_translated", "ui_text_example", true) +end + + local function setup_progress(self) local progress = self.druid:new_progress("progress_fill", "x", 0.4) random_progress(progress, gui.get_node("text_progress")) timer.delay(2, true, function() - random_progress(progress, gui.get_node("text_progress")) + random_progress(progress, gui.get_node("text_progress_amount")) end) end @@ -40,14 +57,12 @@ local function setup_grid(self) end, i) self.druid:new_text(nodes["button_template/text"], "Grid"..i) grid:add(root) - - end end local function setup_timer(self) - self.timer = self.druid:new_timer("text_timer", 120, 0, empty_callback) + self.timer = self.druid:new_timer("timer", 300, 0, empty_callback) end @@ -63,6 +78,8 @@ end function M.setup_page(self) + setup_texts(self) + setup_button(self) setup_progress(self) setup_grid(self) diff --git a/example/kenney/templates/checkbox.gui b/example/kenney/templates/checkbox.gui new file mode 100644 index 0000000..393adbe --- /dev/null +++ b/example/kenney/templates/checkbox.gui @@ -0,0 +1,123 @@ +script: "" +textures { + name: "kenney" + texture: "/example/kenney/assets/images/kenney.atlas" +} +background_color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 +} +nodes { + position { + x: 0.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: 38.0 + y: 36.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: "kenney/check_back_square" + id: "back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: 0.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: 21.0 + y: 20.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: "kenney/checkmark" + id: "check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "back" + 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/kenney/templates/radio.gui b/example/kenney/templates/radio.gui new file mode 100644 index 0000000..eef5fa2 --- /dev/null +++ b/example/kenney/templates/radio.gui @@ -0,0 +1,123 @@ +script: "" +textures { + name: "kenney" + texture: "/example/kenney/assets/images/kenney.atlas" +} +background_color { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 +} +nodes { + position { + x: 0.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: 36.0 + y: 36.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: "kenney/check_back_circle" + id: "back" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + 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: -0.5 + y: 0.5 + 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: 17.0 + y: 17.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: "kenney/tick" + id: "check" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "back" + 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 From 6f37a1ec9aecfe5d69fc6b7ae79064345aecd74a Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 25 Sep 2019 23:46:37 +0300 Subject: [PATCH 052/136] change lang button --- example/kenney/gui/main/main.gui | 63 ++++++++++++++++++++++++++++++++ example/kenney/lang.lua | 2 + example/kenney/page/main.lua | 1 + 3 files changed, 66 insertions(+) diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index ebfca92..f42e680 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -563,6 +563,69 @@ nodes { template_node_child: false size_mode: SIZE_MODE_MANUAL } +nodes { + position { + x: 0.0 + y: 5.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 150.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Change Lang" + font: "game" + id: "text_button_lang" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: true + parent: "button_simple" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 0.8 + text_tracking: 0.0 +} nodes { position { x: 0.0 diff --git a/example/kenney/lang.lua b/example/kenney/lang.lua index 00ca698..d36cef7 100644 --- a/example/kenney/lang.lua +++ b/example/kenney/lang.lua @@ -12,6 +12,7 @@ local en = { ui_section_radio = "Radio", ui_section_checkbox = "Checkbox", ui_text_example = "Translated", + ui_text_change_lang = "Change lang", } local ru = { @@ -24,6 +25,7 @@ local ru = { ui_section_radio = "Выбор", ui_section_checkbox = "Мн. выбор", ui_text_example = "Переведен", + ui_text_change_lang = "Сменить язык", } diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index f27689c..fdbab01 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -33,6 +33,7 @@ local function setup_texts(self) self.druid:new_text("text_simple", "Simple") self.druid:new_text("text_translated", "ui_text_example", true) + self.druid:new_text("text_button_lang", "ui_text_change_lang", true, 150 * 0.7) end From 7917a08f5c347d7ecd6db77e1212de8994a4e567 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:03:53 +0300 Subject: [PATCH 053/136] add simple checkbox component --- druid/base/checkbox.lua | 44 ++++++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + example/kenney/page/main.lua | 11 +++++++++ 3 files changed, 56 insertions(+) create mode 100644 druid/base/checkbox.lua diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua new file mode 100644 index 0000000..cf149ff --- /dev/null +++ b/druid/base/checkbox.lua @@ -0,0 +1,44 @@ +--- Druid checkbox component +-- @module base.checkbox + +local helper = require("druid.helper") + +local M = {} + + +local function state_animate(node, state) + local target = state and 1 or 0 + gui.animate(node, "color.w", target, gui.EASING_OUTSINE, 0.1) +end + + +function M.set_state(self, state, is_silence) + if self.state == state then + return + end + + self.state = state + state_animate(self.node, state) + + if not is_silence and self.callback then + self.callback(self.parent.parent, state) + end +end + + +-- TODO: pass self as first parameter +local function on_click(context, self) + M.set_state(self, not self.state) +end + + +function M.init(self, node, callback, click_node) + self.node = helper.get_node(node) + self.click_node = helper.get_node(click_node) + self.callback = callback + self.button = self.parent:new_button(self.click_node or self.node, on_click, self) + M.set_state(self, false, true) +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index f271681..0c84d06 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -22,6 +22,7 @@ M.comps = { progress = require("druid.base.progress"), grid = require("druid.base.grid"), scroll = require("druid.base.scroll"), + checkbox = require("druid.base.checkbox"), progress_rich = require("druid.rich.progress_rich"), } diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index fdbab01..e5c84c4 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -62,6 +62,16 @@ local function setup_grid(self) end +local function setup_checkbox(self) + self.druid:new_checkbox("radio1/check", nil, "radio1/back") + self.druid:new_checkbox("radio2/check", nil, "radio2/back") + self.druid:new_checkbox("radio3/check", nil, "radio3/back") + self.druid:new_checkbox("checkbox1/check", nil, "checkbox1/back") + self.druid:new_checkbox("checkbox2/check", nil, "checkbox2/back") + self.druid:new_checkbox("checkbox3/check", nil, "checkbox3/back") +end + + local function setup_timer(self) self.timer = self.druid:new_timer("timer", 300, 0, empty_callback) end @@ -85,6 +95,7 @@ function M.setup_page(self) setup_progress(self) setup_grid(self) setup_timer(self) + setup_checkbox(self) setup_scroll(self) setup_back_handler(self) end From 6cebc9d0c9dd32ef3029687d4de53e4e9e8ddcc9 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:27:27 +0300 Subject: [PATCH 054/136] add simple slider component --- druid/base/slider.lua | 82 ++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + example/kenney/gui/main/main.gui | 63 ++++++++++++++++++++++++ example/kenney/page/main.lua | 16 +++++-- 4 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 druid/base/slider.lua diff --git a/druid/base/slider.lua b/druid/base/slider.lua new file mode 100644 index 0000000..0caa56f --- /dev/null +++ b/druid/base/slider.lua @@ -0,0 +1,82 @@ +--- Druid slider component +-- @module base.slider + +local helper = require("druid.helper") +local const = require("druid.const") + +local M = {} +M.interest = { + const.ON_SWIPE +} + + +local function on_change_value(self) + if self.callback then + self.callback(self.parent.parent, self.value) + end +end + + +function M.init(self, node, end_pos, callback) + self.node = helper.get_node(node) + + self.start_pos = gui.get_position(self.node) + self.pos = gui.get_position(self.node) + self.target_pos = self.pos + self.end_pos = end_pos + + self.dist = self.end_pos - self.start_pos + self.is_drag = false + self.value = 0 + self.callback = callback + + assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal") +end + + +function M.on_input(self, action_id, action) + if action_id ~= const.ACTION_TOUCH 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) + self.is_drag = true + end + end + + if self.is_drag and not action.pressed then + -- move + self.pos.x = self.pos.x + action.dx + self.pos.y = self.pos.y + action.dy + + local prev_x = self.target_pos.x + local prev_y = self.target_pos.y + + self.target_pos.x = helper.clamp(self.pos.x, self.start_pos.x, self.end_pos.x) + self.target_pos.y = helper.clamp(self.pos.y, self.start_pos.y, self.end_pos.y) + + gui.set_position(self.node, self.target_pos) + + if prev_x ~= self.target_pos.x or prev_y ~= self.target_pos.y then + + if 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 + self.value = (self.target_pos.y - self.start_pos.y) / self.dist.y + end + + on_change_value(self) + end + end + + if action.released then + self.is_drag = false + end +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index 0c84d06..4cc5fc7 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -22,6 +22,7 @@ M.comps = { progress = require("druid.base.progress"), grid = require("druid.base.grid"), scroll = require("druid.base.scroll"), + slider = require("druid.base.slider"), checkbox = require("druid.base.checkbox"), progress_rich = require("druid.rich.progress_rich"), diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index f42e680..e92b20c 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -1570,6 +1570,69 @@ nodes { template_node_child: false size_mode: SIZE_MODE_AUTO } +nodes { + position { + x: 0.0 + y: 20.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 100.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "50%" + font: "game" + id: "text_progress_slider" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "slider_back" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} nodes { position { x: 0.0 diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index e5c84c4..7a63600 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -11,7 +11,7 @@ end local function random_progress(progress, text) local rnd = math.random() - gui.set_text(text, math.ceil(rnd * 100)) + gui.set_text(text, math.ceil(rnd * 100) .. "%") progress:to(rnd) end @@ -38,10 +38,10 @@ end local function setup_progress(self) - local progress = self.druid:new_progress("progress_fill", "x", 0.4) - random_progress(progress, gui.get_node("text_progress")) + self.progress = self.druid:new_progress("progress_fill", "x", 0.4) + random_progress(self.progress, gui.get_node("text_progress")) timer.delay(2, true, function() - random_progress(progress, gui.get_node("text_progress_amount")) + random_progress(self.progress, gui.get_node("text_progress_amount")) end) end @@ -62,6 +62,13 @@ local function setup_grid(self) end +local function setup_slider(self) + self.druid:new_slider("slider_pin", vmath.vector3(95, 0, 0), function(_, value) + gui.set_text(gui.get_node("text_progress_slider"), math.ceil(value * 100) .. "%") + end) +end + + local function setup_checkbox(self) self.druid:new_checkbox("radio1/check", nil, "radio1/back") self.druid:new_checkbox("radio2/check", nil, "radio2/back") @@ -97,6 +104,7 @@ function M.setup_page(self) setup_timer(self) setup_checkbox(self) setup_scroll(self) + setup_slider(self) setup_back_handler(self) end From c048224a1f4f48ed33cb6a9cabfb1b63a40ca24b Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:46:42 +0300 Subject: [PATCH 055/136] add checkbox group component --- druid/base/checkbox.lua | 6 +++++ druid/base/checkbox_group.lua | 47 +++++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + example/kenney/page/main.lua | 15 ++++++----- 4 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 druid/base/checkbox_group.lua diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index cf149ff..0b3dbb2 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -26,6 +26,11 @@ function M.set_state(self, state, is_silence) end +function M.get_state(self) + return self.state +end + + -- TODO: pass self as first parameter local function on_click(context, self) M.set_state(self, not self.state) @@ -36,6 +41,7 @@ function M.init(self, node, callback, click_node) self.node = helper.get_node(node) self.click_node = helper.get_node(click_node) self.callback = callback + self.button = self.parent:new_button(self.click_node or self.node, on_click, self) M.set_state(self, false, true) end diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua new file mode 100644 index 0000000..459527e --- /dev/null +++ b/druid/base/checkbox_group.lua @@ -0,0 +1,47 @@ +local M = {} + + +local function on_checkbox_click(self, index) + if self.is_radio_mode then + for i = 1, #self.checkboxes do + self.checkboxes[i]:set_state(i == index, true) + end + end +end + + +function M.set_state(self, indexes) + for i = 1, #indexes do + if self.checkbox[indexes[i]] then + self.checkbox[indexes[i]]:set_state(true, true) + end + end +end + + +function M.get_state(self) + local result = {} + + for i = 1, #self.checkboxes do + table.insert(result, self.checkboxes[i]:get_state()) + end + + return result +end + + +function M.init(self, nodes, callback, is_radio_mode, anim_nodes) + self.is_radio_mode = is_radio_mode + self.checkboxes = {} + + for i = 1, #nodes do + local anim_node = anim_nodes and anim_nodes[i] or nil + local checkbox = self.parent:new_checkbox(nodes[i], function() + on_checkbox_click(self, i) + end, anim_node) + table.insert(self.checkboxes, checkbox) + end +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index 4cc5fc7..8077ba8 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -24,6 +24,7 @@ M.comps = { scroll = require("druid.base.scroll"), slider = require("druid.base.slider"), checkbox = require("druid.base.checkbox"), + checkbox_group = require("druid.base.checkbox_group"), progress_rich = require("druid.rich.progress_rich"), } diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 7a63600..27e2da7 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -70,12 +70,15 @@ end local function setup_checkbox(self) - self.druid:new_checkbox("radio1/check", nil, "radio1/back") - self.druid:new_checkbox("radio2/check", nil, "radio2/back") - self.druid:new_checkbox("radio3/check", nil, "radio3/back") - self.druid:new_checkbox("checkbox1/check", nil, "checkbox1/back") - self.druid:new_checkbox("checkbox2/check", nil, "checkbox2/back") - self.druid:new_checkbox("checkbox3/check", nil, "checkbox3/back") + self.druid:new_checkbox_group( + {"radio1/check", "radio2/check", "radio3/check" }, + nil, true, + {"radio1/back", "radio2/back", "radio3/back"}) + + self.druid:new_checkbox_group( + {"checkbox1/check", "checkbox2/check", "checkbox3/check" }, + nil, false, + {"checkbox1/back", "checkbox2/back", "checkbox3/back"}) end From 14e0680f2f8c825abc985047f35c209a21c2e036 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:52:29 +0300 Subject: [PATCH 056/136] updates in new components --- druid/base/checkbox_group.lua | 4 ++-- druid/base/slider.lua | 11 +++++++++++ example/kenney/page/main.lua | 15 ++++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 459527e..92a18a6 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -12,8 +12,8 @@ end function M.set_state(self, indexes) for i = 1, #indexes do - if self.checkbox[indexes[i]] then - self.checkbox[indexes[i]]:set_state(true, true) + if self.checkboxes[i] then + self.checkboxes[i]:set_state(indexes[i], true) end end end diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 0caa56f..ff2881f 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -76,6 +76,17 @@ function M.on_input(self, action_id, action) if action.released then self.is_drag = false end + + return self.is_drag +end + + +function M.set(self, value) + value = helper.clamp(value, 0, 1) + + gui.set_position(self.node, self.start_pos + self.dist * value) + self.value = value + on_change_value(self) end diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 27e2da7..b597021 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -63,22 +63,27 @@ end local function setup_slider(self) - self.druid:new_slider("slider_pin", vmath.vector3(95, 0, 0), function(_, value) + local slider = self.druid:new_slider("slider_pin", vmath.vector3(95, 0, 0), function(_, value) gui.set_text(gui.get_node("text_progress_slider"), math.ceil(value * 100) .. "%") end) + + slider:set(0.2) end local function setup_checkbox(self) - self.druid:new_checkbox_group( - {"radio1/check", "radio2/check", "radio3/check" }, + local group1 = self.druid:new_checkbox_group( + {"radio1/check", "radio2/check", "radio3/check"}, nil, true, {"radio1/back", "radio2/back", "radio3/back"}) - self.druid:new_checkbox_group( - {"checkbox1/check", "checkbox2/check", "checkbox3/check" }, + local group2 = self.druid:new_checkbox_group( + {"checkbox1/check", "checkbox2/check", "checkbox3/check"}, nil, false, {"checkbox1/back", "checkbox2/back", "checkbox3/back"}) + + group1:set_state({false, false, true}) + group2:set_state({true, false, true}) end From 39b5f1c5551093f3e369d87801beb048b919ff1a Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:35:19 +0300 Subject: [PATCH 057/136] update collection to 162 defold --- .gitignore | 3 ++- example/kenney/kenney.collection | 11 +++++++++-- settings_deployer | 2 ++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 settings_deployer diff --git a/.gitignore b/.gitignore index a32d29f..fb6af1f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ Thumbs.db *.pyc .project .cproject -builtins \ No newline at end of file +builtins +dist diff --git a/example/kenney/kenney.collection b/example/kenney/kenney.collection index 3b0225f..3f630ff 100644 --- a/example/kenney/kenney.collection +++ b/example/kenney/kenney.collection @@ -72,9 +72,16 @@ embedded_instances { } embedded_instances { id: "sound" - data: "components {\n" + data: "embedded_components {\n" " id: \"click\"\n" - " component: \"/example/kenney/assets/sounds/click.ogg\"\n" + " type: \"sound\"\n" + " data: \"sound: \\\"/example/kenney/assets/sounds/click.ogg\\\"\\n" + "looping: 0\\n" + "group: \\\"master\\\"\\n" + "gain: 1.0\\n" + "pan: 0.0\\n" + "speed: 1.0\\n" + "\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" diff --git a/settings_deployer b/settings_deployer new file mode 100644 index 0000000..5625ee7 --- /dev/null +++ b/settings_deployer @@ -0,0 +1,2 @@ +#!/bin/bash +use_latest_bob=true From ae9c580c7a80321efe1f2dc3aefcafa095531f4c Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:45:58 +0300 Subject: [PATCH 058/136] update checkbox_group component --- druid/base/checkbox_group.lua | 18 ++++++++++-------- example/kenney/page/main.lua | 6 +++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 92a18a6..3d8de6c 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,11 +1,12 @@ +--- Checkboux group module +-- @module base.checkbox_group + local M = {} local function on_checkbox_click(self, index) - if self.is_radio_mode then - for i = 1, #self.checkboxes do - self.checkboxes[i]:set_state(i == index, true) - end + if self.callback then + self.callback(self.parent.parent, index) end end @@ -30,15 +31,16 @@ function M.get_state(self) end -function M.init(self, nodes, callback, is_radio_mode, anim_nodes) - self.is_radio_mode = is_radio_mode +function M.init(self, nodes, callback, click_nodes) self.checkboxes = {} + self.callback = callback for i = 1, #nodes do - local anim_node = anim_nodes and anim_nodes[i] or nil + local click_node = click_nodes and click_nodes[i] or nil local checkbox = self.parent:new_checkbox(nodes[i], function() on_checkbox_click(self, i) - end, anim_node) + end, click_node) + table.insert(self.checkboxes, checkbox) end end diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index b597021..f7c198e 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -77,13 +77,13 @@ local function setup_checkbox(self) nil, true, {"radio1/back", "radio2/back", "radio3/back"}) - local group2 = self.druid:new_checkbox_group( + local checkbox_group = self.druid:new_checkbox_group( {"checkbox1/check", "checkbox2/check", "checkbox3/check"}, - nil, false, + nil, {"checkbox1/back", "checkbox2/back", "checkbox3/back"}) group1:set_state({false, false, true}) - group2:set_state({true, false, true}) + checkbox_group:set_state({true, false, true}) end From 4a2458ca3b5017104cda30f88b65d284cce54bce Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:46:12 +0300 Subject: [PATCH 059/136] add radio_group component --- druid/base/radio_group.lua | 52 ++++++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + example/kenney/page/main.lua | 6 ++--- 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 druid/base/radio_group.lua diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua new file mode 100644 index 0000000..25e74b6 --- /dev/null +++ b/druid/base/radio_group.lua @@ -0,0 +1,52 @@ +--- Radio group module +-- @module base.checkbox_group + +local M = {} + + +local function on_checkbox_click(self, index) + for i = 1, #self.checkboxes do + self.checkboxes[i]:set_state(i == index, true) + end + + if self.callback then + self.callback(self.parent.parent, index) + end +end + + +function M.set_state(self, index) + on_checkbox_click(self, index) +end + + +function M.get_state(self) + local result = -1 + + for i = 1, #self.checkboxes do + if self.checkboxes[i]:get_state() then + result = i + break + end + end + + return result +end + + +function M.init(self, nodes, callback, click_nodes) + self.checkboxes = {} + self.callback = callback + + for i = 1, #nodes do + local click_node = click_nodes and click_nodes[i] or nil + local checkbox = self.parent:new_checkbox(nodes[i], function() + on_checkbox_click(self, i) + end, click_node) + + table.insert(self.checkboxes, checkbox) + end +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index 8077ba8..a7404a6 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -25,6 +25,7 @@ M.comps = { slider = require("druid.base.slider"), checkbox = require("druid.base.checkbox"), checkbox_group = require("druid.base.checkbox_group"), + radio_group = require("druid.base.radio_group"), progress_rich = require("druid.rich.progress_rich"), } diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index f7c198e..7c00641 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -72,9 +72,9 @@ end local function setup_checkbox(self) - local group1 = self.druid:new_checkbox_group( + local radio_group = self.druid:new_radio_group( {"radio1/check", "radio2/check", "radio3/check"}, - nil, true, + nil, {"radio1/back", "radio2/back", "radio3/back"}) local checkbox_group = self.druid:new_checkbox_group( @@ -82,7 +82,7 @@ local function setup_checkbox(self) nil, {"checkbox1/back", "checkbox2/back", "checkbox3/back"}) - group1:set_state({false, false, true}) + radio_group:set_state(2) checkbox_group:set_state({true, false, true}) end From 78807d7c8d94a3cbce87b28b9c42227821dff7ca Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:53:47 +0300 Subject: [PATCH 060/136] add simple blocker component --- druid/base/blocker.lua | 33 +++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + 2 files changed, 34 insertions(+) create mode 100644 druid/base/blocker.lua diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua new file mode 100644 index 0000000..14f3fc2 --- /dev/null +++ b/druid/base/blocker.lua @@ -0,0 +1,33 @@ +--- Component to block input on specify zone (node) +-- @module base.blocker + +local const = require("druid.const") +local helper = require("druid.helper") + + +local M = {} +M.interest = { + const.ON_SWIPE +} + + +function M.init(self, node) + self.node = helper.get_node(node) + self.event = const.ACTION_TOUCH +end + + +function M.on_input(self, action_id, action) + if not helper.is_enabled(self.node) then + return false + end + + if gui.pick_node(self.node, action.x, action.y) then + return true + end + + return false +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index a7404a6..f5b7c87 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -16,6 +16,7 @@ local _fct_metatable = {} --- Basic components M.comps = { button = require("druid.base.button"), + blocker = require("druid.base.blocker"), back_handler = require("druid.base.back_handler"), text = require("druid.base.text"), timer = require("druid.base.timer"), From 27e0397e6b4e79e131c474522b28796a5bb2644a Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:03:53 +0300 Subject: [PATCH 061/136] cherry-pick simple-checkbox component --- druid/base/checkbox.lua | 44 +++++++++++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + 2 files changed, 45 insertions(+) create mode 100644 druid/base/checkbox.lua diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua new file mode 100644 index 0000000..cf149ff --- /dev/null +++ b/druid/base/checkbox.lua @@ -0,0 +1,44 @@ +--- Druid checkbox component +-- @module base.checkbox + +local helper = require("druid.helper") + +local M = {} + + +local function state_animate(node, state) + local target = state and 1 or 0 + gui.animate(node, "color.w", target, gui.EASING_OUTSINE, 0.1) +end + + +function M.set_state(self, state, is_silence) + if self.state == state then + return + end + + self.state = state + state_animate(self.node, state) + + if not is_silence and self.callback then + self.callback(self.parent.parent, state) + end +end + + +-- TODO: pass self as first parameter +local function on_click(context, self) + M.set_state(self, not self.state) +end + + +function M.init(self, node, callback, click_node) + self.node = helper.get_node(node) + self.click_node = helper.get_node(click_node) + self.callback = callback + self.button = self.parent:new_button(self.click_node or self.node, on_click, self) + M.set_state(self, false, true) +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index ad3618c..93c0100 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -15,6 +15,7 @@ M.comps = { progress = require("druid.base.progress"), grid = require("druid.base.grid"), scroll = require("druid.base.scroll"), + checkbox = require("druid.base.checkbox"), progress_rich = require("druid.rich.progress_rich"), } From 2d3ef5f6c3690b40b4c8bfb96b9765db8ccabe26 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:46:42 +0300 Subject: [PATCH 062/136] cherry-pick checkbox_group component --- druid/base/checkbox.lua | 6 +++++ druid/base/checkbox_group.lua | 47 +++++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + 3 files changed, 54 insertions(+) create mode 100644 druid/base/checkbox_group.lua diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index cf149ff..0b3dbb2 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -26,6 +26,11 @@ function M.set_state(self, state, is_silence) end +function M.get_state(self) + return self.state +end + + -- TODO: pass self as first parameter local function on_click(context, self) M.set_state(self, not self.state) @@ -36,6 +41,7 @@ function M.init(self, node, callback, click_node) self.node = helper.get_node(node) self.click_node = helper.get_node(click_node) self.callback = callback + self.button = self.parent:new_button(self.click_node or self.node, on_click, self) M.set_state(self, false, true) end diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua new file mode 100644 index 0000000..459527e --- /dev/null +++ b/druid/base/checkbox_group.lua @@ -0,0 +1,47 @@ +local M = {} + + +local function on_checkbox_click(self, index) + if self.is_radio_mode then + for i = 1, #self.checkboxes do + self.checkboxes[i]:set_state(i == index, true) + end + end +end + + +function M.set_state(self, indexes) + for i = 1, #indexes do + if self.checkbox[indexes[i]] then + self.checkbox[indexes[i]]:set_state(true, true) + end + end +end + + +function M.get_state(self) + local result = {} + + for i = 1, #self.checkboxes do + table.insert(result, self.checkboxes[i]:get_state()) + end + + return result +end + + +function M.init(self, nodes, callback, is_radio_mode, anim_nodes) + self.is_radio_mode = is_radio_mode + self.checkboxes = {} + + for i = 1, #nodes do + local anim_node = anim_nodes and anim_nodes[i] or nil + local checkbox = self.parent:new_checkbox(nodes[i], function() + on_checkbox_click(self, i) + end, anim_node) + table.insert(self.checkboxes, checkbox) + end +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index 93c0100..dad7c05 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -16,6 +16,7 @@ M.comps = { grid = require("druid.base.grid"), scroll = require("druid.base.scroll"), checkbox = require("druid.base.checkbox"), + checkbox_group = require("druid.base.checkbox_group"), progress_rich = require("druid.rich.progress_rich"), } From 05dd08b14916d15dbc03967bf5b20084f9c49f99 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:45:58 +0300 Subject: [PATCH 063/136] cherry-pick update checkbox_group --- druid/base/checkbox_group.lua | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 459527e..5510a5f 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,11 +1,12 @@ +--- Checkboux group module +-- @module base.checkbox_group + local M = {} local function on_checkbox_click(self, index) - if self.is_radio_mode then - for i = 1, #self.checkboxes do - self.checkboxes[i]:set_state(i == index, true) - end + if self.callback then + self.callback(self.parent.parent, index) end end @@ -30,15 +31,16 @@ function M.get_state(self) end -function M.init(self, nodes, callback, is_radio_mode, anim_nodes) - self.is_radio_mode = is_radio_mode +function M.init(self, nodes, callback, click_nodes) self.checkboxes = {} + self.callback = callback for i = 1, #nodes do - local anim_node = anim_nodes and anim_nodes[i] or nil + local click_node = click_nodes and click_nodes[i] or nil local checkbox = self.parent:new_checkbox(nodes[i], function() on_checkbox_click(self, i) - end, anim_node) + end, click_node) + table.insert(self.checkboxes, checkbox) end end From 3fe8c1157aeead95bb67979ac05b3fa61e3cde9c Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:46:12 +0300 Subject: [PATCH 064/136] #20 radio_group component (based on checkbox) --- druid/base/radio_group.lua | 52 ++++++++++++++++++++++++++++++++++++++ druid/druid.lua | 2 ++ 2 files changed, 54 insertions(+) create mode 100644 druid/base/radio_group.lua diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua new file mode 100644 index 0000000..25e74b6 --- /dev/null +++ b/druid/base/radio_group.lua @@ -0,0 +1,52 @@ +--- Radio group module +-- @module base.checkbox_group + +local M = {} + + +local function on_checkbox_click(self, index) + for i = 1, #self.checkboxes do + self.checkboxes[i]:set_state(i == index, true) + end + + if self.callback then + self.callback(self.parent.parent, index) + end +end + + +function M.set_state(self, index) + on_checkbox_click(self, index) +end + + +function M.get_state(self) + local result = -1 + + for i = 1, #self.checkboxes do + if self.checkboxes[i]:get_state() then + result = i + break + end + end + + return result +end + + +function M.init(self, nodes, callback, click_nodes) + self.checkboxes = {} + self.callback = callback + + for i = 1, #nodes do + local click_node = click_nodes and click_nodes[i] or nil + local checkbox = self.parent:new_checkbox(nodes[i], function() + on_checkbox_click(self, i) + end, click_node) + + table.insert(self.checkboxes, checkbox) + end +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index ad3618c..24795d3 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -15,6 +15,8 @@ M.comps = { progress = require("druid.base.progress"), grid = require("druid.base.grid"), scroll = require("druid.base.scroll"), + checkbox = require("druid.base.checkbox"), + radio_group = require("druid.base.radio_group"), progress_rich = require("druid.rich.progress_rich"), } From 12049adf27177ab173c0acc902ed5f6a9d8feda3 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 08:53:47 +0300 Subject: [PATCH 065/136] #24 cherry-pick, add simple blocker component --- druid/base/blocker.lua | 33 +++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + 2 files changed, 34 insertions(+) create mode 100644 druid/base/blocker.lua diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua new file mode 100644 index 0000000..14f3fc2 --- /dev/null +++ b/druid/base/blocker.lua @@ -0,0 +1,33 @@ +--- Component to block input on specify zone (node) +-- @module base.blocker + +local const = require("druid.const") +local helper = require("druid.helper") + + +local M = {} +M.interest = { + const.ON_SWIPE +} + + +function M.init(self, node) + self.node = helper.get_node(node) + self.event = const.ACTION_TOUCH +end + + +function M.on_input(self, action_id, action) + if not helper.is_enabled(self.node) then + return false + end + + if gui.pick_node(self.node, action.x, action.y) then + return true + end + + return false +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index ad3618c..1b3b50c 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -9,6 +9,7 @@ local _fct_metatable = {} M.comps = { button = require("druid.base.button"), + blocker = require("druid.base.blocker"), android_back = require("druid.base.android_back"), text = require("druid.base.text"), timer = require("druid.base.timer"), From dc3d311236ef5197b531c4ed366bb38106e75fa2 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:27:27 +0300 Subject: [PATCH 066/136] #25 cherry-pick slider component --- druid/base/slider.lua | 82 +++++++++++++++++++++++++++++++++++++++++++ druid/druid.lua | 1 + 2 files changed, 83 insertions(+) create mode 100644 druid/base/slider.lua diff --git a/druid/base/slider.lua b/druid/base/slider.lua new file mode 100644 index 0000000..0caa56f --- /dev/null +++ b/druid/base/slider.lua @@ -0,0 +1,82 @@ +--- Druid slider component +-- @module base.slider + +local helper = require("druid.helper") +local const = require("druid.const") + +local M = {} +M.interest = { + const.ON_SWIPE +} + + +local function on_change_value(self) + if self.callback then + self.callback(self.parent.parent, self.value) + end +end + + +function M.init(self, node, end_pos, callback) + self.node = helper.get_node(node) + + self.start_pos = gui.get_position(self.node) + self.pos = gui.get_position(self.node) + self.target_pos = self.pos + self.end_pos = end_pos + + self.dist = self.end_pos - self.start_pos + self.is_drag = false + self.value = 0 + self.callback = callback + + assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal") +end + + +function M.on_input(self, action_id, action) + if action_id ~= const.ACTION_TOUCH 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) + self.is_drag = true + end + end + + if self.is_drag and not action.pressed then + -- move + self.pos.x = self.pos.x + action.dx + self.pos.y = self.pos.y + action.dy + + local prev_x = self.target_pos.x + local prev_y = self.target_pos.y + + self.target_pos.x = helper.clamp(self.pos.x, self.start_pos.x, self.end_pos.x) + self.target_pos.y = helper.clamp(self.pos.y, self.start_pos.y, self.end_pos.y) + + gui.set_position(self.node, self.target_pos) + + if prev_x ~= self.target_pos.x or prev_y ~= self.target_pos.y then + + if 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 + self.value = (self.target_pos.y - self.start_pos.y) / self.dist.y + end + + on_change_value(self) + end + end + + if action.released then + self.is_drag = false + end +end + + +return M diff --git a/druid/druid.lua b/druid/druid.lua index ad3618c..c8a744a 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -15,6 +15,7 @@ M.comps = { progress = require("druid.base.progress"), grid = require("druid.base.grid"), scroll = require("druid.base.scroll"), + slider = require("druid.base.slider"), progress_rich = require("druid.rich.progress_rich"), } From 2abfe8b0d4bb86a33935fdcd280d4ff7f102b137 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 26 Sep 2019 00:52:29 +0300 Subject: [PATCH 067/136] #25 cherry-pick, update slider component --- druid/base/slider.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 0caa56f..ff2881f 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -76,6 +76,17 @@ function M.on_input(self, action_id, action) if action.released then self.is_drag = false end + + return self.is_drag +end + + +function M.set(self, value) + value = helper.clamp(value, 0, 1) + + gui.set_position(self.node, self.start_pos + self.dist * value) + self.value = value + on_change_value(self) end From e45dce150d3b76c693eb636c982a9c2ce5b67541 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 21:34:16 +0300 Subject: [PATCH 068/136] Rename helper.get_node -> helper.node --- druid/base/blocker.lua | 2 +- druid/base/button.lua | 6 +++--- druid/base/checkbox.lua | 4 ++-- druid/base/grid.lua | 4 ++-- druid/base/progress.lua | 2 +- druid/base/scroll.lua | 4 ++-- druid/base/slider.lua | 2 +- druid/base/text.lua | 2 +- druid/base/timer.lua | 2 +- druid/helper.lua | 6 ++++-- 10 files changed, 18 insertions(+), 16 deletions(-) diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 14f3fc2..4212ec4 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -12,7 +12,7 @@ M.interest = { function M.init(self, node) - self.node = helper.get_node(node) + self.node = helper.node(node) self.event = const.ACTION_TOUCH end diff --git a/druid/base/button.lua b/druid/base/button.lua index 2f87afd..80b519d 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -23,9 +23,9 @@ M.DEFAULT_ACTIVATION_TIME = 0.2 function M.init(self, node, callback, params, anim_node, event) - self.node = helper.get_node(node) + self.node = helper.node(node) self.event = const.ACTION_TOUCH - self.anim_node = anim_node and helper.get_node(anim_node) or self.node + self.anim_node = anim_node and helper.node(anim_node) or self.node self.scale_from = gui.get_scale(self.anim_node) self.scale_to = self.scale_from + b_settings.SCALE_CHANGE self.scale_hover_to = self.scale_from + b_settings.HOVER_SCALE @@ -207,7 +207,7 @@ end --- Set additional node, what need to be clicked on button click -- Used, if need setup, what button can be clicked only in special zone function M.set_click_zone(self, zone) - self.click_zone = helper.get_node(zone) + self.click_zone = helper.node(zone) end diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 0b3dbb2..d7290d2 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -38,8 +38,8 @@ end function M.init(self, node, callback, click_node) - self.node = helper.get_node(node) - self.click_node = helper.get_node(click_node) + self.node = helper.node(node) + self.click_node = helper.node(click_node) self.callback = callback self.button = self.parent:new_button(self.click_node or self.node, on_click, self) diff --git a/druid/base/grid.lua b/druid/base/grid.lua index acdfcbd..e47e69e 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -8,13 +8,13 @@ local M = {} function M.init(self, parent, element, in_row) - self.parent = helper.get_node(parent) + self.parent = helper.node(parent) self.nodes = {} self.offset = vmath.vector3(0) self.anchor = vmath.vector3(0.5, 0, 0) self.in_row = in_row or 1 - self.node_size = gui.get_size(helper.get_node(element)) + self.node_size = gui.get_size(helper.node(element)) self.border = vmath.vector4(0) self.border_offset = vmath.vector3(0) end diff --git a/druid/base/progress.lua b/druid/base/progress.lua index d8cc122..b574350 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -25,7 +25,7 @@ function M.init(self, name, key, init_value) self.prop = hash("scale."..key) self.key = key - self.node = helper.get_node(name) + self.node = helper.node(name) self.scale = gui.get_scale(self.node) self.size = gui.get_size(self.node) self.max_size = self.size[self.key] diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 622b18d..f4c4bf7 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -20,8 +20,8 @@ M.current_scroll = nil function M.init(self, scroll_parent, input_zone, border) - self.node = helper.get_node(scroll_parent) - self.input_zone = helper.get_node(input_zone) + self.node = helper.node(scroll_parent) + self.input_zone = helper.node(input_zone) self.zone_size = gui.get_size(self.input_zone) self.soft_size = settings.SOFT_ZONE_SIZE diff --git a/druid/base/slider.lua b/druid/base/slider.lua index ff2881f..29f25c0 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -18,7 +18,7 @@ end function M.init(self, node, end_pos, callback) - self.node = helper.get_node(node) + self.node = helper.node(node) self.start_pos = gui.get_position(self.node) self.pos = gui.get_position(self.node) diff --git a/druid/base/text.lua b/druid/base/text.lua index b3fbe0a..7405b67 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -14,7 +14,7 @@ M.interest = { function M.init(self, node, value, is_locale, max_width) self.max_width = max_width - self.node = helper.get_node(node) + self.node = helper.node(node) self.start_scale = gui.get_scale(self.node) self.scale = self.start_scale self.last_color = gui.get_color(self.node) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 2ab6cb7..9f7210e 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -14,7 +14,7 @@ local empty = function() end function M.init(self, node, seconds_from, seconds_to, callback) - self.node = helper.get_node(node) + self.node = helper.node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) callback = callback or empty diff --git a/druid/helper.lua b/druid/helper.lua index 1ef342f..2aaea67 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,6 +1,8 @@ --- Druid helper module -- @module helper +local const = require("druid.const") + local M = {} --- Text node or icon node can be nil @@ -80,8 +82,8 @@ end local STRING = "string" -function M.get_node(node_or_name) - if type(node_or_name) == STRING then +function M.node(node_or_name) + if type(node_or_name) == const.STRING then return gui.get_node(node_or_name) end return node_or_name From f8a3b6f632eb734bae6bd07ec5759d8bede26339 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 21:34:26 +0300 Subject: [PATCH 069/136] Move const to const.lua --- druid/const.lua | 15 ++++++++++++++- druid/druid.lua | 4 ++-- druid/helper.lua | 14 +------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/druid/const.lua b/druid/const.lua index eb870dd..be3968b 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -12,6 +12,7 @@ M.ACTION_BACK = hash("back") M.RELEASED = "released" M.PRESSED = "pressed" +M.STRING = "string" --- Interests M.ON_MESSAGE = hash("on_message") @@ -21,6 +22,18 @@ M.ON_UPDATE = hash("on_update") M.ON_SWIPE = hash("on_swipe") M.ON_INPUT = hash("on_input") +M.PIVOTS = { + [gui.PIVOT_CENTER] = vmath.vector3(0), + [gui.PIVOT_N] = vmath.vector3(0, 0.5, 0), + [gui.PIVOT_NE] = vmath.vector3(0.5, 0.5, 0), + [gui.PIVOT_E] = vmath.vector3(0.5, 0, 0), + [gui.PIVOT_SE] = vmath.vector3(0.5, -0.5, 0), + [gui.PIVOT_S] = vmath.vector3(0, -0.5, 0), + [gui.PIVOT_SW] = vmath.vector3(-0.5, -0.5, 0), + [gui.PIVOT_W] = vmath.vector3(-0.5, 0, 0), + [gui.PIVOT_NW] = vmath.vector3(-0.5, -0.5, 0), +} + M.ui_input = { [M.ON_SWIPE] = true, [M.ON_INPUT] = true @@ -30,7 +43,7 @@ M.ui_input = { M.ON_CHANGE_LANGUAGE = hash("on_change_language") M.ON_LAYOUT_CHANGED = hash("on_layout_changed") -M.specific_ui_messages = { +M.SPECIFIC_UI_MESSAGES = { [M.ON_CHANGE_LANGUAGE] = "on_change_language", [M.ON_LAYOUT_CHANGED] = "on_layout_changed" } diff --git a/druid/druid.lua b/druid/druid.lua index f5b7c87..d0170f7 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -91,7 +91,7 @@ local function create(self, module) end self[v][#self[v] + 1] = instance - if const.ui_input[v] then + if const.UI_INPUT[v] then input_init(self) end end @@ -135,7 +135,7 @@ end --- Called on_message function _fct_metatable.on_message(self, message_id, message, sender) - local specific_ui_message = const.specific_ui_messages[message_id] + local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] if specific_ui_message then local array = self[message_id] if array then diff --git a/druid/helper.lua b/druid/helper.lua index 2aaea67..c7c7a36 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -81,7 +81,6 @@ function M.after(count, callback) end -local STRING = "string" function M.node(node_or_name) if type(node_or_name) == const.STRING then return gui.get_node(node_or_name) @@ -144,19 +143,8 @@ function M.is_enabled(node) end -local pivots = { - [gui.PIVOT_CENTER] = vmath.vector3(0), - [gui.PIVOT_N] = vmath.vector3(0, 0.5, 0), - [gui.PIVOT_NE] = vmath.vector3(0.5, 0.5, 0), - [gui.PIVOT_E] = vmath.vector3(0.5, 0, 0), - [gui.PIVOT_SE] = vmath.vector3(0.5, -0.5, 0), - [gui.PIVOT_S] = vmath.vector3(0, -0.5, 0), - [gui.PIVOT_SW] = vmath.vector3(-0.5, -0.5, 0), - [gui.PIVOT_W] = vmath.vector3(-0.5, 0, 0), - [gui.PIVOT_NW] = vmath.vector3(-0.5, -0.5, 0), -} function M.get_pivot_offset(pivot) - return pivots[pivot] + return const.PIVOTS[pivot] end From 88a37f77af7ba8621ce026b0f9b79850f1de2c77 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 22:05:06 +0300 Subject: [PATCH 070/136] Update ldoc comments --- druid/base/back_handler.lua | 10 +++-- druid/base/button.lua | 21 +++++++--- druid/base/progress.lua | 51 +++++++++++++++++-------- druid/base/scroll.lua | 39 ++++++++++++------- druid/base/text.lua | 20 ++++++++-- druid/base/timer.lua | 16 +++++--- druid/const.lua | 8 +++- druid/helper/formats.lua | 19 +++++---- druid/rich/progress_rich.lua | 74 ++++++++++++++++++++++-------------- 9 files changed, 172 insertions(+), 86 deletions(-) diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 4f82c86..dffe1ed 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -1,4 +1,4 @@ ---- Component to handle back key +--- Component to handle back key (android, backspace) -- @module base.back_handler local const = require("druid.const") @@ -9,9 +9,10 @@ M.interest = { } --- Component init function --- @tparam table self component instance --- @tparam callback callback on back button --- @tparam[opt] params callback argument +-- @function back_handler:init +-- @tparam table self Component instance +-- @tparam callback callback On back button +-- @tparam[opt] params Callback argument function M.init(self, callback, params) self.event = const.ACTION_BACK self.callback = callback @@ -20,6 +21,7 @@ end --- Input handler for component +-- @function back_handler:on_input -- @tparam string action_id on_input action id -- @tparam table action on_input action function M.on_input(self, action_id, action) diff --git a/druid/base/button.lua b/druid/base/button.lua index 80b519d..dd80aec 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -22,6 +22,14 @@ M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) M.DEFAULT_ACTIVATION_TIME = 0.2 +--- Component init function +-- @function button:init +-- @tparam table self Component instance +-- @tparam node node Gui node +-- @tparam function callback Button callback +-- @tparam[opt] table params Button callback params +-- @tparam[opt] node anim_node Button anim node (node, if not provided) +-- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) self.node = helper.node(node) self.event = const.ACTION_TOUCH @@ -79,9 +87,6 @@ local function on_button_release(self) end ---- Set text to text field --- @param action_id - input action id --- @param action - input action function M.on_input(self, action_id, action) if not helper.is_enabled(self.node) then return false @@ -197,6 +202,9 @@ function M.activate(self, is_animate, callback) end +--- Disable all button animations +-- @function button:disable_animation +-- @tparam table self Component instance function M.disable_animation(self) self.hover_anim = false self.tap_anim = nil @@ -204,8 +212,11 @@ function M.disable_animation(self) end ---- Set additional node, what need to be clicked on button click --- Used, if need setup, what button can be clicked only in special zone +--- Strict button click area. Useful for +-- no click events outside stencil node +-- @function button:set_click_zone +-- @tparam table self Component instance +-- @tparam node zone Gui node function M.set_click_zone(self, zone) self.click_zone = helper.node(zone) end diff --git a/druid/base/progress.lua b/druid/base/progress.lua index b574350..5f631b7 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -1,4 +1,4 @@ ---- Component to handle progress bars +--- Basic progress bar component -- @module base.progress local const = require("druid.const") @@ -12,25 +12,28 @@ M.interest = { const.ON_UPDATE, } -local PROP_Y = "y" -local PROP_X = "x" - -function M.init(self, name, key, init_value) - if key ~= PROP_X and key ~= PROP_Y then +--- Component init function +-- @function progress:init +-- @tparam table self Component instance +-- @tparam string|node node Progress bar fill node or node name +-- @tparam string key Progress bar direction (x or y) +-- @tparam number init_value Initial value of progress bar +function M.init(self, node, key, init_value) + if key ~= const.SIDE.X and key ~= const.SIDE.Y then settings.log("progress component: key must be 'x' or 'y'. Passed:", key) - key = PROP_X + key = const.SIDE.X end self.prop = hash("scale."..key) self.key = key - self.node = helper.node(name) + self.node = helper.node(node) self.scale = gui.get_scale(self.node) self.size = gui.get_size(self.node) self.max_size = self.size[self.key] self.slice = gui.get_slice9(self.node) - if key == PROP_X then + if key == const.SIDE.X then self.slice_size = self.slice.x + self.slice.z else self.slice_size = self.slice.y + self.slice.w @@ -83,38 +86,54 @@ end --- Fill a progress bar and stop progress animation +-- @function progress:empty +-- @tparam table self Component instance function M.fill(self) set_bar_to(self, 1, true) end ---- To empty a progress bar +--- Empty a progress bar +-- @function progress:empty +-- @tparam table self Component instance function M.empty(self) set_bar_to(self, 0, true) end ---- Set fill a progress bar to value --- @param to - value between 0..1 +--- Instant fill progress bar to value +-- @function progress:set_to +-- @tparam table self Component instance +-- @tparam number to Progress bar value, from 0 to 1 function M.set_to(self, to) set_bar_to(self, to) end +--- Return current progress bar value +-- @function progress:get +-- @tparam table self Component instance function M.get(self) return self.last_value end -function M.set_steps(self, steps, step_callback) +--- Set points on progress bar to fire the callback +-- @function progress:set_steps +-- @tparam table self Component instance +-- @tparam table steps Array of progress bar values +-- @tparam function callback Callback on intersect step value +function M.set_steps(self, steps, callback) self.steps = steps - self.step_callback = step_callback + self.step_callback = callback end --- Start animation of a progress bar --- @param to - value between 0..1 --- @param callback - callback when progress ended if need +-- @function progress:to +-- @tparam table self Component instance +-- @tparam number to value between 0..1 +-- @tparam[opt] function callback Callback on animation ends function M.to(self, to, callback) to = helper.clamp(to, 0, 1) -- cause of float error diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index f4c4bf7..2fbd8bc 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -7,15 +7,13 @@ local settings = require("druid.settings").scroll local M = {} -local SIDE_X = "x" -local SIDE_Y = "y" - M.interest = { const.ON_UPDATE, const.ON_SWIPE, } -- Global on all scrolls +-- TODO: remove it M.current_scroll = nil @@ -280,14 +278,11 @@ function M.on_input(self, action_id, action) if not M.current_scroll and dist >= settings.DEADZONE then local dx = math.abs(inp.start_x - action.x) local dy = math.abs(inp.start_y - action.y) - if dx > dy then - inp.side = SIDE_X - else - inp.side = SIDE_Y - end + inp.side = (dx > dy) and const.SIDE.X or const.SIDE.Y + -- Check scroll side if we can scroll - if (self.can_x and inp.side == SIDE_X or - self.can_y and inp.side == SIDE_Y) then + if (self.can_x and inp.side == const.SIDE.X or + self.can_y and inp.side == const.SIDE.Y) then M.current_scroll = self end end @@ -308,6 +303,7 @@ function M.on_input(self, action_id, action) M.current_scroll = nil result = true end + check_threshold(self) end @@ -316,6 +312,7 @@ end --- Start scroll to target point +-- @function scroll:scroll_to -- @tparam point vector3 target point -- @tparam[opt] bool is_instant instant scroll flag -- @usage scroll:scroll_to(vmath.vector3(0, 50, 0)) @@ -343,7 +340,11 @@ function M.scroll_to(self, point, is_instant) end ---- Scroll to item in scroll by points index +--- Scroll to item in scroll by point index +-- @function scroll:init +-- @tparam table self Component instance +-- @tparam number index Point index +-- @tparam[opt] boolean skip_cb If true, skip the point callback function M.scroll_to_index(self, index, skip_cb) index = helper.clamp(index, 1, #self.points) @@ -359,8 +360,11 @@ function M.scroll_to_index(self, index, skip_cb) end ---- Set points of interest +--- Set points of interest. -- Scroll will always centered on closer points +-- @function scroll:set_points +-- @tparam table self Component instance +-- @tparam table points Array of vector3 points function M.set_points(self, points) self.points = points -- cause of parent move in other side by y @@ -375,21 +379,30 @@ function M.set_points(self, points) end ---- Enable or disable scroll inert +--- Enable or disable scroll inert. -- If disabled, scroll through points (if exist) -- If no points, just simple drag without inertion +-- @function scroll:set_inert +-- @tparam table self Component instance +-- @tparam boolean state Inert scroll state function M.set_inert(self, state) self.is_inert = state end --- Set the callback on scrolling to point (if exist) +-- @function scroll:on_point_move +-- @tparam table self Component instance +-- @tparam function callback Callback on scroll to point of interest function M.on_point_move(self, callback) self.on_point_callback = callback end --- Set the scroll possibly area +-- @function scroll:set_border +-- @tparam table self Component instance +-- @tparam vmath.vector3 border Size of scrolling area function M.set_border(self, border) self.border = border diff --git a/druid/base/text.lua b/druid/base/text.lua index 7405b67..f04bbf7 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -29,6 +29,10 @@ function M.init(self, node, value, is_locale, max_width) end +--- Translate the text by locale_id +-- @function text:translate +-- @tparam table self Component instance +-- @tparam string locale_id Locale id function M.translate(self, locale_id) self.last_locale = locale_id or self.last_locale self:set_to(settings.get_text(self.last_locale)) @@ -56,7 +60,9 @@ end --- Set text to text field --- @param set_to - set value to text field +-- @function text:set_to +-- @tparam table self Component instance +-- @tparam string set_to Text for node function M.set_to(self, set_to) self.last_value = set_to gui.set_text(self.node, set_to) @@ -68,7 +74,9 @@ end --- Set color --- @param color +-- @function text:set_color +-- @tparam table self Component instance +-- @tparam vmath.vector4 color Color for node function M.set_color(self, color) self.last_color = color gui.set_color(self.node, color) @@ -76,7 +84,9 @@ end --- Set alpha --- @param alpha, number [0-1] +-- @function text:set_alpha +-- @tparam table self Component instance +-- @tparam number alpha Alpha for node function M.set_alpha(self, alpha) self.last_color.w = alpha gui.set_color(self.node, self.last_color) @@ -84,7 +94,9 @@ end --- Set scale --- @param scale +-- @function text:set_scale +-- @tparam table self Component instance +-- @tparam vmath.vector3 scale Scale for node function M.set_scale(self, scale) self.last_scale = scale gui.set_scale(self.node, scale) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 9f7210e..af22d1f 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -32,7 +32,9 @@ end --- Set text to text field --- @param set_to - set value in seconds +-- @function timer:set_to +-- @tparam table self Component instance +-- @tparam number set_to Value in seconds function M.set_to(self, set_to) self.last_value = set_to gui.set_text(self.node, formats.second_string_min(set_to)) @@ -40,15 +42,19 @@ end --- Called when update --- @param is_on - boolean is timer on +-- @function timer:set_state +-- @tparam table self Component instance +-- @tparam boolean is_on Timer enable state function M.set_state(self, is_on) self.is_on = is_on end --- Set time interval --- @param from - "from" time in seconds --- @param to - "to" time in seconds +-- @function timer:set_interval +-- @tparam table self Component instance +-- @tparam number from Start time in seconds +-- @tparam number to Target time in seconds function M.set_interval(self, from, to) self.from = from self.value = from @@ -59,8 +65,6 @@ function M.set_interval(self, from, to) end ---- Called when update --- @param dt - delta time function M.update(self, dt) if self.is_on then self.temp = self.temp + dt diff --git a/druid/const.lua b/druid/const.lua index be3968b..e199b59 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -13,6 +13,7 @@ M.ACTION_BACK = hash("back") M.RELEASED = "released" M.PRESSED = "pressed" M.STRING = "string" +M.ZERO = "0" --- Interests M.ON_MESSAGE = hash("on_message") @@ -34,7 +35,12 @@ M.PIVOTS = { [gui.PIVOT_NW] = vmath.vector3(-0.5, -0.5, 0), } -M.ui_input = { +M.SIDE = { + X = "x", + Y = "y" +} + +M.UI_INPUT = { [M.ON_SWIPE] = true, [M.ON_INPUT] = true } diff --git a/druid/helper/formats.lua b/druid/helper/formats.lua index 96aa487..9c38861 100644 --- a/druid/helper/formats.lua +++ b/druid/helper/formats.lua @@ -1,25 +1,27 @@ --- Druid module with utils on string formats -- @module helper.formats +local const = require("druid.const") + local M = {} -local ZERO = "0" - --- Return number with zero number prefix --- @param num number for conversion --- @param count count of numerals +-- @function formats.add_prefix_zeros +-- @tparam number num Number for conversion +-- @tparam number count Count of numerals -- @return string with need count of zero (1,3) -> 001 function M.add_prefix_zeros(num, count) local result = tostring(num) for i = string.len(result), count - 1 do - result = ZERO..result + result = const.ZERO..result end return result end --- Convert seconds to string minutes:seconds --- @param num number of seconds +-- @function formats.second_string_min +-- @tparam number sec Seconds -- @return string minutes:seconds function M.second_string_min(sec) local mins = math.floor(sec / 60) @@ -29,8 +31,9 @@ end --- Interpolate string with named Parameters in Table --- @param s string for interpolate --- @param tab table with parameters +-- @function formats.second_string_min +-- @tparam string s Target string +-- @tparam table tab Table with parameters -- @return string with replaced parameters function M.interpolate_string(s, tab) return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end)) diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index 8785794..87c9b10 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -1,55 +1,71 @@ +--- Component for rich progress component +-- @module rich.progress_rich + local settings = require("druid.settings") local pr_settings = settings.progress_rich local M = {} -function M.init(instance, name, red, green, key) - instance.red = instance.parent:new_progress(red, key) - instance.green = instance.parent:new_progress(green, key) - instance.fill = instance.parent:new_progress(name, key) + +function M.init(self, name, red, green, key) + self.red = self.parent:new_progress(red, key) + self.green = self.parent:new_progress(green, key) + self.fill = self.parent:new_progress(name, key) end -function M.set_to(instance, value) - instance.red:set_to(value) - instance.green:set_to(value) - instance.fill:set_to(value) +--- Instant fill progress bar to value +-- @function progress_rich:set_to +-- @tparam table self Component instance +-- @tparam number value Progress bar value, from 0 to 1 +function M.set_to(self, value) + self.red:set_to(value) + self.green:set_to(value) + self.fill:set_to(value) end -function M.empty(instance) - instance.red:empty() - instance.green:empty() - instance.fill:empty() +--- Empty a progress bar +-- @function progress_rich:empty +-- @tparam table self Component instance +function M.empty(self) + self.red:empty() + self.green:empty() + self.fill:empty() end -function M.to(instance, to, callback) - if instance.timer then - timer.cancel(instance.timer) - instance.timer = nil +--- Start animation of a progress bar +-- @function progress_rich:to +-- @tparam table self Component instance +-- @tparam number to value between 0..1 +-- @tparam[opt] function callback Callback on animation ends +function M.to(self, to, callback) + if self.timer then + timer.cancel(self.timer) + self.timer = nil end - if instance.fill.last_value < to then - instance.red:to(instance.fill.last_value) - instance.green:to(to, function() - instance.timer = timer.delay(pr_settings.DELAY, false, function() - instance.red:to(to) - instance.fill:to(to, callback) + if self.fill.last_value < to then + self.red:to(self.fill.last_value) + self.green:to(to, function() + self.timer = timer.delay(pr_settings.DELAY, false, function() + self.red:to(to) + self.fill:to(to, callback) end) end) end - if instance.fill.last_value > to then - instance.green:to(instance.red.last_value) - instance.fill:to(to, function() - instance.timer = timer.delay(pr_settings.DELAY, false, function() - instance.green:to(to) - instance.red:to(to, callback) + if self.fill.last_value > to then + self.green:to(self.red.last_value) + self.fill:to(to, function() + self.timer = timer.delay(pr_settings.DELAY, false, function() + self.green:to(to) + self.red:to(to, callback) end) end) end end -return M \ No newline at end of file +return M From da27d6edd8e9fa914ddd1be5d03ba48fd3e210a5 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 22:05:17 +0300 Subject: [PATCH 071/136] Generate ldoc --- docs/index.html | 103 +++++++- docs/modules/back_handler.html | 155 +++++++++++ docs/modules/base.back_handler.html | 156 +++++++++++ docs/modules/base.blocker.html | 82 ++++++ docs/modules/base.button.html | 195 ++++++++++++++ docs/modules/base.checkbox.html | 82 ++++++ docs/modules/base.checkbox_group.html | 82 ++++++ docs/modules/base.grid.html | 82 ++++++ docs/modules/base.html | 155 +++++++++++ docs/modules/base.progress.html | 301 +++++++++++++++++++++ docs/modules/base.scroll.html | 278 +++++++++++++++++++ docs/modules/base.slider.html | 82 ++++++ docs/modules/base.text.html | 238 +++++++++++++++++ docs/modules/base.timer.html | 184 +++++++++++++ docs/modules/components.back_handler.html | 155 +++++++++++ docs/modules/constants.html | 111 ++++++++ docs/modules/druid.html | 309 ++++++++++++++++++++++ docs/modules/helper.animate.html | 82 ++++++ docs/modules/helper.formats.html | 191 +++++++++++++ docs/modules/helper.html | 153 +++++++++++ docs/modules/rich.progress_rich.html | 181 +++++++++++++ docs/modules/settings.html | 82 ++++++ 22 files changed, 3438 insertions(+), 1 deletion(-) create mode 100644 docs/modules/back_handler.html create mode 100644 docs/modules/base.back_handler.html create mode 100644 docs/modules/base.blocker.html create mode 100644 docs/modules/base.button.html create mode 100644 docs/modules/base.checkbox.html create mode 100644 docs/modules/base.checkbox_group.html create mode 100644 docs/modules/base.grid.html create mode 100644 docs/modules/base.html create mode 100644 docs/modules/base.progress.html create mode 100644 docs/modules/base.scroll.html create mode 100644 docs/modules/base.slider.html create mode 100644 docs/modules/base.text.html create mode 100644 docs/modules/base.timer.html create mode 100644 docs/modules/components.back_handler.html create mode 100644 docs/modules/constants.html create mode 100644 docs/modules/druid.html create mode 100644 docs/modules/helper.animate.html create mode 100644 docs/modules/helper.formats.html create mode 100644 docs/modules/helper.html create mode 100644 docs/modules/rich.progress_rich.html create mode 100644 docs/modules/settings.html diff --git a/docs/index.html b/docs/index.html index a695fc9..59a5bb7 100644 --- a/docs/index.html +++ b/docs/index.html @@ -29,6 +29,28 @@ +

Modules

+ @@ -37,12 +59,91 @@

Documentation for Druid Library

+

Modules

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
base.back_handlerComponent to handle back key (android, backspace)
base.blockerComponent to block input on specify zone (node)
base.buttonComponent to handle basic GUI button
base.checkboxDruid checkbox component
base.checkbox_groupCheckboux group module
base.gridComponent to handle placing components by row and columns.
base.progressBasic progress bar component
base.checkbox_groupRadio group module
base.scrollComponent to handle scroll content
base.sliderDruid slider component
base.textComponent to handle all GUI texts Good working with localization system
base.timerComponent to handle GUI timers
constantsDruid constants
druidDruid UI Library.
helperDruid helper module
helper.animateDruid helper module for animating GUI nodes
helper.formatsDruid module with utils on string formats
rich.progress_richComponent for rich progress component
settingsDruid settings file
generated by LDoc 1.4.6 -Last updated 2019-09-25 19:57:43 +Last updated 2019-12-05 22:04:11
diff --git a/docs/modules/back_handler.html b/docs/modules/back_handler.html new file mode 100644 index 0000000..0a7f657 --- /dev/null +++ b/docs/modules/back_handler.html @@ -0,0 +1,155 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module back_handler

+

Component to handle back key

+

+ + +

Functions

+ + + + + + + + + +
init(self, callback[, Callback])Component init function
on_input(action_id, action)Input handler for component
+ +
+
+ + +

Functions

+ +
+
+ + init(self, callback[, Callback]) +
+
+ Component init function + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • callback + callback + On back button +
  • +
  • Callback + params + argument + (optional) +
  • +
+ + + + + +
+
+ + on_input(action_id, action) +
+
+ Input handler for component + + +

Parameters:

+
    +
  • action_id + string + on_input action id +
  • +
  • action + table + on_input action +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 21:37:51 +
+
+ + diff --git a/docs/modules/base.back_handler.html b/docs/modules/base.back_handler.html new file mode 100644 index 0000000..5d11f6e --- /dev/null +++ b/docs/modules/base.back_handler.html @@ -0,0 +1,156 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.back_handler

+

Component to handle back key (android, backspace)

+

+ + +

Functions

+ + + + + + + + + +
init(self, callback[, Callback])Component init function
on_input(action_id, action)Input handler for component
+ +
+
+ + +

Functions

+ +
+
+ + init(self, callback[, Callback]) +
+
+ Component init function + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • callback + callback + On back button +
  • +
  • Callback + params + argument + (optional) +
  • +
+ + + + + +
+
+ + on_input(action_id, action) +
+
+ Input handler for component + + +

Parameters:

+
    +
  • action_id + string + on_input action id +
  • +
  • action + table + on_input action +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.blocker.html b/docs/modules/base.blocker.html new file mode 100644 index 0000000..9d0f4a5 --- /dev/null +++ b/docs/modules/base.blocker.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.blocker

+

Component to block input on specify zone (node)

+

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.button.html b/docs/modules/base.button.html new file mode 100644 index 0000000..f99cfcd --- /dev/null +++ b/docs/modules/base.button.html @@ -0,0 +1,195 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.button

+

Component to handle basic GUI button

+

+ + +

Functions

+ + + + + + + + + + + + + +
init(self, node, callback[, params[, anim_node[, event]]])Component init function
disable_animation(self)Disable all button animations
set_click_zone(self, zone)Strict button click area.
+ +
+
+ + +

Functions

+ +
+
+ + init(self, node, callback[, params[, anim_node[, event]]]) +
+
+ Component init function + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • node + node + Gui node +
  • +
  • callback + function + Button callback +
  • +
  • params + table + Button callback params + (optional) +
  • +
  • anim_node + node + Button anim node (node, if not provided) + (optional) +
  • +
  • event + string + Button react event, const.ACTION_TOUCH by default + (optional) +
  • +
+ + + + + +
+
+ + disable_animation(self) +
+
+ Disable all button animations + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
+ + + + + +
+
+ + set_click_zone(self, zone) +
+
+ Strict button click area. Useful for no click events outside stencil node + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • zone + node + Gui node +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.checkbox.html b/docs/modules/base.checkbox.html new file mode 100644 index 0000000..cc3dce8 --- /dev/null +++ b/docs/modules/base.checkbox.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.checkbox

+

Druid checkbox component

+

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.checkbox_group.html b/docs/modules/base.checkbox_group.html new file mode 100644 index 0000000..2c8f1d9 --- /dev/null +++ b/docs/modules/base.checkbox_group.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.checkbox_group

+

Radio group module

+

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.grid.html b/docs/modules/base.grid.html new file mode 100644 index 0000000..c8e0f78 --- /dev/null +++ b/docs/modules/base.grid.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.grid

+

Component to handle placing components by row and columns.

+

Grid can anchor your elements, get content size and other

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.html b/docs/modules/base.html new file mode 100644 index 0000000..6e44f09 --- /dev/null +++ b/docs/modules/base.html @@ -0,0 +1,155 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base

+

Component to handle back key

+

+ + +

Functions

+ + + + + + + + + +
back_handler:init(self, callback[, Callback])Component init function
back_handler:on_input(action_id, action)Input handler for component
+ +
+
+ + +

Functions

+ +
+
+ + back_handler:init(self, callback[, Callback]) +
+
+ Component init function + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • callback + callback + On back button +
  • +
  • Callback + params + argument + (optional) +
  • +
+ + + + + +
+
+ + back_handler:on_input(action_id, action) +
+
+ Input handler for component + + +

Parameters:

+
    +
  • action_id + string + on_input action id +
  • +
  • action + table + on_input action +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 21:36:59 +
+
+ + diff --git a/docs/modules/base.progress.html b/docs/modules/base.progress.html new file mode 100644 index 0000000..ba8e905 --- /dev/null +++ b/docs/modules/base.progress.html @@ -0,0 +1,301 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.progress

+

Basic progress bar component

+

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
init(self, node, key, init_value)Component init function
empty(self)Fill a progress bar and stop progress animation
empty(self)Empty a progress bar
set_to(self, to)Instant fill progress bar to value
get(self)Return current progress bar value
set_steps(self, steps, callback)Set points on progress bar to fire the callback
to(self, to[, callback])Start animation of a progress bar
+ +
+
+ + +

Functions

+ +
+
+ + init(self, node, key, init_value) +
+
+ Component init function + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • node + string or node + Progress bar fill node or node name +
  • +
  • key + string + Progress bar direction (x or y) +
  • +
  • init_value + number + Initial value of progress bar +
  • +
+ + + + + +
+
+ + empty(self) +
+
+ Fill a progress bar and stop progress animation + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
+ + + + + +
+
+ + empty(self) +
+
+ Empty a progress bar + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
+ + + + + +
+
+ + set_to(self, to) +
+
+ Instant fill progress bar to value + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • to + number + Progress bar value, from 0 to 1 +
  • +
+ + + + + +
+
+ + get(self) +
+
+ Return current progress bar value + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
+ + + + + +
+
+ + set_steps(self, steps, callback) +
+
+ Set points on progress bar to fire the callback + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • steps + table + Array of progress bar values +
  • +
  • callback + function + Callback on intersect step value +
  • +
+ + + + + +
+
+ + to(self, to[, callback]) +
+
+ Start animation of a progress bar + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • to + number + value between 0..1 +
  • +
  • callback + function + Callback on animation ends + (optional) +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.scroll.html b/docs/modules/base.scroll.html new file mode 100644 index 0000000..dabe409 --- /dev/null +++ b/docs/modules/base.scroll.html @@ -0,0 +1,278 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.scroll

+

Component to handle scroll content

+

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
scroll_to(vector3[, is_instant])Start scroll to target point
init(self, index[, skip_cb])Scroll to item in scroll by point index
set_points(self, points)Set points of interest.
set_inert(self, state)Enable or disable scroll inert.
on_point_move(self, callback)Set the callback on scrolling to point (if exist)
set_border(self, border)Set the scroll possibly area
+ +
+
+ + +

Functions

+ +
+
+ + scroll_to(vector3[, is_instant]) +
+
+ Start scroll to target point + + +

Parameters:

+
    +
  • vector3 + point + target point +
  • +
  • is_instant + bool + instant scroll flag + (optional) +
  • +
+ + + + +

Usage:

+
    +
  • scroll:scroll_to(vmath.vector3(0, 50, 0))
  • +
  • scroll:scroll_to(vmath.vector3(0), true)
  • +
+ +
+
+ + init(self, index[, skip_cb]) +
+
+ Scroll to item in scroll by point index + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • index + number + Point index +
  • +
  • skip_cb + boolean + If true, skip the point callback + (optional) +
  • +
+ + + + + +
+
+ + set_points(self, points) +
+
+ Set points of interest. Scroll will always centered on closer points + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • points + table + Array of vector3 points +
  • +
+ + + + + +
+
+ + set_inert(self, state) +
+
+ Enable or disable scroll inert. If disabled, scroll through points (if exist) If no points, just simple drag without inertion + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • state + boolean + Inert scroll state +
  • +
+ + + + + +
+
+ + on_point_move(self, callback) +
+
+ Set the callback on scrolling to point (if exist) + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • callback + function + Callback on scroll to point of interest +
  • +
+ + + + + +
+
+ + set_border(self, border) +
+
+ Set the scroll possibly area + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • border + vmath.vector3 + Size of scrolling area +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.slider.html b/docs/modules/base.slider.html new file mode 100644 index 0000000..14f8f6e --- /dev/null +++ b/docs/modules/base.slider.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.slider

+

Druid slider component

+

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.text.html b/docs/modules/base.text.html new file mode 100644 index 0000000..26e0f16 --- /dev/null +++ b/docs/modules/base.text.html @@ -0,0 +1,238 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.text

+

Component to handle all GUI texts Good working with localization system

+

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + +
translate(self, locale_id)Translate the text by locale_id
set_to(self, set_to)Set text to text field
set_color(self, color)Set color
set_alpha(self, alpha)Set alpha
set_scale(self, scale)Set scale
+ +
+
+ + +

Functions

+ +
+
+ + translate(self, locale_id) +
+
+ Translate the text by locale_id + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • locale_id + string + Locale id +
  • +
+ + + + + +
+
+ + set_to(self, set_to) +
+
+ Set text to text field + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • set_to + string + Text for node +
  • +
+ + + + + +
+
+ + set_color(self, color) +
+
+ Set color + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • color + vmath.vector4 + Color for node +
  • +
+ + + + + +
+
+ + set_alpha(self, alpha) +
+
+ Set alpha + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • alpha + number + Alpha for node +
  • +
+ + + + + +
+
+ + set_scale(self, scale) +
+
+ Set scale + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • scale + vmath.vector3 + Scale for node +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/base.timer.html b/docs/modules/base.timer.html new file mode 100644 index 0000000..dc66bfb --- /dev/null +++ b/docs/modules/base.timer.html @@ -0,0 +1,184 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module base.timer

+

Component to handle GUI timers

+

+ + +

Functions

+ + + + + + + + + + + + + +
set_to(self, set_to)Set text to text field
set_state(self, is_on)Called when update
set_interval(self, from, to)Set time interval
+ +
+
+ + +

Functions

+ +
+
+ + set_to(self, set_to) +
+
+ Set text to text field + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • set_to + number + Value in seconds +
  • +
+ + + + + +
+
+ + set_state(self, is_on) +
+
+ Called when update + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • is_on + boolean + Timer enable state +
  • +
+ + + + + +
+
+ + set_interval(self, from, to) +
+
+ Set time interval + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • from + number + Start time in seconds +
  • +
  • to + number + Target time in seconds +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/components.back_handler.html b/docs/modules/components.back_handler.html new file mode 100644 index 0000000..6e25bbe --- /dev/null +++ b/docs/modules/components.back_handler.html @@ -0,0 +1,155 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module components.back_handler

+

Component to handle back key

+

+ + +

Functions

+ + + + + + + + + +
init(self, callback[, Callback])Component init function
on_input(action_id, action)Input handler for component
+ +
+
+ + +

Functions

+ +
+
+ + init(self, callback[, Callback]) +
+
+ Component init function + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • callback + callback + On back button +
  • +
  • Callback + params + argument + (optional) +
  • +
+ + + + + +
+
+ + on_input(action_id, action) +
+
+ Input handler for component + + +

Parameters:

+
    +
  • action_id + string + on_input action id +
  • +
  • action + table + on_input action +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 21:38:00 +
+
+ + diff --git a/docs/modules/constants.html b/docs/modules/constants.html new file mode 100644 index 0000000..5cd9b0b --- /dev/null +++ b/docs/modules/constants.html @@ -0,0 +1,111 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module constants

+

Druid constants

+

+ + +

Fields

+ + + + + +
ON_MESSAGEInterests
+ +
+
+ + +

Fields

+ +
+
+ + ON_MESSAGE +
+
+ Interests + + + + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/druid.html b/docs/modules/druid.html new file mode 100644 index 0000000..f7b1a7a --- /dev/null +++ b/docs/modules/druid.html @@ -0,0 +1,309 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module druid

+

Druid UI Library.

+

Component based UI library to make your life easier. Contains a lot of base components and give API to create your own rich components.

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + +
register(name, module)Register external module
new(component_script)Create UI instance for ui elements
_fct_metatable.on_message(self, message_id, message, sender)Called on_message
_fct_metatable.on_input(self, action_id, action)Called ON_INPUT
_fct_metatable.update(self, dt)Called on_update
+

Tables

+ + + + + +
compsBasic components
+ +
+
+ + +

Functions

+ +
+
+ + register(name, module) +
+
+ Register external module + + +

Parameters:

+
    +
  • name + string + module name +
  • +
  • module + table + lua table with module +
  • +
+ + + + + +
+
+ + new(component_script) +
+
+ Create UI instance for ui elements + + +

Parameters:

+
    +
  • component_script + +
  • +
+ +

Returns:

+
    + + instance with all ui components +
+ + + + +
+
+ + _fct_metatable.on_message(self, message_id, message, sender) +
+
+ Called on_message + + +

Parameters:

+
    +
  • self + +
  • +
  • message_id + +
  • +
  • message + +
  • +
  • sender + +
  • +
+ + + + + +
+
+ + _fct_metatable.on_input(self, action_id, action) +
+
+ Called ON_INPUT + + +

Parameters:

+
    +
  • self + +
  • +
  • action_id + +
  • +
  • action + +
  • +
+ + + + + +
+
+ + _fct_metatable.update(self, dt) +
+
+ Called on_update + + +

Parameters:

+
    +
  • self + +
  • +
  • dt + +
  • +
+ + + + + +
+
+

Tables

+ +
+
+ + comps +
+
+ Basic components + + +

Fields:

+
    +
  • button + +
  • +
  • blocker + +
  • +
  • back_handler + +
  • +
  • text + +
  • +
  • timer + +
  • +
  • progress + +
  • +
  • grid + +
  • +
  • scroll + +
  • +
  • slider + +
  • +
  • checkbox + +
  • +
  • checkbox_group + +
  • +
  • radio_group + +
  • +
  • progress_rich + +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/helper.animate.html b/docs/modules/helper.animate.html new file mode 100644 index 0000000..63f59ee --- /dev/null +++ b/docs/modules/helper.animate.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module helper.animate

+

Druid helper module for animating GUI nodes

+

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/helper.formats.html b/docs/modules/helper.formats.html new file mode 100644 index 0000000..6cf1ce1 --- /dev/null +++ b/docs/modules/helper.formats.html @@ -0,0 +1,191 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module helper.formats

+

Druid module with utils on string formats

+

+ + +

Functions

+ + + + + + + + + + + + + +
add_prefix_zeros(num, count)Return number with zero number prefix
second_string_min(sec)Convert seconds to string minutes:seconds
second_string_min(s, tab)Interpolate string with named Parameters in Table
+ +
+
+ + +

Functions

+ +
+
+ + add_prefix_zeros(num, count) +
+
+ Return number with zero number prefix + + +

Parameters:

+
    +
  • num + number + Number for conversion +
  • +
  • count + number + Count of numerals +
  • +
+ +

Returns:

+
    + + string with need count of zero (1,3) -> 001 +
+ + + + +
+
+ + second_string_min(sec) +
+
+ Convert seconds to string minutes:seconds + + +

Parameters:

+
    +
  • sec + number + Seconds +
  • +
+ +

Returns:

+
    + + string minutes:seconds +
+ + + + +
+
+ + second_string_min(s, tab) +
+
+ Interpolate string with named Parameters in Table + + +

Parameters:

+
    +
  • s + string + Target string +
  • +
  • tab + table + Table with parameters +
  • +
+ +

Returns:

+
    + + string with replaced parameters +
+ + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/helper.html b/docs/modules/helper.html new file mode 100644 index 0000000..e7ecf16 --- /dev/null +++ b/docs/modules/helper.html @@ -0,0 +1,153 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module helper

+

Druid helper module

+

+ + +

Functions

+ + + + + + + + + +
centrate_text_with_icon(text_node, icon_node, margin)Text node or icon node can be nil
centrate_icon_with_text(icon_node, text_node, margin)Icon node or text node can be nil
+ +
+
+ + +

Functions

+ +
+
+ + centrate_text_with_icon(text_node, icon_node, margin) +
+
+ Text node or icon node can be nil + + +

Parameters:

+
    +
  • text_node + +
  • +
  • icon_node + +
  • +
  • margin + +
  • +
+ + + + + +
+
+ + centrate_icon_with_text(icon_node, text_node, margin) +
+
+ Icon node or text node can be nil + + +

Parameters:

+
    +
  • icon_node + +
  • +
  • text_node + +
  • +
  • margin + +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/rich.progress_rich.html b/docs/modules/rich.progress_rich.html new file mode 100644 index 0000000..0ce5b2e --- /dev/null +++ b/docs/modules/rich.progress_rich.html @@ -0,0 +1,181 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module rich.progress_rich

+

Component for rich progress component

+

+ + +

Functions

+ + + + + + + + + + + + + +
set_to(self, value)Instant fill progress bar to value
empty(self)Empty a progress bar
to(self, to[, callback])Start animation of a progress bar
+ +
+
+ + +

Functions

+ +
+
+ + set_to(self, value) +
+
+ Instant fill progress bar to value + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • value + number + Progress bar value, from 0 to 1 +
  • +
+ + + + + +
+
+ + empty(self) +
+
+ Empty a progress bar + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
+ + + + + +
+
+ + to(self, to[, callback]) +
+
+ Start animation of a progress bar + + +

Parameters:

+
    +
  • self + table + Component instance +
  • +
  • to + number + value between 0..1 +
  • +
  • callback + function + Callback on animation ends + (optional) +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + diff --git a/docs/modules/settings.html b/docs/modules/settings.html new file mode 100644 index 0000000..205e608 --- /dev/null +++ b/docs/modules/settings.html @@ -0,0 +1,82 @@ + + + + + Defold Druid UI Library + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module settings

+

Druid settings file

+

+ + + +
+
+ + + + +
+
+
+generated by LDoc 1.4.6 +Last updated 2019-12-05 22:04:11 +
+
+ + From b8dec4826f2b5edadcaea73f6eb3793a90c0f338 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 22:39:35 +0300 Subject: [PATCH 072/136] Add druid with context, get component druid as helper.get_druid(context) --- druid/base/back_handler.lua | 2 +- druid/base/button.lua | 10 +++++----- druid/base/checkbox.lua | 7 ++++--- druid/base/checkbox_group.lua | 7 +++++-- druid/base/progress.lua | 8 ++++---- druid/base/radio_group.lua | 7 +++++-- druid/base/scroll.lua | 2 +- druid/base/slider.lua | 2 +- druid/base/timer.lua | 4 ++-- druid/druid.lua | 18 ++++++++++++------ druid/helper.lua | 6 ++++++ druid/rich/progress_rich.lua | 8 +++++--- 12 files changed, 51 insertions(+), 30 deletions(-) diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index dffe1ed..45d0a2e 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -26,7 +26,7 @@ end -- @tparam table action on_input action function M.on_input(self, action_id, action) if action[const.RELEASED] then - self.callback(self.parent.parent, self.params) + self.callback(self.context, self.params) end return true diff --git a/druid/base/button.lua b/druid/base/button.lua index dd80aec..8a11e86 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -74,7 +74,7 @@ local function on_button_release(self) if self.tap_anim then self.tap_anim(self) end - self.callback(self.parent.parent, self.params, self) + self.callback(self.context, self.params, self) settings.play_sound(self.sound) else set_hover(self, false) @@ -151,7 +151,7 @@ function M.deactivate(self, is_animate, callback) -- callback call three times in gui.animation local clbk = helper.after(3, function() if callback then - callback(self.parent.parent) + callback(self.context) end end) @@ -167,7 +167,7 @@ function M.deactivate(self, is_animate, callback) gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR) gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE) if callback then - callback(self.parent.parent) + callback(self.context) end end end @@ -179,7 +179,7 @@ function M.activate(self, is_animate, callback) local clbk = helper.after(3, function() self.disabled = false if callback then - callback(self.parent.parent) + callback(self.context) end end) @@ -196,7 +196,7 @@ function M.activate(self, is_animate, callback) gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE) self.disabled = false if callback then - callback(self.parent.parent) + callback(self.context) end end end diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index d7290d2..6c3075d 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -21,7 +21,7 @@ function M.set_state(self, state, is_silence) state_animate(self.node, state) if not is_silence and self.callback then - self.callback(self.parent.parent, state) + self.callback(self.context, state) end end @@ -32,17 +32,18 @@ end -- TODO: pass self as first parameter -local function on_click(context, self) +local function on_click(self) M.set_state(self, not self.state) end function M.init(self, node, callback, click_node) + self.druid = helper.get_druid(self) self.node = helper.node(node) self.click_node = helper.node(click_node) self.callback = callback - self.button = self.parent:new_button(self.click_node or self.node, on_click, self) + self.button = self.druid:new_button(self.click_node or self.node, on_click) M.set_state(self, false, true) end diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 3d8de6c..6e92987 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,12 +1,14 @@ --- Checkboux group module -- @module base.checkbox_group +local helper = require("druid.helper") + local M = {} local function on_checkbox_click(self, index) if self.callback then - self.callback(self.parent.parent, index) + self.callback(self.context, index) end end @@ -32,12 +34,13 @@ end function M.init(self, nodes, callback, click_nodes) + self.druid = helper.get_druid(self) self.checkboxes = {} self.callback = callback for i = 1, #nodes do local click_node = click_nodes and click_nodes[i] or nil - local checkbox = self.parent:new_checkbox(nodes[i], function() + local checkbox = self.druid:new_checkbox(nodes[i], function() on_checkbox_click(self, i) end, click_node) diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 5f631b7..450f2a4 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -56,10 +56,10 @@ local function check_steps(self, from, to, exactly) end if v1 < step and step < v2 then - self.step_callback(self.parent.parent, step) + self.step_callback(self.context, step) end if exactly and exactly == step then - self.step_callback(self.parent.parent, step) + self.step_callback(self.context, step) end end end @@ -143,7 +143,7 @@ function M.to(self, to, callback) self.target_callback = callback else if callback then - callback(self.parent.parent, to) + callback(self.context, to) end end end @@ -160,7 +160,7 @@ function M.update(self, dt) check_steps(self, prev_value, self.target, self.target) if self.target_callback then - self.target_callback(self.parent.parent, self.target) + self.target_callback(self.context, self.target) end self.target = nil diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua index 25e74b6..ee22e6a 100644 --- a/druid/base/radio_group.lua +++ b/druid/base/radio_group.lua @@ -1,6 +1,8 @@ --- Radio group module -- @module base.checkbox_group +local helper = require("druid.helper") + local M = {} @@ -10,7 +12,7 @@ local function on_checkbox_click(self, index) end if self.callback then - self.callback(self.parent.parent, index) + self.callback(self.context, index) end end @@ -35,12 +37,13 @@ end function M.init(self, nodes, callback, click_nodes) + self.druid = helper.get_druid(self) self.checkboxes = {} self.callback = callback for i = 1, #nodes do local click_node = click_nodes and click_nodes[i] or nil - local checkbox = self.parent:new_checkbox(nodes[i], function() + local checkbox = self.druid:new_checkbox(nodes[i], function() on_checkbox_click(self, i) end, click_node) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 2fbd8bc..e3e79ee 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -352,7 +352,7 @@ function M.scroll_to_index(self, index, skip_cb) self.selected = index if not skip_cb and self.on_point_callback then - self.on_point_callback(self.parent.parent, index, self.points[index]) + self.on_point_callback(self.context, index, self.points[index]) end end diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 29f25c0..98b5846 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -12,7 +12,7 @@ M.interest = { local function on_change_value(self) if self.callback then - self.callback(self.parent.parent, self.value) + self.callback(self.context, self.value) end end diff --git a/druid/base/timer.lua b/druid/base/timer.lua index af22d1f..c531205 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -25,7 +25,7 @@ function M.init(self, node, seconds_from, seconds_to, callback) if seconds_to - seconds_from == 0 then self:set_state(false) - self.callback(self.parent.parent, self) + self.callback(self.context, self) end return self end @@ -76,7 +76,7 @@ function M.update(self, dt) M.set_to(self, self.value) if self.value == self.target then self:set_state(false) - self.callback(self.parent.parent, self) + self.callback(self.context, self) end end end diff --git a/druid/druid.lua b/druid/druid.lua index d0170f7..ce533c3 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -48,6 +48,8 @@ end -- @tparam table module lua table with module function M.register(name, module) -- TODO: Find better solution to creating elements? + -- Possibly: druid.new(druid.BUTTON, etc?) + -- Current way is very implicit _fct_metatable["new_" .. name] = function(self, ...) return _fct_metatable.new(self, module, ...) end @@ -62,8 +64,10 @@ function M.new(component_script) register_basic_components() register_basic_components = false end - local self = setmetatable({}, {__index = _fct_metatable}) - self.parent = component_script + local self = setmetatable({}, { __index = _fct_metatable }) + -- Druid context here (who created druid) + -- Usually gui_script, but can be component from helper.get_druid(component) + self._context = component_script return self end @@ -77,9 +81,10 @@ end local function create(self, module) - local instance = setmetatable({}, {__index = module}) - instance.parent = self - self[#self + 1] = instance + local instance = setmetatable({}, { __index = module }) + -- Component context, self from component creation + instance.context = self._context + table.insert(self, instance) local register_to = module.interest if register_to then @@ -89,13 +94,14 @@ local function create(self, module) if not self[v] then self[v] = {} end - self[v][#self[v] + 1] = instance + table.insert(self[v], instance) if const.UI_INPUT[v] then input_init(self) end end end + return instance end diff --git a/druid/helper.lua b/druid/helper.lua index c7c7a36..1a3a893 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -148,4 +148,10 @@ function M.get_pivot_offset(pivot) end +function M.get_druid(self) + local context = { _context = self } + return setmetatable(context, { __index = self.context.druid }) +end + + return M diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index 87c9b10..793c9d5 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -1,6 +1,7 @@ --- Component for rich progress component -- @module rich.progress_rich +local helper = require("druid.helper") local settings = require("druid.settings") local pr_settings = settings.progress_rich @@ -8,9 +9,10 @@ local M = {} function M.init(self, name, red, green, key) - self.red = self.parent:new_progress(red, key) - self.green = self.parent:new_progress(green, key) - self.fill = self.parent:new_progress(name, key) + self.druid = helper.get_druid(self) + self.red = self.druid:new_progress(red, key) + self.green = self.druid:new_progress(green, key) + self.fill = self.druid:new_progress(name, key) end From 89933dfaf5fccedf15164051c17d00ececadab13 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 22:39:46 +0300 Subject: [PATCH 073/136] Close TODO on self context --- druid/base/checkbox.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 6c3075d..7725082 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -31,7 +31,6 @@ function M.get_state(self) end --- TODO: pass self as first parameter local function on_click(self) M.set_state(self, not self.state) end From efef4d194d8c77768b319c2290ca8673bcc0f08c Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 5 Dec 2019 23:40:17 +0300 Subject: [PATCH 074/136] Add first implementation of druid styles (only button) --- druid/base/button.lua | 118 +++++------------------- druid/druid.lua | 14 ++- druid/settings.lua | 7 +- druid/styles/bounce/anims.lua | 26 ++++++ druid/styles/bounce/const.lua | 14 +++ druid/styles/bounce/style.lua | 37 ++++++++ example/example.gui.gui_script | 2 +- example/kenney/gui/main/main.gui_script | 2 + example/kenney/page/main.lua | 7 +- 9 files changed, 120 insertions(+), 107 deletions(-) create mode 100644 druid/styles/bounce/anims.lua create mode 100644 druid/styles/bounce/const.lua create mode 100644 druid/styles/bounce/style.lua diff --git a/druid/base/button.lua b/druid/base/button.lua index 8a11e86..5eba022 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -6,21 +6,15 @@ -- Repeated tap local const = require("druid.const") -local ui_animate = require("druid.helper.druid_animate") local settings = require("druid.settings") -local helper = require("druid.helper") local b_settings = settings.button +local helper = require("druid.helper") local M = {} M.interest = { const.ON_INPUT } -M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0) -M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1) -M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 1) -M.DEFAULT_ACTIVATION_TIME = 0.2 - --- Component init function -- @function button:init @@ -31,37 +25,26 @@ M.DEFAULT_ACTIVATION_TIME = 0.2 -- @tparam[opt] node anim_node Button anim node (node, if not provided) -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) + assert(callback, "Button should have callback. To block input on zone use blocker component") + self.style = self.druid_style.BUTTON or {} + self.node = helper.node(node) self.event = const.ACTION_TOUCH self.anim_node = anim_node and helper.node(anim_node) or self.node self.scale_from = gui.get_scale(self.anim_node) - self.scale_to = self.scale_from + b_settings.SCALE_CHANGE - self.scale_hover_to = self.scale_from + b_settings.HOVER_SCALE self.pos = gui.get_position(self.anim_node) self.callback = callback self.params = params - self.tap_anim = M.tap_scale_animation - self.back_anim = M.back_scale_animation self.hover_anim = b_settings.IS_HOVER - self.sound = b_settings.BTN_SOUND - self.sound_disable = b_settings.BTN_SOUND_DISABLED self.click_zone = nil - - -- TODO: to separate component "block_input"? - -- If callback is nil, so the buttons is stub and without anim - -- Used for zones, what should dont pass the input to other UI elements - if not callback then - self.stub = true - self.hover_anim = false - self.callback = function() end - end end local function set_hover(self, state) - if self.hover_anim and self._is_hovered ~= state then - local target_scale = state and self.scale_hover_to or self.scale_from - ui_animate.scale(self, self.anim_node, target_scale, b_settings.HOVER_TIME) + if self._is_hovered ~= state then + if self.style.on_hover then + self.style.on_hover(self, self.anim_node, state) + end self._is_hovered = state end end @@ -71,17 +54,18 @@ local function on_button_release(self) if not self.disabled then if not self.stub and self.can_action then self.can_action = false - if self.tap_anim then - self.tap_anim(self) + if self.style.on_click then + self.style.on_click(self, self.anim_node) end self.callback(self.context, self.params, self) - settings.play_sound(self.sound) else set_hover(self, false) end return true else - settings.play_sound(self.sound_disable) + if self.style.on_click_disabled then + self.style.on_click_disabled(self, self.anim_node) + end return false end end @@ -129,76 +113,20 @@ function M.on_swipe(self) end -function M.tap_scale_animation(self) - ui_animate.scale_to(self, self.anim_node, self.scale_to, - function() - if self.back_anim then - self.back_anim(self) - end - end - ) -end +function M.set_enabled(self, state) + -- if self.disabled == state then + -- return + -- end - -function M.back_scale_animation(self) - ui_animate.scale_to(self, self.anim_node, self.scale_from) -end - - -function M.deactivate(self, is_animate, callback) - self.disabled = true - if is_animate then - -- callback call three times in gui.animation - local clbk = helper.after(3, function() - if callback then - callback(self.context) - end - end) - - ui_animate.color(self, self.node, M.DEFAULT_DEACTIVATE_COLOR, - clbk, M.DEFAULT_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) - - ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.x, - M.DEFAULT_DEACTIVATE_SCALE.x, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - - ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_ACTIVATE_SCALE.y, - M.DEFAULT_DEACTIVATE_SCALE.y, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - else - gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR) - gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE) - if callback then - callback(self.context) - end + self.disabled = not state + if self.style.on_set_enabled then + self.style.on_set_enabled(self, self.node, state) end end -function M.activate(self, is_animate, callback) - if is_animate then - -- callback call three times in gui.animation - local clbk = helper.after(3, function() - self.disabled = false - if callback then - callback(self.context) - end - end) - - ui_animate.color(self, self.node, ui_animate.TINT_SHOW, - clbk, M.DEFAULT_ACTIVATION_TIME, 0, gui.EASING_OUTBOUNCE) - - ui_animate.scale_y_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.x, - M.DEFAULT_ACTIVATE_SCALE.x, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - - ui_animate.scale_x_from_to(self, self.node, M.DEFAULT_DEACTIVATE_SCALE.y, - M.DEFAULT_ACTIVATE_SCALE.y, clbk, M.DEFAULT_ACTIVATION_TIME, gui.EASING_OUTBOUNCE) - else - gui.set_color(self.node, ui_animate.TINT_SHOW) - gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE) - self.disabled = false - if callback then - callback(self.context) - end - end +function M.get_enabled(self) + return not self.disabled end @@ -207,8 +135,6 @@ end -- @tparam table self Component instance function M.disable_animation(self) self.hover_anim = false - self.tap_anim = nil - self.back_anim = nil end diff --git a/druid/druid.lua b/druid/druid.lua index ce533c3..92988db 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -12,6 +12,8 @@ local M = {} local log = settings.log local _fct_metatable = {} +-- Temporary, what the place for it? +local default_style = {} --- Basic components M.comps = { @@ -57,9 +59,9 @@ function M.register(name, module) end ---- Create UI instance for ui elements +--- Create Druid instance for creating components -- @return instance with all ui components -function M.new(component_script) +function M.new(component_script, style) if register_basic_components then register_basic_components() register_basic_components = false @@ -68,10 +70,16 @@ function M.new(component_script) -- Druid context here (who created druid) -- Usually gui_script, but can be component from helper.get_druid(component) self._context = component_script + self._style = style or default_style return self end +function M.set_default_style(style) + default_style = style +end + + local function input_init(self) if not self.input_inited then self.input_inited = true @@ -80,10 +88,12 @@ local function input_init(self) end +-- Create the component local function create(self, module) local instance = setmetatable({}, { __index = module }) -- Component context, self from component creation instance.context = self._context + instance.druid_style = self._style table.insert(self, instance) local register_to = module.interest diff --git a/druid/settings.lua b/druid/settings.lua index d0b51d5..5c5e68b 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -7,12 +7,7 @@ local M = {} M.is_debug = false M.button = { IS_HOVER = true, - IS_HOLD = true, - BTN_SOUND = "click", - BTN_SOUND_DISABLED = "click_disabled", - HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), - HOVER_TIME = 0.05, - SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), + IS_HOLD = true } M.progress = { diff --git a/druid/styles/bounce/anims.lua b/druid/styles/bounce/anims.lua new file mode 100644 index 0000000..bb642a6 --- /dev/null +++ b/druid/styles/bounce/anims.lua @@ -0,0 +1,26 @@ +local ui_animate = require("druid.helper.druid_animate") + + +local M = {} + + +function M.back_scale_animation(self, node, target_scale) + ui_animate.scale_to(self, node, target_scale) +end + + +function M.tap_scale_animation(self, node, target_scale) + ui_animate.scale_to(self, node, target_scale, + function() + M.back_scale_animation(self, node, self.scale_from) + end + ) +end + + +function M.hover_scale(self, target, time) + ui_animate.scale(self, self.anim_node, target, time) +end + + +return M diff --git a/druid/styles/bounce/const.lua b/druid/styles/bounce/const.lua new file mode 100644 index 0000000..f497323 --- /dev/null +++ b/druid/styles/bounce/const.lua @@ -0,0 +1,14 @@ +local M = {} + + +M.BUTTON = { + HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), + HOVER_TIME = 0.05, + SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), + BTN_SOUND = "click", + BTN_SOUND_DISABLED = "click", + DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), + ENABLED_COLOR = vmath.vector4(1), +} + +return M diff --git a/druid/styles/bounce/style.lua b/druid/styles/bounce/style.lua new file mode 100644 index 0000000..f05d840 --- /dev/null +++ b/druid/styles/bounce/style.lua @@ -0,0 +1,37 @@ +local settings = require("druid.settings") +local anims = require("druid.styles.bounce.anims") +local const = require("druid.styles.bounce.const") + +local M = {} + + +M.BUTTON = { + on_hover = function(self, node, state) + if self.hover_anim then + local scale_to = self.scale_from + const.BUTTON.HOVER_SCALE + + local target_scale = state and scale_to or self.scale_from + anims.hover_scale(self, target_scale, const.BUTTON.HOVER_TIME) + end + end, + + on_click = function(self, node) + local scale_to = self.scale_from + const.BUTTON.SCALE_CHANGE + anims.tap_scale_animation(self, node, scale_to) + settings.play_sound(const.BUTTON.BTN_SOUND) + end, + + on_click_disabled = function(self, node) + settings.play_sound(const.BUTTON.BTN_SOUND_DISABLED) + end, + + on_set_enabled = function(self, node, state) + if state then + gui.set_color(node, const.BUTTON.ENABLED_COLOR) + else + gui.set_color(node, const.BUTTON.DISABLED_COLOR) + end + end +} + +return M diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index 1acb004..b640db7 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -58,7 +58,7 @@ local function init_progress(self) local simple = self.druid:new_progress("simple_fill", "x", val) local vert = self.druid:new_progress("simple_vert_fill", "y", val) - simple:set_steps({0, 0.3, 0.6, 1}, function(self, step) + simple:set_steps({0, 0.3, 0.6, 1}, function(_, step) print("STEP:", step) end) diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 9734c99..949418b 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -1,4 +1,5 @@ local druid = require("druid.druid") +local bounce_style = require("druid.styles.bounce.style") local main_page = require("example.kenney.page.main") @@ -15,6 +16,7 @@ end function init(self) + druid.set_default_style(bounce_style) self.druid = druid.new(self) init_top_panel(self) diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 7c00641..225f1cb 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -17,8 +17,11 @@ end local function setup_button(self) - self.druid:new_button("button_simple", lang.toggle_locale, "button_param") - self.druid:new_button("button_template/button", empty_callback, "button_param") + local b = self.druid:new_button("button_simple", lang.toggle_locale, "button_param") + self.druid:new_button("button_template/button", function() + print(b:get_enabled()) + b:set_enabled(not b:get_enabled()) + end, "button_param") end From 125506a4f1755c24746dfd9c7845c89b74dbbe7a Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 10 Jan 2020 16:01:32 +0500 Subject: [PATCH 075/136] Separate style progrese --- druid/base/button.lua | 8 +++---- druid/base/progress.lua | 12 ++++------ druid/base/scroll.lua | 36 +++++++++++++++------------- druid/druid.lua | 3 +++ druid/helper.lua | 11 +++++++++ druid/rich/progress_rich.lua | 7 +++--- druid/settings.lua | 25 +------------------ druid/styles/bounce/const.lua | 14 ----------- druid/styles/bounce/style.lua | 45 ++++++++++++++++++++++++++++------- 9 files changed, 81 insertions(+), 80 deletions(-) delete mode 100644 druid/styles/bounce/const.lua diff --git a/druid/base/button.lua b/druid/base/button.lua index 5eba022..5398ac6 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -6,8 +6,6 @@ -- Repeated tap local const = require("druid.const") -local settings = require("druid.settings") -local b_settings = settings.button local helper = require("druid.helper") local M = {} @@ -26,16 +24,16 @@ M.interest = { -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) assert(callback, "Button should have callback. To block input on zone use blocker component") - self.style = self.druid_style.BUTTON or {} - + self.style = helper.get_style(self, "BUTTON") self.node = helper.node(node) + self.event = const.ACTION_TOUCH self.anim_node = anim_node and helper.node(anim_node) or self.node self.scale_from = gui.get_scale(self.anim_node) self.pos = gui.get_position(self.anim_node) self.callback = callback self.params = params - self.hover_anim = b_settings.IS_HOVER + self.hover_anim = self.style.IS_HOVER self.click_zone = nil end diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 450f2a4..5a5778b 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -3,8 +3,6 @@ local const = require("druid.const") local helper = require("druid.helper") -local settings = require("druid.settings") -local p_settings = settings.progress local M = {} @@ -20,14 +18,12 @@ M.interest = { -- @tparam string key Progress bar direction (x or y) -- @tparam number init_value Initial value of progress bar function M.init(self, node, key, init_value) - if key ~= const.SIDE.X and key ~= const.SIDE.Y then - settings.log("progress component: key must be 'x' or 'y'. Passed:", key) - key = const.SIDE.X - end + assert(key == const.SIDE.X or const.SIDE.Y, "Progress bar key should be 'x' or 'y'") self.prop = hash("scale."..key) self.key = key + self.style = helper.get_style(self, "PROGRESS") self.node = helper.node(node) self.scale = gui.get_scale(self.node) self.size = gui.get_size(self.node) @@ -152,8 +148,8 @@ end function M.update(self, dt) if self.target then local prev_value = self.last_value - local step = math.abs(self.last_value - self.target) * (p_settings.SPEED*dt) - step = math.max(step, p_settings.MIN_DELTA) + local step = math.abs(self.last_value - self.target) * (self.style.SPEED*dt) + step = math.max(step, self.style.MIN_DELTA) self:set_to(helper.step(self.last_value, self.target, step)) if self.last_value == self.target then diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index e3e79ee..798d326 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -3,7 +3,6 @@ local helper = require("druid.helper") local const = require("druid.const") -local settings = require("druid.settings").scroll local M = {} @@ -18,10 +17,12 @@ M.current_scroll = nil function M.init(self, scroll_parent, input_zone, border) + self.style = helper.get_style(self, "SCROLL") self.node = helper.node(scroll_parent) self.input_zone = helper.node(input_zone) + self.zone_size = gui.get_size(self.input_zone) - self.soft_size = settings.SOFT_ZONE_SIZE + self.soft_size = self.style.SOFT_ZONE_SIZE -- Distance from node to node's center local offset = helper.get_pivot_offset(gui.get_pivot(self.input_zone)) @@ -61,16 +62,16 @@ local function check_soft_target(self) local b = self.border if t.y < b.y then - t.y = helper.step(t.y, b.y, math.abs(t.y - b.y) * settings.BACK_SPEED) + t.y = helper.step(t.y, b.y, math.abs(t.y - b.y) * self.style.BACK_SPEED) end if t.x < b.x then - t.x = helper.step(t.x, b.x, math.abs(t.x - b.x) * settings.BACK_SPEED) + t.x = helper.step(t.x, b.x, math.abs(t.x - b.x) * self.style.BACK_SPEED) end if t.y > b.w then - t.y = helper.step(t.y, b.w, math.abs(t.y - b.w) * settings.BACK_SPEED) + t.y = helper.step(t.y, b.w, math.abs(t.y - b.w) * self.style.BACK_SPEED) end if t.x > b.z then - t.x = helper.step(t.x, b.z, math.abs(t.x - b.z) * settings.BACK_SPEED) + t.x = helper.step(t.x, b.z, math.abs(t.x - b.z) * self.style.BACK_SPEED) end end @@ -94,8 +95,8 @@ local function update_hand_scroll(self, dt) inert.x = math.abs(inert.x) * helper.sign(delta_x) inert.y = math.abs(inert.y) * helper.sign(delta_y) - inert.x = inert.x * settings.FRICT_HOLD - inert.y = inert.y * settings.FRICT_HOLD + inert.x = inert.x * self.style.FRICT_HOLD + inert.y = inert.y * self.style.FRICT_HOLD set_pos(self, self.target) end @@ -116,11 +117,11 @@ local function check_points(self) local inert = self.inert if not self.is_inert then - if math.abs(inert.x) > settings.DEADZONE then + if math.abs(inert.x) > self.style.DEADZONE then self:scroll_to_index(self.selected - helper.sign(inert.x)) return end - if math.abs(inert.y) > settings.DEADZONE then + if math.abs(inert.y) > self.style.DEADZONE then self:scroll_to_index(self.selected + helper.sign(inert.y)) return end @@ -154,13 +155,14 @@ local function check_points(self) temp_dist_on_inert = dist end end + self:scroll_to_index(index_on_inert or index) end local function check_threshold(self) local inert = self.inert - if not self.is_inert or vmath.length(inert) < settings.INERT_THRESHOLD then + if not self.is_inert or vmath.length(inert) < self.style.INERT_THRESHOLD then check_points(self) inert.x = 0 inert.y = 0 @@ -171,11 +173,11 @@ end local function update_free_inert(self, dt) local inert = self.inert if inert.x ~= 0 or inert.y ~= 0 then - self.target.x = self.pos.x + (inert.x * dt * settings.INERT_SPEED) - self.target.y = self.pos.y + (inert.y * dt * settings.INERT_SPEED) + self.target.x = self.pos.x + (inert.x * dt * self.style.INERT_SPEED) + self.target.y = self.pos.y + (inert.y * dt * self.style.INERT_SPEED) - inert.x = inert.x * settings.FRICT - inert.y = inert.y * settings.FRICT + inert.x = inert.x * self.style.FRICT + inert.y = inert.y * self.style.FRICT -- Stop, when low inert speed and go to points check_threshold(self) @@ -275,7 +277,7 @@ function M.on_input(self, action_id, action) self.target.y = self.pos.y else local dist = helper.distance(action.x, action.y, inp.start_x, inp.start_y) - if not M.current_scroll and dist >= settings.DEADZONE then + if not M.current_scroll and dist >= self.style.DEADZONE then local dx = math.abs(inp.start_x - action.x) local dy = math.abs(inp.start_y - action.y) inp.side = (dx > dy) and const.SIDE.X or const.SIDE.Y @@ -331,7 +333,7 @@ function M.scroll_to(self, point, is_instant) self.target = target set_pos(self, target) else - gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function() + gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, self.style.ANIM_SPEED, 0, function() self.animate = false self.target = target set_pos(self, target) diff --git a/druid/druid.lua b/druid/druid.lua index 92988db..3f9e40f 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -4,17 +4,20 @@ -- to create your own rich components. -- @module druid + local const = require("druid.const") local druid_input = require("druid.helper.druid_input") local settings = require("druid.settings") local M = {} + local log = settings.log local _fct_metatable = {} -- Temporary, what the place for it? local default_style = {} + --- Basic components M.comps = { button = require("druid.base.button"), diff --git a/druid/helper.lua b/druid/helper.lua index 1a3a893..5c66d14 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,10 +1,12 @@ --- Druid helper module -- @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 @@ -154,4 +156,13 @@ function M.get_druid(self) end +function M.get_style(self, section) + if not self.druid_style then + return {} + end + + return self.druid_style[section] or {} +end + + return M diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index 793c9d5..277e435 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -2,14 +2,13 @@ -- @module rich.progress_rich local helper = require("druid.helper") -local settings = require("druid.settings") -local pr_settings = settings.progress_rich local M = {} function M.init(self, name, red, green, key) self.druid = helper.get_druid(self) + self.style = helper.get_style(self, "PROGRESS_RICH") self.red = self.druid:new_progress(red, key) self.green = self.druid:new_progress(green, key) self.fill = self.druid:new_progress(name, key) @@ -51,7 +50,7 @@ function M.to(self, to, callback) if self.fill.last_value < to then self.red:to(self.fill.last_value) self.green:to(to, function() - self.timer = timer.delay(pr_settings.DELAY, false, function() + self.timer = timer.delay(self.style.DELAY, false, function() self.red:to(to) self.fill:to(to, callback) end) @@ -61,7 +60,7 @@ function M.to(self, to, callback) if self.fill.last_value > to then self.green:to(self.red.last_value) self.fill:to(to, function() - self.timer = timer.delay(pr_settings.DELAY, false, function() + self.timer = timer.delay(self.style.DELAY, false, function() self.green:to(to) self.red:to(to, callback) end) diff --git a/druid/settings.lua b/druid/settings.lua index 5c5e68b..3529af5 100644 --- a/druid/settings.lua +++ b/druid/settings.lua @@ -3,32 +3,9 @@ local M = {} --- TODO: to JSON? + M.is_debug = false -M.button = { - IS_HOVER = true, - IS_HOLD = true -} -M.progress = { - SPEED = 5, -- progress bar fill rate, more faster - MIN_DELTA = 0.005 -} - -M.progress_rich = { - DELAY = 1, -- delay in seconds before main fill -} - -M.scroll = { - FRICT_HOLD = 0.8, -- mult. for inert, while touching - FRICT = 0.93, -- mult for free inert - INERT_THRESHOLD = 2, -- speed to stop inertion - INERT_SPEED = 25, -- koef. of inert speed - DEADZONE = 6, -- in px - SOFT_ZONE_SIZE = 160, -- size of outside zone (back move) - BACK_SPEED = 0.2, -- lerp speed - ANIM_SPEED = 0.3, -- gui.animation speed to point -} function M.get_text(name) -- override to get text for localized text diff --git a/druid/styles/bounce/const.lua b/druid/styles/bounce/const.lua deleted file mode 100644 index f497323..0000000 --- a/druid/styles/bounce/const.lua +++ /dev/null @@ -1,14 +0,0 @@ -local M = {} - - -M.BUTTON = { - HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), - HOVER_TIME = 0.05, - SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), - BTN_SOUND = "click", - BTN_SOUND_DISABLED = "click", - DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), - ENABLED_COLOR = vmath.vector4(1), -} - -return M diff --git a/druid/styles/bounce/style.lua b/druid/styles/bounce/style.lua index f05d840..add520f 100644 --- a/druid/styles/bounce/style.lua +++ b/druid/styles/bounce/style.lua @@ -1,37 +1,66 @@ local settings = require("druid.settings") local anims = require("druid.styles.bounce.anims") -local const = require("druid.styles.bounce.const") local M = {} M.BUTTON = { + HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), + HOVER_TIME = 0.05, + SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), + BTN_SOUND = "click", + BTN_SOUND_DISABLED = "click", + DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), + ENABLED_COLOR = vmath.vector4(1), + IS_HOVER = true, + on_hover = function(self, node, state) if self.hover_anim then - local scale_to = self.scale_from + const.BUTTON.HOVER_SCALE + local scale_to = self.scale_from + M.BUTTON.HOVER_SCALE local target_scale = state and scale_to or self.scale_from - anims.hover_scale(self, target_scale, const.BUTTON.HOVER_TIME) + anims.hover_scale(self, target_scale, M.BUTTON.HOVER_TIME) end end, on_click = function(self, node) - local scale_to = self.scale_from + const.BUTTON.SCALE_CHANGE + local scale_to = self.scale_from + M.BUTTON.SCALE_CHANGE anims.tap_scale_animation(self, node, scale_to) - settings.play_sound(const.BUTTON.BTN_SOUND) + settings.play_sound(M.BUTTON.BTN_SOUND) end, on_click_disabled = function(self, node) - settings.play_sound(const.BUTTON.BTN_SOUND_DISABLED) + settings.play_sound(M.BUTTON.BTN_SOUND_DISABLED) end, on_set_enabled = function(self, node, state) if state then - gui.set_color(node, const.BUTTON.ENABLED_COLOR) + gui.set_color(node, M.BUTTON.ENABLED_COLOR) else - gui.set_color(node, const.BUTTON.DISABLED_COLOR) + gui.set_color(node, M.BUTTON.DISABLED_COLOR) end end } + +M.SCROLL = { + FRICT_HOLD = 0.8, -- mult. for inert, while touching + FRICT = 0.93, -- mult for free inert + INERT_THRESHOLD = 2, -- speed to stop inertion + INERT_SPEED = 25, -- koef. of inert speed + DEADZONE = 6, -- in px + SOFT_ZONE_SIZE = 160, -- size of outside zone (back move) + BACK_SPEED = 0.2, -- lerp speed + ANIM_SPEED = 0.3, -- gui.animation speed to point +} + +M.PROGRESS = { + SPEED = 5, -- progress bar fill rate, more faster + MIN_DELTA = 0.005 +} + +M.PROGRESS_RICH = { + DELAY = 1, -- delay in seconds before main fill +} + return M From 8f32b61ddc21badea066efcb4f5159059423bf1d Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 10 Jan 2020 16:44:05 +0500 Subject: [PATCH 076/136] Start add empty druid style --- druid/base/checkbox.lua | 11 +++---- druid/base/scroll.lua | 1 + druid/styles/bounce/style.lua | 11 +++++++ druid/styles/empty/style.lua | 43 +++++++++++++++++++++++++ example/kenney/gui/main/main.gui_script | 3 +- 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 druid/styles/empty/style.lua diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 7725082..d7406be 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -6,19 +6,15 @@ local helper = require("druid.helper") local M = {} -local function state_animate(node, state) - local target = state and 1 or 0 - gui.animate(node, "color.w", target, gui.EASING_OUTSINE, 0.1) -end - - function M.set_state(self, state, is_silence) if self.state == state then return end self.state = state - state_animate(self.node, state) + if self.style.on_change_state then + self.style.on_change_state(self, self.node, state) + end if not is_silence and self.callback then self.callback(self.context, state) @@ -37,6 +33,7 @@ end function M.init(self, node, callback, click_node) + self.style = helper.get_style(self, "CHECKBOX") self.druid = helper.get_druid(self) self.node = helper.node(node) self.click_node = helper.node(click_node) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 798d326..fa5d169 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -215,6 +215,7 @@ local function add_delta(self, dx, dy) local t = self.target local b = self.border local soft = self.soft_size + -- TODO: Can we calc it more easier? -- A lot of calculations for every side of border diff --git a/druid/styles/bounce/style.lua b/druid/styles/bounce/style.lua index add520f..2acd7e9 100644 --- a/druid/styles/bounce/style.lua +++ b/druid/styles/bounce/style.lua @@ -54,13 +54,24 @@ M.SCROLL = { ANIM_SPEED = 0.3, -- gui.animation speed to point } + M.PROGRESS = { SPEED = 5, -- progress bar fill rate, more faster MIN_DELTA = 0.005 } + M.PROGRESS_RICH = { DELAY = 1, -- delay in seconds before main fill } + +M.CHECKBOX = { + on_change_state = function(self, node, state) + local target = state and 1 or 0 + gui.animate(node, "color.w", target, gui.EASING_OUTSINE, 0.1) + end +} + + return M diff --git a/druid/styles/empty/style.lua b/druid/styles/empty/style.lua new file mode 100644 index 0000000..10f627d --- /dev/null +++ b/druid/styles/empty/style.lua @@ -0,0 +1,43 @@ +local M = {} + + +M.BUTTON = { + BTN_SOUND = "click", + BTN_SOUND_DISABLED = "click", + DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), + ENABLED_COLOR = vmath.vector4(1), + IS_HOVER = false, +} + + +M.SCROLL = { + FRICT_HOLD = 0, -- mult. for inert, while touching + FRICT = 0, -- mult for free inert + INERT_THRESHOLD = 2, -- speed to stop inertion + INERT_SPEED = 0, -- koef. of inert speed + DEADZONE = 6, -- in px + SOFT_ZONE_SIZE = 20, -- size of outside zone (back move) + BACK_SPEED = 0, -- lerp speed + ANIM_SPEED = 0, -- gui.animation speed to point +} + + +M.PROGRESS = { + SPEED = 5, -- progress bar fill rate, more faster + MIN_DELTA = 1 +} + + +M.PROGRESS_RICH = { + DELAY = 0, -- delay in seconds before main fill +} + + +M.CHECKBOX = { + on_change_state = function(self, node, state) + gui.set_enabled(node, state) + end +} + + +return M diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 949418b..c0b923b 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -1,5 +1,6 @@ local druid = require("druid.druid") local bounce_style = require("druid.styles.bounce.style") +local empty_style = require("druid.styles.empty.style") local main_page = require("example.kenney.page.main") @@ -16,7 +17,7 @@ end function init(self) - druid.set_default_style(bounce_style) + druid.set_default_style(empty_style) self.druid = druid.new(self) init_top_panel(self) From c3752dba547f87a8140b16795848df3b7683b0aa Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 11 Jan 2020 02:14:14 +0500 Subject: [PATCH 077/136] Separate text on text and locale components. Auto adjust text sizing --- druid/base/locale.lua | 47 +++++++++++++++++++++++++++++++++ druid/base/text.lua | 60 +++++++++++++++++++------------------------ druid/druid.lua | 1 + 3 files changed, 74 insertions(+), 34 deletions(-) create mode 100644 druid/base/locale.lua diff --git a/druid/base/locale.lua b/druid/base/locale.lua new file mode 100644 index 0000000..3dc914b --- /dev/null +++ b/druid/base/locale.lua @@ -0,0 +1,47 @@ +--- Component to handle all GUI texts +-- Good working with localization system +-- @module base.text + +local const = require("druid.const") +local settings = require("druid.settings") +local helper = require("druid.helper") + +local M = {} +M.interest = { + const.ON_CHANGE_LANGUAGE, +} + + +function M.init(self, node, lang_id) + self.druid = helper.get_druid(self) + self.text = self.druid:new_text(node) + self:translate(lang_id) + + return self +end + + +function M.raw_set(self, text) + self.last_locale = false + self.text:set_to(text) +end + + +--- Translate the text by locale_id +-- @function text:translate +-- @tparam table self Component instance +-- @tparam string locale_id Locale id +function M.translate(self, locale_id) + self.last_locale = locale_id or self.last_locale + self.text:set_to(settings.get_text(self.last_locale)) +end + + +function M.on_change_language(self) + if self.last_locale then + M.translate(self) + end +end + + +return M diff --git a/druid/base/text.lua b/druid/base/text.lua index f04bbf7..17feddd 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -2,57 +2,44 @@ -- Good working with localization system -- @module base.text -local const = require("druid.const") -local settings = require("druid.settings") local helper = require("druid.helper") local M = {} -M.interest = { - const.ON_CHANGE_LANGUAGE, -} +M.interest = {} -function M.init(self, node, value, is_locale, max_width) - self.max_width = max_width +function M.init(self, node, value, no_text_adjust) self.node = helper.node(node) self.start_scale = gui.get_scale(self.node) + self.start_pivot = gui.get_pivot(self.node) + + self.text_area = gui.get_size(self.node) + self.text_area.x = self.text_area.x * self.start_scale.x + self.text_area.y = self.text_area.y * self.start_scale.y + + self.is_no_text_adjust = no_text_adjust self.scale = self.start_scale self.last_color = gui.get_color(self.node) - if is_locale then - self:translate(value) - else - self:set_to(value or 0) - end - + self:set_to(value or 0) return self end ---- Translate the text by locale_id --- @function text:translate --- @tparam table self Component instance --- @tparam string locale_id Locale id -function M.translate(self, locale_id) - self.last_locale = locale_id or self.last_locale - self:set_to(settings.get_text(self.last_locale)) -end - - -function M.on_change_language(self) - if self.last_locale then - M.translate(self) - end -end - - --- Setup scale x, but can only be smaller, than start text scale -local function setup_max_width(self) +local function update_text_area_size(self) + local max_width = self.text_area.x + local max_height = self.text_area.y + local metrics = gui.get_text_metrics_from_node(self.node) local cur_scale = gui.get_scale(self.node) - local scale_modifier = self.max_width / metrics.width + local scale_modifier = max_width / metrics.width scale_modifier = math.min(scale_modifier, self.start_scale.x) + + local scale_modifier_height = max_height / metrics.height + scale_modifier = math.min(scale_modifier, scale_modifier_height) + local new_scale = vmath.vector3(scale_modifier, scale_modifier, cur_scale.z) gui.set_scale(self.node, new_scale) self.scale = new_scale @@ -67,8 +54,8 @@ function M.set_to(self, set_to) self.last_value = set_to gui.set_text(self.node, set_to) - if self.max_width then - setup_max_width(self) + if not self.is_no_text_adjust then + update_text_area_size(self) end end @@ -103,4 +90,9 @@ function M.set_scale(self, scale) end +function M.set_pivot(self, pivot) + +end + + return M diff --git a/druid/druid.lua b/druid/druid.lua index 3f9e40f..161a4c0 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -24,6 +24,7 @@ M.comps = { blocker = require("druid.base.blocker"), back_handler = require("druid.base.back_handler"), text = require("druid.base.text"), + locale = require("druid.base.locale"), timer = require("druid.base.timer"), progress = require("druid.base.progress"), grid = require("druid.base.grid"), From 59c9dc8a9bfb5fe25e2007dc3a1a081b15cfcac2 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 11 Jan 2020 15:04:53 +0500 Subject: [PATCH 078/136] Add set_pivot to text component --- druid/base/locale.lua | 4 +-- druid/base/text.lua | 34 ++++++++++++++++++++----- druid/const.lua | 2 +- example/kenney/gui/main/main.gui | 2 +- example/kenney/gui/main/main.gui_script | 3 ++- example/kenney/page/main.lua | 18 ++++++------- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/druid/base/locale.lua b/druid/base/locale.lua index 3dc914b..b53a8cf 100644 --- a/druid/base/locale.lua +++ b/druid/base/locale.lua @@ -12,9 +12,9 @@ M.interest = { } -function M.init(self, node, lang_id) +function M.init(self, node, lang_id, no_adjust) self.druid = helper.get_druid(self) - self.text = self.druid:new_text(node) + self.text = self.druid:new_text(node, lang_id, no_adjust) self:translate(lang_id) return self diff --git a/druid/base/text.lua b/druid/base/text.lua index 17feddd..2df969c 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -2,23 +2,27 @@ -- Good working with localization system -- @module base.text +local const = require("druid.const") local helper = require("druid.helper") local M = {} -M.interest = {} -function M.init(self, node, value, no_text_adjust) +function M.init(self, node, value, no_adjust) self.node = helper.node(node) - self.start_scale = gui.get_scale(self.node) self.start_pivot = gui.get_pivot(self.node) + self.start_pos = gui.get_position(self.node) + self.pos = gui.get_position(self.node) + + self.start_scale = gui.get_scale(self.node) + self.scale = gui.get_scale(self.node) + self.text_area = gui.get_size(self.node) self.text_area.x = self.text_area.x * self.start_scale.x self.text_area.y = self.text_area.y * self.start_scale.y - self.is_no_text_adjust = no_text_adjust - self.scale = self.start_scale + self.is_no_adjust = no_adjust self.last_color = gui.get_color(self.node) self:set_to(value or 0) @@ -54,7 +58,7 @@ function M.set_to(self, set_to) self.last_value = set_to gui.set_text(self.node, set_to) - if not self.is_no_text_adjust then + if not self.is_no_adjust then update_text_area_size(self) end end @@ -90,8 +94,26 @@ function M.set_scale(self, scale) end +--- Set text pivot. Text will re-anchor inside +-- his text area +-- @function text:set_pivot +-- @tparam table self Component instance +-- @tparam gui.pivot pivot Gui pivot constant function M.set_pivot(self, pivot) + local prev_pivot = gui.get_pivot(self.node) + local prev_offset = const.PIVOTS[prev_pivot] + gui.set_pivot(self.node, pivot) + local cur_offset = const.PIVOTS[pivot] + + local pos_offset = vmath.vector3( + self.text_area.x * (cur_offset.x - prev_offset.x), + self.text_area.y * (cur_offset.y - prev_offset.y), + 0 + ) + + self.pos = self.pos + pos_offset + gui.set_position(self.node, self.pos) end diff --git a/druid/const.lua b/druid/const.lua index e199b59..4ac6a3d 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -32,7 +32,7 @@ M.PIVOTS = { [gui.PIVOT_S] = vmath.vector3(0, -0.5, 0), [gui.PIVOT_SW] = vmath.vector3(-0.5, -0.5, 0), [gui.PIVOT_W] = vmath.vector3(-0.5, 0, 0), - [gui.PIVOT_NW] = vmath.vector3(-0.5, -0.5, 0), + [gui.PIVOT_NW] = vmath.vector3(-0.5, 0.5, 0), } M.SIDE = { diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index e92b20c..c6f22c3 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -840,7 +840,7 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "SImple" + text: "Simple" font: "game" id: "text_simple" xanchor: XANCHOR_NONE diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index c0b923b..55a4996 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -12,12 +12,13 @@ end local function init_top_panel(self) self.druid:new_button("button_left/button", on_control_button, "left") self.druid:new_button("button_right/button", on_control_button, "right") - self.header = self.druid:new_text("text_header", "main_page", true) + self.header = self.druid:new_locale("text_header", "main_page") end function init(self) druid.set_default_style(empty_style) + druid.set_default_style(bounce_style) self.druid = druid.new(self) init_top_panel(self) diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 225f1cb..db04392 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -26,17 +26,17 @@ end local function setup_texts(self) - self.druid:new_text("text_button", "ui_section_button", true) - self.druid:new_text("text_text", "ui_section_text", true) - self.druid:new_text("text_timer", "ui_section_timer", true) - self.druid:new_text("text_progress", "ui_section_progress", true) - self.druid:new_text("text_slider", "ui_section_slider", true) - self.druid:new_text("text_radio", "ui_section_radio", true) - self.druid:new_text("text_checkbox", "ui_section_checkbox", true) + self.druid:new_locale("text_button", "ui_section_button") + self.druid:new_locale("text_text", "ui_section_text") + self.druid:new_locale("text_timer", "ui_section_timer") + self.druid:new_locale("text_progress", "ui_section_progress") + self.druid:new_locale("text_slider", "ui_section_slider") + self.druid:new_locale("text_radio", "ui_section_radio") + self.druid:new_locale("text_checkbox", "ui_section_checkbox") + self.druid:new_locale("text_translated", "ui_text_example") + self.druid:new_locale("text_button_lang", "ui_text_change_lang") self.druid:new_text("text_simple", "Simple") - self.druid:new_text("text_translated", "ui_text_example", true) - self.druid:new_text("text_button_lang", "ui_text_change_lang", true, 150 * 0.7) end From 41a820a1fbbeb3146192f1d3838b67a9bd392918 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 11 Jan 2020 15:37:14 +0500 Subject: [PATCH 079/136] Add texts text page --- druid/base/locale.lua | 2 +- example/kenney/gui/main/main.gui | 994 +++++++++++++++++++++++- example/kenney/gui/main/main.gui_script | 30 +- example/kenney/lang.lua | 2 + example/kenney/page/texts.lua | 55 ++ 5 files changed, 1075 insertions(+), 8 deletions(-) create mode 100644 example/kenney/page/texts.lua diff --git a/druid/base/locale.lua b/druid/base/locale.lua index b53a8cf..f2abda7 100644 --- a/druid/base/locale.lua +++ b/druid/base/locale.lua @@ -21,7 +21,7 @@ function M.init(self, node, lang_id, no_adjust) end -function M.raw_set(self, text) +function M.set_to(self, text) self.last_locale = false self.text:set_to(text) end diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index c6f22c3..0d74dfd 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -160,7 +160,7 @@ nodes { xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT + adjust_mode: ADJUST_MODE_STRETCH parent: "C_Anchor" layer: "" inherit_alpha: true @@ -2989,6 +2989,998 @@ nodes { template_node_child: false size_mode: SIZE_MODE_MANUAL } +nodes { + position { + x: 600.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: "kenney/empty" + id: "text_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "C_Anchor" + 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: -250.0 + y: 280.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Inline:" + font: "game" + id: "inline" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -250.0 + y: 190.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Multiline:" + font: "game" + id: "multiline" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -250.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Anchoring:" + font: "game" + id: "anchoring" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -250.0 + y: 10.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "No adjust:" + font: "game" + id: "no_adjust" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -250.0 + y: -80.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Locale:" + font: "game" + id: "locale" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -250.0 + y: -170.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Max Width:" + font: "game" + id: "max_width" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -250.0 + y: -260.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Max height:" + font: "game" + id: "max_height" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: 280.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Inline:" + font: "game" + id: "text_inline" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: 190.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Multiline" + font: "game" + id: "text_multiline" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: true + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.7019608 + y: 0.8 + z: 1.0 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "" + id: "anchoring_zone_visual" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "text_page" + 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: 150.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Anchoring:" + font: "game" + id: "text_anchoring" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: 10.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "No adjust:" + font: "game" + id: "text_no_adjust" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: -80.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Locale:" + font: "game" + id: "text_locale" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: -170.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Max Width:" + font: "game" + id: "text_max_width" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 150.0 + y: -260.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Max height:" + font: "game" + id: "text_max_height" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: true + parent: "text_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} nodes { position { x: 0.0 diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 55a4996..0f9fed2 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -1,28 +1,46 @@ local druid = require("druid.druid") -local bounce_style = require("druid.styles.bounce.style") + local empty_style = require("druid.styles.empty.style") +local bounce_style = require("druid.styles.bounce.style") local main_page = require("example.kenney.page.main") +local text_page = require("example.kenney.page.texts") -local function on_control_button(self, side) - print("Click on button side", side) +local pages = { + "main_page", + "texts_page" +} + +local function on_control_button(self, delta) + self.page = self.page + delta + if self.page < 1 then + self.page = #pages + end + if self.page > #pages then + self.page = 1 + end + + self.header:translate(pages[self.page]) + local node = gui.get_node("C_Anchor") + gui.animate(node, "position.x", (self.page-1) * -600, gui.EASING_OUTSINE, 0.2) end local function init_top_panel(self) - self.druid:new_button("button_left/button", on_control_button, "left") - self.druid:new_button("button_right/button", on_control_button, "right") + self.druid:new_button("button_left/button", on_control_button, -1) + self.druid:new_button("button_right/button", on_control_button, 1) self.header = self.druid:new_locale("text_header", "main_page") end function init(self) - druid.set_default_style(empty_style) druid.set_default_style(bounce_style) self.druid = druid.new(self) init_top_panel(self) + self.page = 1 main_page.setup_page(self) + text_page.setup_page(self) end diff --git a/example/kenney/lang.lua b/example/kenney/lang.lua index d36cef7..43f0f91 100644 --- a/example/kenney/lang.lua +++ b/example/kenney/lang.lua @@ -4,6 +4,7 @@ local M = {} local en = { main_page = "Main page", + texts_page = "Text page", ui_section_button = "Button", ui_section_text = "Text", ui_section_timer = "Timer", @@ -17,6 +18,7 @@ local en = { local ru = { main_page = "Основное", + texts_page = "Текст", ui_section_button = "Кнопка", ui_section_text = "Текст", ui_section_timer = "Таймер", diff --git a/example/kenney/page/texts.lua b/example/kenney/page/texts.lua new file mode 100644 index 0000000..c1386ce --- /dev/null +++ b/example/kenney/page/texts.lua @@ -0,0 +1,55 @@ +local lang = require("example.kenney.lang") + +local M = {} + +local pivots = { + gui.PIVOT_CENTER, + gui.PIVOT_N, + gui.PIVOT_NE, + gui.PIVOT_E, + gui.PIVOT_SE, + gui.PIVOT_S, + gui.PIVOT_SW, + gui.PIVOT_W, + gui.PIVOT_NW +} + +local function setup_texts(self) + self.druid:new_text("text_inline", "Simple inline text") + self.druid:new_text("text_multiline", "Simple multiline text with smth") + local anchoring = self.druid:new_text("text_anchoring", "Anchoring") + self.druid:new_text("text_no_adjust", "Without adjust size", true) + self.druid:new_locale("text_locale", "ui_text_example") + + local big_text = "Check max size" + local width = self.druid:new_text("text_max_width", big_text) + local height = self.druid:new_text("text_max_height", big_text) + + local pivot_index = 1 + timer.delay(0.3, true, function() + anchoring:set_pivot(pivots[pivot_index]) + + pivot_index = pivot_index + 1 + if pivot_index > #pivots then + pivot_index = 1 + end + end) + + timer.delay(0.2, true, function() + big_text = big_text .. " max" + width:set_to(big_text) + height:set_to(big_text) + + if #big_text > 50 then + big_text = "Check max size" + end + end) +end + + +function M.setup_page(self) + setup_texts(self) +end + + +return M From 8eda125d727c0cb9cddbb24763d89691299120ce Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 29 Jan 2020 22:34:21 +0300 Subject: [PATCH 080/136] Update README.md --- README.md | 190 ++++++++++++++++++++++++++++++++++++++++--- media/druid_logo.png | Bin 0 -> 6863 bytes 2 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 media/druid_logo.png diff --git a/README.md b/README.md index 2a8006a..32bfa90 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,187 @@ -# Defold Druid -Defold UI library --- +![](media/druid_logo.png) +_travis/release bages_ -# Install +**Druid** - powerful defold component UI library. Use standart components or make your own game-specific to make amazing GUI in your games. -# Setup +## Setup +#### Dependency +You can use the druid extension in your own project by adding this project as a [Defold library dependency](https://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add: -# Usage +> [https://github.com/AGulev/druid/archive/master.zip](https://github.com/AGulev/druid/archive/master.zip) -# API +Or point to the ZIP file of a [specific release](https://github.com/AGulev/druid/releases). -# LDoc -Generate with `ldoc .` with `config.ld` file +#### Code +Adjust druid settings: +```lua +local settings = require("druid.settings") +settings.play_sound = function(name) + ... +end -Insctruction here: https://github.com/stevedonovan/LDoc +settings.get_text = function(lang_id) + ... +end +``` -# Authors +## Usage -# License +## Components +Druid provides next basic components: +_insert simple gif of each?_ +- **Button** - basic game button +- **Text** - wrap on gui text node +- **Blocker** - block input in node zone +- **Back** Handler - handle back button (Android, backspace) +- **Locale** - localized text node +- **Timer** - run timer on defined time +- **Progress** - simple progress bar +- **Scroll** - general scroll component +- **Grid** - manage node positions +- **Slider** - simple slider (ex. volume adjust) +- **Checkbox** - simple checkbox +- **Checkbox** group - many checkbox +- **Radio** group - many checkbox with single choice + +## Styles +You can setup default style for all druid module, for druid instance or any base druid component. +Setup default druid style via `druid.set_default_style` +```lua +local druid = require("druid.druid") +local my_style = require("my.amazing.style") + +local function init(self) + druid.set_default_style(my_style) +end +``` +_TODO_ + +## Creating components +Any components creating via druid: +```lua +local druid = require("druid.druid") + +local function init(self) + self.druid = druid.new(self) + local button = self.druid:new_button(node_name, callback) + local text = self.druid:new_text(node_text_name) +end + +function update(self, dt) + self.druid:update(dt) +end + +function on_message(self, message_id, message, sender) + self.druid:on_message(message_id, message, sender) +end + +function on_input(self, action_id, action) + self.druid:on_input(action_id, action) +end +``` + +## Custom components + +Add your custom components via `druid.register` +```lua +local druid = require("druid.druid") +local my_component = require("my.amazing.component") + +local function init(self) + druid.register("my_component", my_component) +end +``` + +Basic custom component template looks like this: +```lua +local const = require("druid.const") + +local M = {} +M.interest = { const.ON_INPUT } + +function M.init(self, ...) + -- Component constructor +end + +-- Call only if exist interest: const.ON_UPDATE +function M.update(self, dt) + +end + +-- Call only if exist interest: const.ON_INPUT or const.ON_SWIPE +function M.on_input(self, action_id, action) + +end + +-- Call only if exist interest: const.ON_MESSAGE +function M.on_message(self, message_id, message, sender) + +end + +-- Call only if swipe was started on another component (ex. scroll) +function M.on_swipe(self) + +end + +return M +``` + +## Best practice on custom components +On each component recomended describe component schema in next way: + +```lua +-- Component module +local helper = require("druid.helper") + +local M = {} + +local SCHEME = { + ROOT = "/root", + ITEM = "/item", + TITLE = "/title" +} + +-- TODO: Rework self.template/self.nodes +-- Make self._inner_data? { component_name, template, nodes } +function M.init(self, template_name, node_table) + -- If component use template, setup it: + self.template = template_name + + -- If component was cloned with gui.clone_tree, pass his nodes + self.nodes = node_table + + -- helper can get node from gui/template/table + local root = helper.node(self, SCHEME.ROOT) + + -- This component can spawn another druid components: + local druid = helper.get_druid(self) + -- Button self on callback is self of _this_ component + local button = druid:new_button(...) + + -- helper can return you the component style + local my_style = helper.get_style(self, "component_name") +end + +``` + +## Example +You can check our example here +_TODO_ + +## API +_Link to ldoc_ + +## Internal +Generate with `ldoc .` with `config.ld` file. [Instructions](https://github.com/stevedonovan/LDoc) + +## Games powered by Druid: +_TODO_ + + +## License +MIT License + + +## Issues and suggestions +If you have any issues, questions or suggestions please [create an issue](https://github.com/AGulev/druid/issues) or contact me: [insality@gmail.com](mailto:insality@gmail.com) diff --git a/media/druid_logo.png b/media/druid_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..84d44b9e31487c53b51fa13d3dccf07b5e7cef12 GIT binary patch literal 6863 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 Date: Thu, 30 Jan 2020 00:31:17 +0300 Subject: [PATCH 081/136] Set functions to setup sound/text from external sources --- README.md | 15 +++++++++------ druid/const.lua | 2 ++ druid/druid.lua | 10 ++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 32bfa90..b575984 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,17 @@ Or point to the ZIP file of a [specific release](https://github.com/AGulev/drui #### Code Adjust druid settings: ```lua -local settings = require("druid.settings") -settings.play_sound = function(name) - ... -end +local druid = require("druid.druid") -settings.get_text = function(lang_id) +--- Function should return localized string by lang_id +druid.set_text_function(function(lang_id) ... -end +end) + +-- Function should play sound by name +druid.set_sound_function(function(name) + ... +end) ``` ## Usage diff --git a/druid/const.lua b/druid/const.lua index 4ac6a3d..44e612f 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -54,4 +54,6 @@ M.SPECIFIC_UI_MESSAGES = { [M.ON_LAYOUT_CHANGED] = "on_layout_changed" } +M.EMPTY_FUNCTION = function() end + return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index 161a4c0..33ce072 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -84,6 +84,16 @@ function M.set_default_style(style) end +function M.set_text_function(callback) + settings.get_text = callback or const.EMPTY_FUNCTION +end + + +function M.set_sound_function(callback) + settings.play_sound = callback or const.EMPTY_FUNCTION +end + + local function input_init(self) if not self.input_inited then self.input_inited = true From 9223862dc2f87a75b76826b7a8bdf34066995d7b Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 01:01:26 +0300 Subject: [PATCH 082/136] Rename helper.node -> helper.get_node --- README.md | 5 +++-- druid/base/blocker.lua | 2 +- druid/base/button.lua | 6 +++--- druid/base/checkbox.lua | 4 ++-- druid/base/grid.lua | 4 ++-- druid/base/progress.lua | 2 +- druid/base/scroll.lua | 4 ++-- druid/base/slider.lua | 2 +- druid/base/text.lua | 2 +- druid/base/timer.lua | 2 +- druid/helper.lua | 17 ++++++++++++++++- 11 files changed, 33 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index b575984..7873bb8 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ end) ## Components Druid provides next basic components: _insert simple gif of each?_ +_separate .md for each base component?_ - **Button** - basic game button - **Text** - wrap on gui text node - **Blocker** - block input in node zone @@ -44,8 +45,8 @@ _insert simple gif of each?_ - **Grid** - manage node positions - **Slider** - simple slider (ex. volume adjust) - **Checkbox** - simple checkbox -- **Checkbox** group - many checkbox -- **Radio** group - many checkbox with single choice +- **Checkbox group** - many checkbox +- **Radio group** - many checkbox with single choice ## Styles You can setup default style for all druid module, for druid instance or any base druid component. diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 4212ec4..14f3fc2 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -12,7 +12,7 @@ M.interest = { function M.init(self, node) - self.node = helper.node(node) + self.node = helper.get_node(node) self.event = const.ACTION_TOUCH end diff --git a/druid/base/button.lua b/druid/base/button.lua index 5398ac6..5d6ca1a 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -25,10 +25,10 @@ M.interest = { function M.init(self, node, callback, params, anim_node, event) assert(callback, "Button should have callback. To block input on zone use blocker component") self.style = helper.get_style(self, "BUTTON") - self.node = helper.node(node) + self.node = helper.get_node(node) self.event = const.ACTION_TOUCH - self.anim_node = anim_node and helper.node(anim_node) or self.node + self.anim_node = anim_node and helper.get_node(anim_node) or self.node self.scale_from = gui.get_scale(self.anim_node) self.pos = gui.get_position(self.anim_node) self.callback = callback @@ -142,7 +142,7 @@ end -- @tparam table self Component instance -- @tparam node zone Gui node function M.set_click_zone(self, zone) - self.click_zone = helper.node(zone) + self.click_zone = helper.get_node(zone) end diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index d7406be..ffc74df 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -35,8 +35,8 @@ end function M.init(self, node, callback, click_node) self.style = helper.get_style(self, "CHECKBOX") self.druid = helper.get_druid(self) - self.node = helper.node(node) - self.click_node = helper.node(click_node) + self.node = helper.get_node(node) + self.click_node = helper.get_node(click_node) self.callback = callback self.button = self.druid:new_button(self.click_node or self.node, on_click) diff --git a/druid/base/grid.lua b/druid/base/grid.lua index e47e69e..acdfcbd 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -8,13 +8,13 @@ local M = {} function M.init(self, parent, element, in_row) - self.parent = helper.node(parent) + self.parent = helper.get_node(parent) self.nodes = {} self.offset = vmath.vector3(0) self.anchor = vmath.vector3(0.5, 0, 0) self.in_row = in_row or 1 - self.node_size = gui.get_size(helper.node(element)) + self.node_size = gui.get_size(helper.get_node(element)) self.border = vmath.vector4(0) self.border_offset = vmath.vector3(0) end diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 5a5778b..3a9019e 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -24,7 +24,7 @@ function M.init(self, node, key, init_value) self.key = key self.style = helper.get_style(self, "PROGRESS") - self.node = helper.node(node) + self.node = helper.get_node(node) self.scale = gui.get_scale(self.node) self.size = gui.get_size(self.node) self.max_size = self.size[self.key] diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index fa5d169..15da58c 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -18,8 +18,8 @@ M.current_scroll = nil function M.init(self, scroll_parent, input_zone, border) self.style = helper.get_style(self, "SCROLL") - self.node = helper.node(scroll_parent) - self.input_zone = helper.node(input_zone) + self.node = helper.get_node(scroll_parent) + self.input_zone = helper.get_node(input_zone) self.zone_size = gui.get_size(self.input_zone) self.soft_size = self.style.SOFT_ZONE_SIZE diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 98b5846..2009274 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -18,7 +18,7 @@ end function M.init(self, node, end_pos, callback) - self.node = helper.node(node) + self.node = helper.get_node(node) self.start_pos = gui.get_position(self.node) self.pos = gui.get_position(self.node) diff --git a/druid/base/text.lua b/druid/base/text.lua index 2df969c..cbeaaff 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -9,7 +9,7 @@ local M = {} function M.init(self, node, value, no_adjust) - self.node = helper.node(node) + self.node = helper.get_node(node) self.start_pivot = gui.get_pivot(self.node) self.start_pos = gui.get_position(self.node) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index c531205..08afe4c 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -14,7 +14,7 @@ local empty = function() end function M.init(self, node, seconds_from, seconds_to, callback) - self.node = helper.node(node) + self.node = helper.get_node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) callback = callback or empty diff --git a/druid/helper.lua b/druid/helper.lua index 5c66d14..e8ef801 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -83,7 +83,7 @@ function M.after(count, callback) end -function M.node(node_or_name) +function M.get_node(node_or_name) if type(node_or_name) == const.STRING then return gui.get_node(node_or_name) end @@ -91,6 +91,21 @@ function M.node(node_or_name) end +-- TODO: Определиться с get_node и node +-- get_node - берет ноду по ноде или строке +-- node - может брать ноду у компонента по схеме (если есть +-- template или таблица нод после gui.clone_tree) +function M.node(component, name) + local template_name = component.template or const.EMPTY_STRING + + if component.nodes then + return component.nodes[template_name .. name] + else + return gui.get_node(template_name .. name) + end +end + + function M.step(current, target, step) if current < target then return math.min(current + step, target) From 513a4c141b42b12cce1c72fd9a55c1232dcdd4f3 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 01:01:45 +0300 Subject: [PATCH 083/136] Move _fct_metatable to separate file druid_instance --- druid/const.lua | 1 + druid/druid.lua | 171 +------------------------------- druid/system/druid_instance.lua | 169 +++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 166 deletions(-) create mode 100644 druid/system/druid_instance.lua diff --git a/druid/const.lua b/druid/const.lua index 44e612f..a20f5d3 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -55,5 +55,6 @@ M.SPECIFIC_UI_MESSAGES = { } M.EMPTY_FUNCTION = function() end +M.EMPTY_STRING = "" return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index 33ce072..8a6ce5b 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -6,14 +6,13 @@ local const = require("druid.const") -local druid_input = require("druid.helper.druid_input") +local druid_instance = require("druid.system.druid_instance") local settings = require("druid.settings") local M = {} local log = settings.log -local _fct_metatable = {} -- Temporary, what the place for it? local default_style = {} @@ -40,7 +39,7 @@ M.comps = { local function register_basic_components() for k, v in pairs(M.comps) do - if not _fct_metatable["new_" .. k] then + if not druid_instance["new_" .. k] then M.register(k, v) else log("Basic component", k, "already registered") @@ -56,8 +55,8 @@ function M.register(name, module) -- TODO: Find better solution to creating elements? -- Possibly: druid.new(druid.BUTTON, etc?) -- Current way is very implicit - _fct_metatable["new_" .. name] = function(self, ...) - return _fct_metatable.new(self, module, ...) + druid_instance["new_" .. name] = function(self, ...) + return druid_instance.new(self, module, ...) end log("Register component", name) end @@ -70,7 +69,7 @@ function M.new(component_script, style) register_basic_components() register_basic_components = false end - local self = setmetatable({}, { __index = _fct_metatable }) + local self = setmetatable({}, { __index = druid_instance }) -- Druid context here (who created druid) -- Usually gui_script, but can be component from helper.get_druid(component) self._context = component_script @@ -94,164 +93,4 @@ function M.set_sound_function(callback) end -local function input_init(self) - if not self.input_inited then - self.input_inited = true - druid_input.focus() - end -end - - --- Create the component -local function create(self, module) - local instance = setmetatable({}, { __index = module }) - -- Component context, self from component creation - instance.context = self._context - instance.druid_style = self._style - table.insert(self, instance) - - local register_to = module.interest - if register_to then - local v - for i = 1, #register_to do - v = register_to[i] - if not self[v] then - self[v] = {} - end - table.insert(self[v], instance) - - if const.UI_INPUT[v] then - input_init(self) - end - end - end - - return instance -end - - -function _fct_metatable.remove(self, instance) - for i = #self, 1, -1 do - if self[i] == instance then - table.remove(self, i) - end - end - local interest = instance.interest - if interest then - local v - for i = 1, #interest do - v = interest[i] - local array = self[v] - for j = #array, 1, -1 do - if array[j] == instance then - table.remove(array, j) - end - end - end - end -end - - -function _fct_metatable.new(self, module, ...) - local instance = create(self, module) - - if instance.init then - instance:init(...) - end - - return instance -end - - ---- Called on_message -function _fct_metatable.on_message(self, message_id, message, sender) - local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] - if specific_ui_message then - local array = self[message_id] - if array then - local item - for i = 1, #array do - item = array[i] - item[specific_ui_message](item, message, sender) - end - end - else - local array = self[const.ON_MESSAGE] - if array then - for i = 1, #array do - array[i]:on_message(message_id, message, sender) - end - end - end -end - - -local function notify_input_on_swipe(self) - if self[const.ON_INPUT] then - local len = #self[const.ON_INPUT] - for i = len, 1, -1 do - local comp = self[const.ON_INPUT][i] - if comp.on_swipe then - comp:on_swipe() - end - end - end -end - - -local function match_event(action_id, events) - if type(events) == "table" then - for i = 1, #events do - if action_id == events[i] then - return true - end - end - else - return action_id == events - end -end - - ---- Called ON_INPUT -function _fct_metatable.on_input(self, action_id, action) - local array = self[const.ON_SWIPE] - if array then - local v, result - local len = #array - for i = len, 1, -1 do - v = array[i] - result = result or v:on_input(action_id, action) - end - if result then - notify_input_on_swipe(self) - return true - end - end - array = self[const.ON_INPUT] - if array then - local v - local len = #array - for i = len, 1, -1 do - v = array[i] - if match_event(action_id, v.event) and v:on_input(action_id, action) then - return true - end - end - return false - end - return false -end - - ---- Called on_update -function _fct_metatable.update(self, dt) - local array = self[const.ON_UPDATE] - if array then - for i = 1, #array do - array[i]:update(dt) - end - end -end - - return M diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua new file mode 100644 index 0000000..9b3403c --- /dev/null +++ b/druid/system/druid_instance.lua @@ -0,0 +1,169 @@ +local const = require("druid.const") +local druid_input = require("druid.helper.druid_input") + +local M = {} + + +local function input_init(self) + if not self.input_inited then + self.input_inited = true + druid_input.focus() + end +end + + +-- Create the component +local function create(self, module) + local instance = setmetatable({}, { __index = module }) + -- Component context, self from component creation + instance.context = self._context + instance.druid_style = self._style + table.insert(self, instance) + + local register_to = module.interest + if register_to then + local v + for i = 1, #register_to do + v = register_to[i] + if not self[v] then + self[v] = {} + end + table.insert(self[v], instance) + + if const.UI_INPUT[v] then + input_init(self) + end + end + end + + return instance +end + + +function M.new(self, module, ...) + local instance = create(self, module) + + if instance.init then + instance:init(...) + end + + return instance +end + + +function M.remove(self, instance) + for i = #self, 1, -1 do + if self[i] == instance then + table.remove(self, i) + end + end + + local interest = instance.interest + if interest then + local v + for i = 1, #interest do + v = interest[i] + local array = self[v] + for j = #array, 1, -1 do + if array[j] == instance then + table.remove(array, j) + end + end + end + end +end + + +--- Called on_message +function M.on_message(self, message_id, message, sender) + local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] + if specific_ui_message then + local array = self[message_id] + if array then + local item + for i = 1, #array do + item = array[i] + item[specific_ui_message](item, message, sender) + end + end + else + local array = self[const.ON_MESSAGE] + if array then + for i = 1, #array do + array[i]:on_message(message_id, message, sender) + end + end + end +end + + +local function notify_input_on_swipe(self) + if self[const.ON_INPUT] then + local len = #self[const.ON_INPUT] + for i = len, 1, -1 do + local comp = self[const.ON_INPUT][i] + if comp.on_swipe then + comp:on_swipe() + end + end + end +end + + +local function match_event(action_id, events) + if type(events) == "table" then + for i = 1, #events do + if action_id == events[i] then + return true + end + end + else + return action_id == events + end +end + + +--- Called ON_INPUT +function M.on_input(self, action_id, action) + local array = self[const.ON_SWIPE] + if array then + local v, result + local len = #array + for i = len, 1, -1 do + v = array[i] + result = result or v:on_input(action_id, action) + end + if result then + notify_input_on_swipe(self) + return true + end + end + + array = self[const.ON_INPUT] + if array then + local v + local len = #array + for i = len, 1, -1 do + v = array[i] + if match_event(action_id, v.event) and v:on_input(action_id, action) then + return true + end + end + return false + end + return false +end + + +--- Called on_update +function M.update(self, dt) + local array = self[const.ON_UPDATE] + if array then + for i = 1, #array do + array[i]:update(dt) + end + end +end + + +return M From 0542ec4e69c99f06bfc46d1d2f9dae6c401af545 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 01:45:25 +0300 Subject: [PATCH 084/136] Move druid settings inside system folder --- druid/druid.lua | 3 ++- druid/styles/bounce/style.lua | 2 +- druid/{ => system}/settings.lua | 1 - example/example.gui.gui_script | 2 +- example/kenney/init.script | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) rename druid/{ => system}/settings.lua (99%) diff --git a/druid/druid.lua b/druid/druid.lua index 8a6ce5b..2263588 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -7,7 +7,7 @@ local const = require("druid.const") local druid_instance = require("druid.system.druid_instance") -local settings = require("druid.settings") +local settings = require("druid.system.settings") local M = {} @@ -85,6 +85,7 @@ end function M.set_text_function(callback) settings.get_text = callback or const.EMPTY_FUNCTION + -- TODO: Update all localized text end diff --git a/druid/styles/bounce/style.lua b/druid/styles/bounce/style.lua index 2acd7e9..1a0bfa2 100644 --- a/druid/styles/bounce/style.lua +++ b/druid/styles/bounce/style.lua @@ -1,4 +1,4 @@ -local settings = require("druid.settings") +local settings = require("druid.system.settings") local anims = require("druid.styles.bounce.anims") local M = {} diff --git a/druid/settings.lua b/druid/system/settings.lua similarity index 99% rename from druid/settings.lua rename to druid/system/settings.lua index 3529af5..58b3987 100644 --- a/druid/settings.lua +++ b/druid/system/settings.lua @@ -3,7 +3,6 @@ local M = {} - M.is_debug = false diff --git a/example/example.gui.gui_script b/example/example.gui.gui_script index b640db7..bbd8be7 100644 --- a/example/example.gui.gui_script +++ b/example/example.gui.gui_script @@ -1,5 +1,5 @@ local druid = require("druid.druid") -local druid_settings = require("druid.settings") +local druid_settings = require("druid.system.settings") local lang = { locale_text = "Localized" diff --git a/example/kenney/init.script b/example/kenney/init.script index 6362a95..aa2bf5c 100644 --- a/example/kenney/init.script +++ b/example/kenney/init.script @@ -1,16 +1,16 @@ +local druid = require("druid.druid") local const = require("druid.const") -local settings = require("druid.settings") local lang = require("example.kenney.lang") local function setup_druid() - settings.play_sound = function(name) + druid.set_sound_function(function(name) sound.play("kenney:/sound#" .. name) - end + end) - settings.get_text = function(lang_id) + druid.set_text_function(function(lang_id) return lang.get_locale(lang_id) - end + end) -- TODO: Call druid.finish_setup? -- Need to update all gui, in case, when gui init was befure this init From ae47bcee8f8b264d7b875fa15b4c238d1634997d Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 01:46:02 +0300 Subject: [PATCH 085/136] Add component instance with general methods. New component constructor --- README.md | 2 +- druid/base/back_handler.lua | 9 ++-- druid/base/blocker.lua | 7 +-- druid/base/button.lua | 11 ++--- druid/base/checkbox.lua | 9 ++-- druid/base/checkbox_group.lua | 8 ++-- druid/base/grid.lua | 3 +- druid/base/locale.lua | 11 ++--- druid/base/progress.lua | 17 +++----- druid/base/radio_group.lua | 8 ++-- druid/base/scroll.lua | 11 ++--- druid/base/slider.lua | 8 ++-- druid/base/text.lua | 3 +- druid/base/timer.lua | 14 +++--- druid/const.lua | 1 + druid/druid.lua | 2 +- druid/helper.lua | 21 ++------- druid/rich/progress_rich.lua | 8 ++-- druid/styles/bounce/style.lua | 24 +++++------ druid/styles/empty/style.lua | 10 ++--- druid/system/component.lua | 75 +++++++++++++++++++++++++++++++++ druid/system/druid_instance.lua | 8 ++-- 22 files changed, 156 insertions(+), 114 deletions(-) create mode 100644 druid/system/component.lua diff --git a/README.md b/README.md index 7873bb8..2efbc43 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ function M.init(self, template_name, node_table) local button = druid:new_button(...) -- helper can return you the component style - local my_style = helper.get_style(self, "component_name") + local my_style = self:get_style() end ``` diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 45d0a2e..bd4078e 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -2,11 +2,10 @@ -- @module base.back_handler local const = require("druid.const") +local component = require("druid.system.component") + +local M = component.new("back_handler", { const.ON_INPUT }) -local M = {} -M.interest = { - const.ON_INPUT -} --- Component init function -- @function back_handler:init @@ -26,7 +25,7 @@ end -- @tparam table action on_input action function M.on_input(self, action_id, action) if action[const.RELEASED] then - self.callback(self.context, self.params) + self.callback(self:get_context(), self.params) end return true diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 14f3fc2..3011f1a 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -3,12 +3,9 @@ local const = require("druid.const") local helper = require("druid.helper") +local component = require("druid.system.component") - -local M = {} -M.interest = { - const.ON_SWIPE -} +local M = component.new("blocker", { const.ON_SWIPE }) function M.init(self, node) diff --git a/druid/base/button.lua b/druid/base/button.lua index 5d6ca1a..67c485e 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -7,12 +7,9 @@ local const = require("druid.const") local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} -M.interest = { - const.ON_INPUT -} - +local M = component.new("button", { const.ON_INPUT }) --- Component init function -- @function button:init @@ -24,7 +21,7 @@ M.interest = { -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) assert(callback, "Button should have callback. To block input on zone use blocker component") - self.style = helper.get_style(self, "BUTTON") + self.style = self:get_style() self.node = helper.get_node(node) self.event = const.ACTION_TOUCH @@ -55,7 +52,7 @@ local function on_button_release(self) if self.style.on_click then self.style.on_click(self, self.anim_node) end - self.callback(self.context, self.params, self) + self.callback(self:get_context(), self.params, self) else set_hover(self, false) end diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index ffc74df..1a52ad0 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -2,8 +2,9 @@ -- @module base.checkbox local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("checkbox") function M.set_state(self, state, is_silence) @@ -17,7 +18,7 @@ function M.set_state(self, state, is_silence) end if not is_silence and self.callback then - self.callback(self.context, state) + self.callback(self:get_context(), state) end end @@ -33,8 +34,8 @@ end function M.init(self, node, callback, click_node) - self.style = helper.get_style(self, "CHECKBOX") - self.druid = helper.get_druid(self) + self.style = self:get_style() + self.druid = self:get_druid() self.node = helper.get_node(node) self.click_node = helper.get_node(click_node) self.callback = callback diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 6e92987..03faf8e 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,14 +1,14 @@ --- Checkboux group module -- @module base.checkbox_group -local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("checkbox_group") local function on_checkbox_click(self, index) if self.callback then - self.callback(self.context, index) + self.callback(self:get_context(), index) end end @@ -34,7 +34,7 @@ end function M.init(self, nodes, callback, click_nodes) - self.druid = helper.get_druid(self) + self.druid = self:get_druid() self.checkboxes = {} self.callback = callback diff --git a/druid/base/grid.lua b/druid/base/grid.lua index acdfcbd..74c4d66 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -3,8 +3,9 @@ -- @module base.grid local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("grid") function M.init(self, parent, element, in_row) diff --git a/druid/base/locale.lua b/druid/base/locale.lua index f2abda7..ec73bf9 100644 --- a/druid/base/locale.lua +++ b/druid/base/locale.lua @@ -3,17 +3,14 @@ -- @module base.text local const = require("druid.const") -local settings = require("druid.settings") -local helper = require("druid.helper") +local settings = require("druid.system.settings") +local component = require("druid.system.component") -local M = {} -M.interest = { - const.ON_CHANGE_LANGUAGE, -} +local M = component.new("locale", { const.ON_CHANGE_LANGUAGE }) function M.init(self, node, lang_id, no_adjust) - self.druid = helper.get_druid(self) + self.druid = self:get_druid() self.text = self.druid:new_text(node, lang_id, no_adjust) self:translate(lang_id) diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 3a9019e..564cebb 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -3,12 +3,9 @@ local const = require("druid.const") local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} - -M.interest = { - const.ON_UPDATE, -} +local M = component.new("progress", { const.ON_UPDATE }) --- Component init function @@ -23,7 +20,7 @@ function M.init(self, node, key, init_value) self.prop = hash("scale."..key) self.key = key - self.style = helper.get_style(self, "PROGRESS") + self.style = self:get_style() self.node = helper.get_node(node) self.scale = gui.get_scale(self.node) self.size = gui.get_size(self.node) @@ -52,10 +49,10 @@ local function check_steps(self, from, to, exactly) end if v1 < step and step < v2 then - self.step_callback(self.context, step) + self.step_callback(self:get_context(), step) end if exactly and exactly == step then - self.step_callback(self.context, step) + self.step_callback(self:get_context(), step) end end end @@ -139,7 +136,7 @@ function M.to(self, to, callback) self.target_callback = callback else if callback then - callback(self.context, to) + callback(self:get_context(), to) end end end @@ -156,7 +153,7 @@ function M.update(self, dt) check_steps(self, prev_value, self.target, self.target) if self.target_callback then - self.target_callback(self.context, self.target) + self.target_callback(self:get_context(), self.target) end self.target = nil diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua index ee22e6a..4802ca8 100644 --- a/druid/base/radio_group.lua +++ b/druid/base/radio_group.lua @@ -1,9 +1,9 @@ --- Radio group module -- @module base.checkbox_group -local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("radio_group") local function on_checkbox_click(self, index) @@ -12,7 +12,7 @@ local function on_checkbox_click(self, index) end if self.callback then - self.callback(self.context, index) + self.callback(self:get_context(), index) end end @@ -37,7 +37,7 @@ end function M.init(self, nodes, callback, click_nodes) - self.druid = helper.get_druid(self) + self.druid = self:get_druid() self.checkboxes = {} self.callback = callback diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 15da58c..7716e3e 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -3,13 +3,10 @@ local helper = require("druid.helper") local const = require("druid.const") +local component = require("druid.system.component") -local M = {} +local M = component.new("scroll", { const.ON_UPDATE, const.ON_SWIPE }) -M.interest = { - const.ON_UPDATE, - const.ON_SWIPE, -} -- Global on all scrolls -- TODO: remove it @@ -17,7 +14,7 @@ M.current_scroll = nil function M.init(self, scroll_parent, input_zone, border) - self.style = helper.get_style(self, "SCROLL") + self.style = self:get_style() self.node = helper.get_node(scroll_parent) self.input_zone = helper.get_node(input_zone) @@ -355,7 +352,7 @@ function M.scroll_to_index(self, index, skip_cb) self.selected = index if not skip_cb and self.on_point_callback then - self.on_point_callback(self.context, index, self.points[index]) + self.on_point_callback(self:get_context(), index, self.points[index]) end end diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 2009274..8503501 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -3,16 +3,14 @@ local helper = require("druid.helper") local const = require("druid.const") +local component = require("druid.system.component") -local M = {} -M.interest = { - const.ON_SWIPE -} +local M = component.new("slider", { const.ON_SWIPE }) local function on_change_value(self) if self.callback then - self.callback(self.context, self.value) + self.callback(self:get_context(), self.value) end end diff --git a/druid/base/text.lua b/druid/base/text.lua index cbeaaff..f7db024 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -4,8 +4,9 @@ local const = require("druid.const") local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("text") function M.init(self, node, value, no_adjust) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 08afe4c..5c26410 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -4,20 +4,16 @@ local const = require("druid.const") local formats = require("druid.helper.formats") local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} -M.interest = { - const.ON_UPDATE -} - -local empty = function() end +local M = component.new("timer", { const.ON_UPDATE }) function M.init(self, node, seconds_from, seconds_to, callback) self.node = helper.get_node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) - callback = callback or empty + callback = callback or const.EMPTY_FUNCTION self:set_to(seconds_from) self:set_interval(seconds_from, seconds_to) @@ -25,7 +21,7 @@ function M.init(self, node, seconds_from, seconds_to, callback) if seconds_to - seconds_from == 0 then self:set_state(false) - self.callback(self.context, self) + self.callback(self:get_context(), self) end return self end @@ -76,7 +72,7 @@ function M.update(self, dt) M.set_to(self, self.value) if self.value == self.target then self:set_state(false) - self.callback(self.context, self) + self.callback(self:get_context(), self) end end end diff --git a/druid/const.lua b/druid/const.lua index a20f5d3..19feaea 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -56,5 +56,6 @@ M.SPECIFIC_UI_MESSAGES = { M.EMPTY_FUNCTION = function() end M.EMPTY_STRING = "" +M.EMPTY_TABLE = {} return M \ No newline at end of file diff --git a/druid/druid.lua b/druid/druid.lua index 2263588..d8b00a4 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -71,7 +71,7 @@ function M.new(component_script, style) end local self = setmetatable({}, { __index = druid_instance }) -- Druid context here (who created druid) - -- Usually gui_script, but can be component from helper.get_druid(component) + -- Usually gui_script, but can be component from self:get_druid() self._context = component_script self._style = style or default_style return self diff --git a/druid/helper.lua b/druid/helper.lua index e8ef801..66c724f 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -96,10 +96,10 @@ end -- node - может брать ноду у компонента по схеме (если есть -- template или таблица нод после gui.clone_tree) function M.node(component, name) - local template_name = component.template or const.EMPTY_STRING + local template_name = component._meta.template or const.EMPTY_STRING - if component.nodes then - return component.nodes[template_name .. name] + if component._meta.nodes then + return component._meta.nodes[template_name .. name] else return gui.get_node(template_name .. name) end @@ -165,19 +165,4 @@ function M.get_pivot_offset(pivot) end -function M.get_druid(self) - local context = { _context = self } - return setmetatable(context, { __index = self.context.druid }) -end - - -function M.get_style(self, section) - if not self.druid_style then - return {} - end - - return self.druid_style[section] or {} -end - - return M diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index 277e435..4a6d3e1 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -1,14 +1,14 @@ --- Component for rich progress component -- @module rich.progress_rich -local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("progress_rich") function M.init(self, name, red, green, key) - self.druid = helper.get_druid(self) - self.style = helper.get_style(self, "PROGRESS_RICH") + self.druid = self:get_druid() + self.style = self:get_style() self.red = self.druid:new_progress(red, key) self.green = self.druid:new_progress(green, key) self.fill = self.druid:new_progress(name, key) diff --git a/druid/styles/bounce/style.lua b/druid/styles/bounce/style.lua index 1a0bfa2..e9d93bf 100644 --- a/druid/styles/bounce/style.lua +++ b/druid/styles/bounce/style.lua @@ -4,7 +4,7 @@ local anims = require("druid.styles.bounce.anims") local M = {} -M.BUTTON = { +M["button"] = { HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), HOVER_TIME = 0.05, SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), @@ -16,34 +16,34 @@ M.BUTTON = { on_hover = function(self, node, state) if self.hover_anim then - local scale_to = self.scale_from + M.BUTTON.HOVER_SCALE + local scale_to = self.scale_from + M.button.HOVER_SCALE local target_scale = state and scale_to or self.scale_from - anims.hover_scale(self, target_scale, M.BUTTON.HOVER_TIME) + anims.hover_scale(self, target_scale, M.button.HOVER_TIME) end end, on_click = function(self, node) - local scale_to = self.scale_from + M.BUTTON.SCALE_CHANGE + local scale_to = self.scale_from + M.button.SCALE_CHANGE anims.tap_scale_animation(self, node, scale_to) - settings.play_sound(M.BUTTON.BTN_SOUND) + settings.play_sound(M.button.BTN_SOUND) end, on_click_disabled = function(self, node) - settings.play_sound(M.BUTTON.BTN_SOUND_DISABLED) + settings.play_sound(M.button.BTN_SOUND_DISABLED) end, on_set_enabled = function(self, node, state) if state then - gui.set_color(node, M.BUTTON.ENABLED_COLOR) + gui.set_color(node, M.button.ENABLED_COLOR) else - gui.set_color(node, M.BUTTON.DISABLED_COLOR) + gui.set_color(node, M.button.DISABLED_COLOR) end end } -M.SCROLL = { +M["scroll"] = { FRICT_HOLD = 0.8, -- mult. for inert, while touching FRICT = 0.93, -- mult for free inert INERT_THRESHOLD = 2, -- speed to stop inertion @@ -55,18 +55,18 @@ M.SCROLL = { } -M.PROGRESS = { +M["progress"] = { SPEED = 5, -- progress bar fill rate, more faster MIN_DELTA = 0.005 } -M.PROGRESS_RICH = { +M["progress_rich"] = { DELAY = 1, -- delay in seconds before main fill } -M.CHECKBOX = { +M["checkbox"] = { on_change_state = function(self, node, state) local target = state and 1 or 0 gui.animate(node, "color.w", target, gui.EASING_OUTSINE, 0.1) diff --git a/druid/styles/empty/style.lua b/druid/styles/empty/style.lua index 10f627d..2ef9698 100644 --- a/druid/styles/empty/style.lua +++ b/druid/styles/empty/style.lua @@ -1,7 +1,7 @@ local M = {} -M.BUTTON = { +M["button"] = { BTN_SOUND = "click", BTN_SOUND_DISABLED = "click", DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), @@ -10,7 +10,7 @@ M.BUTTON = { } -M.SCROLL = { +M["scroll"] = { FRICT_HOLD = 0, -- mult. for inert, while touching FRICT = 0, -- mult for free inert INERT_THRESHOLD = 2, -- speed to stop inertion @@ -22,18 +22,18 @@ M.SCROLL = { } -M.PROGRESS = { +M["progress"] = { SPEED = 5, -- progress bar fill rate, more faster MIN_DELTA = 1 } -M.PROGRESS_RICH = { +M["progress_rich"] = { DELAY = 0, -- delay in seconds before main fill } -M.CHECKBOX = { +M["checkbox"] = { on_change_state = function(self, node, state) gui.set_enabled(node, state) end diff --git a/druid/system/component.lua b/druid/system/component.lua new file mode 100644 index 0000000..57fced6 --- /dev/null +++ b/druid/system/component.lua @@ -0,0 +1,75 @@ +local const = require("druid.const") + +local M = {} +local instance = {} + + +function instance.get_style(self) + if not self._meta.style then + return const.EMPTY_TABLE + end + + return self._meta.style[self._component.name] or const.EMPTY_TABLE +end + + +function instance.set_style(self, component_style) + self._meta.style = component_style +end + + +function instance.set_template(self, template) + self._meta.template = template +end + + +function instance.set_nodes(self, nodes) + self._meta.nodes = nodes +end + + +function instance.get_context(self, context) + return self._meta.context +end + + +function instance.set_context(self, context) + self._meta.context = context +end + + +function instance.get_druid(self) + local context = { _context = self } + return setmetatable(context, { __index = self:get_context().druid }) +end + + +function instance.setup_component(self, context, style) + self._meta = { + template = nil, + context = nil, + nodes = nil, + style = nil, + } + + self:set_context(context) + self:set_style(style) + + return self +end + + +function M.new(name, interest) + local mt = { + _component = { + name = name, + interest = interest + } + } + local component = setmetatable(mt, { __index = instance }) + + return component +end + + +return M \ No newline at end of file diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 9b3403c..3d1c1d3 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -16,11 +16,11 @@ end local function create(self, module) local instance = setmetatable({}, { __index = module }) -- Component context, self from component creation - instance.context = self._context - instance.druid_style = self._style + instance:setup_component(self._context, self._style) + table.insert(self, instance) - local register_to = module.interest + local register_to = module._component.interest if register_to then local v for i = 1, #register_to do @@ -58,7 +58,7 @@ function M.remove(self, instance) end end - local interest = instance.interest + local interest = instance._component.interest if interest then local v for i = 1, #interest do From add6b8e301e1413c8a267949d4d39b7fc424260a Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 01:55:37 +0300 Subject: [PATCH 086/136] Move components array from self to self.components and self.components_all --- druid/const.lua | 1 + druid/druid.lua | 8 ++++++ druid/system/component.lua | 3 +++ druid/system/druid_instance.lua | 47 ++++++++++++++++----------------- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/druid/const.lua b/druid/const.lua index 19feaea..eec8606 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -13,6 +13,7 @@ M.ACTION_BACK = hash("back") M.RELEASED = "released" M.PRESSED = "pressed" M.STRING = "string" +M.TABLE = "table" M.ZERO = "0" --- Interests diff --git a/druid/druid.lua b/druid/druid.lua index d8b00a4..bdc7f9b 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -70,10 +70,18 @@ function M.new(component_script, style) register_basic_components = false end local self = setmetatable({}, { __index = druid_instance }) + -- Druid context here (who created druid) -- Usually gui_script, but can be component from self:get_druid() self._context = component_script self._style = style or default_style + + -- TODO: Find the better way to handle components + -- All component list + self.all_components = {} + -- Map: interest: {components} + self.components = {} + return self end diff --git a/druid/system/component.lua b/druid/system/component.lua index 57fced6..a1ea21e 100644 --- a/druid/system/component.lua +++ b/druid/system/component.lua @@ -1,3 +1,6 @@ +--- General component class +--@class component + local const = require("druid.const") local M = {} diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 3d1c1d3..500e484 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -14,23 +14,23 @@ end -- Create the component local function create(self, module) + ---@class component local instance = setmetatable({}, { __index = module }) -- Component context, self from component creation instance:setup_component(self._context, self._style) - table.insert(self, instance) + table.insert(self.all_components, instance) local register_to = module._component.interest if register_to then - local v for i = 1, #register_to do - v = register_to[i] - if not self[v] then - self[v] = {} + local interest = register_to[i] + if not self.components[interest] then + self.components[interest] = {} end - table.insert(self[v], instance) + table.insert(self.components[interest], instance) - if const.UI_INPUT[v] then + if const.UI_INPUT[interest] then input_init(self) end end @@ -52,18 +52,17 @@ end function M.remove(self, instance) - for i = #self, 1, -1 do - if self[i] == instance then + for i = #self.all_components, 1, -1 do + if self.all_components[i] == instance then table.remove(self, i) end end - local interest = instance._component.interest - if interest then - local v - for i = 1, #interest do - v = interest[i] - local array = self[v] + local interests = instance._component.interest + if interests then + for i = 1, #interests do + local interest = interests[i] + local array = self.components[interest] for j = #array, 1, -1 do if array[j] == instance then table.remove(array, j) @@ -78,7 +77,7 @@ end function M.on_message(self, message_id, message, sender) local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] if specific_ui_message then - local array = self[message_id] + local array = self.components[message_id] if array then local item for i = 1, #array do @@ -87,7 +86,7 @@ function M.on_message(self, message_id, message, sender) end end else - local array = self[const.ON_MESSAGE] + local array = self.components[const.ON_MESSAGE] if array then for i = 1, #array do array[i]:on_message(message_id, message, sender) @@ -98,10 +97,10 @@ end local function notify_input_on_swipe(self) - if self[const.ON_INPUT] then - local len = #self[const.ON_INPUT] + if self.components[const.ON_INPUT] then + local len = #self.components[const.ON_INPUT] for i = len, 1, -1 do - local comp = self[const.ON_INPUT][i] + local comp = self.components[const.ON_INPUT][i] if comp.on_swipe then comp:on_swipe() end @@ -111,7 +110,7 @@ end local function match_event(action_id, events) - if type(events) == "table" then + if type(events) == const.TABLE then for i = 1, #events do if action_id == events[i] then return true @@ -125,7 +124,7 @@ end --- Called ON_INPUT function M.on_input(self, action_id, action) - local array = self[const.ON_SWIPE] + local array = self.components[const.ON_SWIPE] if array then local v, result local len = #array @@ -139,7 +138,7 @@ function M.on_input(self, action_id, action) end end - array = self[const.ON_INPUT] + array = self.components[const.ON_INPUT] if array then local v local len = #array @@ -157,7 +156,7 @@ end --- Called on_update function M.update(self, dt) - local array = self[const.ON_UPDATE] + local array = self.components[const.ON_UPDATE] if array then for i = 1, #array do array[i]:update(dt) From b5686af3910f32bdc6d8fa963c64258d40b34ae5 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 01:55:49 +0300 Subject: [PATCH 087/136] Move default style to druid settings --- druid/druid.lua | 8 ++------ druid/system/settings.lua | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index bdc7f9b..becfb26 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -4,17 +4,13 @@ -- to create your own rich components. -- @module druid - local const = require("druid.const") local druid_instance = require("druid.system.druid_instance") local settings = require("druid.system.settings") local M = {} - local log = settings.log --- Temporary, what the place for it? -local default_style = {} --- Basic components @@ -74,7 +70,7 @@ function M.new(component_script, style) -- Druid context here (who created druid) -- Usually gui_script, but can be component from self:get_druid() self._context = component_script - self._style = style or default_style + self._style = style or settings.default_style -- TODO: Find the better way to handle components -- All component list @@ -87,7 +83,7 @@ end function M.set_default_style(style) - default_style = style + settings.default_style = style end diff --git a/druid/system/settings.lua b/druid/system/settings.lua index 58b3987..2fd8bbb 100644 --- a/druid/system/settings.lua +++ b/druid/system/settings.lua @@ -4,6 +4,7 @@ local M = {} M.is_debug = false +M.default_style = nil function M.get_text(name) From 32bbddb70698b6620c0a94cad516db6ce063326d Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 02:00:01 +0300 Subject: [PATCH 088/136] Little code refactor --- druid/helper/formats.lua | 3 ++- druid/system/component.lua | 4 ++-- druid/system/druid_instance.lua | 7 +++++++ druid/system/settings.lua | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/druid/helper/formats.lua b/druid/helper/formats.lua index 9c38861..d08dccf 100644 --- a/druid/helper/formats.lua +++ b/druid/helper/formats.lua @@ -5,6 +5,7 @@ local const = require("druid.const") local M = {} + --- Return number with zero number prefix -- @function formats.add_prefix_zeros -- @tparam number num Number for conversion @@ -13,7 +14,7 @@ local M = {} function M.add_prefix_zeros(num, count) local result = tostring(num) for i = string.len(result), count - 1 do - result = const.ZERO..result + result = const.ZERO .. result end return result end diff --git a/druid/system/component.lua b/druid/system/component.lua index a1ea21e..b2d8d83 100644 --- a/druid/system/component.lua +++ b/druid/system/component.lua @@ -16,8 +16,8 @@ function instance.get_style(self) end -function instance.set_style(self, component_style) - self._meta.style = component_style +function instance.set_style(self, druid_style) + self._meta.style = druid_style end diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 500e484..86cb821 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -1,10 +1,16 @@ local const = require("druid.const") local druid_input = require("druid.helper.druid_input") +local settings = require("druid.system.settings") local M = {} local function input_init(self) + -- TODO: To custom settings + if not settings.auto_focus_gain then + return + end + if not self.input_inited then self.input_inited = true druid_input.focus() @@ -16,6 +22,7 @@ end local function create(self, module) ---@class component local instance = setmetatable({}, { __index = module }) + -- Component context, self from component creation instance:setup_component(self._context, self._style) diff --git a/druid/system/settings.lua b/druid/system/settings.lua index 2fd8bbb..637339d 100644 --- a/druid/system/settings.lua +++ b/druid/system/settings.lua @@ -5,6 +5,7 @@ local M = {} M.is_debug = false M.default_style = nil +M.auto_focus_gain = true function M.get_text(name) From 2b534cc205275c5e06c9e81cf39b0e327d111707 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 02:11:59 +0300 Subject: [PATCH 089/136] Code style refactor --- README.md | 15 +++++---- druid/druid.lua | 18 +++++------ druid/helper.lua | 21 ++++--------- druid/system/druid_instance.lua | 55 ++++++++++++++++++--------------- 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 2efbc43..ff9622a 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,9 @@ end Basic custom component template looks like this: ```lua local const = require("druid.const") +local component = require("druid.system.component") -local M = {} -M.interest = { const.ON_INPUT } +local M = component.new("amazing_component", { const.ON_INPUT }) function M.init(self, ...) -- Component constructor @@ -137,8 +137,9 @@ On each component recomended describe component schema in next way: ```lua -- Component module local helper = require("druid.helper") +local component = require("druid.system.component") -local M = {} +local M = component.new("new_component") local SCHEME = { ROOT = "/root", @@ -146,20 +147,18 @@ local SCHEME = { TITLE = "/title" } --- TODO: Rework self.template/self.nodes --- Make self._inner_data? { component_name, template, nodes } function M.init(self, template_name, node_table) -- If component use template, setup it: - self.template = template_name + self:set_template(template_name) -- If component was cloned with gui.clone_tree, pass his nodes - self.nodes = node_table + self:set_nodes(node_table) -- helper can get node from gui/template/table local root = helper.node(self, SCHEME.ROOT) -- This component can spawn another druid components: - local druid = helper.get_druid(self) + local druid = self:get_druid(self) -- Button self on callback is self of _this_ component local button = druid:new_button(...) diff --git a/druid/druid.lua b/druid/druid.lua index becfb26..c1f582d 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -14,7 +14,7 @@ local log = settings.log --- Basic components -M.comps = { +M.components = { button = require("druid.base.button"), blocker = require("druid.base.blocker"), back_handler = require("druid.base.back_handler"), @@ -34,7 +34,7 @@ M.comps = { local function register_basic_components() - for k, v in pairs(M.comps) do + for k, v in pairs(M.components) do if not druid_instance["new_" .. k] then M.register(k, v) else @@ -60,25 +60,25 @@ end --- Create Druid instance for creating components -- @return instance with all ui components -function M.new(component_script, style) +function M.new(context, style) if register_basic_components then register_basic_components() register_basic_components = false end - local self = setmetatable({}, { __index = druid_instance }) + local druid = setmetatable({}, { __index = druid_instance }) -- Druid context here (who created druid) -- Usually gui_script, but can be component from self:get_druid() - self._context = component_script - self._style = style or settings.default_style + druid._context = context + druid._style = style or settings.default_style -- TODO: Find the better way to handle components -- All component list - self.all_components = {} + druid.all_components = {} -- Map: interest: {components} - self.components = {} + druid.components = {} - return self + return druid end diff --git a/druid/helper.lua b/druid/helper.lua index 66c724f..953c7ac 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,7 +1,6 @@ --- Druid helper module -- @module helper - local const = require("druid.const") local M = {} @@ -71,22 +70,11 @@ function M.centrate_icon_with_text(icon_node, text_node, margin) end --- call callback after count calls -function M.after(count, callback) - local closure = function() - count = count - 1 - if count <= 0 then - callback() - end - end - return closure -end - - function M.get_node(node_or_name) if type(node_or_name) == const.STRING then return gui.get_node(node_or_name) end + return node_or_name end @@ -97,9 +85,10 @@ end -- template или таблица нод после gui.clone_tree) function M.node(component, name) local template_name = component._meta.template or const.EMPTY_STRING + local nodes = component._meta.nodes - if component._meta.nodes then - return component._meta.nodes[template_name .. name] + if nodes then + return nodes[template_name .. name] else return gui.get_node(template_name .. name) end @@ -139,6 +128,7 @@ function M.sign(val) if val == 0 then return 0 end + return (val < 0) and -1 or 1 end @@ -156,6 +146,7 @@ function M.is_enabled(node) is_enabled = is_enabled and gui.is_enabled(parent) parent = gui.get_parent(parent) end + return is_enabled end diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 86cb821..35abac6 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -80,24 +80,13 @@ function M.remove(self, instance) end ---- Called on_message -function M.on_message(self, message_id, message, sender) - local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] - if specific_ui_message then - local array = self.components[message_id] - if array then - local item - for i = 1, #array do - item = array[i] - item[specific_ui_message](item, message, sender) - end - end - else - local array = self.components[const.ON_MESSAGE] - if array then - for i = 1, #array do - array[i]:on_message(message_id, message, sender) - end +--- Druid instance update function +-- @function druid:update(dt) +function M.update(self, dt) + local array = self.components[const.ON_UPDATE] + if array then + for i = 1, #array do + array[i]:update(dt) end end end @@ -129,8 +118,11 @@ local function match_event(action_id, events) end ---- Called ON_INPUT +--- Druid instance on_input function +-- @function druid:on_input(action_id, action) function M.on_input(self, action_id, action) + -- TODO: расписать отличия ON_SWIPE и ON_INPUT + -- Почему-то некоторые используют ON_SWIPE, а логичнее ON_INPUT? (blocker, slider) local array = self.components[const.ON_SWIPE] if array then local v, result @@ -161,12 +153,25 @@ function M.on_input(self, action_id, action) end ---- Called on_update -function M.update(self, dt) - local array = self.components[const.ON_UPDATE] - if array then - for i = 1, #array do - array[i]:update(dt) +--- Druid instance on_message function +-- @function druid:on_message(message_id, message, sender) +function M.on_message(self, message_id, message, sender) + local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] + if specific_ui_message then + local array = self.components[message_id] + if array then + local item + for i = 1, #array do + item = array[i] + item[specific_ui_message](item, message, sender) + end + end + else + local array = self.components[const.ON_MESSAGE] + if array then + for i = 1, #array do + array[i]:on_message(message_id, message, sender) + end end end end From 8c011dcc27c42b01c4fa331d49060fbd603b093f Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 30 Jan 2020 02:33:35 +0300 Subject: [PATCH 090/136] Progress bar example fix --- example/kenney/page/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index db04392..cefd09d 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -42,7 +42,7 @@ end local function setup_progress(self) self.progress = self.druid:new_progress("progress_fill", "x", 0.4) - random_progress(self.progress, gui.get_node("text_progress")) + random_progress(self.progress, gui.get_node("text_progress_amount")) timer.delay(2, true, function() random_progress(self.progress, gui.get_node("text_progress_amount")) end) From be8869951a7b9eb2aafee50fd8943293db25e7d7 Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 3 Feb 2020 22:08:49 +0300 Subject: [PATCH 091/136] Add class component and druid_instance --- README.md | 24 ++++- druid/base/back_handler.lua | 2 +- druid/base/blocker.lua | 2 +- druid/base/button.lua | 4 +- druid/base/checkbox.lua | 2 +- druid/base/checkbox_group.lua | 2 +- druid/base/grid.lua | 2 +- druid/base/locale.lua | 2 +- druid/base/progress.lua | 2 +- druid/base/radio_group.lua | 2 +- druid/base/scroll.lua | 2 +- druid/base/slider.lua | 2 +- druid/base/text.lua | 2 +- druid/base/timer.lua | 2 +- druid/druid.lua | 25 ++--- druid/rich/progress_rich.lua | 2 +- druid/system/component.lua | 148 +++++++++++++++++--------- druid/system/druid_instance.lua | 146 +++++++++++++------------ druid/system/middleclass.lua | 183 ++++++++++++++++++++++++++++++++ druid/system/settings.lua | 2 - 20 files changed, 404 insertions(+), 154 deletions(-) create mode 100644 druid/system/middleclass.lua diff --git a/README.md b/README.md index ff9622a..6831790 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![](media/druid_logo.png) +[![](media/druid_logo.png)](https://AGulev.github.io/druid/) _travis/release bages_ **Druid** - powerful defold component UI library. Use standart components or make your own game-specific to make amazing GUI in your games. @@ -102,7 +102,7 @@ Basic custom component template looks like this: local const = require("druid.const") local component = require("druid.system.component") -local M = component.new("amazing_component", { const.ON_INPUT }) +local M = component.create("amazing_component", { const.ON_INPUT }) function M.init(self, ...) -- Component constructor @@ -139,7 +139,7 @@ On each component recomended describe component schema in next way: local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("new_component") +local M = component.create("new_component") local SCHEME = { ROOT = "/root", @@ -172,8 +172,25 @@ end You can check our example here _TODO_ +## Reserver componeney keywords +- initialize +- init +- update +- on_input +- on_message +- on_swipe +- setup_component +- get_style +- set_style +- set_template +- set_nodes +- get_context +- set_context +- get_druid + ## API _Link to ldoc_ +[API](https://AGulev.github.io/druid/) ## Internal Generate with `ldoc .` with `config.ld` file. [Instructions](https://github.com/stevedonovan/LDoc) @@ -183,6 +200,7 @@ _TODO_ ## License +Using [middleclass by kikito](https://github.com/kikito/middleclass) MIT License diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index bd4078e..e957989 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -4,7 +4,7 @@ local const = require("druid.const") local component = require("druid.system.component") -local M = component.new("back_handler", { const.ON_INPUT }) +local M = component.create("back_handler", { const.ON_INPUT }) --- Component init function diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 3011f1a..a599d7e 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -5,7 +5,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("blocker", { const.ON_SWIPE }) +local M = component.create("blocker", { const.ON_SWIPE }) function M.init(self, node) diff --git a/druid/base/button.lua b/druid/base/button.lua index 67c485e..d340933 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -9,7 +9,8 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("button", { const.ON_INPUT }) +local M = component.create("button", { const.ON_INPUT }) + --- Component init function -- @function button:init @@ -21,6 +22,7 @@ local M = component.new("button", { const.ON_INPUT }) -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) assert(callback, "Button should have callback. To block input on zone use blocker component") + self.style = self:get_style() self.node = helper.get_node(node) diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 1a52ad0..ef2f5d1 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -4,7 +4,7 @@ local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("checkbox") +local M = component.create("checkbox") function M.set_state(self, state, is_silence) diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 03faf8e..1360a3b 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -3,7 +3,7 @@ local component = require("druid.system.component") -local M = component.new("checkbox_group") +local M = component.create("checkbox_group") local function on_checkbox_click(self, index) diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 74c4d66..34ac83a 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -5,7 +5,7 @@ local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("grid") +local M = component.create("grid") function M.init(self, parent, element, in_row) diff --git a/druid/base/locale.lua b/druid/base/locale.lua index ec73bf9..effd5b3 100644 --- a/druid/base/locale.lua +++ b/druid/base/locale.lua @@ -6,7 +6,7 @@ local const = require("druid.const") local settings = require("druid.system.settings") local component = require("druid.system.component") -local M = component.new("locale", { const.ON_CHANGE_LANGUAGE }) +local M = component.create("locale", { const.ON_CHANGE_LANGUAGE }) function M.init(self, node, lang_id, no_adjust) diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 564cebb..f7b1ac6 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -5,7 +5,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("progress", { const.ON_UPDATE }) +local M = component.create("progress", { const.ON_UPDATE }) --- Component init function diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua index 4802ca8..2b0606b 100644 --- a/druid/base/radio_group.lua +++ b/druid/base/radio_group.lua @@ -3,7 +3,7 @@ local component = require("druid.system.component") -local M = component.new("radio_group") +local M = component.create("radio_group") local function on_checkbox_click(self, index) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 7716e3e..1e3a943 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -5,7 +5,7 @@ local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.system.component") -local M = component.new("scroll", { const.ON_UPDATE, const.ON_SWIPE }) +local M = component.create("scroll", { const.ON_UPDATE, const.ON_SWIPE }) -- Global on all scrolls diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 8503501..fd63782 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -5,7 +5,7 @@ local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.system.component") -local M = component.new("slider", { const.ON_SWIPE }) +local M = component.create("slider", { const.ON_SWIPE }) local function on_change_value(self) diff --git a/druid/base/text.lua b/druid/base/text.lua index f7db024..d0dff8a 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -6,7 +6,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("text") +local M = component.create("text") function M.init(self, node, value, no_adjust) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 5c26410..8554818 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -6,7 +6,7 @@ local formats = require("druid.helper.formats") local helper = require("druid.helper") local component = require("druid.system.component") -local M = component.new("timer", { const.ON_UPDATE }) +local M = component.create("timer", { const.ON_UPDATE }) function M.init(self, node, seconds_from, seconds_to, callback) diff --git a/druid/druid.lua b/druid/druid.lua index c1f582d..3b4b8fe 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -29,7 +29,14 @@ M.components = { checkbox_group = require("druid.base.checkbox_group"), radio_group = require("druid.base.radio_group"), + -- TODO: + -- input - text input + -- infinity_scroll -- to handle big data scroll + progress_rich = require("druid.rich.progress_rich"), + + -- TODO: Examples: + -- Slider menu like clash royale } @@ -52,8 +59,9 @@ function M.register(name, module) -- Possibly: druid.new(druid.BUTTON, etc?) -- Current way is very implicit druid_instance["new_" .. name] = function(self, ...) - return druid_instance.new(self, module, ...) + return druid_instance.create(self, module, ...) end + log("Register component", name) end @@ -65,20 +73,8 @@ function M.new(context, style) register_basic_components() register_basic_components = false end - local druid = setmetatable({}, { __index = druid_instance }) - -- Druid context here (who created druid) - -- Usually gui_script, but can be component from self:get_druid() - druid._context = context - druid._style = style or settings.default_style - - -- TODO: Find the better way to handle components - -- All component list - druid.all_components = {} - -- Map: interest: {components} - druid.components = {} - - return druid + return druid_instance(context, style) end @@ -90,6 +86,7 @@ end function M.set_text_function(callback) settings.get_text = callback or const.EMPTY_FUNCTION -- TODO: Update all localized text + -- TOOD: Need to store all current druid instances? end diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index 4a6d3e1..2c5de7c 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -3,7 +3,7 @@ local component = require("druid.system.component") -local M = component.new("progress_rich") +local M = component.create("progress_rich") function M.init(self, name, red, green, key) diff --git a/druid/system/component.lua b/druid/system/component.lua index b2d8d83..ccfe840 100644 --- a/druid/system/component.lua +++ b/druid/system/component.lua @@ -2,52 +2,12 @@ --@class component local const = require("druid.const") +local class = require("druid.system.middleclass") -local M = {} -local instance = {} +local Component = class("druid.component") -function instance.get_style(self) - if not self._meta.style then - return const.EMPTY_TABLE - end - - return self._meta.style[self._component.name] or const.EMPTY_TABLE -end - - -function instance.set_style(self, druid_style) - self._meta.style = druid_style -end - - -function instance.set_template(self, template) - self._meta.template = template -end - - -function instance.set_nodes(self, nodes) - self._meta.nodes = nodes -end - - -function instance.get_context(self, context) - return self._meta.context -end - - -function instance.set_context(self, context) - self._meta.context = context -end - - -function instance.get_druid(self) - local context = { _context = self } - return setmetatable(context, { __index = self:get_context().druid }) -end - - -function instance.setup_component(self, context, style) +function Component.setup_component(self, context, style) self._meta = { template = nil, context = nil, @@ -62,17 +22,99 @@ function instance.setup_component(self, context, style) end -function M.new(name, interest) - local mt = { - _component = { - name = name, - interest = interest - } - } - local component = setmetatable(mt, { __index = instance }) +function Component.get_style(self) + if not self._meta.style then + return const.EMPTY_TABLE + end - return component + return self._meta.style[self._component.name] or const.EMPTY_TABLE end -return M \ No newline at end of file +function Component.set_style(self, druid_style) + self._meta.style = druid_style +end + + +function Component.get_template(self) + return self._meta.template +end + + +function Component.set_template(self, template) + self._meta.template = template +end + + +function Component.get_nodes(self) + return self._meta.nodes +end + + +function Component.set_nodes(self, nodes) + self._meta.nodes = nodes +end + + +function Component.get_context(self, context) + return self._meta.context +end + + +function Component.set_context(self, context) + self._meta.context = context +end + + +function Component.get_interests(self) + return self._component.interest +end + + +-- TODO: Определиться с get_node и node +-- get_node - берет ноду по ноде или строке +-- node - может брать ноду у компонента по схеме (если есть +-- template или таблица нод после gui.clone_tree) +function Component.get_node(self, node_or_name) + local template_name = self:get_template() or const.EMPTY_STRING + local nodes = self:get_nodes() + + if nodes then + return nodes[template_name .. node_or_name] + else + if type(node_or_name) == const.STRING then + return gui.get_node(template_name .. node_or_name) + else + return node_or_name + end + end +end + + +function Component.get_druid(self) + local context = { _context = self } + return setmetatable(context, { __index = self:get_context().druid }) +end + + +function Component.initialize(self, name, interest) + self._component = { + name = name, + interest = interest + } +end + + +function Component.static.create(name, interest) + -- Yea, inheritance here + local new_class = class(name, Component) + + new_class.initialize = function(self) + Component.initialize(self, name, interest) + end + + return new_class +end + + +return Component diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 35abac6..80a27a2 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -1,8 +1,9 @@ local const = require("druid.const") local druid_input = require("druid.helper.druid_input") local settings = require("druid.system.settings") +local class = require("druid.system.middleclass") -local M = {} +local Druid = class("druid.druid_instance") local function input_init(self) @@ -19,16 +20,15 @@ end -- Create the component -local function create(self, module) +local function create(self, instance_class) ---@class component - local instance = setmetatable({}, { __index = module }) + local instance = instance_class() -- Component context, self from component creation instance:setup_component(self._context, self._style) - table.insert(self.all_components, instance) - local register_to = module._component.interest + local register_to = instance:get_interests() if register_to then for i = 1, #register_to do local interest = register_to[i] @@ -47,51 +47,6 @@ local function create(self, module) end -function M.new(self, module, ...) - local instance = create(self, module) - - if instance.init then - instance:init(...) - end - - return instance -end - - -function M.remove(self, instance) - for i = #self.all_components, 1, -1 do - if self.all_components[i] == instance then - table.remove(self, i) - end - end - - local interests = instance._component.interest - if interests then - for i = 1, #interests do - local interest = interests[i] - local array = self.components[interest] - for j = #array, 1, -1 do - if array[j] == instance then - table.remove(array, j) - end - end - end - end -end - - ---- Druid instance update function --- @function druid:update(dt) -function M.update(self, dt) - local array = self.components[const.ON_UPDATE] - if array then - for i = 1, #array do - array[i]:update(dt) - end - end -end - - local function notify_input_on_swipe(self) if self.components[const.ON_INPUT] then local len = #self.components[const.ON_INPUT] @@ -118,17 +73,76 @@ local function match_event(action_id, events) end +--- Druid constructor +function Druid.initialize(self, context, style) + self._context = context + self._style = style or settings.default_style + self.all_components = {} + self.components = {} +end + + +--- Create new component inside druid instance +function Druid.create(self, instance_class, ...) + local instance = create(self, instance_class) + + if instance.init then + instance:init(...) + end + + return instance +end + + +--- Remove component from druid instance +-- It will call on_remove on component, if exist +function Druid.remove(self, component) + for i = #self.all_components, 1, -1 do + if self.all_components[i] == component then + if component.on_remove then + component:on_remove() + end + table.remove(self, i) + end + end + + local interests = component:get_interests() + if interests then + for i = 1, #interests do + local interest = interests[i] + local array = self.components[interest] + for j = #array, 1, -1 do + if array[j] == component then + table.remove(array, j) + end + end + end + end +end + + +--- Druid instance update function +-- @function druid:update(dt) +function Druid.update(self, dt) + local array = self.components[const.ON_UPDATE] + if array then + for i = 1, #array do + array[i]:update(dt) + end + end +end + + --- Druid instance on_input function -- @function druid:on_input(action_id, action) -function M.on_input(self, action_id, action) +function Druid.on_input(self, action_id, action) -- TODO: расписать отличия ON_SWIPE и ON_INPUT -- Почему-то некоторые используют ON_SWIPE, а логичнее ON_INPUT? (blocker, slider) local array = self.components[const.ON_SWIPE] if array then - local v, result - local len = #array - for i = len, 1, -1 do - v = array[i] + local result + for i = #array, 1, -1 do + local v = array[i] result = result or v:on_input(action_id, action) end if result then @@ -139,42 +153,38 @@ function M.on_input(self, action_id, action) array = self.components[const.ON_INPUT] if array then - local v - local len = #array - for i = len, 1, -1 do - v = array[i] + for i = #array, 1, -1 do + local v = array[i] if match_event(action_id, v.event) and v:on_input(action_id, action) then return true end end return false end + return false end --- Druid instance on_message function -- @function druid:on_message(message_id, message, sender) -function M.on_message(self, message_id, message, sender) +function Druid.on_message(self, message_id, message, sender) local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] if specific_ui_message then local array = self.components[message_id] if array then - local item for i = 1, #array do - item = array[i] + local item = array[i] item[specific_ui_message](item, message, sender) end end else - local array = self.components[const.ON_MESSAGE] - if array then - for i = 1, #array do - array[i]:on_message(message_id, message, sender) - end + local array = self.components[const.ON_MESSAGE] or const.EMPTY_TABLE + for i = 1, #array do + array[i]:on_message(message_id, message, sender) end end end -return M +return Druid diff --git a/druid/system/middleclass.lua b/druid/system/middleclass.lua new file mode 100644 index 0000000..7e36bcd --- /dev/null +++ b/druid/system/middleclass.lua @@ -0,0 +1,183 @@ +local middleclass = { + _VERSION = 'middleclass v4.1.1', + _DESCRIPTION = 'Object Orientation for Lua', + _URL = 'https://github.com/kikito/middleclass', + _LICENSE = [[ + MIT LICENSE + + Copyright (c) 2011 Enrique García Cota + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ]] +} + +local function _createIndexWrapper(aClass, f) + if f == nil then + return aClass.__instanceDict + else + return function(self, name) + local value = aClass.__instanceDict[name] + + if value ~= nil then + return value + elseif type(f) == "function" then + return (f(self, name)) + else + return f[name] + end + end + end +end + +local function _propagateInstanceMethod(aClass, name, f) + f = name == "__index" and _createIndexWrapper(aClass, f) or f + aClass.__instanceDict[name] = f + + for subclass in pairs(aClass.subclasses) do + if rawget(subclass.__declaredMethods, name) == nil then + _propagateInstanceMethod(subclass, name, f) + end + end +end + +local function _declareInstanceMethod(aClass, name, f) + aClass.__declaredMethods[name] = f + + if f == nil and aClass.super then + f = aClass.super.__instanceDict[name] + end + + _propagateInstanceMethod(aClass, name, f) +end + +local function _tostring(self) return "class " .. self.name end +local function _call(self, ...) return self:new(...) end + +local function _createClass(name, super) + local dict = {} + dict.__index = dict + + local aClass = { name = name, super = super, static = {}, + __instanceDict = dict, __declaredMethods = {}, + subclasses = setmetatable({}, {__mode='k'}) } + + if super then + setmetatable(aClass.static, { + __index = function(_,k) + local result = rawget(dict,k) + if result == nil then + return super.static[k] + end + return result + end + }) + else + setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) end }) + end + + setmetatable(aClass, { __index = aClass.static, __tostring = _tostring, + __call = _call, __newindex = _declareInstanceMethod }) + + return aClass +end + +local function _includeMixin(aClass, mixin) + assert(type(mixin) == 'table', "mixin must be a table") + + for name,method in pairs(mixin) do + if name ~= "included" and name ~= "static" then aClass[name] = method end + end + + for name,method in pairs(mixin.static or {}) do + aClass.static[name] = method + end + + if type(mixin.included)=="function" then mixin:included(aClass) end + return aClass +end + +local DefaultMixin = { + __tostring = function(self) return "instance of " .. tostring(self.class) end, + + initialize = function(self, ...) end, + + isInstanceOf = function(self, aClass) + return type(aClass) == 'table' + and type(self) == 'table' + and (self.class == aClass + or type(self.class) == 'table' + and type(self.class.isSubclassOf) == 'function' + and self.class:isSubclassOf(aClass)) + end, + + static = { + allocate = function(self) + assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'") + return setmetatable({ class = self }, self.__instanceDict) + end, + + new = function(self, ...) + assert(type(self) == 'table', "Make sure that you are using 'Class:new' instead of 'Class.new'") + local instance = self:allocate() + instance:initialize(...) + return instance + end, + + subclass = function(self, name) + assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'") + assert(type(name) == "string", "You must provide a name(string) for your class") + + local subclass = _createClass(name, self) + + for methodName, f in pairs(self.__instanceDict) do + _propagateInstanceMethod(subclass, methodName, f) + end + subclass.initialize = function(instance, ...) return self.initialize(instance, ...) end + + self.subclasses[subclass] = true + self:subclassed(subclass) + + return subclass + end, + + subclassed = function(self, other) end, + + isSubclassOf = function(self, other) + return type(other) == 'table' and + type(self.super) == 'table' and + ( self.super == other or self.super:isSubclassOf(other) ) + end, + + include = function(self, ...) + assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'") + for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end + return self + end + } +} + +function middleclass.class(name, super) + assert(type(name) == 'string', "A name (string) is needed for the new class") + return super and super:subclass(name) or _includeMixin(_createClass(name), DefaultMixin) +end + +setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end }) + +return middleclass diff --git a/druid/system/settings.lua b/druid/system/settings.lua index 637339d..1ca7dbe 100644 --- a/druid/system/settings.lua +++ b/druid/system/settings.lua @@ -9,13 +9,11 @@ M.auto_focus_gain = true function M.get_text(name) - -- override to get text for localized text return "[Druid]: locales not inited" end function M.play_sound(name) - -- override to play sound with name end From 9ae07b4784f3c7bc6d499b49c4b437b7cc2aa79c Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 3 Feb 2020 22:16:01 +0300 Subject: [PATCH 092/136] Druid instance refactoring --- druid/const.lua | 2 ++ druid/druid.lua | 2 +- druid/system/druid_instance.lua | 58 +++++++++++++++++---------------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/druid/const.lua b/druid/const.lua index eec8606..b5b820e 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -16,6 +16,8 @@ M.STRING = "string" M.TABLE = "table" M.ZERO = "0" +M.ALL = "all" + --- Interests M.ON_MESSAGE = hash("on_message") M.ON_UPDATE = hash("on_update") diff --git a/druid/druid.lua b/druid/druid.lua index 3b4b8fe..31ac629 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -86,7 +86,7 @@ end function M.set_text_function(callback) settings.get_text = callback or const.EMPTY_FUNCTION -- TODO: Update all localized text - -- TOOD: Need to store all current druid instances? + -- Need to store all current druid instances to iterate over it? end diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 80a27a2..e174852 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -26,7 +26,9 @@ local function create(self, instance_class) -- Component context, self from component creation instance:setup_component(self._context, self._style) - table.insert(self.all_components, instance) + + self.components[const.ALL] = self.components[const.ALL] or {} + table.insert(self.components[const.ALL], instance) local register_to = instance:get_interests() if register_to then @@ -77,7 +79,6 @@ end function Druid.initialize(self, context, style) self._context = context self._style = style or settings.default_style - self.all_components = {} self.components = {} end @@ -97,8 +98,9 @@ end --- Remove component from druid instance -- It will call on_remove on component, if exist function Druid.remove(self, component) - for i = #self.all_components, 1, -1 do - if self.all_components[i] == component then + local all_components = self.components[const.ALL] + for i = #all_components, 1, -1 do + if all_components[i] == component then if component.on_remove then component:on_remove() end @@ -110,10 +112,10 @@ function Druid.remove(self, component) if interests then for i = 1, #interests do local interest = interests[i] - local array = self.components[interest] - for j = #array, 1, -1 do - if array[j] == component then - table.remove(array, j) + local components = self.components[interest] + for j = #components, 1, -1 do + if components[j] == component then + table.remove(components, j) end end end @@ -124,10 +126,10 @@ end --- Druid instance update function -- @function druid:update(dt) function Druid.update(self, dt) - local array = self.components[const.ON_UPDATE] - if array then - for i = 1, #array do - array[i]:update(dt) + local components = self.components[const.ON_UPDATE] + if components then + for i = 1, #components do + components[i]:update(dt) end end end @@ -138,11 +140,11 @@ end function Druid.on_input(self, action_id, action) -- TODO: расписать отличия ON_SWIPE и ON_INPUT -- Почему-то некоторые используют ON_SWIPE, а логичнее ON_INPUT? (blocker, slider) - local array = self.components[const.ON_SWIPE] - if array then + local components = self.components[const.ON_SWIPE] + if components then local result - for i = #array, 1, -1 do - local v = array[i] + for i = #components, 1, -1 do + local v = components[i] result = result or v:on_input(action_id, action) end if result then @@ -151,10 +153,10 @@ function Druid.on_input(self, action_id, action) end end - array = self.components[const.ON_INPUT] - if array then - for i = #array, 1, -1 do - local v = array[i] + components = self.components[const.ON_INPUT] + if components then + for i = #components, 1, -1 do + local v = components[i] if match_event(action_id, v.event) and v:on_input(action_id, action) then return true end @@ -171,17 +173,17 @@ end function Druid.on_message(self, message_id, message, sender) local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] if specific_ui_message then - local array = self.components[message_id] - if array then - for i = 1, #array do - local item = array[i] - item[specific_ui_message](item, message, sender) + local components = self.components[message_id] + if components then + for i = 1, #components do + local component = components[i] + component[specific_ui_message](component, message, sender) end end else - local array = self.components[const.ON_MESSAGE] or const.EMPTY_TABLE - for i = 1, #array do - array[i]:on_message(message_id, message, sender) + local components = self.components[const.ON_MESSAGE] or const.EMPTY_TABLE + for i = 1, #components do + components[i]:on_message(message_id, message, sender) end end end From f619b25ba8504c6eba7752b269435adedf32a884 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 5 Feb 2020 02:42:36 +0300 Subject: [PATCH 093/136] Update docs --- config.ld | 1 - docs/index.html | 85 +++++----- docs/modules/base.back_handler.html | 16 +- docs/modules/base.blocker.html | 6 +- docs/modules/base.button.html | 27 +-- docs/modules/base.checkbox.html | 6 +- docs/modules/base.checkbox_group.html | 6 +- docs/modules/base.grid.html | 9 +- docs/modules/base.progress.html | 36 ++-- docs/modules/base.scroll.html | 39 +++-- docs/modules/base.slider.html | 6 +- docs/modules/base.text.html | 84 +++++----- docs/modules/base.timer.html | 20 ++- docs/modules/druid.html | 233 +++++--------------------- docs/modules/helper.animate.html | 34 ++-- docs/modules/helper.formats.html | 47 +++--- docs/modules/helper.html | 37 ++-- docs/modules/rich.progress_rich.html | 42 ++--- docs/modules/settings.html | 30 ++-- 19 files changed, 333 insertions(+), 431 deletions(-) diff --git a/config.ld b/config.ld index 92f8231..43d3a05 100644 --- a/config.ld +++ b/config.ld @@ -1,7 +1,6 @@ project='Druid' title='Defold Druid UI Library' description='Documentation for Druid Library' -format='lunamark' file={"./druid"} dir='./docs' style='!pale' diff --git a/docs/index.html b/docs/index.html index 59a5bb7..e8b905e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -31,25 +31,26 @@

Modules

@@ -62,55 +63,61 @@

Modules

- + - + - + - + - + - + - + + + + + - + - + - + - - + + - + - + @@ -119,23 +126,23 @@ - - - - - + - + - - + + + + + +
base.back_handlerdruid.back_handler Component to handle back key (android, backspace)
base.blockerdruid.blocker Component to block input on specify zone (node)
base.buttondruid.button Component to handle basic GUI button
base.checkboxdruid.checkbox Druid checkbox component
base.checkbox_groupdruid.checkbox_group Checkboux group module
base.griddruid.grid Component to handle placing components by row and columns.
base.progressdruid.localeComponent to handle all GUI texts + Good working with localization system
druid.progress Basic progress bar component
base.checkbox_groupdruid.radio_group Radio group module
base.scrolldruid.scroll Component to handle scroll content
base.sliderdruid.slider Druid slider component
base.textComponent to handle all GUI texts Good working with localization systemdruid.textComponent to handle all GUI texts + Good working with localization system
base.timerdruid.timer Component to handle GUI timers
constantsconst Druid constants
helperDruid helper module
helper.animateDruid helper module for animating GUI nodesText node or icon node can be nil
helper.formats Druid module with utils on string formats
rich.progress_richdruid.progress_rich Component for rich progress component
settingsDruid settings filecomponentBasic class for all Druid components.
druid_instanceDruid main class.
@@ -143,7 +150,7 @@
generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 02:41:04
diff --git a/docs/modules/base.back_handler.html b/docs/modules/base.back_handler.html index 5d11f6e..50d1f20 100644 --- a/docs/modules/base.back_handler.html +++ b/docs/modules/base.back_handler.html @@ -44,18 +44,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -99,15 +101,15 @@
    • self table - Component instance + Component instance
    • callback callback - On back button + On back button
    • Callback params - argument + argument (optional)
    @@ -129,11 +131,11 @@
    • action_id string - on_input action id + on_input action id
    • action table - on_input action + on_input action
    @@ -149,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.blocker.html b/docs/modules/base.blocker.html index 9d0f4a5..e43d201 100644 --- a/docs/modules/base.blocker.html +++ b/docs/modules/base.blocker.html @@ -40,18 +40,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -75,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.button.html b/docs/modules/base.button.html index f99cfcd..57ef749 100644 --- a/docs/modules/base.button.html +++ b/docs/modules/base.button.html @@ -44,18 +44,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -103,29 +105,29 @@
    • self table - Component instance + Component instance
    • node node - Gui node + Gui node
    • callback function - Button callback + Button callback
    • params table - Button callback params + Button callback params (optional)
    • anim_node node - Button anim node (node, if not provided) + Button anim node (node, if not provided) (optional)
    • event string - Button react event, const.ACTION_TOUCH by default + Button react event, const.ACTION_TOUCH by default (optional)
    @@ -147,7 +149,7 @@
    • self table - Component instance + Component instance
    @@ -161,18 +163,19 @@ set_click_zone(self, zone)
    - Strict button click area. Useful for no click events outside stencil node + Strict button click area. Useful for + no click events outside stencil node

    Parameters:

    • self table - Component instance + Component instance
    • zone node - Gui node + Gui node
    @@ -188,7 +191,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.checkbox.html b/docs/modules/base.checkbox.html index cc3dce8..92d23d3 100644 --- a/docs/modules/base.checkbox.html +++ b/docs/modules/base.checkbox.html @@ -40,18 +40,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -75,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.checkbox_group.html b/docs/modules/base.checkbox_group.html index 2c8f1d9..34069ff 100644 --- a/docs/modules/base.checkbox_group.html +++ b/docs/modules/base.checkbox_group.html @@ -40,18 +40,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -75,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.grid.html b/docs/modules/base.grid.html index c8e0f78..af5cf25 100644 --- a/docs/modules/base.grid.html +++ b/docs/modules/base.grid.html @@ -40,18 +40,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -61,7 +63,8 @@

    Module base.grid

    Component to handle placing components by row and columns.

    -

    Grid can anchor your elements, get content size and other

    +

    + Grid can anchor your elements, get content size and other

    @@ -75,7 +78,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.progress.html b/docs/modules/base.progress.html index ba8e905..5622257 100644 --- a/docs/modules/base.progress.html +++ b/docs/modules/base.progress.html @@ -44,18 +44,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -119,19 +121,19 @@
    • self table - Component instance + Component instance
    • node string or node - Progress bar fill node or node name + Progress bar fill node or node name
    • key string - Progress bar direction (x or y) + Progress bar direction (x or y)
    • init_value number - Initial value of progress bar + Initial value of progress bar
    @@ -152,7 +154,7 @@
    • self table - Component instance + Component instance
    @@ -173,7 +175,7 @@
    • self table - Component instance + Component instance
    @@ -194,11 +196,11 @@
    • self table - Component instance + Component instance
    • to number - Progress bar value, from 0 to 1 + Progress bar value, from 0 to 1
    @@ -219,7 +221,7 @@
    • self table - Component instance + Component instance
    @@ -240,15 +242,15 @@
    • self table - Component instance + Component instance
    • steps table - Array of progress bar values + Array of progress bar values
    • callback function - Callback on intersect step value + Callback on intersect step value
    @@ -269,15 +271,15 @@
    • self table - Component instance + Component instance
    • to number - value between 0..1 + value between 0..1
    • callback function - Callback on animation ends + Callback on animation ends (optional)
    @@ -294,7 +296,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.scroll.html b/docs/modules/base.scroll.html index dabe409..087322d 100644 --- a/docs/modules/base.scroll.html +++ b/docs/modules/base.scroll.html @@ -44,18 +44,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -115,11 +117,11 @@
    • vector3 point - target point + target point
    • is_instant bool - instant scroll flag + instant scroll flag (optional)
    @@ -146,15 +148,15 @@
    • self table - Component instance + Component instance
    • index number - Point index + Point index
    • skip_cb boolean - If true, skip the point callback + If true, skip the point callback (optional)
    @@ -169,18 +171,19 @@ set_points(self, points)
    - Set points of interest. Scroll will always centered on closer points + Set points of interest. + Scroll will always centered on closer points

    Parameters:

    • self table - Component instance + Component instance
    • points table - Array of vector3 points + Array of vector3 points
    @@ -194,18 +197,20 @@ set_inert(self, state)
    - Enable or disable scroll inert. If disabled, scroll through points (if exist) If no points, just simple drag without inertion + Enable or disable scroll inert. + If disabled, scroll through points (if exist) + If no points, just simple drag without inertion

    Parameters:

    • self table - Component instance + Component instance
    • state boolean - Inert scroll state + Inert scroll state
    @@ -226,11 +231,11 @@
    • self table - Component instance + Component instance
    • callback function - Callback on scroll to point of interest + Callback on scroll to point of interest
    @@ -251,11 +256,11 @@
    • self table - Component instance + Component instance
    • border vmath.vector3 - Size of scrolling area + Size of scrolling area
    @@ -271,7 +276,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.slider.html b/docs/modules/base.slider.html index 14f8f6e..37e794d 100644 --- a/docs/modules/base.slider.html +++ b/docs/modules/base.slider.html @@ -40,18 +40,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -75,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.text.html b/docs/modules/base.text.html index 26e0f16..7b29689 100644 --- a/docs/modules/base.text.html +++ b/docs/modules/base.text.html @@ -44,18 +44,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -64,16 +66,13 @@

    Module base.text

    -

    Component to handle all GUI texts Good working with localization system

    +

    Component to handle all GUI texts + Good working with localization system

    Functions

    - - - - @@ -90,6 +89,10 @@ + + + +
    translate(self, locale_id)Translate the text by locale_id
    set_to(self, set_to) Set text to text fieldset_scale(self, scale) Set scale
    set_pivot(self, pivot)Set text pivot.

    @@ -99,31 +102,6 @@

    Functions

    -
    - - translate(self, locale_id) -
    -
    - Translate the text by locale_id - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • locale_id - string - Locale id -
    • -
    - - - - - -
    set_to(self, set_to) @@ -136,11 +114,11 @@
    • self table - Component instance + Component instance
    • set_to string - Text for node + Text for node
    @@ -161,11 +139,11 @@
    • self table - Component instance + Component instance
    • color vmath.vector4 - Color for node + Color for node
    @@ -186,11 +164,11 @@
    • self table - Component instance + Component instance
    • alpha number - Alpha for node + Alpha for node
    @@ -211,11 +189,37 @@
    • self table - Component instance + Component instance
    • scale vmath.vector3 - Scale for node + Scale for node +
    • +
    + + + + + +
    +
    + + set_pivot(self, pivot) +
    +
    + Set text pivot. Text will re-anchor inside + his text area + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • pivot + gui.pivot + Gui pivot constant
    @@ -231,7 +235,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/base.timer.html b/docs/modules/base.timer.html index dc66bfb..7c5d6fb 100644 --- a/docs/modules/base.timer.html +++ b/docs/modules/base.timer.html @@ -44,18 +44,20 @@
  • base.checkbox
  • base.checkbox_group
  • base.grid
  • +
  • base.text
  • base.progress
  • base.checkbox_group
  • base.scroll
  • base.slider
  • base.text
  • base.timer
  • -
  • constants
  • +
  • const
  • druid
  • helper
  • helper.animate
  • helper.formats
  • rich.progress_rich
  • +
  • component
  • settings
  • @@ -103,11 +105,11 @@
    • self table - Component instance + Component instance
    • set_to number - Value in seconds + Value in seconds
    @@ -128,11 +130,11 @@
    • self table - Component instance + Component instance
    • is_on boolean - Timer enable state + Timer enable state
    @@ -153,15 +155,15 @@
    • self table - Component instance + Component instance
    • from number - Start time in seconds + Start time in seconds
    • to number - Target time in seconds + Target time in seconds
    @@ -177,7 +179,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-04 23:46:10
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index f7b1a7a..41b769f 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -33,31 +33,31 @@

    Contents

    Modules

    @@ -66,37 +66,25 @@

    Module druid

    Druid UI Library.

    -

    Component based UI library to make your life easier. Contains a lot of base components and give API to create your own rich components.

    +

    + Powerful Defold component based UI library. Use standart + components or make your own game-specific to make amazing + GUI in your games. +

    Contains the several basic components and examples + to how to do your custom complex components to + separate UI game logic to small files +

    Functions

    - + - - - - - - - - - - - - - - - -
    register(name, module)Register external moduleRegister external druid component.
    new(component_script)Create UI instance for ui elements
    _fct_metatable.on_message(self, message_id, message, sender)Called on_message
    _fct_metatable.on_input(self, action_id, action)Called ON_INPUT
    _fct_metatable.update(self, dt)Called on_update
    -

    Tables

    - - - - + +
    compsBasic componentsnew(context[, style])Create Druid instance.
    @@ -112,18 +100,20 @@ register(name, module)
    - Register external module + Register external druid component. + After register you can create the component with + druid_instance:new_{name}. For example `druid:new_button(...)`

    Parameters:

    • name string - module name + module name
    • module table - lua table with module + lua table with component
    @@ -134,166 +124,35 @@
    - new(component_script) + new(context[, style])
    - Create UI instance for ui elements + Create Druid instance.

    Parameters:

      -
    • component_script - +
    • context + table + Druid context. Usually it is self of script +
    • +
    • style + table + Druid style module + (optional)

    Returns:

      - instance with all ui components + druid_instance + Druid instance
    -
    -
    - - _fct_metatable.on_message(self, message_id, message, sender) -
    -
    - Called on_message - - -

    Parameters:

    -
      -
    • self - -
    • -
    • message_id - -
    • -
    • message - -
    • -
    • sender - -
    • -
    - - - - - -
    -
    - - _fct_metatable.on_input(self, action_id, action) -
    -
    - Called ON_INPUT - - -

    Parameters:

    -
      -
    • self - -
    • -
    • action_id - -
    • -
    • action - -
    • -
    - - - - - -
    -
    - - _fct_metatable.update(self, dt) -
    -
    - Called on_update - - -

    Parameters:

    -
      -
    • self - -
    • -
    • dt - -
    • -
    - - - - - -
    - -

    Tables

    - -
    -
    - - comps -
    -
    - Basic components - - -

    Fields:

    -
      -
    • button - -
    • -
    • blocker - -
    • -
    • back_handler - -
    • -
    • text - -
    • -
    • timer - -
    • -
    • progress - -
    • -
    • grid - -
    • -
    • scroll - -
    • -
    • slider - -
    • -
    • checkbox - -
    • -
    • checkbox_group - -
    • -
    • radio_group - -
    • -
    • progress_rich - -
    • -
    - - - - -
    @@ -302,7 +161,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 02:41:04
    diff --git a/docs/modules/helper.animate.html b/docs/modules/helper.animate.html index 63f59ee..b07fb30 100644 --- a/docs/modules/helper.animate.html +++ b/docs/modules/helper.animate.html @@ -34,25 +34,27 @@

    Modules

    @@ -75,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 00:14:12
    diff --git a/docs/modules/helper.formats.html b/docs/modules/helper.formats.html index 6cf1ce1..e89c3e9 100644 --- a/docs/modules/helper.formats.html +++ b/docs/modules/helper.formats.html @@ -38,25 +38,26 @@

    Modules

    @@ -103,18 +104,18 @@
    • num number - Number for conversion + Number for conversion
    • count number - Count of numerals + Count of numerals

    Returns:

      - string with need count of zero (1,3) -> 001 + string with need count of zero (1,3) -> 001
    @@ -133,7 +134,7 @@
    • sec number - Seconds + Seconds
    @@ -159,11 +160,11 @@
    • s string - Target string + Target string
    • tab table - Table with parameters + Table with parameters
    @@ -184,7 +185,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 02:41:04
    diff --git a/docs/modules/helper.html b/docs/modules/helper.html index e7ecf16..6e1efff 100644 --- a/docs/modules/helper.html +++ b/docs/modules/helper.html @@ -38,25 +38,26 @@

    Modules

    @@ -64,7 +65,7 @@

    Module helper

    -

    Druid helper module

    +

    Text node or icon node can be nil

    @@ -146,7 +147,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 02:41:04
    diff --git a/docs/modules/rich.progress_rich.html b/docs/modules/rich.progress_rich.html index 0ce5b2e..e69b51e 100644 --- a/docs/modules/rich.progress_rich.html +++ b/docs/modules/rich.progress_rich.html @@ -38,24 +38,26 @@

    Modules

    @@ -103,11 +105,11 @@
    • self table - Component instance + Component instance
    • value number - Progress bar value, from 0 to 1 + Progress bar value, from 0 to 1
    @@ -128,7 +130,7 @@
    • self table - Component instance + Component instance
    @@ -149,15 +151,15 @@
    • self table - Component instance + Component instance
    • to number - value between 0..1 + value between 0..1
    • callback function - Callback on animation ends + Callback on animation ends (optional)
    @@ -174,7 +176,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 00:02:17
    diff --git a/docs/modules/settings.html b/docs/modules/settings.html index 205e608..4dbda1f 100644 --- a/docs/modules/settings.html +++ b/docs/modules/settings.html @@ -34,24 +34,26 @@

    Modules

    @@ -75,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 +Last updated 2020-02-05 00:02:17
    From 366c8a9acc2440f4af8308ba8230d3d6769483b7 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 5 Feb 2020 02:42:58 +0300 Subject: [PATCH 094/136] Add missed docs files --- docs/modules/.druidback_handler.html | 158 ++++++ docs/modules/.druidblocker.html | 84 +++ docs/modules/.druidbutton.html | 198 +++++++ docs/modules/.druidcheckbox.html | 84 +++ docs/modules/.druidcheckbox_group.html | 84 +++ docs/modules/.druidgrid.html | 85 +++ docs/modules/.druidprogress.html | 303 +++++++++++ docs/modules/.druidscroll.html | 283 ++++++++++ docs/modules/.druidslider.html | 84 +++ docs/modules/.druidtext.html | 242 +++++++++ docs/modules/.druidtimer.html | 186 +++++++ docs/modules/component.html | 405 ++++++++++++++ docs/modules/const.html | 112 ++++ docs/modules/druid.back_handler.html | 157 ++++++ docs/modules/druid.blocker.html | 83 +++ docs/modules/druid.button.html | 197 +++++++ docs/modules/druid.checkbox.html | 83 +++ docs/modules/druid.checkbox_group.html | 83 +++ docs/modules/druid.grid.html | 84 +++ docs/modules/druid.locale.html | 124 +++++ docs/modules/druid.progress.html | 302 +++++++++++ docs/modules/druid.progress_rich.html | 182 +++++++ docs/modules/druid.radio_group.html | 83 +++ docs/modules/druid.scroll.html | 282 ++++++++++ docs/modules/druid.slider.html | 83 +++ docs/modules/druid.text.html | 241 +++++++++ docs/modules/druid.timer.html | 185 +++++++ docs/modules/druid_instance.html | 716 +++++++++++++++++++++++++ 28 files changed, 5193 insertions(+) create mode 100644 docs/modules/.druidback_handler.html create mode 100644 docs/modules/.druidblocker.html create mode 100644 docs/modules/.druidbutton.html create mode 100644 docs/modules/.druidcheckbox.html create mode 100644 docs/modules/.druidcheckbox_group.html create mode 100644 docs/modules/.druidgrid.html create mode 100644 docs/modules/.druidprogress.html create mode 100644 docs/modules/.druidscroll.html create mode 100644 docs/modules/.druidslider.html create mode 100644 docs/modules/.druidtext.html create mode 100644 docs/modules/.druidtimer.html create mode 100644 docs/modules/component.html create mode 100644 docs/modules/const.html create mode 100644 docs/modules/druid.back_handler.html create mode 100644 docs/modules/druid.blocker.html create mode 100644 docs/modules/druid.button.html create mode 100644 docs/modules/druid.checkbox.html create mode 100644 docs/modules/druid.checkbox_group.html create mode 100644 docs/modules/druid.grid.html create mode 100644 docs/modules/druid.locale.html create mode 100644 docs/modules/druid.progress.html create mode 100644 docs/modules/druid.progress_rich.html create mode 100644 docs/modules/druid.radio_group.html create mode 100644 docs/modules/druid.scroll.html create mode 100644 docs/modules/druid.slider.html create mode 100644 docs/modules/druid.text.html create mode 100644 docs/modules/druid.timer.html create mode 100644 docs/modules/druid_instance.html diff --git a/docs/modules/.druidback_handler.html b/docs/modules/.druidback_handler.html new file mode 100644 index 0000000..db4227b --- /dev/null +++ b/docs/modules/.druidback_handler.html @@ -0,0 +1,158 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidback_handler

    +

    Component to handle back key (android, backspace)

    +

    + + +

    Functions

    + + + + + + + + + +
    back_handler:init(self, callback[, Callback])Component init function
    back_handler:on_input(action_id, action)Input handler for component
    + +
    +
    + + +

    Functions

    + +
    +
    + + back_handler:init(self, callback[, Callback]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • callback + callback + On back button +
    • +
    • Callback + params + argument + (optional) +
    • +
    + + + + + +
    +
    + + back_handler:on_input(action_id, action) +
    +
    + Input handler for component + + +

    Parameters:

    +
      +
    • action_id + string + on_input action id +
    • +
    • action + table + on_input action +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidblocker.html b/docs/modules/.druidblocker.html new file mode 100644 index 0000000..24bcd5f --- /dev/null +++ b/docs/modules/.druidblocker.html @@ -0,0 +1,84 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidblocker

    +

    Component to block input on specify zone (node)

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidbutton.html b/docs/modules/.druidbutton.html new file mode 100644 index 0000000..810d334 --- /dev/null +++ b/docs/modules/.druidbutton.html @@ -0,0 +1,198 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidbutton

    +

    Component to handle basic GUI button

    +

    + + +

    Functions

    + + + + + + + + + + + + + +
    button:init(self, node, callback[, params[, anim_node[, event]]])Component init function
    button:disable_animation(self)Disable all button animations
    button:set_click_zone(self, zone)Strict button click area.
    + +
    +
    + + +

    Functions

    + +
    +
    + + button:init(self, node, callback[, params[, anim_node[, event]]]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • node + node + Gui node +
    • +
    • callback + function + Button callback +
    • +
    • params + table + Button callback params + (optional) +
    • +
    • anim_node + node + Button anim node (node, if not provided) + (optional) +
    • +
    • event + string + Button react event, const.ACTION_TOUCH by default + (optional) +
    • +
    + + + + + +
    +
    + + button:disable_animation(self) +
    +
    + Disable all button animations + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + button:set_click_zone(self, zone) +
    +
    + Strict button click area. Useful for + no click events outside stencil node + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • zone + node + Gui node +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidcheckbox.html b/docs/modules/.druidcheckbox.html new file mode 100644 index 0000000..fad3da3 --- /dev/null +++ b/docs/modules/.druidcheckbox.html @@ -0,0 +1,84 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidcheckbox

    +

    Druid checkbox component

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidcheckbox_group.html b/docs/modules/.druidcheckbox_group.html new file mode 100644 index 0000000..71aa616 --- /dev/null +++ b/docs/modules/.druidcheckbox_group.html @@ -0,0 +1,84 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidcheckbox_group

    +

    Radio group module

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidgrid.html b/docs/modules/.druidgrid.html new file mode 100644 index 0000000..10824a8 --- /dev/null +++ b/docs/modules/.druidgrid.html @@ -0,0 +1,85 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidgrid

    +

    Component to handle placing components by row and columns.

    +

    + Grid can anchor your elements, get content size and other

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidprogress.html b/docs/modules/.druidprogress.html new file mode 100644 index 0000000..e4f351d --- /dev/null +++ b/docs/modules/.druidprogress.html @@ -0,0 +1,303 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidprogress

    +

    Basic progress bar component

    +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    progress:init(self, node, key, init_value)Component init function
    progress:empty(self)Fill a progress bar and stop progress animation
    progress:empty(self)Empty a progress bar
    progress:set_to(self, to)Instant fill progress bar to value
    progress:get(self)Return current progress bar value
    progress:set_steps(self, steps, callback)Set points on progress bar to fire the callback
    progress:to(self, to[, callback])Start animation of a progress bar
    + +
    +
    + + +

    Functions

    + +
    +
    + + progress:init(self, node, key, init_value) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • node + string or node + Progress bar fill node or node name +
    • +
    • key + string + Progress bar direction (x or y) +
    • +
    • init_value + number + Initial value of progress bar +
    • +
    + + + + + +
    +
    + + progress:empty(self) +
    +
    + Fill a progress bar and stop progress animation + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + progress:empty(self) +
    +
    + Empty a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + progress:set_to(self, to) +
    +
    + Instant fill progress bar to value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • to + number + Progress bar value, from 0 to 1 +
    • +
    + + + + + +
    +
    + + progress:get(self) +
    +
    + Return current progress bar value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + progress:set_steps(self, steps, callback) +
    +
    + Set points on progress bar to fire the callback + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • steps + table + Array of progress bar values +
    • +
    • callback + function + Callback on intersect step value +
    • +
    + + + + + +
    +
    + + progress:to(self, to[, callback]) +
    +
    + Start animation of a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • to + number + value between 0..1 +
    • +
    • callback + function + Callback on animation ends + (optional) +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidscroll.html b/docs/modules/.druidscroll.html new file mode 100644 index 0000000..42b29ff --- /dev/null +++ b/docs/modules/.druidscroll.html @@ -0,0 +1,283 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidscroll

    +

    Component to handle scroll content

    +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    scroll:scroll_to(vector3[, is_instant])Start scroll to target point
    scroll:init(self, index[, skip_cb])Scroll to item in scroll by point index
    scroll:set_points(self, points)Set points of interest.
    scroll:set_inert(self, state)Enable or disable scroll inert.
    scroll:on_point_move(self, callback)Set the callback on scrolling to point (if exist)
    scroll:set_border(self, border)Set the scroll possibly area
    + +
    +
    + + +

    Functions

    + +
    +
    + + scroll:scroll_to(vector3[, is_instant]) +
    +
    + Start scroll to target point + + +

    Parameters:

    +
      +
    • vector3 + point + target point +
    • +
    • is_instant + bool + instant scroll flag + (optional) +
    • +
    + + + + +

    Usage:

    +
      +
    • scroll:scroll_to(vmath.vector3(0, 50, 0))
    • +
    • scroll:scroll_to(vmath.vector3(0), true)
    • +
    + +
    +
    + + scroll:init(self, index[, skip_cb]) +
    +
    + Scroll to item in scroll by point index + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • index + number + Point index +
    • +
    • skip_cb + boolean + If true, skip the point callback + (optional) +
    • +
    + + + + + +
    +
    + + scroll:set_points(self, points) +
    +
    + Set points of interest. + Scroll will always centered on closer points + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • points + table + Array of vector3 points +
    • +
    + + + + + +
    +
    + + scroll:set_inert(self, state) +
    +
    + Enable or disable scroll inert. + If disabled, scroll through points (if exist) + If no points, just simple drag without inertion + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • state + boolean + Inert scroll state +
    • +
    + + + + + +
    +
    + + scroll:on_point_move(self, callback) +
    +
    + Set the callback on scrolling to point (if exist) + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • callback + function + Callback on scroll to point of interest +
    • +
    + + + + + +
    +
    + + scroll:set_border(self, border) +
    +
    + Set the scroll possibly area + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • border + vmath.vector3 + Size of scrolling area +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidslider.html b/docs/modules/.druidslider.html new file mode 100644 index 0000000..58b522b --- /dev/null +++ b/docs/modules/.druidslider.html @@ -0,0 +1,84 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidslider

    +

    Druid slider component

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidtext.html b/docs/modules/.druidtext.html new file mode 100644 index 0000000..8700c2e --- /dev/null +++ b/docs/modules/.druidtext.html @@ -0,0 +1,242 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidtext

    +

    Component to handle all GUI texts + Good working with localization system

    +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + +
    text:set_to(self, set_to)Set text to text field
    text:set_color(self, color)Set color
    text:set_alpha(self, alpha)Set alpha
    text:set_scale(self, scale)Set scale
    text:set_pivot(self, pivot)Set text pivot.
    + +
    +
    + + +

    Functions

    + +
    +
    + + text:set_to(self, set_to) +
    +
    + Set text to text field + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • set_to + string + Text for node +
    • +
    + + + + + +
    +
    + + text:set_color(self, color) +
    +
    + Set color + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • color + vmath.vector4 + Color for node +
    • +
    + + + + + +
    +
    + + text:set_alpha(self, alpha) +
    +
    + Set alpha + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • alpha + number + Alpha for node +
    • +
    + + + + + +
    +
    + + text:set_scale(self, scale) +
    +
    + Set scale + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • scale + vmath.vector3 + Scale for node +
    • +
    + + + + + +
    +
    + + text:set_pivot(self, pivot) +
    +
    + Set text pivot. Text will re-anchor inside + his text area + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • pivot + gui.pivot + Gui pivot constant +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/.druidtimer.html b/docs/modules/.druidtimer.html new file mode 100644 index 0000000..073d58d --- /dev/null +++ b/docs/modules/.druidtimer.html @@ -0,0 +1,186 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module .druidtimer

    +

    Component to handle GUI timers

    +

    + + +

    Functions

    + + + + + + + + + + + + + +
    timer:set_to(self, set_to)Set text to text field
    timer:set_state(self, is_on)Called when update
    timer:set_interval(self, from, to)Set time interval
    + +
    +
    + + +

    Functions

    + +
    +
    + + timer:set_to(self, set_to) +
    +
    + Set text to text field + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • set_to + number + Value in seconds +
    • +
    + + + + + +
    +
    + + timer:set_state(self, is_on) +
    +
    + Called when update + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • is_on + boolean + Timer enable state +
    • +
    + + + + + +
    +
    + + timer:set_interval(self, from, to) +
    +
    + Set time interval + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • from + number + Start time in seconds +
    • +
    • to + number + Target time in seconds +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-04 23:48:07 +
    +
    + + diff --git a/docs/modules/component.html b/docs/modules/component.html new file mode 100644 index 0000000..19309cb --- /dev/null +++ b/docs/modules/component.html @@ -0,0 +1,405 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module component

    +

    Basic class for all Druid components.

    +

    + To create you component, use `component.create`

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    setup_component(table, table)Setup component context and his style table
    get_style()Get current component style table
    set_style(style)Set current component style table
    get_template()Get current component template name
    set_template(template)Set current component template name
    get_nodes()Get current component nodes
    set_nodes(nodes)Set current component nodes
    get_context()Get current component context
    set_context(context)Set current component context
    get_interests()Get current component interests
    get_druid()Return druid with context of calling component.
    Component.create(name, interest)Create new component.
    + +
    +
    + + +

    Functions

    + +
    +
    + + setup_component(table, table) +
    +
    + Setup component context and his style table + + +

    Parameters:

    +
      +
    • table + style + Druid style module +
    • +
    • table + style + Druid style module +
    • +
    + +

    Returns:

    +
      + + Component + Component itself +
    + + + + +
    +
    + + get_style() +
    +
    + Get current component style table + + + +

    Returns:

    +
      + + table + Component style table +
    + + + + +
    +
    + + set_style(style) +
    +
    + Set current component style table + + +

    Parameters:

    +
      +
    • style + table + Druid style module +
    • +
    + + + + + +
    +
    + + get_template() +
    +
    + Get current component template name + + + +

    Returns:

    +
      + + string + Component template name +
    + + + + +
    +
    + + set_template(template) +
    +
    + Set current component template name + + +

    Parameters:

    +
      +
    • template + string + Component template name +
    • +
    + + + + + +
    +
    + + get_nodes() +
    +
    + Get current component nodes + + + +

    Returns:

    +
      + + table + Component nodes table +
    + + + + +
    +
    + + set_nodes(nodes) +
    +
    + Set current component nodes + + +

    Parameters:

    +
      +
    • nodes + table + Component nodes table +
    • +
    + + + + + +
    +
    + + get_context() +
    +
    + Get current component context + + + +

    Returns:

    +
      + + table + Component context +
    + + + + +
    +
    + + set_context(context) +
    +
    + Set current component context + + +

    Parameters:

    +
      +
    • context + table + Druid context. Usually it is self of script +
    • +
    + + + + + +
    +
    + + get_interests() +
    +
    + Get current component interests + + + +

    Returns:

    +
      + + table + List of component interests +
    + + + + +
    +
    + + get_druid() +
    +
    + Return druid with context of calling component. + Use it to create component inside of other components. + + + +

    Returns:

    +
      + + Druid + Druid instance with component context +
    + + + + +
    +
    + + Component.create(name, interest) +
    +
    + Create new component. It will inheritance from basic + druid component. + + +

    Parameters:

    +
      +
    • name + string + Component name +
    • +
    • interest + table + List of component's interest +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/const.html b/docs/modules/const.html new file mode 100644 index 0000000..019e1a4 --- /dev/null +++ b/docs/modules/const.html @@ -0,0 +1,112 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module const

    +

    Druid constants

    +

    + + +

    Fields

    + + + + + +
    ON_MESSAGEInterests
    + +
    +
    + + +

    Fields

    + +
    +
    + + ON_MESSAGE +
    +
    + Interests + + + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html new file mode 100644 index 0000000..7d5829e --- /dev/null +++ b/docs/modules/druid.back_handler.html @@ -0,0 +1,157 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.back_handler

    +

    Component to handle back key (android, backspace)

    +

    + + +

    Functions

    + + + + + + + + + +
    init(self, callback[, Callback])Component init function
    on_input(action_id, action)Input handler for component
    + +
    +
    + + +

    Functions

    + +
    +
    + + init(self, callback[, Callback]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • callback + callback + On back button +
    • +
    • Callback + params + argument + (optional) +
    • +
    + + + + + +
    +
    + + on_input(action_id, action) +
    +
    + Input handler for component + + +

    Parameters:

    +
      +
    • action_id + string + on_input action id +
    • +
    • action + table + on_input action +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html new file mode 100644 index 0000000..20e343f --- /dev/null +++ b/docs/modules/druid.blocker.html @@ -0,0 +1,83 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.blocker

    +

    Component to block input on specify zone (node)

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html new file mode 100644 index 0000000..8452e64 --- /dev/null +++ b/docs/modules/druid.button.html @@ -0,0 +1,197 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.button

    +

    Component to handle basic GUI button

    +

    + + +

    Functions

    + + + + + + + + + + + + + +
    init(self, node, callback[, params[, anim_node[, event]]])Component init function
    disable_animation(self)Disable all button animations
    set_click_zone(self, zone)Strict button click area.
    + +
    +
    + + +

    Functions

    + +
    +
    + + init(self, node, callback[, params[, anim_node[, event]]]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • node + node + Gui node +
    • +
    • callback + function + Button callback +
    • +
    • params + table + Button callback params + (optional) +
    • +
    • anim_node + node + Button anim node (node, if not provided) + (optional) +
    • +
    • event + string + Button react event, const.ACTION_TOUCH by default + (optional) +
    • +
    + + + + + +
    +
    + + disable_animation(self) +
    +
    + Disable all button animations + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + set_click_zone(self, zone) +
    +
    + Strict button click area. Useful for + no click events outside stencil node + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • zone + node + Gui node +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html new file mode 100644 index 0000000..2eb557a --- /dev/null +++ b/docs/modules/druid.checkbox.html @@ -0,0 +1,83 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.checkbox

    +

    Druid checkbox component

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html new file mode 100644 index 0000000..b7c40b2 --- /dev/null +++ b/docs/modules/druid.checkbox_group.html @@ -0,0 +1,83 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.checkbox_group

    +

    Checkboux group module

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html new file mode 100644 index 0000000..d749e24 --- /dev/null +++ b/docs/modules/druid.grid.html @@ -0,0 +1,84 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.grid

    +

    Component to handle placing components by row and columns.

    +

    + Grid can anchor your elements, get content size and other

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.locale.html b/docs/modules/druid.locale.html new file mode 100644 index 0000000..ee8be26 --- /dev/null +++ b/docs/modules/druid.locale.html @@ -0,0 +1,124 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.locale

    +

    Component to handle all GUI texts + Good working with localization system

    +

    + + +

    Functions

    + + + + + +
    text:translate(self, locale_id)Translate the text by locale_id
    + +
    +
    + + +

    Functions

    + +
    +
    + + text:translate(self, locale_id) +
    +
    + Translate the text by locale_id + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • locale_id + string + Locale id +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html new file mode 100644 index 0000000..7e0b1fa --- /dev/null +++ b/docs/modules/druid.progress.html @@ -0,0 +1,302 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.progress

    +

    Basic progress bar component

    +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    init(self, node, key, init_value)Component init function
    empty(self)Fill a progress bar and stop progress animation
    empty(self)Empty a progress bar
    set_to(self, to)Instant fill progress bar to value
    get(self)Return current progress bar value
    set_steps(self, steps, callback)Set points on progress bar to fire the callback
    to(self, to[, callback])Start animation of a progress bar
    + +
    +
    + + +

    Functions

    + +
    +
    + + init(self, node, key, init_value) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • node + string or node + Progress bar fill node or node name +
    • +
    • key + string + Progress bar direction (x or y) +
    • +
    • init_value + number + Initial value of progress bar +
    • +
    + + + + + +
    +
    + + empty(self) +
    +
    + Fill a progress bar and stop progress animation + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + empty(self) +
    +
    + Empty a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + set_to(self, to) +
    +
    + Instant fill progress bar to value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • to + number + Progress bar value, from 0 to 1 +
    • +
    + + + + + +
    +
    + + get(self) +
    +
    + Return current progress bar value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + set_steps(self, steps, callback) +
    +
    + Set points on progress bar to fire the callback + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • steps + table + Array of progress bar values +
    • +
    • callback + function + Callback on intersect step value +
    • +
    + + + + + +
    +
    + + to(self, to[, callback]) +
    +
    + Start animation of a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • to + number + value between 0..1 +
    • +
    • callback + function + Callback on animation ends + (optional) +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.progress_rich.html b/docs/modules/druid.progress_rich.html new file mode 100644 index 0000000..98909b2 --- /dev/null +++ b/docs/modules/druid.progress_rich.html @@ -0,0 +1,182 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.progress_rich

    +

    Component for rich progress component

    +

    + + +

    Functions

    + + + + + + + + + + + + + +
    set_to(self, value)Instant fill progress bar to value
    empty(self)Empty a progress bar
    to(self, to[, callback])Start animation of a progress bar
    + +
    +
    + + +

    Functions

    + +
    +
    + + set_to(self, value) +
    +
    + Instant fill progress bar to value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • value + number + Progress bar value, from 0 to 1 +
    • +
    + + + + + +
    +
    + + empty(self) +
    +
    + Empty a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + to(self, to[, callback]) +
    +
    + Start animation of a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • to + number + value between 0..1 +
    • +
    • callback + function + Callback on animation ends + (optional) +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html new file mode 100644 index 0000000..a76e405 --- /dev/null +++ b/docs/modules/druid.radio_group.html @@ -0,0 +1,83 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.radio_group

    +

    Radio group module

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html new file mode 100644 index 0000000..266dc5f --- /dev/null +++ b/docs/modules/druid.scroll.html @@ -0,0 +1,282 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.scroll

    +

    Component to handle scroll content

    +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    scroll_to(vector3[, is_instant])Start scroll to target point
    init(self, index[, skip_cb])Scroll to item in scroll by point index
    set_points(self, points)Set points of interest.
    set_inert(self, state)Enable or disable scroll inert.
    on_point_move(self, callback)Set the callback on scrolling to point (if exist)
    set_border(self, border)Set the scroll possibly area
    + +
    +
    + + +

    Functions

    + +
    +
    + + scroll_to(vector3[, is_instant]) +
    +
    + Start scroll to target point + + +

    Parameters:

    +
      +
    • vector3 + point + target point +
    • +
    • is_instant + bool + instant scroll flag + (optional) +
    • +
    + + + + +

    Usage:

    +
      +
    • scroll:scroll_to(vmath.vector3(0, 50, 0))
    • +
    • scroll:scroll_to(vmath.vector3(0), true)
    • +
    + +
    +
    + + init(self, index[, skip_cb]) +
    +
    + Scroll to item in scroll by point index + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • index + number + Point index +
    • +
    • skip_cb + boolean + If true, skip the point callback + (optional) +
    • +
    + + + + + +
    +
    + + set_points(self, points) +
    +
    + Set points of interest. + Scroll will always centered on closer points + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • points + table + Array of vector3 points +
    • +
    + + + + + +
    +
    + + set_inert(self, state) +
    +
    + Enable or disable scroll inert. + If disabled, scroll through points (if exist) + If no points, just simple drag without inertion + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • state + boolean + Inert scroll state +
    • +
    + + + + + +
    +
    + + on_point_move(self, callback) +
    +
    + Set the callback on scrolling to point (if exist) + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • callback + function + Callback on scroll to point of interest +
    • +
    + + + + + +
    +
    + + set_border(self, border) +
    +
    + Set the scroll possibly area + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • border + vmath.vector3 + Size of scrolling area +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html new file mode 100644 index 0000000..57fc713 --- /dev/null +++ b/docs/modules/druid.slider.html @@ -0,0 +1,83 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.slider

    +

    Druid slider component

    +

    + + + +
    +
    + + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html new file mode 100644 index 0000000..47483a0 --- /dev/null +++ b/docs/modules/druid.text.html @@ -0,0 +1,241 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.text

    +

    Component to handle all GUI texts + Good working with localization system

    +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + +
    set_to(self, set_to)Set text to text field
    set_color(self, color)Set color
    set_alpha(self, alpha)Set alpha
    set_scale(self, scale)Set scale
    set_pivot(self, pivot)Set text pivot.
    + +
    +
    + + +

    Functions

    + +
    +
    + + set_to(self, set_to) +
    +
    + Set text to text field + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • set_to + string + Text for node +
    • +
    + + + + + +
    +
    + + set_color(self, color) +
    +
    + Set color + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • color + vmath.vector4 + Color for node +
    • +
    + + + + + +
    +
    + + set_alpha(self, alpha) +
    +
    + Set alpha + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • alpha + number + Alpha for node +
    • +
    + + + + + +
    +
    + + set_scale(self, scale) +
    +
    + Set scale + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • scale + vmath.vector3 + Scale for node +
    • +
    + + + + + +
    +
    + + set_pivot(self, pivot) +
    +
    + Set text pivot. Text will re-anchor inside + his text area + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • pivot + gui.pivot + Gui pivot constant +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html new file mode 100644 index 0000000..4af92c2 --- /dev/null +++ b/docs/modules/druid.timer.html @@ -0,0 +1,185 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.timer

    +

    Component to handle GUI timers

    +

    + + +

    Functions

    + + + + + + + + + + + + + +
    set_to(self, set_to)Set text to text field
    set_state(self, is_on)Called when update
    set_interval(self, from, to)Set time interval
    + +
    +
    + + +

    Functions

    + +
    +
    + + set_to(self, set_to) +
    +
    + Set text to text field + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • set_to + number + Value in seconds +
    • +
    + + + + + +
    +
    + + set_state(self, is_on) +
    +
    + Called when update + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • is_on + boolean + Timer enable state +
    • +
    + + + + + +
    +
    + + set_interval(self, from, to) +
    +
    + Set time interval + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • from + number + Start time in seconds +
    • +
    • to + number + Target time in seconds +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html new file mode 100644 index 0000000..5165ae6 --- /dev/null +++ b/docs/modules/druid_instance.html @@ -0,0 +1,716 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid_instance

    +

    Druid main class.

    +

    Create instance of this + to start creating components

    +

    See also:

    + + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    druid:initialize(table, table)Druid class constructor
    druid:create(component_module, ...)Create new druid component
    druid:remove(component)Remove component from druid instance.
    druid:update(dt)Druid update function
    druid:on_input(action_id, action)Druid on_input function
    druid:on_message(message_id, message, sender)Druid on_message function
    druid:new_button(...)Create button basic component
    druid:new_blocker(...)Create blocker basic component
    druid:new_back_handler(...)Create back_handler basic component
    druid:new_text(...)Create text basic component
    druid:new_locale(...)Create locale basic component
    druid:new_timer(...)Create timer basic component
    druid:new_progress(...)Create progress basic component
    druid:new_grid(...)Create grid basic component
    druid:new_scroll(...)Create scroll basic component
    druid:new_slider(...)Create slider basic component
    druid:new_checkbox(...)Create checkbox basic component
    druid:new_checkbox_group(...)Create checkbox_group basic component
    druid:new_radio_group(...)Create radio_group basic component
    druid:new_progress_rich(...)Create progress_rich basic component
    + +
    +
    + + +

    Functions

    + +
    +
    + + druid:initialize(table, table) +
    +
    + Druid class constructor + + +

    Parameters:

    +
      +
    • table + style + Druid style module +
    • +
    • table + style + Druid style module +
    • +
    + + + + + +
    +
    + + druid:create(component_module, ...) +
    +
    + Create new druid component + + +

    Parameters:

    +
      +
    • component_module + Component + Component module +
    • +
    • ... + args + Other component params to pass it to component:init function +
    • +
    + + + + + +
    +
    + + druid:remove(component) +
    +
    + Remove component from druid instance. + Component `on_remove` function will be invoked, if exist. + + +

    Parameters:

    +
      +
    • component + Component + Component instance +
    • +
    + + + + + +
    +
    + + druid:update(dt) +
    +
    + Druid update function + + +

    Parameters:

    +
      +
    • dt + number + Delta time +
    • +
    + + + + + +
    +
    + + druid:on_input(action_id, action) +
    +
    + Druid on_input function + + +

    Parameters:

    +
      +
    • action_id + hash + Action_id from on_input +
    • +
    • action + table + Action from on_input +
    • +
    + + + + + +
    +
    + + druid:on_message(message_id, message, sender) +
    +
    + Druid on_message function + + +

    Parameters:

    +
      +
    • message_id + hash + Message_id from on_message +
    • +
    • message + table + Message from on_message +
    • +
    • sender + hash + Sender from on_message +
    • +
    + + + + + +
    +
    + + druid:new_button(...) +
    +
    + Create button basic component + + +

    Parameters:

    +
      +
    • ... + args + button init args +
    • +
    + +

    Returns:

    +
      + + Component + button component +
    + + + + +
    +
    + + druid:new_blocker(...) +
    +
    + Create blocker basic component + + +

    Parameters:

    +
      +
    • ... + args + blocker init args +
    • +
    + +

    Returns:

    +
      + + Component + blocker component +
    + + + + +
    +
    + + druid:new_back_handler(...) +
    +
    + Create back_handler basic component + + +

    Parameters:

    +
      +
    • ... + args + back_handler init args +
    • +
    + +

    Returns:

    +
      + + Component + back_handler component +
    + + + + +
    +
    + + druid:new_text(...) +
    +
    + Create text basic component + + +

    Parameters:

    +
      +
    • ... + args + text init args +
    • +
    + +

    Returns:

    +
      + + Component + text component +
    + + + + +
    +
    + + druid:new_locale(...) +
    +
    + Create locale basic component + + +

    Parameters:

    +
      +
    • ... + args + locale init args +
    • +
    + +

    Returns:

    +
      + + Component + locale component +
    + + + + +
    +
    + + druid:new_timer(...) +
    +
    + Create timer basic component + + +

    Parameters:

    +
      +
    • ... + args + timer init args +
    • +
    + +

    Returns:

    +
      + + Component + timer component +
    + + + + +
    +
    + + druid:new_progress(...) +
    +
    + Create progress basic component + + +

    Parameters:

    +
      +
    • ... + args + progress init args +
    • +
    + +

    Returns:

    +
      + + Component + progress component +
    + + + + +
    +
    + + druid:new_grid(...) +
    +
    + Create grid basic component + + +

    Parameters:

    +
      +
    • ... + args + grid init args +
    • +
    + +

    Returns:

    +
      + + Component + grid component +
    + + + + +
    +
    + + druid:new_scroll(...) +
    +
    + Create scroll basic component + + +

    Parameters:

    +
      +
    • ... + args + scroll init args +
    • +
    + +

    Returns:

    +
      + + Component + scroll component +
    + + + + +
    +
    + + druid:new_slider(...) +
    +
    + Create slider basic component + + +

    Parameters:

    +
      +
    • ... + args + slider init args +
    • +
    + +

    Returns:

    +
      + + Component + slider component +
    + + + + +
    +
    + + druid:new_checkbox(...) +
    +
    + Create checkbox basic component + + +

    Parameters:

    +
      +
    • ... + args + checkbox init args +
    • +
    + +

    Returns:

    +
      + + Component + checkbox component +
    + + + + +
    +
    + + druid:new_checkbox_group(...) +
    +
    + Create checkbox_group basic component + + +

    Parameters:

    +
      +
    • ... + args + checkbox_group init args +
    • +
    + +

    Returns:

    +
      + + Component + checkbox_group component +
    + + + + +
    +
    + + druid:new_radio_group(...) +
    +
    + Create radio_group basic component + + +

    Parameters:

    +
      +
    • ... + args + radio_group init args +
    • +
    + +

    Returns:

    +
      + + Component + radio_group component +
    + + + + +
    +
    + + druid:new_progress_rich(...) +
    +
    + Create progress_rich basic component + + +

    Parameters:

    +
      +
    • ... + args + progress_rich init args +
    • +
    + +

    Returns:

    +
      + + Component + progress_rich component +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-02-05 02:41:04 +
    +
    + + From ec2acceebe5a7647533ce299219174a2ec5e344e Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 5 Feb 2020 02:43:02 +0300 Subject: [PATCH 095/136] Update docs --- docs/index.html | 2 +- docs/modules/.druidback_handler.html | 158 ----------- docs/modules/.druidblocker.html | 84 ------ docs/modules/.druidbutton.html | 198 -------------- docs/modules/.druidcheckbox.html | 84 ------ docs/modules/.druidcheckbox_group.html | 84 ------ docs/modules/.druidgrid.html | 85 ------ docs/modules/.druidprogress.html | 303 ---------------------- docs/modules/.druidscroll.html | 283 -------------------- docs/modules/.druidslider.html | 84 ------ docs/modules/.druidtext.html | 242 ----------------- docs/modules/.druidtimer.html | 186 ------------- docs/modules/back_handler.html | 155 ----------- docs/modules/base.back_handler.html | 158 ----------- docs/modules/base.blocker.html | 84 ------ docs/modules/base.button.html | 198 -------------- docs/modules/base.checkbox.html | 84 ------ docs/modules/base.checkbox_group.html | 84 ------ docs/modules/base.grid.html | 85 ------ docs/modules/base.html | 155 ----------- docs/modules/base.progress.html | 303 ---------------------- docs/modules/base.scroll.html | 283 -------------------- docs/modules/base.slider.html | 84 ------ docs/modules/base.text.html | 242 ----------------- docs/modules/base.timer.html | 186 ------------- docs/modules/component.html | 2 +- docs/modules/components.back_handler.html | 155 ----------- docs/modules/const.html | 2 +- docs/modules/constants.html | 111 -------- docs/modules/druid.back_handler.html | 2 +- docs/modules/druid.blocker.html | 2 +- docs/modules/druid.button.html | 2 +- docs/modules/druid.checkbox.html | 2 +- docs/modules/druid.checkbox_group.html | 2 +- docs/modules/druid.grid.html | 2 +- docs/modules/druid.html | 2 +- docs/modules/druid.locale.html | 2 +- docs/modules/druid.progress.html | 2 +- docs/modules/druid.progress_rich.html | 2 +- docs/modules/druid.radio_group.html | 2 +- docs/modules/druid.scroll.html | 2 +- docs/modules/druid.slider.html | 2 +- docs/modules/druid.text.html | 2 +- docs/modules/druid.timer.html | 2 +- docs/modules/druid_instance.html | 8 +- docs/modules/helper.animate.html | 84 ------ docs/modules/helper.formats.html | 2 +- docs/modules/helper.html | 2 +- docs/modules/rich.progress_rich.html | 183 ------------- docs/modules/settings.html | 84 ------ 50 files changed, 24 insertions(+), 4533 deletions(-) delete mode 100644 docs/modules/.druidback_handler.html delete mode 100644 docs/modules/.druidblocker.html delete mode 100644 docs/modules/.druidbutton.html delete mode 100644 docs/modules/.druidcheckbox.html delete mode 100644 docs/modules/.druidcheckbox_group.html delete mode 100644 docs/modules/.druidgrid.html delete mode 100644 docs/modules/.druidprogress.html delete mode 100644 docs/modules/.druidscroll.html delete mode 100644 docs/modules/.druidslider.html delete mode 100644 docs/modules/.druidtext.html delete mode 100644 docs/modules/.druidtimer.html delete mode 100644 docs/modules/back_handler.html delete mode 100644 docs/modules/base.back_handler.html delete mode 100644 docs/modules/base.blocker.html delete mode 100644 docs/modules/base.button.html delete mode 100644 docs/modules/base.checkbox.html delete mode 100644 docs/modules/base.checkbox_group.html delete mode 100644 docs/modules/base.grid.html delete mode 100644 docs/modules/base.html delete mode 100644 docs/modules/base.progress.html delete mode 100644 docs/modules/base.scroll.html delete mode 100644 docs/modules/base.slider.html delete mode 100644 docs/modules/base.text.html delete mode 100644 docs/modules/base.timer.html delete mode 100644 docs/modules/components.back_handler.html delete mode 100644 docs/modules/constants.html delete mode 100644 docs/modules/helper.animate.html delete mode 100644 docs/modules/rich.progress_rich.html delete mode 100644 docs/modules/settings.html diff --git a/docs/index.html b/docs/index.html index e8b905e..f04bfad 100644 --- a/docs/index.html +++ b/docs/index.html @@ -150,7 +150,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/.druidback_handler.html b/docs/modules/.druidback_handler.html deleted file mode 100644 index db4227b..0000000 --- a/docs/modules/.druidback_handler.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidback_handler

    -

    Component to handle back key (android, backspace)

    -

    - - -

    Functions

    - - - - - - - - - -
    back_handler:init(self, callback[, Callback])Component init function
    back_handler:on_input(action_id, action)Input handler for component
    - -
    -
    - - -

    Functions

    - -
    -
    - - back_handler:init(self, callback[, Callback]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - callback - On back button -
    • -
    • Callback - params - argument - (optional) -
    • -
    - - - - - -
    -
    - - back_handler:on_input(action_id, action) -
    -
    - Input handler for component - - -

    Parameters:

    -
      -
    • action_id - string - on_input action id -
    • -
    • action - table - on_input action -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidblocker.html b/docs/modules/.druidblocker.html deleted file mode 100644 index 24bcd5f..0000000 --- a/docs/modules/.druidblocker.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidblocker

    -

    Component to block input on specify zone (node)

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidbutton.html b/docs/modules/.druidbutton.html deleted file mode 100644 index 810d334..0000000 --- a/docs/modules/.druidbutton.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidbutton

    -

    Component to handle basic GUI button

    -

    - - -

    Functions

    - - - - - - - - - - - - - -
    button:init(self, node, callback[, params[, anim_node[, event]]])Component init function
    button:disable_animation(self)Disable all button animations
    button:set_click_zone(self, zone)Strict button click area.
    - -
    -
    - - -

    Functions

    - -
    -
    - - button:init(self, node, callback[, params[, anim_node[, event]]]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • node - node - Gui node -
    • -
    • callback - function - Button callback -
    • -
    • params - table - Button callback params - (optional) -
    • -
    • anim_node - node - Button anim node (node, if not provided) - (optional) -
    • -
    • event - string - Button react event, const.ACTION_TOUCH by default - (optional) -
    • -
    - - - - - -
    -
    - - button:disable_animation(self) -
    -
    - Disable all button animations - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - button:set_click_zone(self, zone) -
    -
    - Strict button click area. Useful for - no click events outside stencil node - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • zone - node - Gui node -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidcheckbox.html b/docs/modules/.druidcheckbox.html deleted file mode 100644 index fad3da3..0000000 --- a/docs/modules/.druidcheckbox.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidcheckbox

    -

    Druid checkbox component

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidcheckbox_group.html b/docs/modules/.druidcheckbox_group.html deleted file mode 100644 index 71aa616..0000000 --- a/docs/modules/.druidcheckbox_group.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidcheckbox_group

    -

    Radio group module

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidgrid.html b/docs/modules/.druidgrid.html deleted file mode 100644 index 10824a8..0000000 --- a/docs/modules/.druidgrid.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidgrid

    -

    Component to handle placing components by row and columns.

    -

    - Grid can anchor your elements, get content size and other

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidprogress.html b/docs/modules/.druidprogress.html deleted file mode 100644 index e4f351d..0000000 --- a/docs/modules/.druidprogress.html +++ /dev/null @@ -1,303 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidprogress

    -

    Basic progress bar component

    -

    - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    progress:init(self, node, key, init_value)Component init function
    progress:empty(self)Fill a progress bar and stop progress animation
    progress:empty(self)Empty a progress bar
    progress:set_to(self, to)Instant fill progress bar to value
    progress:get(self)Return current progress bar value
    progress:set_steps(self, steps, callback)Set points on progress bar to fire the callback
    progress:to(self, to[, callback])Start animation of a progress bar
    - -
    -
    - - -

    Functions

    - -
    -
    - - progress:init(self, node, key, init_value) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • node - string or node - Progress bar fill node or node name -
    • -
    • key - string - Progress bar direction (x or y) -
    • -
    • init_value - number - Initial value of progress bar -
    • -
    - - - - - -
    -
    - - progress:empty(self) -
    -
    - Fill a progress bar and stop progress animation - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - progress:empty(self) -
    -
    - Empty a progress bar - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - progress:set_to(self, to) -
    -
    - Instant fill progress bar to value - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • to - number - Progress bar value, from 0 to 1 -
    • -
    - - - - - -
    -
    - - progress:get(self) -
    -
    - Return current progress bar value - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - progress:set_steps(self, steps, callback) -
    -
    - Set points on progress bar to fire the callback - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • steps - table - Array of progress bar values -
    • -
    • callback - function - Callback on intersect step value -
    • -
    - - - - - -
    -
    - - progress:to(self, to[, callback]) -
    -
    - Start animation of a progress bar - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • to - number - value between 0..1 -
    • -
    • callback - function - Callback on animation ends - (optional) -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidscroll.html b/docs/modules/.druidscroll.html deleted file mode 100644 index 42b29ff..0000000 --- a/docs/modules/.druidscroll.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidscroll

    -

    Component to handle scroll content

    -

    - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    scroll:scroll_to(vector3[, is_instant])Start scroll to target point
    scroll:init(self, index[, skip_cb])Scroll to item in scroll by point index
    scroll:set_points(self, points)Set points of interest.
    scroll:set_inert(self, state)Enable or disable scroll inert.
    scroll:on_point_move(self, callback)Set the callback on scrolling to point (if exist)
    scroll:set_border(self, border)Set the scroll possibly area
    - -
    -
    - - -

    Functions

    - -
    -
    - - scroll:scroll_to(vector3[, is_instant]) -
    -
    - Start scroll to target point - - -

    Parameters:

    -
      -
    • vector3 - point - target point -
    • -
    • is_instant - bool - instant scroll flag - (optional) -
    • -
    - - - - -

    Usage:

    -
      -
    • scroll:scroll_to(vmath.vector3(0, 50, 0))
    • -
    • scroll:scroll_to(vmath.vector3(0), true)
    • -
    - -
    -
    - - scroll:init(self, index[, skip_cb]) -
    -
    - Scroll to item in scroll by point index - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • index - number - Point index -
    • -
    • skip_cb - boolean - If true, skip the point callback - (optional) -
    • -
    - - - - - -
    -
    - - scroll:set_points(self, points) -
    -
    - Set points of interest. - Scroll will always centered on closer points - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • points - table - Array of vector3 points -
    • -
    - - - - - -
    -
    - - scroll:set_inert(self, state) -
    -
    - Enable or disable scroll inert. - If disabled, scroll through points (if exist) - If no points, just simple drag without inertion - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • state - boolean - Inert scroll state -
    • -
    - - - - - -
    -
    - - scroll:on_point_move(self, callback) -
    -
    - Set the callback on scrolling to point (if exist) - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - function - Callback on scroll to point of interest -
    • -
    - - - - - -
    -
    - - scroll:set_border(self, border) -
    -
    - Set the scroll possibly area - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • border - vmath.vector3 - Size of scrolling area -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidslider.html b/docs/modules/.druidslider.html deleted file mode 100644 index 58b522b..0000000 --- a/docs/modules/.druidslider.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidslider

    -

    Druid slider component

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidtext.html b/docs/modules/.druidtext.html deleted file mode 100644 index 8700c2e..0000000 --- a/docs/modules/.druidtext.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidtext

    -

    Component to handle all GUI texts - Good working with localization system

    -

    - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - -
    text:set_to(self, set_to)Set text to text field
    text:set_color(self, color)Set color
    text:set_alpha(self, alpha)Set alpha
    text:set_scale(self, scale)Set scale
    text:set_pivot(self, pivot)Set text pivot.
    - -
    -
    - - -

    Functions

    - -
    -
    - - text:set_to(self, set_to) -
    -
    - Set text to text field - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • set_to - string - Text for node -
    • -
    - - - - - -
    -
    - - text:set_color(self, color) -
    -
    - Set color - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • color - vmath.vector4 - Color for node -
    • -
    - - - - - -
    -
    - - text:set_alpha(self, alpha) -
    -
    - Set alpha - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • alpha - number - Alpha for node -
    • -
    - - - - - -
    -
    - - text:set_scale(self, scale) -
    -
    - Set scale - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • scale - vmath.vector3 - Scale for node -
    • -
    - - - - - -
    -
    - - text:set_pivot(self, pivot) -
    -
    - Set text pivot. Text will re-anchor inside - his text area - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • pivot - gui.pivot - Gui pivot constant -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/.druidtimer.html b/docs/modules/.druidtimer.html deleted file mode 100644 index 073d58d..0000000 --- a/docs/modules/.druidtimer.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module .druidtimer

    -

    Component to handle GUI timers

    -

    - - -

    Functions

    - - - - - - - - - - - - - -
    timer:set_to(self, set_to)Set text to text field
    timer:set_state(self, is_on)Called when update
    timer:set_interval(self, from, to)Set time interval
    - -
    -
    - - -

    Functions

    - -
    -
    - - timer:set_to(self, set_to) -
    -
    - Set text to text field - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • set_to - number - Value in seconds -
    • -
    - - - - - -
    -
    - - timer:set_state(self, is_on) -
    -
    - Called when update - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • is_on - boolean - Timer enable state -
    • -
    - - - - - -
    -
    - - timer:set_interval(self, from, to) -
    -
    - Set time interval - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • from - number - Start time in seconds -
    • -
    • to - number - Target time in seconds -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:48:07 -
    -
    - - diff --git a/docs/modules/back_handler.html b/docs/modules/back_handler.html deleted file mode 100644 index 0a7f657..0000000 --- a/docs/modules/back_handler.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module back_handler

    -

    Component to handle back key

    -

    - - -

    Functions

    - - - - - - - - - -
    init(self, callback[, Callback])Component init function
    on_input(action_id, action)Input handler for component
    - -
    -
    - - -

    Functions

    - -
    -
    - - init(self, callback[, Callback]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - callback - On back button -
    • -
    • Callback - params - argument - (optional) -
    • -
    - - - - - -
    -
    - - on_input(action_id, action) -
    -
    - Input handler for component - - -

    Parameters:

    -
      -
    • action_id - string - on_input action id -
    • -
    • action - table - on_input action -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2019-12-05 21:37:51 -
    -
    - - diff --git a/docs/modules/base.back_handler.html b/docs/modules/base.back_handler.html deleted file mode 100644 index 50d1f20..0000000 --- a/docs/modules/base.back_handler.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.back_handler

    -

    Component to handle back key (android, backspace)

    -

    - - -

    Functions

    - - - - - - - - - -
    init(self, callback[, Callback])Component init function
    on_input(action_id, action)Input handler for component
    - -
    -
    - - -

    Functions

    - -
    -
    - - init(self, callback[, Callback]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - callback - On back button -
    • -
    • Callback - params - argument - (optional) -
    • -
    - - - - - -
    -
    - - on_input(action_id, action) -
    -
    - Input handler for component - - -

    Parameters:

    -
      -
    • action_id - string - on_input action id -
    • -
    • action - table - on_input action -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.blocker.html b/docs/modules/base.blocker.html deleted file mode 100644 index e43d201..0000000 --- a/docs/modules/base.blocker.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.blocker

    -

    Component to block input on specify zone (node)

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.button.html b/docs/modules/base.button.html deleted file mode 100644 index 57ef749..0000000 --- a/docs/modules/base.button.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.button

    -

    Component to handle basic GUI button

    -

    - - -

    Functions

    - - - - - - - - - - - - - -
    init(self, node, callback[, params[, anim_node[, event]]])Component init function
    disable_animation(self)Disable all button animations
    set_click_zone(self, zone)Strict button click area.
    - -
    -
    - - -

    Functions

    - -
    -
    - - init(self, node, callback[, params[, anim_node[, event]]]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • node - node - Gui node -
    • -
    • callback - function - Button callback -
    • -
    • params - table - Button callback params - (optional) -
    • -
    • anim_node - node - Button anim node (node, if not provided) - (optional) -
    • -
    • event - string - Button react event, const.ACTION_TOUCH by default - (optional) -
    • -
    - - - - - -
    -
    - - disable_animation(self) -
    -
    - Disable all button animations - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - set_click_zone(self, zone) -
    -
    - Strict button click area. Useful for - no click events outside stencil node - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • zone - node - Gui node -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.checkbox.html b/docs/modules/base.checkbox.html deleted file mode 100644 index 92d23d3..0000000 --- a/docs/modules/base.checkbox.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.checkbox

    -

    Druid checkbox component

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.checkbox_group.html b/docs/modules/base.checkbox_group.html deleted file mode 100644 index 34069ff..0000000 --- a/docs/modules/base.checkbox_group.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.checkbox_group

    -

    Radio group module

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.grid.html b/docs/modules/base.grid.html deleted file mode 100644 index af5cf25..0000000 --- a/docs/modules/base.grid.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.grid

    -

    Component to handle placing components by row and columns.

    -

    - Grid can anchor your elements, get content size and other

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.html b/docs/modules/base.html deleted file mode 100644 index 6e44f09..0000000 --- a/docs/modules/base.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base

    -

    Component to handle back key

    -

    - - -

    Functions

    - - - - - - - - - -
    back_handler:init(self, callback[, Callback])Component init function
    back_handler:on_input(action_id, action)Input handler for component
    - -
    -
    - - -

    Functions

    - -
    -
    - - back_handler:init(self, callback[, Callback]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - callback - On back button -
    • -
    • Callback - params - argument - (optional) -
    • -
    - - - - - -
    -
    - - back_handler:on_input(action_id, action) -
    -
    - Input handler for component - - -

    Parameters:

    -
      -
    • action_id - string - on_input action id -
    • -
    • action - table - on_input action -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2019-12-05 21:36:59 -
    -
    - - diff --git a/docs/modules/base.progress.html b/docs/modules/base.progress.html deleted file mode 100644 index 5622257..0000000 --- a/docs/modules/base.progress.html +++ /dev/null @@ -1,303 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.progress

    -

    Basic progress bar component

    -

    - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    init(self, node, key, init_value)Component init function
    empty(self)Fill a progress bar and stop progress animation
    empty(self)Empty a progress bar
    set_to(self, to)Instant fill progress bar to value
    get(self)Return current progress bar value
    set_steps(self, steps, callback)Set points on progress bar to fire the callback
    to(self, to[, callback])Start animation of a progress bar
    - -
    -
    - - -

    Functions

    - -
    -
    - - init(self, node, key, init_value) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • node - string or node - Progress bar fill node or node name -
    • -
    • key - string - Progress bar direction (x or y) -
    • -
    • init_value - number - Initial value of progress bar -
    • -
    - - - - - -
    -
    - - empty(self) -
    -
    - Fill a progress bar and stop progress animation - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - empty(self) -
    -
    - Empty a progress bar - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - set_to(self, to) -
    -
    - Instant fill progress bar to value - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • to - number - Progress bar value, from 0 to 1 -
    • -
    - - - - - -
    -
    - - get(self) -
    -
    - Return current progress bar value - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - set_steps(self, steps, callback) -
    -
    - Set points on progress bar to fire the callback - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • steps - table - Array of progress bar values -
    • -
    • callback - function - Callback on intersect step value -
    • -
    - - - - - -
    -
    - - to(self, to[, callback]) -
    -
    - Start animation of a progress bar - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • to - number - value between 0..1 -
    • -
    • callback - function - Callback on animation ends - (optional) -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.scroll.html b/docs/modules/base.scroll.html deleted file mode 100644 index 087322d..0000000 --- a/docs/modules/base.scroll.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.scroll

    -

    Component to handle scroll content

    -

    - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    scroll_to(vector3[, is_instant])Start scroll to target point
    init(self, index[, skip_cb])Scroll to item in scroll by point index
    set_points(self, points)Set points of interest.
    set_inert(self, state)Enable or disable scroll inert.
    on_point_move(self, callback)Set the callback on scrolling to point (if exist)
    set_border(self, border)Set the scroll possibly area
    - -
    -
    - - -

    Functions

    - -
    -
    - - scroll_to(vector3[, is_instant]) -
    -
    - Start scroll to target point - - -

    Parameters:

    -
      -
    • vector3 - point - target point -
    • -
    • is_instant - bool - instant scroll flag - (optional) -
    • -
    - - - - -

    Usage:

    -
      -
    • scroll:scroll_to(vmath.vector3(0, 50, 0))
    • -
    • scroll:scroll_to(vmath.vector3(0), true)
    • -
    - -
    -
    - - init(self, index[, skip_cb]) -
    -
    - Scroll to item in scroll by point index - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • index - number - Point index -
    • -
    • skip_cb - boolean - If true, skip the point callback - (optional) -
    • -
    - - - - - -
    -
    - - set_points(self, points) -
    -
    - Set points of interest. - Scroll will always centered on closer points - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • points - table - Array of vector3 points -
    • -
    - - - - - -
    -
    - - set_inert(self, state) -
    -
    - Enable or disable scroll inert. - If disabled, scroll through points (if exist) - If no points, just simple drag without inertion - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • state - boolean - Inert scroll state -
    • -
    - - - - - -
    -
    - - on_point_move(self, callback) -
    -
    - Set the callback on scrolling to point (if exist) - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - function - Callback on scroll to point of interest -
    • -
    - - - - - -
    -
    - - set_border(self, border) -
    -
    - Set the scroll possibly area - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • border - vmath.vector3 - Size of scrolling area -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.slider.html b/docs/modules/base.slider.html deleted file mode 100644 index 37e794d..0000000 --- a/docs/modules/base.slider.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.slider

    -

    Druid slider component

    -

    - - - -
    -
    - - - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.text.html b/docs/modules/base.text.html deleted file mode 100644 index 7b29689..0000000 --- a/docs/modules/base.text.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.text

    -

    Component to handle all GUI texts - Good working with localization system

    -

    - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - -
    set_to(self, set_to)Set text to text field
    set_color(self, color)Set color
    set_alpha(self, alpha)Set alpha
    set_scale(self, scale)Set scale
    set_pivot(self, pivot)Set text pivot.
    - -
    -
    - - -

    Functions

    - -
    -
    - - set_to(self, set_to) -
    -
    - Set text to text field - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • set_to - string - Text for node -
    • -
    - - - - - -
    -
    - - set_color(self, color) -
    -
    - Set color - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • color - vmath.vector4 - Color for node -
    • -
    - - - - - -
    -
    - - set_alpha(self, alpha) -
    -
    - Set alpha - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • alpha - number - Alpha for node -
    • -
    - - - - - -
    -
    - - set_scale(self, scale) -
    -
    - Set scale - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • scale - vmath.vector3 - Scale for node -
    • -
    - - - - - -
    -
    - - set_pivot(self, pivot) -
    -
    - Set text pivot. Text will re-anchor inside - his text area - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • pivot - gui.pivot - Gui pivot constant -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/base.timer.html b/docs/modules/base.timer.html deleted file mode 100644 index 7c5d6fb..0000000 --- a/docs/modules/base.timer.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module base.timer

    -

    Component to handle GUI timers

    -

    - - -

    Functions

    - - - - - - - - - - - - - -
    set_to(self, set_to)Set text to text field
    set_state(self, is_on)Called when update
    set_interval(self, from, to)Set time interval
    - -
    -
    - - -

    Functions

    - -
    -
    - - set_to(self, set_to) -
    -
    - Set text to text field - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • set_to - number - Value in seconds -
    • -
    - - - - - -
    -
    - - set_state(self, is_on) -
    -
    - Called when update - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • is_on - boolean - Timer enable state -
    • -
    - - - - - -
    -
    - - set_interval(self, from, to) -
    -
    - Set time interval - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • from - number - Start time in seconds -
    • -
    • to - number - Target time in seconds -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-04 23:46:10 -
    -
    - - diff --git a/docs/modules/component.html b/docs/modules/component.html index 19309cb..efdbf93 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -398,7 +398,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/components.back_handler.html b/docs/modules/components.back_handler.html deleted file mode 100644 index 6e25bbe..0000000 --- a/docs/modules/components.back_handler.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module components.back_handler

    -

    Component to handle back key

    -

    - - -

    Functions

    - - - - - - - - - -
    init(self, callback[, Callback])Component init function
    on_input(action_id, action)Input handler for component
    - -
    -
    - - -

    Functions

    - -
    -
    - - init(self, callback[, Callback]) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - callback - On back button -
    • -
    • Callback - params - argument - (optional) -
    • -
    - - - - - -
    -
    - - on_input(action_id, action) -
    -
    - Input handler for component - - -

    Parameters:

    -
      -
    • action_id - string - on_input action id -
    • -
    • action - table - on_input action -
    • -
    - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2019-12-05 21:38:00 -
    -
    - - diff --git a/docs/modules/const.html b/docs/modules/const.html index 019e1a4..a660ac7 100644 --- a/docs/modules/const.html +++ b/docs/modules/const.html @@ -105,7 +105,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/constants.html b/docs/modules/constants.html deleted file mode 100644 index 5cd9b0b..0000000 --- a/docs/modules/constants.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module constants

    -

    Druid constants

    -

    - - -

    Fields

    - - - - - -
    ON_MESSAGEInterests
    - -
    -
    - - -

    Fields

    - -
    -
    - - ON_MESSAGE -
    -
    - Interests - - - - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2019-12-05 22:04:11 -
    -
    - - diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 7d5829e..056ed7a 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -150,7 +150,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 20e343f..2bfeb01 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 8452e64..5550167 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -190,7 +190,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index 2eb557a..69bf10e 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index b7c40b2..fd22518 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index d749e24..2dc932e 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 41b769f..e2407f7 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -161,7 +161,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.locale.html b/docs/modules/druid.locale.html index ee8be26..a815917 100644 --- a/docs/modules/druid.locale.html +++ b/docs/modules/druid.locale.html @@ -117,7 +117,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index 7e0b1fa..a51299f 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -295,7 +295,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.progress_rich.html b/docs/modules/druid.progress_rich.html index 98909b2..f543b12 100644 --- a/docs/modules/druid.progress_rich.html +++ b/docs/modules/druid.progress_rich.html @@ -175,7 +175,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index a76e405..37f9b24 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index 266dc5f..dc62222 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -275,7 +275,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index 57fc713..bb12425 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index 47483a0..d118b49 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -234,7 +234,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index 4af92c2..23a625d 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -178,7 +178,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index 5165ae6..f0be67e 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -93,7 +93,7 @@ Druid class constructor - druid:create(component_module, ...) + druid:create(component, ...) Create new druid component @@ -204,7 +204,7 @@
    - druid:create(component_module, ...) + druid:create(component, ...)
    Create new druid component @@ -212,7 +212,7 @@

    Parameters:

      -
    • component_module +
    • component Component Component module
    • @@ -709,7 +709,7 @@
      generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
      diff --git a/docs/modules/helper.animate.html b/docs/modules/helper.animate.html deleted file mode 100644 index b07fb30..0000000 --- a/docs/modules/helper.animate.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
      - -
      - -
      -
      -
      - - -
      - - - - - - -
      - -

      Module helper.animate

      -

      Druid helper module for animating GUI nodes

      -

      - - - -
      -
      - - - - -
      -
      -
      -generated by LDoc 1.4.6 -Last updated 2020-02-05 00:14:12 -
      -
      - - diff --git a/docs/modules/helper.formats.html b/docs/modules/helper.formats.html index e89c3e9..3f58d1e 100644 --- a/docs/modules/helper.formats.html +++ b/docs/modules/helper.formats.html @@ -185,7 +185,7 @@
      generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
      diff --git a/docs/modules/helper.html b/docs/modules/helper.html index 6e1efff..d796afa 100644 --- a/docs/modules/helper.html +++ b/docs/modules/helper.html @@ -147,7 +147,7 @@
      generated by LDoc 1.4.6 -Last updated 2020-02-05 02:41:04 +Last updated 2020-02-05 02:43:10
      diff --git a/docs/modules/rich.progress_rich.html b/docs/modules/rich.progress_rich.html deleted file mode 100644 index e69b51e..0000000 --- a/docs/modules/rich.progress_rich.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
      - -
      - -
      -
      -
      - - -
      - - - - - - -
      - -

      Module rich.progress_rich

      -

      Component for rich progress component

      -

      - - -

      Functions

      - - - - - - - - - - - - - -
      set_to(self, value)Instant fill progress bar to value
      empty(self)Empty a progress bar
      to(self, to[, callback])Start animation of a progress bar
      - -
      -
      - - -

      Functions

      - -
      -
      - - set_to(self, value) -
      -
      - Instant fill progress bar to value - - -

      Parameters:

      -
        -
      • self - table - Component instance -
      • -
      • value - number - Progress bar value, from 0 to 1 -
      • -
      - - - - - -
      -
      - - empty(self) -
      -
      - Empty a progress bar - - -

      Parameters:

      -
        -
      • self - table - Component instance -
      • -
      - - - - - -
      -
      - - to(self, to[, callback]) -
      -
      - Start animation of a progress bar - - -

      Parameters:

      -
        -
      • self - table - Component instance -
      • -
      • to - number - value between 0..1 -
      • -
      • callback - function - Callback on animation ends - (optional) -
      • -
      - - - - - -
      -
      - - -
      -
      -
      -generated by LDoc 1.4.6 -Last updated 2020-02-05 00:02:17 -
      -
      - - diff --git a/docs/modules/settings.html b/docs/modules/settings.html deleted file mode 100644 index 4dbda1f..0000000 --- a/docs/modules/settings.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
      - -
      - -
      -
      -
      - - -
      - - - - - - -
      - -

      Module settings

      -

      Druid settings file

      -

      - - - -
      -
      - - - - -
      -
      -
      -generated by LDoc 1.4.6 -Last updated 2020-02-05 00:02:17 -
      -
      - - From 92098052e3242c2d0113ff56667fe342ddf7f2de Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 5 Feb 2020 02:43:37 +0300 Subject: [PATCH 096/136] All basic components declared with explicit way --- druid/druid.lua | 82 +++++-------- druid/system/druid_instance.lua | 206 +++++++++++++++++++++++++++++--- druid/system/settings.lua | 1 + 3 files changed, 223 insertions(+), 66 deletions(-) diff --git a/druid/druid.lua b/druid/druid.lua index 31ac629..0003720 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,7 +1,12 @@ --- Druid UI Library. --- Component based UI library to make your life easier. --- Contains a lot of base components and give API --- to create your own rich components. +-- Powerful Defold component based UI library. Use standart +-- components or make your own game-specific to make amazing +-- GUI in your games. +-- +-- Contains the several basic components and examples +-- to how to do your custom complex components to +-- separate UI game logic to small files +-- -- @module druid local const = require("druid.const") @@ -13,47 +18,12 @@ local M = {} local log = settings.log ---- Basic components -M.components = { - button = require("druid.base.button"), - blocker = require("druid.base.blocker"), - back_handler = require("druid.base.back_handler"), - text = require("druid.base.text"), - locale = require("druid.base.locale"), - timer = require("druid.base.timer"), - progress = require("druid.base.progress"), - grid = require("druid.base.grid"), - scroll = require("druid.base.scroll"), - slider = require("druid.base.slider"), - checkbox = require("druid.base.checkbox"), - checkbox_group = require("druid.base.checkbox_group"), - radio_group = require("druid.base.radio_group"), - - -- TODO: - -- input - text input - -- infinity_scroll -- to handle big data scroll - - progress_rich = require("druid.rich.progress_rich"), - - -- TODO: Examples: - -- Slider menu like clash royale -} - - -local function register_basic_components() - for k, v in pairs(M.components) do - if not druid_instance["new_" .. k] then - M.register(k, v) - else - log("Basic component", k, "already registered") - end - end -end - - ---- Register external module +--- Register external druid component. +-- After register you can create the component with +-- druid_instance:new_{name}. For example `druid:new_button(...)` +-- @function druid:register -- @tparam string name module name --- @tparam table module lua table with module +-- @tparam table module lua table with component function M.register(name, module) -- TODO: Find better solution to creating elements? -- Possibly: druid.new(druid.BUTTON, etc?) @@ -66,23 +36,30 @@ function M.register(name, module) end ---- Create Druid instance for creating components --- @return instance with all ui components +--- Create Druid instance. +-- @function druid.new +-- @tparam table context Druid context. Usually it is self of script +-- @tparam[opt] table style Druid style module +-- @treturn druid_instance Druid instance function M.new(context, style) - if register_basic_components then - register_basic_components() - register_basic_components = false - end - return druid_instance(context, style) end +-- Set new default style. +-- @function druid.set_default_style +-- @tparam table style Druid style module function M.set_default_style(style) settings.default_style = style end +-- Set text function. +-- Druid locale component will call this function +-- to get translated text. After set_text_funtion +-- all existing locale component will be updated +-- @function druid.set_text_function(callback) +-- @tparam function callback Get localized text function function M.set_text_function(callback) settings.get_text = callback or const.EMPTY_FUNCTION -- TODO: Update all localized text @@ -90,6 +67,11 @@ function M.set_text_function(callback) end +-- Set sound function. +-- Component will call this function to +-- play sound by sound_id +-- @function druid.set_sound_function +-- @tparam function callback Sound play callback function M.set_sound_function(callback) settings.play_sound = callback or const.EMPTY_FUNCTION end diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index e174852..b76b652 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -1,8 +1,43 @@ +--- Druid main class. Create instance of this +-- to start creating components +-- @module druid_instance +-- @see druid.button +-- @see druid.blocker +-- @see druid.back_handler +-- @see druid.text +-- @see druid.locale +-- @see druid.timer +-- @see druid.progress +-- @see druid.grid +-- @see druid.scroll +-- @see druid.slider +-- @see druid.checkbox +-- @see druid.checkbox_group +-- @see druid.radio_group + local const = require("druid.const") local druid_input = require("druid.helper.druid_input") local settings = require("druid.system.settings") local class = require("druid.system.middleclass") +local button = require("druid.base.button") +local blocker = require("druid.base.blocker") +local back_handler = require("druid.base.back_handler") +local text = require("druid.base.text") +local locale = require("druid.base.locale") +local timer = require("druid.base.timer") +local progress = require("druid.base.progress") +local grid = require("druid.base.grid") +local scroll = require("druid.base.scroll") +local slider = require("druid.base.slider") +local checkbox = require("druid.base.checkbox") +local checkbox_group = require("druid.base.checkbox_group") +local radio_group = require("druid.base.radio_group") +-- local input - require("druid.base.input") +-- local infinity_scroll = require("druid.base.infinity_scroll") +local progress_rich = require("druid.rich.progress_rich") + +-- @classmod Druid local Druid = class("druid.druid_instance") @@ -19,12 +54,9 @@ local function input_init(self) end --- Create the component +-- Create the component itself local function create(self, instance_class) - ---@class component local instance = instance_class() - - -- Component context, self from component creation instance:setup_component(self._context, self._style) self.components[const.ALL] = self.components[const.ALL] or {} @@ -75,7 +107,10 @@ local function match_event(action_id, events) end ---- Druid constructor +--- Druid class constructor +-- @function druid:initialize +-- @tparam context table Druid context. Usually it is self of script +-- @tparam style table Druid style module function Druid.initialize(self, context, style) self._context = context self._style = style or settings.default_style @@ -83,9 +118,12 @@ function Druid.initialize(self, context, style) end ---- Create new component inside druid instance -function Druid.create(self, instance_class, ...) - local instance = create(self, instance_class) +--- Create new druid component +-- @function druid:create +-- @tparam Component component Component module +-- @tparam args ... Other component params to pass it to component:init function +function Druid.create(self, component, ...) + local instance = create(self, component) if instance.init then instance:init(...) @@ -95,8 +133,10 @@ function Druid.create(self, instance_class, ...) end ---- Remove component from druid instance --- It will call on_remove on component, if exist +--- Remove component from druid instance. +-- Component `on_remove` function will be invoked, if exist. +-- @function druid:remove +-- @tparam Component component Component instance function Druid.remove(self, component) local all_components = self.components[const.ALL] for i = #all_components, 1, -1 do @@ -123,8 +163,9 @@ function Druid.remove(self, component) end ---- Druid instance update function --- @function druid:update(dt) +--- Druid update function +-- @function druid:update +-- @tparam number dt Delta time function Druid.update(self, dt) local components = self.components[const.ON_UPDATE] if components then @@ -135,8 +176,10 @@ function Druid.update(self, dt) end ---- Druid instance on_input function --- @function druid:on_input(action_id, action) +--- Druid on_input function +-- @function druid:on_input +-- @tparam hash action_id Action_id from on_input +-- @tparam table action Action from on_input function Druid.on_input(self, action_id, action) -- TODO: расписать отличия ON_SWIPE и ON_INPUT -- Почему-то некоторые используют ON_SWIPE, а логичнее ON_INPUT? (blocker, slider) @@ -168,8 +211,11 @@ function Druid.on_input(self, action_id, action) end ---- Druid instance on_message function --- @function druid:on_message(message_id, message, sender) +--- Druid on_message function +-- @function druid:on_message +-- @tparam hash message_id Message_id from on_message +-- @tparam table message Message from on_message +-- @tparam hash sender Sender from on_message function Druid.on_message(self, message_id, message, sender) local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] if specific_ui_message then @@ -189,4 +235,132 @@ function Druid.on_message(self, message_id, message, sender) end +--- Create button basic component +-- @function druid:new_button +-- @tparam args ... button init args +-- @treturn Component button component +function Druid.new_button(self, ...) + return Druid.create(self, button, ...) +end + + +--- Create blocker basic component +-- @function druid:new_blocker +-- @tparam args ... blocker init args +-- @treturn Component blocker component +function Druid.new_blocker(self, ...) + return Druid.create(self, blocker, ...) +end + + +--- Create back_handler basic component +-- @function druid:new_back_handler +-- @tparam args ... back_handler init args +-- @treturn Component back_handler component +function Druid.new_back_handler(self, ...) + return Druid.create(self, back_handler, ...) +end + + +--- Create text basic component +-- @function druid:new_text +-- @tparam args ... text init args +-- @treturn Component text component +function Druid.new_text(self, ...) + return Druid.create(self, text, ...) +end + + +--- Create locale basic component +-- @function druid:new_locale +-- @tparam args ... locale init args +-- @treturn Component locale component +function Druid.new_locale(self, ...) + return Druid.create(self, locale, ...) +end + + +--- Create timer basic component +-- @function druid:new_timer +-- @tparam args ... timer init args +-- @treturn Component timer component +function Druid.new_timer(self, ...) + return Druid.create(self, timer, ...) +end + + +--- Create progress basic component +-- @function druid:new_progress +-- @tparam args ... progress init args +-- @treturn Component progress component +function Druid.new_progress(self, ...) + return Druid.create(self, progress, ...) +end + + +--- Create grid basic component +-- @function druid:new_grid +-- @tparam args ... grid init args +-- @treturn Component grid component +function Druid.new_grid(self, ...) + return Druid.create(self, grid, ...) +end + + +--- Create scroll basic component +-- @function druid:new_scroll +-- @tparam args ... scroll init args +-- @treturn Component scroll component +function Druid.new_scroll(self, ...) + return Druid.create(self, scroll, ...) +end + + +--- Create slider basic component +-- @function druid:new_slider +-- @tparam args ... slider init args +-- @treturn Component slider component +function Druid.new_slider(self, ...) + return Druid.create(self, slider, ...) +end + + +--- Create checkbox basic component +-- @function druid:new_checkbox +-- @tparam args ... checkbox init args +-- @treturn Component checkbox component +function Druid.new_checkbox(self, ...) + return Druid.create(self, checkbox, ...) +end + + +--- Create checkbox_group basic component +-- @function druid:new_checkbox_group +-- @tparam args ... checkbox_group init args +-- @treturn Component checkbox_group component +function Druid.new_checkbox_group(self, ...) + return Druid.create(self, checkbox_group, ...) +end + + +--- Create radio_group basic component +-- @function druid:new_radio_group +-- @tparam args ... radio_group init args +-- @treturn Component radio_group component +function Druid.new_radio_group(self, ...) + return Druid.create(self, radio_group, ...) +end + + +--- Create progress_rich basic component +-- @function druid:new_progress_rich +-- @tparam args ... progress_rich init args +-- @treturn Component progress_rich component +function Druid.new_progress_rich(self, ...) + return Druid.create(self, progress_rich, ...) +end + + + + return Druid diff --git a/druid/system/settings.lua b/druid/system/settings.lua index 1ca7dbe..d7bdfcd 100644 --- a/druid/system/settings.lua +++ b/druid/system/settings.lua @@ -1,5 +1,6 @@ --- Druid settings file -- @module settings +-- @local local M = {} From 544fd8d73667e31016b1daa17c7cf19f7053c06d Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 5 Feb 2020 02:44:09 +0300 Subject: [PATCH 097/136] Update ldoc code comments --- druid/base/back_handler.lua | 2 +- druid/base/blocker.lua | 2 +- druid/base/button.lua | 4 ++- druid/base/checkbox.lua | 2 +- druid/base/checkbox_group.lua | 2 +- druid/base/grid.lua | 2 +- druid/base/locale.lua | 2 +- druid/base/progress.lua | 2 +- druid/base/radio_group.lua | 2 +- druid/base/scroll.lua | 2 +- druid/base/slider.lua | 2 +- druid/base/text.lua | 2 +- druid/base/timer.lua | 2 +- druid/const.lua | 31 ++++++++++++++++++-- druid/helper.lua | 2 +- druid/helper/druid_animate.lua | 2 +- druid/rich/progress_rich.lua | 2 +- druid/system/component.lua | 53 ++++++++++++++++++++++++++++++++-- 18 files changed, 98 insertions(+), 20 deletions(-) diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index e957989..fa1d001 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -1,5 +1,5 @@ --- Component to handle back key (android, backspace) --- @module base.back_handler +-- @module druid.back_handler local const = require("druid.const") local component = require("druid.system.component") diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index a599d7e..5585252 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -1,5 +1,5 @@ --- Component to block input on specify zone (node) --- @module base.blocker +-- @module druid.blocker local const = require("druid.const") local helper = require("druid.helper") diff --git a/druid/base/button.lua b/druid/base/button.lua index d340933..f28aff7 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,5 +1,5 @@ --- Component to handle basic GUI button --- @module base.button +-- @module druid.button -- TODO: Add button mode: -- Long tap @@ -26,8 +26,10 @@ function M.init(self, node, callback, params, anim_node, event) self.style = self:get_style() self.node = helper.get_node(node) + -- TODO: match event inside on_input? self.event = const.ACTION_TOUCH self.anim_node = anim_node and helper.get_node(anim_node) or self.node + -- TODO: rename to start_scale self.scale_from = gui.get_scale(self.anim_node) self.pos = gui.get_position(self.anim_node) self.callback = callback diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index ef2f5d1..1d36dd9 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -1,5 +1,5 @@ --- Druid checkbox component --- @module base.checkbox +-- @module druid.checkbox local helper = require("druid.helper") local component = require("druid.system.component") diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 1360a3b..ea5e03d 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,5 +1,5 @@ --- Checkboux group module --- @module base.checkbox_group +-- @module druid.checkbox_group local component = require("druid.system.component") diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 34ac83a..d423959 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -1,6 +1,6 @@ --- Component to handle placing components by row and columns. -- Grid can anchor your elements, get content size and other --- @module base.grid +-- @module druid.grid local helper = require("druid.helper") local component = require("druid.system.component") diff --git a/druid/base/locale.lua b/druid/base/locale.lua index effd5b3..4aedbfc 100644 --- a/druid/base/locale.lua +++ b/druid/base/locale.lua @@ -1,6 +1,6 @@ --- Component to handle all GUI texts -- Good working with localization system --- @module base.text +-- @module druid.locale local const = require("druid.const") local settings = require("druid.system.settings") diff --git a/druid/base/progress.lua b/druid/base/progress.lua index f7b1ac6..9530f1d 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -1,5 +1,5 @@ --- Basic progress bar component --- @module base.progress +-- @module druid.progress local const = require("druid.const") local helper = require("druid.helper") diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua index 2b0606b..4450265 100644 --- a/druid/base/radio_group.lua +++ b/druid/base/radio_group.lua @@ -1,5 +1,5 @@ --- Radio group module --- @module base.checkbox_group +-- @module druid.radio_group local component = require("druid.system.component") diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 1e3a943..49eb85b 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -1,5 +1,5 @@ --- Component to handle scroll content --- @module base.scroll +-- @module druid.scroll local helper = require("druid.helper") local const = require("druid.const") diff --git a/druid/base/slider.lua b/druid/base/slider.lua index fd63782..59c0fb5 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -1,5 +1,5 @@ --- Druid slider component --- @module base.slider +-- @module druid.slider local helper = require("druid.helper") local const = require("druid.const") diff --git a/druid/base/text.lua b/druid/base/text.lua index d0dff8a..7aae65b 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,6 +1,6 @@ --- Component to handle all GUI texts -- Good working with localization system --- @module base.text +-- @module druid.text local const = require("druid.const") local helper = require("druid.helper") diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 8554818..42de1af 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,5 +1,5 @@ --- Component to handle GUI timers --- @module base.timer +-- @module druid.timer local const = require("druid.const") local formats = require("druid.helper.formats") diff --git a/druid/const.lua b/druid/const.lua index b5b820e..c94fb5c 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -1,8 +1,9 @@ --- Druid constants --- @module constants +-- @module const local M = {} + -- Actions M.ACTION_TOUCH = hash("touch") M.ACTION_TEXT = hash("text") @@ -10,22 +11,25 @@ M.ACTION_BACKSPACE = hash("backspace") M.ACTION_ENTER = hash("enter") M.ACTION_BACK = hash("back") + M.RELEASED = "released" M.PRESSED = "pressed" M.STRING = "string" M.TABLE = "table" M.ZERO = "0" - M.ALL = "all" + --- Interests M.ON_MESSAGE = hash("on_message") M.ON_UPDATE = hash("on_update") + -- Input M.ON_SWIPE = hash("on_swipe") M.ON_INPUT = hash("on_input") + M.PIVOTS = { [gui.PIVOT_CENTER] = vmath.vector3(0), [gui.PIVOT_N] = vmath.vector3(0, 0.5, 0), @@ -38,11 +42,13 @@ M.PIVOTS = { [gui.PIVOT_NW] = vmath.vector3(-0.5, 0.5, 0), } + M.SIDE = { X = "x", Y = "y" } + M.UI_INPUT = { [M.ON_SWIPE] = true, [M.ON_INPUT] = true @@ -52,13 +58,34 @@ M.UI_INPUT = { M.ON_CHANGE_LANGUAGE = hash("on_change_language") M.ON_LAYOUT_CHANGED = hash("on_layout_changed") + M.SPECIFIC_UI_MESSAGES = { [M.ON_CHANGE_LANGUAGE] = "on_change_language", [M.ON_LAYOUT_CHANGED] = "on_layout_changed" } + +-- Basic druid components +M.COMPONENTS = { + BUTTON = "button", + BLOCKER = "blocker", + BACK_HANDLER = "back_handler", + TEXT = "text", + LOCALE = "locale", + TIMER = "timer", + PROGRESS = "progress", + GRID = "grid", + SCROLL = "scroll", + SLIDER = "slider", + CHECKBOX = "checkbox", + CHECKBOX_GROUP = "checkbox_group", + RADIO_GROUP = "radio_group", +} + + M.EMPTY_FUNCTION = function() end M.EMPTY_STRING = "" M.EMPTY_TABLE = {} + return M \ No newline at end of file diff --git a/druid/helper.lua b/druid/helper.lua index 953c7ac..781480c 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,4 +1,4 @@ ---- Druid helper module +-- Druid helper module -- @module helper local const = require("druid.const") diff --git a/druid/helper/druid_animate.lua b/druid/helper/druid_animate.lua index fa58cc4..22ed827 100644 --- a/druid/helper/druid_animate.lua +++ b/druid/helper/druid_animate.lua @@ -1,4 +1,4 @@ ---- Druid helper module for animating GUI nodes +-- Druid helper module for animating GUI nodes -- @module helper.animate local M = {} diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index 2c5de7c..ec53597 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -1,5 +1,5 @@ --- Component for rich progress component --- @module rich.progress_rich +-- @module druid.progress_rich local component = require("druid.system.component") diff --git a/druid/system/component.lua b/druid/system/component.lua index ccfe840..2013cda 100644 --- a/druid/system/component.lua +++ b/druid/system/component.lua @@ -1,12 +1,19 @@ ---- General component class ---@class component +--- Basic class for all Druid components. +-- To create you component, use `component.create` +-- @module component local const = require("druid.const") local class = require("druid.system.middleclass") +-- @classmod Component local Component = class("druid.component") +--- Setup component context and his style table +-- @function component:setup_component +-- @tparam context table Druid context. Usually it is self of script +-- @tparam style table Druid style module +-- @treturn Component Component itself function Component.setup_component(self, context, style) self._meta = { template = nil, @@ -22,6 +29,9 @@ function Component.setup_component(self, context, style) end +--- Get current component style table +-- @function component:get_style +-- @treturn table Component style table function Component.get_style(self) if not self._meta.style then return const.EMPTY_TABLE @@ -31,41 +41,65 @@ function Component.get_style(self) end +--- Set current component style table +-- @function component:set_style +-- @tparam table style Druid style module function Component.set_style(self, druid_style) self._meta.style = druid_style end +--- Get current component template name +-- @function component:get_template +-- @treturn string Component template name function Component.get_template(self) return self._meta.template end +--- Set current component template name +-- @function component:set_template +-- @tparam string template Component template name function Component.set_template(self, template) self._meta.template = template end +--- Get current component nodes +-- @function component:get_nodes +-- @treturn table Component nodes table function Component.get_nodes(self) return self._meta.nodes end +--- Set current component nodes +-- @function component:set_nodes +-- @tparam table nodes Component nodes table function Component.set_nodes(self, nodes) self._meta.nodes = nodes end +--- Get current component context +-- @function component:get_context +-- @treturn table Component context function Component.get_context(self, context) return self._meta.context end +--- Set current component context +-- @function component:set_context +-- @tparam table context Druid context. Usually it is self of script function Component.set_context(self, context) self._meta.context = context end +--- Get current component interests +-- @function component:get_interests +-- @treturn table List of component interests function Component.get_interests(self) return self._component.interest end @@ -91,12 +125,22 @@ function Component.get_node(self, node_or_name) end +--- Return druid with context of calling component. +-- Use it to create component inside of other components. +-- @function component:get_druid +-- @treturn Druid Druid instance with component context function Component.get_druid(self) local context = { _context = self } return setmetatable(context, { __index = self:get_context().druid }) end +--- Basic constructor of component. It will call automaticaly +-- by `Component.static.create` +-- @function component:initialize +-- @tparam string name Component name +-- @tparam table interest List of component's interest +-- @local function Component.initialize(self, name, interest) self._component = { name = name, @@ -105,6 +149,11 @@ function Component.initialize(self, name, interest) end +--- Create new component. It will inheritance from basic +-- druid component. +-- @function Component.create +-- @tparam string name Component name +-- @tparam table interest List of component's interest function Component.static.create(name, interest) -- Yea, inheritance here local new_class = class(name, Component) From e1edc8ae9b4f5b74d23b4b4a54deab29670c36bd Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 6 Feb 2020 01:20:13 +0300 Subject: [PATCH 098/136] Move component from system to root folder --- README.md | 4 +- druid/base/back_handler.lua | 2 +- druid/base/blocker.lua | 2 +- druid/base/button.lua | 2 +- druid/base/checkbox.lua | 2 +- druid/base/checkbox_group.lua | 2 +- druid/base/grid.lua | 2 +- druid/base/locale.lua | 2 +- druid/base/progress.lua | 2 +- druid/base/radio_group.lua | 2 +- druid/base/scroll.lua | 2 +- druid/base/slider.lua | 2 +- druid/base/text.lua | 2 +- druid/base/timer.lua | 2 +- druid/component.lua | 169 ++++++++++++++++++++++++++++++++++ druid/rich/progress_rich.lua | 2 +- 16 files changed, 185 insertions(+), 16 deletions(-) create mode 100644 druid/component.lua diff --git a/README.md b/README.md index 6831790..7f46b50 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ end Basic custom component template looks like this: ```lua local const = require("druid.const") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("amazing_component", { const.ON_INPUT }) @@ -137,7 +137,7 @@ On each component recomended describe component schema in next way: ```lua -- Component module local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("new_component") diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index fa1d001..67078c5 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -2,7 +2,7 @@ -- @module druid.back_handler local const = require("druid.const") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("back_handler", { const.ON_INPUT }) diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 5585252..dcd00bd 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -3,7 +3,7 @@ local const = require("druid.const") local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("blocker", { const.ON_SWIPE }) diff --git a/druid/base/button.lua b/druid/base/button.lua index f28aff7..5fb3a14 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -7,7 +7,7 @@ local const = require("druid.const") local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("button", { const.ON_INPUT }) diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 1d36dd9..3c9c148 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -2,7 +2,7 @@ -- @module druid.checkbox local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("checkbox") diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index ea5e03d..90f9481 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,7 +1,7 @@ --- Checkboux group module -- @module druid.checkbox_group -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("checkbox_group") diff --git a/druid/base/grid.lua b/druid/base/grid.lua index d423959..1878fa3 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -3,7 +3,7 @@ -- @module druid.grid local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("grid") diff --git a/druid/base/locale.lua b/druid/base/locale.lua index 4aedbfc..d419f01 100644 --- a/druid/base/locale.lua +++ b/druid/base/locale.lua @@ -4,7 +4,7 @@ local const = require("druid.const") local settings = require("druid.system.settings") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("locale", { const.ON_CHANGE_LANGUAGE }) diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 9530f1d..cdf5776 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -3,7 +3,7 @@ local const = require("druid.const") local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("progress", { const.ON_UPDATE }) diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua index 4450265..b5e2f97 100644 --- a/druid/base/radio_group.lua +++ b/druid/base/radio_group.lua @@ -1,7 +1,7 @@ --- Radio group module -- @module druid.radio_group -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("radio_group") diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 49eb85b..fb32d9d 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -3,7 +3,7 @@ local helper = require("druid.helper") local const = require("druid.const") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("scroll", { const.ON_UPDATE, const.ON_SWIPE }) diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 59c0fb5..2c2a3ed 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -3,7 +3,7 @@ local helper = require("druid.helper") local const = require("druid.const") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("slider", { const.ON_SWIPE }) diff --git a/druid/base/text.lua b/druid/base/text.lua index 7aae65b..bc44c7c 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -4,7 +4,7 @@ local const = require("druid.const") local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("text") diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 42de1af..62c3c41 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -4,7 +4,7 @@ local const = require("druid.const") local formats = require("druid.helper.formats") local helper = require("druid.helper") -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("timer", { const.ON_UPDATE }) diff --git a/druid/component.lua b/druid/component.lua new file mode 100644 index 0000000..2013cda --- /dev/null +++ b/druid/component.lua @@ -0,0 +1,169 @@ +--- Basic class for all Druid components. +-- To create you component, use `component.create` +-- @module component + +local const = require("druid.const") +local class = require("druid.system.middleclass") + +-- @classmod Component +local Component = class("druid.component") + + +--- Setup component context and his style table +-- @function component:setup_component +-- @tparam context table Druid context. Usually it is self of script +-- @tparam style table Druid style module +-- @treturn Component Component itself +function Component.setup_component(self, context, style) + self._meta = { + template = nil, + context = nil, + nodes = nil, + style = nil, + } + + self:set_context(context) + self:set_style(style) + + return self +end + + +--- Get current component style table +-- @function component:get_style +-- @treturn table Component style table +function Component.get_style(self) + if not self._meta.style then + return const.EMPTY_TABLE + end + + return self._meta.style[self._component.name] or const.EMPTY_TABLE +end + + +--- Set current component style table +-- @function component:set_style +-- @tparam table style Druid style module +function Component.set_style(self, druid_style) + self._meta.style = druid_style +end + + +--- Get current component template name +-- @function component:get_template +-- @treturn string Component template name +function Component.get_template(self) + return self._meta.template +end + + +--- Set current component template name +-- @function component:set_template +-- @tparam string template Component template name +function Component.set_template(self, template) + self._meta.template = template +end + + +--- Get current component nodes +-- @function component:get_nodes +-- @treturn table Component nodes table +function Component.get_nodes(self) + return self._meta.nodes +end + + +--- Set current component nodes +-- @function component:set_nodes +-- @tparam table nodes Component nodes table +function Component.set_nodes(self, nodes) + self._meta.nodes = nodes +end + + +--- Get current component context +-- @function component:get_context +-- @treturn table Component context +function Component.get_context(self, context) + return self._meta.context +end + + +--- Set current component context +-- @function component:set_context +-- @tparam table context Druid context. Usually it is self of script +function Component.set_context(self, context) + self._meta.context = context +end + + +--- Get current component interests +-- @function component:get_interests +-- @treturn table List of component interests +function Component.get_interests(self) + return self._component.interest +end + + +-- TODO: Определиться с get_node и node +-- get_node - берет ноду по ноде или строке +-- node - может брать ноду у компонента по схеме (если есть +-- template или таблица нод после gui.clone_tree) +function Component.get_node(self, node_or_name) + local template_name = self:get_template() or const.EMPTY_STRING + local nodes = self:get_nodes() + + if nodes then + return nodes[template_name .. node_or_name] + else + if type(node_or_name) == const.STRING then + return gui.get_node(template_name .. node_or_name) + else + return node_or_name + end + end +end + + +--- Return druid with context of calling component. +-- Use it to create component inside of other components. +-- @function component:get_druid +-- @treturn Druid Druid instance with component context +function Component.get_druid(self) + local context = { _context = self } + return setmetatable(context, { __index = self:get_context().druid }) +end + + +--- Basic constructor of component. It will call automaticaly +-- by `Component.static.create` +-- @function component:initialize +-- @tparam string name Component name +-- @tparam table interest List of component's interest +-- @local +function Component.initialize(self, name, interest) + self._component = { + name = name, + interest = interest + } +end + + +--- Create new component. It will inheritance from basic +-- druid component. +-- @function Component.create +-- @tparam string name Component name +-- @tparam table interest List of component's interest +function Component.static.create(name, interest) + -- Yea, inheritance here + local new_class = class(name, Component) + + new_class.initialize = function(self) + Component.initialize(self, name, interest) + end + + return new_class +end + + +return Component diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua index ec53597..fe39a9b 100644 --- a/druid/rich/progress_rich.lua +++ b/druid/rich/progress_rich.lua @@ -1,7 +1,7 @@ --- Component for rich progress component -- @module druid.progress_rich -local component = require("druid.system.component") +local component = require("druid.component") local M = component.create("progress_rich") From 3b38992de8f090ba68d84c55e32e198515927a19 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 6 Feb 2020 01:53:41 +0300 Subject: [PATCH 099/136] remove druid_animate, update docs --- docs/index.html | 14 +- docs/modules/component.html | 4 +- docs/modules/const.html | 4 +- docs/modules/druid.back_handler.html | 4 +- docs/modules/druid.blocker.html | 4 +- docs/modules/druid.button.html | 4 +- docs/modules/druid.checkbox.html | 4 +- docs/modules/druid.checkbox_group.html | 4 +- docs/modules/druid.grid.html | 4 +- docs/modules/druid.html | 4 +- docs/modules/druid.locale.html | 4 +- docs/modules/druid.progress.html | 4 +- docs/modules/druid.progress_rich.html | 4 +- docs/modules/druid.radio_group.html | 4 +- docs/modules/druid.scroll.html | 4 +- docs/modules/druid.slider.html | 4 +- docs/modules/druid.text.html | 4 +- docs/modules/druid.timer.html | 4 +- docs/modules/druid_instance.html | 4 +- docs/modules/helper.formats.html | 4 +- docs/modules/helper.html | 4 +- druid/base/button.lua | 1 + druid/base/timer.lua | 24 ++-- druid/helper/druid_animate.lua | 189 ------------------------- druid/styles/bounce/anims.lua | 24 +++- druid/system/component.lua | 169 ---------------------- druid/system/druid_instance.lua | 2 - 27 files changed, 79 insertions(+), 424 deletions(-) delete mode 100644 druid/helper/druid_animate.lua delete mode 100644 druid/system/component.lua diff --git a/docs/index.html b/docs/index.html index f04bfad..6e28364 100644 --- a/docs/index.html +++ b/docs/index.html @@ -44,12 +44,12 @@
    • druid.slider
    • druid.text
    • druid.timer
    • +
    • component
    • const
    • druid
    • helper
    • helper.formats
    • druid.progress_rich
    • -
    • component
    • druid_instance
    @@ -58,7 +58,7 @@
    -

    Documentation for Druid Library

    +

    Documentation for Druid UI Library

    Modules

    @@ -116,6 +116,10 @@ + + + + @@ -136,10 +140,6 @@ - - - - @@ -150,7 +150,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/component.html b/docs/modules/component.html index efdbf93..97bca4d 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -398,7 +398,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/const.html b/docs/modules/const.html index a660ac7..67e8268 100644 --- a/docs/modules/const.html +++ b/docs/modules/const.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -105,7 +105,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 056ed7a..851b443 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -150,7 +150,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 2bfeb01..2eac1e0 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -47,12 +47,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 5550167..54a61db 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -190,7 +190,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index 69bf10e..4a55bba 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -47,12 +47,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index fd22518..b8824a0 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -47,12 +47,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 2dc932e..3aeed3a 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -47,12 +47,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index e2407f7..51c19d0 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -161,7 +161,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.locale.html b/docs/modules/druid.locale.html index a815917..45da53f 100644 --- a/docs/modules/druid.locale.html +++ b/docs/modules/druid.locale.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -117,7 +117,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index a51299f..5bb06b8 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -295,7 +295,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.progress_rich.html b/docs/modules/druid.progress_rich.html index f543b12..2cce401 100644 --- a/docs/modules/druid.progress_rich.html +++ b/docs/modules/druid.progress_rich.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -175,7 +175,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index 37f9b24..b1bb0e0 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -47,12 +47,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index dc62222..2836be1 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -275,7 +275,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index bb12425..427bc7a 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -47,12 +47,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -76,7 +76,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index d118b49..abb909d 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -234,7 +234,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index 23a625d..52c40e5 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -178,7 +178,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index f0be67e..93f898e 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -709,7 +709,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/helper.formats.html b/docs/modules/helper.formats.html index 3f58d1e..f2f5a94 100644 --- a/docs/modules/helper.formats.html +++ b/docs/modules/helper.formats.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -185,7 +185,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/docs/modules/helper.html b/docs/modules/helper.html index d796afa..1b48bb9 100644 --- a/docs/modules/helper.html +++ b/docs/modules/helper.html @@ -51,12 +51,12 @@
  • druid.slider
  • druid.text
  • druid.timer
  • +
  • component
  • const
  • druid
  • helper
  • helper.formats
  • druid.progress_rich
  • -
  • component
  • druid_instance
  • @@ -147,7 +147,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-05 02:43:10 +Last updated 2020-02-06 01:47:09
    diff --git a/druid/base/button.lua b/druid/base/button.lua index 5fb3a14..549c330 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -4,6 +4,7 @@ -- TODO: Add button mode: -- Long tap -- Repeated tap +-- Double tap? local const = require("druid.const") local helper = require("druid.helper") diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 62c3c41..b7f1adc 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -62,18 +62,20 @@ end function M.update(self, dt) - if self.is_on then - self.temp = self.temp + dt - local dist = math.min(1, math.abs(self.value - self.target)) + if not self.is_on then + return + end - if self.temp > dist then - self.temp = self.temp - dist - self.value = helper.step(self.value, self.target, 1) - M.set_to(self, self.value) - if self.value == self.target then - self:set_state(false) - self.callback(self:get_context(), self) - end + self.temp = self.temp + dt + local dist = math.min(1, math.abs(self.value - self.target)) + + if self.temp > dist then + self.temp = self.temp - dist + self.value = helper.step(self.value, self.target, 1) + M.set_to(self, self.value) + if self.value == self.target then + self:set_state(false) + self.callback(self:get_context(), self) end end end diff --git a/druid/helper/druid_animate.lua b/druid/helper/druid_animate.lua deleted file mode 100644 index 22ed827..0000000 --- a/druid/helper/druid_animate.lua +++ /dev/null @@ -1,189 +0,0 @@ --- Druid helper module for animating GUI nodes --- @module helper.animate - -local M = {} - -local PROP_SCALE = gui.PROP_SCALE -local PROP_POSITION = gui.PROP_POSITION -local PROP_COLOR = hash("color") -local PROP_SCALE_X = "scale.x" -local PROP_SCALE_Y = "scale.y" - -M.PROP_POS_X = hash("position.x") -M.PROP_POS_Y = hash("position.y") -M.PROP_ALPHA = hash("color.w") - -M.TINT_HIDE = vmath.vector4(1, 1, 1, 0) -M.TINT_SHOW = vmath.vector4(1, 1, 1, 1) - -M.V3_ONE = vmath.vector3(1, 1, 1) -M.V3_ZERO = vmath.vector3(0, 0, 1) - -M.SCALE_ANIMATION_TIME = 0.1 -M.BOUNCE_ANIMATION_TIME = 0.25 -M.ALPHA_ANIMATION_TIME = 0.25 - - -function M.alpha(self, node, alpha, callback, time, delay, easing, playback) - time = time or M.ALPHA_ANIMATION_TIME - delay = delay or 0 - easing = easing or gui.EASING_LINEAR - playback = playback or gui.PLAYBACK_ONCE_FORWARD - gui.animate(node, M.PROP_ALPHA, alpha, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) -end - - -function M.color(self, node, color, callback, time, delay, easing, playback) - time = time or M.ALPHA_ANIMATION_TIME - delay = delay or 0 - easing = easing or gui.EASING_LINEAR - playback = playback or gui.PLAYBACK_ONCE_FORWARD - gui.animate(node, PROP_COLOR, color, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) -end - - -function M.shake(self, node, callback, str, time) - str = str or - 30 - time = time or 0.25 - local pos = gui.get_position(node) - pos.x = pos.x + str - gui.animate(node, PROP_POSITION, pos, gui.EASING_INELASTIC, time, - 0, - function() - if callback then - callback(self) - end - end, - gui.PLAYBACK_ONCE_BACKWARD - ) -end - - -function M.bounce(self, node, change_to, callback, time, easing, playback, delaly) - time = time or M.BOUNCE_ANIMATION_TIME - delaly = delaly or 0 - easing = easing or gui.EASING_OUTSINE - playback = playback or gui.PLAYBACK_ONCE_PINGPONG - gui.animate(node, PROP_SCALE, change_to, easing, time, delaly, - function() - if callback then - callback(self) - end - end, - playback) -end - - -function M.fly_to(self, node, to_pos, speed, callback, delay, easing) - easing = easing or gui.EASING_OUTSINE - delay = delay or 0 - local time = vmath.length(to_pos - gui.get_position(node)) / 100 / speed - gui.animate(node, gui.PROP_POSITION, to_pos, easing, time, delay, - function() - if callback then - callback(self, node) - end - end) -end - - -function M.fly_by_x(self, node, to_x, time, callback, delay, easing, playback) - playback = playback or gui.PLAYBACK_ONCE_FORWARD - easing = easing or gui.EASING_OUTSINE - delay = delay or 0 - gui.animate(node, M.PROP_POS_X, to_x, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) -end - - -function M.fly_by_y(self, node, to_y, time, callback, delay, easing, playback) - playback = playback or gui.PLAYBACK_ONCE_FORWARD - easing = easing or gui.EASING_OUTSINE - delay = delay or 0 - time = time or 0.25 - gui.animate(node, M.PROP_POS_Y, to_y, easing, time, delay, - function() - if callback then - callback(self, node) - end - end, - playback) -end - - -function M.scale_to(self, node, to, callback, time, delay, easing) - easing = easing or gui.EASING_INSINE - time = time or M.SCALE_ANIMATION_TIME - delay = delay or 0 - time = time or 0.25 - gui.animate(node, PROP_SCALE, to, easing, time, delay, - function() - if callback then - callback(self, node) - end - end - ) -end - - -function M.scale(self, node, to, time) - gui.animate(node, "scale", to, gui.EASING_OUTSINE, time) -end - - -function M.scale_x_from_to(self, node, from, to, callback, time, easing, delay, playback) - easing = easing or gui.EASING_INSINE - time = time or M.SCALE_ANIMATION_TIME - delay = delay or 0 - playback = playback or gui.PLAYBACK_ONCE_FORWARD - local scale = gui.get_scale(node) - scale.x = from - gui.set_scale(node, scale) - gui.animate(node, PROP_SCALE_X, to, easing, time, delay, - function() - if callback then - callback(self) - end - end, - playback - ) -end - - -function M.scale_y_from_to(self, node, from, to, callback, time, easing, delay, playback) - easing = easing or gui.EASING_INSINE - time = time or M.SCALE_ANIMATION_TIME - delay = delay or 0 - playback = playback or gui.PLAYBACK_ONCE_FORWARD - local scale = gui.get_scale(node) - scale.y = from - gui.set_scale(node, scale) - gui.animate(node, PROP_SCALE_Y, to, easing, time, delay, - function() - if callback then - callback(self) - end - end, - playback - ) -end - - -return M \ No newline at end of file diff --git a/druid/styles/bounce/anims.lua b/druid/styles/bounce/anims.lua index bb642a6..ae56a40 100644 --- a/druid/styles/bounce/anims.lua +++ b/druid/styles/bounce/anims.lua @@ -1,16 +1,28 @@ -local ui_animate = require("druid.helper.druid_animate") - - local M = {} +local function scale_to(self, node, to, callback, time, delay, easing) + easing = easing or gui.EASING_INSINE + time = time or M.SCALE_ANIMATION_TIME + delay = delay or 0 + time = time or 0.25 + gui.animate(node, gui.PROP_SCALE, to, easing, time, delay, + function() + if callback then + callback(self, node) + end + end + ) +end + + function M.back_scale_animation(self, node, target_scale) - ui_animate.scale_to(self, node, target_scale) + scale_to(self, node, target_scale) end function M.tap_scale_animation(self, node, target_scale) - ui_animate.scale_to(self, node, target_scale, + scale_to(self, node, target_scale, function() M.back_scale_animation(self, node, self.scale_from) end @@ -19,7 +31,7 @@ end function M.hover_scale(self, target, time) - ui_animate.scale(self, self.anim_node, target, time) + gui.animate(self.anim_node, "scale", target, gui.EASING_OUTSINE, time) end diff --git a/druid/system/component.lua b/druid/system/component.lua deleted file mode 100644 index 2013cda..0000000 --- a/druid/system/component.lua +++ /dev/null @@ -1,169 +0,0 @@ ---- Basic class for all Druid components. --- To create you component, use `component.create` --- @module component - -local const = require("druid.const") -local class = require("druid.system.middleclass") - --- @classmod Component -local Component = class("druid.component") - - ---- Setup component context and his style table --- @function component:setup_component --- @tparam context table Druid context. Usually it is self of script --- @tparam style table Druid style module --- @treturn Component Component itself -function Component.setup_component(self, context, style) - self._meta = { - template = nil, - context = nil, - nodes = nil, - style = nil, - } - - self:set_context(context) - self:set_style(style) - - return self -end - - ---- Get current component style table --- @function component:get_style --- @treturn table Component style table -function Component.get_style(self) - if not self._meta.style then - return const.EMPTY_TABLE - end - - return self._meta.style[self._component.name] or const.EMPTY_TABLE -end - - ---- Set current component style table --- @function component:set_style --- @tparam table style Druid style module -function Component.set_style(self, druid_style) - self._meta.style = druid_style -end - - ---- Get current component template name --- @function component:get_template --- @treturn string Component template name -function Component.get_template(self) - return self._meta.template -end - - ---- Set current component template name --- @function component:set_template --- @tparam string template Component template name -function Component.set_template(self, template) - self._meta.template = template -end - - ---- Get current component nodes --- @function component:get_nodes --- @treturn table Component nodes table -function Component.get_nodes(self) - return self._meta.nodes -end - - ---- Set current component nodes --- @function component:set_nodes --- @tparam table nodes Component nodes table -function Component.set_nodes(self, nodes) - self._meta.nodes = nodes -end - - ---- Get current component context --- @function component:get_context --- @treturn table Component context -function Component.get_context(self, context) - return self._meta.context -end - - ---- Set current component context --- @function component:set_context --- @tparam table context Druid context. Usually it is self of script -function Component.set_context(self, context) - self._meta.context = context -end - - ---- Get current component interests --- @function component:get_interests --- @treturn table List of component interests -function Component.get_interests(self) - return self._component.interest -end - - --- TODO: Определиться с get_node и node --- get_node - берет ноду по ноде или строке --- node - может брать ноду у компонента по схеме (если есть --- template или таблица нод после gui.clone_tree) -function Component.get_node(self, node_or_name) - local template_name = self:get_template() or const.EMPTY_STRING - local nodes = self:get_nodes() - - if nodes then - return nodes[template_name .. node_or_name] - else - if type(node_or_name) == const.STRING then - return gui.get_node(template_name .. node_or_name) - else - return node_or_name - end - end -end - - ---- Return druid with context of calling component. --- Use it to create component inside of other components. --- @function component:get_druid --- @treturn Druid Druid instance with component context -function Component.get_druid(self) - local context = { _context = self } - return setmetatable(context, { __index = self:get_context().druid }) -end - - ---- Basic constructor of component. It will call automaticaly --- by `Component.static.create` --- @function component:initialize --- @tparam string name Component name --- @tparam table interest List of component's interest --- @local -function Component.initialize(self, name, interest) - self._component = { - name = name, - interest = interest - } -end - - ---- Create new component. It will inheritance from basic --- druid component. --- @function Component.create --- @tparam string name Component name --- @tparam table interest List of component's interest -function Component.static.create(name, interest) - -- Yea, inheritance here - local new_class = class(name, Component) - - new_class.initialize = function(self) - Component.initialize(self, name, interest) - end - - return new_class -end - - -return Component diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index b76b652..4a524fe 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -361,6 +361,4 @@ function Druid.new_progress_rich(self, ...) end - - return Druid From f65d5ce71cdf2206a03e9e576c2d953b0413755b Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 7 Feb 2020 01:10:10 +0300 Subject: [PATCH 100/136] Update docs --- docs/index.html | 14 ++------ docs/modules/component.html | 4 +-- docs/modules/const.html | 34 ++++++++++++++++++- docs/modules/druid.back_handler.html | 4 +-- docs/modules/druid.blocker.html | 4 +-- docs/modules/druid.button.html | 4 +-- docs/modules/druid.checkbox.html | 4 +-- docs/modules/druid.checkbox_group.html | 4 +-- docs/modules/druid.grid.html | 4 +-- docs/modules/druid.html | 4 +-- docs/modules/druid.locale.html | 4 +-- docs/modules/druid.progress.html | 4 +-- docs/modules/druid.progress_rich.html | 4 +-- docs/modules/druid.radio_group.html | 4 +-- docs/modules/druid.scroll.html | 4 +-- docs/modules/druid.slider.html | 4 +-- docs/modules/druid.text.html | 4 +-- docs/modules/druid.timer.html | 4 +-- docs/modules/druid_instance.html | 4 +-- docs/modules/helper.formats.html | 3 +- docs/modules/helper.html | 47 ++++++++++++++++---------- druid/const.lua | 3 +- druid/helper.lua | 18 ++++++++-- druid/helper/formats.lua | 1 + 24 files changed, 100 insertions(+), 88 deletions(-) diff --git a/docs/index.html b/docs/index.html index 6e28364..193baec 100644 --- a/docs/index.html +++ b/docs/index.html @@ -45,10 +45,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -58,7 +56,7 @@
    -

    Documentation for Druid UI Library

    +

    Documentation for Druid Library

    Modules

    druid.timer Component to handle GUI timers
    componentBasic class for all Druid components.
    const Druid constantsdruid.progress_rich Component for rich progress component
    componentBasic class for all Druid components.
    druid_instance Druid main class.
    @@ -120,10 +118,6 @@ - - - - @@ -132,10 +126,6 @@ - - - - @@ -150,7 +140,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/component.html b/docs/modules/component.html index 97bca4d..5923cd0 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -398,7 +396,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/const.html b/docs/modules/const.html index 67e8268..0b50a56 100644 --- a/docs/modules/const.html +++ b/docs/modules/const.html @@ -32,6 +32,7 @@

    Contents

    @@ -69,6 +70,13 @@

    +

    Tables

    +
    component Basic class for all Druid components.
    constDruid constants
    druid Druid UI Library.helper Text node or icon node can be nil
    helper.formatsDruid module with utils on string formats
    druid.progress_rich Component for rich progress component
    + + + + +
    pivots

    Fields

    @@ -81,6 +89,30 @@
    +

    Tables

    + +
    +
    + + pivots +
    +
    + + + +

    Fields:

    +
      +
    • test + test +
    • +
    + + + + + +
    +

    Fields

    @@ -105,7 +137,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:01:14
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 851b443..c0b420f 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -150,7 +148,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 2eac1e0..e1924ab 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -48,10 +48,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -76,7 +74,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 54a61db..7e0edbc 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -190,7 +188,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index 4a55bba..51a2f75 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -48,10 +48,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -76,7 +74,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index b8824a0..0071b08 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -48,10 +48,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -76,7 +74,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 3aeed3a..9321a7f 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -48,10 +48,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -77,7 +75,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 51c19d0..18bfff8 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -161,7 +159,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.locale.html b/docs/modules/druid.locale.html index 45da53f..cd07ef0 100644 --- a/docs/modules/druid.locale.html +++ b/docs/modules/druid.locale.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -117,7 +115,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index 5bb06b8..c133fb8 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -295,7 +293,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.progress_rich.html b/docs/modules/druid.progress_rich.html index 2cce401..335a6b3 100644 --- a/docs/modules/druid.progress_rich.html +++ b/docs/modules/druid.progress_rich.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -175,7 +173,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index b1bb0e0..e4db277 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -48,10 +48,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -76,7 +74,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index 2836be1..c91a211 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -275,7 +273,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index 427bc7a..4a71669 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -48,10 +48,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -76,7 +74,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index abb909d..c35de59 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -234,7 +232,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index 52c40e5..afc6f94 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -178,7 +176,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index 93f898e..fc11032 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -709,7 +707,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/docs/modules/helper.formats.html b/docs/modules/helper.formats.html index f2f5a94..59952c4 100644 --- a/docs/modules/helper.formats.html +++ b/docs/modules/helper.formats.html @@ -52,7 +52,6 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • helper.formats
  • @@ -185,7 +184,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:01:59
    diff --git a/docs/modules/helper.html b/docs/modules/helper.html index 1b48bb9..0577525 100644 --- a/docs/modules/helper.html +++ b/docs/modules/helper.html @@ -52,10 +52,8 @@
  • druid.text
  • druid.timer
  • component
  • -
  • const
  • druid
  • helper
  • -
  • helper.formats
  • druid.progress_rich
  • druid_instance
  • @@ -72,12 +70,12 @@

    Functions

    - - + + - - + +
    centrate_text_with_icon(text_node, icon_node, margin)Text node or icon node can be nilcentrate_text_with_icon([text_node][, icon_node], margin)Center two nodes.
    centrate_icon_with_text(icon_node, text_node, margin)Icon node or text node can be nilcentrate_icon_with_text([icon_node[, text_node[, margin=0]]])Center two nodes.
    @@ -90,22 +88,29 @@
    - centrate_text_with_icon(text_node, icon_node, margin) + centrate_text_with_icon([text_node][, icon_node], margin)
    - Text node or icon node can be nil + Center two nodes. + Nodes will be center around 0 x position + text_node will be first (at left side)

    Parameters:

    • text_node - + text + Gui text node + (optional)
    • icon_node - + box + Gui box node + (optional)
    • margin - + number + Offset between nodes
    @@ -116,22 +121,30 @@
    - centrate_icon_with_text(icon_node, text_node, margin) + centrate_icon_with_text([icon_node[, text_node[, margin=0]]])
    - Icon node or text node can be nil + Center two nodes. + Nodes will be center around 0 x position + icon_node will be first (at left side)

    Parameters:

    • icon_node - + box + Gui box node + (optional)
    • text_node - + text + Gui text node + (optional)
    • margin - + number + Offset between nodes + (default 0)
    @@ -147,7 +160,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-06 01:47:09 +Last updated 2020-02-07 01:09:38
    diff --git a/druid/const.lua b/druid/const.lua index c94fb5c..ace87b6 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -1,10 +1,9 @@ --- Druid constants +-- @local -- @module const local M = {} - --- Actions M.ACTION_TOUCH = hash("touch") M.ACTION_TEXT = hash("text") M.ACTION_BACKSPACE = hash("backspace") diff --git a/druid/helper.lua b/druid/helper.lua index 781480c..d842bd2 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -1,4 +1,4 @@ --- Druid helper module +-- Druid helper module for gui layouts -- @module helper local const = require("druid.const") @@ -28,7 +28,13 @@ local function get_icon_width(icon_node) end ---- Text node or icon node can be nil +--- 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) @@ -49,7 +55,13 @@ function M.centrate_text_with_icon(text_node, icon_node, margin) end ---- Icon node or text node can be nil +--- 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) diff --git a/druid/helper/formats.lua b/druid/helper/formats.lua index d08dccf..626ee52 100644 --- a/druid/helper/formats.lua +++ b/druid/helper/formats.lua @@ -1,4 +1,5 @@ --- Druid module with utils on string formats +-- @local -- @module helper.formats local const = require("druid.const") From 080035c301274b8686cda3d370488c3ab54debfa Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 7 Feb 2020 01:17:43 +0300 Subject: [PATCH 101/136] Move helper.get_node to component --- README.md | 4 ++-- druid/base/blocker.lua | 2 +- druid/base/button.lua | 6 +++--- druid/base/checkbox.lua | 5 ++--- druid/base/grid.lua | 5 ++--- druid/base/progress.lua | 2 +- druid/base/scroll.lua | 4 ++-- druid/base/slider.lua | 2 +- druid/base/text.lua | 3 +-- druid/base/timer.lua | 2 +- druid/component.lua | 1 + druid/helper.lua | 34 +++++++++------------------------- 12 files changed, 26 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 7f46b50..da5806f 100644 --- a/README.md +++ b/README.md @@ -154,8 +154,8 @@ function M.init(self, template_name, node_table) -- If component was cloned with gui.clone_tree, pass his nodes self:set_nodes(node_table) - -- helper can get node from gui/template/table - local root = helper.node(self, SCHEME.ROOT) + -- Component can get node from gui/template/table + local root = self:get_node(self, SCHEME.ROOT) -- This component can spawn another druid components: local druid = self:get_druid(self) diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index dcd00bd..5c48263 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -9,7 +9,7 @@ local M = component.create("blocker", { const.ON_SWIPE }) function M.init(self, node) - self.node = helper.get_node(node) + self.node = self:get_node(node) self.event = const.ACTION_TOUCH end diff --git a/druid/base/button.lua b/druid/base/button.lua index 549c330..5367a57 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -25,11 +25,11 @@ function M.init(self, node, callback, params, anim_node, event) assert(callback, "Button should have callback. To block input on zone use blocker component") self.style = self:get_style() - self.node = helper.get_node(node) + self.node = self:get_node(node) -- TODO: match event inside on_input? self.event = const.ACTION_TOUCH - self.anim_node = anim_node and helper.get_node(anim_node) or self.node + self.anim_node = anim_node and helper:get_node(anim_node) or self.node -- TODO: rename to start_scale self.scale_from = gui.get_scale(self.anim_node) self.pos = gui.get_position(self.anim_node) @@ -144,7 +144,7 @@ end -- @tparam table self Component instance -- @tparam node zone Gui node function M.set_click_zone(self, zone) - self.click_zone = helper.get_node(zone) + self.click_zone = self:get_node(zone) end diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 3c9c148..707e6ea 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -1,7 +1,6 @@ --- Druid checkbox component -- @module druid.checkbox -local helper = require("druid.helper") local component = require("druid.component") local M = component.create("checkbox") @@ -36,8 +35,8 @@ end function M.init(self, node, callback, click_node) self.style = self:get_style() self.druid = self:get_druid() - self.node = helper.get_node(node) - self.click_node = helper.get_node(click_node) + self.node = self:get_node(node) + self.click_node = self:get_node(click_node) self.callback = callback self.button = self.druid:new_button(self.click_node or self.node, on_click) diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 1878fa3..6ba4e7e 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -2,20 +2,19 @@ -- Grid can anchor your elements, get content size and other -- @module druid.grid -local helper = require("druid.helper") local component = require("druid.component") local M = component.create("grid") function M.init(self, parent, element, in_row) - self.parent = helper.get_node(parent) + self.parent = self:get_node(parent) self.nodes = {} self.offset = vmath.vector3(0) self.anchor = vmath.vector3(0.5, 0, 0) self.in_row = in_row or 1 - self.node_size = gui.get_size(helper.get_node(element)) + self.node_size = gui.get_size(self:get_node(element)) self.border = vmath.vector4(0) self.border_offset = vmath.vector3(0) end diff --git a/druid/base/progress.lua b/druid/base/progress.lua index cdf5776..251c38f 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -21,7 +21,7 @@ function M.init(self, node, key, init_value) self.key = key self.style = self:get_style() - self.node = helper.get_node(node) + 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] diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index fb32d9d..a00459a 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -15,8 +15,8 @@ M.current_scroll = nil function M.init(self, scroll_parent, input_zone, border) self.style = self:get_style() - self.node = helper.get_node(scroll_parent) - self.input_zone = helper.get_node(input_zone) + self.node = self:get_node(scroll_parent) + self.input_zone = self:get_node(input_zone) self.zone_size = gui.get_size(self.input_zone) self.soft_size = self.style.SOFT_ZONE_SIZE diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 2c2a3ed..5b8d691 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -16,7 +16,7 @@ end function M.init(self, node, end_pos, callback) - self.node = helper.get_node(node) + self.node = self:get_node(node) self.start_pos = gui.get_position(self.node) self.pos = gui.get_position(self.node) diff --git a/druid/base/text.lua b/druid/base/text.lua index bc44c7c..72307d8 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -3,14 +3,13 @@ -- @module druid.text local const = require("druid.const") -local helper = require("druid.helper") local component = require("druid.component") local M = component.create("text") function M.init(self, node, value, no_adjust) - self.node = helper.get_node(node) + self.node = self:get_node(node) self.start_pivot = gui.get_pivot(self.node) self.start_pos = gui.get_position(self.node) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index b7f1adc..efd8fc9 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -10,7 +10,7 @@ local M = component.create("timer", { const.ON_UPDATE }) function M.init(self, node, seconds_from, seconds_to, callback) - self.node = helper.get_node(node) + self.node = self:get_node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) callback = callback or const.EMPTY_FUNCTION diff --git a/druid/component.lua b/druid/component.lua index 2013cda..8b9caf5 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -114,6 +114,7 @@ function Component.get_node(self, node_or_name) local nodes = self:get_nodes() if nodes then + assert(type(node_or_name) == "strings", "You should pass node name instead of node") return nodes[template_name .. node_or_name] else if type(node_or_name) == const.STRING then diff --git a/druid/helper.lua b/druid/helper.lua index d842bd2..ccd08a4 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -82,31 +82,6 @@ function M.centrate_icon_with_text(icon_node, text_node, margin) end -function M.get_node(node_or_name) - if type(node_or_name) == const.STRING then - return gui.get_node(node_or_name) - end - - return node_or_name -end - - --- TODO: Определиться с get_node и node --- get_node - берет ноду по ноде или строке --- node - может брать ноду у компонента по схеме (если есть --- template или таблица нод после gui.clone_tree) -function M.node(component, name) - local template_name = component._meta.template or const.EMPTY_STRING - local nodes = component._meta.nodes - - if nodes then - return nodes[template_name .. name] - else - return gui.get_node(template_name .. name) - end -end - - function M.step(current, target, step) if current < target then return math.min(current + step, target) @@ -151,6 +126,11 @@ function M.round(num, numDecimalPlaces) 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) @@ -163,6 +143,10 @@ function M.is_enabled(node) 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 From aac80795b9af5dbd2d9a7fb01bc66a18daa4e7b4 Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 7 Feb 2020 01:36:11 +0300 Subject: [PATCH 102/136] Add alpha_todo fur alpha release --- alpha_todo.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 alpha_todo.txt diff --git a/alpha_todo.txt b/alpha_todo.txt new file mode 100644 index 0000000..6073ea5 --- /dev/null +++ b/alpha_todo.txt @@ -0,0 +1,22 @@ +Simple to-do for Druid Alpha 2.0 + +- custom input settings (name of touch, text, etc) +- refactor on_swipe. To on_scroll? Add input priority +- remove button event and match_event from druid +- add docs for all components +- button polish, actions +- ability to relocalize all locale text nodes +- better name for locale component? lang? lang_text? +- better scroll size management, check different cases. So implicit now +- better grid + scroll management +- add druid settings (add auto_focus input and other stuff) +- better default style, add template for custom style +- add template for user components +- add good examples with template and/or nodes (basic component no use any of them) +- add docs folder for every component with gifs? Solutions +- add init/remove stuff for every style in component. How to set custom sprites for button states? +- better callbacks for every components +- separate custom data and predefined fields in components? +- try use final druid in real project (FI uses custom druid) +- better name for slider component? +- add text component for alpha release \ No newline at end of file From b198e095603443b11977ea9f13b07912dc19e210 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 14:44:01 +0300 Subject: [PATCH 103/136] Add functions stubs --- README.md | 2 +- alpha_todo.txt | 37 +++++++++++++++++++---------- druid/base/button.lua | 42 +++++++++++++++++++++++++++++---- druid/base/input.lua | 15 ++++++++++++ druid/system/druid_instance.lua | 2 +- 5 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 druid/base/input.lua diff --git a/README.md b/README.md index da5806f..298b34e 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ function on_message(self, message_id, message, sender) end function on_input(self, action_id, action) - self.druid:on_input(action_id, action) + return self.druid:on_input(action_id, action) end ``` diff --git a/alpha_todo.txt b/alpha_todo.txt index 6073ea5..65da880 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -1,22 +1,33 @@ -Simple to-do for Druid Alpha 2.0 +Simple to-do for Druid Alpha 0.2.0 -- custom input settings (name of touch, text, etc) -- refactor on_swipe. To on_scroll? Add input priority + +-- High - remove button event and match_event from druid -- add docs for all components -- button polish, actions -- ability to relocalize all locale text nodes +- add hover component +- add druid events/triggers? better callback system - better name for locale component? lang? lang_text? - better scroll size management, check different cases. So implicit now - better grid + scroll management +- button polish, actions +- button add key trigger +- add text component for alpha release +- refactor on_swipe. To on_scroll? Add input priority - add druid settings (add auto_focus input and other stuff) -- better default style, add template for custom style -- add template for user components -- add good examples with template and/or nodes (basic component no use any of them) -- add docs folder for every component with gifs? Solutions - add init/remove stuff for every style in component. How to set custom sprites for button states? - better callbacks for every components -- separate custom data and predefined fields in components? -- try use final druid in real project (FI uses custom druid) +- better default style, add template for custom style +- add docs for all components +- add docs folder for every component with gifs? Solutions - better name for slider component? -- add text component for alpha release \ No newline at end of file +- separate custom data and predefined fields in components? +- unify component api (get/set/to and other general stuff) +- compare with gooey + + +-- Low +- add code template and example for user components +- custom input settings (name of touch, text, etc) +- ability to relocalize all locale text nodes +- add good examples with template and/or nodes (basic component no use any of them) +- try use final druid in real project (FI uses custom druid) (use in 4321?) +- Druid store assest - separate repository with rich components diff --git a/druid/base/button.lua b/druid/base/button.lua index 5367a57..95add22 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,11 +1,6 @@ --- Component to handle basic GUI button -- @module druid.button --- TODO: Add button mode: --- Long tap --- Repeated tap --- Double tap? - local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") @@ -148,4 +143,41 @@ function M.set_click_zone(self, zone) end +-- TODO: implement them all! +--- Set key-code to trigger this button +function M.set_key_trigger(self, key) + +end + + +--- Get key-code to trigger this button +function M.get_key_trigger(self) + +end + + +--- Set usual button callback +function M.set_callback(self, callback) + +end + + +--- Repeat callback always, while holding button +function M.set_hold_callback(self, callback) + +end + + +--- Get doubletap callback on this button +function M.set_double_tap_callback(self, callback) + +end + + +--- Single callbacka after long_tap. No usual callback invoked +function M.set_long_tap_callback(self, callback) + +end + + return M diff --git a/druid/base/input.lua b/druid/base/input.lua new file mode 100644 index 0000000..3b05fb8 --- /dev/null +++ b/druid/base/input.lua @@ -0,0 +1,15 @@ +--- Druid input text component +-- @local unimplemented +-- @module druid.input + +local component = require("druid.component") + +local M = component.create("input") + + +function M.init(self, node, callback, click_node) + self.style = self:get_style() +end + + +return M diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 4a524fe..d3800ae 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -33,7 +33,7 @@ local slider = require("druid.base.slider") local checkbox = require("druid.base.checkbox") local checkbox_group = require("druid.base.checkbox_group") local radio_group = require("druid.base.radio_group") --- local input - require("druid.base.input") +local input - require("druid.base.input") -- local infinity_scroll = require("druid.base.infinity_scroll") local progress_rich = require("druid.rich.progress_rich") From 0dd37a03cd39ff8dba84db847a57ff2e85382261 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 14:49:22 +0300 Subject: [PATCH 104/136] Add simple druid event library --- druid/event.lua | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 druid/event.lua diff --git a/druid/event.lua b/druid/event.lua new file mode 100644 index 0000000..f84ac00 --- /dev/null +++ b/druid/event.lua @@ -0,0 +1,37 @@ +--- Lua event small library + +local class = require("druid.system.middleclass") + +local M = class("druid.event") + + +function M.initialize(self) + self._callbacks = {} +end + + +function M.subscribe(self, callback) + assert(type(callback) == "function", "Callback should be function") + + table.insert(self._callbacks, callback) +end + + +function M.unsubscribe(self, callback) + for i = 1, #self._callbacks do + if self._callbacks[i] == callback then + table.remove(self._callbacks, i) + return + end + end +end + + +function M.trigger(self, ...) + for i = 1, #self._callbacks do + self._callbacks[i](...) + end +end + + +return M From 3e30fd44172fb9ef617ebfc93eda5747015ea75d Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 15:09:29 +0300 Subject: [PATCH 105/136] Remove match_event from druid, add hover component --- druid/base/back_handler.lua | 6 +-- druid/base/blocker.lua | 5 ++- druid/base/button.lua | 6 ++- druid/base/hover.lua | 76 +++++++++++++++++++++++++++++++++ druid/system/druid_instance.lua | 37 +++++++++------- 5 files changed, 109 insertions(+), 21 deletions(-) create mode 100644 druid/base/hover.lua diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 67078c5..70cd190 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -13,7 +13,6 @@ local M = component.create("back_handler", { const.ON_INPUT }) -- @tparam callback callback On back button -- @tparam[opt] params Callback argument function M.init(self, callback, params) - self.event = const.ACTION_BACK self.callback = callback self.params = params end @@ -24,11 +23,12 @@ end -- @tparam string action_id on_input action id -- @tparam table action on_input action function M.on_input(self, action_id, action) - if action[const.RELEASED] then + if action_id == const.ACTION_BACK and action[const.RELEASED] then self.callback(self:get_context(), self.params) + return true end - return true + return false end diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 5c48263..54d41b3 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -10,11 +10,14 @@ local M = component.create("blocker", { const.ON_SWIPE }) function M.init(self, node) self.node = self:get_node(node) - self.event = const.ACTION_TOUCH end function M.on_input(self, action_id, action) + if action_id ~= const.ACTION_TOUCH then + return false + end + if not helper.is_enabled(self.node) then return false end diff --git a/druid/base/button.lua b/druid/base/button.lua index 95add22..85d68dd 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -22,8 +22,6 @@ function M.init(self, node, callback, params, anim_node, event) self.style = self:get_style() self.node = self:get_node(node) - -- TODO: match event inside on_input? - self.event = const.ACTION_TOUCH self.anim_node = anim_node and helper:get_node(anim_node) or self.node -- TODO: rename to start_scale self.scale_from = gui.get_scale(self.anim_node) @@ -67,6 +65,10 @@ end function M.on_input(self, action_id, action) + if action_id ~= const.ACTION_TOUCH then + return false + end + if not helper.is_enabled(self.node) then return false end diff --git a/druid/base/hover.lua b/druid/base/hover.lua new file mode 100644 index 0000000..0015f35 --- /dev/null +++ b/druid/base/hover.lua @@ -0,0 +1,76 @@ +--- Component to handle hover node interaction +-- @module druid.input + +local Event = require("druid.event") +local const = require("druid.const") +local helper = require("druid.helper") +local component = require("druid.component") + +local M = component.create("hover", { const.ON_INPUT }) + + +--- Component init function +-- @function hover:init +-- @tparam table self Component instance +-- @tparam node node Gui node +-- @tparam function on_hover_callback Hover callback +function M.init(self, node, on_hover_callback) + self.style = self:get_style() + self.node = self:get_node(node) + + self._is_hovered = false + self.on_hover = Event() + if on_hover_callback then + self.on_hover:subscribe(on_hover_callback) + end +end + + +local function set_hover(self, state) + if self._is_hovered ~= state then + self._is_hovered = state + self.on_hover:trigger(state) + end +end + + +function M.on_input(self, action_id, action) + if action_id ~= const.ACTION_TOUCH then + return + end + + if not helper.is_enabled(self.node) then + return false + end + + local is_pick = gui.pick_node(self.node, action.x, action.y) + + if not is_pick then + set_hover(self, false) + return false + end + + if action.released then + set_hover(self, false) + else + set_hover(self, true) + end +end + + +function M.on_swipe(self) + set_hover(self, false) +end + + +--- Strict button click area. Useful for +-- no click events outside stencil node +-- @function button:set_click_zone +-- @tparam table self Component instance +-- @tparam node zone Gui node +function M.set_click_zone(self, zone) + self.click_zone = self:get_node(zone) +end + + +return M diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index d3800ae..9907edd 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -4,6 +4,7 @@ -- @see druid.button -- @see druid.blocker -- @see druid.back_handler +-- @see druid.input -- @see druid.text -- @see druid.locale -- @see druid.timer @@ -23,6 +24,7 @@ local class = require("druid.system.middleclass") local button = require("druid.base.button") local blocker = require("druid.base.blocker") local back_handler = require("druid.base.back_handler") +local hover = require("druid.base.hover") local text = require("druid.base.text") local locale = require("druid.base.locale") local timer = require("druid.base.timer") @@ -33,7 +35,7 @@ local slider = require("druid.base.slider") local checkbox = require("druid.base.checkbox") local checkbox_group = require("druid.base.checkbox_group") local radio_group = require("druid.base.radio_group") -local input - require("druid.base.input") +local input = require("druid.base.input") -- local infinity_scroll = require("druid.base.infinity_scroll") local progress_rich = require("druid.rich.progress_rich") @@ -94,19 +96,6 @@ local function notify_input_on_swipe(self) end -local function match_event(action_id, events) - if type(events) == const.TABLE then - for i = 1, #events do - if action_id == events[i] then - return true - end - end - else - return action_id == events - end -end - - --- Druid class constructor -- @function druid:initialize -- @tparam context table Druid context. Usually it is self of script @@ -200,7 +189,7 @@ function Druid.on_input(self, action_id, action) if components then for i = #components, 1, -1 do local v = components[i] - if match_event(action_id, v.event) and v:on_input(action_id, action) then + if v:on_input(action_id, action) then return true end end @@ -262,6 +251,15 @@ function Druid.new_back_handler(self, ...) end +--- Create hover basic component +-- @function druid:new_hover +-- @tparam args ... hover init args +-- @treturn Component hover component +function Druid.new_hover(self, ...) + return Druid.create(self, hover, ...) +end + + --- Create text basic component -- @function druid:new_text -- @tparam args ... text init args @@ -334,6 +332,15 @@ function Druid.new_checkbox(self, ...) end +--- Create input basic component +-- @function druid:new_input +-- @tparam args ... input init args +-- @treturn Component input component +function Druid.new_input(self, ...) + return Druid.create(self, input, ...) +end + + --- Create checkbox_group basic component -- @function druid:new_checkbox_group -- @tparam args ... checkbox_group init args From 2c0b100ab7e4fdea95ac50850694f4cab16452c8 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 15:19:18 +0300 Subject: [PATCH 106/136] Move hover logic from button to hover component --- druid/base/button.lua | 33 +++++++++++---------------------- druid/base/hover.lua | 5 +++-- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index 85d68dd..36bc2d4 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -8,6 +8,14 @@ local component = require("druid.component") local M = component.create("button", { const.ON_INPUT }) +local function on_button_hover(self, hover_state) + if not self.style.on_hover then + return + end + + self.style.on_hover(self, self.anim_node, hover_state) +end + --- Component init function -- @function button:init -- @tparam table self Component instance @@ -19,6 +27,7 @@ local M = component.create("button", { const.ON_INPUT }) function M.init(self, node, callback, params, anim_node, event) assert(callback, "Button should have callback. To block input on zone use blocker component") + self.druid = self:get_druid() self.style = self:get_style() self.node = self:get_node(node) @@ -29,20 +38,12 @@ function M.init(self, node, callback, params, anim_node, event) self.callback = callback self.params = params self.hover_anim = self.style.IS_HOVER + self.hover = self.druid:new_hover(node, self, on_button_hover) + self.click_zone = nil end -local function set_hover(self, state) - if self._is_hovered ~= state then - if self.style.on_hover then - self.style.on_hover(self, self.anim_node, state) - end - self._is_hovered = state - end -end - - local function on_button_release(self) if not self.disabled then if not self.stub and self.can_action then @@ -51,8 +52,6 @@ local function on_button_release(self) self.style.on_click(self, self.anim_node) end self.callback(self:get_context(), self.params, self) - else - set_hover(self, false) end return true else @@ -81,7 +80,6 @@ function M.on_input(self, action_id, action) if not is_pick then -- Can't interact, if touch outside of button self.can_action = false - set_hover(self, false) return false end @@ -93,10 +91,7 @@ function M.on_input(self, action_id, action) end if action.released then - set_hover(self, false) return on_button_release(self) - else - set_hover(self, true) end return not self.disabled @@ -104,17 +99,11 @@ end function M.on_swipe(self) - -- unhover button if start swipe self.can_action = false - set_hover(self, false) end function M.set_enabled(self, state) - -- if self.disabled == state then - -- return - -- end - self.disabled = not state if self.style.on_set_enabled then self.style.on_set_enabled(self, self.node, state) diff --git a/druid/base/hover.lua b/druid/base/hover.lua index 0015f35..dbf5016 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -14,11 +14,12 @@ local M = component.create("hover", { const.ON_INPUT }) -- @tparam table self Component instance -- @tparam node node Gui node -- @tparam function on_hover_callback Hover callback -function M.init(self, node, on_hover_callback) +function M.init(self, node, context, on_hover_callback) self.style = self:get_style() self.node = self:get_node(node) self._is_hovered = false + self.context = context self.on_hover = Event() if on_hover_callback then self.on_hover:subscribe(on_hover_callback) @@ -29,7 +30,7 @@ end local function set_hover(self, state) if self._is_hovered ~= state then self._is_hovered = state - self.on_hover:trigger(state) + self.on_hover:trigger(self.context, state) end end From 640753c080343d6a5795f7434bd02368d073853e Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 15:24:52 +0300 Subject: [PATCH 107/136] Rename locale -> lang_text --- alpha_todo.txt | 8 +++-- druid/base/button.lua | 39 ++++++++++++------------ druid/base/{locale.lua => lang_text.lua} | 4 +-- druid/system/druid_instance.lua | 16 +++++----- example/kenney/gui/main/main.gui_script | 2 +- example/kenney/page/main.lua | 18 +++++------ example/kenney/page/texts.lua | 2 +- 7 files changed, 46 insertions(+), 43 deletions(-) rename druid/base/{locale.lua => lang_text.lua} (90%) diff --git a/alpha_todo.txt b/alpha_todo.txt index 65da880..e5c646a 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -2,9 +2,9 @@ Simple to-do for Druid Alpha 0.2.0 -- High -- remove button event and match_event from druid -- add hover component -- add druid events/triggers? better callback system ++ remove button event and match_event from druid ++ add hover component ++ add druid events/triggers? better callback system - better name for locale component? lang? lang_text? - better scroll size management, check different cases. So implicit now - better grid + scroll management @@ -22,6 +22,7 @@ Simple to-do for Druid Alpha 0.2.0 - separate custom data and predefined fields in components? - unify component api (get/set/to and other general stuff) - compare with gooey +- button and hover click restriction zone? -- Low @@ -31,3 +32,4 @@ Simple to-do for Druid Alpha 0.2.0 - add good examples with template and/or nodes (basic component no use any of them) - try use final druid in real project (FI uses custom druid) (use in 4321?) - Druid store assest - separate repository with rich components +- ability to control buttons via controller. Select it by cursor (d-pad) diff --git a/druid/base/button.lua b/druid/base/button.lua index 36bc2d4..d0de518 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -16,6 +16,26 @@ local function on_button_hover(self, hover_state) self.style.on_hover(self, self.anim_node, hover_state) end + +local function on_button_release(self) + if not self.disabled then + if not self.stub and self.can_action then + self.can_action = false + if self.style.on_click then + self.style.on_click(self, self.anim_node) + end + self.callback(self:get_context(), self.params, self) + end + return true + else + if self.style.on_click_disabled then + self.style.on_click_disabled(self, self.anim_node) + end + return false + end +end + + --- Component init function -- @function button:init -- @tparam table self Component instance @@ -44,25 +64,6 @@ function M.init(self, node, callback, params, anim_node, event) end -local function on_button_release(self) - if not self.disabled then - if not self.stub and self.can_action then - self.can_action = false - if self.style.on_click then - self.style.on_click(self, self.anim_node) - end - self.callback(self:get_context(), self.params, self) - end - return true - else - if self.style.on_click_disabled then - self.style.on_click_disabled(self, self.anim_node) - end - return false - end -end - - function M.on_input(self, action_id, action) if action_id ~= const.ACTION_TOUCH then return false diff --git a/druid/base/locale.lua b/druid/base/lang_text.lua similarity index 90% rename from druid/base/locale.lua rename to druid/base/lang_text.lua index d419f01..760190e 100644 --- a/druid/base/locale.lua +++ b/druid/base/lang_text.lua @@ -1,12 +1,12 @@ --- Component to handle all GUI texts -- Good working with localization system --- @module druid.locale +-- @module druid.lang_text local const = require("druid.const") local settings = require("druid.system.settings") local component = require("druid.component") -local M = component.create("locale", { const.ON_CHANGE_LANGUAGE }) +local M = component.create("lang_text", { const.ON_CHANGE_LANGUAGE }) function M.init(self, node, lang_id, no_adjust) diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 9907edd..08e790a 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -6,7 +6,7 @@ -- @see druid.back_handler -- @see druid.input -- @see druid.text --- @see druid.locale +-- @see druid.lang_text -- @see druid.timer -- @see druid.progress -- @see druid.grid @@ -26,7 +26,7 @@ local blocker = require("druid.base.blocker") local back_handler = require("druid.base.back_handler") local hover = require("druid.base.hover") local text = require("druid.base.text") -local locale = require("druid.base.locale") +local lang_text = require("druid.base.lang_text") local timer = require("druid.base.timer") local progress = require("druid.base.progress") local grid = require("druid.base.grid") @@ -269,12 +269,12 @@ function Druid.new_text(self, ...) end ---- Create locale basic component --- @function druid:new_locale --- @tparam args ... locale init args --- @treturn Component locale component -function Druid.new_locale(self, ...) - return Druid.create(self, locale, ...) +--- Create lang_text basic component +-- @function druid:new_lang_text +-- @tparam args ... lang_text init args +-- @treturn Component lang_text component +function Druid.new_lang_text(self, ...) + return Druid.create(self, lang_text, ...) end diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 0f9fed2..357e8b3 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -29,7 +29,7 @@ end local function init_top_panel(self) self.druid:new_button("button_left/button", on_control_button, -1) self.druid:new_button("button_right/button", on_control_button, 1) - self.header = self.druid:new_locale("text_header", "main_page") + self.header = self.druid:new_lang_text("text_header", "main_page") end diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index cefd09d..e4d719f 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -26,16 +26,16 @@ end local function setup_texts(self) - self.druid:new_locale("text_button", "ui_section_button") - self.druid:new_locale("text_text", "ui_section_text") - self.druid:new_locale("text_timer", "ui_section_timer") - self.druid:new_locale("text_progress", "ui_section_progress") - self.druid:new_locale("text_slider", "ui_section_slider") - self.druid:new_locale("text_radio", "ui_section_radio") - self.druid:new_locale("text_checkbox", "ui_section_checkbox") + self.druid:new_lang_text("text_button", "ui_section_button") + self.druid:new_lang_text("text_text", "ui_section_text") + self.druid:new_lang_text("text_timer", "ui_section_timer") + self.druid:new_lang_text("text_progress", "ui_section_progress") + self.druid:new_lang_text("text_slider", "ui_section_slider") + self.druid:new_lang_text("text_radio", "ui_section_radio") + self.druid:new_lang_text("text_checkbox", "ui_section_checkbox") - self.druid:new_locale("text_translated", "ui_text_example") - self.druid:new_locale("text_button_lang", "ui_text_change_lang") + self.druid:new_lang_text("text_translated", "ui_text_example") + self.druid:new_lang_text("text_button_lang", "ui_text_change_lang") self.druid:new_text("text_simple", "Simple") end diff --git a/example/kenney/page/texts.lua b/example/kenney/page/texts.lua index c1386ce..d1d459d 100644 --- a/example/kenney/page/texts.lua +++ b/example/kenney/page/texts.lua @@ -19,7 +19,7 @@ local function setup_texts(self) self.druid:new_text("text_multiline", "Simple multiline text with smth") local anchoring = self.druid:new_text("text_anchoring", "Anchoring") self.druid:new_text("text_no_adjust", "Without adjust size", true) - self.druid:new_locale("text_locale", "ui_text_example") + self.druid:new_lang_text("text_locale", "ui_text_example") local big_text = "Check max size" local width = self.druid:new_text("text_max_width", big_text) From 3ae5011bde462c24fc199163da66bda808113fe4 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 15:44:20 +0300 Subject: [PATCH 108/136] Liveupdate 165 fixes --- alpha_todo.txt | 18 +++++++++--------- liveupdate.settings | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 liveupdate.settings diff --git a/alpha_todo.txt b/alpha_todo.txt index e5c646a..ac659ed 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -5,24 +5,24 @@ Simple to-do for Druid Alpha 0.2.0 + remove button event and match_event from druid + add hover component + add druid events/triggers? better callback system -- better name for locale component? lang? lang_text? -- better scroll size management, check different cases. So implicit now -- better grid + scroll management -- button polish, actions -- button add key trigger -- add text component for alpha release ++ better name for locale component? lang? lang_text? ++ better name for slider component? Slider is ok - refactor on_swipe. To on_scroll? Add input priority -- add druid settings (add auto_focus input and other stuff) +- separate custom data and predefined fields in components? - add init/remove stuff for every style in component. How to set custom sprites for button states? +- button add key trigger +- button polish, actions +- add druid settings (add auto_focus input and other stuff) - better callbacks for every components - better default style, add template for custom style - add docs for all components - add docs folder for every component with gifs? Solutions -- better name for slider component? -- separate custom data and predefined fields in components? - unify component api (get/set/to and other general stuff) +- add text component for alpha release - compare with gooey - button and hover click restriction zone? +- better scroll size management, check different cases. So implicit now +- better grid + scroll management -- Low diff --git a/liveupdate.settings b/liveupdate.settings new file mode 100644 index 0000000..10a44f5 --- /dev/null +++ b/liveupdate.settings @@ -0,0 +1,6 @@ +[liveupdate] +mode = Zip +zip-filepath = /Users/insality/code/defold/defold-eva/dist +supported-versions = "1.0.0" +publickey = /Users/insality/code/provisions/liveupdate/public.der +privatekey = /Users/insality/code/provisions/liveupdate/private.der \ No newline at end of file From 44016bc4f3fac5e3e84e9ea8e4c21836b397c07e Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 22 Feb 2020 23:54:26 +0300 Subject: [PATCH 109/136] Remove progress_rich component, move it to separate repository (druid-assets) --- druid/rich/progress_rich.lua | 72 --------------------------------- druid/system/druid_instance.lua | 10 ----- 2 files changed, 82 deletions(-) delete mode 100644 druid/rich/progress_rich.lua diff --git a/druid/rich/progress_rich.lua b/druid/rich/progress_rich.lua deleted file mode 100644 index fe39a9b..0000000 --- a/druid/rich/progress_rich.lua +++ /dev/null @@ -1,72 +0,0 @@ ---- Component for rich progress component --- @module druid.progress_rich - -local component = require("druid.component") - -local M = component.create("progress_rich") - - -function M.init(self, name, red, green, key) - self.druid = self:get_druid() - self.style = self:get_style() - self.red = self.druid:new_progress(red, key) - self.green = self.druid:new_progress(green, key) - self.fill = self.druid:new_progress(name, key) -end - - ---- Instant fill progress bar to value --- @function progress_rich:set_to --- @tparam table self Component instance --- @tparam number value Progress bar value, from 0 to 1 -function M.set_to(self, value) - self.red:set_to(value) - self.green:set_to(value) - self.fill:set_to(value) -end - - ---- Empty a progress bar --- @function progress_rich:empty --- @tparam table self Component instance -function M.empty(self) - self.red:empty() - self.green:empty() - self.fill:empty() -end - - ---- Start animation of a progress bar --- @function progress_rich:to --- @tparam table self Component instance --- @tparam number to value between 0..1 --- @tparam[opt] function callback Callback on animation ends -function M.to(self, to, callback) - if self.timer then - timer.cancel(self.timer) - self.timer = nil - end - - if self.fill.last_value < to then - self.red:to(self.fill.last_value) - self.green:to(to, function() - self.timer = timer.delay(self.style.DELAY, false, function() - self.red:to(to) - self.fill:to(to, callback) - end) - end) - end - - if self.fill.last_value > to then - self.green:to(self.red.last_value) - self.fill:to(to, function() - self.timer = timer.delay(self.style.DELAY, false, function() - self.green:to(to) - self.red:to(to, callback) - end) - end) - end -end - - -return M diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 08e790a..684c515 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -37,7 +37,6 @@ local checkbox_group = require("druid.base.checkbox_group") local radio_group = require("druid.base.radio_group") local input = require("druid.base.input") -- local infinity_scroll = require("druid.base.infinity_scroll") -local progress_rich = require("druid.rich.progress_rich") -- @classmod Druid local Druid = class("druid.druid_instance") @@ -359,13 +358,4 @@ function Druid.new_radio_group(self, ...) end ---- Create progress_rich basic component --- @function druid:new_progress_rich --- @tparam args ... progress_rich init args --- @treturn Component progress_rich component -function Druid.new_progress_rich(self, ...) - return Druid.create(self, progress_rich, ...) -end - - return Druid From c2b65eb4e20b22db8719b245854629b11fe379aa Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 23 Feb 2020 12:17:25 +0300 Subject: [PATCH 110/136] Input priority little rework? Remove on_swipe --- README.md | 8 ++--- alpha_todo.txt | 20 ++++++------ druid/base/blocker.lua | 2 +- druid/base/button.lua | 9 +++++- druid/base/hover.lua | 2 +- druid/base/scroll.lua | 2 +- druid/base/slider.lua | 2 +- druid/const.lua | 49 ++++++++---------------------- druid/system/druid_instance.lua | 54 ++++++++++++++------------------- 9 files changed, 61 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 298b34e..60931e1 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ function M.update(self, dt) end --- Call only if exist interest: const.ON_INPUT or const.ON_SWIPE +-- Call only if exist interest: const.ON_INPUT or const.ON_INPUT_HIGH function M.on_input(self, action_id, action) end @@ -123,8 +123,8 @@ function M.on_message(self, message_id, message, sender) end --- Call only if swipe was started on another component (ex. scroll) -function M.on_swipe(self) +-- Call if input was interrupt by previous components (ex. scroll) +function M.on_input_interrupt(self) end @@ -178,7 +178,7 @@ _TODO_ - update - on_input - on_message -- on_swipe +- on_input_interrupt - setup_component - get_style - set_style diff --git a/alpha_todo.txt b/alpha_todo.txt index ac659ed..aae9b80 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -7,29 +7,29 @@ Simple to-do for Druid Alpha 0.2.0 + add druid events/triggers? better callback system + better name for locale component? lang? lang_text? + better name for slider component? Slider is ok ++ Druid store assets - separate repository with rich components (progress_rich migrate) - refactor on_swipe. To on_scroll? Add input priority - separate custom data and predefined fields in components? - add init/remove stuff for every style in component. How to set custom sprites for button states? +- unify component api (get/set/to and other general stuff) +- add druid settings (add auto_focus input and other stuff) - button add key trigger - button polish, actions -- add druid settings (add auto_focus input and other stuff) -- better callbacks for every components -- better default style, add template for custom style -- add docs for all components -- add docs folder for every component with gifs? Solutions -- unify component api (get/set/to and other general stuff) -- add text component for alpha release -- compare with gooey - button and hover click restriction zone? +- better callbacks for every components - better scroll size management, check different cases. So implicit now - better grid + scroll management +- better default style, add template for custom style +- add text component for alpha release +- compare with gooey +- add docs for all components +- add docs folder for every component with gifs? Solutions -- Low - add code template and example for user components - custom input settings (name of touch, text, etc) -- ability to relocalize all locale text nodes - add good examples with template and/or nodes (basic component no use any of them) - try use final druid in real project (FI uses custom druid) (use in 4321?) -- Druid store assest - separate repository with rich components +- ability to relocalize all locale text nodes - ability to control buttons via controller. Select it by cursor (d-pad) diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 54d41b3..d03fc3f 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -5,7 +5,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local M = component.create("blocker", { const.ON_SWIPE }) +local M = component.create("blocker", { const.ON_INPUT_HIGH }) function M.init(self, node) diff --git a/druid/base/button.lua b/druid/base/button.lua index d0de518..618663f 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,6 +1,7 @@ --- Component to handle basic GUI button -- @module druid.button +local Event = require("druid.event") local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") @@ -60,6 +61,12 @@ function M.init(self, node, callback, params, anim_node, event) self.hover_anim = self.style.IS_HOVER self.hover = self.druid:new_hover(node, self, on_button_hover) + -- Event stubs + self.on_click = Event() + self.on_hold_click = Event() + self.on_long_click = Event() + self.on_double_click = Event() + self.click_zone = nil end @@ -99,7 +106,7 @@ function M.on_input(self, action_id, action) end -function M.on_swipe(self) +function M.on_input_interrupt(self) self.can_action = false end diff --git a/druid/base/hover.lua b/druid/base/hover.lua index dbf5016..71a15bc 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -59,7 +59,7 @@ function M.on_input(self, action_id, action) end -function M.on_swipe(self) +function M.on_input_interrupt(self) set_hover(self, false) end diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index a00459a..b5382ca 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -5,7 +5,7 @@ local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.component") -local M = component.create("scroll", { const.ON_UPDATE, const.ON_SWIPE }) +local M = component.create("scroll", { const.ON_UPDATE, const.ON_INPUT_HIGH }) -- Global on all scrolls diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 5b8d691..80a8534 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -5,7 +5,7 @@ local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.component") -local M = component.create("slider", { const.ON_SWIPE }) +local M = component.create("slider", { const.ON_INPUT_HIGH }) local function on_change_value(self) diff --git a/druid/const.lua b/druid/const.lua index ace87b6..fd2c121 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -19,14 +19,13 @@ M.ZERO = "0" M.ALL = "all" ---- Interests +--- Component Interests M.ON_MESSAGE = hash("on_message") M.ON_UPDATE = hash("on_update") - - --- Input -M.ON_SWIPE = hash("on_swipe") +M.ON_INPUT_HIGH = hash("on_input_high") M.ON_INPUT = hash("on_input") +M.ON_CHANGE_LANGUAGE = hash("on_change_language") +M.ON_LAYOUT_CHANGED = hash("on_layout_changed") M.PIVOTS = { @@ -42,43 +41,21 @@ M.PIVOTS = { } -M.SIDE = { - X = "x", - Y = "y" -} - - -M.UI_INPUT = { - [M.ON_SWIPE] = true, - [M.ON_INPUT] = true -} - --- UI messages -M.ON_CHANGE_LANGUAGE = hash("on_change_language") -M.ON_LAYOUT_CHANGED = hash("on_layout_changed") - - M.SPECIFIC_UI_MESSAGES = { [M.ON_CHANGE_LANGUAGE] = "on_change_language", [M.ON_LAYOUT_CHANGED] = "on_layout_changed" } --- Basic druid components -M.COMPONENTS = { - BUTTON = "button", - BLOCKER = "blocker", - BACK_HANDLER = "back_handler", - TEXT = "text", - LOCALE = "locale", - TIMER = "timer", - PROGRESS = "progress", - GRID = "grid", - SCROLL = "scroll", - SLIDER = "slider", - CHECKBOX = "checkbox", - CHECKBOX_GROUP = "checkbox_group", - RADIO_GROUP = "radio_group", +M.UI_INPUT = { + [M.ON_INPUT_HIGH] = true, + [M.ON_INPUT] = true +} + + +M.SIDE = { + X = "x", + Y = "y" } diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 684c515..1a217ca 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -82,16 +82,24 @@ local function create(self, instance_class) end -local function notify_input_on_swipe(self) - if self.components[const.ON_INPUT] then - local len = #self.components[const.ON_INPUT] - for i = len, 1, -1 do - local comp = self.components[const.ON_INPUT][i] - if comp.on_swipe then - comp:on_swipe() +local function process_input(action_id, action, components, is_input_consumed) + if not components then + return is_input_consumed + end + + for i = #components, 1, -1 do + local component = components[i] + + if not is_input_consumed then + is_input_consumed = component:on_input(action_id, action) + else + if component.on_input_interrupt then + component:on_input_interrupt() end end end + + return is_input_consumed end @@ -169,33 +177,15 @@ end -- @tparam hash action_id Action_id from on_input -- @tparam table action Action from on_input function Druid.on_input(self, action_id, action) - -- TODO: расписать отличия ON_SWIPE и ON_INPUT - -- Почему-то некоторые используют ON_SWIPE, а логичнее ON_INPUT? (blocker, slider) - local components = self.components[const.ON_SWIPE] - if components then - local result - for i = #components, 1, -1 do - local v = components[i] - result = result or v:on_input(action_id, action) - end - if result then - notify_input_on_swipe(self) - return true - end - end + local is_input_consumed = false - components = self.components[const.ON_INPUT] - if components then - for i = #components, 1, -1 do - local v = components[i] - if v:on_input(action_id, action) then - return true - end - end - return false - end + is_input_consumed = process_input(action_id, action, + self.components[const.ON_INPUT_HIGH], is_input_consumed) - return false + is_input_consumed = process_input(action_id, action, + self.components[const.ON_INPUT], is_input_consumed) + + return is_input_consumed end From cb6fd3038a68f3bb59e26d4329dc8c43646450cc Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 23 Feb 2020 13:00:59 +0300 Subject: [PATCH 111/136] Add examples to component docs --- alpha_todo.txt | 3 ++- config.ld | 6 +++++- druid/base/button.lua | 11 +++++++++++ druid/druid.lua | 5 +++++ druid/event.lua | 2 ++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/alpha_todo.txt b/alpha_todo.txt index aae9b80..552c412 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -8,7 +8,7 @@ Simple to-do for Druid Alpha 0.2.0 + better name for locale component? lang? lang_text? + better name for slider component? Slider is ok + Druid store assets - separate repository with rich components (progress_rich migrate) -- refactor on_swipe. To on_scroll? Add input priority ++ refactor on_swipe. To on_scroll? Add input priority - separate custom data and predefined fields in components? - add init/remove stuff for every style in component. How to set custom sprites for button states? - unify component api (get/set/to and other general stuff) @@ -24,6 +24,7 @@ Simple to-do for Druid Alpha 0.2.0 - compare with gooey - add docs for all components - add docs folder for every component with gifs? Solutions +- remove component autoremove all children component -- Low diff --git a/config.ld b/config.ld index 43d3a05..b9a95cd 100644 --- a/config.ld +++ b/config.ld @@ -2,6 +2,10 @@ project='Druid' title='Defold Druid UI Library' description='Documentation for Druid Library' file={"./druid"} +package='druid' +sort=true dir='./docs' -style='!pale' +style='!fixed' +format='discount' +use_markdown_titles=true no_space_before_args=true \ No newline at end of file diff --git a/druid/base/button.lua b/druid/base/button.lua index 618663f..22f55b2 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,6 +1,17 @@ --- Component to handle basic GUI button -- @module druid.button +--- Component events +-- @tfield druid_event on_click +-- @tfield druid_event on_hold_click +-- @tfield druid_event on_long_click +-- @tfield druid_event on_double_click +-- @table events + +--- Component fields +-- @tfield node Main node +-- @table fields + local Event = require("druid.event") local const = require("druid.const") local helper = require("druid.helper") diff --git a/druid/druid.lua b/druid/druid.lua index 0003720..0716805 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -7,6 +7,11 @@ -- to how to do your custom complex components to -- separate UI game logic to small files -- +-- require("druid.druid") +-- function init(self) +-- self.druid = druid.new(self) +-- end +-- -- @module druid local const = require("druid.const") diff --git a/druid/event.lua b/druid/event.lua index f84ac00..baccb8e 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -1,7 +1,9 @@ --- Lua event small library +-- @module druid_event local class = require("druid.system.middleclass") +-- @class DruidEvent local M = class("druid.event") From 5c576e6059e8498f54d606dbe25f9a95c85736f8 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 23 Feb 2020 13:01:15 +0300 Subject: [PATCH 112/136] Update ldoc --- docs/index.html | 25 +- docs/{ldoc_pale.css => ldoc_fixed.css} | 14 +- docs/modules/component.html | 544 ++++++------ docs/modules/druid.back_handler.html | 19 +- docs/modules/druid.blocker.html | 19 +- docs/modules/druid.button.html | 265 +++++- docs/modules/druid.checkbox.html | 19 +- docs/modules/druid.checkbox_group.html | 19 +- docs/modules/druid.grid.html | 18 +- .../{helper.html => druid.helper.html} | 154 +++- docs/modules/druid.html | 94 ++- ...id.progress_rich.html => druid.input.html} | 86 +- ...druid.locale.html => druid.lang_text.html} | 21 +- docs/modules/druid.progress.html | 183 +++-- docs/modules/druid.radio_group.html | 19 +- docs/modules/druid.scroll.html | 177 ++-- docs/modules/druid.slider.html | 19 +- docs/modules/druid.text.html | 69 +- docs/modules/druid.timer.html | 55 +- docs/modules/{const.html => druid_event.html} | 86 +- docs/modules/druid_instance.html | 775 +++++++++--------- docs/modules/helper.formats.html | 191 ----- 22 files changed, 1493 insertions(+), 1378 deletions(-) rename docs/{ldoc_pale.css => ldoc_fixed.css} (95%) rename docs/modules/{helper.html => druid.helper.html} (70%) rename docs/modules/{druid.progress_rich.html => druid.input.html} (61%) rename docs/modules/{druid.locale.html => druid.lang_text.html} (87%) rename docs/modules/{const.html => druid_event.html} (56%) delete mode 100644 docs/modules/helper.formats.html diff --git a/docs/index.html b/docs/index.html index 193baec..45b2665 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -37,7 +37,8 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • -
  • druid.locale
  • +
  • druid.input
  • +
  • druid.lang_text
  • druid.progress
  • druid.radio_group
  • druid.scroll
  • @@ -46,8 +47,8 @@
  • druid.timer
  • component
  • druid
  • -
  • helper
  • -
  • druid.progress_rich
  • +
  • druid_event
  • +
  • druid.helper
  • druid_instance
  • @@ -85,7 +86,11 @@ Component to handle placing components by row and columns. - druid.locale + druid.input + Component to handle hover node interaction + + + druid.lang_text Component to handle all GUI texts Good working with localization system @@ -123,12 +128,12 @@ Druid UI Library. - helper - Text node or icon node can be nil + druid_event + Lua event small library - druid.progress_rich - Component for rich progress component + druid.helper + Text node or icon node can be nil druid_instance @@ -140,7 +145,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/ldoc_pale.css b/docs/ldoc_fixed.css similarity index 95% rename from docs/ldoc_pale.css rename to docs/ldoc_fixed.css index 4202bd3..9b0fc00 100644 --- a/docs/ldoc_pale.css +++ b/docs/ldoc_fixed.css @@ -147,16 +147,22 @@ table.index td { text-align: left; vertical-align: top; } #main { background-color:#FFFFFF; // #f0f0f0; - //border-left: 2px solid #cccccc; + border-left: 1px solid #cccccc; } #navigation { + position: fixed; + top: 0; + left: 0; float: left; width: 14em; vertical-align: top; background-color:#FFFFFF; // #f0f0f0; border-right: 2px solid #cccccc; overflow: visible; + overflow-y: scroll; + height: 100%; + padding-left: 1em; } #navigation h2 { @@ -165,7 +171,6 @@ table.index td { text-align: left; vertical-align: top; } color:#000000; text-align: left; padding:0.2em; - //border-top:1px solid #dddddd; border-bottom:1px solid #dddddd; } @@ -189,6 +194,7 @@ table.index td { text-align: left; vertical-align: top; } #content { margin-left: 14em; padding: 1em; + padding-left: 2em; width: 700px; border-left: 2px solid #cccccc; // border-right: 2px solid #cccccc; @@ -197,8 +203,10 @@ table.index td { text-align: left; vertical-align: top; } #about { clear: both; - padding: 5px; + padding-left: 1em; + margin-left: 14em; // avoid the damn sidebar! border-top: 2px solid #cccccc; + border-left: 2px solid #cccccc; background-color: #ffffff; } diff --git a/docs/modules/component.html b/docs/modules/component.html index 5923cd0..d0b3851 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -64,59 +65,58 @@

    Module component

    Basic class for all Druid components.

    -

    - To create you component, use `component.create`

    +

    To create you component, use component.create

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + +
    setup_component(table, table)Setup component context and his style table
    get_style()Get current component style table
    set_style(style)Set current component style table
    get_template()Get current component template name
    set_template(template)Set current component template name
    get_nodes()Get current component nodes
    set_nodes(nodes)Set current component nodesComponent.create(name, interest)Create new component.
    get_context() Get current component context
    set_context(context)Set current component contextget_druid()Return druid with context of calling component.
    get_interests() Get current component interests
    get_druid()Return druid with context of calling component.get_nodes()Get current component nodes
    Component.create(name, interest)Create new component.get_style()Get current component style table
    get_template()Get current component template name
    set_context(context)Set current component context
    set_nodes(nodes)Set current component nodes
    set_style(style)Set current component style table
    set_template(template)Set current component template name
    setup_component(table, table)Setup component context and his style table
    @@ -127,6 +127,237 @@

    Functions

    +
    + + Component.create(name, interest) +
    +
    + Create new component. It will inheritance from basic + druid component. + + +

    Parameters:

    +
      +
    • name + string + Component name +
    • +
    • interest + table + List of component's interest +
    • +
    + + + + + +
    +
    + + get_context() +
    +
    + Get current component context + + + +

    Returns:

    +
      + + table + Component context +
    + + + + +
    +
    + + get_druid() +
    +
    + Return druid with context of calling component. + Use it to create component inside of other components. + + + +

    Returns:

    +
      + + Druid + Druid instance with component context +
    + + + + +
    +
    + + get_interests() +
    +
    + Get current component interests + + + +

    Returns:

    +
      + + table + List of component interests +
    + + + + +
    +
    + + get_nodes() +
    +
    + Get current component nodes + + + +

    Returns:

    +
      + + table + Component nodes table +
    + + + + +
    +
    + + get_style() +
    +
    + Get current component style table + + + +

    Returns:

    +
      + + table + Component style table +
    + + + + +
    +
    + + get_template() +
    +
    + Get current component template name + + + +

    Returns:

    +
      + + string + Component template name +
    + + + + +
    +
    + + set_context(context) +
    +
    + Set current component context + + +

    Parameters:

    +
      +
    • context + table + Druid context. Usually it is self of script +
    • +
    + + + + + +
    +
    + + set_nodes(nodes) +
    +
    + Set current component nodes + + +

    Parameters:

    +
      +
    • nodes + table + Component nodes table +
    • +
    + + + + + +
    +
    + + set_style(style) +
    +
    + Set current component style table + + +

    Parameters:

    +
      +
    • style + table + Druid style module +
    • +
    + + + + + +
    +
    + + set_template(template) +
    +
    + Set current component template name + + +

    Parameters:

    +
      +
    • template + string + Component template name +
    • +
    + + + + + +
    setup_component(table, table) @@ -157,237 +388,6 @@ -
    -
    - - get_style() -
    -
    - Get current component style table - - - -

    Returns:

    -
      - - table - Component style table -
    - - - - -
    -
    - - set_style(style) -
    -
    - Set current component style table - - -

    Parameters:

    -
      -
    • style - table - Druid style module -
    • -
    - - - - - -
    -
    - - get_template() -
    -
    - Get current component template name - - - -

    Returns:

    -
      - - string - Component template name -
    - - - - -
    -
    - - set_template(template) -
    -
    - Set current component template name - - -

    Parameters:

    -
      -
    • template - string - Component template name -
    • -
    - - - - - -
    -
    - - get_nodes() -
    -
    - Get current component nodes - - - -

    Returns:

    -
      - - table - Component nodes table -
    - - - - -
    -
    - - set_nodes(nodes) -
    -
    - Set current component nodes - - -

    Parameters:

    -
      -
    • nodes - table - Component nodes table -
    • -
    - - - - - -
    -
    - - get_context() -
    -
    - Get current component context - - - -

    Returns:

    -
      - - table - Component context -
    - - - - -
    -
    - - set_context(context) -
    -
    - Set current component context - - -

    Parameters:

    -
      -
    • context - table - Druid context. Usually it is self of script -
    • -
    - - - - - -
    -
    - - get_interests() -
    -
    - Get current component interests - - - -

    Returns:

    -
      - - table - List of component interests -
    - - - - -
    -
    - - get_druid() -
    -
    - Return druid with context of calling component. - Use it to create component inside of other components. - - - -

    Returns:

    -
      - - Druid - Druid instance with component context -
    - - - - -
    -
    - - Component.create(name, interest) -
    -
    - Create new component. It will inheritance from basic - druid component. - - -

    Parameters:

    -
      -
    • name - string - Component name -
    • -
    • interest - table - List of component's interest -
    • -
    - - - - -
    @@ -396,7 +396,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index c0b420f..66881c1 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -64,7 +65,9 @@

    Module druid.back_handler

    Component to handle back key (android, backspace)

    -

    +

    + +

    Functions

    @@ -148,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index e1924ab..cd46818 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -34,23 +34,24 @@

    Modules

    @@ -60,7 +61,9 @@

    Module druid.blocker

    Component to block input on specify zone (node)

    -

    +

    + +

    @@ -74,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 7e0edbc..4108eb2 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -33,28 +33,30 @@

    Contents

    Modules

    @@ -64,23 +66,56 @@

    Module druid.button

    Component to handle basic GUI button

    -

    +

    + +

    Functions

    - - - - + + + + + + + + + + + + + + + + + + + + + + + + +
    init(self, node, callback[, params[, anim_node[, event]]])Component init function
    disable_animation(self) Disable all button animations
    get_key_trigger(self)Get key-code to trigger this button
    init(self, node, callback[, params[, anim_node[, event]]])Component init function
    set_callback(self, callback)Set usual button callback
    set_click_zone(self, zone) Strict button click area.
    set_double_tap_callback(self, callback)Get doubletap callback on this button
    set_hold_callback(self, callback)Repeat callback always, while holding button
    set_long_tap_callback(self, callback)Single callbacka after long_tap.
    +

    Tables

    + + + + + + + + +
    eventsComponent events
    fieldsComponent fields

    @@ -90,6 +125,49 @@

    Functions

    +
    + + disable_animation(self) +
    +
    + Disable all button animations + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + get_key_trigger(self) +
    +
    + Get key-code to trigger this button + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    + + + + + +
    init(self, node, callback[, params[, anim_node[, event]]]) @@ -135,18 +213,24 @@
    - - disable_animation(self) + + set_callback(self, callback)
    - Disable all button animations + Set usual button callback

    Parameters:

    • self - table - Component instance + + + +
    • +
    • callback + + +
    @@ -180,6 +264,153 @@ +
    +
    + + set_double_tap_callback(self, callback) +
    +
    + Get doubletap callback on this button + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    • callback + + + +
    • +
    + + + + + +
    +
    + + set_hold_callback(self, callback) +
    +
    + Repeat callback always, while holding button + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    • callback + + + +
    • +
    + + + + + +
    +
    + + set_long_tap_callback(self, callback) +
    +
    + Single callbacka after long_tap. No usual callback invoked + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    • callback + + + +
    • +
    + + + + + +
    +
    +

    Tables

    + +
    +
    + + events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_click + druid_event + + + +
    • +
    • on_hold_click + druid_event + + + +
    • +
    • on_long_click + druid_event + + + +
    • +
    • on_double_click + druid_event + + + +
    • +
    + + + + + +
    +
    + + fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • Main + node + node +
    • +
    + + + + +
    @@ -188,7 +419,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index 51a2f75..e3b8461 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -34,23 +34,24 @@

    Modules

    @@ -60,7 +61,9 @@

    Module druid.checkbox

    Druid checkbox component

    -

    +

    + +

    @@ -74,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index 0071b08..6a20fe6 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -34,23 +34,24 @@

    Modules

    @@ -60,7 +61,9 @@

    Module druid.checkbox_group

    Checkboux group module

    -

    +

    + +

    @@ -74,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 9321a7f..ad0f258 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -34,23 +34,24 @@

    Modules

    @@ -60,8 +61,7 @@

    Module druid.grid

    Component to handle placing components by row and columns.

    -

    - Grid can anchor your elements, get content size and other

    +

    Grid can anchor your elements, get content size and other

    @@ -75,7 +75,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/helper.html b/docs/modules/druid.helper.html similarity index 70% rename from docs/modules/helper.html rename to docs/modules/druid.helper.html index 0577525..820aaec 100644 --- a/docs/modules/helper.html +++ b/docs/modules/druid.helper.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -62,20 +63,30 @@
    -

    Module helper

    +

    Module druid.helper

    Text node or icon node can be nil

    -

    +

    + +

    Functions

    + + + + - - + + + + + +
    centrate_icon_with_text([icon_node[, text_node[, margin=0]]])Center two nodes.
    centrate_text_with_icon([text_node][, icon_node], margin) Center two nodes.
    centrate_icon_with_text([icon_node[, text_node[, margin=0]]])Center two nodes.get_pivot_offset(pivot)Get node offset for given gui pivot
    is_enabled(node)Check if node is enabled in gui hierarchy.
    @@ -86,39 +97,6 @@

    Functions

    -
    - - centrate_text_with_icon([text_node][, icon_node], margin) -
    -
    - Center two nodes. - Nodes will be center around 0 x position - text_node will be first (at left side) - - -

    Parameters:

    -
      -
    • text_node - text - Gui text node - (optional) -
    • -
    • icon_node - box - Gui box node - (optional) -
    • -
    • margin - number - Offset between nodes -
    • -
    - - - - - -
    centrate_icon_with_text([icon_node[, text_node[, margin=0]]]) @@ -152,6 +130,94 @@ + +
    + + centrate_text_with_icon([text_node][, icon_node], margin) +
    +
    + Center two nodes. + Nodes will be center around 0 x position + text_node will be first (at left side) + + +

    Parameters:

    +
      +
    • text_node + text + Gui text node + (optional) +
    • +
    • icon_node + box + Gui box node + (optional) +
    • +
    • margin + number + Offset between nodes +
    • +
    + + + + + +
    +
    + + get_pivot_offset(pivot) +
    +
    + Get node offset for given gui pivot + + +

    Parameters:

    +
      +
    • pivot + gui.pivot + The node pivot +
    • +
    + +

    Returns:

    +
      + + vector3 + Vector offset with [-1..1] values +
    + + + + +
    +
    + + is_enabled(node) +
    +
    + Check if node is enabled in gui hierarchy. + Return false, if node or any his parent is disabled + + +

    Parameters:

    +
      +
    • node + node + Gui node +
    • +
    + +

    Returns:

    +
      + + bool + Is enabled in hierarchy +
    + + + +
    @@ -160,7 +226,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 18bfff8..eef8815 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -65,25 +66,36 @@

    Module druid

    Druid UI Library.

    - Powerful Defold component based UI library. Use standart + +

    Powerful Defold component based UI library. Use standart components or make your own game-specific to make amazing - GUI in your games. + GUI in your games.

    +

    Contains the several basic components and examples to how to do your custom complex components to - separate UI game logic to small files + separate UI game logic to small files

    + + +
    +require("druid.druid")
    +function init(self)
    +    self.druid = druid.new(self)
    +end
    +
    +

    Functions

    - - - - + + + +
    register(name, module)Register external druid component.
    new(context[, style]) Create Druid instance.
    register(name, module)Register external druid component.

    @@ -93,33 +105,6 @@

    Functions

    -
    - - register(name, module) -
    -
    - Register external druid component. - After register you can create the component with - druid_instance:new_{name}. For example `druid:new_button(...)` - - -

    Parameters:

    -
      -
    • name - string - module name -
    • -
    • module - table - lua table with component -
    • -
    - - - - - -
    new(context[, style]) @@ -151,6 +136,33 @@ + +
    + + register(name, module) +
    +
    + Register external druid component. + After register you can create the component with + druidinstance:new{name}. For example druid:new_button(...) + + +

    Parameters:

    +
      +
    • name + string + module name +
    • +
    • module + table + lua table with component +
    • +
    + + + + +
    @@ -159,7 +171,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.progress_rich.html b/docs/modules/druid.input.html similarity index 61% rename from docs/modules/druid.progress_rich.html rename to docs/modules/druid.input.html index 335a6b3..234ed47 100644 --- a/docs/modules/druid.progress_rich.html +++ b/docs/modules/druid.input.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -62,24 +63,22 @@
    -

    Module druid.progress_rich

    -

    Component for rich progress component

    -

    +

    Module druid.input

    +

    Component to handle hover node interaction

    +

    + +

    Functions

    - - + + - - - - - - + +
    set_to(self, value)Instant fill progress bar to valuebutton:set_click_zone(self, zone)Strict button click area.
    empty(self)Empty a progress bar
    to(self, to[, callback])Start animation of a progress barhover:init(self, node, on_hover_callback)Component init function
    @@ -91,11 +90,12 @@
    - - set_to(self, value) + + button:set_click_zone(self, zone)
    - Instant fill progress bar to value + Strict button click area. Useful for + no click events outside stencil node

    Parameters:

    @@ -104,9 +104,9 @@ table Component instance -
  • value - number - Progress bar value, from 0 to 1 +
  • zone + node + Gui node
  • @@ -116,11 +116,11 @@
    - - empty(self) + + hover:init(self, node, on_hover_callback)
    - Empty a progress bar + Component init function

    Parameters:

    @@ -129,35 +129,13 @@ table Component instance - - - - - - -
    -
    - - to(self, to[, callback]) -
    -
    - Start animation of a progress bar - - -

    Parameters:

    -
      -
    • self - table - Component instance +
    • node + node + Gui node
    • -
    • to - number - value between 0..1 -
    • -
    • callback +
    • on_hover_callback function - Callback on animation ends - (optional) + Hover callback
    @@ -173,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.locale.html b/docs/modules/druid.lang_text.html similarity index 87% rename from docs/modules/druid.locale.html rename to docs/modules/druid.lang_text.html index cd07ef0..7eefddd 100644 --- a/docs/modules/druid.locale.html +++ b/docs/modules/druid.lang_text.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -62,10 +63,12 @@
    -

    Module druid.locale

    +

    Module druid.lang_text

    Component to handle all GUI texts Good working with localization system

    -

    +

    + +

    Functions

    @@ -115,7 +118,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index c133fb8..a505c5a 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -64,36 +65,38 @@

    Module druid.progress

    Basic progress bar component

    -

    +

    + +

    Functions

    - - + + - - - - - - - - + + + + + + + + @@ -106,6 +109,69 @@

    Functions

    +
    + + empty(self) +
    +
    + Empty a progress bar + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + empty(self) +
    +
    + Fill a progress bar and stop progress animation + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + get(self) +
    +
    + Return current progress bar value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    init(self, node, key, init_value) @@ -140,11 +206,11 @@
    - - empty(self) + + set_steps(self, steps, callback)
    - Fill a progress bar and stop progress animation + Set points on progress bar to fire the callback

    Parameters:

    @@ -153,26 +219,13 @@ table Component instance - - - - - - -
    -
    - - empty(self) -
    -
    - Empty a progress bar - - -

    Parameters:

    -
      -
    • self +
    • steps table - Component instance + Array of progress bar values +
    • +
    • callback + function + Callback on intersect step value
    @@ -205,56 +258,6 @@ -
    -
    - - get(self) -
    -
    - Return current progress bar value - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - set_steps(self, steps, callback) -
    -
    - Set points on progress bar to fire the callback - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • steps - table - Array of progress bar values -
    • -
    • callback - function - Callback on intersect step value -
    • -
    - - - - -
    @@ -293,7 +296,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index e4db277..95f1c32 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -34,23 +34,24 @@

    Modules

    @@ -60,7 +61,9 @@

    Module druid.radio_group

    Radio group module

    -

    +

    + +

    @@ -74,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index c91a211..c12e1aa 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -64,35 +65,37 @@

    Module druid.scroll

    Component to handle scroll content

    -

    +

    + +

    Functions

    init(self, node, key, init_value)Component init functionempty(self)Empty a progress bar
    empty(self) Fill a progress bar and stop progress animation
    empty(self)Empty a progress bar
    set_to(self, to)Instant fill progress bar to value
    get(self) Return current progress bar value
    init(self, node, key, init_value)Component init function
    set_steps(self, steps, callback) Set points on progress bar to fire the callback
    set_to(self, to)Instant fill progress bar to value
    to(self, to[, callback]) Start animation of a progress bar
    - - - - - - - - - - - - + + + + + + + + + + + +
    scroll_to(vector3[, is_instant])Start scroll to target point
    init(self, index[, skip_cb]) Scroll to item in scroll by point index
    set_points(self, points)Set points of interest.
    set_inert(self, state)Enable or disable scroll inert.
    on_point_move(self, callback) Set the callback on scrolling to point (if exist)
    scroll_to(vector3[, is_instant])Start scroll to target point
    set_border(self, border) Set the scroll possibly area
    set_inert(self, state)Enable or disable scroll inert.
    set_points(self, points)Set points of interest.

    @@ -102,6 +105,61 @@

    Functions

    +
    + + init(self, index[, skip_cb]) +
    +
    + Scroll to item in scroll by point index + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • index + number + Point index +
    • +
    • skip_cb + boolean + If true, skip the point callback + (optional) +
    • +
    + + + + + +
    +
    + + on_point_move(self, callback) +
    +
    + Set the callback on scrolling to point (if exist) + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • callback + function + Callback on scroll to point of interest +
    • +
    + + + + + +
    scroll_to(vector3[, is_instant]) @@ -134,11 +192,11 @@
    - - init(self, index[, skip_cb]) + + set_border(self, border)
    - Scroll to item in scroll by point index + Set the scroll possibly area

    Parameters:

    @@ -147,40 +205,9 @@ table Component instance -
  • index - number - Point index -
  • -
  • skip_cb - boolean - If true, skip the point callback - (optional) -
  • - - - - - - -
    -
    - - set_points(self, points) -
    -
    - Set points of interest. - Scroll will always centered on closer points - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • points - table - Array of vector3 points +
    • border + vmath.vector3 + Size of scrolling area
    @@ -217,11 +244,12 @@
    - - on_point_move(self, callback) + + set_points(self, points)
    - Set the callback on scrolling to point (if exist) + Set points of interest. + Scroll will always centered on closer points

    Parameters:

    @@ -230,34 +258,9 @@ table Component instance -
  • callback - function - Callback on scroll to point of interest -
  • - - - - - - -
    -
    - - set_border(self, border) -
    -
    - Set the scroll possibly area - - -

    Parameters:

    -
      -
    • self +
    • points table - Component instance -
    • -
    • border - vmath.vector3 - Size of scrolling area + Array of vector3 points
    @@ -273,7 +276,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index 4a71669..fb5dc21 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -34,23 +34,24 @@

    Modules

    @@ -60,7 +61,9 @@

    Module druid.slider

    Druid slider component

    -

    +

    + +

    @@ -74,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index c35de59..a1ec437 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -65,30 +66,32 @@

    Module druid.text

    Component to handle all GUI texts Good working with localization system

    -

    +

    + +

    Functions

    - - + + - - + + - - + +
    set_to(self, set_to)Set text to text fieldset_alpha(self, alpha)Set alpha
    set_color(self, color) Set color
    set_alpha(self, alpha)Set alphaset_pivot(self, pivot)Set text pivot.
    set_scale(self, scale) Set scale
    set_pivot(self, pivot)Set text pivot.set_to(self, set_to)Set text to text field
    @@ -100,11 +103,11 @@
    - - set_to(self, set_to) + + set_alpha(self, alpha)
    - Set text to text field + Set alpha

    Parameters:

    @@ -113,9 +116,9 @@ table Component instance -
  • set_to - string - Text for node +
  • alpha + number + Alpha for node
  • @@ -150,11 +153,12 @@
    - - set_alpha(self, alpha) + + set_pivot(self, pivot)
    - Set alpha + Set text pivot. Text will re-anchor inside + his text area

    Parameters:

    @@ -163,9 +167,9 @@ table Component instance -
  • alpha - number - Alpha for node +
  • pivot + gui.pivot + Gui pivot constant
  • @@ -200,12 +204,11 @@
    - - set_pivot(self, pivot) + + set_to(self, set_to)
    - Set text pivot. Text will re-anchor inside - his text area + Set text to text field

    Parameters:

    @@ -214,9 +217,9 @@ table Component instance -
  • pivot - gui.pivot - Gui pivot constant +
  • set_to + string + Text for node
  • @@ -232,7 +235,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index afc6f94..afa6a7a 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -64,22 +65,24 @@

    Module druid.timer

    Component to handle GUI timers

    -

    +

    + +

    Functions

    - - + + - - + +
    set_to(self, set_to)Set text to text fieldset_interval(self, from, to)Set time interval
    set_state(self, is_on) Called when update
    set_interval(self, from, to)Set time intervalset_to(self, set_to)Set text to text field
    @@ -91,11 +94,11 @@
    - - set_to(self, set_to) + + set_interval(self, from, to)
    - Set text to text field + Set time interval

    Parameters:

    @@ -104,9 +107,13 @@ table Component instance -
  • set_to +
  • from number - Value in seconds + Start time in seconds +
  • +
  • to + number + Target time in seconds
  • @@ -141,11 +148,11 @@
    - - set_interval(self, from, to) + + set_to(self, set_to)
    - Set time interval + Set text to text field

    Parameters:

    @@ -154,13 +161,9 @@ table Component instance -
  • from +
  • set_to number - Start time in seconds -
  • -
  • to - number - Target time in seconds + Value in seconds
  • @@ -176,7 +179,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/const.html b/docs/modules/druid_event.html similarity index 56% rename from docs/modules/const.html rename to docs/modules/druid_event.html index 0b50a56..f6bda44 100644 --- a/docs/modules/const.html +++ b/docs/modules/druid_event.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -30,34 +30,28 @@
  • Index
  • -

    Contents

    -

    Modules

    @@ -65,79 +59,25 @@
    -

    Module const

    -

    Druid constants

    -

    +

    Module druid_event

    +

    Lua event small library

    +

    + +

    -

    Tables

    - - - - - -
    pivots
    -

    Fields

    - - - - - -
    ON_MESSAGEInterests


    -

    Tables

    - -
    -
    - - pivots -
    -
    - - - -

    Fields:

    -
      -
    • test - test -
    • -
    - - - - - -
    -
    -

    Fields

    - -
    -
    - - ON_MESSAGE -
    -
    - Interests - - - - - - - -
    -
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:01:14 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index fc11032..719a0ca 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -4,7 +4,7 @@ Defold Druid UI Library - + @@ -38,23 +38,24 @@

    Modules

    @@ -71,8 +72,9 @@
  • druid.button
  • druid.blocker
  • druid.back_handler
  • +
  • druid.input
  • druid.text
  • -
  • druid.locale
  • +
  • druid.lang_text
  • druid.timer
  • druid.progress
  • druid.grid
  • @@ -86,69 +88,25 @@

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - + + @@ -159,12 +117,60 @@ + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    druid:initialize(table, table)Druid class constructor
    druid:create(component, ...) Create new druid component
    druid:remove(component)Remove component from druid instance.
    druid:update(dt)Druid update function
    druid:on_input(action_id, action)Druid on_input function
    druid:on_message(message_id, message, sender)Druid on_message function
    druid:new_button(...)Create button basic component
    druid:new_blocker(...)Create blocker basic componentdruid:initialize(table, table)Druid class constructor
    druid:new_back_handler(...) Create back_handler basic component
    druid:new_text(...)Create text basic componentdruid:new_blocker(...)Create blocker basic component
    druid:new_locale(...)Create locale basic component
    druid:new_timer(...)Create timer basic component
    druid:new_progress(...)Create progress basic component
    druid:new_grid(...)Create grid basic component
    druid:new_scroll(...)Create scroll basic component
    druid:new_slider(...)Create slider basic componentdruid:new_button(...)Create button basic component
    druid:new_checkbox(...)Create checkbox_group basic component
    druid:new_grid(...)Create grid basic component
    druid:new_hover(...)Create hover basic component
    druid:new_input(...)Create input basic component
    druid:new_lang_text(...)Create lang_text basic component
    druid:new_progress(...)Create progress basic component
    druid:new_radio_group(...) Create radio_group basic component
    druid:new_progress_rich(...)Create progress_rich basic componentdruid:new_scroll(...)Create scroll basic component
    druid:new_slider(...)Create slider basic component
    druid:new_text(...)Create text basic component
    druid:new_timer(...)Create timer basic component
    druid:on_input(action_id, action)Druid on_input function
    druid:on_message(message_id, message, sender)Druid on_message function
    druid:remove(component)Remove component from druid instance.
    druid:update(dt)Druid update function
    @@ -175,31 +181,6 @@

    Functions

    -
    - - druid:initialize(table, table) -
    -
    - Druid class constructor - - -

    Parameters:

    -
      -
    • table - style - Druid style module -
    • -
    • table - style - Druid style module -
    • -
    - - - - - -
    druid:create(component, ...) @@ -226,19 +207,22 @@
    - - druid:remove(component) + + druid:initialize(table, table)
    - Remove component from druid instance. - Component `on_remove` function will be invoked, if exist. + Druid class constructor

    Parameters:

      -
    • component - Component - Component instance +
    • table + style + Druid style module +
    • +
    • table + style + Druid style module
    @@ -248,93 +232,18 @@
    - - druid:update(dt) + + druid:new_back_handler(...)
    - Druid update function - - -

    Parameters:

    -
      -
    • dt - number - Delta time -
    • -
    - - - - - -
    -
    - - druid:on_input(action_id, action) -
    -
    - Druid on_input function - - -

    Parameters:

    -
      -
    • action_id - hash - Action_id from on_input -
    • -
    • action - table - Action from on_input -
    • -
    - - - - - -
    -
    - - druid:on_message(message_id, message, sender) -
    -
    - Druid on_message function - - -

    Parameters:

    -
      -
    • message_id - hash - Message_id from on_message -
    • -
    • message - table - Message from on_message -
    • -
    • sender - hash - Sender from on_message -
    • -
    - - - - - -
    -
    - - druid:new_button(...) -
    -
    - Create button basic component + Create back_handler basic component

    Parameters:

    • ... args - button init args + back_handler init args
    @@ -342,7 +251,7 @@
      Component - button component + back_handler component
    @@ -377,18 +286,18 @@
    - - druid:new_back_handler(...) + + druid:new_button(...)
    - Create back_handler basic component + Create button basic component

    Parameters:

    • ... args - back_handler init args + button init args
    @@ -396,196 +305,7 @@
      Component - back_handler component -
    - - - - -
    -
    - - druid:new_text(...) -
    -
    - Create text basic component - - -

    Parameters:

    -
      -
    • ... - args - text init args -
    • -
    - -

    Returns:

    -
      - - Component - text component -
    - - - - -
    -
    - - druid:new_locale(...) -
    -
    - Create locale basic component - - -

    Parameters:

    -
      -
    • ... - args - locale init args -
    • -
    - -

    Returns:

    -
      - - Component - locale component -
    - - - - -
    -
    - - druid:new_timer(...) -
    -
    - Create timer basic component - - -

    Parameters:

    -
      -
    • ... - args - timer init args -
    • -
    - -

    Returns:

    -
      - - Component - timer component -
    - - - - -
    -
    - - druid:new_progress(...) -
    -
    - Create progress basic component - - -

    Parameters:

    -
      -
    • ... - args - progress init args -
    • -
    - -

    Returns:

    -
      - - Component - progress component -
    - - - - -
    -
    - - druid:new_grid(...) -
    -
    - Create grid basic component - - -

    Parameters:

    -
      -
    • ... - args - grid init args -
    • -
    - -

    Returns:

    -
      - - Component - grid component -
    - - - - -
    -
    - - druid:new_scroll(...) -
    -
    - Create scroll basic component - - -

    Parameters:

    -
      -
    • ... - args - scroll init args -
    • -
    - -

    Returns:

    -
      - - Component - scroll component -
    - - - - -
    -
    - - druid:new_slider(...) -
    -
    - Create slider basic component - - -

    Parameters:

    -
      -
    • ... - args - slider init args -
    • -
    - -

    Returns:

    -
      - - Component - slider component + button component
    @@ -645,6 +365,141 @@ +
    +
    + + druid:new_grid(...) +
    +
    + Create grid basic component + + +

    Parameters:

    +
      +
    • ... + args + grid init args +
    • +
    + +

    Returns:

    +
      + + Component + grid component +
    + + + + +
    +
    + + druid:new_hover(...) +
    +
    + Create hover basic component + + +

    Parameters:

    +
      +
    • ... + args + hover init args +
    • +
    + +

    Returns:

    +
      + + Component + hover component +
    + + + + +
    +
    + + druid:new_input(...) +
    +
    + Create input basic component + + +

    Parameters:

    +
      +
    • ... + args + input init args +
    • +
    + +

    Returns:

    +
      + + Component + input component +
    + + + + +
    +
    + + druid:new_lang_text(...) +
    +
    + Create lang_text basic component + + +

    Parameters:

    +
      +
    • ... + args + lang_text init args +
    • +
    + +

    Returns:

    +
      + + Component + lang_text component +
    + + + + +
    +
    + + druid:new_progress(...) +
    +
    + Create progress basic component + + +

    Parameters:

    +
      +
    • ... + args + progress init args +
    • +
    + +

    Returns:

    +
      + + Component + progress component +
    + + + +
    @@ -674,18 +529,18 @@
    - - druid:new_progress_rich(...) + + druid:new_scroll(...)
    - Create progress_rich basic component + Create scroll basic component

    Parameters:

    • ... args - progress_rich init args + scroll init args
    @@ -693,12 +548,190 @@
      Component - progress_rich component + scroll component
    +
    +
    + + druid:new_slider(...) +
    +
    + Create slider basic component + + +

    Parameters:

    +
      +
    • ... + args + slider init args +
    • +
    + +

    Returns:

    +
      + + Component + slider component +
    + + + + +
    +
    + + druid:new_text(...) +
    +
    + Create text basic component + + +

    Parameters:

    +
      +
    • ... + args + text init args +
    • +
    + +

    Returns:

    +
      + + Component + text component +
    + + + + +
    +
    + + druid:new_timer(...) +
    +
    + Create timer basic component + + +

    Parameters:

    +
      +
    • ... + args + timer init args +
    • +
    + +

    Returns:

    +
      + + Component + timer component +
    + + + + +
    +
    + + druid:on_input(action_id, action) +
    +
    + Druid on_input function + + +

    Parameters:

    +
      +
    • action_id + hash + Actionid from oninput +
    • +
    • action + table + Action from on_input +
    • +
    + + + + + +
    +
    + + druid:on_message(message_id, message, sender) +
    +
    + Druid on_message function + + +

    Parameters:

    +
      +
    • message_id + hash + Messageid from onmessage +
    • +
    • message + table + Message from on_message +
    • +
    • sender + hash + Sender from on_message +
    • +
    + + + + + +
    +
    + + druid:remove(component) +
    +
    + Remove component from druid instance. + Component on_remove function will be invoked, if exist. + + +

    Parameters:

    +
      +
    • component + Component + Component instance +
    • +
    + + + + + +
    +
    + + druid:update(dt) +
    +
    + Druid update function + + +

    Parameters:

    +
      +
    • dt + number + Delta time +
    • +
    + + + + +
    @@ -707,7 +740,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-07 01:09:38 +Last updated 2020-02-23 13:01:03
    diff --git a/docs/modules/helper.formats.html b/docs/modules/helper.formats.html deleted file mode 100644 index 59952c4..0000000 --- a/docs/modules/helper.formats.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - Defold Druid UI Library - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module helper.formats

    -

    Druid module with utils on string formats

    -

    - - -

    Functions

    - - - - - - - - - - - - - -
    add_prefix_zeros(num, count)Return number with zero number prefix
    second_string_min(sec)Convert seconds to string minutes:seconds
    second_string_min(s, tab)Interpolate string with named Parameters in Table
    - -
    -
    - - -

    Functions

    - -
    -
    - - add_prefix_zeros(num, count) -
    -
    - Return number with zero number prefix - - -

    Parameters:

    -
      -
    • num - number - Number for conversion -
    • -
    • count - number - Count of numerals -
    • -
    - -

    Returns:

    -
      - - string with need count of zero (1,3) -> 001 -
    - - - - -
    -
    - - second_string_min(sec) -
    -
    - Convert seconds to string minutes:seconds - - -

    Parameters:

    -
      -
    • sec - number - Seconds -
    • -
    - -

    Returns:

    -
      - - string minutes:seconds -
    - - - - -
    -
    - - second_string_min(s, tab) -
    -
    - Interpolate string with named Parameters in Table - - -

    Parameters:

    -
      -
    • s - string - Target string -
    • -
    • tab - table - Table with parameters -
    • -
    - -

    Returns:

    -
      - - string with replaced parameters -
    - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.6 -Last updated 2020-02-07 01:01:59 -
    -
    - - From 822db35e84baf48e979cf11cc7868a7b6edf4bc0 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 23 Feb 2020 22:57:44 +0300 Subject: [PATCH 113/136] Documentation experiments --- alpha_todo.txt | 6 +- config.ld | 2 +- docs/index.html | 2 +- docs/modules/component.html | 370 ++++++++--------- docs/modules/druid.back_handler.html | 8 +- docs/modules/druid.blocker.html | 8 +- docs/modules/druid.button.html | 249 ++++-------- docs/modules/druid.checkbox.html | 8 +- docs/modules/druid.checkbox_group.html | 8 +- docs/modules/druid.grid.html | 8 +- docs/modules/druid.helper.html | 112 +++--- docs/modules/druid.html | 70 ++-- docs/modules/druid.input.html | 68 ++-- docs/modules/druid.lang_text.html | 8 +- docs/modules/druid.progress.html | 176 ++++---- docs/modules/druid.radio_group.html | 8 +- docs/modules/druid.scroll.html | 166 ++++---- docs/modules/druid.slider.html | 8 +- docs/modules/druid.text.html | 58 +-- docs/modules/druid.timer.html | 44 +- docs/modules/druid_event.html | 93 ++++- docs/modules/druid_instance.html | 536 ++++++++++++------------- druid/base/button.lua | 62 ++- druid/component.lua | 40 +- druid/event.lua | 10 + 25 files changed, 1071 insertions(+), 1057 deletions(-) diff --git a/alpha_todo.txt b/alpha_todo.txt index 552c412..cff23aa 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -9,13 +9,15 @@ Simple to-do for Druid Alpha 0.2.0 + better name for slider component? Slider is ok + Druid store assets - separate repository with rich components (progress_rich migrate) + refactor on_swipe. To on_scroll? Add input priority -- separate custom data and predefined fields in components? ++ separate custom data and predefined fields in components? Every component have their fields and events - add init/remove stuff for every style in component. How to set custom sprites for button states? -- unify component api (get/set/to and other general stuff) - add druid settings (add auto_focus input and other stuff) + - button add key trigger - button polish, actions - button and hover click restriction zone? + +- unify component api (get/set/to and other general stuff) - better callbacks for every components - better scroll size management, check different cases. So implicit now - better grid + scroll management diff --git a/config.ld b/config.ld index b9a95cd..00b4508 100644 --- a/config.ld +++ b/config.ld @@ -3,7 +3,7 @@ title='Defold Druid UI Library' description='Documentation for Druid Library' file={"./druid"} package='druid' -sort=true +sort=false dir='./docs' style='!fixed' format='discount' diff --git a/docs/index.html b/docs/index.html index 45b2665..e865552 100644 --- a/docs/index.html +++ b/docs/index.html @@ -145,7 +145,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/component.html b/docs/modules/component.html index d0b3851..a05a234 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -38,15 +38,12 @@

    Modules

    @@ -70,54 +70,54 @@

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Component.create(name, interest)Create new component.
    get_context()Get current component context
    get_druid()Return druid with context of calling component.
    get_interests()Get current component interests
    get_nodes()Get current component nodes
    get_style() Get current component style table
    get_template()Get current component template name
    set_context(context)Set current component context
    set_nodes(nodes)Set current component nodes
    set_style(style) Set current component style table
    get_template()Get current component template name
    set_template(template) Set current component template name
    get_nodes()Get current component nodes
    set_nodes(nodes)Set current component nodes
    get_context()Get current component context
    set_context(context)Set current component context
    get_interests()Get current component interests
    get_druid()Return druid with context of calling component.
    setup_component(table, table) Setup component context and his style table
    Component.create(name, interest)Create new component.

    @@ -128,23 +128,120 @@
    - - Component.create(name, interest) + + get_style()
    - Create new component. It will inheritance from basic - druid component. + Get current component style table + + + +

    Returns:

    +
      + + table + Component style table +
    + + + + +
    +
    + + set_style(style) +
    +
    + Set current component style table

    Parameters:

      -
    • name - string - Component name -
    • -
    • interest +
    • style table - List of component's interest + Druid style module +
    • +
    + + + + + +
    +
    + + get_template() +
    +
    + Get current component template name + + + +

    Returns:

    +
      + + string + Component template name +
    + + + + +
    +
    + + set_template(template) +
    +
    + Set current component template name + + +

    Parameters:

    +
      +
    • template + string + Component template name +
    • +
    + + + + + +
    +
    + + get_nodes() +
    +
    + Get current component nodes + + + +

    Returns:

    +
      + + table + Component nodes table +
    + + + + +
    +
    + + set_nodes(nodes) +
    +
    + Set current component nodes + + +

    Parameters:

    +
      +
    • nodes + table + Component nodes table
    @@ -174,21 +271,21 @@
    - - get_druid() + + set_context(context)
    - Return druid with context of calling component. - Use it to create component inside of other components. + Set current component context +

    Parameters:

    +
      +
    • context + table + Druid context. Usually it is self of script +
    • +
    -

    Returns:

    -
      - - Druid - Druid instance with component context -
    @@ -215,148 +312,25 @@
    - - get_nodes() + + get_druid()
    - Get current component nodes + Return druid with context of calling component. + Use it to create component inside of other components.

    Returns:

      - table - Component nodes table + Druid + Druid instance with component context
    -
    -
    - - get_style() -
    -
    - Get current component style table - - - -

    Returns:

    -
      - - table - Component style table -
    - - - - -
    -
    - - get_template() -
    -
    - Get current component template name - - - -

    Returns:

    -
      - - string - Component template name -
    - - - - -
    -
    - - set_context(context) -
    -
    - Set current component context - - -

    Parameters:

    -
      -
    • context - table - Druid context. Usually it is self of script -
    • -
    - - - - - -
    -
    - - set_nodes(nodes) -
    -
    - Set current component nodes - - -

    Parameters:

    -
      -
    • nodes - table - Component nodes table -
    • -
    - - - - - -
    -
    - - set_style(style) -
    -
    - Set current component style table - - -

    Parameters:

    -
      -
    • style - table - Druid style module -
    • -
    - - - - - -
    -
    - - set_template(template) -
    -
    - Set current component template name - - -

    Parameters:

    -
      -
    • template - string - Component template name -
    • -
    - - - - -
    @@ -388,6 +362,32 @@ +
    +
    + + Component.create(name, interest) +
    +
    + Create new component. It will inheritance from basic + druid component. + + +

    Parameters:

    +
      +
    • name + string + Component name +
    • +
    • interest + table + List of component's interest +
    • +
    + + + + +
    @@ -396,7 +396,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 66881c1..66d587d 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -38,15 +38,12 @@

    Modules

    @@ -151,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index cd46818..46ce82d 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -34,15 +34,12 @@

    Modules

    @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 4108eb2..82fe0ef 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -39,15 +39,12 @@

    Modules

    @@ -73,49 +73,37 @@

    Functions

    - - - - - - - - - - + + - - - - - - - - - - + +
    disable_animation(self)Disable all button animations
    get_key_trigger(self)Get key-code to trigger this button
    init(self, node, callback[, params[, anim_node[, event]]]) Component init function
    set_callback(self, callback)Set usual button callbackdisable_animation(self)Disable all button animations
    set_click_zone(self, zone) Strict button click area.
    set_double_tap_callback(self, callback)Get doubletap callback on this button
    set_hold_callback(self, callback)Repeat callback always, while holding button
    set_long_tap_callback(self, callback)Single callbacka after long_tap.get_key_trigger(self)Get key-code to trigger this button

    Tables

    - + - + + + + +
    eventsEvents Component events
    fieldsFields Component fields
    StyleComponent style params

    @@ -125,49 +113,6 @@

    Functions

    -
    - - disable_animation(self) -
    -
    - Disable all button animations - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - get_key_trigger(self) -
    -
    - Get key-code to trigger this button - - -

    Parameters:

    -
      -
    • self - - - -
    • -
    - - - - - -
    init(self, node, callback[, params[, anim_node[, event]]]) @@ -213,24 +158,18 @@
    - - set_callback(self, callback) + + disable_animation(self)
    - Set usual button callback + Disable all button animations

    Parameters:

    • self - - - -
    • -
    • callback - - - + table + Component instance
    @@ -266,11 +205,11 @@
    - - set_double_tap_callback(self, callback) + + get_key_trigger(self)
    - Get doubletap callback on this button + Get key-code to trigger this button

    Parameters:

    @@ -279,65 +218,6 @@ - -
  • callback - - - -
  • - - - - - - -
    -
    - - set_hold_callback(self, callback) -
    -
    - Repeat callback always, while holding button - - -

    Parameters:

    -
      -
    • self - - - -
    • -
    • callback - - - -
    • -
    - - - - - -
    -
    - - set_long_tap_callback(self, callback) -
    -
    - Single callbacka after long_tap. No usual callback invoked - - -

    Parameters:

    -
      -
    • self - - - -
    • -
    • callback - - -
    @@ -351,8 +231,8 @@
    - - events + + Events
    Component events @@ -362,27 +242,19 @@
    • on_click druid_event - - - + On release button callback
    • -
    • on_hold_click +
    • on_repeated_click druid_event - - - + On repeated action button callback
    • on_long_click druid_event - - - + On long tap button callback
    • on_double_click druid_event - - - + On double tap button callback
    @@ -392,8 +264,8 @@
    - - fields + + Fields
    Component fields @@ -401,9 +273,64 @@

    Fields:

      -
    • Main +
    • node node - node + Trigger node +
    • +
    • anim_node + node + Animation node + (default node) +
    • +
    • scale_from + vector3 + Initial scale of anim_node +
    • +
    • pos + vector3 + Initial pos of anim_node +
    • +
    • params + any + Params to click callbacks +
    • +
    • hover_anim + boolean + Is hover anim enabled +
    • +
    • hover + druid.hover + Druid hover logic component +
    • +
    • click_zone + node + Restriction zone + (optional) +
    • +
    + + + + + +
    +
    + + Style +
    +
    + Component style params + + +

    Fields:

    +
      +
    • on_click + function + (self, node) +
    • +
    • on_hover + function + (self, node, hover_state)
    @@ -419,7 +346,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index e3b8461..bfe3b2a 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -34,15 +34,12 @@

    Modules

    @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index 6a20fe6..e492ef9 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -34,15 +34,12 @@

    Modules

    @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index ad0f258..6914a07 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -34,15 +34,12 @@

    Modules

    @@ -75,7 +75,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.helper.html b/docs/modules/druid.helper.html index 820aaec..ae45827 100644 --- a/docs/modules/druid.helper.html +++ b/docs/modules/druid.helper.html @@ -38,15 +38,12 @@

    Modules

    @@ -72,22 +72,22 @@

    Functions

    - - - - - - + + + + + +
    centrate_icon_with_text([icon_node[, text_node[, margin=0]]])Center two nodes.
    centrate_text_with_icon([text_node][, icon_node], margin) Center two nodes.
    get_pivot_offset(pivot)Get node offset for given gui pivotcentrate_icon_with_text([icon_node[, text_node[, margin=0]]])Center two nodes.
    is_enabled(node) Check if node is enabled in gui hierarchy.
    get_pivot_offset(pivot)Get node offset for given gui pivot

    @@ -97,6 +97,39 @@

    Functions

    +
    + + centrate_text_with_icon([text_node][, icon_node], margin) +
    +
    + Center two nodes. + Nodes will be center around 0 x position + text_node will be first (at left side) + + +

    Parameters:

    +
      +
    • text_node + text + Gui text node + (optional) +
    • +
    • icon_node + box + Gui box node + (optional) +
    • +
    • margin + number + Offset between nodes +
    • +
    + + + + + +
    centrate_icon_with_text([icon_node[, text_node[, margin=0]]]) @@ -132,33 +165,28 @@
    - - centrate_text_with_icon([text_node][, icon_node], margin) + + is_enabled(node)
    - Center two nodes. - Nodes will be center around 0 x position - text_node will be first (at left side) + Check if node is enabled in gui hierarchy. + Return false, if node or any his parent is disabled

    Parameters:

      -
    • text_node - text - Gui text node - (optional) -
    • -
    • icon_node - box - Gui box node - (optional) -
    • -
    • margin - number - Offset between nodes +
    • node + node + Gui node
    +

    Returns:

    +
      + + bool + Is enabled in hierarchy +
    @@ -190,34 +218,6 @@ -
    -
    - - is_enabled(node) -
    -
    - Check if node is enabled in gui hierarchy. - Return false, if node or any his parent is disabled - - -

    Parameters:

    -
      -
    • node - node - Gui node -
    • -
    - -

    Returns:

    -
      - - bool - Is enabled in hierarchy -
    - - - -
    @@ -226,7 +226,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index eef8815..66d2c54 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -38,15 +38,12 @@

    Modules

    @@ -88,14 +88,14 @@

    Functions

    - - - - + + + +
    new(context[, style])Create Druid instance.
    register(name, module) Register external druid component.
    new(context[, style])Create Druid instance.

    @@ -105,6 +105,33 @@

    Functions

    +
    + + register(name, module) +
    +
    + Register external druid component. + After register you can create the component with + druidinstance:new{name}. For example druid:new_button(...) + + +

    Parameters:

    +
      +
    • name + string + module name +
    • +
    • module + table + lua table with component +
    • +
    + + + + + +
    new(context[, style]) @@ -136,33 +163,6 @@ -
    -
    - - register(name, module) -
    -
    - Register external druid component. - After register you can create the component with - druidinstance:new{name}. For example druid:new_button(...) - - -

    Parameters:

    -
      -
    • name - string - module name -
    • -
    • module - table - lua table with component -
    • -
    - - - - -
    @@ -171,7 +171,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.input.html b/docs/modules/druid.input.html index 234ed47..3c37497 100644 --- a/docs/modules/druid.input.html +++ b/docs/modules/druid.input.html @@ -38,15 +38,12 @@

    Modules

    @@ -72,14 +72,14 @@

    Functions

    - - - - + + + +
    button:set_click_zone(self, zone)Strict button click area.
    hover:init(self, node, on_hover_callback) Component init function
    button:set_click_zone(self, zone)Strict button click area.

    @@ -89,32 +89,6 @@

    Functions

    -
    - - button:set_click_zone(self, zone) -
    -
    - Strict button click area. Useful for - no click events outside stencil node - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • zone - node - Gui node -
    • -
    - - - - - -
    hover:init(self, node, on_hover_callback) @@ -143,6 +117,32 @@ + +
    + + button:set_click_zone(self, zone) +
    +
    + Strict button click area. Useful for + no click events outside stencil node + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • zone + node + Gui node +
    • +
    + + + + +
    @@ -151,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.lang_text.html b/docs/modules/druid.lang_text.html index 7eefddd..2c02a82 100644 --- a/docs/modules/druid.lang_text.html +++ b/docs/modules/druid.lang_text.html @@ -38,15 +38,12 @@

    Modules

    @@ -118,7 +118,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index a505c5a..2b0ede6 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -38,15 +38,12 @@

    Modules

    @@ -73,30 +73,30 @@

    Functions

    - - + + - - - - - - - - - - + + + + + + + + + + @@ -109,69 +109,6 @@

    Functions

    -
    - - empty(self) -
    -
    - Empty a progress bar - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - empty(self) -
    -
    - Fill a progress bar and stop progress animation - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    -
    - - get(self) -
    -
    - Return current progress bar value - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    - - - - - -
    init(self, node, key, init_value) @@ -206,11 +143,11 @@
    - - set_steps(self, steps, callback) + + empty(self)
    - Set points on progress bar to fire the callback + Fill a progress bar and stop progress animation

    Parameters:

    @@ -219,13 +156,26 @@ table Component instance -
  • steps + + + + + + +
  • +
    + + empty(self) +
    +
    + Empty a progress bar + + +

    Parameters:

    +
      +
    • self table - Array of progress bar values -
    • -
    • callback - function - Callback on intersect step value + Component instance
    @@ -258,6 +208,56 @@ +
    +
    + + get(self) +
    +
    + Return current progress bar value + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    + + + + + +
    +
    + + set_steps(self, steps, callback) +
    +
    + Set points on progress bar to fire the callback + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • steps + table + Array of progress bar values +
    • +
    • callback + function + Callback on intersect step value +
    • +
    + + + + +
    @@ -296,7 +296,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index 95f1c32..082f70a 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -34,15 +34,12 @@

    Modules

    @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index c12e1aa..81b1019 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -38,15 +38,12 @@

    Modules

    @@ -72,29 +72,29 @@

    Functions

    empty(self)Empty a progress barinit(self, node, key, init_value)Component init function
    empty(self) Fill a progress bar and stop progress animation
    get(self)Return current progress bar value
    init(self, node, key, init_value)Component init function
    set_steps(self, steps, callback)Set points on progress bar to fire the callbackempty(self)Empty a progress bar
    set_to(self, to) Instant fill progress bar to value
    get(self)Return current progress bar value
    set_steps(self, steps, callback)Set points on progress bar to fire the callback
    to(self, to[, callback]) Start animation of a progress bar
    - - - - - - - - - - + + + + + + - - + + + + + +
    init(self, index[, skip_cb])Scroll to item in scroll by point index
    on_point_move(self, callback)Set the callback on scrolling to point (if exist)
    scroll_to(vector3[, is_instant]) Start scroll to target point
    set_border(self, border)Set the scroll possibly areainit(self, index[, skip_cb])Scroll to item in scroll by point index
    set_points(self, points)Set points of interest.
    set_inert(self, state) Enable or disable scroll inert.
    set_points(self, points)Set points of interest.on_point_move(self, callback)Set the callback on scrolling to point (if exist)
    set_border(self, border)Set the scroll possibly area
    @@ -105,61 +105,6 @@

    Functions

    -
    - - init(self, index[, skip_cb]) -
    -
    - Scroll to item in scroll by point index - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • index - number - Point index -
    • -
    • skip_cb - boolean - If true, skip the point callback - (optional) -
    • -
    - - - - - -
    -
    - - on_point_move(self, callback) -
    -
    - Set the callback on scrolling to point (if exist) - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • callback - function - Callback on scroll to point of interest -
    • -
    - - - - - -
    scroll_to(vector3[, is_instant]) @@ -192,11 +137,11 @@
    - - set_border(self, border) + + init(self, index[, skip_cb])
    - Set the scroll possibly area + Scroll to item in scroll by point index

    Parameters:

    @@ -205,9 +150,40 @@ table Component instance -
  • border - vmath.vector3 - Size of scrolling area +
  • index + number + Point index +
  • +
  • skip_cb + boolean + If true, skip the point callback + (optional) +
  • + + + + + + +
    +
    + + set_points(self, points) +
    +
    + Set points of interest. + Scroll will always centered on closer points + + +

    Parameters:

    +
      +
    • self + table + Component instance +
    • +
    • points + table + Array of vector3 points
    @@ -244,12 +220,11 @@
    - - set_points(self, points) + + on_point_move(self, callback)
    - Set points of interest. - Scroll will always centered on closer points + Set the callback on scrolling to point (if exist)

    Parameters:

    @@ -258,9 +233,34 @@ table Component instance -
  • points +
  • callback + function + Callback on scroll to point of interest +
  • + + + + + + +
    +
    + + set_border(self, border) +
    +
    + Set the scroll possibly area + + +

    Parameters:

    +
      +
    • self table - Array of vector3 points + Component instance +
    • +
    • border + vmath.vector3 + Size of scrolling area
    @@ -276,7 +276,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index fb5dc21..03e14f1 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -34,15 +34,12 @@

    Modules

    @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index a1ec437..41d09ef 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -38,15 +38,12 @@

    Modules

    @@ -74,24 +74,24 @@

    Functions

    - - + + - - + + - - + +
    set_alpha(self, alpha)Set alphaset_to(self, set_to)Set text to text field
    set_color(self, color) Set color
    set_pivot(self, pivot)Set text pivot.set_alpha(self, alpha)Set alpha
    set_scale(self, scale) Set scale
    set_to(self, set_to)Set text to text fieldset_pivot(self, pivot)Set text pivot.
    @@ -103,11 +103,11 @@
    - - set_alpha(self, alpha) + + set_to(self, set_to)
    - Set alpha + Set text to text field

    Parameters:

    @@ -116,9 +116,9 @@ table Component instance -
  • alpha - number - Alpha for node +
  • set_to + string + Text for node
  • @@ -153,12 +153,11 @@
    - - set_pivot(self, pivot) + + set_alpha(self, alpha)
    - Set text pivot. Text will re-anchor inside - his text area + Set alpha

    Parameters:

    @@ -167,9 +166,9 @@ table Component instance -
  • pivot - gui.pivot - Gui pivot constant +
  • alpha + number + Alpha for node
  • @@ -204,11 +203,12 @@
    - - set_to(self, set_to) + + set_pivot(self, pivot)
    - Set text to text field + Set text pivot. Text will re-anchor inside + his text area

    Parameters:

    @@ -217,9 +217,9 @@ table Component instance -
  • set_to - string - Text for node +
  • pivot + gui.pivot + Gui pivot constant
  • @@ -235,7 +235,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index afa6a7a..242b9b2 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -38,15 +38,12 @@

    Modules

    @@ -73,16 +73,16 @@

    Functions

    - - + + - - + +
    set_interval(self, from, to)Set time intervalset_to(self, set_to)Set text to text field
    set_state(self, is_on) Called when update
    set_to(self, set_to)Set text to text fieldset_interval(self, from, to)Set time interval
    @@ -94,11 +94,11 @@
    - - set_interval(self, from, to) + + set_to(self, set_to)
    - Set time interval + Set text to text field

    Parameters:

    @@ -107,13 +107,9 @@ table Component instance -
  • from +
  • set_to number - Start time in seconds -
  • -
  • to - number - Target time in seconds + Value in seconds
  • @@ -148,11 +144,11 @@
    - - set_to(self, set_to) + + set_interval(self, from, to)
    - Set text to text field + Set time interval

    Parameters:

    @@ -161,9 +157,13 @@ table Component instance -
  • set_to +
  • from number - Value in seconds + Start time in seconds +
  • +
  • to + number + Target time in seconds
  • @@ -179,7 +179,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid_event.html b/docs/modules/druid_event.html index f6bda44..37e3a1c 100644 --- a/docs/modules/druid_event.html +++ b/docs/modules/druid_event.html @@ -30,19 +30,20 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -66,18 +70,99 @@

    +

    Functions

    + + + + + + + + + + + + + +
    event:subscribe(callback)Subscribe callback on event
    event:unsubscribe(callback)Unsubscribe callback on event
    event:trigger(...)Trigger the event and call all subscribed callbacks


    +

    Functions

    + +
    +
    + + event:subscribe(callback) +
    +
    + Subscribe callback on event + + +

    Parameters:

    +
      +
    • callback + function + Callback itself +
    • +
    + + + + + +
    +
    + + event:unsubscribe(callback) +
    +
    + Unsubscribe callback on event + + +

    Parameters:

    +
      +
    • callback + function + Callback itself +
    • +
    + + + + + +
    +
    + + event:trigger(...) +
    +
    + Trigger the event and call all subscribed callbacks + + +

    Parameters:

    +
      +
    • ... + All event params +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index 719a0ca..f3df01a 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -38,15 +38,12 @@

    Modules

    @@ -88,73 +88,21 @@

    Functions

    - - - - - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -165,12 +113,64 @@ - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    druid:create(component, ...)Create new druid component
    druid:initialize(table, table) Druid class constructor
    druid:new_back_handler(...)Create back_handler basic componentdruid:create(component, ...)Create new druid component
    druid:new_blocker(...)Create blocker basic componentdruid:remove(component)Remove component from druid instance.
    druid:new_button(...)Create button basic component
    druid:new_checkbox(...)Create checkbox basic component
    druid:new_checkbox_group(...)Create checkbox_group basic component
    druid:new_grid(...)Create grid basic component
    druid:new_hover(...)Create hover basic component
    druid:new_input(...)Create input basic component
    druid:new_lang_text(...)Create lang_text basic component
    druid:new_progress(...)Create progress basic component
    druid:new_radio_group(...)Create radio_group basic component
    druid:new_scroll(...)Create scroll basic component
    druid:new_slider(...)Create slider basic component
    druid:new_text(...)Create text basic component
    druid:new_timer(...)Create timer basic componentdruid:update(dt)Druid update function
    druid:on_input(action_id, action)Druid on_message function
    druid:remove(component)Remove component from druid instance.druid:new_button(...)Create button basic component
    druid:update(dt)Druid update functiondruid:new_blocker(...)Create blocker basic component
    druid:new_back_handler(...)Create back_handler basic component
    druid:new_hover(...)Create hover basic component
    druid:new_text(...)Create text basic component
    druid:new_lang_text(...)Create lang_text basic component
    druid:new_timer(...)Create timer basic component
    druid:new_progress(...)Create progress basic component
    druid:new_grid(...)Create grid basic component
    druid:new_scroll(...)Create scroll basic component
    druid:new_slider(...)Create slider basic component
    druid:new_checkbox(...)Create checkbox basic component
    druid:new_input(...)Create input basic component
    druid:new_checkbox_group(...)Create checkbox_group basic component
    druid:new_radio_group(...)Create radio_group basic component
    @@ -181,31 +181,6 @@

    Functions

    -
    - - druid:create(component, ...) -
    -
    - Create new druid component - - -

    Parameters:

    -
      -
    • component - Component - Component module -
    • -
    • ... - args - Other component params to pass it to component:init function -
    • -
    - - - - - -
    druid:initialize(table, table) @@ -232,18 +207,140 @@
    - - druid:new_back_handler(...) + + druid:create(component, ...)
    - Create back_handler basic component + Create new druid component + + +

    Parameters:

    +
      +
    • component + Component + Component module +
    • +
    • ... + args + Other component params to pass it to component:init function +
    • +
    + + + + + +
    +
    + + druid:remove(component) +
    +
    + Remove component from druid instance. + Component on_remove function will be invoked, if exist. + + +

    Parameters:

    +
      +
    • component + Component + Component instance +
    • +
    + + + + + +
    +
    + + druid:update(dt) +
    +
    + Druid update function + + +

    Parameters:

    +
      +
    • dt + number + Delta time +
    • +
    + + + + + +
    +
    + + druid:on_input(action_id, action) +
    +
    + Druid on_input function + + +

    Parameters:

    +
      +
    • action_id + hash + Actionid from oninput +
    • +
    • action + table + Action from on_input +
    • +
    + + + + + +
    +
    + + druid:on_message(message_id, message, sender) +
    +
    + Druid on_message function + + +

    Parameters:

    +
      +
    • message_id + hash + Messageid from onmessage +
    • +
    • message + table + Message from on_message +
    • +
    • sender + hash + Sender from on_message +
    • +
    + + + + + +
    +
    + + druid:new_button(...) +
    +
    + Create button basic component

    Parameters:

    • ... args - back_handler init args + button init args
    @@ -251,7 +348,7 @@
      Component - back_handler component + button component
    @@ -286,18 +383,18 @@
    - - druid:new_button(...) + + druid:new_back_handler(...)
    - Create button basic component + Create back_handler basic component

    Parameters:

    • ... args - button init args + back_handler init args
    @@ -305,88 +402,7 @@
      Component - button component -
    - - - - -
    -
    - - druid:new_checkbox(...) -
    -
    - Create checkbox basic component - - -

    Parameters:

    -
      -
    • ... - args - checkbox init args -
    • -
    - -

    Returns:

    -
      - - Component - checkbox component -
    - - - - -
    -
    - - druid:new_checkbox_group(...) -
    -
    - Create checkbox_group basic component - - -

    Parameters:

    -
      -
    • ... - args - checkbox_group init args -
    • -
    - -

    Returns:

    -
      - - Component - checkbox_group component -
    - - - - -
    -
    - - druid:new_grid(...) -
    -
    - Create grid basic component - - -

    Parameters:

    -
      -
    • ... - args - grid init args -
    • -
    - -

    Returns:

    -
      - - Component - grid component + back_handler component
    @@ -421,18 +437,18 @@
    - - druid:new_input(...) + + druid:new_text(...)
    - Create input basic component + Create text basic component

    Parameters:

    • ... args - input init args + text init args
    @@ -440,7 +456,7 @@
      Component - input component + text component
    @@ -473,6 +489,33 @@ +
    +
    + + druid:new_timer(...) +
    +
    + Create timer basic component + + +

    Parameters:

    +
      +
    • ... + args + timer init args +
    • +
    + +

    Returns:

    +
      + + Component + timer component +
    + + + +
    @@ -502,18 +545,18 @@
    - - druid:new_radio_group(...) + + druid:new_grid(...)
    - Create radio_group basic component + Create grid basic component

    Parameters:

    • ... args - radio_group init args + grid init args
    @@ -521,7 +564,7 @@
      Component - radio_group component + grid component
    @@ -583,18 +626,18 @@
    - - druid:new_text(...) + + druid:new_checkbox(...)
    - Create text basic component + Create checkbox basic component

    Parameters:

    • ... args - text init args + checkbox init args
    @@ -602,7 +645,7 @@
      Component - text component + checkbox component
    @@ -610,18 +653,18 @@
    - - druid:new_timer(...) + + druid:new_input(...)
    - Create timer basic component + Create input basic component

    Parameters:

    • ... args - timer init args + input init args
    @@ -629,7 +672,7 @@
      Component - timer component + input component
    @@ -637,97 +680,54 @@
    - - druid:on_input(action_id, action) + + druid:new_checkbox_group(...)
    - Druid on_input function + Create checkbox_group basic component

    Parameters:

      -
    • action_id - hash - Actionid from oninput -
    • -
    • action - table - Action from on_input +
    • ... + args + checkbox_group init args
    +

    Returns:

    +
      + + Component + checkbox_group component +
    - - druid:on_message(message_id, message, sender) + + druid:new_radio_group(...)
    - Druid on_message function + Create radio_group basic component

    Parameters:

      -
    • message_id - hash - Messageid from onmessage -
    • -
    • message - table - Message from on_message -
    • -
    • sender - hash - Sender from on_message +
    • ... + args + radio_group init args
    +

    Returns:

    +
      - - - -
    -
    - - druid:remove(component) -
    -
    - Remove component from druid instance. - Component on_remove function will be invoked, if exist. - - -

    Parameters:

    -
      -
    • component - Component - Component instance -
    • -
    - - - - - -
    -
    - - druid:update(dt) -
    -
    - Druid update function - - -

    Parameters:

    -
      -
    • dt - number - Delta time -
    • -
    - + Component + radio_group component + @@ -740,7 +740,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 13:01:03 +Last updated 2020-02-23 22:54:59
    diff --git a/druid/base/button.lua b/druid/base/button.lua index 22f55b2..34f8f37 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -2,15 +2,27 @@ -- @module druid.button --- Component events --- @tfield druid_event on_click --- @tfield druid_event on_hold_click --- @tfield druid_event on_long_click --- @tfield druid_event on_double_click --- @table events +-- @table Events +-- @tfield druid_event on_click On release button callback +-- @tfield druid_event on_repeated_click On repeated action button callback +-- @tfield druid_event on_long_click On long tap button callback +-- @tfield druid_event on_double_click On double tap button callback --- Component fields --- @tfield node Main node --- @table fields +-- @table Fields +-- @tfield node node Trigger node +-- @tfield[opt=node] node anim_node Animation node +-- @tfield vector3 scale_from Initial scale of anim_node +-- @tfield vector3 pos Initial pos of anim_node +-- @tfield any params Params to click callbacks +-- @tfield boolean hover_anim Is hover anim enabled +-- @tfield druid.hover hover Druid hover logic component +-- @tfield[opt] node click_zone Restriction zone + +--- Component style params +-- @table Style +-- @tfield function on_click (self, node) +-- @tfield function on_hover (self, node, hover_state) local Event = require("druid.event") local const = require("druid.const") @@ -36,7 +48,7 @@ local function on_button_release(self) if self.style.on_click then self.style.on_click(self, self.anim_node) end - self.callback(self:get_context(), self.params, self) + self.on_click:trigger(self:get_context(), self.params, self) end return true else @@ -66,19 +78,21 @@ function M.init(self, node, callback, params, anim_node, event) self.anim_node = anim_node and helper:get_node(anim_node) or self.node -- TODO: rename to start_scale self.scale_from = gui.get_scale(self.anim_node) - self.pos = gui.get_position(self.anim_node) - self.callback = callback self.params = params self.hover_anim = self.style.IS_HOVER self.hover = self.druid:new_hover(node, self, on_button_hover) + self.click_zone = nil -- Event stubs self.on_click = Event() - self.on_hold_click = Event() + self.on_repeated_click = Event() self.on_long_click = Event() self.on_double_click = Event() - self.click_zone = nil + if callback then + self.on_click:subscribe(callback) + end + end @@ -166,28 +180,4 @@ function M.get_key_trigger(self) end ---- Set usual button callback -function M.set_callback(self, callback) - -end - - ---- Repeat callback always, while holding button -function M.set_hold_callback(self, callback) - -end - - ---- Get doubletap callback on this button -function M.set_double_tap_callback(self, callback) - -end - - ---- Single callbacka after long_tap. No usual callback invoked -function M.set_long_tap_callback(self, callback) - -end - - return M diff --git a/druid/component.lua b/druid/component.lua index 8b9caf5..bc49060 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -9,26 +9,6 @@ local class = require("druid.system.middleclass") local Component = class("druid.component") ---- Setup component context and his style table --- @function component:setup_component --- @tparam context table Druid context. Usually it is self of script --- @tparam style table Druid style module --- @treturn Component Component itself -function Component.setup_component(self, context, style) - self._meta = { - template = nil, - context = nil, - nodes = nil, - style = nil, - } - - self:set_context(context) - self:set_style(style) - - return self -end - - --- Get current component style table -- @function component:get_style -- @treturn table Component style table @@ -136,6 +116,26 @@ function Component.get_druid(self) end +--- Setup component context and his style table +-- @function component:setup_component +-- @tparam context table Druid context. Usually it is self of script +-- @tparam style table Druid style module +-- @treturn Component Component itself +function Component.setup_component(self, context, style) + self._meta = { + template = nil, + context = nil, + nodes = nil, + style = nil, + } + + self:set_context(context) + self:set_style(style) + + return self +end + + --- Basic constructor of component. It will call automaticaly -- by `Component.static.create` -- @function component:initialize diff --git a/druid/event.lua b/druid/event.lua index baccb8e..8b3350e 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -12,13 +12,20 @@ function M.initialize(self) end +--- Subscribe callback on event +-- @function event:subscribe +-- @tparam function callback Callback itself function M.subscribe(self, callback) + assert(type(self) == "table", "You should subscribe to event with : syntax") assert(type(callback) == "function", "Callback should be function") table.insert(self._callbacks, callback) end +--- Unsubscribe callback on event +-- @function event:unsubscribe +-- @tparam function callback Callback itself function M.unsubscribe(self, callback) for i = 1, #self._callbacks do if self._callbacks[i] == callback then @@ -29,6 +36,9 @@ function M.unsubscribe(self, callback) end +--- Trigger the event and call all subscribed callbacks +-- @function event:trigger +-- @param ... All event params function M.trigger(self, ...) for i = 1, #self._callbacks do self._callbacks[i](...) From a81d49de9d74ad7872d9e834651a8a69880835dc Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 00:03:29 +0300 Subject: [PATCH 114/136] Rename bounce -> default style, start make new example pages --- docs/index.html | 2 +- docs/modules/component.html | 2 +- docs/modules/druid.back_handler.html | 2 +- docs/modules/druid.blocker.html | 2 +- docs/modules/druid.button.html | 16 +++++++++++++++- docs/modules/druid.checkbox.html | 2 +- docs/modules/druid.checkbox_group.html | 2 +- docs/modules/druid.grid.html | 2 +- docs/modules/druid.helper.html | 2 +- docs/modules/druid.html | 2 +- docs/modules/druid.input.html | 2 +- docs/modules/druid.lang_text.html | 2 +- docs/modules/druid.progress.html | 2 +- docs/modules/druid.radio_group.html | 2 +- docs/modules/druid.scroll.html | 2 +- docs/modules/druid.slider.html | 2 +- docs/modules/druid.text.html | 2 +- docs/modules/druid.timer.html | 2 +- docs/modules/druid_event.html | 2 +- docs/modules/druid_instance.html | 2 +- druid/base/button.lua | 6 ++++++ druid/styles/{bounce => default}/anims.lua | 0 druid/styles/{bounce => default}/style.lua | 2 +- example/kenney/gui/main/main.gui_script | 8 +++++--- example/kenney/lang.lua | 4 ++++ 25 files changed, 50 insertions(+), 24 deletions(-) rename druid/styles/{bounce => default}/anims.lua (100%) rename druid/styles/{bounce => default}/style.lua (97%) diff --git a/docs/index.html b/docs/index.html index e865552..8e850b0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -145,7 +145,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/component.html b/docs/modules/component.html index a05a234..03ef47b 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -396,7 +396,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 66d587d..2943f1f 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -151,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 46ce82d..ad72a4e 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 82fe0ef..886be31 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -328,9 +328,23 @@ function (self, node) +
  • on_click_disabled + function + (self, node) +
  • on_hover function (self, node, hover_state) +
  • +
  • on_set_enabled + function + (self, node, enabled_state) +
  • +
  • IS_HOVER + bool + + +
  • @@ -346,7 +360,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index bfe3b2a..66054fe 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index e492ef9..1c40d26 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 6914a07..69dee2b 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -75,7 +75,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.helper.html b/docs/modules/druid.helper.html index ae45827..c81e977 100644 --- a/docs/modules/druid.helper.html +++ b/docs/modules/druid.helper.html @@ -226,7 +226,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 66d2c54..46038ef 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -171,7 +171,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.input.html b/docs/modules/druid.input.html index 3c37497..da6d315 100644 --- a/docs/modules/druid.input.html +++ b/docs/modules/druid.input.html @@ -151,7 +151,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.lang_text.html b/docs/modules/druid.lang_text.html index 2c02a82..9f52f6b 100644 --- a/docs/modules/druid.lang_text.html +++ b/docs/modules/druid.lang_text.html @@ -118,7 +118,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index 2b0ede6..e8e1115 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -296,7 +296,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index 082f70a..5d71a85 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index 81b1019..551ceb5 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -276,7 +276,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index 03e14f1..a4abba6 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -77,7 +77,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index 41d09ef..6df4131 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -235,7 +235,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index 242b9b2..8fef622 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -179,7 +179,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid_event.html b/docs/modules/druid_event.html index 37e3a1c..dc54081 100644 --- a/docs/modules/druid_event.html +++ b/docs/modules/druid_event.html @@ -162,7 +162,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index f3df01a..732fba4 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -740,7 +740,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-23 22:54:59 +Last updated 2020-02-24 00:03:02
    diff --git a/druid/base/button.lua b/druid/base/button.lua index 34f8f37..bacc089 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,6 +1,9 @@ --- Component to handle basic GUI button -- @module druid.button +--- Button gui component +--@class druid + --- Component events -- @table Events -- @tfield druid_event on_click On release button callback @@ -22,7 +25,10 @@ --- Component style params -- @table Style -- @tfield function on_click (self, node) +-- @tfield function on_click_disabled (self, node) -- @tfield function on_hover (self, node, hover_state) +-- @tfield function on_set_enabled (self, node, enabled_state) +-- @tfield bool IS_HOVER local Event = require("druid.event") local const = require("druid.const") diff --git a/druid/styles/bounce/anims.lua b/druid/styles/default/anims.lua similarity index 100% rename from druid/styles/bounce/anims.lua rename to druid/styles/default/anims.lua diff --git a/druid/styles/bounce/style.lua b/druid/styles/default/style.lua similarity index 97% rename from druid/styles/bounce/style.lua rename to druid/styles/default/style.lua index e9d93bf..d9a7d46 100644 --- a/druid/styles/bounce/style.lua +++ b/druid/styles/default/style.lua @@ -1,5 +1,5 @@ local settings = require("druid.system.settings") -local anims = require("druid.styles.bounce.anims") +local anims = require("druid.styles.default.anims") local M = {} diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 357e8b3..30fd8af 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -1,14 +1,16 @@ local druid = require("druid.druid") local empty_style = require("druid.styles.empty.style") -local bounce_style = require("druid.styles.bounce.style") +local default_style = require("druid.styles.default.style") local main_page = require("example.kenney.page.main") local text_page = require("example.kenney.page.texts") local pages = { "main_page", - "texts_page" + "texts_page", + "button_page", + "scroll_page", } local function on_control_button(self, delta) @@ -34,7 +36,7 @@ end function init(self) - druid.set_default_style(bounce_style) + druid.set_default_style(default_style) self.druid = druid.new(self) init_top_panel(self) diff --git a/example/kenney/lang.lua b/example/kenney/lang.lua index 43f0f91..c7eb298 100644 --- a/example/kenney/lang.lua +++ b/example/kenney/lang.lua @@ -5,6 +5,8 @@ local M = {} local en = { main_page = "Main page", texts_page = "Text page", + button_page = "Button page", + scroll_page = "Scroll page", ui_section_button = "Button", ui_section_text = "Text", ui_section_timer = "Timer", @@ -19,6 +21,8 @@ local en = { local ru = { main_page = "Основное", texts_page = "Текст", + button_page = "Кнопки", + scroll_page = "Скролл", ui_section_button = "Кнопка", ui_section_text = "Текст", ui_section_timer = "Таймер", From ac2bbc29d3812bb4bdb42e32947df67dac1cc213 Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 09:34:16 +0300 Subject: [PATCH 115/136] Add druid events in components --- druid/base/back_handler.lua | 5 +- druid/base/blocker.lua | 14 + druid/base/button.lua | 9 +- druid/base/checkbox.lua | 5 +- druid/base/checkbox_group.lua | 13 +- druid/base/grid.lua | 10 + druid/base/hover.lua | 6 +- druid/base/slider.lua | 8 +- druid/base/text.lua | 11 + druid/base/timer.lua | 17 +- druid/event.lua | 9 +- example/kenney/gui/main/main.gui | 909 ++++++++++++++++++++++++ example/kenney/gui/main/main.gui_script | 4 + example/kenney/page/button.lua | 23 + example/kenney/page/scroll.lua | 8 + 15 files changed, 1019 insertions(+), 32 deletions(-) create mode 100644 example/kenney/page/button.lua create mode 100644 example/kenney/page/scroll.lua diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 70cd190..2431f80 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -1,6 +1,7 @@ --- Component to handle back key (android, backspace) -- @module druid.back_handler +local Event = require("druid.event") local const = require("druid.const") local component = require("druid.component") @@ -15,6 +16,8 @@ local M = component.create("back_handler", { const.ON_INPUT }) function M.init(self, callback, params) self.callback = callback self.params = params + + self.on_back = Event(callback) end @@ -24,7 +27,7 @@ end -- @tparam table action on_input action function M.on_input(self, action_id, action) if action_id == const.ACTION_BACK and action[const.RELEASED] then - self.callback(self:get_context(), self.params) + self.on_back:trigger(self:get_context(), self.params) return true end diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index d03fc3f..303d703 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -1,6 +1,7 @@ --- Component to block input on specify zone (node) -- @module druid.blocker +local Event = require("druid.event") local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") @@ -10,6 +11,9 @@ local M = component.create("blocker", { const.ON_INPUT_HIGH }) function M.init(self, node) self.node = self:get_node(node) + + self.on_click = Event() + self.on_enable_change = Event() end @@ -30,4 +34,14 @@ function M.on_input(self, action_id, action) end +function M.set_enabled(self, state) + +end + + +function M.is_enabled(self, state) + +end + + return M diff --git a/druid/base/button.lua b/druid/base/button.lua index bacc089..a24d24d 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -75,8 +75,6 @@ end -- @tparam[opt] node anim_node Button anim node (node, if not provided) -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) - assert(callback, "Button should have callback. To block input on zone use blocker component") - self.druid = self:get_druid() self.style = self:get_style() self.node = self:get_node(node) @@ -90,15 +88,10 @@ function M.init(self, node, callback, params, anim_node, event) self.click_zone = nil -- Event stubs - self.on_click = Event() + self.on_click = Event(callback) self.on_repeated_click = Event() self.on_long_click = Event() self.on_double_click = Event() - - if callback then - self.on_click:subscribe(callback) - end - end diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 707e6ea..723decd 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -1,6 +1,7 @@ --- Druid checkbox component -- @module druid.checkbox +local Event = require("druid.event") local component = require("druid.component") local M = component.create("checkbox") @@ -17,7 +18,7 @@ function M.set_state(self, state, is_silence) end if not is_silence and self.callback then - self.callback(self:get_context(), state) + self.on_change_state:trigger(self:get_context(), state) end end @@ -41,6 +42,8 @@ function M.init(self, node, callback, click_node) self.button = self.druid:new_button(self.click_node or self.node, on_click) M.set_state(self, false, true) + + self.on_change_state = Event(callback) end diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 90f9481..3f5ed11 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,18 +1,12 @@ --- Checkboux group module -- @module druid.checkbox_group +local Event = require("druid.event") local component = require("druid.component") local M = component.create("checkbox_group") -local function on_checkbox_click(self, index) - if self.callback then - self.callback(self:get_context(), index) - end -end - - function M.set_state(self, indexes) for i = 1, #indexes do if self.checkboxes[i] then @@ -36,12 +30,13 @@ end function M.init(self, nodes, callback, click_nodes) self.druid = self:get_druid() self.checkboxes = {} - self.callback = callback + + self.on_checkbox_click = Event(callback) for i = 1, #nodes do local click_node = click_nodes and click_nodes[i] or nil local checkbox = self.druid:new_checkbox(nodes[i], function() - on_checkbox_click(self, i) + self.on_checkbox_click:trigger(self:get_context(), i) end, click_node) table.insert(self.checkboxes, checkbox) diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 6ba4e7e..31ad635 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -2,6 +2,7 @@ -- Grid can anchor your elements, get content size and other -- @module druid.grid +local Event = require("druid.event") local component = require("druid.component") local M = component.create("grid") @@ -17,6 +18,11 @@ function M.init(self, parent, element, in_row) self.node_size = gui.get_size(self:get_node(element)) self.border = vmath.vector4(0) self.border_offset = vmath.vector3(0) + + self.on_add_item = Event() + self.on_remove_item = Event() + self.on_clear = Event() + self.on_update_positions = Event() end @@ -59,6 +65,8 @@ local function update_pos(self) local node = self.nodes[i] gui.set_position(node, get_pos(self, i)) end + + self.on_update_positions:trigger(self:get_context()) end @@ -82,6 +90,8 @@ function M.add(self, item, index) local pos = get_pos(self, index) check_border(self, pos) update_pos(self) + + self.on_add_item:trigger(self:get_context(), item, index) end diff --git a/druid/base/hover.lua b/druid/base/hover.lua index 71a15bc..42af7d4 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -20,10 +20,8 @@ function M.init(self, node, context, on_hover_callback) self._is_hovered = false self.context = context - self.on_hover = Event() - if on_hover_callback then - self.on_hover:subscribe(on_hover_callback) - end + + self.on_hover = Event(on_hover_callback) end diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 80a8534..6fd3f9f 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -1,6 +1,7 @@ --- Druid slider component -- @module druid.slider +local Event = require("druid.event") local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.component") @@ -9,9 +10,7 @@ local M = component.create("slider", { const.ON_INPUT_HIGH }) local function on_change_value(self) - if self.callback then - self.callback(self:get_context(), self.value) - end + self.on_change_value:trigger(self:get_context(), self.value) end @@ -26,7 +25,8 @@ function M.init(self, node, end_pos, callback) self.dist = self.end_pos - self.start_pos self.is_drag = false self.value = 0 - self.callback = callback + + self.on_change_value = Event(callback) assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal") end diff --git a/druid/base/text.lua b/druid/base/text.lua index 72307d8..2cee229 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -2,6 +2,7 @@ -- Good working with localization system -- @module druid.text +local Event = require("druid.event") local const = require("druid.const") local component = require("druid.component") @@ -25,6 +26,10 @@ function M.init(self, node, value, no_adjust) self.is_no_adjust = no_adjust self.last_color = gui.get_color(self.node) + self.on_set_text = Event() + self.on_update_text_scale = Event() + self.on_set_pivot = Event() + self:set_to(value or 0) return self end @@ -47,6 +52,8 @@ local function update_text_area_size(self) local new_scale = vmath.vector3(scale_modifier, scale_modifier, cur_scale.z) gui.set_scale(self.node, new_scale) self.scale = new_scale + + self.on_update_text_scale:trigger(self:get_context(), new_scale) end @@ -58,6 +65,8 @@ function M.set_to(self, set_to) self.last_value = set_to gui.set_text(self.node, set_to) + self.on_set_text:trigger(self:get_context(), set_to) + if not self.is_no_adjust then update_text_area_size(self) end @@ -114,6 +123,8 @@ function M.set_pivot(self, pivot) self.pos = self.pos + pos_offset gui.set_position(self.node, self.pos) + + self.on_set_pivot:trigger(self:get_context(), pivot) end diff --git a/druid/base/timer.lua b/druid/base/timer.lua index efd8fc9..8fecf86 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,6 +1,7 @@ --- Component to handle GUI timers -- @module druid.timer +local Event = require("druid.event") local const = require("druid.const") local formats = require("druid.helper.formats") local helper = require("druid.helper") @@ -13,16 +14,19 @@ function M.init(self, node, seconds_from, seconds_to, callback) self.node = self:get_node(node) seconds_from = math.max(seconds_from, 0) seconds_to = math.max(seconds_to or 0, 0) - callback = callback or const.EMPTY_FUNCTION + + self.on_tick = Event() + self.on_set_enabled = Event() + self.on_timer_end = Event(callback) self:set_to(seconds_from) self:set_interval(seconds_from, seconds_to) - self.callback = callback if seconds_to - seconds_from == 0 then self:set_state(false) - self.callback(self:get_context(), self) + self.on_timer_end:trigger(self:get_context(), self) end + return self end @@ -43,6 +47,8 @@ end -- @tparam boolean is_on Timer enable state function M.set_state(self, is_on) self.is_on = is_on + + self.on_set_enabled:trigger(self:get_context(), is_on) end @@ -73,9 +79,12 @@ function M.update(self, dt) self.temp = self.temp - dist self.value = helper.step(self.value, self.target, 1) M.set_to(self, self.value) + + self.on_tick:trigger(self:get_context(), self.value) + if self.value == self.target then self:set_state(false) - self.callback(self:get_context(), self) + self.on_timer_end:trigger(self:get_context(), self) end end end diff --git a/druid/event.lua b/druid/event.lua index 8b3350e..d38761e 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -7,8 +7,15 @@ local class = require("druid.system.middleclass") local M = class("druid.event") -function M.initialize(self) +--- Event constructur +-- @function Event +-- @tparam function initial_callback Subscribe the callback on new event, if callback exist +function M.initialize(self, initial_callback) self._callbacks = {} + + if initial_callback then + self:subscribe(initial_callback) + end end diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index 0d74dfd..1ba3e11 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -3981,6 +3981,915 @@ 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: "kenney/empty" + id: "button_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "C_Anchor" + 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: -200.0 + y: 280.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_usual" + parent: "button_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_usual/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_usual" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Usual" + font: "game" + id: "button_usual/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_usual/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 8 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -200.0 + y: 180.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_custom_style" + parent: "button_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_custom_style/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_custom_style" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.5 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Custom Style" + font: "game" + id: "button_custom_style/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_custom_style/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 3 + overridden_fields: 8 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -200.0 + y: 80.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_long_tap" + parent: "button_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_long_tap/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_long_tap" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Long tap" + font: "game" + id: "button_long_tap/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_long_tap/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 3 + overridden_fields: 8 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -200.0 + y: -20.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_repeated_tap" + parent: "button_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_repeated_tap/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_repeated_tap" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Repeated" + font: "game" + id: "button_repeated_tap/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_repeated_tap/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 3 + overridden_fields: 8 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -200.0 + y: -120.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_double_tap" + parent: "button_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_double_tap/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_double_tap" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Double tap" + font: "game" + id: "button_double_tap/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_double_tap/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 3 + overridden_fields: 8 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 1800.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: "kenney/empty" + id: "scroll_page" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_STRETCH + parent: "C_Anchor" + 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: 0.0 diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 30fd8af..8760379 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -5,6 +5,8 @@ local default_style = require("druid.styles.default.style") local main_page = require("example.kenney.page.main") local text_page = require("example.kenney.page.texts") +local button_page = require("example.kenney.page.button") +local scroll_page = require("example.kenney.page.scroll") local pages = { "main_page", @@ -43,6 +45,8 @@ function init(self) self.page = 1 main_page.setup_page(self) text_page.setup_page(self) + button_page.setup_page(self) + scroll_page.setup_page(self) end diff --git a/example/kenney/page/button.lua b/example/kenney/page/button.lua new file mode 100644 index 0000000..308b1eb --- /dev/null +++ b/example/kenney/page/button.lua @@ -0,0 +1,23 @@ +local sprite_change_style = {} + +local M = {} + + +local function setup_buttons(self) + self.druid:new_button("button_usual/button") + + local custom_style = self.druid:new_button("button_custom_style/button") + custom_style:set_style(sprite_change_style) + + -- HOVER_IMAGE and DEFAULT_IMAGE - from our custom style params + custom_style.HOVER_IMAGE = "button_yellow" + custom_style.DEFAULT_IMAGE = "button_blue" +end + + +function M.setup_page(self) + setup_buttons(self) +end + + +return M diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua new file mode 100644 index 0000000..8f56646 --- /dev/null +++ b/example/kenney/page/scroll.lua @@ -0,0 +1,8 @@ +local M = {} + + +function M.setup_page(self) +end + + +return M From d28b77bc9a4f442faa77c32dc17723db32533a9d Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 09:40:09 +0300 Subject: [PATCH 116/136] Hover context remove (get from get_context()) --- druid/base/button.lua | 2 +- druid/base/hover.lua | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index a24d24d..4bcf9f6 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -84,7 +84,7 @@ function M.init(self, node, callback, params, anim_node, event) self.scale_from = gui.get_scale(self.anim_node) self.params = params self.hover_anim = self.style.IS_HOVER - self.hover = self.druid:new_hover(node, self, on_button_hover) + self.hover = self.druid:new_hover(node, on_button_hover) self.click_zone = nil -- Event stubs diff --git a/druid/base/hover.lua b/druid/base/hover.lua index 42af7d4..5f04feb 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -14,12 +14,11 @@ local M = component.create("hover", { const.ON_INPUT }) -- @tparam table self Component instance -- @tparam node node Gui node -- @tparam function on_hover_callback Hover callback -function M.init(self, node, context, on_hover_callback) +function M.init(self, node, on_hover_callback) self.style = self:get_style() self.node = self:get_node(node) self._is_hovered = false - self.context = context self.on_hover = Event(on_hover_callback) end @@ -28,7 +27,7 @@ end local function set_hover(self, state) if self._is_hovered ~= state then self._is_hovered = state - self.on_hover:trigger(self.context, state) + self.on_hover:trigger(self:get_context(), state) end end From b1fbb7c5bf08200e6d3f505e215aab9f4765e033 Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 20:29:56 +0300 Subject: [PATCH 117/136] Add simple scroll events --- druid/base/scroll.lua | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index b5382ca..193a089 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -1,6 +1,7 @@ --- Component to handle scroll content -- @module druid.scroll +local Event = require("druid.event") local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.component") @@ -41,14 +42,21 @@ function M.init(self, scroll_parent, input_zone, border) } self:set_border(border) + + self.on_scroll = Event() + self.on_scroll_to = Event() + self.on_point_scroll = Event() end local function set_pos(self, pos) - self.pos.x = pos.x - self.pos.y = pos.y + if self.pos.x ~= pos.x or self.pos.y ~= pos.y then + self.pos.x = pos.x + self.pos.y = pos.y + gui.set_position(self.node, self.pos) - gui.set_position(self.node, self.pos) + self.on_scroll:trigger(self:get_context(), self.pos) + end end @@ -337,6 +345,8 @@ function M.scroll_to(self, point, is_instant) set_pos(self, target) end) end + + self.on_scroll_to:trigger(self:get_context(), point, is_instant) end @@ -351,8 +361,8 @@ function M.scroll_to_index(self, index, skip_cb) if self.selected ~= index then self.selected = index - if not skip_cb and self.on_point_callback then - self.on_point_callback(self:get_context(), index, self.points[index]) + if not skip_cb then + self.on_point_scroll:trigger(self:get_context(), index, self.points[index]) end end @@ -395,7 +405,7 @@ end -- @tparam table self Component instance -- @tparam function callback Callback on scroll to point of interest function M.on_point_move(self, callback) - self.on_point_callback = callback + self.on_point_scroll:subscribe(callback) end From 162bbd0ed982215e5a51515f4fb5f53150ec5fd3 Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 23:36:44 +0300 Subject: [PATCH 118/136] Add more events on button (long_tap, repeated_tap, double_tap) --- druid/base/button.lua | 78 +++++++++++++++++++++++-- druid/event.lua | 15 +++++ druid/styles/default/style.lua | 2 + druid/styles/empty/style.lua | 2 + example/kenney/gui/main/main.gui_script | 5 +- example/kenney/page/button.lua | 30 +++++++++- 6 files changed, 122 insertions(+), 10 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index 4bcf9f6..abe994f 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -47,14 +47,67 @@ local function on_button_hover(self, hover_state) end +local function on_button_click(self) + if self.style.on_click then + self.style.on_click(self, self.anim_node) + end + self.click_in_row = 1 + self.on_click:trigger(self:get_context(), self.params, self) +end + + +local function on_button_repeated_click(self) + if self.style.on_click then + self.style.on_click(self, self.anim_node) + end + self.click_in_row = self.click_in_row + 1 + self.on_repeated_click:trigger(self:get_context(), self.params, self) +end + + +local function on_button_long_click(self) + if self.style.on_click then + self.style.on_click(self, self.anim_node) + end + self.click_in_row = 1 + self.on_long_click:trigger(self:get_context(), self.params, self) +end + + +local function on_button_double_click(self) + if self.style.on_click then + self.style.on_click(self, self.anim_node) + end + self.click_in_row = self.click_in_row + 1 + self.on_double_click:trigger(self:get_context(), self.params, self) +end + + local function on_button_release(self) + if self.is_repeated_started then + return false + end + if not self.disabled then - if not self.stub and self.can_action then + if self.can_action then self.can_action = false - if self.style.on_click then - self.style.on_click(self, self.anim_node) + + local time = socket.gettime() + local is_long_click = (time - self.last_pressed_time) > self.style.LONGTAP_TIME + is_long_click = is_long_click and self.on_long_click:is_exist() + + local is_double_click = (time - self.last_released_time) < self.style.DOUBLETAP_TIME + is_double_click = is_double_click and self.on_double_click:is_exist() + + if is_long_click then + on_button_long_click(self) + elseif is_double_click then + on_button_double_click(self) + else + on_button_click(self) end - self.on_click:trigger(self:get_context(), self.params, self) + + self.last_released_time = time end return true else @@ -86,6 +139,10 @@ function M.init(self, node, callback, params, anim_node, event) self.hover_anim = self.style.IS_HOVER self.hover = self.druid:new_hover(node, on_button_hover) self.click_zone = nil + self.is_repeated_started = false + self.last_pressed_time = 0 + self.last_released_time = 0 + self.click_in_row = 0 -- Event stubs self.on_click = Event(callback) @@ -118,10 +175,20 @@ function M.on_input(self, action_id, action) if action.pressed then -- Can interact if start touch on the button self.can_action = true - self.repeated_counter = 0 + self.is_repeated_started = false + self.last_pressed_time = socket.gettime() return true end + -- While hold button, repeat rate pick from input.repeat_interval + if action.repeated then + if not self.disabled and self.on_repeated_click:is_exist() and self.can_action then + self.is_repeated_started = true + on_button_repeated_click(self) + return true + end + end + if action.released then return on_button_release(self) end @@ -166,7 +233,6 @@ function M.set_click_zone(self, zone) end --- TODO: implement them all! --- Set key-code to trigger this button function M.set_key_trigger(self, key) diff --git a/druid/event.lua b/druid/event.lua index d38761e..1d6c289 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -43,6 +43,21 @@ function M.unsubscribe(self, callback) end +--- Return true, if event have at lease one handler +-- @function event:is_exist +-- @treturn boolean True if event have handlers +function M.is_exist(self) + return #self._callbacks > 0 +end + + +--- Clear the all event handlers +-- @function event:clear +function M.clear(self) + self._callbacks = {} +end + + --- Trigger the event and call all subscribed callbacks -- @function event:trigger -- @param ... All event params diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index d9a7d46..430c0fb 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -12,6 +12,8 @@ M["button"] = { BTN_SOUND_DISABLED = "click", DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), ENABLED_COLOR = vmath.vector4(1), + LONGTAP_TIME = 0.4, + DOUBLETAP_TIME = 0.4, IS_HOVER = true, on_hover = function(self, node, state) diff --git a/druid/styles/empty/style.lua b/druid/styles/empty/style.lua index 2ef9698..27a9a43 100644 --- a/druid/styles/empty/style.lua +++ b/druid/styles/empty/style.lua @@ -6,6 +6,8 @@ M["button"] = { BTN_SOUND_DISABLED = "click", DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), ENABLED_COLOR = vmath.vector4(1), + LONGTAP_TIME = 0.4, + DOUBLETAP_TIME = 0.4, IS_HOVER = false, } diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index 8760379..bd472e3 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -42,11 +42,14 @@ function init(self) self.druid = druid.new(self) init_top_panel(self) - self.page = 1 + self.page = 3 main_page.setup_page(self) text_page.setup_page(self) button_page.setup_page(self) scroll_page.setup_page(self) + + -- Refresh state + on_control_button(self, 0) end diff --git a/example/kenney/page/button.lua b/example/kenney/page/button.lua index 308b1eb..cdfad37 100644 --- a/example/kenney/page/button.lua +++ b/example/kenney/page/button.lua @@ -3,15 +3,39 @@ local sprite_change_style = {} local M = {} +local function usual_callback() + print("Usual callback") +end + +local function long_tap_callback() + print("Long tap callback") +end + +local function repeated_callback(self, params, button) + print("Repeated callback", button.click_in_row) +end + +local function double_tap_callback(self, params, button) + print("Double tap callback", button.click_in_row) +end + + local function setup_buttons(self) - self.druid:new_button("button_usual/button") + self.druid:new_button("button_usual/button", usual_callback) - local custom_style = self.druid:new_button("button_custom_style/button") + local custom_style = self.druid:new_button("button_custom_style/button", usual_callback) custom_style:set_style(sprite_change_style) - -- HOVER_IMAGE and DEFAULT_IMAGE - from our custom style params custom_style.HOVER_IMAGE = "button_yellow" custom_style.DEFAULT_IMAGE = "button_blue" + + + self.druid:new_button("button_long_tap/button", usual_callback) + .on_long_click:subscribe(long_tap_callback) + self.druid:new_button("button_repeated_tap/button", usual_callback) + .on_repeated_click:subscribe(repeated_callback) + self.druid:new_button("button_double_tap/button", usual_callback) + .on_double_click:subscribe(double_tap_callback) end From 2d45573f02d9af4d0b8192677afda3075de46e91 Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 24 Feb 2020 23:56:57 +0300 Subject: [PATCH 119/136] Add key_trigger to the button --- druid/base/button.lua | 46 +++++++-- druid/base/hover.lua | 10 +- example/kenney/gui/main/main.gui | 160 +++++++++++++++++++++++++++++++ example/kenney/page/button.lua | 6 +- game.project | 3 + input/game.input_binding | 4 + 6 files changed, 216 insertions(+), 13 deletions(-) diff --git a/druid/base/button.lua b/druid/base/button.lua index abe994f..6edc540 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -38,6 +38,19 @@ local component = require("druid.component") local M = component.create("button", { const.ON_INPUT }) +local function is_input_match(self, action_id) + if action_id == const.ACTION_TOUCH then + return true + end + + if self.key_trigger and action_id == self.key_trigger then + return true + end + + return false +end + + local function on_button_hover(self, hover_state) if not self.style.on_hover then return @@ -57,6 +70,11 @@ end local function on_button_repeated_click(self) + if not self.is_repeated_started then + self.click_in_row = 0 + self.is_repeated_started = true + end + if self.style.on_click then self.style.on_click(self, self.anim_node) end @@ -143,6 +161,7 @@ function M.init(self, node, callback, params, anim_node, event) self.last_pressed_time = 0 self.last_released_time = 0 self.click_in_row = 0 + self.key_trigger = nil -- Event stubs self.on_click = Event(callback) @@ -153,17 +172,23 @@ end function M.on_input(self, action_id, action) - if action_id ~= const.ACTION_TOUCH then + if not is_input_match(self, action_id) then return false end + local is_key_trigger = (action_id == self.key_trigger) + if not helper.is_enabled(self.node) then return false end - local is_pick = gui.pick_node(self.node, action.x, action.y) - if self.click_zone then - is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y) + local is_pick = true + + if not is_key_trigger then + is_pick = gui.pick_node(self.node, action.x, action.y) + if self.click_zone then + is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y) + end end if not is_pick then @@ -172,6 +197,10 @@ function M.on_input(self, action_id, action) return false end + if is_key_trigger then + self.hover:set_hover(not action.released) + end + if action.pressed then -- Can interact if start touch on the button self.can_action = true @@ -183,7 +212,6 @@ function M.on_input(self, action_id, action) -- While hold button, repeat rate pick from input.repeat_interval if action.repeated then if not self.disabled and self.on_repeated_click:is_exist() and self.can_action then - self.is_repeated_started = true on_button_repeated_click(self) return true end @@ -234,14 +262,18 @@ end --- Set key-code to trigger this button +-- @function button:set_key_trigger +-- @tparam hash key The action_id of the key function M.set_key_trigger(self, key) - + self.key_trigger = hash(key) end --- Get key-code to trigger this button +-- @function button:get_key_trigger +-- @treturn hash The action_id of the key function M.get_key_trigger(self) - + return self.key_trigger end diff --git a/druid/base/hover.lua b/druid/base/hover.lua index 5f04feb..bf93a7b 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -24,7 +24,7 @@ function M.init(self, node, on_hover_callback) end -local function set_hover(self, state) +function M.set_hover(self, state) if self._is_hovered ~= state then self._is_hovered = state self.on_hover:trigger(self:get_context(), state) @@ -44,20 +44,20 @@ function M.on_input(self, action_id, action) local is_pick = gui.pick_node(self.node, action.x, action.y) if not is_pick then - set_hover(self, false) + M.set_hover(self, false) return false end if action.released then - set_hover(self, false) + M.set_hover(self, false) else - set_hover(self, true) + M.set_hover(self, true) end end function M.on_input_interrupt(self) - set_hover(self, false) + M.set_hover(self, false) end diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index 1ba3e11..be9af76 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -4835,6 +4835,166 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: -200.0 + y: -220.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEMPLATE + id: "button_key_trigger" + parent: "button_page" + layer: "" + inherit_alpha: true + alpha: 1.0 + template: "/example/kenney/templates/button.gui" + template_node_child: false +} +nodes { + position { + x: 0.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: 130.0 + y: 60.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: "kenney/button_blue" + id: "button_key_trigger/button" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "button_key_trigger" + layer: "" + inherit_alpha: true + slice9 { + x: 15.0 + y: 15.0 + z: 15.0 + w: 15.0 + } + clipping_mode: CLIPPING_MODE_NONE + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: true + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 7.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.5 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Press Space" + font: "game" + id: "button_key_trigger/text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + shadow { + x: 0.101960786 + y: 0.2 + z: 0.6 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "button_key_trigger/button" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 0.0 + shadow_alpha: 0.78 + overridden_fields: 3 + overridden_fields: 8 + template_node_child: true + text_leading: 1.0 + text_tracking: 0.0 +} nodes { position { x: 1800.0 diff --git a/example/kenney/page/button.lua b/example/kenney/page/button.lua index cdfad37..3ff56ff 100644 --- a/example/kenney/page/button.lua +++ b/example/kenney/page/button.lua @@ -29,13 +29,17 @@ local function setup_buttons(self) custom_style.HOVER_IMAGE = "button_yellow" custom_style.DEFAULT_IMAGE = "button_blue" - self.druid:new_button("button_long_tap/button", usual_callback) .on_long_click:subscribe(long_tap_callback) self.druid:new_button("button_repeated_tap/button", usual_callback) .on_repeated_click:subscribe(repeated_callback) self.druid:new_button("button_double_tap/button", usual_callback) .on_double_click:subscribe(double_tap_callback) + + local button_space = self.druid:new_button("button_key_trigger/button", usual_callback) + button_space:set_key_trigger("key_space") + button_space.on_long_click:subscribe(long_tap_callback) + button_space.on_double_click:subscribe(double_tap_callback) end diff --git a/game.project b/game.project index c918863..6e20bc6 100644 --- a/game.project +++ b/game.project @@ -17,3 +17,6 @@ include_dirs = druid [graphics] texture_profiles = /example/res/custom.texture_profiles +[input] +gamepads = /builtins/input/default.gamepadsc + diff --git a/input/game.input_binding b/input/game.input_binding index 4d43ca9..8700888 100644 --- a/input/game.input_binding +++ b/input/game.input_binding @@ -6,6 +6,10 @@ key_trigger { input: KEY_BACK action: "back" } +key_trigger { + input: KEY_SPACE + action: "key_space" +} mouse_trigger { input: MOUSE_BUTTON_1 action: "touch" From 09dbd66484892cf89c632d9871df18b2325866e5 Mon Sep 17 00:00:00 2001 From: Insality Date: Tue, 25 Feb 2020 00:13:54 +0300 Subject: [PATCH 120/136] Add click_zone to hover --- druid/base/button.lua | 1 + druid/base/hover.lua | 3 +++ 2 files changed, 4 insertions(+) diff --git a/druid/base/button.lua b/druid/base/button.lua index 6edc540..2b6e4bf 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -258,6 +258,7 @@ end -- @tparam node zone Gui node function M.set_click_zone(self, zone) self.click_zone = self:get_node(zone) + self.hover:set_click_zone(zone) end diff --git a/druid/base/hover.lua b/druid/base/hover.lua index bf93a7b..a535af9 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -42,6 +42,9 @@ function M.on_input(self, action_id, action) end local is_pick = gui.pick_node(self.node, action.x, action.y) + if self.click_zone then + is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y) + end if not is_pick then M.set_hover(self, false) From 5ea102d0aa898d80ecdfc5d8abf057d5e17063b7 Mon Sep 17 00:00:00 2001 From: Insality Date: Tue, 25 Feb 2020 00:26:53 +0300 Subject: [PATCH 121/136] To-do list changes --- alpha_todo.txt | 4 ++-- druid/base/button.lua | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/alpha_todo.txt b/alpha_todo.txt index cff23aa..fbbf68e 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -13,9 +13,9 @@ Simple to-do for Druid Alpha 0.2.0 - add init/remove stuff for every style in component. How to set custom sprites for button states? - add druid settings (add auto_focus input and other stuff) -- button add key trigger ++ button add key trigger - button polish, actions -- button and hover click restriction zone? ++ button and hover click restriction zone? - unify component api (get/set/to and other general stuff) - better callbacks for every components diff --git a/druid/base/button.lua b/druid/base/button.lua index 2b6e4bf..8733a39 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -176,14 +176,12 @@ function M.on_input(self, action_id, action) return false end - local is_key_trigger = (action_id == self.key_trigger) - if not helper.is_enabled(self.node) then return false end local is_pick = true - + local is_key_trigger = (action_id == self.key_trigger) if not is_key_trigger then is_pick = gui.pick_node(self.node, action.x, action.y) if self.click_zone then From 4634b7c686b41b629449f0c3657d4c964ce9b21a Mon Sep 17 00:00:00 2001 From: Insality Date: Tue, 25 Feb 2020 22:42:39 +0300 Subject: [PATCH 122/136] Button more events, more examples --- druid/base/button.lua | 70 +++++++++++++++++++--------------- druid/component.lua | 1 + druid/styles/default/style.lua | 9 ++--- druid/styles/sprites/style.lua | 52 +++++++++++++++++++++++++ example/kenney/page/button.lua | 28 +++++++------- 5 files changed, 112 insertions(+), 48 deletions(-) create mode 100644 druid/styles/sprites/style.lua diff --git a/druid/base/button.lua b/druid/base/button.lua index 8733a39..7b940d9 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -18,7 +18,6 @@ -- @tfield vector3 scale_from Initial scale of anim_node -- @tfield vector3 pos Initial pos of anim_node -- @tfield any params Params to click callbacks --- @tfield boolean hover_anim Is hover anim enabled -- @tfield druid.hover hover Druid hover logic component -- @tfield[opt] node click_zone Restriction zone @@ -52,17 +51,17 @@ end local function on_button_hover(self, hover_state) - if not self.style.on_hover then + if not self._style.on_hover then return end - self.style.on_hover(self, self.anim_node, hover_state) + self._style.on_hover(self, self.anim_node, hover_state) end local function on_button_click(self) - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = 1 self.on_click:trigger(self:get_context(), self.params, self) @@ -75,29 +74,35 @@ local function on_button_repeated_click(self) self.is_repeated_started = true end - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = self.click_in_row + 1 - self.on_repeated_click:trigger(self:get_context(), self.params, self) + self.on_repeated_click:trigger(self:get_context(), self.params, self, self.click_in_row) end local function on_button_long_click(self) - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = 1 - self.on_long_click:trigger(self:get_context(), self.params, self) + local time = socket.gettime() - self.last_pressed_time + self.on_long_click:trigger(self:get_context(), self.params, self, time) end local function on_button_double_click(self) - if self.style.on_click then - self.style.on_click(self, self.anim_node) + if self._style.on_click then + self._style.on_click(self, self.anim_node) end self.click_in_row = self.click_in_row + 1 - self.on_double_click:trigger(self:get_context(), self.params, self) + self.on_double_click:trigger(self:get_context(), self.params, self, self.click_in_row) +end + + +local function on_button_hold(self, press_time) + self.on_hold_callback:trigger(self:get_context(), self.params, self, press_time) end @@ -111,10 +116,10 @@ local function on_button_release(self) self.can_action = false local time = socket.gettime() - local is_long_click = (time - self.last_pressed_time) > self.style.LONGTAP_TIME + local is_long_click = (time - self.last_pressed_time) > self._style.LONGTAP_TIME is_long_click = is_long_click and self.on_long_click:is_exist() - local is_double_click = (time - self.last_released_time) < self.style.DOUBLETAP_TIME + local is_double_click = (time - self.last_released_time) < self._style.DOUBLETAP_TIME is_double_click = is_double_click and self.on_double_click:is_exist() if is_long_click then @@ -129,8 +134,8 @@ local function on_button_release(self) end return true else - if self.style.on_click_disabled then - self.style.on_click_disabled(self, self.anim_node) + if self._style.on_click_disabled then + self._style.on_click_disabled(self, self.anim_node) end return false end @@ -147,14 +152,12 @@ end -- @tparam[opt] string event Button react event, const.ACTION_TOUCH by default function M.init(self, node, callback, params, anim_node, event) self.druid = self:get_druid() - self.style = self:get_style() self.node = self:get_node(node) self.anim_node = anim_node and helper:get_node(anim_node) or self.node -- TODO: rename to start_scale self.scale_from = gui.get_scale(self.anim_node) self.params = params - self.hover_anim = self.style.IS_HOVER self.hover = self.druid:new_hover(node, on_button_hover) self.click_zone = nil self.is_repeated_started = false @@ -168,6 +171,7 @@ function M.init(self, node, callback, params, anim_node, event) self.on_repeated_click = Event() self.on_long_click = Event() self.on_double_click = Event() + self.on_hold_callback = Event() end @@ -219,6 +223,20 @@ function M.on_input(self, action_id, action) return on_button_release(self) end + if not self.disabled and self.can_action and self.on_long_click:is_exist() then + local press_time = socket.gettime() - self.last_pressed_time + + if self._style.AUTOHOLD_TRIGGER and self._style.AUTOHOLD_TRIGGER <= press_time then + on_button_release(self) + return true + end + + if press_time >= self._style.LONGTAP_TIME then + on_button_hold(self, press_time) + return true + end + end + return not self.disabled end @@ -230,8 +248,8 @@ end function M.set_enabled(self, state) self.disabled = not state - if self.style.on_set_enabled then - self.style.on_set_enabled(self, self.node, state) + if self._style.on_set_enabled then + self._style.on_set_enabled(self, self.node, state) end end @@ -241,14 +259,6 @@ function M.get_enabled(self) end ---- Disable all button animations --- @function button:disable_animation --- @tparam table self Component instance -function M.disable_animation(self) - self.hover_anim = false -end - - --- Strict button click area. Useful for -- no click events outside stencil node -- @function button:set_click_zone diff --git a/druid/component.lua b/druid/component.lua index bc49060..0e17adf 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -26,6 +26,7 @@ end -- @tparam table style Druid style module function Component.set_style(self, druid_style) self._meta.style = druid_style + self._style = self:get_style() end diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index 430c0fb..ee5d3ac 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -13,16 +13,15 @@ M["button"] = { DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), ENABLED_COLOR = vmath.vector4(1), LONGTAP_TIME = 0.4, + AUTOHOLD_TRIGGER = 0.8, DOUBLETAP_TIME = 0.4, IS_HOVER = true, on_hover = function(self, node, state) - if self.hover_anim then - local scale_to = self.scale_from + M.button.HOVER_SCALE + local scale_to = self.scale_from + M.button.HOVER_SCALE - local target_scale = state and scale_to or self.scale_from - anims.hover_scale(self, target_scale, M.button.HOVER_TIME) - end + local target_scale = state and scale_to or self.scale_from + anims.hover_scale(self, target_scale, M.button.HOVER_TIME) end, on_click = function(self, node) diff --git a/druid/styles/sprites/style.lua b/druid/styles/sprites/style.lua new file mode 100644 index 0000000..b99409d --- /dev/null +++ b/druid/styles/sprites/style.lua @@ -0,0 +1,52 @@ +local M = {} + + +M["button"] = { + BTN_SOUND = "click", + BTN_SOUND_DISABLED = "click", + DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), + ENABLED_COLOR = vmath.vector4(1), + LONGTAP_TIME = 0.4, + DOUBLETAP_TIME = 0.4, + HOVER_IMAGE = "button_yellow", + DEFAULT_IMAGE = "button_blue", + CLICK_IMAGE = "button_red", + + on_hover = function(self, node, state) + local anim = state and M.button.HOVER_IMAGE or M.button.DEFAULT_IMAGE + gui.play_flipbook(node, anim) + end +} + + +M["scroll"] = { + FRICT_HOLD = 0, -- mult. for inert, while touching + FRICT = 0, -- mult for free inert + INERT_THRESHOLD = 2, -- speed to stop inertion + INERT_SPEED = 0, -- koef. of inert speed + DEADZONE = 6, -- in px + SOFT_ZONE_SIZE = 20, -- size of outside zone (back move) + BACK_SPEED = 0, -- lerp speed + ANIM_SPEED = 0, -- gui.animation speed to point +} + + +M["progress"] = { + SPEED = 5, -- progress bar fill rate, more faster + MIN_DELTA = 1 +} + + +M["progress_rich"] = { + DELAY = 0, -- delay in seconds before main fill +} + + +M["checkbox"] = { + on_change_state = function(self, node, state) + gui.set_enabled(node, state) + end +} + + +return M diff --git a/example/kenney/page/button.lua b/example/kenney/page/button.lua index 3ff56ff..e736935 100644 --- a/example/kenney/page/button.lua +++ b/example/kenney/page/button.lua @@ -1,4 +1,4 @@ -local sprite_change_style = {} +local sprite_style = require("druid.styles.sprites.style") local M = {} @@ -7,16 +7,20 @@ local function usual_callback() print("Usual callback") end -local function long_tap_callback() - print("Long tap callback") +local function long_tap_callback(self, params, button, hold_time) + print("Long tap callback", hold_time) end -local function repeated_callback(self, params, button) - print("Repeated callback", button.click_in_row) +local function hold_callback(self, params, button, hold_time) + print("On hold callback", hold_time) end -local function double_tap_callback(self, params, button) - print("Double tap callback", button.click_in_row) +local function repeated_callback(self, params, button, click_in_row) + print("Repeated callback", click_in_row) +end + +local function double_tap_callback(self, params, button, click_in_row) + print("Double tap callback", click_in_row) end @@ -24,13 +28,11 @@ local function setup_buttons(self) self.druid:new_button("button_usual/button", usual_callback) local custom_style = self.druid:new_button("button_custom_style/button", usual_callback) - custom_style:set_style(sprite_change_style) - -- HOVER_IMAGE and DEFAULT_IMAGE - from our custom style params - custom_style.HOVER_IMAGE = "button_yellow" - custom_style.DEFAULT_IMAGE = "button_blue" + custom_style:set_style(sprite_style) - self.druid:new_button("button_long_tap/button", usual_callback) - .on_long_click:subscribe(long_tap_callback) + local long_button = self.druid:new_button("button_long_tap/button", usual_callback) + long_button.on_hold_callback:subscribe(hold_callback) + long_button.on_long_click:subscribe(long_tap_callback) self.druid:new_button("button_repeated_tap/button", usual_callback) .on_repeated_click:subscribe(repeated_callback) self.druid:new_button("button_double_tap/button", usual_callback) From 53a77c0fcb55e4f80a70d2027a757220e7625b34 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 26 Feb 2020 00:09:04 +0300 Subject: [PATCH 123/136] Start scroll rework --- alpha_todo.txt | 6 +- druid/base/scroll.lua | 45 ++- druid/styles/default/style.lua | 2 +- example/kenney/gui/main/main.gui | 370 +++++++++++++++++++++++- example/kenney/gui/main/main.gui_script | 2 +- example/kenney/page/main.lua | 2 +- example/kenney/page/scroll.lua | 1 + 7 files changed, 403 insertions(+), 25 deletions(-) diff --git a/alpha_todo.txt b/alpha_todo.txt index fbbf68e..50baac2 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -10,11 +10,10 @@ Simple to-do for Druid Alpha 0.2.0 + Druid store assets - separate repository with rich components (progress_rich migrate) + refactor on_swipe. To on_scroll? Add input priority + separate custom data and predefined fields in components? Every component have their fields and events -- add init/remove stuff for every style in component. How to set custom sprites for button states? ++ How to set custom sprites for button states? - add druid settings (add auto_focus input and other stuff) + button add key trigger -- button polish, actions + button and hover click restriction zone? - unify component api (get/set/to and other general stuff) @@ -22,12 +21,13 @@ Simple to-do for Druid Alpha 0.2.0 - better scroll size management, check different cases. So implicit now - better grid + scroll management - better default style, add template for custom style -- add text component for alpha release +- add input_text component for alpha release - compare with gooey - add docs for all components - add docs folder for every component with gifs? Solutions - remove component autoremove all children component +- button polish, actions -- Low - add code template and example for user components diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 193a089..2b7e351 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -14,6 +14,19 @@ local M = component.create("scroll", { const.ON_UPDATE, const.ON_INPUT_HIGH }) M.current_scroll = nil +local function get_border(node) + local pivot = gui.get_pivot(node) + local pivot_offset = helper.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 + + function M.init(self, scroll_parent, input_zone, border) self.style = self:get_style() self.node = self:get_node(scroll_parent) @@ -30,8 +43,7 @@ function M.init(self, scroll_parent, input_zone, border) self.is_inert = true self.inert = vmath.vector3(0) - self.start_pos = gui.get_position(self.node) - self.pos = self.start_pos + self.pos = gui.get_position(self.node) self.target = vmath.vector3(self.pos) self.input = { @@ -41,7 +53,14 @@ function M.init(self, scroll_parent, input_zone, border) side = false, } - self:set_border(border) + local input_border = get_border(self.input_zone) + local content_border = get_border(self.node) + self:set_border(vmath.vector4( + input_border.x - content_border.x, + -input_border.w + content_border.w, + input_border.z - content_border.z, + -input_border.y + content_border.y + )) self.on_scroll = Event() self.on_scroll_to = Event() @@ -69,13 +88,13 @@ local function check_soft_target(self) if t.y < b.y then t.y = helper.step(t.y, b.y, math.abs(t.y - b.y) * self.style.BACK_SPEED) end - if t.x < b.x then + if t.x > b.x then t.x = helper.step(t.x, b.x, math.abs(t.x - b.x) * self.style.BACK_SPEED) end if t.y > b.w then t.y = helper.step(t.y, b.w, math.abs(t.y - b.w) * self.style.BACK_SPEED) end - if t.x > b.z then + if t.x < b.z then t.x = helper.step(t.x, b.z, math.abs(t.x - b.z) * self.style.BACK_SPEED) end end @@ -229,10 +248,10 @@ local function add_delta(self, dx, dy) local x_perc = 1 local y_perc = 1 - if t.x < b.x and dx < 0 then + if t.x > b.x and dx < 0 then x_perc = (soft - (b.x - t.x)) / soft end - if t.x > b.z and dx > 0 then + if t.x < b.z and dx > 0 then x_perc = (soft - (t.x - b.z)) / soft end -- If disabled scroll by x @@ -414,15 +433,11 @@ end -- @tparam table self Component instance -- @tparam vmath.vector3 border Size of scrolling area function M.set_border(self, border) + -- border.x - min content.x node pos + -- border.y - min content.y node pos + -- border.z - max content.x node pos + -- border.w - max content.y node pos self.border = border - - self.border.x = self.border.x + self.start_pos.x - self.border.z = self.border.z + self.start_pos.x - self.border.y = self.border.y + self.start_pos.y - self.border.w = self.border.w + self.start_pos.y - - border.z = math.max(border.x, border.z) - border.w = math.max(border.y, border.w) self.can_x = (border.x ~= border.z) self.can_y = (border.y ~= border.w) end diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index ee5d3ac..f34558f 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -7,7 +7,7 @@ local M = {} M["button"] = { HOVER_SCALE = vmath.vector3(-0.025, -0.025, 1), HOVER_TIME = 0.05, - SCALE_CHANGE = vmath.vector3(-0.05, - 0.05, 1), + SCALE_CHANGE = vmath.vector3(-0.05, -0.05, 1), BTN_SOUND = "click", BTN_SOUND_DISABLED = "click", DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index be9af76..d707cbf 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -198,7 +198,7 @@ nodes { } size { x: 600.0 - y: 900.0 + y: 1250.0 z: 0.0 w: 1.0 } @@ -5015,8 +5015,8 @@ nodes { w: 1.0 } size { - x: 1.0 - y: 1.0 + x: 600.0 + y: 900.0 z: 0.0 w: 1.0 } @@ -5043,12 +5043,374 @@ nodes { z: 0.0 w: 0.0 } + clipping_mode: CLIPPING_MODE_STENCIL + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.0 + y: 150.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: 600.0 + y: 300.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: "kenney/empty" + id: "simple_scroll_input" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_page" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_STENCIL + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: 0.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: 1200.0 + y: 300.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.5019608 + y: 0.4 + z: 0.8 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "" + id: "simple_scroll_content" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "simple_scroll_input" + 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 + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: -489.0 + y: 91.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Hello!" + font: "game" + id: "content1" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "simple_scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 220.0 + y: 71.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Hello!" + font: "game" + id: "content4" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "simple_scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: -128.0 + y: -54.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Hello!" + font: "game" + id: "content2" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "simple_scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 466.0 + y: -73.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: 200.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Hello!" + font: "game" + id: "content3" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "simple_scroll_content" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 } nodes { position { diff --git a/example/kenney/gui/main/main.gui_script b/example/kenney/gui/main/main.gui_script index bd472e3..627cbc7 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/kenney/gui/main/main.gui_script @@ -42,7 +42,7 @@ function init(self) self.druid = druid.new(self) init_top_panel(self) - self.page = 3 + self.page = 1 main_page.setup_page(self) text_page.setup_page(self) button_page.setup_page(self) diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index e4d719f..70e5539 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -96,7 +96,7 @@ end local function setup_scroll(self) - self.scroll = self.druid:new_scroll("scroll_content", "main_page", vmath.vector4(0, 0, 0, 200)) + self.scroll = self.druid:new_scroll("scroll_content", "main_page") end diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua index 8f56646..f47c818 100644 --- a/example/kenney/page/scroll.lua +++ b/example/kenney/page/scroll.lua @@ -2,6 +2,7 @@ local M = {} function M.setup_page(self) + self.druid:new_scroll("simple_scroll_content", "simple_scroll_input") end From 5ef9e6fa658ec4c92df1f8a6371d2701e9c9fe7e Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 13 Mar 2020 16:03:19 +0300 Subject: [PATCH 124/136] Update text multiline sizing --- druid/base/text.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/druid/base/text.lua b/druid/base/text.lua index 2cee229..95b4ced 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -9,6 +9,16 @@ local component = require("druid.component") local M = component.create("text") +local function update_text_size(self) + local size = vmath.vector3( + self.start_size.x * (self.start_scale.x / self.scale.x), + self.start_size.y * (self.start_scale.y / self.scale.y), + self.start_size.z + ) + gui.set_size(self.node, size) +end + + function M.init(self, node, value, no_adjust) self.node = self:get_node(node) self.start_pivot = gui.get_pivot(self.node) @@ -19,6 +29,7 @@ function M.init(self, node, value, no_adjust) self.start_scale = gui.get_scale(self.node) self.scale = gui.get_scale(self.node) + self.start_size = gui.get_size(self.node) self.text_area = gui.get_size(self.node) self.text_area.x = self.text_area.x * self.start_scale.x self.text_area.y = self.text_area.y * self.start_scale.y @@ -53,6 +64,8 @@ local function update_text_area_size(self) gui.set_scale(self.node, new_scale) self.scale = new_scale + update_text_size(self) + self.on_update_text_scale:trigger(self:get_context(), new_scale) end From 85e2235bae1600856bcae3f7608a8b7c63981dba Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 19 Mar 2020 00:07:55 +0300 Subject: [PATCH 125/136] Add more scroll examples --- alpha_todo.txt | 2 +- druid/base/grid.lua | 2 +- druid/base/scroll.lua | 39 ++-- druid/base/text.lua | 3 + druid/druid.lua | 4 +- druid/system/druid_instance.lua | 3 +- druid/system/settings.lua | 10 - example/kenney/gui/main/main.gui | 344 ++++++++++++++++++++++++++++++- example/kenney/page/scroll.lua | 23 +++ 9 files changed, 394 insertions(+), 36 deletions(-) diff --git a/alpha_todo.txt b/alpha_todo.txt index 50baac2..bf7cbc8 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -11,7 +11,7 @@ Simple to-do for Druid Alpha 0.2.0 + refactor on_swipe. To on_scroll? Add input priority + separate custom data and predefined fields in components? Every component have their fields and events + How to set custom sprites for button states? -- add druid settings (add auto_focus input and other stuff) ++ add druid settings (add auto_focus input and other stuff) (to game.project) + button add key trigger + button and hover click restriction zone? diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 31ad635..6dad84d 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -98,7 +98,7 @@ end function M.get_size(self) return vmath.vector3( self.border.z - self.border.x, - self.border.w - self.border.y, + self.border.y - self.border.w, 0) end diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 2b7e351..eaa0b5d 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -27,6 +27,25 @@ local function get_border(node) end +local function update_border(self) + local input_border = get_border(self.input_zone) + local content_border = get_border(self.node) + + -- border.x - min content.x node pos + -- border.y - min content.y node pos + -- border.z - max content.x node pos + -- border.w - max content.y node pos + self.border = vmath.vector4( + input_border.x - content_border.x, + -input_border.w + content_border.w, + input_border.z - content_border.z, + -input_border.y + content_border.y + ) + self.can_x = (self.border.x ~= self.border.z) + self.can_y = (self.border.y ~= self.border.w) +end + + function M.init(self, scroll_parent, input_zone, border) self.style = self:get_style() self.node = self:get_node(scroll_parent) @@ -53,14 +72,7 @@ function M.init(self, scroll_parent, input_zone, border) side = false, } - local input_border = get_border(self.input_zone) - local content_border = get_border(self.node) - self:set_border(vmath.vector4( - input_border.x - content_border.x, - -input_border.w + content_border.w, - input_border.z - content_border.z, - -input_border.y + content_border.y - )) + update_border(self) self.on_scroll = Event() self.on_scroll_to = Event() @@ -432,14 +444,9 @@ end -- @function scroll:set_border -- @tparam table self Component instance -- @tparam vmath.vector3 border Size of scrolling area -function M.set_border(self, border) - -- border.x - min content.x node pos - -- border.y - min content.y node pos - -- border.z - max content.x node pos - -- border.w - max content.y node pos - self.border = border - self.can_x = (border.x ~= border.z) - self.can_y = (border.y ~= border.w) +function M.set_border(self, content_size) + gui.set_size(self.node, content_size) + update_border(self) end diff --git a/druid/base/text.lua b/druid/base/text.lua index 95b4ced..1c19c2f 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -48,6 +48,9 @@ end --- Setup scale x, but can only be smaller, than start text scale local function update_text_area_size(self) + gui.set_scale(self.node, self.start_scale) + gui.set_size(self.node, self.start_size) + local max_width = self.text_area.x local max_height = self.text_area.y diff --git a/druid/druid.lua b/druid/druid.lua index 0716805..5993e26 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -20,8 +20,6 @@ local settings = require("druid.system.settings") local M = {} -local log = settings.log - --- Register external druid component. -- After register you can create the component with @@ -37,7 +35,7 @@ function M.register(name, module) return druid_instance.create(self, module, ...) end - log("Register component", name) + -- print("Register component", name) end diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 1a217ca..f06f10b 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -43,8 +43,7 @@ local Druid = class("druid.druid_instance") local function input_init(self) - -- TODO: To custom settings - if not settings.auto_focus_gain then + if not sys.get_config("druid.auto_focus") == "1" then return end diff --git a/druid/system/settings.lua b/druid/system/settings.lua index d7bdfcd..0dfe1a1 100644 --- a/druid/system/settings.lua +++ b/druid/system/settings.lua @@ -4,10 +4,7 @@ local M = {} -M.is_debug = false M.default_style = nil -M.auto_focus_gain = true - function M.get_text(name) return "[Druid]: locales not inited" @@ -18,11 +15,4 @@ function M.play_sound(name) end -function M.log(...) - if M.is_debug then - print("[Druid]: ", ...) - end -end - - return M diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index d707cbf..11a21f8 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -3918,6 +3918,61 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: 150.0 + y: -260.0 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 0.7019608 + y: 0.7019608 + z: 0.7019608 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "" + id: "text_max_height_visual" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "text_page" + 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: 0.7 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} nodes { position { x: 150.0 @@ -5053,7 +5108,62 @@ nodes { nodes { position { x: 0.0 - y: 150.0 + y: 450.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: 600.0 + y: 1900.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: "kenney/empty" + id: "scroll_page_content" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_N + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_page" + 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: 0.0 + y: -300.0 z: 0.0 w: 1.0 } @@ -5089,7 +5199,7 @@ nodes { yanchor: YANCHOR_NONE pivot: PIVOT_CENTER adjust_mode: ADJUST_MODE_FIT - parent: "scroll_page" + parent: "scroll_page_content" layer: "" inherit_alpha: true slice9 { @@ -5107,7 +5217,7 @@ nodes { } nodes { position { - x: 0.0 + x: 300.0 y: 0.0 z: 0.0 w: 1.0 @@ -5412,6 +5522,234 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: 0.0 + y: -630.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: 600.0 + y: 300.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: "kenney/empty" + id: "scroll_with_grid_size" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_page_content" + layer: "" + inherit_alpha: true + slice9 { + x: 0.0 + y: 0.0 + z: 0.0 + w: 0.0 + } + clipping_mode: CLIPPING_MODE_STENCIL + clipping_visible: true + clipping_inverted: false + alpha: 1.0 + template_node_child: false + size_mode: SIZE_MODE_MANUAL +} +nodes { + position { + x: -300.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: 600.0 + y: 300.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 0.6 + z: 0.4 + w: 1.0 + } + type: TYPE_BOX + blend_mode: BLEND_MODE_ALPHA + texture: "" + id: "grid_content" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_with_grid_size" + 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: -180.0 + y: -550.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: 200.0 + y: 100.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: "kenney/button_blue" + id: "grid_prefab" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_page_content" + layer: "" + inherit_alpha: true + slice9 { + x: 10.0 + y: 10.0 + z: 10.0 + w: 10.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: 0.0 + y: 5.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: 180.0 + y: 50.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Just text" + font: "game" + id: "grid_prefab_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.2 + y: 0.3019608 + z: 0.7019608 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + parent: "grid_prefab" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} nodes { position { x: 0.0 diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua index f47c818..dd945c4 100644 --- a/example/kenney/page/scroll.lua +++ b/example/kenney/page/scroll.lua @@ -1,8 +1,31 @@ local M = {} +local function init_grid(self) + local prefab = gui.get_node("grid_prefab") + + + local grid = self.druid:new_grid("grid_content", "grid_prefab", 20) + grid:set_anchor(vmath.vector3(0, 0.5, 0)) + grid:set_offset(vmath.vector3(15, 100, 0)) + + for i = 1, 40 do + local clone_prefab = gui.clone_tree(prefab) + + grid:add(clone_prefab["grid_prefab"]) + gui.set_text(clone_prefab["grid_prefab_text"], "Node " .. i) + end + + gui.set_enabled(prefab, false) + local grid_scroll = self.druid:new_scroll("grid_content", "scroll_with_grid_size") + grid_scroll:set_border(grid:get_size()) +end + + function M.setup_page(self) + self.druid:new_scroll("scroll_page_content", "scroll_page") self.druid:new_scroll("simple_scroll_content", "simple_scroll_input") + init_grid(self) end From 2ec192d0f55a3eedca83788c242d26d4d7a9ef3d Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 19 Mar 2020 00:08:07 +0300 Subject: [PATCH 126/136] add autofocus settings to druid config --- game.project | 2 ++ 1 file changed, 2 insertions(+) diff --git a/game.project b/game.project index 6e20bc6..2a618f5 100644 --- a/game.project +++ b/game.project @@ -20,3 +20,5 @@ texture_profiles = /example/res/custom.texture_profiles [input] gamepads = /builtins/input/default.gamepadsc +[druid] +autofocus = 1 \ No newline at end of file From 296bf3dc2f512cc74f781f5a2615a03245ea03c2 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 19 Mar 2020 00:17:10 +0300 Subject: [PATCH 127/136] Add clickable scroll nodes --- example/kenney/gui/main/main.gui | 61 ++++++++++++++++++++++++++++++-- example/kenney/page/scroll.lua | 4 +-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index 11a21f8..e9a1721 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -5651,6 +5651,61 @@ nodes { z: 1.0 w: 1.0 } + size { + x: 240.0 + y: 150.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: "kenney/empty" + id: "grid_prefab" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_page_content" + 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: 0.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: 200.0 y: 100.0 @@ -5666,12 +5721,12 @@ nodes { type: TYPE_BOX blend_mode: BLEND_MODE_ALPHA texture: "kenney/button_blue" - id: "grid_prefab" + id: "grid_button" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER adjust_mode: ADJUST_MODE_FIT - parent: "scroll_page_content" + parent: "grid_prefab" layer: "" inherit_alpha: true slice9 { @@ -5740,7 +5795,7 @@ nodes { } adjust_mode: ADJUST_MODE_FIT line_break: false - parent: "grid_prefab" + parent: "grid_button" layer: "" inherit_alpha: true alpha: 1.0 diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua index dd945c4..d43a4c3 100644 --- a/example/kenney/page/scroll.lua +++ b/example/kenney/page/scroll.lua @@ -4,16 +4,16 @@ local M = {} local function init_grid(self) local prefab = gui.get_node("grid_prefab") - local grid = self.druid:new_grid("grid_content", "grid_prefab", 20) grid:set_anchor(vmath.vector3(0, 0.5, 0)) - grid:set_offset(vmath.vector3(15, 100, 0)) for i = 1, 40 do local clone_prefab = gui.clone_tree(prefab) grid:add(clone_prefab["grid_prefab"]) gui.set_text(clone_prefab["grid_prefab_text"], "Node " .. i) + + self.druid:new_button(clone_prefab["grid_button"]) end gui.set_enabled(prefab, false) From c41957c751aaf1ff6bfdbac05aeadf1053ccfae0 Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 19 Mar 2020 00:27:53 +0300 Subject: [PATCH 128/136] Add dirty example of scrollbar of scroll --- example/kenney/gui/main/main.gui | 110 +++++++++++++++++++++++++++++++ example/kenney/page/scroll.lua | 10 +++ 2 files changed, 120 insertions(+) diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index e9a1721..6833812 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -5632,6 +5632,116 @@ nodes { template_node_child: false size_mode: SIZE_MODE_MANUAL } +nodes { + position { + x: 0.0 + y: -780.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: 600.0 + y: 4.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: "kenney/slider_back" + id: "grid_scroll_slider" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_page_content" + layer: "" + inherit_alpha: true + slice9 { + x: 10.0 + y: 0.0 + z: 10.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: -300.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: 0.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 36.0 + y: 36.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: "kenney/slider_move" + id: "grid_scroll_pin" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "grid_scroll_slider" + 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: -180.0 diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua index d43a4c3..dce2847 100644 --- a/example/kenney/page/scroll.lua +++ b/example/kenney/page/scroll.lua @@ -18,7 +18,17 @@ local function init_grid(self) gui.set_enabled(prefab, false) local grid_scroll = self.druid:new_scroll("grid_content", "scroll_with_grid_size") + local size = grid:get_size() grid_scroll:set_border(grid:get_size()) + + local scroll_slider = self.druid:new_slider("grid_scroll_pin", vmath.vector3(300, 0, 0), function(_, value) + grid_scroll:scroll_to(vmath.vector3(-size.x * value, size.y, size.z), true) + end) + + grid_scroll.on_scroll:subscribe(function(_, point) + local value = -point.x / size.x + scroll_slider:set(value) + end) end From b33efd692fdd83eed4adcd8dcae5832ff9af625f Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 19:40:50 +0300 Subject: [PATCH 129/136] Better scroll and slider API --- druid/base/scroll.lua | 48 ++++++++++++++++++++++++++++++++ druid/base/slider.lua | 6 ++-- example/kenney/gui/main/main.gui | 6 ++-- example/kenney/page/scroll.lua | 7 ++--- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index eaa0b5d..f95cdd9 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -380,6 +380,29 @@ function M.scroll_to(self, point, is_instant) self.on_scroll_to:trigger(self:get_context(), point, is_instant) end +--- Start scroll to target scroll percent +-- @function scroll:scroll_to_percent +-- @tparam point vector3 target percent +-- @tparam[opt] bool is_instant instant scroll flag +-- @usage scroll:scroll_to_percent(vmath.vector3(0.5, 0, 0)) +function M.scroll_to_percent(self, percent, is_instant) + local border = self.border + + local size_x = math.abs(border.z - border.x) + if size_x == 0 then + size_x = 1 + end + local size_y = math.abs(border.w - border.y) + if size_y == 0 then + size_y = 1 + end + + local pos = vmath.vector3( + -size_x * percent.x + border.x, + -size_y * percent.y + border.y, + 0) + M.scroll_to(self, pos, is_instant) +end --- Scroll to item in scroll by point index -- @function scroll:init @@ -450,4 +473,29 @@ function M.set_border(self, content_size) end +--- Return current scroll progress +-- @function scroll:get_scroll_percent +-- @tparam table self Component instance +-- @return vmath.vector3 Scroll progress +function M.get_scroll_percent(self) + local border = self.border + local size_x = math.abs(border.z - border.x) + if size_x == 0 then + size_x = 1 + end + + local size_y = math.abs(border.w - border.y) + if size_y == 0 then + size_y = 1 + end + local pos = self.pos + + return vmath.vector3( + (border.x - pos.x) / size_x, + (border.y - pos.y) / size_y, + 0 + ) +end + + return M diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 6fd3f9f..945c4e3 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -79,12 +79,14 @@ function M.on_input(self, action_id, action) end -function M.set(self, value) +function M.set(self, value, is_silent) value = helper.clamp(value, 0, 1) gui.set_position(self.node, self.start_pos + self.dist * value) self.value = value - on_change_value(self) + if not is_silent then + on_change_value(self) + end end diff --git a/example/kenney/gui/main/main.gui b/example/kenney/gui/main/main.gui index 6833812..e1b5f7a 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/kenney/gui/main/main.gui @@ -6153,7 +6153,7 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "Tap me!" + text: "<<<" font: "game" id: "button_left/text" xanchor: XANCHOR_NONE @@ -6179,6 +6179,7 @@ nodes { alpha: 1.0 outline_alpha: 0.0 shadow_alpha: 0.78 + overridden_fields: 8 template_node_child: true text_leading: 1.0 text_tracking: 0.0 @@ -6311,7 +6312,7 @@ nodes { } type: TYPE_TEXT blend_mode: BLEND_MODE_ALPHA - text: "Tap me!" + text: ">>>" font: "game" id: "button_right/text" xanchor: XANCHOR_NONE @@ -6337,6 +6338,7 @@ nodes { alpha: 1.0 outline_alpha: 0.0 shadow_alpha: 0.78 + overridden_fields: 8 template_node_child: true text_leading: 1.0 text_tracking: 0.0 diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua index dce2847..71fe04d 100644 --- a/example/kenney/page/scroll.lua +++ b/example/kenney/page/scroll.lua @@ -17,17 +17,16 @@ local function init_grid(self) end gui.set_enabled(prefab, false) + local grid_scroll = self.druid:new_scroll("grid_content", "scroll_with_grid_size") - local size = grid:get_size() grid_scroll:set_border(grid:get_size()) local scroll_slider = self.druid:new_slider("grid_scroll_pin", vmath.vector3(300, 0, 0), function(_, value) - grid_scroll:scroll_to(vmath.vector3(-size.x * value, size.y, size.z), true) + grid_scroll:scroll_to_percent(vmath.vector3(value, 0, 0), true) end) grid_scroll.on_scroll:subscribe(function(_, point) - local value = -point.x / size.x - scroll_slider:set(value) + scroll_slider:set(grid_scroll:get_scroll_percent().x, true) end) end From ca78b10794593d2dd0a8c22d16c2533873c9b4e6 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 21:37:32 +0300 Subject: [PATCH 130/136] Update component docs --- alpha_todo.txt | 8 +- docs/index.html | 2 +- druid/base/back_handler.lua | 10 +- druid/base/blocker.lua | 24 ++++- druid/base/button.lua | 13 +-- druid/base/checkbox.lua | 67 ++++++++---- druid/base/checkbox_group.lua | 61 +++++++---- druid/base/grid.lua | 42 ++++++++ druid/base/hover.lua | 27 +++-- druid/base/input.lua | 3 +- druid/base/lang_text.lua | 58 ++++++---- druid/base/progress.lua | 192 ++++++++++++++++++--------------- druid/base/radio_group.lua | 55 ++++++---- druid/base/scroll.lua | 149 +++++++++++++++---------- druid/base/slider.lua | 25 +++++ druid/base/text.lua | 93 +++++++++------- druid/base/timer.lua | 94 +++++++++------- druid/event.lua | 2 +- example/kenney/page/main.lua | 4 +- example/kenney/page/scroll.lua | 8 +- 20 files changed, 603 insertions(+), 334 deletions(-) diff --git a/alpha_todo.txt b/alpha_todo.txt index bf7cbc8..62342af 100644 --- a/alpha_todo.txt +++ b/alpha_todo.txt @@ -15,21 +15,21 @@ Simple to-do for Druid Alpha 0.2.0 + button add key trigger + button and hover click restriction zone? ++ button polish, actions ++ better scroll size management, check different cases. So implicit now ++ better callbacks for every components - unify component api (get/set/to and other general stuff) -- better callbacks for every components -- better scroll size management, check different cases. So implicit now - better grid + scroll management - better default style, add template for custom style -- add input_text component for alpha release - compare with gooey - add docs for all components - add docs folder for every component with gifs? Solutions - remove component autoremove all children component -- button polish, actions -- Low +- add input_text component for alpha release - add code template and example for user components - custom input settings (name of touch, text, etc) - add good examples with template and/or nodes (basic component no use any of them) diff --git a/docs/index.html b/docs/index.html index 8e850b0..aa797fc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -145,7 +145,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 20:02:23
    diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index 2431f80..00414c8 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -1,6 +1,14 @@ --- Component to handle back key (android, backspace) -- @module druid.back_handler +--- Component events +-- @table Events +-- @tfield druid_event on_back On back handler callback + +--- Component fields +-- @table Fields +-- @tfield any params Params to click callbacks + local Event = require("druid.event") local const = require("druid.const") local component = require("druid.component") @@ -10,11 +18,9 @@ local M = component.create("back_handler", { const.ON_INPUT }) --- Component init function -- @function back_handler:init --- @tparam table self Component instance -- @tparam callback callback On back button -- @tparam[opt] params Callback argument function M.init(self, callback, params) - self.callback = callback self.params = params self.on_back = Event(callback) diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 303d703..e32239e 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -1,9 +1,17 @@ ---- Component to block input on specify zone (node) +--- Component to block input on specify zone by node -- @module druid.blocker +--- Component events +-- @table Events +-- @tfield druid_event on_click On release button callback +-- @tfield druid_event on_enable_change On enable/disable callback + +--- Component fields +-- @table Fields +-- @tfield node node Trigger node + local Event = require("druid.event") local const = require("druid.const") -local helper = require("druid.helper") local component = require("druid.component") local M = component.create("blocker", { const.ON_INPUT_HIGH }) @@ -22,7 +30,7 @@ function M.on_input(self, action_id, action) return false end - if not helper.is_enabled(self.node) then + if not self:is_enabled(self.node) then return false end @@ -34,13 +42,19 @@ function M.on_input(self, action_id, action) end +--- Set enabled blocker component state +-- @function blocker:set_enabled +-- @tparam bool state Enabled state function M.set_enabled(self, state) - + gui.set_enabled(self.node, state) end +--- Return blocked enabled state +-- @function blocker:is_enabled +-- @treturn bool True, if blocker is enabled function M.is_enabled(self, state) - + return gui.is_enabled(self.node) end diff --git a/druid/base/button.lua b/druid/base/button.lua index 7b940d9..9c431f9 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -1,9 +1,6 @@ --- Component to handle basic GUI button -- @module druid.button ---- Button gui component ---@class druid - --- Component events -- @table Events -- @tfield druid_event on_click On release button callback @@ -144,7 +141,6 @@ end --- Component init function -- @function button:init --- @tparam table self Component instance -- @tparam node node Gui node -- @tparam function callback Button callback -- @tparam[opt] table params Button callback params @@ -246,6 +242,9 @@ function M.on_input_interrupt(self) end +--- Set enabled button component state +-- @function button:set_enabled +-- @tparam bool state Enabled state function M.set_enabled(self, state) self.disabled = not state if self._style.on_set_enabled then @@ -254,7 +253,10 @@ function M.set_enabled(self, state) end -function M.get_enabled(self) +--- Return button enabled state +-- @function button:is_enabled +-- @treturn bool True, if button is enabled +function M.is_enabled(self) return not self.disabled end @@ -262,7 +264,6 @@ end --- Strict button click area. Useful for -- no click events outside stencil node -- @function button:set_click_zone --- @tparam table self Component instance -- @tparam node zone Gui node function M.set_click_zone(self, zone) self.click_zone = self:get_node(zone) diff --git a/druid/base/checkbox.lua b/druid/base/checkbox.lua index 723decd..7770be9 100644 --- a/druid/base/checkbox.lua +++ b/druid/base/checkbox.lua @@ -1,13 +1,54 @@ --- Druid checkbox component -- @module druid.checkbox +--- Component events +-- @table Events +-- @tfield druid_event on_change_state On change state callback + +--- Component fields +-- @table Fields +-- @tfield node node Visual node +-- @tfield[opt=node] node click_node Button trigger node +-- @tfield druid.button button Button component from click_node + +--- Component style params +-- @table Style +-- @tfield function on_change_state (self, node, state) + local Event = require("druid.event") local component = require("druid.component") local M = component.create("checkbox") -function M.set_state(self, state, is_silence) +local function on_click(self) + M.set_state(self, not self.state) +end + + +--- Component init function +-- @function checkbox:init +-- @tparam node node Gui node +-- @tparam function callback Checkbox callback +-- @tparam[opt=node] node click node Trigger node, by default equals to node +function M.init(self, node, callback, click_node) + self.style = self:get_style() + self.druid = self:get_druid() + self.node = self:get_node(node) + self.click_node = self:get_node(click_node) + + self.button = self.druid:new_button(self.click_node or self.node, on_click) + M.set_state(self, false, true) + + self.on_change_state = Event(callback) +end + + +--- Set checkbox state +-- @function checkbox:set_state +-- @tparam bool state Checkbox state +-- @tparam bool is_silent Don't trigger on_change_state if true +function M.set_state(self, state, is_silent) if self.state == state then return end @@ -17,34 +58,18 @@ function M.set_state(self, state, is_silence) self.style.on_change_state(self, self.node, state) end - if not is_silence and self.callback then + if not is_silent then self.on_change_state:trigger(self:get_context(), state) end end +--- Return checkbox state +-- @function checkbox:get_state +-- @treturn bool Checkbox state function M.get_state(self) return self.state end -local function on_click(self) - M.set_state(self, not self.state) -end - - -function M.init(self, node, callback, click_node) - self.style = self:get_style() - self.druid = self:get_druid() - self.node = self:get_node(node) - self.click_node = self:get_node(click_node) - self.callback = callback - - self.button = self.druid:new_button(self.click_node or self.node, on_click) - M.set_state(self, false, true) - - self.on_change_state = Event(callback) -end - - return M diff --git a/druid/base/checkbox_group.lua b/druid/base/checkbox_group.lua index 3f5ed11..dd9a94a 100644 --- a/druid/base/checkbox_group.lua +++ b/druid/base/checkbox_group.lua @@ -1,32 +1,25 @@ ---- Checkboux group module +--- Checkbox group module -- @module druid.checkbox_group +--- Component events +-- @table Events +-- @tfield druid_event on_checkbox_click On any checkbox click + +--- Component fields +-- @table Fields +-- @tfield table checkboxes Array of checkbox components + local Event = require("druid.event") local component = require("druid.component") local M = component.create("checkbox_group") -function M.set_state(self, indexes) - for i = 1, #indexes do - if self.checkboxes[i] then - self.checkboxes[i]:set_state(indexes[i], true) - end - end -end - - -function M.get_state(self) - local result = {} - - for i = 1, #self.checkboxes do - table.insert(result, self.checkboxes[i]:get_state()) - end - - return result -end - - +--- Component init function +-- @function checkbox_group:init +-- @tparam node[] node Array of gui node +-- @tparam function callback Checkbox callback +-- @tparam[opt=node] node[] click node Array of trigger nodes, by default equals to nodes function M.init(self, nodes, callback, click_nodes) self.druid = self:get_druid() self.checkboxes = {} @@ -44,4 +37,30 @@ function M.init(self, nodes, callback, click_nodes) end +--- Set checkbox group state +-- @function checkbox_group:set_state +-- @tparam bool[] state Array of checkbox state +function M.set_state(self, indexes) + for i = 1, #indexes do + if self.checkboxes[i] then + self.checkboxes[i]:set_state(indexes[i], true) + end + end +end + + +--- Return checkbox group state +-- @function checkbox_group:get_state +-- @treturn bool[] Array if checkboxes state +function M.get_state(self) + local result = {} + + for i = 1, #self.checkboxes do + table.insert(result, self.checkboxes[i]:get_state()) + end + + return result +end + + return M diff --git a/druid/base/grid.lua b/druid/base/grid.lua index 6dad84d..86e0444 100644 --- a/druid/base/grid.lua +++ b/druid/base/grid.lua @@ -2,12 +2,34 @@ -- Grid can anchor your elements, get content size and other -- @module druid.grid +--- Component events +-- @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_clear On grid clear callback +-- @tfield druid_event on_update_positions On update item positions callback + +--- Component fields +-- @table Fields +-- @tfield node parent Parent gui node +-- @tfield node[] nodes List of all grid nodes +-- @tfield vector3 offset Item distance between each other items +-- @tfield vector3 anchor Item anchor +-- @tfield vector3 node_size Item size +-- @tfield vector4 border The size of item content +-- @tfield vector3 border_offer The border offset for correct anchor calculations + local Event = require("druid.event") local component = require("druid.component") local M = component.create("grid") +--- Component init function +-- @function grid:init +-- @tparam node parent The gui node parent, where items will be placed +-- @tparam node element Element prefab. Need to get it size +-- @tparam[opt=1] number in_row How many nodes in row can be placed function M.init(self, parent, element, in_row) self.parent = self:get_node(parent) self.nodes = {} @@ -55,6 +77,7 @@ local function get_pos(self, index) temp_pos.x = col * (self.node_size.x + self.offset.x) - self.border_offset.x temp_pos.y = -row * (self.node_size.y + self.offset.y) - self.border_offset.y + temp_pos.z = 0 return temp_pos end @@ -70,18 +93,29 @@ local function update_pos(self) end + +--- Set grid items offset, the distance between items +-- @function grid:set_offset +-- @tparam vector3 offset Offset function M.set_offset(self, offset) self.offset = offset update_pos(self) end +--- Set grid anchor +-- @function grid:set_anchor +-- @tparam vector3 acnhor Anchor function M.set_anchor(self, anchor) self.anchor = anchor update_pos(self) end +--- Add new item to the grid +-- @function grid:add +-- @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) table.insert(self.nodes, index, item) @@ -95,6 +129,9 @@ function M.add(self, item, index) end +--- Return grid content size +-- @function grid:get_size +-- @treturn vector3 The grid content size function M.get_size(self) return vmath.vector3( self.border.z - self.border.x, @@ -103,6 +140,9 @@ function M.get_size(self) end +--- Return array of all node positions +-- @function grid:get_all_pos +-- @treturn vector3[] All grid node positions function M.get_all_pos(self) local result = {} for i = 1, #self.nodes do @@ -113,6 +153,8 @@ function M.get_all_pos(self) end +--- Clear all items from the grid +-- @function grid:clear function M.clear(self) for i = 1, #self.nodes do gui.delete_node(self.nodes[i]) diff --git a/druid/base/hover.lua b/druid/base/hover.lua index a535af9..a38cda0 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -1,5 +1,9 @@ --- Component to handle hover node interaction --- @module druid.input +-- @module druid.hover + +--- Component events +-- @table Events +-- @tfield druid_event on_hover On hover callback local Event = require("druid.event") local const = require("druid.const") @@ -11,7 +15,6 @@ local M = component.create("hover", { const.ON_INPUT }) --- Component init function -- @function hover:init --- @tparam table self Component instance -- @tparam node node Gui node -- @tparam function on_hover_callback Hover callback function M.init(self, node, on_hover_callback) @@ -24,14 +27,6 @@ function M.init(self, node, on_hover_callback) end -function M.set_hover(self, state) - if self._is_hovered ~= state then - self._is_hovered = state - self.on_hover:trigger(self:get_context(), state) - end -end - - function M.on_input(self, action_id, action) if action_id ~= const.ACTION_TOUCH then return @@ -64,10 +59,20 @@ function M.on_input_interrupt(self) end +--- Set hover state +-- @function hover:set_hover +-- @tparam bool state The hover state +function M.set_hover(self, state) + if self._is_hovered ~= state then + self._is_hovered = state + self.on_hover:trigger(self:get_context(), state) + end +end + + --- Strict button click area. Useful for -- no click events outside stencil node -- @function button:set_click_zone --- @tparam table self Component instance -- @tparam node zone Gui node function M.set_click_zone(self, zone) self.click_zone = self:get_node(zone) diff --git a/druid/base/input.lua b/druid/base/input.lua index 3b05fb8..21079a2 100644 --- a/druid/base/input.lua +++ b/druid/base/input.lua @@ -1,4 +1,5 @@ ---- Druid input text component +--- Druid input text component. +-- Carry on user text input -- @local unimplemented -- @module druid.input diff --git a/druid/base/lang_text.lua b/druid/base/lang_text.lua index 760190e..5c81c03 100644 --- a/druid/base/lang_text.lua +++ b/druid/base/lang_text.lua @@ -2,6 +2,15 @@ -- Good working with localization system -- @module druid.lang_text +--- Component events +-- @table Events +-- @tfield druid_event on_change On change text callback + +--- Component fields +-- @table Fields +-- @tfield druid.text text The text component + +local Event = require("druid.event") local const = require("druid.const") local settings = require("druid.system.settings") local component = require("druid.component") @@ -9,31 +18,23 @@ local component = require("druid.component") local M = component.create("lang_text", { const.ON_CHANGE_LANGUAGE }) -function M.init(self, node, lang_id, no_adjust) +--- Component init function +-- @function lang_text:init +-- @tparam node node The text node +-- @tparam string locale_id Default locale id +-- @tparam bool no_adjust If true, will not correct text size +function M.init(self, node, locale_id, no_adjust) self.druid = self:get_druid() - self.text = self.druid:new_text(node, lang_id, no_adjust) - self:translate(lang_id) + self.text = self.druid:new_text(node, locale_id, no_adjust) + + self.on_change = Event() + + self:translate(locale_id) return self end -function M.set_to(self, text) - self.last_locale = false - self.text:set_to(text) -end - - ---- Translate the text by locale_id --- @function text:translate --- @tparam table self Component instance --- @tparam string locale_id Locale id -function M.translate(self, locale_id) - self.last_locale = locale_id or self.last_locale - self.text:set_to(settings.get_text(self.last_locale)) -end - - function M.on_change_language(self) if self.last_locale then M.translate(self) @@ -41,4 +42,23 @@ function M.on_change_language(self) end +--- Setup raw text to lang_text component +-- @function lang_text:set_to +-- @tparam string text Text for text node +function M.set_to(self, text) + self.last_locale = false + self.text:set_to(text) + self.on_change:trigger() +end + + +--- Translate the text by locale_id +-- @function lang_text:translate +-- @tparam string locale_id Locale id +function M.translate(self, locale_id) + self.last_locale = locale_id or self.last_locale + self.text:set_to(settings.get_text(self.last_locale)) +end + + return M diff --git a/druid/base/progress.lua b/druid/base/progress.lua index 251c38f..2aa21e8 100644 --- a/druid/base/progress.lua +++ b/druid/base/progress.lua @@ -1,6 +1,26 @@ ---- Basic progress bar component +--- Basic progress bar component. +-- For correct progress bar init it should be in max size from gui -- @module druid.progress +--- Component events +-- @table Events +-- @tfield druid_event on_change On progress bar change callback + +--- Component fields +-- @table Fields +-- @tfield node node Progress bar fill node +-- @tfield string key The progress bar direction +-- @tfield vector3 scale Current progress bar scale +-- @tfield vector3 size Current progress bar size +-- @tfield number max_size Maximum size of progress bar +-- @tfield vector4 slice Progress bar slice9 settings + +--- Component style params +-- @table Style +-- @tfield number SPEED Progress bas fill rate. More -> faster +-- @tfield number MIN_DELTA Minimum step to fill progress bar + +local Event = require("druid.event") local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") @@ -8,34 +28,6 @@ local component = require("druid.component") local M = component.create("progress", { const.ON_UPDATE }) ---- Component init function --- @function progress:init --- @tparam table self Component instance --- @tparam string|node node Progress bar fill node or node name --- @tparam string key Progress bar direction (x or y) --- @tparam number init_value Initial value of progress bar -function M.init(self, node, key, init_value) - assert(key == const.SIDE.X or const.SIDE.Y, "Progress bar key should be 'x' or 'y'") - - self.prop = hash("scale."..key) - self.key = key - - self.style = self:get_style() - 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.slice = gui.get_slice9(self.node) - if 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:set_to(init_value or 1) -end - - local function check_steps(self, from, to, exactly) if not self.steps then return @@ -58,7 +50,7 @@ local function check_steps(self, from, to, exactly) end -local function set_bar_to(self, set_to, is_silence) +local function set_bar_to(self, set_to, is_silent) local prev_value = self.last_value self.last_value = set_to @@ -72,73 +64,38 @@ local function set_bar_to(self, set_to, is_silence) self.size[self.key] = size gui.set_size(self.node, self.size) - if not is_silence then + if not is_silent then check_steps(self, prev_value, set_to) end end ---- Fill a progress bar and stop progress animation --- @function progress:empty --- @tparam table self Component instance -function M.fill(self) - set_bar_to(self, 1, true) -end +--- Component init function +-- @function progress:init +-- @tparam string|node node Progress bar fill node or node name +-- @tparam string key Progress bar direction: const.SIDE.X or const.SIDE.Y +-- @tparam number init_value Initial value of progress bar +function M.init(self, node, key, init_value) + assert(key == const.SIDE.X or const.SIDE.Y, "Progress bar key should be 'x' or 'y'") + self.prop = hash("scale."..key) + self.key = key ---- Empty a progress bar --- @function progress:empty --- @tparam table self Component instance -function M.empty(self) - set_bar_to(self, 0, true) -end - - ---- Instant fill progress bar to value --- @function progress:set_to --- @tparam table self Component instance --- @tparam number to Progress bar value, from 0 to 1 -function M.set_to(self, to) - set_bar_to(self, to) -end - - ---- Return current progress bar value --- @function progress:get --- @tparam table self Component instance -function M.get(self) - return self.last_value -end - - ---- Set points on progress bar to fire the callback --- @function progress:set_steps --- @tparam table self Component instance --- @tparam table steps Array of progress bar values --- @tparam function callback Callback on intersect step value -function M.set_steps(self, steps, callback) - self.steps = steps - self.step_callback = callback -end - - ---- Start animation of a progress bar --- @function progress:to --- @tparam table self Component instance --- @tparam number to value between 0..1 --- @tparam[opt] function callback Callback on animation ends -function M.to(self, to, callback) - to = helper.clamp(to, 0, 1) - -- cause of float error - local value = helper.round(to, 5) - if value ~= self.last_value then - self.target = value - self.target_callback = callback + self.style = self:get_style() + 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.slice = gui.get_slice9(self.node) + if key == const.SIDE.X then + self.slice_size = self.slice.x + self.slice.z else - if callback then - callback(self:get_context(), to) - end + self.slice_size = self.slice.y + self.slice.w end + + self.on_change = Event() + + self:set_to(init_value or 1) end @@ -162,4 +119,63 @@ function M.update(self, dt) end +--- Fill a progress bar and stop progress animation +-- @function progress:fill +function M.fill(self) + set_bar_to(self, 1, true) +end + + +--- Empty a progress bar +-- @function progress:empty +function M.empty(self) + set_bar_to(self, 0, true) +end + + +--- Instant fill progress bar to value +-- @function progress:set_to +-- @tparam number to Progress bar value, from 0 to 1 +function M.set_to(self, to) + set_bar_to(self, to) +end + + +--- Return current progress bar value +-- @function progress:get +function M.get(self) + return self.last_value +end + + +--- Set points on progress bar to fire the callback +-- @function progress:set_steps +-- @tparam number[] steps Array of progress bar values +-- @tparam function callback Callback on intersect step value +-- @usage progress:set_steps({0, 0.3, 0.6, 1}, function(self, step) end) +function M.set_steps(self, steps, callback) + self.steps = steps + self.step_callback = callback +end + + +--- Start animation of a progress bar +-- @function progress:to +-- @tparam number to value between 0..1 +-- @tparam[opt] function callback Callback on animation ends +function M.to(self, to, callback) + to = helper.clamp(to, 0, 1) + -- cause of float error + local value = helper.round(to, 5) + if value ~= self.last_value then + self.target = value + self.target_callback = callback + else + if callback then + callback(self:get_context(), to) + end + end +end + + return M diff --git a/druid/base/radio_group.lua b/druid/base/radio_group.lua index b5e2f97..a446d02 100644 --- a/druid/base/radio_group.lua +++ b/druid/base/radio_group.lua @@ -1,6 +1,15 @@ --- Radio group module -- @module druid.radio_group +--- Component events +-- @table Events +-- @tfield druid_event on_radio_click On any checkbox click + +--- Component fields +-- @table Fields +-- @tfield table checkboxes Array of checkbox components + +local Event = require("druid.event") local component = require("druid.component") local M = component.create("radio_group") @@ -11,17 +20,43 @@ local function on_checkbox_click(self, index) self.checkboxes[i]:set_state(i == index, true) end - if self.callback then - self.callback(self:get_context(), index) + self.on_radio_click:trigger(self:get_context(), index) +end + + +--- Component init function +-- @function radio_group:init +-- @tparam node[] node Array of gui node +-- @tparam function callback Radio callback +-- @tparam[opt=node] node[] click node Array of trigger nodes, by default equals to nodes +function M.init(self, nodes, callback, click_nodes) + self.druid = self:get_druid() + self.checkboxes = {} + + self.on_radio_click = Event(callback) + + for i = 1, #nodes do + local click_node = click_nodes and click_nodes[i] or nil + local checkbox = self.druid:new_checkbox(nodes[i], function() + on_checkbox_click(self, i) + end, click_node) + + table.insert(self.checkboxes, checkbox) end end +--- Set radio group state +-- @function radio_group:set_state +-- @tparam bool[] state Array of checkbox state function M.set_state(self, index) on_checkbox_click(self, index) end +--- Return radio group state +-- @function radio_group:get_state +-- @treturn bool[] Array if checkboxes state function M.get_state(self) local result = -1 @@ -36,20 +71,4 @@ function M.get_state(self) end -function M.init(self, nodes, callback, click_nodes) - self.druid = self:get_druid() - self.checkboxes = {} - self.callback = callback - - for i = 1, #nodes do - local click_node = click_nodes and click_nodes[i] or nil - local checkbox = self.druid:new_checkbox(nodes[i], function() - on_checkbox_click(self, i) - end, click_node) - - table.insert(self.checkboxes, checkbox) - end -end - - return M diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index f95cdd9..4a437c2 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -1,6 +1,41 @@ ---- Component to handle scroll content +--- Component to handle scroll content. +-- Scroll consist from two nodes: scroll parent and scroll input +-- Scroll input the user input zone, it's static +-- Scroll parent the scroll moving part, it will change position. +-- Setup initial scroll size by changing scroll parent size. If scroll parent +-- size will be less than scroll_input size, no scroll is available. For scroll +-- parent size should be more than input size -- @module druid.scroll +--- Component events +-- @table Events +-- @tfield druid_event on_scroll On scroll move callback +-- @tfield druid_event on_scroll_to On scroll_to function callback +-- @tfield druid_event on_point_scroll On scroll_to_index function callbck + +--- Component fields +-- @table Fields +-- @tfield node node Scroll parent node +-- @tfield node input_zone Scroll input node +-- @tfield vector3 zone_size Current scroll content size +-- @tfield number soft_size Soft zone size from style table +-- @tfield vector3 center_offset Distance from node to node's center +-- @tfield bool is_inert Flag, if scroll now moving by inertion +-- @tfield vector3 inert Current inert speed +-- @tfield vector3 pos Current scroll posisition +-- @tfield vector3 target Current scroll target position + +--- Component style params +-- @table Style +-- @tfield number FRICT_HOLD Multiplier for inertion, while touching +-- @tfield number FRICT Multiplier for free inertion +-- @tfield number INERT_THRESHOLD Scroll speed to stop inertion +-- @tfield number INERT_SPEED Multiplier for inertion speed +-- @tfield number DEADZONE Deadzone for start scrol in pixels +-- @tfield number SOFT_ZONE_SIZE Size of outside zone in pixels (for scroll back moving) +-- @tfield number BACK_SPEED Scroll back returning lerp speed +-- @tfield number ANIM_SPEED Scroll gui.animation speed for scroll_to function + local Event = require("druid.event") local helper = require("druid.helper") local const = require("druid.const") @@ -46,39 +81,6 @@ local function update_border(self) end -function M.init(self, scroll_parent, input_zone, border) - self.style = self:get_style() - self.node = self:get_node(scroll_parent) - self.input_zone = self:get_node(input_zone) - - self.zone_size = gui.get_size(self.input_zone) - self.soft_size = self.style.SOFT_ZONE_SIZE - - -- Distance from node to node's center - local offset = helper.get_pivot_offset(gui.get_pivot(self.input_zone)) - self.center_offset = vmath.vector3(self.zone_size) - self.center_offset.x = self.center_offset.x * offset.x - self.center_offset.y = self.center_offset.y * offset.y - - self.is_inert = true - self.inert = vmath.vector3(0) - self.pos = gui.get_position(self.node) - self.target = vmath.vector3(self.pos) - - self.input = { - touch = false, - start_x = 0, - start_y = 0, - side = false, - } - - update_border(self) - - self.on_scroll = Event() - self.on_scroll_to = Event() - self.on_point_scroll = Event() -end - local function set_pos(self, pos) if self.pos.x ~= pos.x or self.pos.y ~= pos.y then @@ -146,6 +148,7 @@ end --- Find closer point of interest -- if no inert, scroll to next point by scroll direction -- if inert, find next point by scroll director +-- @local local function check_points(self) if not self.points then return @@ -236,17 +239,6 @@ local function cancel_animate(self) end -function M.update(self, dt) - if self.input.touch then - if M.current_scroll == self then - update_hand_scroll(self, dt) - end - else - update_free_inert(self, dt) - end -end - - local function add_delta(self, dx, dy) local t = self.target local b = self.border @@ -295,6 +287,55 @@ local function add_delta(self, dx, dy) end +--- Component init function +-- @function scroll:init +-- @tparam node scroll_parent Gui node where placed scroll content. This node will change position +-- @tparam node input_zone Gui node where input is catched +function M.init(self, scroll_parent, input_zone) + self.style = self:get_style() + self.node = self:get_node(scroll_parent) + self.input_zone = self:get_node(input_zone) + + self.zone_size = gui.get_size(self.input_zone) + self.soft_size = self.style.SOFT_ZONE_SIZE + + -- Distance from node to node's center + local offset = helper.get_pivot_offset(gui.get_pivot(self.input_zone)) + self.center_offset = vmath.vector3(self.zone_size) + self.center_offset.x = self.center_offset.x * offset.x + self.center_offset.y = self.center_offset.y * offset.y + + self.is_inert = true + self.inert = vmath.vector3(0) + self.pos = gui.get_position(self.node) + self.target = vmath.vector3(self.pos) + + self.input = { + touch = false, + start_x = 0, + start_y = 0, + side = false, + } + + update_border(self) + + self.on_scroll = Event() + self.on_scroll_to = Event() + self.on_point_scroll = Event() +end + + +function M.update(self, dt) + if self.input.touch then + if M.current_scroll == self then + update_hand_scroll(self, dt) + end + else + update_free_inert(self, dt) + end +end + + function M.on_input(self, action_id, action) if action_id ~= const.ACTION_TOUCH then return false @@ -377,9 +418,10 @@ function M.scroll_to(self, point, is_instant) end) end - self.on_scroll_to:trigger(self:get_context(), point, is_instant) + self.on_scroll_to:trigger(self:get_context(), target, is_instant) end + --- Start scroll to target scroll percent -- @function scroll:scroll_to_percent -- @tparam point vector3 target percent @@ -404,11 +446,11 @@ function M.scroll_to_percent(self, percent, is_instant) M.scroll_to(self, pos, is_instant) end + --- Scroll to item in scroll by point index -- @function scroll:init --- @tparam table self Component instance -- @tparam number index Point index --- @tparam[opt] boolean skip_cb If true, skip the point callback +-- @tparam[opt] bool skip_cb If true, skip the point callback function M.scroll_to_index(self, index, skip_cb) index = helper.clamp(index, 1, #self.points) @@ -427,7 +469,6 @@ end --- Set points of interest. -- Scroll will always centered on closer points -- @function scroll:set_points --- @tparam table self Component instance -- @tparam table points Array of vector3 points function M.set_points(self, points) self.points = points @@ -447,8 +488,7 @@ end -- If disabled, scroll through points (if exist) -- If no points, just simple drag without inertion -- @function scroll:set_inert --- @tparam table self Component instance --- @tparam boolean state Inert scroll state +-- @tparam bool state Inert scroll state function M.set_inert(self, state) self.is_inert = state end @@ -456,7 +496,6 @@ end --- Set the callback on scrolling to point (if exist) -- @function scroll:on_point_move --- @tparam table self Component instance -- @tparam function callback Callback on scroll to point of interest function M.on_point_move(self, callback) self.on_point_scroll:subscribe(callback) @@ -465,8 +504,7 @@ end --- Set the scroll possibly area -- @function scroll:set_border --- @tparam table self Component instance --- @tparam vmath.vector3 border Size of scrolling area +-- @tparam vector3 border Size of scrolling area function M.set_border(self, content_size) gui.set_size(self.node, content_size) update_border(self) @@ -475,8 +513,7 @@ end --- Return current scroll progress -- @function scroll:get_scroll_percent --- @tparam table self Component instance --- @return vmath.vector3 Scroll progress +-- @treturn vector3 Scroll progress function M.get_scroll_percent(self) local border = self.border local size_x = math.abs(border.z - border.x) diff --git a/druid/base/slider.lua b/druid/base/slider.lua index 945c4e3..f5b8f13 100644 --- a/druid/base/slider.lua +++ b/druid/base/slider.lua @@ -1,6 +1,22 @@ --- Druid slider component -- @module druid.slider +--- Component events +-- @table Events +-- @tfield druid_event on_change_value On change value callback + +--- Component fields +-- @table Fields +-- @tfield node node Slider pin node +-- @tfield vector3 start_pos Start pin node position +-- @tfield vector3 pos Current pin node position +-- @tfield vector3 target_pos Targer pin node position +-- @tfield vector3 end_pos End pin node position +-- @tfield number dist Length between start and end position +-- @tfield bool is_drag Current drag state +-- @tfield number value Current slider value + + local Event = require("druid.event") local helper = require("druid.helper") local const = require("druid.const") @@ -14,6 +30,11 @@ local function on_change_value(self) end +--- Component init function +-- @function slider:init +-- @tparam node node Gui pin node +-- @tparam vector3 end_pos The end position of slider +-- @tparam[opt] function callback On slider change callback function M.init(self, node, end_pos, callback) self.node = self:get_node(node) @@ -79,6 +100,10 @@ function M.on_input(self, action_id, action) end +--- Set value for slider +-- @function slider:set +-- @tparam number value Value from 0 to 1 +-- @tparam[opt] bool is_silent Don't trigger event if true function M.set(self, value, is_silent) value = helper.clamp(value, 0, 1) diff --git a/druid/base/text.lua b/druid/base/text.lua index 1c19c2f..436a4c7 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -1,7 +1,25 @@ ---- Component to handle all GUI texts --- Good working with localization system +--- Component to handle all GUI texts. +-- Druid text can adjust itself for text node size +-- Text will never will be outside of his text size (even multiline) -- @module druid.text +--- Component events +-- @table Events +-- @tfield druid_event on_set_text On set text callback +-- @tfield druid_event on_update_text_scale On adjust text size callback +-- @tfield druid_event on_set_pivot On change pivot callback + +--- Component fields +-- @table Fields +-- @tfield node node Text node +-- @tfield vector3 pos Current text position +-- @tfield vector3 start_scale Initial text node scale +-- @tfield vector3 scale Current text node scale +-- @tfield vector3 start_size Initial text node size +-- @tfield vector3 text_area Current text node available are +-- @tfield bool is_no_adjust Current text size adjust settings +-- @tfield vector3 color Current text color + local Event = require("druid.event") local const = require("druid.const") local component = require("druid.component") @@ -19,33 +37,6 @@ local function update_text_size(self) end -function M.init(self, node, value, no_adjust) - self.node = self:get_node(node) - self.start_pivot = gui.get_pivot(self.node) - - self.start_pos = gui.get_position(self.node) - self.pos = gui.get_position(self.node) - - self.start_scale = gui.get_scale(self.node) - self.scale = gui.get_scale(self.node) - - self.start_size = gui.get_size(self.node) - self.text_area = gui.get_size(self.node) - self.text_area.x = self.text_area.x * self.start_scale.x - self.text_area.y = self.text_area.y * self.start_scale.y - - self.is_no_adjust = no_adjust - self.last_color = gui.get_color(self.node) - - self.on_set_text = Event() - self.on_update_text_scale = Event() - self.on_set_pivot = Event() - - self:set_to(value or 0) - return self -end - - --- Setup scale x, but can only be smaller, than start text scale local function update_text_area_size(self) gui.set_scale(self.node, self.start_scale) @@ -73,9 +64,37 @@ local function update_text_area_size(self) end +--- Component init function +-- @function text:init +-- @tparam node node Gui text node +-- @tparam[opt] string value Initial text +-- @tparam[opt] bool no_adjust If true, text will be not auto-adjust size +function M.init(self, node, value, no_adjust) + self.node = self:get_node(node) + self.pos = gui.get_position(self.node) + + self.start_scale = gui.get_scale(self.node) + self.scale = gui.get_scale(self.node) + + self.start_size = gui.get_size(self.node) + self.text_area = gui.get_size(self.node) + self.text_area.x = self.text_area.x * self.start_scale.x + self.text_area.y = self.text_area.y * self.start_scale.y + + self.is_no_adjust = no_adjust + self.color = gui.get_color(self.node) + + self.on_set_text = Event() + self.on_update_text_scale = Event() + self.on_set_pivot = Event() + + self:set_to(value or 0) + return self +end + + --- Set text to text field -- @function text:set_to --- @tparam table self Component instance -- @tparam string set_to Text for node function M.set_to(self, set_to) self.last_value = set_to @@ -91,28 +110,25 @@ end --- Set color -- @function text:set_color --- @tparam table self Component instance --- @tparam vmath.vector4 color Color for node +-- @tparam vector4 color Color for node function M.set_color(self, color) - self.last_color = color + self.color = color gui.set_color(self.node, color) end --- Set alpha -- @function text:set_alpha --- @tparam table self Component instance -- @tparam number alpha Alpha for node function M.set_alpha(self, alpha) - self.last_color.w = alpha - gui.set_color(self.node, self.last_color) + self.color.w = alpha + gui.set_color(self.node, self.color) end --- Set scale -- @function text:set_scale --- @tparam table self Component instance --- @tparam vmath.vector3 scale Scale for node +-- @tparam vector3 scale Scale for node function M.set_scale(self, scale) self.last_scale = scale gui.set_scale(self.node, scale) @@ -122,7 +138,6 @@ end --- Set text pivot. Text will re-anchor inside -- his text area -- @function text:set_pivot --- @tparam table self Component instance -- @tparam gui.pivot pivot Gui pivot constant function M.set_pivot(self, pivot) local prev_pivot = gui.get_pivot(self.node) diff --git a/druid/base/timer.lua b/druid/base/timer.lua index 8fecf86..712dc93 100644 --- a/druid/base/timer.lua +++ b/druid/base/timer.lua @@ -1,6 +1,24 @@ ---- Component to handle GUI timers +--- Component to handle GUI timers. +-- Timer updating by game delta time. If game is not focused - +-- timer will be not updated. -- @module druid.timer +--- Component events +-- @table Events +-- @tfield druid_event on_tick On timer tick callback. Fire every second +-- @tfield druid_event on_set_enabled On timer change enabled state callback +-- @tfield druid_event on_timer_end On timer end callback + +--- Component fields +-- @table Fields +-- @tfield node node Trigger node +-- @tfield[opt=node] node anim_node Animation node +-- @tfield vector3 scale_from Initial scale of anim_node +-- @tfield vector3 pos Initial pos of anim_node +-- @tfield any params Params to click callbacks +-- @tfield druid.hover hover Druid hover logic component +-- @tfield[opt] node click_zone Restriction zone + local Event = require("druid.event") local const = require("druid.const") local formats = require("druid.helper.formats") @@ -10,6 +28,12 @@ local component = require("druid.component") local M = component.create("timer", { const.ON_UPDATE }) +--- Component init function +-- @function timer:init +-- @tparam node node Gui text node +-- @tparam number seconds_from Start timer value in seconds +-- @tparam[opt=0] number seconds_to End timer value in seconds +-- @tparam[opt] function callback Function on timer end function M.init(self, node, seconds_from, seconds_to, callback) self.node = self:get_node(node) seconds_from = math.max(seconds_from, 0) @@ -31,42 +55,6 @@ function M.init(self, node, seconds_from, seconds_to, callback) end ---- Set text to text field --- @function timer:set_to --- @tparam table self Component instance --- @tparam number set_to Value in seconds -function M.set_to(self, set_to) - self.last_value = set_to - gui.set_text(self.node, formats.second_string_min(set_to)) -end - - ---- Called when update --- @function timer:set_state --- @tparam table self Component instance --- @tparam boolean is_on Timer enable state -function M.set_state(self, is_on) - self.is_on = is_on - - self.on_set_enabled:trigger(self:get_context(), is_on) -end - - ---- Set time interval --- @function timer:set_interval --- @tparam table self Component instance --- @tparam number from Start time in seconds --- @tparam number to Target time in seconds -function M.set_interval(self, from, to) - self.from = from - self.value = from - self.temp = 0 - self.target = to - M.set_state(self, true) - M.set_to(self, from) -end - - function M.update(self, dt) if not self.is_on then return @@ -89,5 +77,37 @@ function M.update(self, dt) end end +--- Set text to text field +-- @function timer:set_to +-- @tparam number set_to Value in seconds +function M.set_to(self, set_to) + self.last_value = set_to + gui.set_text(self.node, formats.second_string_min(set_to)) +end + + +--- Called when update +-- @function timer:set_state +-- @tparam bool is_on Timer enable state +function M.set_state(self, is_on) + self.is_on = is_on + + self.on_set_enabled:trigger(self:get_context(), is_on) +end + + +--- Set time interval +-- @function timer:set_interval +-- @tparam number from Start time in seconds +-- @tparam number to Target time in seconds +function M.set_interval(self, from, to) + self.from = from + self.value = from + self.temp = 0 + self.target = to + M.set_state(self, true) + M.set_to(self, from) +end + return M \ No newline at end of file diff --git a/druid/event.lua b/druid/event.lua index 1d6c289..b4bc110 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -45,7 +45,7 @@ end --- Return true, if event have at lease one handler -- @function event:is_exist --- @treturn boolean True if event have handlers +-- @treturn bool True if event have handlers function M.is_exist(self) return #self._callbacks > 0 end diff --git a/example/kenney/page/main.lua b/example/kenney/page/main.lua index 70e5539..834593c 100644 --- a/example/kenney/page/main.lua +++ b/example/kenney/page/main.lua @@ -19,8 +19,8 @@ end local function setup_button(self) local b = self.druid:new_button("button_simple", lang.toggle_locale, "button_param") self.druid:new_button("button_template/button", function() - print(b:get_enabled()) - b:set_enabled(not b:get_enabled()) + print(b:is_enabled()) + b:set_enabled(not b:is_enabled()) end, "button_param") end diff --git a/example/kenney/page/scroll.lua b/example/kenney/page/scroll.lua index 71fe04d..4fb112c 100644 --- a/example/kenney/page/scroll.lua +++ b/example/kenney/page/scroll.lua @@ -4,6 +4,7 @@ local M = {} local function init_grid(self) local prefab = gui.get_node("grid_prefab") + local grid_scroll = self.druid:new_scroll("grid_content", "scroll_with_grid_size") local grid = self.druid:new_grid("grid_content", "grid_prefab", 20) grid:set_anchor(vmath.vector3(0, 0.5, 0)) @@ -13,12 +14,15 @@ local function init_grid(self) grid:add(clone_prefab["grid_prefab"]) gui.set_text(clone_prefab["grid_prefab_text"], "Node " .. i) - self.druid:new_button(clone_prefab["grid_button"]) + self.druid:new_button(clone_prefab["grid_button"], function() + local position = gui.get_position(clone_prefab["grid_prefab"]) + position.x = -position.x + grid_scroll:scroll_to(position) + end) end gui.set_enabled(prefab, false) - local grid_scroll = self.druid:new_scroll("grid_content", "scroll_with_grid_size") grid_scroll:set_border(grid:get_size()) local scroll_slider = self.druid:new_slider("grid_scroll_pin", vmath.vector3(300, 0, 0), function(_, value) From b7e58950aa8588aced1fd973f72ae21c4471be3d Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 21:43:06 +0300 Subject: [PATCH 131/136] Update docs, updated ldoc generated files --- config.ld | 7 +- docs/index.html | 22 +- docs/modules/component.html | 3 +- docs/modules/druid.back_handler.html | 69 +++++- docs/modules/druid.blocker.html | 152 ++++++++++++- docs/modules/druid.button.html | 104 ++++++--- docs/modules/druid.checkbox.html | 193 +++++++++++++++- docs/modules/druid.checkbox_group.html | 157 ++++++++++++- docs/modules/druid.grid.html | 288 +++++++++++++++++++++++- docs/modules/druid.helper.html | 3 +- docs/modules/druid.hover.html | 209 +++++++++++++++++ docs/modules/druid.html | 7 +- docs/modules/druid.input.html | 84 +------ docs/modules/druid.lang_text.html | 129 ++++++++++- docs/modules/druid.progress.html | 191 +++++++++++----- docs/modules/druid.radio_group.html | 155 ++++++++++++- docs/modules/druid.scroll.html | 298 +++++++++++++++++++++---- docs/modules/druid.slider.html | 164 +++++++++++++- docs/modules/druid.text.html | 184 +++++++++++---- docs/modules/druid.timer.html | 167 ++++++++++++-- docs/modules/druid_event.html | 70 +++++- docs/modules/druid_instance.html | 3 +- druid/base/blocker.lua | 3 + druid/base/hover.lua | 2 +- druid/base/input.lua | 2 +- druid/druid.lua | 4 +- 26 files changed, 2354 insertions(+), 316 deletions(-) create mode 100644 docs/modules/druid.hover.html diff --git a/config.ld b/config.ld index 00b4508..6da4f05 100644 --- a/config.ld +++ b/config.ld @@ -1,7 +1,12 @@ project='Druid' title='Defold Druid UI Library' description='Documentation for Druid Library' -file={"./druid"} +file={"./druid", + exclude = { + "./druid/styles/", + "./druid/system/middleclass.lua" + } +} package='druid' sort=false dir='./docs' diff --git a/docs/index.html b/docs/index.html index aa797fc..c7d2383 100644 --- a/docs/index.html +++ b/docs/index.html @@ -37,6 +37,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -67,7 +68,7 @@ druid.blocker - Component to block input on specify zone (node) + Component to block input on specify zone by node druid.button @@ -79,16 +80,20 @@ druid.checkbox_group - Checkboux group module + Checkbox group module druid.grid Component to handle placing components by row and columns. - druid.input + druid.hover Component to handle hover node interaction + + druid.input + Druid input text component. + druid.lang_text Component to handle all GUI texts @@ -96,7 +101,7 @@ druid.progress - Basic progress bar component + Basic progress bar component. druid.radio_group @@ -104,7 +109,7 @@ druid.scroll - Component to handle scroll content + Component to handle scroll content. druid.slider @@ -112,12 +117,11 @@ druid.text - Component to handle all GUI texts - Good working with localization system + Component to handle all GUI texts. druid.timer - Component to handle GUI timers + Component to handle GUI timers. component @@ -145,7 +149,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 20:02:23 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/component.html b/docs/modules/component.html index 03ef47b..a145600 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -44,6 +44,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -396,7 +397,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 2943f1f..19bd134 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -33,6 +33,7 @@

    Contents

    @@ -44,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -73,7 +75,7 @@

    Functions

    - + @@ -81,6 +83,17 @@
    init(self, callback[, Callback])init(callback[, Callback]) Component init function
    Input handler for component
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    @@ -91,7 +104,7 @@
    - init(self, callback[, Callback]) + init(callback[, Callback])
    Component init function @@ -99,10 +112,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • callback callback On back button @@ -143,6 +152,52 @@ +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_back + druid_event + On back handler callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • params + any + Params to click callbacks +
    • +
    + + + + +
    @@ -151,7 +206,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index ad72a4e..1c9d698 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -30,6 +30,11 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -40,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -60,24 +66,166 @@

    Module druid.blocker

    -

    Component to block input on specify zone (node)

    +

    Component to block input on specify zone by node

    +

    Functions

    + + + + + + + + + + + + + +
    init(node)Component init function
    set_enabled(state)Set enabled blocker component state
    is_enabled()Return blocked enabled state
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    +

    Functions

    + +
    +
    + + init(node) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + Gui node +
    • +
    + + + + + +
    +
    + + set_enabled(state) +
    +
    + Set enabled blocker component state + + +

    Parameters:

    +
      +
    • state + bool + Enabled state +
    • +
    + + + + + +
    +
    + + is_enabled() +
    +
    + Return blocked enabled state + + + +

    Returns:

    +
      + + bool + True, if blocker is enabled +
    + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_click + druid_event + On release button callback +
    • +
    • on_enable_change + druid_event + On enable/disable callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Trigger node +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 886be31..a7097f9 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -45,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -74,19 +75,27 @@

    Functions

    - + - - + + - + + + + + - + + + + +
    init(self, node, callback[, params[, anim_node[, event]]])init(node, callback[, params[, anim_node[, event]]]) Component init function
    disable_animation(self)Disable all button animationsset_enabled(state)Set enabled button component state
    set_click_zone(self, zone)is_enabled()Return button enabled state
    set_click_zone(zone) Strict button click area.
    get_key_trigger(self)set_key_trigger(key)Set key-code to trigger this button
    get_key_trigger() Get key-code to trigger this button
    @@ -115,7 +124,7 @@
    - init(self, node, callback[, params[, anim_node[, event]]]) + init(node, callback[, params[, anim_node[, event]]])
    Component init function @@ -123,10 +132,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • node node Gui node @@ -158,18 +163,18 @@
    - - disable_animation(self) + + set_enabled(state)
    - Disable all button animations + Set enabled button component state

    Parameters:

      -
    • self - table - Component instance +
    • state + bool + Enabled state
    @@ -177,10 +182,30 @@ +
    +
    + + is_enabled() +
    +
    + Return button enabled state + + + +

    Returns:

    +
      + + bool + True, if button is enabled +
    + + + +
    - set_click_zone(self, zone) + set_click_zone(zone)
    Strict button click area. Useful for @@ -189,10 +214,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • zone node Gui node @@ -203,24 +224,43 @@ +
    +
    + + set_key_trigger(key) +
    +
    + Set key-code to trigger this button + + +

    Parameters:

    +
      +
    • key + hash + The action_id of the key +
    • +
    + + + + +
    - get_key_trigger(self) + get_key_trigger()
    Get key-code to trigger this button -

    Parameters:

    -
      -
    • self +

      Returns:

      +
        - - -
    - + hash + The action_id of the key + @@ -294,10 +334,6 @@ any Params to click callbacks -
  • hover_anim - boolean - Is hover anim enabled -
  • hover druid.hover Druid hover logic component @@ -360,7 +396,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index 66054fe..cb9ad9f 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -30,6 +30,11 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -40,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -66,18 +72,203 @@

    +

    Functions

    + + + + + + + + + + + + + +
    init(node, callback[, click=node])Component init function
    set_state(state, is_silent)Set checkbox state
    get_state()Return checkbox state
    +

    Tables

    + + + + + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields
    StyleComponent style params


    +

    Functions

    + +
    +
    + + init(node, callback[, click=node]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + Gui node +
    • +
    • callback + function + Checkbox callback +
    • +
    • click + node + node Trigger node, by default equals to node + (default node) +
    • +
    + + + + + +
    +
    + + set_state(state, is_silent) +
    +
    + Set checkbox state + + +

    Parameters:

    +
      +
    • state + bool + Checkbox state +
    • +
    • is_silent + bool + Don't trigger onchangestate if true +
    • +
    + + + + + +
    +
    + + get_state() +
    +
    + Return checkbox state + + + +

    Returns:

    +
      + + bool + Checkbox state +
    + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_change_state + druid_event + On change state callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Visual node +
    • +
    • click_node + node + Button trigger node + (default node) +
    • +
    • button + druid.button + Button component from click_node +
    • +
    + + + + + +
    +
    + + Style +
    +
    + Component style params + + +

    Fields:

    +
      +
    • on_change_state + function + (self, node, state) +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index 1c40d26..920762e 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -30,6 +30,11 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -40,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -60,24 +66,171 @@

    Module druid.checkbox_group

    -

    Checkboux group module

    +

    Checkbox group module

    +

    Functions

    + + + + + + + + + + + + + +
    init(node, callback[, click=node])Component init function
    set_state(state)Set checkbox group state
    get_state()Return checkbox group state
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    +

    Functions

    + +
    +
    + + init(node, callback[, click=node]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node[] + Array of gui node +
    • +
    • callback + function + Checkbox callback +
    • +
    • click + node[] + node Array of trigger nodes, by default equals to nodes + (default node) +
    • +
    + + + + + +
    +
    + + set_state(state) +
    +
    + Set checkbox group state + + +

    Parameters:

    +
      +
    • state + bool[] + Array of checkbox state +
    • +
    + + + + + +
    +
    + + get_state() +
    +
    + Return checkbox group state + + + +

    Returns:

    +
      + + bool[] + Array if checkboxes state +
    + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_checkbox_click + druid_event + On any checkbox click +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • checkboxes + table + Array of checkbox components +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 69dee2b..3df4a00 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -30,6 +30,11 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -40,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -64,18 +70,298 @@

    Grid can anchor your elements, get content size and other

    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    init(parent, element[, in_row=1])Component init function
    set_offset(offset)Set grid items offset, the distance between items
    set_anchor(acnhor)Set grid anchor
    add(item[, index])Add new item to the grid
    get_size()Return grid content size
    get_all_pos()Return array of all node positions
    clear()Clear all items from the grid
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    +

    Functions

    + +
    +
    + + init(parent, element[, in_row=1]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • parent + node + The gui node parent, where items will be placed +
    • +
    • element + node + Element prefab. Need to get it size +
    • +
    • in_row + number + How many nodes in row can be placed + (default 1) +
    • +
    + + + + + +
    +
    + + set_offset(offset) +
    +
    + Set grid items offset, the distance between items + + +

    Parameters:

    +
      +
    • offset + vector3 + Offset +
    • +
    + + + + + +
    +
    + + set_anchor(acnhor) +
    +
    + Set grid anchor + + +

    Parameters:

    +
      +
    • acnhor + vector3 + Anchor +
    • +
    + + + + + +
    +
    + + add(item[, index]) +
    +
    + Add new item to the grid + + +

    Parameters:

    +
      +
    • item + node + Gui node +
    • +
    • index + number + The item position. By default add as last item + (optional) +
    • +
    + + + + + +
    +
    + + get_size() +
    +
    + Return grid content size + + + +

    Returns:

    +
      + + vector3 + The grid content size +
    + + + + +
    +
    + + get_all_pos() +
    +
    + Return array of all node positions + + + +

    Returns:

    +
      + + vector3[] + All grid node positions +
    + + + + +
    +
    + + clear() +
    +
    + Clear all items from the grid + + + + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_add_item + druid_event + On item add callback +
    • +
    • on_remove_item + druid_event + On item remove callback +
    • +
    • on_clear + druid_event + On grid clear callback +
    • +
    • on_update_positions + druid_event + On update item positions callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • parent + node + Parent gui node +
    • +
    • nodes + node[] + List of all grid nodes +
    • +
    • offset + vector3 + Item distance between each other items +
    • +
    • anchor + vector3 + Item anchor +
    • +
    • node_size + vector3 + Item size +
    • +
    • border + vector4 + The size of item content +
    • +
    • border_offer + vector3 + The border offset for correct anchor calculations +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.helper.html b/docs/modules/druid.helper.html index c81e977..5091943 100644 --- a/docs/modules/druid.helper.html +++ b/docs/modules/druid.helper.html @@ -44,6 +44,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -226,7 +227,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.hover.html b/docs/modules/druid.hover.html new file mode 100644 index 0000000..da05a4d --- /dev/null +++ b/docs/modules/druid.hover.html @@ -0,0 +1,209 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module druid.hover

    +

    Component to handle hover node interaction

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + +
    init(node, on_hover_callback)Component init function
    set_hover(state)Set hover state
    set_click_zone(zone)Strict button click area.
    +

    Tables

    + + + + + +
    EventsComponent events
    + +
    +
    + + +

    Functions

    + +
    +
    + + init(node, on_hover_callback) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + Gui node +
    • +
    • on_hover_callback + function + Hover callback +
    • +
    + + + + + +
    +
    + + set_hover(state) +
    +
    + Set hover state + + +

    Parameters:

    +
      +
    • state + bool + The hover state +
    • +
    + + + + + +
    +
    + + set_click_zone(zone) +
    +
    + Strict button click area. Useful for + no click events outside stencil node + + +

    Parameters:

    +
      +
    • zone + node + Gui node +
    • +
    + + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_hover + druid_event + On hover callback +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 21:42:52 +
    +
    + + diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 46038ef..7e40457 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -44,6 +44,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -68,8 +69,8 @@

    Powerful Defold component based UI library. Use standart - components or make your own game-specific to make amazing - GUI in your games.

    + components or make your own game-specific components to + make amazing GUI in your games.

    Contains the several basic components and examples to how to do your custom complex components to @@ -171,7 +172,7 @@

    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.input.html b/docs/modules/druid.input.html index da6d315..b453a81 100644 --- a/docs/modules/druid.input.html +++ b/docs/modules/druid.input.html @@ -30,10 +30,6 @@
  • Index
  • -

    Contents

    -

    Modules

    @@ -44,6 +40,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -64,94 +61,23 @@

    Module druid.input

    -

    Component to handle hover node interaction

    -

    - -

    +

    Druid input text component.

    +

    Carry on user text input + UNIMPLEMENTED

    -

    Functions

    - - - - - - - - - -
    hover:init(self, node, on_hover_callback)Component init function
    button:set_click_zone(self, zone)Strict button click area.


    -

    Functions

    - -
    -
    - - hover:init(self, node, on_hover_callback) -
    -
    - Component init function - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • node - node - Gui node -
    • -
    • on_hover_callback - function - Hover callback -
    • -
    - - - - - -
    -
    - - button:set_click_zone(self, zone) -
    -
    - Strict button click area. Useful for - no click events outside stencil node - - -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    • zone - node - Gui node -
    • -
    - - - - - -
    -
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.lang_text.html b/docs/modules/druid.lang_text.html index 9f52f6b..9c5f2f6 100644 --- a/docs/modules/druid.lang_text.html +++ b/docs/modules/druid.lang_text.html @@ -33,6 +33,7 @@

    Contents

    @@ -44,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -74,10 +76,29 @@

    Functions

    - + + + + + + + + +
    text:translate(self, locale_id)init(node, locale_id, no_adjust)Component init function
    set_to(text)Setup raw text to lang_text component
    translate(locale_id) Translate the text by locale_id
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    @@ -87,8 +108,58 @@
    - - text:translate(self, locale_id) + + init(node, locale_id, no_adjust) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + The text node +
    • +
    • locale_id + string + Default locale id +
    • +
    • no_adjust + bool + If true, will not correct text size +
    • +
    + + + + + +
    +
    + + set_to(text) +
    +
    + Setup raw text to lang_text component + + +

    Parameters:

    +
      +
    • text + string + Text for text node +
    • +
    + + + + + +
    +
    + + translate(locale_id)
    Translate the text by locale_id @@ -96,10 +167,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • locale_id string Locale id @@ -110,6 +177,52 @@ +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_change + druid_event + On change text callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • text + druid.text + The text component +
    • +
    + + + + +
    @@ -118,7 +231,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index e8e1115..14ca013 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -33,6 +33,7 @@

    Contents

    @@ -44,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -64,43 +66,56 @@

    Module druid.progress

    -

    Basic progress bar component

    -

    - -

    +

    Basic progress bar component.

    +

    For correct progress bar init it should be in max size from gui

    Functions

    - + - + - + - + - + - + - +
    init(self, node, key, init_value)init(node, key, init_value) Component init function
    empty(self)fill() Fill a progress bar and stop progress animation
    empty(self)empty() Empty a progress bar
    set_to(self, to)set_to(to) Instant fill progress bar to value
    get(self)get() Return current progress bar value
    set_steps(self, steps, callback)set_steps(steps, callback) Set points on progress bar to fire the callback
    to(self, to[, callback])to(to[, callback]) Start animation of a progress bar
    +

    Tables

    + + + + + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields
    StyleComponent style params


    @@ -111,7 +126,7 @@
    - init(self, node, key, init_value) + init(node, key, init_value)
    Component init function @@ -119,17 +134,13 @@

    Parameters:

      -
    • self - table - Component instance -
    • node string or node Progress bar fill node or node name
    • key string - Progress bar direction (x or y) + Progress bar direction: const.SIDE.X or const.SIDE.Y
    • init_value number @@ -143,20 +154,13 @@
    - - empty(self) + + fill()
    Fill a progress bar and stop progress animation -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    @@ -165,19 +169,12 @@
    - empty(self) + empty()
    Empty a progress bar -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    @@ -186,7 +183,7 @@
    - set_to(self, to) + set_to(to)
    Instant fill progress bar to value @@ -194,10 +191,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • to number Progress bar value, from 0 to 1 @@ -211,19 +204,12 @@
    - get(self) + get()
    Return current progress bar value -

    Parameters:

    -
      -
    • self - table - Component instance -
    • -
    @@ -232,7 +218,7 @@
    - set_steps(self, steps, callback) + set_steps(steps, callback)
    Set points on progress bar to fire the callback @@ -240,12 +226,8 @@

    Parameters:

      -
    • self - table - Component instance -
    • steps - table + number[] Array of progress bar values
    • callback @@ -257,11 +239,15 @@ +

      Usage:

      +
        +
        progress:set_steps({0, 0.3, 0.6, 1}, function(self, step) end)
        +
    - to(self, to[, callback]) + to(to[, callback])
    Start animation of a progress bar @@ -269,10 +255,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • to number value between 0..1 @@ -288,6 +270,97 @@ +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_change + druid_event + On progress bar change callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Progress bar fill node +
    • +
    • key + string + The progress bar direction +
    • +
    • scale + vector3 + Current progress bar scale +
    • +
    • size + vector3 + Current progress bar size +
    • +
    • max_size + number + Maximum size of progress bar +
    • +
    • slice + vector4 + Progress bar slice9 settings +
    • +
    + + + + + +
    +
    + + Style +
    +
    + Component style params + + +

    Fields:

    +
      +
    • SPEED + number + Progress bas fill rate. More -> faster +
    • +
    • MIN_DELTA + number + Minimum step to fill progress bar +
    • +
    + + + + +
    @@ -296,7 +369,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index 5d71a85..e14bc76 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -30,6 +30,11 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -40,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -66,18 +72,165 @@

    +

    Functions

    + + + + + + + + + + + + + +
    init(node, callback[, click=node])Component init function
    set_state(state)Set radio group state
    get_state()Return radio group state
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    +

    Functions

    + +
    +
    + + init(node, callback[, click=node]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node[] + Array of gui node +
    • +
    • callback + function + Radio callback +
    • +
    • click + node[] + node Array of trigger nodes, by default equals to nodes + (default node) +
    • +
    + + + + + +
    +
    + + set_state(state) +
    +
    + Set radio group state + + +

    Parameters:

    +
      +
    • state + bool[] + Array of checkbox state +
    • +
    + + + + + +
    +
    + + get_state() +
    +
    + Return radio group state + + + +

    Returns:

    +
      + + bool[] + Array if checkboxes state +
    + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_radio_click + druid_event + On any checkbox click +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • checkboxes + table + Array of checkbox components +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index 551ceb5..38a41bb 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -33,6 +33,7 @@

    Contents

    @@ -44,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -64,38 +66,68 @@

    Module druid.scroll

    -

    Component to handle scroll content

    -

    - -

    +

    Component to handle scroll content.

    +

    Scroll consist from two nodes: scroll parent and scroll input + Scroll input the user input zone, it's static + Scroll parent the scroll moving part, it will change position. + Setup initial scroll size by changing scroll parent size. If scroll parent + size will be less than scroll_input size, no scroll is available. For scroll + parent size should be more than input size

    Functions

    + + + + - + + + + + - + - + - + - + + + + + +
    init(scroll_parent, input_zone)Component init function
    scroll_to(vector3[, is_instant]) Start scroll to target point
    init(self, index[, skip_cb])scroll_to_percent(vector3[, is_instant])Start scroll to target scroll percent
    init(index[, skip_cb]) Scroll to item in scroll by point index
    set_points(self, points)set_points(points) Set points of interest.
    set_inert(self, state)set_inert(state) Enable or disable scroll inert.
    on_point_move(self, callback)on_point_move(callback) Set the callback on scrolling to point (if exist)
    set_border(self, border)set_border(border) Set the scroll possibly area
    get_scroll_percent()Return current scroll progress
    +

    Tables

    + + + + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields
    StyleComponent style params

    @@ -105,6 +137,31 @@

    Functions

    +
    + + init(scroll_parent, input_zone) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • scroll_parent + node + Gui node where placed scroll content. This node will change position +
    • +
    • input_zone + node + Gui node where input is catched +
    • +
    + + + + + +
    scroll_to(vector3[, is_instant]) @@ -135,10 +192,40 @@
  • scroll:scroll_to(vmath.vector3(0), true)
  • +
    +
    + + scroll_to_percent(vector3[, is_instant]) +
    +
    + Start scroll to target scroll percent + + +

    Parameters:

    +
      +
    • vector3 + point + target percent +
    • +
    • is_instant + bool + instant scroll flag + (optional) +
    • +
    + + + + +

    Usage:

    +
      +
      scroll:scroll_to_percent(vmath.vector3(0.5, 0, 0))
      +
    +
    - init(self, index[, skip_cb]) + init(index[, skip_cb])
    Scroll to item in scroll by point index @@ -146,16 +233,12 @@

    Parameters:

      -
    • self - table - Component instance -
    • index number Point index
    • skip_cb - boolean + bool If true, skip the point callback (optional)
    • @@ -168,7 +251,7 @@
    - set_points(self, points) + set_points(points)
    Set points of interest. @@ -177,10 +260,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • points table Array of vector3 points @@ -194,7 +273,7 @@
    - set_inert(self, state) + set_inert(state)
    Enable or disable scroll inert. @@ -204,12 +283,8 @@

    Parameters:

      -
    • self - table - Component instance -
    • state - boolean + bool Inert scroll state
    @@ -221,7 +296,7 @@
    - on_point_move(self, callback) + on_point_move(callback)
    Set the callback on scrolling to point (if exist) @@ -229,10 +304,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • callback function Callback on scroll to point of interest @@ -246,7 +317,7 @@
    - set_border(self, border) + set_border(border)
    Set the scroll possibly area @@ -254,12 +325,8 @@

    Parameters:

      -
    • self - table - Component instance -
    • border - vmath.vector3 + vector3 Size of scrolling area
    @@ -268,6 +335,161 @@ +
    +
    + + get_scroll_percent() +
    +
    + Return current scroll progress + + + +

    Returns:

    +
      + + vector3 + Scroll progress +
    + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_scroll + druid_event + On scroll move callback +
    • +
    • on_scroll_to + druid_event + On scroll_to function callback +
    • +
    • on_point_scroll + druid_event + On scrolltoindex function callbck +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Scroll parent node +
    • +
    • input_zone + node + Scroll input node +
    • +
    • zone_size + vector3 + Current scroll content size +
    • +
    • soft_size + number + Soft zone size from style table +
    • +
    • center_offset + vector3 + Distance from node to node's center +
    • +
    • is_inert + bool + Flag, if scroll now moving by inertion +
    • +
    • inert + vector3 + Current inert speed +
    • +
    • pos + vector3 + Current scroll posisition +
    • +
    • target + vector3 + Current scroll target position +
    • +
    + + + + + +
    +
    + + Style +
    +
    + Component style params + + +

    Fields:

    +
      +
    • FRICT_HOLD + number + Multiplier for inertion, while touching +
    • +
    • FRICT + number + Multiplier for free inertion +
    • +
    • INERT_THRESHOLD + number + Scroll speed to stop inertion +
    • +
    • INERT_SPEED + number + Multiplier for inertion speed +
    • +
    • DEADZONE + number + Deadzone for start scrol in pixels +
    • +
    • SOFT_ZONE_SIZE + number + Size of outside zone in pixels (for scroll back moving) +
    • +
    • BACK_SPEED + number + Scroll back returning lerp speed +
    • +
    • ANIM_SPEED + number + Scroll gui.animation speed for scroll_to function +
    • +
    + + + + +
    @@ -276,7 +498,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index a4abba6..2f2e11e 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -30,6 +30,11 @@
  • Index
  • +

    Contents

    +

    Modules

    @@ -40,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -66,18 +72,174 @@

    +

    Functions

    + + + + + + + + + +
    init(node, end_pos[, callback])Component init function
    set(value[, is_silent])Set value for slider
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    +

    Functions

    + +
    +
    + + init(node, end_pos[, callback]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + Gui pin node +
    • +
    • end_pos + vector3 + The end position of slider +
    • +
    • callback + function + On slider change callback + (optional) +
    • +
    + + + + + +
    +
    + + set(value[, is_silent]) +
    +
    + Set value for slider + + +

    Parameters:

    +
      +
    • value + number + Value from 0 to 1 +
    • +
    • is_silent + bool + Don't trigger event if true + (optional) +
    • +
    + + + + + +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_change_value + druid_event + On change value callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Slider pin node +
    • +
    • start_pos + vector3 + Start pin node position +
    • +
    • pos + vector3 + Current pin node position +
    • +
    • target_pos + vector3 + Targer pin node position +
    • +
    • end_pos + vector3 + End pin node position +
    • +
    • dist + number + Length between start and end position +
    • +
    • is_drag + bool + Current drag state +
    • +
    • value + number + Current slider value +
    • +
    + + + + + +
    +
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index 6df4131..7796639 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -33,6 +33,7 @@

    Contents

    @@ -44,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -64,36 +66,49 @@

    Module druid.text

    -

    Component to handle all GUI texts - Good working with localization system

    -

    - -

    +

    Component to handle all GUI texts.

    +

    Druid text can adjust itself for text node size + Text will never will be outside of his text size (even multiline)

    Functions

    - + + + + + - + - + - + - +
    set_to(self, set_to)init(node[, value[, no_adjust]])Component init function
    set_to(set_to) Set text to text field
    set_color(self, color)set_color(color) Set color
    set_alpha(self, alpha)set_alpha(alpha) Set alpha
    set_scale(self, scale)set_scale(scale) Set scale
    set_pivot(self, pivot)set_pivot(pivot) Set text pivot.
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    @@ -102,9 +117,40 @@

    Functions

    +
    + + init(node[, value[, no_adjust]]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + Gui text node +
    • +
    • value + string + Initial text + (optional) +
    • +
    • no_adjust + bool + If true, text will be not auto-adjust size + (optional) +
    • +
    + + + + + +
    - set_to(self, set_to) + set_to(set_to)
    Set text to text field @@ -112,10 +158,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • set_to string Text for node @@ -129,7 +171,7 @@
    - set_color(self, color) + set_color(color)
    Set color @@ -137,12 +179,8 @@

    Parameters:

      -
    • self - table - Component instance -
    • color - vmath.vector4 + vector4 Color for node
    @@ -154,7 +192,7 @@
    - set_alpha(self, alpha) + set_alpha(alpha)
    Set alpha @@ -162,10 +200,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • alpha number Alpha for node @@ -179,7 +213,7 @@
    - set_scale(self, scale) + set_scale(scale)
    Set scale @@ -187,12 +221,8 @@

    Parameters:

      -
    • self - table - Component instance -
    • scale - vmath.vector3 + vector3 Scale for node
    @@ -204,7 +234,7 @@
    - set_pivot(self, pivot) + set_pivot(pivot)
    Set text pivot. Text will re-anchor inside @@ -213,10 +243,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • pivot gui.pivot Gui pivot constant @@ -227,6 +253,88 @@ +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_set_text + druid_event + On set text callback +
    • +
    • on_update_text_scale + druid_event + On adjust text size callback +
    • +
    • on_set_pivot + druid_event + On change pivot callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Text node +
    • +
    • pos + vector3 + Current text position +
    • +
    • start_scale + vector3 + Initial text node scale +
    • +
    • scale + vector3 + Current text node scale +
    • +
    • start_size + vector3 + Initial text node size +
    • +
    • text_area + vector3 + Current text node available are +
    • +
    • is_no_adjust + bool + Current text size adjust settings +
    • +
    • color + vector3 + Current text color +
    • +
    + + + + +
    @@ -235,7 +343,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index 8fef622..a45db3f 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -33,6 +33,7 @@

    Contents

    @@ -44,6 +45,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -64,27 +66,41 @@

    Module druid.timer

    -

    Component to handle GUI timers

    -

    - -

    +

    Component to handle GUI timers.

    +

    Timer updating by game delta time. If game is not focused - + timer will be not updated.

    Functions

    - + + + + + - + - +
    set_to(self, set_to)init(node, seconds_from[, seconds_to=0[, callback]])Component init function
    set_to(set_to) Set text to text field
    set_state(self, is_on)set_state(is_on) Called when update
    set_interval(self, from, to)set_interval(from, to) Set time interval
    +

    Tables

    + + + + + + + + + +
    EventsComponent events
    FieldsComponent fields


    @@ -93,9 +109,44 @@

    Functions

    +
    + + init(node, seconds_from[, seconds_to=0[, callback]]) +
    +
    + Component init function + + +

    Parameters:

    +
      +
    • node + node + Gui text node +
    • +
    • seconds_from + number + Start timer value in seconds +
    • +
    • seconds_to + number + End timer value in seconds + (default 0) +
    • +
    • callback + function + Function on timer end + (optional) +
    • +
    + + + + + +
    - set_to(self, set_to) + set_to(set_to)
    Set text to text field @@ -103,10 +154,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • set_to number Value in seconds @@ -120,7 +167,7 @@
    - set_state(self, is_on) + set_state(is_on)
    Called when update @@ -128,12 +175,8 @@

    Parameters:

      -
    • self - table - Component instance -
    • is_on - boolean + bool Timer enable state
    @@ -145,7 +188,7 @@
    - set_interval(self, from, to) + set_interval(from, to)
    Set time interval @@ -153,10 +196,6 @@

    Parameters:

      -
    • self - table - Component instance -
    • from number Start time in seconds @@ -171,6 +210,86 @@ +
    +
    +

    Tables

    + +
    +
    + + Events +
    +
    + Component events + + +

    Fields:

    +
      +
    • on_tick + druid_event + On timer tick callback. Fire every second +
    • +
    • on_set_enabled + druid_event + On timer change enabled state callback +
    • +
    • on_timer_end + druid_event + On timer end callback +
    • +
    + + + + + +
    +
    + + Fields +
    +
    + Component fields + + +

    Fields:

    +
      +
    • node + node + Trigger node +
    • +
    • anim_node + node + Animation node + (default node) +
    • +
    • scale_from + vector3 + Initial scale of anim_node +
    • +
    • pos + vector3 + Initial pos of anim_node +
    • +
    • params + any + Params to click callbacks +
    • +
    • hover + druid.hover + Druid hover logic component +
    • +
    • click_zone + node + Restriction zone + (optional) +
    • +
    + + + + +
    @@ -179,7 +298,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid_event.html b/docs/modules/druid_event.html index dc54081..b665666 100644 --- a/docs/modules/druid_event.html +++ b/docs/modules/druid_event.html @@ -44,6 +44,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -72,6 +73,10 @@

    Functions

    + + + + @@ -81,6 +86,14 @@ + + + + + + + + @@ -93,6 +106,27 @@

    Functions

    +
    + + Event(initial_callback) +
    +
    + Event constructur + + +

    Parameters:

    +
      +
    • initial_callback + function + Subscribe the callback on new event, if callback exist +
    • +
    + + + + + +
    event:subscribe(callback) @@ -134,6 +168,40 @@ + +
    + + event:is_exist() +
    +
    + Return true, if event have at lease one handler + + + +

    Returns:

    +
      + + bool + True if event have handlers +
    + + + + +
    +
    + + event:clear() +
    +
    + Clear the all event handlers + + + + + + +
    @@ -162,7 +230,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index 732fba4..d4f8c21 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -44,6 +44,7 @@
  • druid.checkbox
  • druid.checkbox_group
  • druid.grid
  • +
  • druid.hover
  • druid.input
  • druid.lang_text
  • druid.progress
  • @@ -740,7 +741,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-02-24 00:03:02 +Last updated 2020-03-21 21:42:52
    diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index e32239e..0b336bd 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -17,6 +17,9 @@ local component = require("druid.component") local M = component.create("blocker", { const.ON_INPUT_HIGH }) +--- Component init function +-- @function blocker:init +-- @tparam node node Gui node function M.init(self, node) self.node = self:get_node(node) diff --git a/druid/base/hover.lua b/druid/base/hover.lua index a38cda0..0fb916a 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -72,7 +72,7 @@ end --- Strict button click area. Useful for -- no click events outside stencil node --- @function button:set_click_zone +-- @function hover:set_click_zone -- @tparam node zone Gui node function M.set_click_zone(self, zone) self.click_zone = self:get_node(zone) diff --git a/druid/base/input.lua b/druid/base/input.lua index 21079a2..603eb71 100644 --- a/druid/base/input.lua +++ b/druid/base/input.lua @@ -1,6 +1,6 @@ --- Druid input text component. -- Carry on user text input --- @local unimplemented +-- UNIMPLEMENTED -- @module druid.input local component = require("druid.component") diff --git a/druid/druid.lua b/druid/druid.lua index 5993e26..3a05c83 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -1,7 +1,7 @@ --- Druid UI Library. -- Powerful Defold component based UI library. Use standart --- components or make your own game-specific to make amazing --- GUI in your games. +-- components or make your own game-specific components to +-- make amazing GUI in your games. -- -- Contains the several basic components and examples -- to how to do your custom complex components to From c0320d9f1bfe31f56c07cc78fdfc06795803a3e7 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 22:54:18 +0300 Subject: [PATCH 132/136] Update README and add topics --- README.md | 218 ++++++------------ config.ld | 1 + docs/index.html | 38 ++- docs/modules/component.html | 11 +- docs/modules/druid.back_handler.html | 11 +- docs/modules/druid.blocker.html | 11 +- docs/modules/druid.button.html | 11 +- docs/modules/druid.checkbox.html | 11 +- docs/modules/druid.checkbox_group.html | 11 +- docs/modules/druid.grid.html | 11 +- docs/modules/druid.helper.html | 11 +- docs/modules/druid.hover.html | 11 +- docs/modules/druid.html | 11 +- docs/modules/druid.input.html | 11 +- docs/modules/druid.lang_text.html | 11 +- docs/modules/druid.progress.html | 11 +- docs/modules/druid.radio_group.html | 11 +- docs/modules/druid.scroll.html | 11 +- docs/modules/druid.slider.html | 11 +- docs/modules/druid.text.html | 11 +- docs/modules/druid.timer.html | 11 +- docs/modules/druid_event.html | 11 +- docs/modules/druid_instance.html | 11 +- docs/topics/README.md.html | 217 +++++++++++++++++ docs/topics/components.md.html | 152 ++++++++++++ docs/topics/create_custom_components.md.html | 172 ++++++++++++++ .../topics/creating_custom_components.md.html | 200 ++++++++++++++++ docs/topics/druid_assets.md.html | 96 ++++++++ docs/topics/examples.md.html | 94 ++++++++ docs/topics/online_example.md.html | 86 +++++++ docs/topics/styles.md.html | 145 ++++++++++++ docs_md/components.md | 40 ++++ docs_md/creating_custom_components.md | 105 +++++++++ docs_md/druid_assets.md | 8 + docs_md/examples.md | 6 + docs_md/styles.md | 47 ++++ 36 files changed, 1671 insertions(+), 174 deletions(-) create mode 100644 docs/topics/README.md.html create mode 100644 docs/topics/components.md.html create mode 100644 docs/topics/create_custom_components.md.html create mode 100644 docs/topics/creating_custom_components.md.html create mode 100644 docs/topics/druid_assets.md.html create mode 100644 docs/topics/examples.md.html create mode 100644 docs/topics/online_example.md.html create mode 100644 docs/topics/styles.md.html create mode 100644 docs_md/components.md create mode 100644 docs_md/creating_custom_components.md create mode 100644 docs_md/druid_assets.md create mode 100644 docs_md/examples.md create mode 100644 docs_md/styles.md diff --git a/README.md b/README.md index 60931e1..21a78bd 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,60 @@ -[![](media/druid_logo.png)](https://AGulev.github.io/druid/) -_travis/release bages_ +![](druid_logo.png) -**Druid** - powerful defold component UI library. Use standart components or make your own game-specific to make amazing GUI in your games. +**Druid** - powerful defold component UI library. Use basic druid components or make your own game-specific components to make amazing GUI in your games. ## Setup #### Dependency You can use the druid extension in your own project by adding this project as a [Defold library dependency](https://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add: -> [https://github.com/AGulev/druid/archive/master.zip](https://github.com/AGulev/druid/archive/master.zip) +> [https://github.com/Insality/druid/archive/master.zip](https://github.com/Insality/druid/archive/master.zip) -Or point to the ZIP file of a [specific release](https://github.com/AGulev/druid/releases). +Or point to the ZIP file of a [specific release](https://github.com/Insality/druid/releases). #### Code -Adjust druid settings: +Adjust druid settings, if needed: ```lua local druid = require("druid.druid") ---- Function should return localized string by lang_id -druid.set_text_function(function(lang_id) - ... -end) +-- Used for button component and custom components +druid.set_sound_function(callback) --- Function should play sound by name -druid.set_sound_function(function(name) - ... -end) +-- Used for lang_text component +druid.set_text_function(callback) + +-- Used for change default druid style +druid.set_default_style(your_style) ``` -## Usage - ## Components Druid provides next basic components: -_insert simple gif of each?_ -_separate .md for each base component?_ -- **Button** - basic game button -- **Text** - wrap on gui text node -- **Blocker** - block input in node zone -- **Back** Handler - handle back button (Android, backspace) -- **Locale** - localized text node -- **Timer** - run timer on defined time -- **Progress** - simple progress bar -- **Scroll** - general scroll component -- **Grid** - manage node positions -- **Slider** - simple slider (ex. volume adjust) -- **Checkbox** - simple checkbox -- **Checkbox group** - many checkbox -- **Radio group** - many checkbox with single choice +- **Button** - Basic game button -## Styles -You can setup default style for all druid module, for druid instance or any base druid component. -Setup default druid style via `druid.set_default_style` -```lua -local druid = require("druid.druid") -local my_style = require("my.amazing.style") +- **Text** - Wrap on text node with text size adjusting -local function init(self) - druid.set_default_style(my_style) -end -``` -_TODO_ +- **Blocker** - Block input in node zone + +- **Back Handler** - Handle back button (Android, backspace) + +- **Lang text** - Text component with handle localization system + +- **Timer** - Run timer on text node + +- **Progress** - Basic progress bar + +- **Scroll** - Basic scroll component + +- **Grid** - Component for manage node positions + +- **Slider** - Basic slider component + +- **Checkbox** - Basic checkbox component + +- **Checkbox group** - Several checkboxes in one group + +- **Radio group** - Several checkboxes in one group with single choice + +Full info see on _components.md_ ## Creating components Any components creating via druid: @@ -81,128 +76,45 @@ function on_message(self, message_id, message, sender) end function on_input(self, action_id, action) - return self.druid:on_input(action_id, action) + self.druid:on_input(action_id, action) end ``` -## Custom components +## Examples +See the [example folder](https://github.com/Insality/druid/tree/develop/example/kenney) for examples of how to use Druid +See the [druid-assets repository](https://github.com/Insality/druid-assets) for examples of how to create custom components and styles +Try the HTML5 version of the example app -Add your custom components via `druid.register` -```lua -local druid = require("druid.druid") -local my_component = require("my.amazing.component") +## Documentation +To learn druid better, read next documentation: +- Druid components +- Create custom components +- Druid asset store +- Druid Styles -local function init(self) - druid.register("my_component", my_component) -end -``` - -Basic custom component template looks like this: -```lua -local const = require("druid.const") -local component = require("druid.component") - -local M = component.create("amazing_component", { const.ON_INPUT }) - -function M.init(self, ...) - -- Component constructor -end - --- Call only if exist interest: const.ON_UPDATE -function M.update(self, dt) - -end - --- Call only if exist interest: const.ON_INPUT or const.ON_INPUT_HIGH -function M.on_input(self, action_id, action) - -end - --- Call only if exist interest: const.ON_MESSAGE -function M.on_message(self, message_id, message, sender) - -end - --- Call if input was interrupt by previous components (ex. scroll) -function M.on_input_interrupt(self) - -end - -return M -``` - -## Best practice on custom components -On each component recomended describe component schema in next way: - -```lua --- Component module -local helper = require("druid.helper") -local component = require("druid.component") - -local M = component.create("new_component") - -local SCHEME = { - ROOT = "/root", - ITEM = "/item", - TITLE = "/title" -} - -function M.init(self, template_name, node_table) - -- If component use template, setup it: - self:set_template(template_name) - - -- If component was cloned with gui.clone_tree, pass his nodes - self:set_nodes(node_table) - - -- Component can get node from gui/template/table - local root = self:get_node(self, SCHEME.ROOT) - - -- This component can spawn another druid components: - local druid = self:get_druid(self) - -- Button self on callback is self of _this_ component - local button = druid:new_button(...) - - -- helper can return you the component style - local my_style = self:get_style() -end - -``` - -## Example -You can check our example here -_TODO_ - -## Reserver componeney keywords -- initialize -- init -- update -- on_input -- on_message -- on_input_interrupt -- setup_component -- get_style -- set_style -- set_template -- set_nodes -- get_context -- set_context -- get_druid - -## API -_Link to ldoc_ -[API](https://AGulev.github.io/druid/) - -## Internal -Generate with `ldoc .` with `config.ld` file. [Instructions](https://github.com/stevedonovan/LDoc) +Full druid documentation you can find here: +https://insality.github.io/druid/ ## Games powered by Druid: -_TODO_ +_Will fill later_ +## Future plans + +- Basic input component + +- Add on_layout_change support (to keep gui data between layout change) + +- Add on_change_language support (call single function to update all druid instance) + +- Better documentation and examples + +- Add more comfortable gamepad support for GUI (ability to select button with DPAD and other stuff) ## License -Using [middleclass by kikito](https://github.com/kikito/middleclass) +Original idea by [AGulev](https://github.com/AGulev) +Developed and supporting by [Insality](https://github.com/Insality) MIT License ## Issues and suggestions -If you have any issues, questions or suggestions please [create an issue](https://github.com/AGulev/druid/issues) or contact me: [insality@gmail.com](mailto:insality@gmail.com) +If you have any issues, questions or suggestions please [create an issue](https://github.com/Insality/druid/issues) or contact me: [insality@gmail.com](mailto:insality@gmail.com) diff --git a/config.ld b/config.ld index 6da4f05..273a754 100644 --- a/config.ld +++ b/config.ld @@ -12,5 +12,6 @@ sort=false dir='./docs' style='!fixed' format='discount' +topics={"./docs_md", "README.md"} use_markdown_titles=true no_space_before_args=true \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index c7d2383..d3f743d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -52,6 +52,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -144,12 +153,39 @@
    Event(initial_callback)Event constructur
    event:subscribe(callback) Subscribe callback on eventUnsubscribe callback on event
    event:is_exist()Return true, if event have at lease one handler
    event:clear()Clear the all event handlers
    event:trigger(...) Trigger the event and call all subscribed callbacks
    Druid main class.
    +

    Topics

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    components.md
    creating_custom_components.md
    druid_assets.md
    examples.md
    styles.md
    README.md
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/component.html b/docs/modules/component.html index a145600..e6dac59 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -59,6 +59,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -397,7 +406,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 19bd134..005e084 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -206,7 +215,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 1c9d698..3bc14f0 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -225,7 +234,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index a7097f9..1efe781 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -396,7 +405,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index cb9ad9f..2aa1d8d 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -268,7 +277,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index 920762e..dbce218 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -230,7 +239,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 3df4a00..3936ae6 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -361,7 +370,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.helper.html b/docs/modules/druid.helper.html index 5091943..a5266ee 100644 --- a/docs/modules/druid.helper.html +++ b/docs/modules/druid.helper.html @@ -59,6 +59,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -227,7 +236,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.hover.html b/docs/modules/druid.hover.html index da05a4d..24d095f 100644 --- a/docs/modules/druid.hover.html +++ b/docs/modules/druid.hover.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -202,7 +211,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 7e40457..9f684f4 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -59,6 +59,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -172,7 +181,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.input.html b/docs/modules/druid.input.html index b453a81..b68341f 100644 --- a/docs/modules/druid.input.html +++ b/docs/modules/druid.input.html @@ -55,6 +55,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -77,7 +86,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.lang_text.html b/docs/modules/druid.lang_text.html index 9c5f2f6..e30116f 100644 --- a/docs/modules/druid.lang_text.html +++ b/docs/modules/druid.lang_text.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -231,7 +240,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index 14ca013..418969f 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -369,7 +378,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index e14bc76..bf332db 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -230,7 +239,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index 38a41bb..58ba8dc 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -498,7 +507,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index 2f2e11e..4226c9b 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -239,7 +248,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index 7796639..0743aa4 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -343,7 +352,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index a45db3f..77e1e15 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -60,6 +60,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -298,7 +307,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid_event.html b/docs/modules/druid_event.html index b665666..3438627 100644 --- a/docs/modules/druid_event.html +++ b/docs/modules/druid_event.html @@ -59,6 +59,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -230,7 +239,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index d4f8c21..5d26240 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -59,6 +59,15 @@
  • druid.helper
  • druid_instance
  • +

    Topics

    + @@ -741,7 +750,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 21:42:52 +Last updated 2020-03-21 22:53:41
    diff --git a/docs/topics/README.md.html b/docs/topics/README.md.html new file mode 100644 index 0000000..39777e6 --- /dev/null +++ b/docs/topics/README.md.html @@ -0,0 +1,217 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    + +

    Druid - powerful defold component UI library. Use basic druid components or make your own game-specific components to make amazing GUI in your games.

    + +

    +

    Setup

    +

    Dependency

    +

    You can use the druid extension in your own project by adding this project as a Defold library dependency. Open your game.project file and in the dependencies field under project add:

    + +
    +

    https://github.com/Insality/druid/archive/master.zip

    +
    + +

    Or point to the ZIP file of a specific release.

    + + +

    Code

    +

    Adjust druid settings, if needed:

    + +
    +local druid = require("druid.druid")
    +
    +-- Used for button component and custom components
    +druid.set_sound_function(callback)
    +
    +-- Used for lang_text component
    +druid.set_text_function(callback)
    +
    +-- Used for change default druid style
    +druid.set_default_style(your_style)
    +
    + + +

    +

    Components

    +

    Druid provides next basic components: +- Button - Basic game button

    + +
      +
    • Text - Wrap on text node with text size adjusting

    • +
    • Blocker - Block input in node zone

    • +
    • Back Handler - Handle back button (Android, backspace)

    • +
    • Lang text - Text component with handle localization system

    • +
    • Timer - Run timer on text node

    • +
    • Progress - Basic progress bar

    • +
    • Scroll - Basic scroll component

    • +
    • Grid - Component for manage node positions

    • +
    • Slider - Basic slider component

    • +
    • Checkbox - Basic checkbox component

    • +
    • Checkbox group - Several checkboxes in one group

    • +
    • Radio group - Several checkboxes in one group with single choice

    • +
    + +

    Full info see on components.md

    + +

    +

    Creating components

    +

    Any components creating via druid:

    + +
    +local druid = require("druid.druid")
    +
    +local function init(self)
    +    self.druid = druid.new(self)
    +    local button = self.druid:new_button(node_name, callback)
    +    local text = self.druid:new_text(node_text_name)
    +end
    +
    +function update(self, dt)
    +    self.druid:update(dt)
    +end
    +
    +function on_message(self, message_id, message, sender)
    +    self.druid:on_message(message_id, message, sender)
    +end
    +
    +function on_input(self, action_id, action)
    +    self.druid:on_input(action_id, action)
    +end
    +
    + + +

    +

    Examples

    +

    See the example folder for examples of how to use Druid +See the druid-assets repository for examples of how to create custom components and styles +Try the HTML5 version of the example app

    + +

    +

    Documentation

    +

    To learn druid better, read next documentation: +- Druid components +- Create custom components +- Druid asset store +- Druid Styles

    + +

    Full druid documentation you can find here: +https://insality.github.io/druid/

    + +

    +

    Games powered by Druid:

    +

    Will fill later

    + +

    +

    Future plans

    + +
      +
    • Basic input component

    • +
    • Add onlayoutchange support (to keep gui data between layout change)

    • +
    • Add onchangelanguage support (call single function to update all druid instance)

    • +
    • Better documentation and examples

    • +
    • Add more comfortable gamepad support for GUI (ability to select button with DPAD and other stuff)

    • +
    + +

    +

    License

    +

    Original idea by AGulev +Developed and supporting by Insality +MIT License

    + + +

    +

    Issues and suggestions

    +

    If you have any issues, questions or suggestions please create an issue or contact me: insality@gmail.com + +

    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:53:41 +
    +
    + + diff --git a/docs/topics/components.md.html b/docs/topics/components.md.html new file mode 100644 index 0000000..7ba3381 --- /dev/null +++ b/docs/topics/components.md.html @@ -0,0 +1,152 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Druid components

    + +

    +

    Button

    +

    Basic game button

    + +

    +

    Text

    +

    Wrap on text node with text size adjusting

    + +

    +

    Blocker

    +

    Block input in node zone

    + +

    +

    Back Handler

    +

    Handle back button (Android, backspace)

    + +

    +

    Locale

    +

    Text component with handle localization system

    + +

    +

    Timer

    +

    Run timer on text node

    + +

    +

    Progress

    +

    Basic progress bar

    + +

    +

    Scroll

    +

    Basic scroll component

    + +

    +

    Grid

    +

    Component for manage node positions

    + +

    +

    Slider

    +

    Basic slider component

    + +

    +

    Checkbox

    +

    Basic checkbox component

    + +

    +

    Checkbox group

    +

    Several checkboxes in one group

    + +

    +

    Radio group

    +

    Several checkboxes in one group with single choice

    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:53:41 +
    +
    + + diff --git a/docs/topics/create_custom_components.md.html b/docs/topics/create_custom_components.md.html new file mode 100644 index 0000000..758f9c9 --- /dev/null +++ b/docs/topics/create_custom_components.md.html @@ -0,0 +1,172 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Custom components

    + +

    Add your custom components via druid.register

    + +
    +local druid = require("druid.druid")
    +local my_component = require("my.amazing.component")
    +
    +local function init(self)
    +    druid.register("my_component", my_component)
    +end
    +
    + + +

    Basic custom component template looks like this:

    + +
    +local const = require("druid.const")
    +
    +local M = {}
    +M.interest = { const.ON_INPUT }
    +
    +function M.init(self, ...)
    +    -- Component constructor
    +end
    +
    +-- Call only if exist interest: const.ON_UPDATE
    +function M.update(self, dt)
    +
    +end
    +
    +-- Call only if exist interest: const.ON_INPUT or const.ON_SWIPE
    +function M.on_input(self, action_id, action)
    +
    +end
    +
    +-- Call only if exist interest: const.ON_MESSAGE
    +function M.on_message(self, message_id, message, sender)
    +
    +end
    +
    +-- Call only if swipe was started on another component (ex. scroll)
    +function M.on_swipe(self)
    +
    +end
    +
    +return M
    +
    + + + +

    Best practice on custom components

    +

    On each component recomended describe component schema in next way:

    + + +
    +-- Component module
    +local helper = require("druid.helper")
    +
    +local M = {}
    +
    +local SCHEME = {
    +    ROOT = "/root",
    +    ITEM = "/item",
    +    TITLE = "/title"
    +}
    +
    +-- TODO: Rework self.template/self.nodes
    +-- Make self._inner_data? { component_name, template, nodes }
    +function M.init(self, template_name, node_table)
    +    -- If component use template, setup it:
    + self.template = template_name
    +
    +    -- If component was cloned with gui.clone_tree, pass his nodes
    + self.nodes = node_table
    +
    +    -- helper can get node from gui/template/table
    + local root = helper.node(self, SCHEME.ROOT)
    +
    +    -- This component can spawn another druid components:
    + local druid = helper.get_druid(self)
    +    -- Button self on callback is self of _this_ component
    + local button = druid:new_button(...)
    +
    +    -- helper can return you the component style
    + local my_style = helper.get_style(self, "component_name")
    +end
    +
    + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:00:04 +
    +
    + + diff --git a/docs/topics/creating_custom_components.md.html b/docs/topics/creating_custom_components.md.html new file mode 100644 index 0000000..95f9872 --- /dev/null +++ b/docs/topics/creating_custom_components.md.html @@ -0,0 +1,200 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Creating custom components

    + +

    +

    Overview

    +

    Druid allows you to create your custom components from druid basic components or other custom components

    + + +

    +

    Custom components

    +

    Basic custom component template looks like this:

    + +
    +local const = require("druid.const")
    +local component = require("druid.component")
    +
    +local M = component.create("your_component")
    +
    +-- Component constructor
    +function M.init(self, ...)
    +end
    +
    +-- Call only if exist interest: const.ON_UPDATE
    +function M.update(self, dt)
    +end
    +
    +-- Call only if exist interest: const.ON_INPUT or const.ON_INPUT_HIGH
    +function M.on_input(self, action_id, action)
    +end
    +
    +-- Call only if exist interest: const.ON_MESSAGE
    +function M.on_message(self, message_id, message, sender)
    +end
    +
    +-- Call only if component with ON_CHANGE_LANGUAGE interest
    +function M.on_change_language(self)
    +end
    +
    +-- Call only if component with ON_LAYOUT_CHANGE interest
    +function M.on_layout_change(self)
    +end
    +
    +return M
    +
    + + + +

    Add your custom component to druid via druid.register

    + +
    +local druid = require("druid.druid")
    +local my_component = require("my.amazing.component")
    +
    +local function init(self)
    +    druid.register("my_component", my_component)
    +end
    +
    + + +

    Interest

    +

    Interest - is a way to indicate what events your component will respond to. +There is next interests in druid: +- ON_MESSAGE - component will receive messages from on_message

    + +
      +
    • ON_UPDATE - component will be updated from update

    • +
    • ONINPUTHIGH - component will receive input from oninput, before other components with ONINPUT

    • +
    • ON_INPUT - component will receive input from oninput, after other components with ONINPUT_HIGH

    • +
    • ONCHANGELANGUAGE - will call onchangelanguage function on language change trigger

    • +
    • ONLAYOUTCHANGED will call onlayoutchange function on layout change trigger

    • +
    + + +

    +

    Best practice on custom components

    +

    On each component recomended describe component scheme in next way:

    + + +
    +-- Component module
    +local component = require("druid.component")
    +
    +local M = component.create("your_component")
    +
    +local SCHEME = {
    +    ROOT = "/root",
    +    ITEM = "/item",
    +    TITLE = "/title"
    +}
    +
    +function M.init(self, template_name, node_table)
    +    -- If component use template, setup it:
    + self:set_template(template_name)
    +
    +    -- If component was cloned with gui.clone_tree, pass his nodes
    + self:set_nodes(node_table)
    +
    +    -- helper can get node from gui/template/table
    + local root = self:get_node(SCHEME.ROOT)
    +
    +    -- This component can spawn another druid components:
    + local druid = self:get_druid()
    +
    +    -- Button self on callback is self of _this_ component
    + local button = druid:new_button(...)
    +
    +    -- helper can return you the component style for current component
    + -- It return by component name from
    + local my_style = self:get_style()
    +end
    +
    + + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:53:41 +
    +
    + + diff --git a/docs/topics/druid_assets.md.html b/docs/topics/druid_assets.md.html new file mode 100644 index 0000000..3debc03 --- /dev/null +++ b/docs/topics/druid_assets.md.html @@ -0,0 +1,96 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Druid assets

    + +

    +

    Overview

    +

    I've created druid-assets repository to make a marketplace with custom styles and components.

    + +

    Any of druid users can push their own components and styles to share it with the other users

    + +

    Also, this marketplace is great example to how you can create your custom components

    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:53:41 +
    +
    + + diff --git a/docs/topics/examples.md.html b/docs/topics/examples.md.html new file mode 100644 index 0000000..af12fe9 --- /dev/null +++ b/docs/topics/examples.md.html @@ -0,0 +1,94 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Examples

    + +

    +

    Overview

    +

    See the example folder for examples of how to use Druid

    + +

    Try the HTML5 version of the example app

    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:53:41 +
    +
    + + diff --git a/docs/topics/online_example.md.html b/docs/topics/online_example.md.html new file mode 100644 index 0000000..b057b31 --- /dev/null +++ b/docs/topics/online_example.md.html @@ -0,0 +1,86 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Online example

    + +

    Check druid --here-- (link)

    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:00:04 +
    +
    + + diff --git a/docs/topics/styles.md.html b/docs/topics/styles.md.html new file mode 100644 index 0000000..d5e4639 --- /dev/null +++ b/docs/topics/styles.md.html @@ -0,0 +1,145 @@ + + + + + Defold Druid UI Library + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Styles

    + +

    +

    Overview

    +

    Styles - set of functions and parameters for components to customize their behavior.

    + +

    Styles is a table, where key is name of component, and value is style table for this component.

    + +

    In component API documentation, you can find the style API for this component. Or just lookup for existing styles and modify them.

    + +

    +

    Usage

    +

    Setup default druid style for all druid instances via druid.set_default_style

    + +
    +local druid = require("druid.druid")
    +local my_style = require("my.amazing.style")
    +
    +local function init(self)
    +    druid.set_default_style(my_style)
    +end
    +
    + + +

    Setup custom style to specific druid instance:

    + +
    +local druid = require("druid.druid")
    +local my_style = require("my.amazing.style")
    +
    +local function init(self)
    +    -- This druid instance will be use my_style as default
    + self.druid = druid.new(self, my_style)
    +end
    +
    + + +

    Change component style with setstyle_ function

    + +
    +local druid = require("druid.druid")
    +local my_style = require("my.amazing.style")
    +
    +local function init(self)
    +    self.druid = druid.new(self)
    +    self.button = self.druid:new_button(self, "node")
    +    -- Setup custom style for specific component
    + self.button:set_style(my_style)
    +end
    +
    + + +

    +

    Create custom components

    +

    Styles is just lua table, so it can be described in just one single file +TODO

    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated 2020-03-21 22:53:41 +
    +
    + + diff --git a/docs_md/components.md b/docs_md/components.md new file mode 100644 index 0000000..dec3186 --- /dev/null +++ b/docs_md/components.md @@ -0,0 +1,40 @@ +# Druid components + +## Button +Basic game button + +## Text +Wrap on text node with text size adjusting + +## Blocker +Block input in node zone + +## Back Handler +Handle back button (Android, backspace) + +## Locale +Text component with handle localization system + +## Timer +Run timer on text node + +## Progress +Basic progress bar + +## Scroll +Basic scroll component + +## Grid +Component for manage node positions + +## Slider +Basic slider component + +## Checkbox +Basic checkbox component + +## Checkbox group +Several checkboxes in one group + +## Radio group +Several checkboxes in one group with single choice diff --git a/docs_md/creating_custom_components.md b/docs_md/creating_custom_components.md new file mode 100644 index 0000000..197a2f3 --- /dev/null +++ b/docs_md/creating_custom_components.md @@ -0,0 +1,105 @@ +# Creating custom components + +## Overview +Druid allows you to create your custom components from druid basic components or other custom components + + +## Custom components +Basic custom component template looks like this: +```lua +local const = require("druid.const") +local component = require("druid.component") + +local M = component.create("your_component") + +-- Component constructor +function M.init(self, ...) +end + +-- Call only if exist interest: const.ON_UPDATE +function M.update(self, dt) +end + +-- Call only if exist interest: const.ON_INPUT or const.ON_INPUT_HIGH +function M.on_input(self, action_id, action) +end + +-- Call only if exist interest: const.ON_MESSAGE +function M.on_message(self, message_id, message, sender) +end + +-- Call only if component with ON_CHANGE_LANGUAGE interest +function M.on_change_language(self) +end + +-- Call only if component with ON_LAYOUT_CHANGE interest +function M.on_layout_change(self) +end + +return M +``` + + +Add your custom component to druid via `druid.register` +```lua +local druid = require("druid.druid") +local my_component = require("my.amazing.component") + +local function init(self) + druid.register("my_component", my_component) +end +``` + +### Interest +Interest - is a way to indicate what events your component will respond to. +There is next interests in druid: +- **ON_MESSAGE** - component will receive messages from on_message + +- **ON_UPDATE** - component will be updated from update + +- **ON_INPUT_HIGH** - component will receive input from on_input, before other components with ON_INPUT + +- **ON_INPUT** - component will receive input from on_input, after other components with ON_INPUT_HIGH + +- **ON_CHANGE_LANGUAGE** - will call _on_change_language_ function on language change trigger + +- **ON_LAYOUT_CHANGED** will call _on_layout_change_ function on layout change trigger + + +## Best practice on custom components +On each component recomended describe component scheme in next way: + +```lua +-- Component module +local component = require("druid.component") + +local M = component.create("your_component") + +local SCHEME = { + ROOT = "/root", + ITEM = "/item", + TITLE = "/title" +} + +function M.init(self, template_name, node_table) + -- If component use template, setup it: + self:set_template(template_name) + + -- If component was cloned with gui.clone_tree, pass his nodes + self:set_nodes(node_table) + + -- helper can get node from gui/template/table + local root = self:get_node(SCHEME.ROOT) + + -- This component can spawn another druid components: + local druid = self:get_druid() + + -- Button self on callback is self of _this_ component + local button = druid:new_button(...) + + -- helper can return you the component style for current component + -- It return by component name from + local my_style = self:get_style() +end + +``` \ No newline at end of file diff --git a/docs_md/druid_assets.md b/docs_md/druid_assets.md new file mode 100644 index 0000000..8a2c992 --- /dev/null +++ b/docs_md/druid_assets.md @@ -0,0 +1,8 @@ +# Druid assets + +## Overview +I've created [druid-assets repository](https://github.com/Insality/druid-assets) to make a _marketplace_ with custom styles and components. + +Any of druid users can push their own components and styles to share it with the other users + +Also, this marketplace is great example to how you can create your custom components \ No newline at end of file diff --git a/docs_md/examples.md b/docs_md/examples.md new file mode 100644 index 0000000..84a9c86 --- /dev/null +++ b/docs_md/examples.md @@ -0,0 +1,6 @@ +# Examples + +## Overview +See the [example folder](https://github.com/Insality/druid/tree/develop/example/kenney) for examples of how to use Druid + +Try the HTML5 version of the example app \ No newline at end of file diff --git a/docs_md/styles.md b/docs_md/styles.md new file mode 100644 index 0000000..a018c43 --- /dev/null +++ b/docs_md/styles.md @@ -0,0 +1,47 @@ +# Styles + +## Overview +Styles - set of functions and parameters for components to customize their behavior. + +Styles is a table, where key is name of component, and value is style table for this component. + +In component API documentation, you can find the style API for this component. Or just lookup for existing styles and modify them. + +## Usage +Setup default druid style for all druid instances via `druid.set_default_style` +```lua +local druid = require("druid.druid") +local my_style = require("my.amazing.style") + +local function init(self) + druid.set_default_style(my_style) +end +``` + +Setup custom style to specific druid instance: +```lua +local druid = require("druid.druid") +local my_style = require("my.amazing.style") + +local function init(self) + -- This druid instance will be use my_style as default + self.druid = druid.new(self, my_style) +end +``` + +Change component style with _set_style_ function +```lua +local druid = require("druid.druid") +local my_style = require("my.amazing.style") + +local function init(self) + self.druid = druid.new(self) + self.button = self.druid:new_button(self, "node") + -- Setup custom style for specific component + self.button:set_style(my_style) +end +``` + +## Create custom components +Styles is just lua table, so it can be described in just one single file +__TODO__ From 1763cda9cd6f07f5b80b9bace82c6b090bdf021c Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 22:55:23 +0300 Subject: [PATCH 133/136] Correct logo link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 21a78bd..57b9c8b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![](druid_logo.png) +[![](media/druid_logo.png)](https://insality.github.io/druid/) **Druid** - powerful defold component UI library. Use basic druid components or make your own game-specific components to make amazing GUI in your games. From a2106e4499d5d3ca976452355a4ddb239c417e36 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 22:57:24 +0300 Subject: [PATCH 134/136] Fix README --- README.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 57b9c8b..6ca3a64 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,11 @@ **Druid** - powerful defold component UI library. Use basic druid components or make your own game-specific components to make amazing GUI in your games. + ## Setup -#### Dependency + +### Dependency + You can use the druid extension in your own project by adding this project as a [Defold library dependency](https://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add: > [https://github.com/Insality/druid/archive/master.zip](https://github.com/Insality/druid/archive/master.zip) @@ -11,7 +14,8 @@ You can use the druid extension in your own project by adding this project as a Or point to the ZIP file of a [specific release](https://github.com/Insality/druid/releases). -#### Code +### Code + Adjust druid settings, if needed: ```lua local druid = require("druid.druid") @@ -26,7 +30,9 @@ druid.set_text_function(callback) druid.set_default_style(your_style) ``` + ## Components + Druid provides next basic components: - **Button** - Basic game button @@ -56,7 +62,9 @@ Druid provides next basic components: Full info see on _components.md_ + ## Creating components + Any components creating via druid: ```lua local druid = require("druid.druid") @@ -80,12 +88,18 @@ function on_input(self, action_id, action) end ``` + ## Examples -See the [example folder](https://github.com/Insality/druid/tree/develop/example/kenney) for examples of how to use Druid -See the [druid-assets repository](https://github.com/Insality/druid-assets) for examples of how to create custom components and styles + +See the [example folder](https://github.com/insality/druid/tree/develop/example/kenney) for examples of how to use Druid + +See the [druid-assets repository](https://github.com/insality/druid-assets) for examples of how to create custom components and styles + Try the HTML5 version of the example app + ## Documentation + To learn druid better, read next documentation: - Druid components - Create custom components @@ -95,9 +109,12 @@ To learn druid better, read next documentation: Full druid documentation you can find here: https://insality.github.io/druid/ -## Games powered by Druid: + +## Games powered by Druid + _Will fill later_ + ## Future plans - Basic input component @@ -110,11 +127,16 @@ _Will fill later_ - Add more comfortable gamepad support for GUI (ability to select button with DPAD and other stuff) + ## License + Original idea by [AGulev](https://github.com/AGulev) + Developed and supporting by [Insality](https://github.com/Insality) + MIT License ## Issues and suggestions + If you have any issues, questions or suggestions please [create an issue](https://github.com/Insality/druid/issues) or contact me: [insality@gmail.com](mailto:insality@gmail.com) From 762620f71000c4ff3eb42fd5ec53baf0169c3152 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 23:00:25 +0300 Subject: [PATCH 135/136] Update README and other docs --- README.md | 4 ++ docs/index.html | 2 +- docs/modules/component.html | 2 +- docs/modules/druid.back_handler.html | 2 +- docs/modules/druid.blocker.html | 2 +- docs/modules/druid.button.html | 2 +- docs/modules/druid.checkbox.html | 2 +- docs/modules/druid.checkbox_group.html | 2 +- docs/modules/druid.grid.html | 2 +- docs/modules/druid.helper.html | 2 +- docs/modules/druid.hover.html | 2 +- docs/modules/druid.html | 2 +- docs/modules/druid.input.html | 2 +- docs/modules/druid.lang_text.html | 2 +- docs/modules/druid.progress.html | 2 +- docs/modules/druid.radio_group.html | 2 +- docs/modules/druid.scroll.html | 2 +- docs/modules/druid.slider.html | 2 +- docs/modules/druid.text.html | 2 +- docs/modules/druid.timer.html | 2 +- docs/modules/druid_event.html | 2 +- docs/modules/druid_instance.html | 2 +- docs/topics/README.md.html | 50 ++++++++++++++----- docs/topics/components.md.html | 12 ++++- .../topics/creating_custom_components.md.html | 2 +- docs/topics/druid_assets.md.html | 2 +- docs/topics/examples.md.html | 2 +- docs/topics/styles.md.html | 2 +- docs_md/components.md | 6 +++ 29 files changed, 83 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 6ca3a64..72aa393 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,10 @@ Druid provides next basic components: - **Radio group** - Several checkboxes in one group with single choice +- **Hover** - Trigger component for check node hover state + +- **Input** - Component to process user text input + Full info see on _components.md_ diff --git a/docs/index.html b/docs/index.html index d3f743d..c3f84fb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -185,7 +185,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/component.html b/docs/modules/component.html index e6dac59..ef4bc84 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -406,7 +406,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 005e084..f430074 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -215,7 +215,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 3bc14f0..51202b1 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -234,7 +234,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 1efe781..9bc583a 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -405,7 +405,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index 2aa1d8d..950cbaa 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -277,7 +277,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index dbce218..25b2c0e 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -239,7 +239,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index 3936ae6..34b19ac 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -370,7 +370,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.helper.html b/docs/modules/druid.helper.html index a5266ee..7e0d187 100644 --- a/docs/modules/druid.helper.html +++ b/docs/modules/druid.helper.html @@ -236,7 +236,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.hover.html b/docs/modules/druid.hover.html index 24d095f..3aacad3 100644 --- a/docs/modules/druid.hover.html +++ b/docs/modules/druid.hover.html @@ -211,7 +211,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index 9f684f4..39e0d48 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -181,7 +181,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.input.html b/docs/modules/druid.input.html index b68341f..3db5add 100644 --- a/docs/modules/druid.input.html +++ b/docs/modules/druid.input.html @@ -86,7 +86,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.lang_text.html b/docs/modules/druid.lang_text.html index e30116f..7930f45 100644 --- a/docs/modules/druid.lang_text.html +++ b/docs/modules/druid.lang_text.html @@ -240,7 +240,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index 418969f..b0750f0 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -378,7 +378,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index bf332db..d12b79e 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -239,7 +239,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index 58ba8dc..bcdbe27 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -507,7 +507,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index 4226c9b..309e95b 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -248,7 +248,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index 0743aa4..25ae2f4 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -352,7 +352,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index 77e1e15..a65a18c 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -307,7 +307,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid_event.html b/docs/modules/druid_event.html index 3438627..88500c8 100644 --- a/docs/modules/druid_event.html +++ b/docs/modules/druid_event.html @@ -239,7 +239,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index 5d26240..6269911 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -750,7 +750,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/topics/README.md.html b/docs/topics/README.md.html index 39777e6..8f1bc1d 100644 --- a/docs/topics/README.md.html +++ b/docs/topics/README.md.html @@ -37,7 +37,7 @@
  • Creating components
  • Examples
  • Documentation
  • -
  • Games powered by Druid:
  • +
  • Games powered by Druid
  • Future plans
  • License
  • Issues and suggestions
  • @@ -81,13 +81,16 @@
    -

    +

    Druid - powerful defold component UI library. Use basic druid components or make your own game-specific components to make amazing GUI in your games.

    +

    Setup

    -

    Dependency

    + +

    Dependency

    +

    You can use the druid extension in your own project by adding this project as a Defold library dependency. Open your game.project file and in the dependencies field under project add:

    @@ -97,7 +100,8 @@

    Or point to the ZIP file of a specific release.

    -

    Code

    +

    Code

    +

    Adjust druid settings, if needed:

    @@ -114,8 +118,10 @@
     
    +

    Components

    +

    Druid provides next basic components: - Button - Basic game button

    @@ -132,12 +138,16 @@
  • Checkbox - Basic checkbox component

  • Checkbox group - Several checkboxes in one group

  • Radio group - Several checkboxes in one group with single choice

  • +
  • Hover - Trigger component for check node hover state

  • +
  • Input - Component to process user text input

  • Full info see on components.md

    +

    Creating components

    +

    Any components creating via druid:

    @@ -163,14 +173,20 @@
     
    +

    Examples

    -

    See the example folder for examples of how to use Druid -See the druid-assets repository for examples of how to create custom components and styles -Try the HTML5 version of the example app

    + +

    See the example folder for examples of how to use Druid

    + +

    See the druid-assets repository for examples of how to create custom components and styles

    + +

    Try the HTML5 version of the example app

    +

    Documentation

    +

    To learn druid better, read next documentation: - Druid components - Create custom components @@ -180,10 +196,13 @@ Try the HTML5 version of the example app

    Full druid documentation you can find here: https://insality.github.io/druid/

    -

    -

    Games powered by Druid:

    + +

    +

    Games powered by Druid

    +

    Will fill later

    +

    Future plans

    @@ -195,22 +214,27 @@ https://insality.github.io/druid/

  • Add more comfortable gamepad support for GUI (ability to select button with DPAD and other stuff)

  • +

    License

    -

    Original idea by AGulev -Developed and supporting by Insality -MIT License

    + +

    Original idea by AGulev

    + +

    Developed and supporting by Insality

    + +

    MIT License

    Issues and suggestions

    +

    If you have any issues, questions or suggestions please create an issue or contact me: insality@gmail.com

    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/topics/components.md.html b/docs/topics/components.md.html index 7ba3381..a8c9c0a 100644 --- a/docs/topics/components.md.html +++ b/docs/topics/components.md.html @@ -45,6 +45,8 @@
  • Checkbox
  • Checkbox group
  • Radio group
  • +
  • Hover
  • +
  • Input
  • @@ -140,12 +142,20 @@

    Radio group

    Several checkboxes in one group with single choice

    +

    +

    Hover

    +

    Trigger component for check node hover state

    + +

    +

    Input

    +

    Component to process user text input

    +
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/topics/creating_custom_components.md.html b/docs/topics/creating_custom_components.md.html index 95f9872..67d997b 100644 --- a/docs/topics/creating_custom_components.md.html +++ b/docs/topics/creating_custom_components.md.html @@ -193,7 +193,7 @@ There is next interests in druid:
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/topics/druid_assets.md.html b/docs/topics/druid_assets.md.html index 3debc03..b45f35a 100644 --- a/docs/topics/druid_assets.md.html +++ b/docs/topics/druid_assets.md.html @@ -89,7 +89,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/topics/examples.md.html b/docs/topics/examples.md.html index af12fe9..dafc08b 100644 --- a/docs/topics/examples.md.html +++ b/docs/topics/examples.md.html @@ -87,7 +87,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs/topics/styles.md.html b/docs/topics/styles.md.html index d5e4639..9c680d6 100644 --- a/docs/topics/styles.md.html +++ b/docs/topics/styles.md.html @@ -138,7 +138,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-03-21 22:53:41 +Last updated 2020-03-21 22:59:46
    diff --git a/docs_md/components.md b/docs_md/components.md index dec3186..ecfb132 100644 --- a/docs_md/components.md +++ b/docs_md/components.md @@ -38,3 +38,9 @@ Several checkboxes in one group ## Radio group Several checkboxes in one group with single choice + +## Hover +Trigger component for check node hover state + +## Input +Component to process user text input \ No newline at end of file From 11b2120baa7e27a93b2f4d2817d27dc78cb94b0d Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 21 Mar 2020 23:18:59 +0300 Subject: [PATCH 136/136] Remove old examples --- example/{kenney => }/assets/fonts/exo2.ttf | Bin example/{kenney => }/assets/fonts/game.font | 2 +- .../assets/images/back/back_blue.png | Bin .../assets/images/back/back_gray.png | Bin .../assets/images/back/back_green.png | Bin .../assets/images/back/back_red.png | Bin .../assets/images/buttons/button_blue.png | Bin .../assets/images/buttons/button_green.png | Bin .../assets/images/buttons/button_red.png | Bin .../assets/images/buttons/button_yellow.png | Bin example/{kenney => }/assets/images/empty.png | Bin example/assets/images/kenney.atlas | 79 + .../assets/images/progress/progress_back.png | Bin .../images/progress/progress_fill_green.png | Bin .../images/progress/progress_fill_red.png | Bin .../images/progress/progress_fill_yellow.png | Bin .../assets/images/radio/check_back_circle.png | Bin .../assets/images/radio/check_back_square.png | Bin .../assets/images/radio/checkmark.png | Bin .../{kenney => }/assets/images/radio/tick.png | Bin .../assets/images/slider/slider_back.png | Bin .../assets/images/slider/slider_move.png | Bin example/{kenney => }/assets/sounds/click.ogg | Bin example/example.collection | 79 - example/example.gui | 1660 ----------------- example/example.gui.gui_script | 155 -- example/game.font | 17 - example/gui.atlas | 24 - example/{kenney => }/gui/main/main.gui | 36 +- example/{kenney => }/gui/main/main.gui_script | 8 +- example/{kenney => }/init.script | 2 +- example/{kenney => }/kenney.collection | 6 +- example/kenney/assets/images/kenney.atlas | 60 - example/{kenney => }/lang.lua | 0 example/{kenney => }/page/button.lua | 0 example/{kenney => }/page/main.lua | 2 +- example/{kenney => }/page/scroll.lua | 3 +- example/{kenney => }/page/texts.lua | 2 - example/res/click.ogg | Bin 4880 -> 0 bytes example/res/custom.texture_profiles | 18 - example/res/empty.png | Bin 14525 -> 0 bytes example/res/exo2.ttf | Bin 110068 -> 0 bytes example/res/gray_long.png | Bin 12428 -> 0 bytes example/res/green_long.png | Bin 15809 -> 0 bytes example/res/progress_back.png | Bin 1790 -> 0 bytes example/res/progress_green.png | Bin 15890 -> 0 bytes example/res/progress_red.png | Bin 15883 -> 0 bytes example/res/progress_yellow.png | Bin 1447 -> 0 bytes example/scroll.collection | 37 - example/scroll/scroll.gui | 821 -------- example/scroll/scroll.gui_script | 84 - example/{kenney => }/templates/button.gui | 4 +- example/{kenney => }/templates/checkbox.gui | 2 +- example/{kenney => }/templates/radio.gui | 2 +- game.project | 8 +- 55 files changed, 116 insertions(+), 2995 deletions(-) rename example/{kenney => }/assets/fonts/exo2.ttf (100%) rename example/{kenney => }/assets/fonts/game.font (87%) rename example/{kenney => }/assets/images/back/back_blue.png (100%) rename example/{kenney => }/assets/images/back/back_gray.png (100%) rename example/{kenney => }/assets/images/back/back_green.png (100%) rename example/{kenney => }/assets/images/back/back_red.png (100%) rename example/{kenney => }/assets/images/buttons/button_blue.png (100%) rename example/{kenney => }/assets/images/buttons/button_green.png (100%) rename example/{kenney => }/assets/images/buttons/button_red.png (100%) rename example/{kenney => }/assets/images/buttons/button_yellow.png (100%) rename example/{kenney => }/assets/images/empty.png (100%) create mode 100644 example/assets/images/kenney.atlas rename example/{kenney => }/assets/images/progress/progress_back.png (100%) rename example/{kenney => }/assets/images/progress/progress_fill_green.png (100%) rename example/{kenney => }/assets/images/progress/progress_fill_red.png (100%) rename example/{kenney => }/assets/images/progress/progress_fill_yellow.png (100%) rename example/{kenney => }/assets/images/radio/check_back_circle.png (100%) rename example/{kenney => }/assets/images/radio/check_back_square.png (100%) rename example/{kenney => }/assets/images/radio/checkmark.png (100%) rename example/{kenney => }/assets/images/radio/tick.png (100%) rename example/{kenney => }/assets/images/slider/slider_back.png (100%) rename example/{kenney => }/assets/images/slider/slider_move.png (100%) rename example/{kenney => }/assets/sounds/click.ogg (100%) delete mode 100644 example/example.collection delete mode 100644 example/example.gui delete mode 100644 example/example.gui.gui_script delete mode 100644 example/game.font delete mode 100644 example/gui.atlas rename example/{kenney => }/gui/main/main.gui (98%) rename example/{kenney => }/gui/main/main.gui_script (85%) rename example/{kenney => }/init.script (92%) rename example/{kenney => }/kenney.collection (89%) delete mode 100644 example/kenney/assets/images/kenney.atlas rename example/{kenney => }/lang.lua (100%) rename example/{kenney => }/page/button.lua (100%) rename example/{kenney => }/page/main.lua (98%) rename example/{kenney => }/page/scroll.lua (89%) rename example/{kenney => }/page/texts.lua (96%) delete mode 100755 example/res/click.ogg delete mode 100644 example/res/custom.texture_profiles delete mode 100755 example/res/empty.png delete mode 100755 example/res/exo2.ttf delete mode 100644 example/res/gray_long.png delete mode 100644 example/res/green_long.png delete mode 100755 example/res/progress_back.png delete mode 100755 example/res/progress_green.png delete mode 100755 example/res/progress_red.png delete mode 100755 example/res/progress_yellow.png delete mode 100644 example/scroll.collection delete mode 100644 example/scroll/scroll.gui delete mode 100644 example/scroll/scroll.gui_script rename example/{kenney => }/templates/button.gui (94%) rename example/{kenney => }/templates/checkbox.gui (96%) rename example/{kenney => }/templates/radio.gui (96%) diff --git a/example/kenney/assets/fonts/exo2.ttf b/example/assets/fonts/exo2.ttf similarity index 100% rename from example/kenney/assets/fonts/exo2.ttf rename to example/assets/fonts/exo2.ttf diff --git a/example/kenney/assets/fonts/game.font b/example/assets/fonts/game.font similarity index 87% rename from example/kenney/assets/fonts/game.font rename to example/assets/fonts/game.font index 5cc90eb..fda7575 100644 --- a/example/kenney/assets/fonts/game.font +++ b/example/assets/fonts/game.font @@ -1,4 +1,4 @@ -font: "/example/kenney/assets/fonts/exo2.ttf" +font: "/example/assets/fonts/exo2.ttf" material: "/builtins/fonts/font-df.material" size: 40 antialias: 1 diff --git a/example/kenney/assets/images/back/back_blue.png b/example/assets/images/back/back_blue.png similarity index 100% rename from example/kenney/assets/images/back/back_blue.png rename to example/assets/images/back/back_blue.png diff --git a/example/kenney/assets/images/back/back_gray.png b/example/assets/images/back/back_gray.png similarity index 100% rename from example/kenney/assets/images/back/back_gray.png rename to example/assets/images/back/back_gray.png diff --git a/example/kenney/assets/images/back/back_green.png b/example/assets/images/back/back_green.png similarity index 100% rename from example/kenney/assets/images/back/back_green.png rename to example/assets/images/back/back_green.png diff --git a/example/kenney/assets/images/back/back_red.png b/example/assets/images/back/back_red.png similarity index 100% rename from example/kenney/assets/images/back/back_red.png rename to example/assets/images/back/back_red.png diff --git a/example/kenney/assets/images/buttons/button_blue.png b/example/assets/images/buttons/button_blue.png similarity index 100% rename from example/kenney/assets/images/buttons/button_blue.png rename to example/assets/images/buttons/button_blue.png diff --git a/example/kenney/assets/images/buttons/button_green.png b/example/assets/images/buttons/button_green.png similarity index 100% rename from example/kenney/assets/images/buttons/button_green.png rename to example/assets/images/buttons/button_green.png diff --git a/example/kenney/assets/images/buttons/button_red.png b/example/assets/images/buttons/button_red.png similarity index 100% rename from example/kenney/assets/images/buttons/button_red.png rename to example/assets/images/buttons/button_red.png diff --git a/example/kenney/assets/images/buttons/button_yellow.png b/example/assets/images/buttons/button_yellow.png similarity index 100% rename from example/kenney/assets/images/buttons/button_yellow.png rename to example/assets/images/buttons/button_yellow.png diff --git a/example/kenney/assets/images/empty.png b/example/assets/images/empty.png similarity index 100% rename from example/kenney/assets/images/empty.png rename to example/assets/images/empty.png diff --git a/example/assets/images/kenney.atlas b/example/assets/images/kenney.atlas new file mode 100644 index 0000000..622bf0d --- /dev/null +++ b/example/assets/images/kenney.atlas @@ -0,0 +1,79 @@ +images { + image: "/example/assets/images/back/back_blue.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/back/back_gray.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/back/back_green.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/back/back_red.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/buttons/button_green.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/buttons/button_red.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/buttons/button_yellow.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/empty.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/progress/progress_back.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/progress/progress_fill_green.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/progress/progress_fill_red.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/progress/progress_fill_yellow.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/radio/check_back_circle.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/radio/check_back_square.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/radio/checkmark.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/radio/tick.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/slider/slider_back.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/slider/slider_move.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/example/assets/images/buttons/button_blue.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +margin: 0 +extrude_borders: 2 +inner_padding: 0 diff --git a/example/kenney/assets/images/progress/progress_back.png b/example/assets/images/progress/progress_back.png similarity index 100% rename from example/kenney/assets/images/progress/progress_back.png rename to example/assets/images/progress/progress_back.png diff --git a/example/kenney/assets/images/progress/progress_fill_green.png b/example/assets/images/progress/progress_fill_green.png similarity index 100% rename from example/kenney/assets/images/progress/progress_fill_green.png rename to example/assets/images/progress/progress_fill_green.png diff --git a/example/kenney/assets/images/progress/progress_fill_red.png b/example/assets/images/progress/progress_fill_red.png similarity index 100% rename from example/kenney/assets/images/progress/progress_fill_red.png rename to example/assets/images/progress/progress_fill_red.png diff --git a/example/kenney/assets/images/progress/progress_fill_yellow.png b/example/assets/images/progress/progress_fill_yellow.png similarity index 100% rename from example/kenney/assets/images/progress/progress_fill_yellow.png rename to example/assets/images/progress/progress_fill_yellow.png diff --git a/example/kenney/assets/images/radio/check_back_circle.png b/example/assets/images/radio/check_back_circle.png similarity index 100% rename from example/kenney/assets/images/radio/check_back_circle.png rename to example/assets/images/radio/check_back_circle.png diff --git a/example/kenney/assets/images/radio/check_back_square.png b/example/assets/images/radio/check_back_square.png similarity index 100% rename from example/kenney/assets/images/radio/check_back_square.png rename to example/assets/images/radio/check_back_square.png diff --git a/example/kenney/assets/images/radio/checkmark.png b/example/assets/images/radio/checkmark.png similarity index 100% rename from example/kenney/assets/images/radio/checkmark.png rename to example/assets/images/radio/checkmark.png diff --git a/example/kenney/assets/images/radio/tick.png b/example/assets/images/radio/tick.png similarity index 100% rename from example/kenney/assets/images/radio/tick.png rename to example/assets/images/radio/tick.png diff --git a/example/kenney/assets/images/slider/slider_back.png b/example/assets/images/slider/slider_back.png similarity index 100% rename from example/kenney/assets/images/slider/slider_back.png rename to example/assets/images/slider/slider_back.png diff --git a/example/kenney/assets/images/slider/slider_move.png b/example/assets/images/slider/slider_move.png similarity index 100% rename from example/kenney/assets/images/slider/slider_move.png rename to example/assets/images/slider/slider_move.png diff --git a/example/kenney/assets/sounds/click.ogg b/example/assets/sounds/click.ogg similarity index 100% rename from example/kenney/assets/sounds/click.ogg rename to example/assets/sounds/click.ogg diff --git a/example/example.collection b/example/example.collection deleted file mode 100644 index 3b0c850..0000000 --- a/example/example.collection +++ /dev/null @@ -1,79 +0,0 @@ -name: "main" -scale_along_z: 0 -embedded_instances { - id: "go" - data: "components {\n" - " id: \"example\"\n" - " component: \"/example/example.gui\"\n" - " position {\n" - " x: 0.0\n" - " y: 0.0\n" - " z: 0.0\n" - " }\n" - " rotation {\n" - " x: 0.0\n" - " y: 0.0\n" - " z: 0.0\n" - " w: 1.0\n" - " }\n" - "}\n" - "" - position { - x: 0.0 - y: 0.0 - z: 0.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale3 { - x: 1.0 - y: 1.0 - z: 1.0 - } -} -embedded_instances { - id: "sounds" - data: "embedded_components {\n" - " id: \"click\"\n" - " type: \"sound\"\n" - " data: \"sound: \\\"/example/res/click.ogg\\\"\\n" - "looping: 0\\n" - "group: \\\"master\\\"\\n" - "gain: 0.4\\n" - "pan: 0.0\\n" - "speed: 1.0\\n" - "\"\n" - " position {\n" - " x: 0.0\n" - " y: 0.0\n" - " z: 0.0\n" - " }\n" - " rotation {\n" - " x: 0.0\n" - " y: 0.0\n" - " z: 0.0\n" - " w: 1.0\n" - " }\n" - "}\n" - "" - position { - x: 0.0 - y: 0.0 - z: 0.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale3 { - x: 1.0 - y: 1.0 - z: 1.0 - } -} diff --git a/example/example.gui b/example/example.gui deleted file mode 100644 index 4c938ae..0000000 --- a/example/example.gui +++ /dev/null @@ -1,1660 +0,0 @@ -script: "/example/example.gui.gui_script" -fonts { - name: "game" - font: "/example/game.font" -} -textures { - name: "gui" - texture: "/example/gui.atlas" -} -background_color { - x: 0.0 - y: 0.0 - z: 0.0 - w: 0.0 -} -nodes { - position { - x: 300.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: "control" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - 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: -150.0 - y: 50.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.5 - y: 0.5 - z: 1.0 - w: 1.0 - } - size { - x: 426.0 - y: 190.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/green_long" - id: "prev" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "control" - 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: 0.0 - y: 20.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Prev" - font: "game" - id: "prev_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "prev" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 1.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 150.0 - y: 50.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.5 - y: 0.5 - z: 1.0 - w: 1.0 - } - size { - x: 426.0 - y: 190.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/green_long" - id: "next" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "control" - 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: 0.0 - y: 20.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Next" - font: "game" - id: "next_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "next" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 1.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 300.0 - y: 400.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: "center" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - 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: 0.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: "buttons" - 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: 0.0 - y: 254.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.5 - y: 0.5 - z: 1.0 - w: 1.0 - } - size { - x: 426.0 - y: 190.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/green_long" - id: "button_1" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "buttons" - 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: 0.0 - y: 20.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Button 1" - font: "game" - id: "text_1" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "button_1" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 1.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 0.0 - y: 129.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.5 - y: 0.5 - z: 1.0 - w: 1.0 - } - size { - x: 426.0 - y: 190.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/green_long" - id: "button_2" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "buttons" - 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: 0.0 - y: 20.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Button 2" - font: "game" - id: "text_2" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "button_2" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 1.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 600.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: "progress" - 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: 0.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: 391.0 - y: 40.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/progress_back" - id: "simple_back" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "progress" - 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: -194.5 - y: 2.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: 389.0 - y: 35.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/progress_yellow" - id: "simple_fill" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_W - adjust_mode: ADJUST_MODE_FIT - parent: "simple_back" - layer: "" - inherit_alpha: true - slice9 { - x: 15.0 - y: 0.0 - z: 15.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: 0.0 - y: 106.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: 391.0 - y: 40.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/progress_back" - id: "simple_vert" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "progress" - 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: 0.0 - y: -17.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: 389.0 - y: 35.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/progress_yellow" - id: "simple_vert_fill" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_S - adjust_mode: ADJUST_MODE_FIT - parent: "simple_vert" - layer: "" - inherit_alpha: true - slice9 { - x: 15.0 - y: 0.0 - z: 15.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: 0.0 - y: -130.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: 391.0 - y: 40.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/progress_back" - id: "rich_back" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "progress" - 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: -194.5 - y: 2.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: 389.0 - y: 35.0 - z: 0.0 - w: 1.0 - } - color { - x: 0.6 - y: 0.6 - z: 0.6 - w: 1.0 - } - type: TYPE_BOX - blend_mode: BLEND_MODE_ALPHA - texture: "gui/progress_green" - id: "rich_green" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_W - adjust_mode: ADJUST_MODE_FIT - parent: "rich_back" - layer: "" - inherit_alpha: true - slice9 { - x: 15.0 - y: 0.0 - z: 15.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: -194.5 - y: 2.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: 389.0 - y: 35.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/progress_red" - id: "rich_red" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_W - adjust_mode: ADJUST_MODE_FIT - parent: "rich_back" - layer: "" - inherit_alpha: true - slice9 { - x: 15.0 - y: 0.0 - z: 15.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: -194.5 - y: 2.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: 389.0 - y: 35.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/progress_yellow" - id: "rich_fill" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_W - adjust_mode: ADJUST_MODE_FIT - parent: "rich_back" - layer: "" - inherit_alpha: true - slice9 { - x: 15.0 - y: 0.0 - z: 15.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: 110.0 - y: 250.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.5 - y: 0.5 - z: 1.0 - w: 1.0 - } - size { - x: 426.0 - y: 190.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/green_long" - id: "rich_add" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "progress" - 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: 0.0 - y: 20.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "add rich" - font: "game" - id: "rich_add_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "rich_add" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 1.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: -110.0 - y: 250.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 0.5 - y: 0.5 - z: 1.0 - w: 1.0 - } - size { - x: 426.0 - y: 190.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/green_long" - id: "rich_dec" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "progress" - 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: 0.0 - y: 20.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "dec rich\n" - "" - font: "game" - id: "rich_dec_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "rich_dec" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 1.0 - shadow_alpha: 1.0 - template_node_child: false - 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 deleted file mode 100644 index bbd8be7..0000000 --- a/example/example.gui.gui_script +++ /dev/null @@ -1,155 +0,0 @@ -local druid = require("druid.druid") -local druid_settings = require("druid.system.settings") - -local lang = { - locale_text = "Localized" -} -local start_x = 300 -local page_width = 600 -local cur_page = 1 -local max_page = 3 - - - -local function log(self, params) - print(params) -end - - -local function setup_druid(self) - -- two different way of exernal component regesstration - druid.comps["my_mega_test_comp"] = require "druid.base.text" - druid.register("my_custom_component", {}) - - druid_settings.is_debug = true - druid_settings.play_sound = function(name) - sound.play("sounds#" .. name) - end - druid_settings.get_text = function(text_id) - return lang[text_id] - end -end - - -local function change_page(self, delta) - cur_page = cur_page + delta - cur_page = math.max(1, cur_page) - cur_page = math.min(cur_page, max_page) - - gui.animate(gui.get_node("center"), "position.x", - start_x - (page_width * (cur_page - 1)), gui.EASING_OUTSINE, 0.1) -end - -local function init_pages(self) - self.druid:new_button("prev", change_page, -1) - self.druid:new_button("next", change_page, 1) -end - - -local function init_buttons(self) - self.druid:new_button("button_1", log, "button 1") - - self.druid:new(druid.comps.button, "button_2", log, "button 2") -end - - -local function init_progress(self) - local val = 0.4 - local simple = self.druid:new_progress("simple_fill", "x", val) - local vert = self.druid:new_progress("simple_vert_fill", "y", val) - - simple:set_steps({0, 0.3, 0.6, 1}, function(_, step) - print("STEP:", step) - end) - - timer.delay(0.4, true, function() - val = val + 0.1 - if val > 1 then - simple:empty() - vert:empty() - val = 0 - end - simple:to(val) - 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 - rich:to(rich_val) - end) - self.druid:new_button("rich_dec", function() - rich_val = rich_val - 0.1 - rich:to(rich_val) - end) -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_anchor(vmath.vector3(0)) - 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_anchor(vmath.vector3(0)) - 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) - - init_pages(self) - init_buttons(self) - init_progress(self) - init_grid(self) - - self.druid:new_android_back(log, "some") -end - -function update(self, dt) - self.druid:update(dt) -end - -function on_message(self, message_id, message, sender) - self.druid:on_message(message_id, message, sender) -end - -function on_input(self, action_id, action) - self.druid:on_input(action_id, action) -end \ No newline at end of file diff --git a/example/game.font b/example/game.font deleted file mode 100644 index 2b014d6..0000000 --- a/example/game.font +++ /dev/null @@ -1,17 +0,0 @@ -font: "/example/res/exo2.ttf" -material: "/builtins/fonts/font.material" -size: 64 -antialias: 1 -alpha: 1.0 -outline_alpha: 0.0 -outline_width: 0.0 -shadow_alpha: 1.0 -shadow_blur: 0 -shadow_x: 3.0 -shadow_y: -5.0 -extra_characters: "" -output_format: TYPE_BITMAP -all_chars: false -cache_width: 0 -cache_height: 0 -render_mode: MODE_MULTI_LAYER diff --git a/example/gui.atlas b/example/gui.atlas deleted file mode 100644 index 6cb5a3a..0000000 --- a/example/gui.atlas +++ /dev/null @@ -1,24 +0,0 @@ -images { - image: "/example/res/gray_long.png" -} -images { - image: "/example/res/green_long.png" -} -images { - image: "/example/res/progress_back.png" -} -images { - image: "/example/res/progress_green.png" -} -images { - image: "/example/res/progress_red.png" -} -images { - image: "/example/res/progress_yellow.png" -} -images { - image: "/example/res/empty.png" -} -margin: 2 -extrude_borders: 2 -inner_padding: 0 diff --git a/example/kenney/gui/main/main.gui b/example/gui/main/main.gui similarity index 98% rename from example/kenney/gui/main/main.gui rename to example/gui/main/main.gui index e1b5f7a..4e3a5ec 100644 --- a/example/kenney/gui/main/main.gui +++ b/example/gui/main/main.gui @@ -1,11 +1,11 @@ -script: "/example/kenney/gui/main/main.gui_script" +script: "/example/gui/main/main.gui_script" fonts { name: "game" - font: "/example/kenney/assets/fonts/game.font" + font: "/example/assets/fonts/game.font" } textures { name: "kenney" - texture: "/example/kenney/assets/images/kenney.atlas" + texture: "/example/assets/images/kenney.atlas" } background_color { x: 0.0 @@ -387,7 +387,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -1843,7 +1843,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/radio.gui" + template: "/example/templates/radio.gui" template_node_child: false } nodes { @@ -1993,7 +1993,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/radio.gui" + template: "/example/templates/radio.gui" template_node_child: false } nodes { @@ -2143,7 +2143,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/radio.gui" + template: "/example/templates/radio.gui" template_node_child: false } nodes { @@ -2466,7 +2466,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/checkbox.gui" + template: "/example/templates/checkbox.gui" template_node_child: false } nodes { @@ -2616,7 +2616,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/checkbox.gui" + template: "/example/templates/checkbox.gui" template_node_child: false } nodes { @@ -2766,7 +2766,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/checkbox.gui" + template: "/example/templates/checkbox.gui" template_node_child: false } nodes { @@ -4128,7 +4128,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -4287,7 +4287,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -4447,7 +4447,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -4607,7 +4607,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -4767,7 +4767,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -4927,7 +4927,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -6062,7 +6062,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { @@ -6221,7 +6221,7 @@ nodes { layer: "" inherit_alpha: true alpha: 1.0 - template: "/example/kenney/templates/button.gui" + template: "/example/templates/button.gui" template_node_child: false } nodes { diff --git a/example/kenney/gui/main/main.gui_script b/example/gui/main/main.gui_script similarity index 85% rename from example/kenney/gui/main/main.gui_script rename to example/gui/main/main.gui_script index 627cbc7..26f3d8a 100644 --- a/example/kenney/gui/main/main.gui_script +++ b/example/gui/main/main.gui_script @@ -3,10 +3,10 @@ local druid = require("druid.druid") local empty_style = require("druid.styles.empty.style") local default_style = require("druid.styles.default.style") -local main_page = require("example.kenney.page.main") -local text_page = require("example.kenney.page.texts") -local button_page = require("example.kenney.page.button") -local scroll_page = require("example.kenney.page.scroll") +local main_page = require("example.page.main") +local text_page = require("example.page.texts") +local button_page = require("example.page.button") +local scroll_page = require("example.page.scroll") local pages = { "main_page", diff --git a/example/kenney/init.script b/example/init.script similarity index 92% rename from example/kenney/init.script rename to example/init.script index aa2bf5c..87e6385 100644 --- a/example/kenney/init.script +++ b/example/init.script @@ -1,6 +1,6 @@ local druid = require("druid.druid") local const = require("druid.const") -local lang = require("example.kenney.lang") +local lang = require("example.lang") local function setup_druid() diff --git a/example/kenney/kenney.collection b/example/kenney.collection similarity index 89% rename from example/kenney/kenney.collection rename to example/kenney.collection index 3f630ff..a8b3693 100644 --- a/example/kenney/kenney.collection +++ b/example/kenney.collection @@ -4,7 +4,7 @@ embedded_instances { id: "gui" data: "components {\n" " id: \"main\"\n" - " component: \"/example/kenney/gui/main/main.gui\"\n" + " component: \"/example/gui/main/main.gui\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -39,7 +39,7 @@ embedded_instances { id: "system" data: "components {\n" " id: \"init\"\n" - " component: \"/example/kenney/init.script\"\n" + " component: \"/example/init.script\"\n" " position {\n" " x: 0.0\n" " y: 0.0\n" @@ -75,7 +75,7 @@ embedded_instances { data: "embedded_components {\n" " id: \"click\"\n" " type: \"sound\"\n" - " data: \"sound: \\\"/example/kenney/assets/sounds/click.ogg\\\"\\n" + " data: \"sound: \\\"/example/assets/sounds/click.ogg\\\"\\n" "looping: 0\\n" "group: \\\"master\\\"\\n" "gain: 1.0\\n" diff --git a/example/kenney/assets/images/kenney.atlas b/example/kenney/assets/images/kenney.atlas deleted file mode 100644 index f2df027..0000000 --- a/example/kenney/assets/images/kenney.atlas +++ /dev/null @@ -1,60 +0,0 @@ -images { - image: "/example/kenney/assets/images/back/back_blue.png" -} -images { - image: "/example/kenney/assets/images/back/back_gray.png" -} -images { - image: "/example/kenney/assets/images/back/back_green.png" -} -images { - image: "/example/kenney/assets/images/back/back_red.png" -} -images { - image: "/example/kenney/assets/images/buttons/button_green.png" -} -images { - image: "/example/kenney/assets/images/buttons/button_red.png" -} -images { - image: "/example/kenney/assets/images/buttons/button_yellow.png" -} -images { - image: "/example/kenney/assets/images/empty.png" -} -images { - image: "/example/kenney/assets/images/progress/progress_back.png" -} -images { - image: "/example/kenney/assets/images/progress/progress_fill_green.png" -} -images { - image: "/example/kenney/assets/images/progress/progress_fill_red.png" -} -images { - image: "/example/kenney/assets/images/progress/progress_fill_yellow.png" -} -images { - image: "/example/kenney/assets/images/radio/check_back_circle.png" -} -images { - image: "/example/kenney/assets/images/radio/check_back_square.png" -} -images { - image: "/example/kenney/assets/images/radio/checkmark.png" -} -images { - image: "/example/kenney/assets/images/radio/tick.png" -} -images { - image: "/example/kenney/assets/images/slider/slider_back.png" -} -images { - image: "/example/kenney/assets/images/slider/slider_move.png" -} -images { - image: "/example/kenney/assets/images/buttons/button_blue.png" -} -margin: 0 -extrude_borders: 2 -inner_padding: 0 diff --git a/example/kenney/lang.lua b/example/lang.lua similarity index 100% rename from example/kenney/lang.lua rename to example/lang.lua diff --git a/example/kenney/page/button.lua b/example/page/button.lua similarity index 100% rename from example/kenney/page/button.lua rename to example/page/button.lua diff --git a/example/kenney/page/main.lua b/example/page/main.lua similarity index 98% rename from example/kenney/page/main.lua rename to example/page/main.lua index 834593c..5702deb 100644 --- a/example/kenney/page/main.lua +++ b/example/page/main.lua @@ -1,4 +1,4 @@ -local lang = require("example.kenney.lang") +local lang = require("example.lang") local M = {} diff --git a/example/kenney/page/scroll.lua b/example/page/scroll.lua similarity index 89% rename from example/kenney/page/scroll.lua rename to example/page/scroll.lua index 4fb112c..6557082 100644 --- a/example/kenney/page/scroll.lua +++ b/example/page/scroll.lua @@ -14,11 +14,12 @@ local function init_grid(self) grid:add(clone_prefab["grid_prefab"]) gui.set_text(clone_prefab["grid_prefab_text"], "Node " .. i) - self.druid:new_button(clone_prefab["grid_button"], function() + local button = self.druid:new_button(clone_prefab["grid_button"], function() local position = gui.get_position(clone_prefab["grid_prefab"]) position.x = -position.x grid_scroll:scroll_to(position) end) + button:set_click_zone(gui.get_node("scroll_with_grid_size")) end gui.set_enabled(prefab, false) diff --git a/example/kenney/page/texts.lua b/example/page/texts.lua similarity index 96% rename from example/kenney/page/texts.lua rename to example/page/texts.lua index d1d459d..0a91534 100644 --- a/example/kenney/page/texts.lua +++ b/example/page/texts.lua @@ -1,5 +1,3 @@ -local lang = require("example.kenney.lang") - local M = {} local pivots = { diff --git a/example/res/click.ogg b/example/res/click.ogg deleted file mode 100755 index 5d223f37eea2a29857ca36b536a6190d7afede79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4880 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 diff --git a/example/res/custom.texture_profiles b/example/res/custom.texture_profiles deleted file mode 100644 index 5b0d776..0000000 --- a/example/res/custom.texture_profiles +++ /dev/null @@ -1,18 +0,0 @@ -path_settings { - path: "**" - profile: "Default" -} -profiles { - name: "Default" - platforms { - os: OS_ID_GENERIC - formats { - format: TEXTURE_FORMAT_RGBA - compression_level: BEST - compression_type: COMPRESSION_TYPE_DEFAULT - } - mipmaps: false - max_texture_size: 0 - premultiply_alpha: true - } -} diff --git a/example/res/empty.png b/example/res/empty.png deleted file mode 100755 index 5da9ec0922e6066d3284b286ec892cc4f6745636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14525 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 diff --git a/example/res/gray_long.png b/example/res/gray_long.png deleted file mode 100644 index cc29967043b7264a3656ac885c1640b15976add2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12428 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 AVE_OC diff --git a/example/res/progress_back.png b/example/res/progress_back.png deleted file mode 100755 index 30a6652412e4c9f4e482851ad3cd8f4de0722563..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1790 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 diff --git a/example/res/progress_yellow.png b/example/res/progress_yellow.png deleted file mode 100755 index 3e4e38d959eef9831526d07b6b37b60934767ff9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1447 zcmV;Y1z7rtP)B#u+WAz7C<7=*odN03k!V7YUzJ~B$D6;E!>1?EY!b%Eu}H| z-XNltB$y2y&|qRC6d)AB?#!HHo^#KgxibuEx9rUClT3E@&MZ53nLNLF?z#6I`~9oO zF#`)md&X~pnGJ!N+3J3)ZTT?+Fj~L?;CWy_up8J8Y(+#w*4i!LCU6C~0GtKRk?18L z#YC^0=yoEVmBi;~4&C!|+qu@8(P|m3cA&k%#s$Jd7)OA&fnEA<7ZG_NZ7sJ)fER%U z;7^PtOMFVO>#bb%0}#i){*a4)AP0bV3Ntwj`hl>)jN=$rfny2;5s`IgSFYd2RWsiA zy6*Me>-;#u4;@ucs6rv%Z{$(M-^Ey9H4uue`9}IpA zEe_;BF!t#^AR;nBjC}^bdYvD)Q^5lvwCXU(9l}8~`yOMP-UlKg6Uf+RWgX$9&(?d}A5$>nU8{~YiHOKFghIX~fxTuNt+!RDq#8Rd*n%k$L`0@axp;Zu$V;bp zQm$a|&4>G^ohleaM5e=_-fseX$M4wnvwPYbH@E(nnGL)AI)!kbb5}(~Wb(wGPkWK* zti)?~|L#5Pox(FI=}Ki0k!h9^e)#CQP)%-^27ijA_l1baR2ZuF`I{F)is^}zs@e0B z0zpJ%sx<3=ifM01iN|8SA*oRi5t$aL4uu3I2j)VIY>&NaupyWy96n;yQ{)3%Pq}Pqr6Qaf#L_{V+8k~Mwg+R>pz77S?ffUn4zj*COKekk* zMx?u%@+$w`P9qplFo=k(TdC0@bgTNF>-=g}_j~2+Q{arR>;FqiTqCj5pFCLMzgq1- zr9i7yt+`-6dy=L`5)oNH%Aj%{Lnt5qJrFvpaq!{4>LRWIKY8Wv0w?n*bpJ3?%s;TY z;+@0b2YbDd(^l0zh=@E`((vh~gRz6Eo_k$y212Y38~HArTw0#*w#&|Z1{_W?ZHnFs zl#ao>gcKv~XvA2S?euk=W0`|nU4w|o1E)VjMgPLI!Ju+AhHy_H+$lLg9SYtyoB$Sc z$AFPKDF;IGKpU~yt; zdERrN9}4ah;0<7JexgCI%!lD!La#gM6!MzR)rxI-m4^IPp&%l%c2XS-sXv!dJ%v#- z9P(L4X=nn}i>3Z&%}`hY-UQAATkF=tO4nePsvz)AAu!Y_s7nwLS$lP%?{^C2@X*kt zr^EBx-SWD>v^>93Z)lI~#bw|%;5%Sr{~s@f-xJ0{qDLJFiP9{Hh{#%N%urMp|1q6G z?XK7RrRDj{&5fg>;LZXs1E+y)^~Sn$pbRqSV@r(|LAf9zvUY~o%Sp{Ig-ezk#)hx5Z(eVjeD`-U-rO%;7Q*rNA{h{&3|4cq{(02j&_@i`v_{$H;Q_y>2k4O4<+oVfr1002ovPDHLkV1gvO BzJCA! diff --git a/example/scroll.collection b/example/scroll.collection deleted file mode 100644 index c54a758..0000000 --- a/example/scroll.collection +++ /dev/null @@ -1,37 +0,0 @@ -name: "default" -scale_along_z: 0 -embedded_instances { - id: "scroll" - data: "components {\n" - " id: \"scroll\"\n" - " component: \"/example/scroll/scroll.gui\"\n" - " position {\n" - " x: 0.0\n" - " y: 0.0\n" - " z: 0.0\n" - " }\n" - " rotation {\n" - " x: 0.0\n" - " y: 0.0\n" - " z: 0.0\n" - " w: 1.0\n" - " }\n" - "}\n" - "" - position { - x: 0.0 - y: 0.0 - z: 0.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale3 { - x: 1.0 - y: 1.0 - z: 1.0 - } -} diff --git a/example/scroll/scroll.gui b/example/scroll/scroll.gui deleted file mode 100644 index c9fab11..0000000 --- a/example/scroll/scroll.gui +++ /dev/null @@ -1,821 +0,0 @@ -script: "/example/scroll/scroll.gui_script" -fonts { - name: "game" - font: "/example/game.font" -} -textures { - name: "gui" - texture: "/example/gui.atlas" -} -background_color { - x: 0.0 - y: 0.0 - z: 0.0 - w: 0.0 -} -nodes { - position { - x: 300.0 - y: 450.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: 600.0 - y: 900.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: "input_zone" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_STRETCH - 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: 0.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: "parent" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_STRETCH - parent: "input_zone" - 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: 0.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: "main_page" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_FIT - parent: "parent" - 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: 0.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Main scroll page" - font: "game" - id: "main_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "main_page" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 0.0 - shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: -600.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: "left_page" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_STRETCH - parent: "parent" - 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: 0.0 - y: 330.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Left text\n" - "" - font: "game" - id: "left_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "left_page" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 0.0 - shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 0.0 - y: 554.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: 400.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: "left_page" - layer: "" - inherit_alpha: false - 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: 0.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "1" - font: "game" - id: "number" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "prefab" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 0.0 - shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 0.0 - y: -150.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: 600.0 - y: 600.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: "" - id: "page_input" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_STRETCH - parent: "left_page" - layer: "" - inherit_alpha: true - slice9 { - x: 0.0 - y: 0.0 - z: 0.0 - w: 0.0 - } - clipping_mode: CLIPPING_MODE_STENCIL - clipping_visible: true - clipping_inverted: false - alpha: 0.3 - template_node_child: false - size_mode: SIZE_MODE_MANUAL -} -nodes { - position { - x: 0.0 - y: 300.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: 600.0 - y: 600.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: "page_parent" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_N - adjust_mode: ADJUST_MODE_STRETCH - parent: "page_input" - 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: 600.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: "right_page" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - adjust_mode: ADJUST_MODE_STRETCH - parent: "parent" - 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: 0.0 - y: 330.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: 200.0 - y: 100.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA - text: "Right text\n" - "" - font: "game" - id: "right_text" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER - outline { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } - adjust_mode: ADJUST_MODE_FIT - line_break: false - parent: "right_page" - layer: "" - inherit_alpha: true - alpha: 1.0 - outline_alpha: 0.0 - shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 -} -nodes { - position { - x: 0.0 - y: 150.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: 600.0 - y: 600.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: "" - id: "right_input" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_N - adjust_mode: ADJUST_MODE_STRETCH - parent: "right_page" - layer: "" - inherit_alpha: true - slice9 { - x: 0.0 - y: 0.0 - z: 0.0 - w: 0.0 - } - clipping_mode: CLIPPING_MODE_STENCIL - clipping_visible: true - clipping_inverted: false - alpha: 0.3 - template_node_child: false - size_mode: SIZE_MODE_MANUAL -} -nodes { - position { - x: 0.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: 600.0 - y: 600.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: "right_parent" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_N - adjust_mode: ADJUST_MODE_STRETCH - parent: "right_input" - 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 -} -material: "/builtins/materials/gui.material" -adjust_reference: ADJUST_REFERENCE_PARENT -max_nodes: 512 diff --git a/example/scroll/scroll.gui_script b/example/scroll/scroll.gui_script deleted file mode 100644 index 259b9be..0000000 --- a/example/scroll/scroll.gui_script +++ /dev/null @@ -1,84 +0,0 @@ -local druid = require("druid.druid") - - -local function init_left_page(self) - local prefab = gui.get_node("prefab") - self.left_grid = self.druid:new_grid("page_parent", prefab, 1) - self.left_grid:set_offset(vmath.vector3(0, 5, 0)) - - for i = 1, 7 do - local nodes = gui.clone_tree(prefab) - gui.set_text(nodes["number"], i) - self.left_grid:add(nodes["prefab"]) - end - - local size = self.left_grid:get_size() - local view_size = gui.get_size(gui.get_node("page_parent")) - - self.left_scroll = self.druid:new_scroll("page_parent", "page_input", - vmath.vector4(0, view_size.y/2, 0, -size.y - view_size.y/2)) - - self.left_scroll:set_points(self.left_grid:get_all_pos()) -end - - -local function log(self, index) - print("Click on", index) -end - - -local function init_right_page(self) - local prefab = gui.get_node("prefab") - self.right_grid = self.druid:new_grid("right_parent", prefab, 1) - self.right_grid:set_offset(vmath.vector3(0, 5, 0)) - - for i = 1, 20 do - local nodes = gui.clone_tree(prefab) - gui.set_text(nodes["number"], i) - self.druid:new_button(nodes["prefab"], log, i) - self.right_grid:add(nodes["prefab"]) - end - - local size = self.right_grid:get_size() - local view_size = gui.get_size(gui.get_node("right_parent")) - - -- TODO: Should we calc scrolle size with parent size? - -- If yes, we will pass only content size to correct scrolling - self.right_scroll = self.druid:new_scroll("right_parent", "right_input", - vmath.vector4(0, 0, 0, -size.y - view_size.y)) - - self.right_scroll:set_points(self.right_grid:get_all_pos()) - - self.right_scroll:on_point_move(function(self, index, pos) - print("Point to element:", index) - end) -end - - -function init(self) - self.druid = druid.new(self) - - -- -600 to 600 - left and right pos.x pages - -- border is vmath.vector4(left_x, top_y, right_x, bot_y) - self.main_scroll = self.druid:new_scroll("parent", "input_zone", - vmath.vector4(-600, 0, 600, 0)) - - self.main_scroll:set_points({ - vmath.vector3(600, 0, 0), - vmath.vector3(0, 0, 0), - vmath.vector3(-600, 0, 0), - }) - -- Disable free inert and we only scroll via points, if exist - self.main_scroll:set_inert(false) - - init_left_page(self) - init_right_page(self) -end - -function update(self, dt) - self.druid:update(dt) -end - -function on_input(self, action_id, action) - self.druid:on_input(action_id, action) -end diff --git a/example/kenney/templates/button.gui b/example/templates/button.gui similarity index 94% rename from example/kenney/templates/button.gui rename to example/templates/button.gui index 4beda9c..0e17ab9 100644 --- a/example/kenney/templates/button.gui +++ b/example/templates/button.gui @@ -1,11 +1,11 @@ script: "" fonts { name: "game" - font: "/example/kenney/assets/fonts/game.font" + font: "/example/assets/fonts/game.font" } textures { name: "kenney" - texture: "/example/kenney/assets/images/kenney.atlas" + texture: "/example/assets/images/kenney.atlas" } background_color { x: 0.0 diff --git a/example/kenney/templates/checkbox.gui b/example/templates/checkbox.gui similarity index 96% rename from example/kenney/templates/checkbox.gui rename to example/templates/checkbox.gui index 393adbe..53c2069 100644 --- a/example/kenney/templates/checkbox.gui +++ b/example/templates/checkbox.gui @@ -1,7 +1,7 @@ script: "" textures { name: "kenney" - texture: "/example/kenney/assets/images/kenney.atlas" + texture: "/example/assets/images/kenney.atlas" } background_color { x: 0.0 diff --git a/example/kenney/templates/radio.gui b/example/templates/radio.gui similarity index 96% rename from example/kenney/templates/radio.gui rename to example/templates/radio.gui index eef5fa2..75ed7d1 100644 --- a/example/kenney/templates/radio.gui +++ b/example/templates/radio.gui @@ -1,7 +1,7 @@ script: "" textures { name: "kenney" - texture: "/example/kenney/assets/images/kenney.atlas" + texture: "/example/assets/images/kenney.atlas" } background_color { x: 0.0 diff --git a/game.project b/game.project index 2a618f5..f9d7075 100644 --- a/game.project +++ b/game.project @@ -1,5 +1,5 @@ [bootstrap] -main_collection = /example/kenney/kenney.collectionc +main_collection = /example/kenney.collectionc [script] shared_state = 1 @@ -14,11 +14,9 @@ title = druid [library] include_dirs = druid -[graphics] -texture_profiles = /example/res/custom.texture_profiles - [input] gamepads = /builtins/input/default.gamepadsc [druid] -autofocus = 1 \ No newline at end of file +autofocus = 1 +