mirror of
https://github.com/Insality/druid
synced 2025-06-27 18:37:45 +02:00
Merge branch 'develop' into feature/D20-radio-component
This commit is contained in:
commit
07ebb202ac
@ -10,6 +10,12 @@ Defold UI library
|
|||||||
|
|
||||||
# API
|
# API
|
||||||
|
|
||||||
|
# LDoc
|
||||||
|
|
||||||
|
Generate with `ldoc .` with `config.ld` file
|
||||||
|
|
||||||
|
Insctruction here: https://github.com/stevedonovan/LDoc
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
8
config.ld
Normal file
8
config.ld
Normal file
@ -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
|
49
docs/index.html
Normal file
49
docs/index.html
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<head>
|
||||||
|
<title>Defold Druid UI Library</title>
|
||||||
|
<link rel="stylesheet" href="ldoc_pale.css" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
|
||||||
|
<div id="product">
|
||||||
|
<div id="product_logo"></div>
|
||||||
|
<div id="product_name"><big><b></b></big></div>
|
||||||
|
<div id="product_description"></div>
|
||||||
|
</div> <!-- id="product" -->
|
||||||
|
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Menu -->
|
||||||
|
|
||||||
|
<div id="navigation">
|
||||||
|
<br/>
|
||||||
|
<h1>Druid</h1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Documentation for Druid Library</h2>
|
||||||
|
|
||||||
|
|
||||||
|
</div> <!-- id="content" -->
|
||||||
|
</div> <!-- id="main" -->
|
||||||
|
<div id="about">
|
||||||
|
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
|
||||||
|
<i style="float:right;">Last updated 2019-09-25 19:57:43 </i>
|
||||||
|
</div> <!-- id="about" -->
|
||||||
|
</div> <!-- id="container" -->
|
||||||
|
</body>
|
||||||
|
</html>
|
303
docs/ldoc_pale.css
Normal file
303
docs/ldoc_pale.css
Normal file
@ -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; }
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
local data = require("druid.data")
|
|
||||||
|
|
||||||
local M = {}
|
|
||||||
M.interest = {
|
|
||||||
data.ON_INPUT
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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(self, action_id, action)
|
|
||||||
if action[data.RELEASED] then
|
|
||||||
self.callback(self.parent.parent, self.params)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
return M
|
|
34
druid/base/back_handler.lua
Normal file
34
druid/base/back_handler.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
--- Component to handle back key
|
||||||
|
-- @module base.back_handler
|
||||||
|
|
||||||
|
local const = require("druid.const")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
M.interest = {
|
||||||
|
const.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 = const.ACTION_BACK
|
||||||
|
self.callback = callback
|
||||||
|
self.params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 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[const.RELEASED] then
|
||||||
|
self.callback(self.parent.parent, self.params)
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return M
|
33
druid/base/blocker.lua
Normal file
33
druid/base/blocker.lua
Normal file
@ -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
|
@ -1,4 +1,11 @@
|
|||||||
local data = require("druid.data")
|
--- Component to handle basic GUI button
|
||||||
|
-- @module base.button
|
||||||
|
|
||||||
|
-- TODO: Add button mode:
|
||||||
|
-- Long tap
|
||||||
|
-- Repeated tap
|
||||||
|
|
||||||
|
local const = require("druid.const")
|
||||||
local ui_animate = require("druid.helper.druid_animate")
|
local ui_animate = require("druid.helper.druid_animate")
|
||||||
local settings = require("druid.settings")
|
local settings = require("druid.settings")
|
||||||
local helper = require("druid.helper")
|
local helper = require("druid.helper")
|
||||||
@ -6,18 +13,18 @@ local b_settings = settings.button
|
|||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
M.interest = {
|
M.interest = {
|
||||||
data.ON_INPUT
|
const.ON_INPUT
|
||||||
}
|
}
|
||||||
|
|
||||||
M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0)
|
M.DEFAULT_DEACTIVATE_COLOR = vmath.vector4(0, 0, 0, 0)
|
||||||
M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1)
|
M.DEFAULT_DEACTIVATE_SCALE = vmath.vector3(0.8, 0.9, 1)
|
||||||
M.DEFAULT_ACTIVATE_SCALE = vmath.vector3(1, 1, 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)
|
function M.init(self, node, callback, params, anim_node, event)
|
||||||
self.node = helper.get_node(node)
|
self.node = helper.get_node(node)
|
||||||
self.event = data.A_TOUCH
|
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
|
||||||
self.scale_from = gui.get_scale(self.anim_node)
|
self.scale_from = gui.get_scale(self.anim_node)
|
||||||
self.scale_to = self.scale_from + b_settings.SCALE_CHANGE
|
self.scale_to = self.scale_from + b_settings.SCALE_CHANGE
|
||||||
@ -30,14 +37,23 @@ function M.init(self, node, callback, params, anim_node, event)
|
|||||||
self.hover_anim = b_settings.IS_HOVER
|
self.hover_anim = b_settings.IS_HOVER
|
||||||
self.sound = b_settings.BTN_SOUND
|
self.sound = b_settings.BTN_SOUND
|
||||||
self.sound_disable = b_settings.BTN_SOUND_DISABLED
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
local function set_hover(self, state)
|
local function set_hover(self, state)
|
||||||
if self.hover_anim and self._is_hovered ~= state then
|
if self.hover_anim and self._is_hovered ~= state then
|
||||||
local target_scale = state and self.scale_hover_to or self.scale_from
|
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
|
self._is_hovered = state
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -47,15 +63,17 @@ local function on_button_release(self)
|
|||||||
if not self.disabled then
|
if not self.disabled then
|
||||||
if not self.stub and self.can_action then
|
if not self.stub and self.can_action then
|
||||||
self.can_action = false
|
self.can_action = false
|
||||||
self.tap_anim(self)
|
if self.tap_anim then
|
||||||
settings.play_sound(self.sound)
|
self.tap_anim(self)
|
||||||
|
end
|
||||||
self.callback(self.parent.parent, self.params, self)
|
self.callback(self.parent.parent, self.params, self)
|
||||||
|
settings.play_sound(self.sound)
|
||||||
else
|
else
|
||||||
set_hover(self, false)
|
set_hover(self, false)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
self.sound_disable()
|
settings.play_sound(self.sound_disable)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -70,30 +88,32 @@ function M.on_input(self, action_id, action)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local is_pick = gui.pick_node(self.node, action.x, action.y)
|
local is_pick = gui.pick_node(self.node, action.x, action.y)
|
||||||
if self.ext_zone then
|
if self.click_zone then
|
||||||
is_pick = is_pick and gui.pick_node(self.ext_zone, action.x, action.y)
|
is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
if is_pick then
|
if not 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
|
|
||||||
-- Can't interact, if touch outside of button
|
-- Can't interact, if touch outside of button
|
||||||
self.can_action = false
|
self.can_action = false
|
||||||
set_hover(self, false)
|
set_hover(self, false)
|
||||||
return false
|
return false
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -123,21 +143,21 @@ end
|
|||||||
function M.deactivate(self, is_animate, callback)
|
function M.deactivate(self, is_animate, callback)
|
||||||
self.disabled = true
|
self.disabled = true
|
||||||
if is_animate then
|
if is_animate then
|
||||||
local counter = 0
|
-- callback call three times in gui.animation
|
||||||
local clbk = function()
|
local clbk = helper.after(3, function()
|
||||||
counter = counter + 1
|
if callback then
|
||||||
if counter == 3 and callback then
|
|
||||||
callback(self.parent.parent)
|
callback(self.parent.parent)
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
|
|
||||||
ui_animate.color(self, self.node, M.DEFAULT_DEACTIVATE_COLOR,
|
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,
|
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,
|
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
|
else
|
||||||
gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR)
|
gui.set_color(self.node, M.DEFAULT_DEACTIVATE_COLOR)
|
||||||
gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE)
|
gui.set_scale(self.node, M.DEFAULT_DEACTIVATE_SCALE)
|
||||||
@ -150,24 +170,22 @@ end
|
|||||||
|
|
||||||
function M.activate(self, is_animate, callback)
|
function M.activate(self, is_animate, callback)
|
||||||
if is_animate then
|
if is_animate then
|
||||||
local counter = 0
|
-- callback call three times in gui.animation
|
||||||
local clbk = function()
|
local clbk = helper.after(3, function()
|
||||||
counter = counter + 1
|
|
||||||
if counter == 3 then
|
|
||||||
self.disabled = false
|
self.disabled = false
|
||||||
if callback then
|
if callback then
|
||||||
callback(self.parent.parent)
|
callback(self.parent.parent)
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
end
|
|
||||||
ui_animate.color(self, self.node, ui_animate.TINT_SHOW,
|
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,
|
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,
|
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
|
else
|
||||||
gui.set_color(self.node, ui_animate.TINT_SHOW)
|
gui.set_color(self.node, ui_animate.TINT_SHOW)
|
||||||
gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE)
|
gui.set_scale(self.node, M.DEFAULT_ACTIVATE_SCALE)
|
||||||
@ -178,10 +196,18 @@ function M.activate(self, is_animate, callback)
|
|||||||
end
|
end
|
||||||
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
|
--- Set additional node, what need to be clicked on button click
|
||||||
-- Used, if need setup, what button can be clicked only in special zone
|
-- Used, if need setup, what button can be clicked only in special zone
|
||||||
function M.set_ext_zone(self, zone)
|
function M.set_click_zone(self, zone)
|
||||||
self.ext_zone = helper.get_node(zone)
|
self.click_zone = helper.get_node(zone)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
50
druid/base/checkbox.lua
Normal file
50
druid/base/checkbox.lua
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
--- 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
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
49
druid/base/checkbox_group.lua
Normal file
49
druid/base/checkbox_group.lua
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
--- Checkboux group module
|
||||||
|
-- @module base.checkbox_group
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
|
||||||
|
local function on_checkbox_click(self, index)
|
||||||
|
if self.callback then
|
||||||
|
self.callback(self.parent.parent, index)
|
||||||
|
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, 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
|
@ -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 helper = require("druid.helper")
|
||||||
|
|
||||||
local M = {}
|
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)
|
function M.init(self, parent, element, in_row)
|
||||||
self.parent = helper.get_node(parent)
|
self.parent = helper.get_node(parent)
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
local data = require("druid.data")
|
--- Component to handle progress bars
|
||||||
|
-- @module base.progress
|
||||||
|
|
||||||
|
local const = require("druid.const")
|
||||||
local helper = require("druid.helper")
|
local helper = require("druid.helper")
|
||||||
local settings = require("druid.settings")
|
local settings = require("druid.settings")
|
||||||
local p_settings = settings.progress
|
local p_settings = settings.progress
|
||||||
@ -6,7 +9,7 @@ local p_settings = settings.progress
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
M.interest = {
|
M.interest = {
|
||||||
data.ON_UPDATE,
|
const.ON_UPDATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
local PROP_Y = "y"
|
local PROP_Y = "y"
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
--- Component to handle scroll content
|
||||||
|
-- @module base.scroll
|
||||||
|
|
||||||
local helper = require("druid.helper")
|
local helper = require("druid.helper")
|
||||||
local data = require("druid.data")
|
local const = require("druid.const")
|
||||||
local settings = require("druid.settings").scroll
|
local settings = require("druid.settings").scroll
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
@ -8,8 +11,8 @@ local SIDE_X = "x"
|
|||||||
local SIDE_Y = "y"
|
local SIDE_Y = "y"
|
||||||
|
|
||||||
M.interest = {
|
M.interest = {
|
||||||
data.ON_UPDATE,
|
const.ON_UPDATE,
|
||||||
data.ON_SWIPE,
|
const.ON_SWIPE,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Global on all scrolls
|
-- Global on all scrolls
|
||||||
@ -99,10 +102,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
local function get_zone_center(self)
|
local function get_zone_center(self)
|
||||||
local pos = vmath.vector3(self.pos)
|
return self.pos + self.center_offset
|
||||||
pos.x = pos.x + self.center_offset.x
|
|
||||||
pos.y = pos.y + self.center_offset.y
|
|
||||||
return pos
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function M.on_input(self, action_id, action)
|
function M.on_input(self, action_id, action)
|
||||||
if action_id ~= data.A_TOUCH then
|
if action_id ~= const.ACTION_TOUCH then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local inp = self.input
|
local inp = self.input
|
||||||
@ -289,18 +289,21 @@ function M.on_input(self, action_id, action)
|
|||||||
M.current_scroll = self
|
M.current_scroll = self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if M.current_scroll == self then
|
end
|
||||||
add_delta(self, action.dx, action.dy)
|
end
|
||||||
result = true
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
if action.released then
|
if action.released then
|
||||||
|
inp.touch = false
|
||||||
|
inp.side = false
|
||||||
if M.current_scroll == self then
|
if M.current_scroll == self then
|
||||||
M.current_scroll = nil
|
M.current_scroll = nil
|
||||||
inp.touch = false
|
|
||||||
inp.side = false
|
|
||||||
result = true
|
result = true
|
||||||
end
|
end
|
||||||
check_threshold(self)
|
check_threshold(self)
|
||||||
@ -310,8 +313,12 @@ function M.on_input(self, action_id, action)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Start scroll to point (x, y, z)
|
--- Start scroll to target point
|
||||||
function M.scroll_to(self, 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 b = self.border
|
||||||
local target = vmath.vector3(point)
|
local target = vmath.vector3(point)
|
||||||
target.x = helper.clamp(point.x - self.center_offset.x, b.x, b.z)
|
target.x = helper.clamp(point.x - self.center_offset.x, b.x, b.z)
|
||||||
@ -319,12 +326,18 @@ function M.scroll_to(self, point)
|
|||||||
|
|
||||||
cancel_animate(self)
|
cancel_animate(self)
|
||||||
|
|
||||||
self.animate = true
|
self.animate = not is_instant
|
||||||
gui.animate(self.node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, settings.ANIM_SPEED, 0, function()
|
|
||||||
self.animate = false
|
if is_instant then
|
||||||
self.target = target
|
self.target = target
|
||||||
set_pos(self, 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
|
end
|
||||||
|
|
||||||
|
|
||||||
|
93
druid/base/slider.lua
Normal file
93
druid/base/slider.lua
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
--- 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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
return M
|
@ -1,10 +1,14 @@
|
|||||||
local data = require("druid.data")
|
--- 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 settings = require("druid.settings")
|
||||||
local helper = require("druid.helper")
|
local helper = require("druid.helper")
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
M.interest = {
|
M.interest = {
|
||||||
data.ON_CHANGE_LANGUAGE,
|
const.ON_CHANGE_LANGUAGE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
local data = require("druid.data")
|
--- Component to handle GUI timers
|
||||||
|
-- @module base.timer
|
||||||
|
|
||||||
|
local const = require("druid.const")
|
||||||
local formats = require("druid.helper.formats")
|
local formats = require("druid.helper.formats")
|
||||||
local helper = require("druid.helper")
|
local helper = require("druid.helper")
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
M.interest = {
|
M.interest = {
|
||||||
data.ON_UPDATE
|
const.ON_UPDATE
|
||||||
}
|
}
|
||||||
|
|
||||||
local empty = function() end
|
local empty = function() end
|
||||||
|
|
||||||
|
|
||||||
function M.init(self, node, seconds_from, seconds_to, callback)
|
function M.init(self, node, seconds_from, seconds_to, callback)
|
||||||
self.node = helper.get_node(node)
|
self.node = helper.get_node(node)
|
||||||
seconds_from = math.max(seconds_from, 0)
|
seconds_from = math.max(seconds_from, 0)
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
|
--- Druid constants
|
||||||
|
-- @module constants
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
-- actions
|
-- Actions
|
||||||
|
M.ACTION_TOUCH = hash("touch")
|
||||||
M.A_TOUCH = hash("touch")
|
M.ACTION_TEXT = hash("text")
|
||||||
M.A_TEXT = hash("text")
|
M.ACTION_BACKSPACE = hash("backspace")
|
||||||
M.A_BACKSPACE = hash("backspace")
|
M.ACTION_ENTER = hash("enter")
|
||||||
M.A_ENTER = hash("enter")
|
M.ACTION_BACK = hash("back")
|
||||||
M.A_ANDR_BACK = hash("back")
|
|
||||||
|
|
||||||
M.RELEASED = "released"
|
M.RELEASED = "released"
|
||||||
M.PRESSED = "pressed"
|
M.PRESSED = "pressed"
|
||||||
|
|
||||||
--- interests
|
--- Interests
|
||||||
|
|
||||||
M.ON_MESSAGE = hash("on_message")
|
M.ON_MESSAGE = hash("on_message")
|
||||||
M.ON_UPDATE = hash("on_update")
|
M.ON_UPDATE = hash("on_update")
|
||||||
|
|
||||||
-- input
|
-- Input
|
||||||
M.ON_SWIPE = hash("on_swipe")
|
M.ON_SWIPE = hash("on_swipe")
|
||||||
M.ON_INPUT = hash("on_input")
|
M.ON_INPUT = hash("on_input")
|
||||||
|
|
||||||
M.ui_input = {
|
M.ui_input = {
|
||||||
[M.ON_SWIPE] = true,
|
[M.ON_SWIPE] = true,
|
||||||
[M.ON_INPUT] = true
|
[M.ON_INPUT] = true
|
||||||
|
|
||||||
}
|
}
|
||||||
-- ui messages
|
|
||||||
|
-- UI messages
|
||||||
M.ON_CHANGE_LANGUAGE = hash("on_change_language")
|
M.ON_CHANGE_LANGUAGE = hash("on_change_language")
|
||||||
M.ON_LAYOUT_CHANGED = hash("on_layout_changed")
|
M.ON_LAYOUT_CHANGED = hash("on_layout_changed")
|
||||||
|
|
@ -1,4 +1,10 @@
|
|||||||
local data = require("druid.data")
|
--- 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 const = require("druid.const")
|
||||||
local druid_input = require("druid.helper.druid_input")
|
local druid_input = require("druid.helper.druid_input")
|
||||||
local settings = require("druid.settings")
|
local settings = require("druid.settings")
|
||||||
|
|
||||||
@ -7,9 +13,11 @@ local M = {}
|
|||||||
local log = settings.log
|
local log = settings.log
|
||||||
local _fct_metatable = {}
|
local _fct_metatable = {}
|
||||||
|
|
||||||
|
--- Basic components
|
||||||
M.comps = {
|
M.comps = {
|
||||||
button = require("druid.base.button"),
|
button = require("druid.base.button"),
|
||||||
android_back = require("druid.base.android_back"),
|
back_handler = require("druid.base.back_handler"),
|
||||||
|
blocker = require("druid.base.blocker"),
|
||||||
text = require("druid.base.text"),
|
text = require("druid.base.text"),
|
||||||
timer = require("druid.base.timer"),
|
timer = require("druid.base.timer"),
|
||||||
progress = require("druid.base.progress"),
|
progress = require("druid.base.progress"),
|
||||||
@ -17,6 +25,8 @@ M.comps = {
|
|||||||
scroll = require("druid.base.scroll"),
|
scroll = require("druid.base.scroll"),
|
||||||
checkbox = require("druid.base.checkbox"),
|
checkbox = require("druid.base.checkbox"),
|
||||||
radio_group = require("druid.base.radio_group"),
|
radio_group = require("druid.base.radio_group"),
|
||||||
|
checkbox_group = require("druid.base.checkbox_group"),
|
||||||
|
slider = require("druid.base.slider"),
|
||||||
|
|
||||||
progress_rich = require("druid.rich.progress_rich"),
|
progress_rich = require("druid.rich.progress_rich"),
|
||||||
}
|
}
|
||||||
@ -33,6 +43,9 @@ local function register_basic_components()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Register external module
|
||||||
|
-- @tparam string name module name
|
||||||
|
-- @tparam table module lua table with module
|
||||||
function M.register(name, module)
|
function M.register(name, module)
|
||||||
-- TODO: Find better solution to creating elements?
|
-- TODO: Find better solution to creating elements?
|
||||||
_fct_metatable["new_" .. name] = function(self, ...)
|
_fct_metatable["new_" .. name] = function(self, ...)
|
||||||
@ -78,7 +91,7 @@ local function create(self, module)
|
|||||||
end
|
end
|
||||||
self[v][#self[v] + 1] = instance
|
self[v][#self[v] + 1] = instance
|
||||||
|
|
||||||
if data.ui_input[v] then
|
if const.ui_input[v] then
|
||||||
input_init(self)
|
input_init(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -122,7 +135,7 @@ end
|
|||||||
|
|
||||||
--- Called on_message
|
--- Called on_message
|
||||||
function _fct_metatable.on_message(self, message_id, message, sender)
|
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
|
if specific_ui_message then
|
||||||
local array = self[message_id]
|
local array = self[message_id]
|
||||||
if array then
|
if array then
|
||||||
@ -133,7 +146,7 @@ function _fct_metatable.on_message(self, message_id, message, sender)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local array = self[data.ON_MESSAGE]
|
local array = self[const.ON_MESSAGE]
|
||||||
if array then
|
if array then
|
||||||
for i = 1, #array do
|
for i = 1, #array do
|
||||||
array[i]:on_message(message_id, message, sender)
|
array[i]:on_message(message_id, message, sender)
|
||||||
@ -144,10 +157,10 @@ end
|
|||||||
|
|
||||||
|
|
||||||
local function notify_input_on_swipe(self)
|
local function notify_input_on_swipe(self)
|
||||||
if self[data.ON_INPUT] then
|
if self[const.ON_INPUT] then
|
||||||
local len = #self[data.ON_INPUT]
|
local len = #self[const.ON_INPUT]
|
||||||
for i = len, 1, -1 do
|
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
|
if comp.on_swipe then
|
||||||
comp:on_swipe()
|
comp:on_swipe()
|
||||||
end
|
end
|
||||||
@ -171,7 +184,7 @@ end
|
|||||||
|
|
||||||
--- Called ON_INPUT
|
--- Called ON_INPUT
|
||||||
function _fct_metatable.on_input(self, action_id, action)
|
function _fct_metatable.on_input(self, action_id, action)
|
||||||
local array = self[data.ON_SWIPE]
|
local array = self[const.ON_SWIPE]
|
||||||
if array then
|
if array then
|
||||||
local v, result
|
local v, result
|
||||||
local len = #array
|
local len = #array
|
||||||
@ -184,7 +197,7 @@ function _fct_metatable.on_input(self, action_id, action)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
array = self[data.ON_INPUT]
|
array = self[const.ON_INPUT]
|
||||||
if array then
|
if array then
|
||||||
local v
|
local v
|
||||||
local len = #array
|
local len = #array
|
||||||
@ -202,7 +215,7 @@ end
|
|||||||
|
|
||||||
--- Called on_update
|
--- Called on_update
|
||||||
function _fct_metatable.update(self, dt)
|
function _fct_metatable.update(self, dt)
|
||||||
local array = self[data.ON_UPDATE]
|
local array = self[const.ON_UPDATE]
|
||||||
if array then
|
if array then
|
||||||
for i = 1, #array do
|
for i = 1, #array do
|
||||||
array[i]:update(dt)
|
array[i]:update(dt)
|
||||||
|
@ -1,20 +1,81 @@
|
|||||||
|
--- Druid helper module
|
||||||
|
-- @module helper
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.centrate_text_with_icon(text_node, icon_node, offset_x)
|
--- Text node or icon node can be nil
|
||||||
offset_x = offset_x or 0
|
local function get_text_width(text_node)
|
||||||
local metr = gui.get_text_metrics_from_node(text_node)
|
if text_node then
|
||||||
local scl = gui.get_scale(text_node).x
|
local text_metrics = gui.get_text_metrics_from_node(text_node)
|
||||||
local pos = gui.get_position(text_node)
|
local text_scale = gui.get_scale(text_node).x
|
||||||
local scl_i = gui.get_scale(icon_node).x
|
return text_metrics.width * text_scale
|
||||||
local pos_i = gui.get_position(icon_node)
|
end
|
||||||
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
|
return 0
|
||||||
gui.set_position(text_node, pos)
|
end
|
||||||
pos_i.x = width/2 - icon_w + offset_x
|
|
||||||
gui.set_position(icon_node, pos_i)
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
-- 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
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -96,4 +157,5 @@ function M.get_pivot_offset(pivot)
|
|||||||
return pivots[pivot]
|
return pivots[pivot]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return M
|
return M
|
@ -1,3 +1,6 @@
|
|||||||
|
--- Druid helper module for animating GUI nodes
|
||||||
|
-- @module helper.animate
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local PROP_SCALE = gui.PROP_SCALE
|
local PROP_SCALE = gui.PROP_SCALE
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
--- Druid inner module to acquire/release input
|
||||||
|
-- @module helper.input
|
||||||
|
-- @local
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local ADD_FOCUS = hash("acquire_input_focus")
|
local ADD_FOCUS = hash("acquire_input_focus")
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
|
--- Druid module with utils on string formats
|
||||||
|
-- @module helper.formats
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local ZERO = "0"
|
local ZERO = "0"
|
||||||
|
|
||||||
-- Return number with zero number prefix
|
--- Return number with zero number prefix
|
||||||
-- @param num - number for conversion
|
-- @param num number for conversion
|
||||||
-- @param count - count of numerals
|
-- @param count count of numerals
|
||||||
-- @return string with need count of zero (1,3) -> 001
|
-- @return string with need count of zero (1,3) -> 001
|
||||||
function M.add_prefix_zeros(num, count)
|
function M.add_prefix_zeros(num, count)
|
||||||
local result = tostring(num)
|
local result = tostring(num)
|
||||||
@ -15,8 +18,8 @@ function M.add_prefix_zeros(num, count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Convert seconds to string minutes:seconds
|
--- Convert seconds to string minutes:seconds
|
||||||
-- @param num - number of seconds
|
-- @param num number of seconds
|
||||||
-- @return string minutes:seconds
|
-- @return string minutes:seconds
|
||||||
function M.second_string_min(sec)
|
function M.second_string_min(sec)
|
||||||
local mins = math.floor(sec / 60)
|
local mins = math.floor(sec / 60)
|
||||||
@ -25,11 +28,11 @@ function M.second_string_min(sec)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Interpolate string with named Parameters in Table
|
--- Interpolate string with named Parameters in Table
|
||||||
-- @param s - string for interpolate
|
-- @param s string for interpolate
|
||||||
-- @param tab - table with parameters
|
-- @param tab table with parameters
|
||||||
-- @return string with replaced 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))
|
return (s:gsub('($%b{})', function(w) return tab[w:sub(3, -2)] or w end))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
--- Druid settings file
|
||||||
|
-- @module settings
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
-- TODO: to JSON?
|
||||||
M.is_debug = false
|
M.is_debug = false
|
||||||
|
|
||||||
M.button = {
|
M.button = {
|
||||||
IS_HOVER = true,
|
IS_HOVER = true,
|
||||||
IS_HOLD = true,
|
IS_HOLD = true,
|
||||||
@ -33,13 +36,13 @@ M.scroll = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function M.get_text(name)
|
function M.get_text(name)
|
||||||
-- override to get text for localized text
|
-- override to get text for localized text
|
||||||
return "locales not inited"
|
return "[Druid]: locales not inited"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function M.play_sound(name)
|
function M.play_sound(name)
|
||||||
-- override to play sound with name
|
-- override to play sound with name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user