Merge pull request #275 from Insality/update

Prepare for release 12
This commit is contained in:
Maksim Tuprikov
2024-10-17 01:07:21 +03:00
committed by GitHub
103 changed files with 4078 additions and 13492 deletions

View File

@@ -17,7 +17,7 @@ jobs:
- name: Build && Run - name: Build && Run
run: | run: |
deployer_url="https://raw.githubusercontent.com/Insality/defold-deployer/1/deployer.sh" deployer_url="https://raw.githubusercontent.com/Insality/defold-deployer/1/deployer.sh"
curl -s ${deployer_url} | bash -s lbd --headless --settings ./unit_test.txt curl -s ${deployer_url} | bash -s lbd --headless --settings ./test/test.ini
- name: Upload test report - name: Upload test report
run: bash <(curl -s https://codecov.io/bash) run: bash <(curl -s https://codecov.io/bash)

4
.gitignore vendored
View File

@@ -10,4 +10,8 @@ Thumbs.db
builtins builtins
dist dist
deployer_version_settings.txt deployer_version_settings.txt
.deployer_cache .deployer_cache
bob*.jar
manifest.private.der
manifest.public.der

View File

@@ -1,56 +0,0 @@
std = "max"
files['.luacheckrc'].global = false
unused_args = false
max_code_line_length = 120
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",
"html5",
"describe",
"before",
"after",
"it",
}

38
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,38 @@
{
"Lua.diagnostics.globals": [
"init",
"final",
"update",
"on_message",
"on_input",
"describe",
"before",
"after",
"it",
"utf8",
"defos",
"clipboard",
"editor"
],
"Lua.workspace.checkThirdParty": false,
"Lua.diagnostics.neededFileStatus": {
"undefined-field": "Any",
"assign-type-mismatch": "Any",
"missing-return": "Any",
"missing-fields": "Any",
"return-type-mismatch": "Any",
"lowercase-global": "Any"
},
"Lua.workspace.ignoreDir": [
".vscode",
"test/tests/*.lua",
"utils/annotations_manual.lua"
],
"Lua.runtime.pathStrict": true,
"Lua.diagnostics.libraryFiles": "Enable",
"Lua.runtime.version": "Lua 5.1",
"Lua.workspace.library": [
"~/Library/Application Support/Code/User/globalStorage/astronachos.defold",
"~/Library/Application Support/Code/User/workspaceStorage/72e25b7e0fdc873ee6f7baa61edbd6b1/astronachos.defold"
]
}

View File

@@ -1,11 +1,11 @@
[![](media/druid_logo.png)](https://insality.github.io/druid/) [![](media/druid_logo.png)](https://insality.github.io/druid/)
[![Github-sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/insality) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/insality) [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/insality) [![GitHub release (latest by date)](https://img.shields.io/github/v/tag/insality/druid?style=for-the-badge&label=Release)](https://github.com/Insality/druid/tags)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/insality/druid/ci-workflow.yml?branch=master&style=for-the-badge)](https://github.com/Insality/druid/actions)
[![codecov](https://img.shields.io/codecov/c/github/Insality/druid?style=for-the-badge)](https://codecov.io/gh/Insality/druid)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/insality/druid)](https://github.com/Insality/druid/releases) [![Github-sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/insality) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/insality) [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/insality)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/insality/druid/ci-workflow.yml?branch=master)](https://github.com/Insality/druid/actions)
[![codecov](https://codecov.io/gh/Insality/druid/branch/master/graph/badge.svg)](https://codecov.io/gh/Insality/druid)
**Druid** - powerful **Defold** component UI framework that empowers developers to create stunning and customizable GUIs by leveraging a wide range of embedded components or effortlessly designing their own game-specific components. **Druid** - powerful **Defold** component UI framework that empowers developers to create stunning and customizable GUIs by leveraging a wide range of embedded components or effortlessly designing their own game-specific components.
@@ -17,18 +17,26 @@ Try the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Dr
To integrate the **Druid** extension into your own project, add this project as a [dependency](https://www.defold.com/manuals/libraries/) in your **Defold** game. Open your `game.project` file and add the following line to the dependencies field under the project section: To integrate the **Druid** extension into your own project, add this project as a [dependency](https://www.defold.com/manuals/libraries/) in your **Defold** game. Open your `game.project` file and add the following line to the dependencies field under the project section:
**Druid v0.11.0** **Druid v0.12.0**
> [https://github.com/Insality/druid/archive/refs/tags/0.11.0.zip](https://github.com/Insality/druid/archive/refs/tags/0.11.0.zip) > [https://github.com/Insality/druid/archive/refs/tags/0.12.0.zip](https://github.com/Insality/druid/archive/refs/tags/0.12.0.zip)
Here is a list of [all releases](https://github.com/Insality/druid/releases). Here is a list of [all releases](https://github.com/Insality/druid/releases).
Size: **67.16 KB**
> The size metrics exlcude the extended components, which are including only on demand. ### Library Size
> **Note:** The library size is calculated based on the build report per platform. The extended components are exlcuded, which are including only on demand.
| Platform | Library Size |
| ---------------- | ------------- |
| HTML5 | **38.96 KB** |
| Desktop / Mobile | **65.97 KB** |
### Input Bindings ### Input Bindings
**Druid** utilizes the `/builtins/input/all.input_binding` input bindings. For custom input bindings, refer to the Input Binding section in the **_[Advanced Setup](docs_md/advanced-setup.md#input-bindings)_**.
**Druid** utilizes the `/builtins/input/all.input_binding` input bindings. Either use this file for your project by setting the `Runtime -> Input -> Game Binding` field in the `game.project` input section to `/builtins/input/all.input_binding`, or add the specific bindings you need to your game's input binding file. For custom input bindings, refer to the Input Binding section in the [Advanced Setup](https://github.com/Insality/druid/blob/master/docs_md/advanced-setup.md#input-bindings).
## Usage ## Usage
@@ -140,7 +148,7 @@ druid.register("data_list", data_list)
| **[Slider](https://insality.github.io/druid/modules/Slider.html)** | Logic over GUI Node. Handle draggable node with position restrictions. | [Slider Example](https://insality.github.io/druid/druid/?example=general_sliders) | <img src="media/preview/slider.gif" width="200" height="100"> | | **[Slider](https://insality.github.io/druid/modules/Slider.html)** | Logic over GUI Node. Handle draggable node with position restrictions. | [Slider Example](https://insality.github.io/druid/druid/?example=general_sliders) | <img src="media/preview/slider.gif" width="200" height="100"> |
| **[Timer](https://insality.github.io/druid/modules/Timer.html)** | Logic over GUI Text. Handle basic timer functions. | ❌ | <img src="media/preview/timer.gif" width="200" height="100"> | | **[Timer](https://insality.github.io/druid/modules/Timer.html)** | Logic over GUI Text. Handle basic timer functions. | ❌ | <img src="media/preview/timer.gif" width="200" height="100"> |
| **[Hotkey](https://insality.github.io/druid/modules/Hotkey.html)** | Allow to set callbacks for keyboard hotkeys with key modificators. | [Hotkey Example](https://insality.github.io/druid/druid/?example=general_hotkey) | <img src="media/preview/hotkey.gif" width="200" height="100"> | | **[Hotkey](https://insality.github.io/druid/modules/Hotkey.html)** | Allow to set callbacks for keyboard hotkeys with key modificators. | [Hotkey Example](https://insality.github.io/druid/druid/?example=general_hotkey) | <img src="media/preview/hotkey.gif" width="200" height="100"> |
| **[Layout](https://insality.github.io/druid/modules/Layout.html)** | Logic over GUI Node. Handle node size depends on layout mode and screen aspect ratio. Contains helpers to build more complex UI layout. | [Layout Example](https://insality.github.io/druid/druid/?example=general_layout) | <img src="media/preview/layout.gif" width="200" height="100"> | | **[Layout](https://insality.github.io/druid/modules/Layout.html)** | Logic over GUI Node. Arrange nodes inside layout node with margin/paddings settings. | [Layout Example](https://insality.github.io/druid/druid/?example=general_layout) | <img src="media/preview/layout.gif" width="200" height="100"> |
For a complete overview, see: **_[components.md](docs_md/01-components.md)_**. For a complete overview, see: **_[components.md](docs_md/01-components.md)_**.
@@ -173,8 +181,6 @@ Each example page provides a direct link to the corresponding example code, maki
Or refer directly to the [**example folder**](https://github.com/Insality/druid/tree/develop/example) for code examples demonstrating how to use **Druid**. Or refer directly to the [**example folder**](https://github.com/Insality/druid/tree/develop/example) for code examples demonstrating how to use **Druid**.
If you want to see examples of GUIs created with Druid, please refer to the [game_examples.md](docs_md/game_examples.md) file.
## Documentation ## Documentation
To better understand **Druid**, read the following documentation: To better understand **Druid**, read the following documentation:

View File

@@ -4,7 +4,6 @@ description='Documentation for Druid Framework'
file={"./druid", file={"./druid",
exclude = { exclude = {
"./druid/styles/", "./druid/styles/",
"./druid/system/middleclass.lua",
"./druid/templates/", "./druid/templates/",
"./druid/annotations.lua", "./druid/annotations.lua",
"./druid/custom/rich_text/module", "./druid/custom/rich_text/module",

View File

@@ -17,3 +17,4 @@ date,sha,version,build_size,build_time,platform,mode,is_cache_using,commits_coun
2023-08-05T16:31:19Z,37fff52aa59feb20f761ef4d340d9f677743d54b,0.11.693,2456,43,js-web,release,true,693 2023-08-05T16:31:19Z,37fff52aa59feb20f761ef4d340d9f677743d54b,0.11.693,2456,43,js-web,release,true,693
2023-08-05T16:41:25Z,d7dd4a86b81d73d345ad7e136de9c2c488bc4d8b,0.11.694,2452,43,js-web,release,true,694 2023-08-05T16:41:25Z,d7dd4a86b81d73d345ad7e136de9c2c488bc4d8b,0.11.694,2452,43,js-web,release,true,694
2023-10-20T08:23:33Z,9132dc477b645d674ec21efbfcf85f48ef0ea8a6,0.11.718,2544,47,js-web,release,true,718 2023-10-20T08:23:33Z,9132dc477b645d674ec21efbfcf85f48ef0ea8a6,0.11.718,2544,47,js-web,release,true,718
2024-10-15T16:54:05Z,ea80c874f6c0ea175b317d01ac45c567db9179c7,0.11.0,1840,24,js-web,release,true,796
1 date sha version build_size build_time platform mode is_cache_using commits_count
17 2023-08-05T16:31:19Z 37fff52aa59feb20f761ef4d340d9f677743d54b 0.11.693 2456 43 js-web release true 693
18 2023-08-05T16:41:25Z d7dd4a86b81d73d345ad7e136de9c2c488bc4d8b 0.11.694 2452 43 js-web release true 694
19 2023-10-20T08:23:33Z 9132dc477b645d674ec21efbfcf85f48ef0ea8a6 0.11.718 2544 47 js-web release true 718
20 2024-10-15T16:54:05Z ea80c874f6c0ea175b317d01ac45c567db9179c7 0.11.0 1840 24 js-web release true 796

View File

@@ -147,9 +147,8 @@ local back_handler = self.druid:new_back_handler(callback, [params])
<ul> <ul>
<li><span class="parameter">params</span> <li><span class="parameter">params</span>
<span class="types"><span class="type">any</span></span> <span class="types"><span class="type">any</span> or <span class="type">nil</span></span>
(<em>optional</em>)
</li> </li>
</ul> </ul>

View File

@@ -106,7 +106,7 @@ return AwesomeComponent
<td class="summary">Context used as first arg in all Druid events</td> <td class="summary">Context used as first arg in all Druid events</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#get_druid">get_druid(self)</a></td> <td class="name" nowrap><a href="#get_druid">get_druid(self, template, nodes)</a></td>
<td class="summary">Get Druid instance for inner component creation.</td> <td class="summary">Get Druid instance for inner component creation.</td>
</tr> </tr>
<tr> <tr>
@@ -226,7 +226,7 @@ return AwesomeComponent
</dd> </dd>
<dt> <dt>
<a name = "get_druid"></a> <a name = "get_druid"></a>
<strong>get_druid(self)</strong> <strong>get_druid(self, template, nodes)</strong>
</dt> </dt>
<dd> <dd>
Get Druid instance for inner component creation. Get Druid instance for inner component creation.
@@ -238,6 +238,14 @@ return AwesomeComponent
<span class="types"><span class="type">BaseComponent</span></span> <span class="types"><span class="type">BaseComponent</span></span>
<a href="../modules/BaseComponent.html#">BaseComponent</a> <a href="../modules/BaseComponent.html#">BaseComponent</a>
</li> </li>
<li><span class="parameter">template</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
The template name
</li>
<li><span class="parameter">nodes</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
The nodes table
</li>
</ul> </ul>
<h3>Returns:</h3> <h3>Returns:</h3>

View File

@@ -97,7 +97,7 @@
print(&quot;Also the button component is passed in callback params&quot;) print(&quot;Also the button component is passed in callback params&quot;)
end end
local custom_args = &quot;any variable to pass inside callback&quot; local custom_args = &quot;Any variable to pass inside callback&quot;
local button = self.druid:new_button(&quot;button_name&quot;, on_button_click, custom_args) local button = self.druid:new_button(&quot;button_name&quot;, on_button_click, custom_args)
</pre> </pre>
</ul> </ul>
@@ -153,7 +153,7 @@ local button = self.druid:new_button(&quot;button_name&quot;, on_button_click, c
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#click_zone">click_zone</a></td> <td class="name" nowrap><a href="#click_zone">click_zone</a></td>
<td class="summary">Additional button click area, defined by another GUI Node</td> <td class="summary">Additional button click area, defined by another GUI node</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#hover">hover</a></td> <td class="name" nowrap><a href="#hover">hover</a></td>
@@ -360,7 +360,7 @@ local button = self.druid:new_button(&quot;button_name&quot;, on_button_click, c
<a href="../modules/Button.html#">Button</a> <a href="../modules/Button.html#">Button</a>
</li> </li>
<li><span class="parameter">zone</span> <li><span class="parameter">zone</span>
<span class="types"><a class="type" href="../modules/Button.html#node">node</a> or <span class="type">nil</span></span> <span class="types"><a class="type" href="../modules/Button.html#node">node</a>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Gui node Gui node
</li> </li>
</ul> </ul>
@@ -433,7 +433,7 @@ button:set_enabled(<span class="keyword">true</span>)</pre>
<a href="../modules/Button.html#">Button</a> <a href="../modules/Button.html#">Button</a>
</li> </li>
<li><span class="parameter">key</span> <li><span class="parameter">key</span>
<span class="types"><span class="type">hash</span></span> <span class="types"><span class="type">hash</span> or <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The action_id of the input key The action_id of the input key
</li> </li>
</ul> </ul>
@@ -508,19 +508,16 @@ button:set_enabled(<span class="keyword">true</span>)</pre>
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">LONGTAP_TIME</span> <li><span class="parameter">LONGTAP_TIME</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Minimum time to trigger on_hold_callback Minimum time to trigger on_hold_callback. Default: 0.4
(<em>default</em> 0.4)
</li> </li>
<li><span class="parameter">AUTOHOLD_TRIGGER</span> <li><span class="parameter">AUTOHOLD_TRIGGER</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Maximum hold time to trigger button release while holding Maximum hold time to trigger button release while holding. Default: 0.8
(<em>default</em> 0.8)
</li> </li>
<li><span class="parameter">DOUBLETAP_TIME</span> <li><span class="parameter">DOUBLETAP_TIME</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Time between double taps Time between double taps. Default: 0.4
(<em>default</em> 0.4)
</li> </li>
<li><span class="parameter">on_click</span> <li><span class="parameter">on_click</span>
<span class="types"><span class="type">function</span></span> <span class="types"><span class="type">function</span></span>
@@ -565,9 +562,8 @@ button:set_enabled(<span class="keyword">true</span>)</pre>
<ul> <ul>
<li><span class="parameter">anim_node</span> <li><span class="parameter">anim_node</span>
<span class="types"><a class="type" href="../modules/Button.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Button.html#node">node</a> or <span class="type">nil</span></span>
Default node
(<em>default</em> node)
</li> </li>
</ul> </ul>
@@ -581,14 +577,13 @@ button:set_enabled(<span class="keyword">true</span>)</pre>
<strong>click_zone</strong> <strong>click_zone</strong>
</dt> </dt>
<dd> <dd>
Additional button click area, defined by another GUI Node Additional button click area, defined by another GUI node
<ul> <ul>
<li><span class="parameter">click_zone</span> <li><span class="parameter">click_zone</span>
<span class="types"><a class="type" href="../modules/Button.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Button.html#node">node</a> or <span class="type">nil</span></span>
(<em>optional</em>)
</li> </li>
</ul> </ul>

View File

@@ -87,7 +87,7 @@
<td class="summary">Return checkbox state</td> <td class="summary">Return checkbox state</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, node, callback[, click_node=node[, initial_state=false]])</a></td> <td class="name" nowrap><a href="#init">init(self, node, callback, click_node, initial_state)</a></td>
<td class="summary">The <a href="../modules/Checkbox.html#">Checkbox</a> constructor</td> <td class="summary">The <a href="../modules/Checkbox.html#">Checkbox</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -158,7 +158,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, node, callback[, click_node=node[, initial_state=false]])</strong> <strong>init(self, node, callback, click_node, initial_state)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/Checkbox.html#">Checkbox</a> constructor The <a href="../modules/Checkbox.html#">Checkbox</a> constructor
@@ -179,14 +179,12 @@
Checkbox callback Checkbox callback
</li> </li>
<li><span class="parameter">click_node</span> <li><span class="parameter">click_node</span>
<span class="types"><a class="type" href="../modules/Checkbox.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Checkbox.html#node">node</a> or <span class="type">nil</span></span>
Trigger node, by default equals to node Trigger node, by default equals to node. Default: node
(<em>default</em> node)
</li> </li>
<li><span class="parameter">initial_state</span> <li><span class="parameter">initial_state</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
The initial state of checkbox, default - false The initial state of checkbox, default - false
(<em>default</em> false)
</li> </li>
</ul> </ul>
@@ -289,9 +287,8 @@
<ul> <ul>
<li><span class="parameter">click_node</span> <li><span class="parameter">click_node</span>
<span class="types"><a class="type" href="../modules/Checkbox.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Checkbox.html#node">node</a> or <span class="type">nil</span></span>
(<em>default</em> node)
</li> </li>
</ul> </ul>

View File

@@ -86,7 +86,7 @@
<td class="summary">Return checkbox group state</td> <td class="summary">Return checkbox group state</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, nodes, callback[, click_nodes=node])</a></td> <td class="name" nowrap><a href="#init">init(self, nodes, callback, click_nodes)</a></td>
<td class="summary">The <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> constructor</td> <td class="summary">The <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -142,7 +142,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, nodes, callback[, click_nodes=node])</strong> <strong>init(self, nodes, callback, click_nodes)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> constructor The <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> constructor
@@ -163,9 +163,8 @@
Checkbox callback Checkbox callback
</li> </li>
<li><span class="parameter">click_nodes</span> <li><span class="parameter">click_nodes</span>
<span class="types"><span class="type">node[]</span></span> <span class="types"><span class="type">node[]</span> or <span class="type">nil</span></span>
Array of trigger nodes, by default equals to nodes Array of trigger nodes, by default equals to nodes
(<em>default</em> node)
</li> </li>
</ul> </ul>

View File

@@ -83,6 +83,10 @@
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
<table class="function_list"> <table class="function_list">
<tr>
<td class="name" nowrap><a href="#add">add(self, data, index, shift_policy)</a></td>
<td class="summary">Add element to DataList.</td>
</tr>
<tr> <tr>
<td class="name" nowrap><a href="#clear">clear(self)</a></td> <td class="name" nowrap><a href="#clear">clear(self)</a></td>
<td class="summary">Clear the DataList and refresh visuals</td> <td class="summary">Clear the DataList and refresh visuals</td>
@@ -100,22 +104,10 @@
<td class="summary">Return current data from DataList component</td> <td class="summary">Return current data from DataList component</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#get_first_index">get_first_index(self)</a></td>
<td class="summary">Return first index from data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#get_index">get_index(self, data)</a></td> <td class="name" nowrap><a href="#get_index">get_index(self, data)</a></td>
<td class="summary">Return index for data value</td> <td class="summary">Return index for data value</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#get_last_index">get_last_index(self)</a></td>
<td class="summary">Return last index from data</td>
</tr>
<tr>
<td class="name" nowrap><a href="#get_length">get_length(self)</a></td>
<td class="summary">Return amount of data</td>
</tr>
<tr>
<td class="name" nowrap><a href="#init">init(self, scroll, grid, create_function)</a></td> <td class="name" nowrap><a href="#init">init(self, scroll, grid, create_function)</a></td>
<td class="summary">The <a href="../modules/DataList.html#">DataList</a> constructor</td> <td class="summary">The <a href="../modules/DataList.html#">DataList</a> constructor</td>
</tr> </tr>
@@ -124,6 +116,14 @@
<td class="summary">Druid System on_remove function</td> <td class="summary">Druid System on_remove function</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#remove">remove(self, index, shift_policy)</a></td>
<td class="summary">Remove element from DataList.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#remove_by_data">remove_by_data(self, data, shift_policy)</a></td>
<td class="summary">Remove element from DataList by data value.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#scroll_to_index">scroll_to_index(self, index)</a></td> <td class="name" nowrap><a href="#scroll_to_index">scroll_to_index(self, index)</a></td>
<td class="summary">Instant scroll to element with passed index</td> <td class="summary">Instant scroll to element with passed index</td>
</tr> </tr>
@@ -131,6 +131,10 @@
<td class="name" nowrap><a href="#set_data">set_data(self, data)</a></td> <td class="name" nowrap><a href="#set_data">set_data(self, data)</a></td>
<td class="summary">Set new data set for DataList component</td> <td class="summary">Set new data set for DataList component</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#set_use_cache">set_use_cache(self, is_use_cache)</a></td>
<td class="summary">Set refresh function for DataList component</td>
</tr>
</table> </table>
<h2><a href="#Fields">Fields</a></h2> <h2><a href="#Fields">Fields</a></h2>
<table class="function_list"> <table class="function_list">
@@ -140,7 +144,7 @@
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#last_index">last_index</a></td> <td class="name" nowrap><a href="#last_index">last_index</a></td>
<td class="summary">The current visual last data index</td> <td class="summary">The current last index of visual elements</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_element_add">on_element_add</a></td> <td class="name" nowrap><a href="#on_element_add">on_element_add</a></td>
@@ -164,7 +168,7 @@
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#top_index">top_index</a></td> <td class="name" nowrap><a href="#top_index">top_index</a></td>
<td class="summary">The current visual top data index</td> <td class="summary">The current top index of visual elements</td>
</tr> </tr>
</table> </table>
@@ -175,6 +179,39 @@
<h2 class="section-header "><a name="Functions"></a>Functions</h2> <h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function"> <dl class="function">
<dt>
<a name = "add"></a>
<strong>add(self, data, index, shift_policy)</strong>
</dt>
<dd>
Add element to DataList. Currenly untested
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
<li><span class="parameter">data</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
</li>
<li><span class="parameter">index</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
</li>
<li><span class="parameter">shift_policy</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
The constant from const.SHIFT.*
</li>
</ul>
</dd>
<dt> <dt>
<a name = "clear"></a> <a name = "clear"></a>
<strong>clear(self)</strong> <strong>clear(self)</strong>
@@ -276,27 +313,6 @@
</dd>
<dt>
<a name = "get_first_index"></a>
<strong>get_first_index(self)</strong>
</dt>
<dd>
Return first index from data. It not always equals to 1
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "get_index"></a> <a name = "get_index"></a>
@@ -322,48 +338,6 @@
</dd>
<dt>
<a name = "get_last_index"></a>
<strong>get_last_index(self)</strong>
</dt>
<dd>
Return last index from data
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
</ul>
</dd>
<dt>
<a name = "get_length"></a>
<strong>get_length(self)</strong>
</dt>
<dd>
Return amount of data
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
@@ -418,6 +392,64 @@
</dd>
<dt>
<a name = "remove"></a>
<strong>remove(self, index, shift_policy)</strong>
</dt>
<dd>
Remove element from DataList. Currenly untested
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
<li><span class="parameter">index</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
</li>
<li><span class="parameter">shift_policy</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
The constant from const.SHIFT.*
</li>
</ul>
</dd>
<dt>
<a name = "remove_by_data"></a>
<strong>remove_by_data(self, data, shift_policy)</strong>
</dt>
<dd>
Remove element from DataList by data value. Currenly untested
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
<li><span class="parameter">data</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
</li>
<li><span class="parameter">shift_policy</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
The constant from const.SHIFT.*
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "scroll_to_index"></a> <a name = "scroll_to_index"></a>
@@ -474,6 +506,37 @@
</dd>
<dt>
<a name = "set_use_cache"></a>
<strong>set_use_cache(self, is_use_cache)</strong>
</dt>
<dd>
Set refresh function for DataList component
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DataList</span></span>
<a href="../modules/DataList.html#">DataList</a>
</li>
<li><span class="parameter">is_use_cache</span>
<span class="types"><span class="type">boolean</span></span>
Use cache version of DataList. Requires make setup of components in on_element_add callback and clean in on_element_remove
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.data_list</span></span>
Current DataList instance
</ol>
</dd> </dd>
</dl> </dl>
<h2 class="section-header "><a name="Fields"></a>Fields</h2> <h2 class="section-header "><a name="Fields"></a>Fields</h2>
@@ -504,7 +567,7 @@
<strong>last_index</strong> <strong>last_index</strong>
</dt> </dt>
<dd> <dd>
The current visual last data index The current last index of visual elements
<ul> <ul>
@@ -624,7 +687,7 @@
<strong>top_index</strong> <strong>top_index</strong>
</dt> </dt>
<dd> <dd>
The current visual top data index The current top index of visual elements
<ul> <ul>

View File

@@ -129,16 +129,20 @@
<td class="summary">Is component now touching</td> <td class="summary">Is component now touching</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#node">node</a></td>
<td class="summary">Drag node</td>
</tr>
<tr>
<td class="name" nowrap><a href="#on_drag">on_drag</a></td> <td class="name" nowrap><a href="#on_drag">on_drag</a></td>
<td class="summary">on drag progress callback(self, dx, dy, total_x, total_y)</td> <td class="summary">on drag progress callback(self, dx, dy, total_x, total_y, touch)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_drag_end">on_drag_end</a></td> <td class="name" nowrap><a href="#on_drag_end">on_drag_end</a></td>
<td class="summary">Event on drag end callback(self, total_x, total_y)</td> <td class="summary">Event on drag end callback(self, total_x, total_y, touch)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_drag_start">on_drag_start</a></td> <td class="name" nowrap><a href="#on_drag_start">on_drag_start</a></td>
<td class="summary">Event on drag start callback(self)</td> <td class="summary">Event on drag start callback(self, touch)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_touch_end">on_touch_end</a></td> <td class="name" nowrap><a href="#on_touch_end">on_touch_end</a></td>
@@ -149,6 +153,14 @@
<td class="summary">Event on touch start callback(self)</td> <td class="summary">Event on touch start callback(self)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#screen_x">screen_x</a></td>
<td class="summary">Current touch x screen position</td>
</tr>
<tr>
<td class="name" nowrap><a href="#screen_y">screen_y</a></td>
<td class="summary">Current touch y screen position</td>
</tr>
<tr>
<td class="name" nowrap><a href="#touch_start_pos">touch_start_pos</a></td> <td class="name" nowrap><a href="#touch_start_pos">touch_start_pos</a></td>
<td class="summary">Touch start position</td> <td class="summary">Touch start position</td>
</tr> </tr>
@@ -184,7 +196,7 @@
<a href="../modules/Drag.html#">Drag</a> <a href="../modules/Drag.html#">Drag</a>
</li> </li>
<li><span class="parameter">node</span> <li><span class="parameter">node</span>
<span class="types"><span class="type">node</span></span> <span class="types"><a class="type" href="../modules/Drag.html#node">node</a></span>
GUI node to detect dragging GUI node to detect dragging
</li> </li>
<li><span class="parameter">on_drag_callback</span> <li><span class="parameter">on_drag_callback</span>
@@ -241,7 +253,7 @@
<a href="../modules/Drag.html#">Drag</a> <a href="../modules/Drag.html#">Drag</a>
</li> </li>
<li><span class="parameter">node</span> <li><span class="parameter">node</span>
<span class="types"><span class="type">node</span></span> <span class="types"><a class="type" href="../modules/Drag.html#node">node</a>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Gui node Gui node
</li> </li>
</ul> </ul>
@@ -293,14 +305,12 @@
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">DRAG_DEADZONE</span> <li><span class="parameter">DRAG_DEADZONE</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Distance in pixels to start dragging Distance in pixels to start dragging. Default: 10
(<em>default</em> 10)
</li> </li>
<li><span class="parameter">NO_USE_SCREEN_KOEF</span> <li><span class="parameter">NO_USE_SCREEN_KOEF</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If screen aspect ratio affects on drag values If screen aspect ratio affects on drag values. Default: false
(<em>default</em> false)
</li> </li>
</ul> </ul>
@@ -392,13 +402,33 @@
</dd>
<dt>
<a name = "node"></a>
<strong>node</strong>
</dt>
<dd>
Drag node
<ul>
<li><span class="parameter">node</span>
<span class="types"><a class="type" href="../modules/Drag.html#node">node</a></span>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "on_drag"></a> <a name = "on_drag"></a>
<strong>on_drag</strong> <strong>on_drag</strong>
</dt> </dt>
<dd> <dd>
on drag progress callback(self, dx, dy, total_x, total_y) on drag progress callback(self, dx, dy, total_x, total_y, touch)
<ul> <ul>
@@ -418,7 +448,7 @@
<strong>on_drag_end</strong> <strong>on_drag_end</strong>
</dt> </dt>
<dd> <dd>
Event on drag end callback(self, total_x, total_y) Event on drag end callback(self, total_x, total_y, touch)
<ul> <ul>
@@ -438,7 +468,7 @@
<strong>on_drag_start</strong> <strong>on_drag_start</strong>
</dt> </dt>
<dd> <dd>
Event on drag start callback(self) Event on drag start callback(self, touch)
<ul> <ul>
@@ -492,6 +522,46 @@
</dd>
<dt>
<a name = "screen_x"></a>
<strong>screen_x</strong>
</dt>
<dd>
Current touch x screen position
<ul>
<li><span class="parameter">screen_x</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "screen_y"></a>
<strong>screen_y</strong>
</dt>
<dd>
Current touch y screen position
<ul>
<li><span class="parameter">screen_y</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "touch_start_pos"></a> <a name = "touch_start_pos"></a>

View File

@@ -87,15 +87,23 @@
<td class="summary">Clear the all event handlers</td> <td class="summary">Clear the all event handlers</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#initialize">initialize(self, initial_callback)</a></td> <td class="name" nowrap><a href="#create">create(callback, callback_context)</a></td>
<td class="summary">DruidEvent constructor</td> <td class="summary">DruidEvent constructor</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#is_empty">is_empty(self)</a></td>
<td class="summary">Return true, if event not have handler</td>
</tr>
<tr>
<td class="name" nowrap><a href="#is_exist">is_exist(self)</a></td> <td class="name" nowrap><a href="#is_exist">is_exist(self)</a></td>
<td class="summary">Return true, if event have at lease one handler</td> <td class="summary">Return true, if event have at lease one handler</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#subscribe">subscribe(self, callback, context)</a></td> <td class="name" nowrap><a href="#is_subscribed">is_subscribed(self, callback, callback_context)</a></td>
<td class="summary">Check is event subscribed.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#subscribe">subscribe(self, callback, callback_context)</a></td>
<td class="summary">Subscribe callback on event</td> <td class="summary">Subscribe callback on event</td>
</tr> </tr>
<tr> <tr>
@@ -103,7 +111,7 @@
<td class="summary">Trigger the event and call all subscribed callbacks</td> <td class="summary">Trigger the event and call all subscribed callbacks</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#unsubscribe">unsubscribe(self, callback, context)</a></td> <td class="name" nowrap><a href="#unsubscribe">unsubscribe(self, callback, callback_context)</a></td>
<td class="summary">Unsubscribe callback on event</td> <td class="summary">Unsubscribe callback on event</td>
</tr> </tr>
</table> </table>
@@ -141,8 +149,8 @@
</dd> </dd>
<dt> <dt>
<a name = "initialize"></a> <a name = "create"></a>
<strong>initialize(self, initial_callback)</strong> <strong>create(callback, callback_context)</strong>
</dt> </dt>
<dd> <dd>
DruidEvent constructor DruidEvent constructor
@@ -150,14 +158,14 @@
<h3>Parameters:</h3> <h3>Parameters:</h3>
<ul> <ul>
<li><span class="parameter">self</span> <li><span class="parameter">callback</span>
<span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a>
</li>
<li><span class="parameter">initial_callback</span>
<span class="types"><span class="type">function</span> or <span class="type">nil</span></span> <span class="types"><span class="type">function</span> or <span class="type">nil</span></span>
Subscribe the callback on new event, if callback exist Subscribe the callback on new event, if callback exist
</li> </li>
<li><span class="parameter">callback_context</span>
<span class="types"><span class="type">any</span> or <span class="type">nil</span></span>
Additional context as first param to callback call
</li>
</ul> </ul>
@@ -167,7 +175,38 @@
<ul> <ul>
<pre class="example"><span class="keyword">local</span> Event = <span class="global">require</span>(<span class="string">"druid.event"</span>) <pre class="example"><span class="keyword">local</span> Event = <span class="global">require</span>(<span class="string">"druid.event"</span>)
... ...
<span class="keyword">local</span> event = Event(initial_callback)</pre> <span class="keyword">local</span> event = Event(callback)</pre>
</ul>
</dd>
<dt>
<a name = "is_empty"></a>
<strong>is_empty(self)</strong>
</dt>
<dd>
Return true, if event not have handler
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean</span></span>
True if event not have handlers
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> is_long_click_handler_not_exists = button.on_long_click:is_empty()</pre>
</ul> </ul>
</dd> </dd>
@@ -201,10 +240,45 @@
<pre class="example"><span class="keyword">local</span> is_long_click_handler_exists = button.on_long_click:is_exist()</pre> <pre class="example"><span class="keyword">local</span> is_long_click_handler_exists = button.on_long_click:is_exist()</pre>
</ul> </ul>
</dd>
<dt>
<a name = "is_subscribed"></a>
<strong>is_subscribed(self, callback, callback_context)</strong>
</dt>
<dd>
Check is event subscribed.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a>
</li>
<li><span class="parameter">callback</span>
<span class="types"><span class="type">function</span></span>
Callback itself
</li>
<li><span class="parameter">callback_context</span>
<span class="types"><span class="type">any</span> or <span class="type">nil</span></span>
Additional context as first param to callback call
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean,</span></span>
number|nil @Is event subscribed, return index of callback in event as second param
</ol>
</dd> </dd>
<dt> <dt>
<a name = "subscribe"></a> <a name = "subscribe"></a>
<strong>subscribe(self, callback, context)</strong> <strong>subscribe(self, callback, callback_context)</strong>
</dt> </dt>
<dd> <dd>
Subscribe callback on event Subscribe callback on event
@@ -220,12 +294,18 @@
<span class="types"><span class="type">function</span></span> <span class="types"><span class="type">function</span></span>
Callback itself Callback itself
</li> </li>
<li><span class="parameter">context</span> <li><span class="parameter">callback_context</span>
<span class="types"><span class="type">any</span> or <span class="type">nil</span></span> <span class="types"><span class="type">any</span> or <span class="type">nil</span></span>
Additional context as first param to callback call, usually it's self Additional context as first param to callback call, usually it's self
</li> </li>
</ul> </ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean</span></span>
True if callback was subscribed
</ol>
@@ -274,7 +354,7 @@ event:trigger(<span class="string">"Param1"</span>, <span class="string">"Param2
</dd> </dd>
<dt> <dt>
<a name = "unsubscribe"></a> <a name = "unsubscribe"></a>
<strong>unsubscribe(self, callback, context)</strong> <strong>unsubscribe(self, callback, callback_context)</strong>
</dt> </dt>
<dd> <dd>
Unsubscribe callback on event Unsubscribe callback on event
@@ -290,7 +370,7 @@ event:trigger(<span class="string">"Param1"</span>, <span class="string">"Param2
<span class="types"><span class="type">function</span></span> <span class="types"><span class="type">function</span></span>
Callback itself Callback itself
</li> </li>
<li><span class="parameter">context</span> <li><span class="parameter">callback_context</span>
<span class="types"><span class="type">any</span> or <span class="type">nil</span></span> <span class="types"><span class="type">any</span> or <span class="type">nil</span></span>
Additional context as first param to callback call Additional context as first param to callback call
</li> </li>

View File

@@ -142,10 +142,6 @@ end
<td class="summary">Call this in gui_script final function.</td> <td class="summary">Call this in gui_script final function.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#new">new(self, component, ...)</a></td>
<td class="summary">Create new component.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#new_back_handler">new_back_handler(self, callback, params)</a></td> <td class="name" nowrap><a href="#new_back_handler">new_back_handler(self, callback, params)</a></td>
<td class="summary">Create <a href="../modules/BackHandler.html#">BackHandler</a> component</td> <td class="summary">Create <a href="../modules/BackHandler.html#">BackHandler</a> component</td>
</tr> </tr>
@@ -162,7 +158,7 @@ end
<td class="summary">Create <a href="../modules/Checkbox.html#">Checkbox</a> component</td> <td class="summary">Create <a href="../modules/Checkbox.html#">Checkbox</a> component</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#new_checkbox_group">new_checkbox_group(self, nodes, callback[, click_nodes=node])</a></td> <td class="name" nowrap><a href="#new_checkbox_group">new_checkbox_group(self, nodes, callback, click_nodes)</a></td>
<td class="summary">Create <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> component</td> <td class="summary">Create <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> component</td>
</tr> </tr>
<tr> <tr>
@@ -182,7 +178,7 @@ end
<td class="summary">Create <a href="../modules/Hotkey.html#">Hotkey</a> component</td> <td class="summary">Create <a href="../modules/Hotkey.html#">Hotkey</a> component</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#new_hover">new_hover(self, node, on_hover_callback)</a></td> <td class="name" nowrap><a href="#new_hover">new_hover(self, node, on_hover_callback, on_mouse_hover_callback)</a></td>
<td class="summary">Create <a href="../modules/Hover.html#">Hover</a> component</td> <td class="summary">Create <a href="../modules/Hover.html#">Hover</a> component</td>
</tr> </tr>
<tr> <tr>
@@ -202,7 +198,7 @@ end
<td class="summary">Create <a href="../modules/Progress.html#">Progress</a> component</td> <td class="summary">Create <a href="../modules/Progress.html#">Progress</a> component</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#new_radio_group">new_radio_group(self, nodes, callback[, click_nodes=node])</a></td> <td class="name" nowrap><a href="#new_radio_group">new_radio_group(self, nodes, callback, click_nodes)</a></td>
<td class="summary">Create <a href="../modules/RadioGroup.html#">RadioGroup</a> component</td> <td class="summary">Create <a href="../modules/RadioGroup.html#">RadioGroup</a> component</td>
</tr> </tr>
<tr> <tr>
@@ -246,11 +242,11 @@ end
<td class="summary">Remove created component from Druid instance.</td> <td class="summary">Remove created component from Druid instance.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#set_blacklist">set_blacklist(self[, blacklist_components=nil])</a></td> <td class="name" nowrap><a href="#set_blacklist">set_blacklist(self, blacklist_components)</a></td>
<td class="summary">Set blacklist components for input processing.</td> <td class="summary">Set blacklist components for input processing.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#set_whitelist">set_whitelist(self[, whitelist_components=nil])</a></td> <td class="name" nowrap><a href="#set_whitelist">set_whitelist(self, whitelist_components)</a></td>
<td class="summary">Set whitelist components for input processing.</td> <td class="summary">Set whitelist components for input processing.</td>
</tr> </tr>
<tr> <tr>
@@ -286,41 +282,6 @@ end
</dd>
<dt>
<a name = "new"></a>
<strong>new(self, component, ...)</strong>
</dt>
<dd>
Create new component.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">DruidInstance</span></span>
</li>
<li><span class="parameter">component</span>
<span class="types"><span class="type">BaseComponent</span></span>
Component module
</li>
<li><span class="parameter">...</span>
<span class="types"><span class="type">any</span></span>
Other component params to pass it to component:init function
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">BaseComponent</span></span>
Component instance
</ol>
</dd> </dd>
<dt> <dt>
<a name = "new_back_handler"></a> <a name = "new_back_handler"></a>
@@ -411,11 +372,11 @@ end
Button callback Button callback
</li> </li>
<li><span class="parameter">params</span> <li><span class="parameter">params</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span> <span class="types"><span class="type">any</span> or <span class="type">nil</span></span>
Button callback params Button callback params
</li> </li>
<li><span class="parameter">anim_node</span> <li><span class="parameter">anim_node</span>
<span class="types"><span class="type">node</span> or <span class="type">nil</span></span> <span class="types"><span class="type">node</span>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Button anim node (node, if not provided) Button anim node (node, if not provided)
</li> </li>
</ul> </ul>
@@ -476,7 +437,7 @@ end
</dd> </dd>
<dt> <dt>
<a name = "new_checkbox_group"></a> <a name = "new_checkbox_group"></a>
<strong>new_checkbox_group(self, nodes, callback[, click_nodes=node])</strong> <strong>new_checkbox_group(self, nodes, callback, click_nodes)</strong>
</dt> </dt>
<dd> <dd>
Create <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> component Create <a href="../modules/CheckboxGroup.html#">CheckboxGroup</a> component
@@ -489,7 +450,7 @@ end
</li> </li>
<li><span class="parameter">nodes</span> <li><span class="parameter">nodes</span>
<span class="types"><span class="type">node[]</span></span> <span class="types"><span class="type">(node</span> or <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string)[]</a></span>
Array of gui node Array of gui node
</li> </li>
<li><span class="parameter">callback</span> <li><span class="parameter">callback</span>
@@ -497,9 +458,8 @@ end
Checkbox callback Checkbox callback
</li> </li>
<li><span class="parameter">click_nodes</span> <li><span class="parameter">click_nodes</span>
<span class="types"><span class="type">node[]</span></span> <span class="types"><span class="type">(node</span>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string)[]</a> or <span class="type">nil</span></span>
Array of trigger nodes, by default equals to nodes Array of trigger nodes, by default equals to nodes
(<em>default</em> node)
</li> </li>
</ul> </ul>
@@ -660,7 +620,7 @@ end
</dd> </dd>
<dt> <dt>
<a name = "new_hover"></a> <a name = "new_hover"></a>
<strong>new_hover(self, node, on_hover_callback)</strong> <strong>new_hover(self, node, on_hover_callback, on_mouse_hover_callback)</strong>
</dt> </dt>
<dd> <dd>
Create <a href="../modules/Hover.html#">Hover</a> component Create <a href="../modules/Hover.html#">Hover</a> component
@@ -680,6 +640,10 @@ end
<span class="types"><span class="type">function</span> or <span class="type">nil</span></span> <span class="types"><span class="type">function</span> or <span class="type">nil</span></span>
Hover callback Hover callback
</li> </li>
<li><span class="parameter">on_mouse_hover_callback</span>
<span class="types"><span class="type">function</span> or <span class="type">nil</span></span>
Mouse hover callback
</li>
</ul> </ul>
<h3>Returns:</h3> <h3>Returns:</h3>
@@ -712,7 +676,7 @@ end
Button node to enabled input component Button node to enabled input component
</li> </li>
<li><span class="parameter">text_node</span> <li><span class="parameter">text_node</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">node</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a>, <span class="type">node</span> or <span class="type">druid.text</span></span>
Text node what will be changed on user input Text node what will be changed on user input
</li> </li>
<li><span class="parameter">keyboard_type</span> <li><span class="parameter">keyboard_type</span>
@@ -847,7 +811,7 @@ end
</dd> </dd>
<dt> <dt>
<a name = "new_radio_group"></a> <a name = "new_radio_group"></a>
<strong>new_radio_group(self, nodes, callback[, click_nodes=node])</strong> <strong>new_radio_group(self, nodes, callback, click_nodes)</strong>
</dt> </dt>
<dd> <dd>
Create <a href="../modules/RadioGroup.html#">RadioGroup</a> component Create <a href="../modules/RadioGroup.html#">RadioGroup</a> component
@@ -860,7 +824,7 @@ end
</li> </li>
<li><span class="parameter">nodes</span> <li><span class="parameter">nodes</span>
<span class="types"><span class="type">node[]</span></span> <span class="types"><span class="type">(node</span> or <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string)[]</a></span>
Array of gui node Array of gui node
</li> </li>
<li><span class="parameter">callback</span> <li><span class="parameter">callback</span>
@@ -868,9 +832,8 @@ end
Radio callback Radio callback
</li> </li>
<li><span class="parameter">click_nodes</span> <li><span class="parameter">click_nodes</span>
<span class="types"><span class="type">node[]</span></span> <span class="types"><span class="type">(node</span>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string)[]</a> or <span class="type">nil</span></span>
Array of trigger nodes, by default equals to nodes Array of trigger nodes, by default equals to nodes
(<em>default</em> node)
</li> </li>
</ul> </ul>
@@ -1211,7 +1174,7 @@ end
Message from on_message Message from on_message
</li> </li>
<li><span class="parameter">sender</span> <li><span class="parameter">sender</span>
<span class="types"><span class="type">hash</span></span> <span class="types"><span class="type">url</span></span>
Sender from on_message Sender from on_message
</li> </li>
</ul> </ul>
@@ -1242,6 +1205,12 @@ end
</li> </li>
</ul> </ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean</span></span>
True if component was removed
</ol>
@@ -1249,7 +1218,7 @@ end
</dd> </dd>
<dt> <dt>
<a name = "set_blacklist"></a> <a name = "set_blacklist"></a>
<strong>set_blacklist(self[, blacklist_components=nil])</strong> <strong>set_blacklist(self, blacklist_components)</strong>
</dt> </dt>
<dd> <dd>
Set blacklist components for input processing. Set blacklist components for input processing.
@@ -1264,9 +1233,8 @@ end
<a href="../modules/DruidInstance.html#">DruidInstance</a> <a href="../modules/DruidInstance.html#">DruidInstance</a>
</li> </li>
<li><span class="parameter">blacklist_components</span> <li><span class="parameter">blacklist_components</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">BaseComponent</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a>, <span class="type">BaseComponent</span> or <span class="type">nil</span></span>
The array of component to blacklist The array of component to blacklist
(<em>default</em> nil)
</li> </li>
</ul> </ul>
@@ -1283,7 +1251,7 @@ end
</dd> </dd>
<dt> <dt>
<a name = "set_whitelist"></a> <a name = "set_whitelist"></a>
<strong>set_whitelist(self[, whitelist_components=nil])</strong> <strong>set_whitelist(self, whitelist_components)</strong>
</dt> </dt>
<dd> <dd>
Set whitelist components for input processing. Set whitelist components for input processing.
@@ -1298,9 +1266,8 @@ end
</li> </li>
<li><span class="parameter">whitelist_components</span> <li><span class="parameter">whitelist_components</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">BaseComponent</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a>, <span class="type">BaseComponent</span> or <span class="type">nil</span></span>
The array of component to whitelist The array of component to whitelist
(<em>default</em> nil)
</li> </li>
</ul> </ul>

View File

@@ -420,7 +420,7 @@
<ol> <ol>
<span class="types"><span class="type">vector3</span></span> <span class="types"><span class="type">vector3</span></span>
Node position node position
</ol> </ol>

View File

@@ -151,10 +151,18 @@ helper.centrate_nodes(0, node_1, node_2)
<td class="summary">Check if device is native mobile (Android or iOS)</td> <td class="summary">Check if device is native mobile (Android or iOS)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#helper.is_multitouch_supported">helper.is_multitouch_supported()</a></td>
<td class="summary">Check if device is mobile and can support multitouch</td>
</tr>
<tr>
<td class="name" nowrap><a href="#helper.is_web">helper.is_web()</a></td> <td class="name" nowrap><a href="#helper.is_web">helper.is_web()</a></td>
<td class="summary">Check if device is HTML5</td> <td class="summary">Check if device is HTML5</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#helper.is_web_mobile">helper.is_web_mobile()</a></td>
<td class="summary">Check if device is HTML5 mobile</td>
</tr>
<tr>
<td class="name" nowrap><a href="#helper.lerp">helper.lerp(a, b, t)</a></td> <td class="name" nowrap><a href="#helper.lerp">helper.lerp(a, b, t)</a></td>
<td class="summary">Lerp between two values</td> <td class="summary">Lerp between two values</td>
</tr> </tr>
@@ -658,6 +666,26 @@ helper.centrate_nodes(0, node_1, node_2)
</dd>
<dt>
<a name = "helper.is_multitouch_supported"></a>
<strong>helper.is_multitouch_supported()</strong>
</dt>
<dd>
Check if device is mobile and can support multitouch
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean</span></span>
Is multitouch supported
</ol>
</dd> </dd>
<dt> <dt>
<a name = "helper.is_web"></a> <a name = "helper.is_web"></a>
@@ -678,6 +706,26 @@ helper.centrate_nodes(0, node_1, node_2)
</dd>
<dt>
<a name = "helper.is_web_mobile"></a>
<strong>helper.is_web_mobile()</strong>
</dt>
<dd>
Check if device is HTML5 mobile
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean</span></span>
Is web mobile
</ol>
</dd> </dd>
<dt> <dt>
<a name = "helper.lerp"></a> <a name = "helper.lerp"></a>

View File

@@ -90,6 +90,10 @@
<td class="name" nowrap><a href="#init">init(self, keys, callback, callback_argument)</a></td> <td class="name" nowrap><a href="#init">init(self, keys, callback, callback_argument)</a></td>
<td class="summary">The <a href="../modules/Hotkey.html#">Hotkey</a> constructor</td> <td class="summary">The <a href="../modules/Hotkey.html#">Hotkey</a> constructor</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#set_repeat">set_repeat(self, is_enabled_repeated)</a></td>
<td class="summary">If true, the callback will be triggered on action.repeated</td>
</tr>
</table> </table>
<h2><a href="#Tables">Tables</a></h2> <h2><a href="#Tables">Tables</a></h2>
<table class="function_list"> <table class="function_list">
@@ -113,8 +117,12 @@
<td class="summary">Visual node</td> <td class="summary">Visual node</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_change_state">on_change_state</a></td> <td class="name" nowrap><a href="#on_hotkey_pressed">on_hotkey_pressed</a></td>
<td class="summary">On change state callback(self, state)</td> <td class="summary">On hotkey released callback(self, argument)</td>
</tr>
<tr>
<td class="name" nowrap><a href="#on_hotkey_released">on_hotkey_released</a></td>
<td class="summary">On hotkey released callback(self, argument)</td>
</tr> </tr>
</table> </table>
@@ -192,6 +200,37 @@
</dd>
<dt>
<a name = "set_repeat"></a>
<strong>set_repeat(self, is_enabled_repeated)</strong>
</dt>
<dd>
If true, the callback will be triggered on action.repeated
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Hotkey</span></span>
<a href="../modules/Hotkey.html#">Hotkey</a>
</li>
<li><span class="parameter">is_enabled_repeated</span>
<span class="types"><span class="type">bool</span></span>
The flag value
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Hotkey</span></span>
</ol>
</dd> </dd>
</dl> </dl>
<h2 class="section-header "><a name="Tables"></a>Tables</h2> <h2 class="section-header "><a name="Tables"></a>Tables</h2>
@@ -254,9 +293,8 @@
<ul> <ul>
<li><span class="parameter">click_node</span> <li><span class="parameter">click_node</span>
<span class="types"><a class="type" href="../modules/Hotkey.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Hotkey.html#node">node</a> or <span class="type">nil</span></span>
(<em>default</em> node)
</li> </li>
</ul> </ul>
@@ -286,15 +324,35 @@
</dd> </dd>
<dt> <dt>
<a name = "on_change_state"></a> <a name = "on_hotkey_pressed"></a>
<strong>on_change_state</strong> <strong>on_hotkey_pressed</strong>
</dt> </dt>
<dd> <dd>
On change state callback(self, state) On hotkey released callback(self, argument)
<ul> <ul>
<li><span class="parameter">on_change_state</span> <li><span class="parameter">on_hotkey_pressed</span>
<span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a>
</li>
</ul>
</dd>
<dt>
<a name = "on_hotkey_released"></a>
<strong>on_hotkey_released</strong>
</dt>
<dd>
On hotkey released callback(self, argument)
<ul>
<li><span class="parameter">on_hotkey_released</span>
<span class="types"><span class="type">DruidEvent</span></span> <span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a> <a href="../modules/DruidEvent.html#">DruidEvent</a>
</li> </li>

View File

@@ -33,6 +33,7 @@
<h2>Contents</h2> <h2>Contents</h2>
<ul> <ul>
<li><a href="#Functions">Functions</a></li> <li><a href="#Functions">Functions</a></li>
<li><a href="#Tables">Tables</a></li>
<li><a href="#Fields">Fields</a></li> <li><a href="#Fields">Fields</a></li>
</ul> </ul>
@@ -82,7 +83,7 @@
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, node, on_hover_callback)</a></td> <td class="name" nowrap><a href="#init">init(self, node, on_hover_callback, on_mouse_hover)</a></td>
<td class="summary">The <a href="../modules/Hover.html#">Hover</a> constructor</td> <td class="summary">The <a href="../modules/Hover.html#">Hover</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -114,8 +115,19 @@
<td class="summary">Set mouse hover state</td> <td class="summary">Set mouse hover state</td>
</tr> </tr>
</table> </table>
<h2><a href="#Tables">Tables</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#style">style</a></td>
<td class="summary">Component style params.</td>
</tr>
</table>
<h2><a href="#Fields">Fields</a></h2> <h2><a href="#Fields">Fields</a></h2>
<table class="function_list"> <table class="function_list">
<tr>
<td class="name" nowrap><a href="#node">node</a></td>
<td class="summary">Hover node</td>
</tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_hover">on_hover</a></td> <td class="name" nowrap><a href="#on_hover">on_hover</a></td>
<td class="summary">On hover callback(self, state, hover_instance)</td> <td class="summary">On hover callback(self, state, hover_instance)</td>
@@ -135,7 +147,7 @@
<dl class="function"> <dl class="function">
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, node, on_hover_callback)</strong> <strong>init(self, node, on_hover_callback, on_mouse_hover)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/Hover.html#">Hover</a> constructor The <a href="../modules/Hover.html#">Hover</a> constructor
@@ -148,13 +160,17 @@
<a href="../modules/Hover.html#">Hover</a> <a href="../modules/Hover.html#">Hover</a>
</li> </li>
<li><span class="parameter">node</span> <li><span class="parameter">node</span>
<span class="types"><span class="type">node</span></span> <span class="types"><a class="type" href="../modules/Hover.html#node">node</a></span>
Gui node Gui node
</li> </li>
<li><span class="parameter">on_hover_callback</span> <li><span class="parameter">on_hover_callback</span>
<span class="types"><span class="type">function</span></span> <span class="types"><span class="type">function</span></span>
Hover callback Hover callback
</li> </li>
<li><span class="parameter">on_mouse_hover</span>
<span class="types"><span class="type">function</span></span>
On mouse hover callback
</li>
</ul> </ul>
@@ -259,7 +275,7 @@
<a href="../modules/Hover.html#">Hover</a> <a href="../modules/Hover.html#">Hover</a>
</li> </li>
<li><span class="parameter">zone</span> <li><span class="parameter">zone</span>
<span class="types"><span class="type">node</span></span> <span class="types"><a class="type" href="../modules/Hover.html#node">node</a>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Gui node Gui node
</li> </li>
</ul> </ul>
@@ -345,11 +361,64 @@
</dd>
</dl>
<h2 class="section-header "><a name="Tables"></a>Tables</h2>
<dl class="function">
<dt>
<a name = "style"></a>
<strong>style</strong>
</dt>
<dd>
Component style params.
You can override this component styles params in druid styles table
or create your own style
<h3>Fields:</h3>
<ul>
<li><span class="parameter">ON_HOVER_CURSOR</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
Mouse hover style on node hover
(<em>optional</em>)
</li>
<li><span class="parameter">ON_MOUSE_HOVER_CURSOR</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
Mouse hover style on node mouse hover
(<em>optional</em>)
</li>
</ul>
</dd> </dd>
</dl> </dl>
<h2 class="section-header "><a name="Fields"></a>Fields</h2> <h2 class="section-header "><a name="Fields"></a>Fields</h2>
<dl class="function"> <dl class="function">
<dt>
<a name = "node"></a>
<strong>node</strong>
</dt>
<dd>
Hover node
<ul>
<li><span class="parameter">node</span>
<span class="types"><a class="type" href="../modules/Hover.html#node">node</a></span>
</li>
</ul>
</dd>
<dt> <dt>
<a name = "on_hover"></a> <a name = "on_hover"></a>
<strong>on_hover</strong> <strong>on_hover</strong>

View File

@@ -93,10 +93,18 @@
<td class="summary">Return current input field text</td> <td class="summary">Return current input field text</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#get_text_selected_replaced">get_text_selected_replaced(self, text)</a></td>
<td class="summary">Replace selected text with new text</td>
</tr>
<tr>
<td class="name" nowrap><a href="#init">init(self, click_node, text_node, keyboard_type)</a></td> <td class="name" nowrap><a href="#init">init(self, click_node, text_node, keyboard_type)</a></td>
<td class="summary">The <a href="../modules/Input.html#">Input</a> constructor</td> <td class="summary">The <a href="../modules/Input.html#">Input</a> constructor</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#move_selection">move_selection(self, delta, is_add_to_selection, is_move_to_end)</a></td>
<td class="summary">Change cursor position by delta</td>
</tr>
<tr>
<td class="name" nowrap><a href="#reset_changes">reset_changes(self)</a></td> <td class="name" nowrap><a href="#reset_changes">reset_changes(self)</a></td>
<td class="summary">Reset current input selection and return previous value</td> <td class="summary">Reset current input selection and return previous value</td>
</tr> </tr>
@@ -105,6 +113,10 @@
<td class="summary">Select input field.</td> <td class="summary">Select input field.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#select_cursor">select_cursor(self, cursor_index, start_index, end_index)</a></td>
<td class="summary">Set cursor position in input field</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_allowed_characters">set_allowed_characters(self, characters)</a></td> <td class="name" nowrap><a href="#set_allowed_characters">set_allowed_characters(self, characters)</a></td>
<td class="summary">Set allowed charaters for input field.</td> <td class="summary">Set allowed charaters for input field.</td>
</tr> </tr>
@@ -139,6 +151,18 @@
<td class="summary">Button component</td> <td class="summary">Button component</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#current_value">current_value</a></td>
<td class="summary">Current input value with marked text</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cursor_index">cursor_index</a></td>
<td class="summary">The cursor index.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#end_index">end_index</a></td>
<td class="summary">Theselection end index.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#is_empty">is_empty</a></td> <td class="name" nowrap><a href="#is_empty">is_empty</a></td>
<td class="summary">Is current input is empty now</td> <td class="summary">Is current input is empty now</td>
</tr> </tr>
@@ -151,6 +175,14 @@
<td class="summary">Gui keyboard type for input field</td> <td class="summary">Gui keyboard type for input field</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#marked_text_width">marked_text_width</a></td>
<td class="summary">Marked text width</td>
</tr>
<tr>
<td class="name" nowrap><a href="#marked_value">marked_value</a></td>
<td class="summary">Marked text for input field.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#max_length">max_length</a></td> <td class="name" nowrap><a href="#max_length">max_length</a></td>
<td class="summary">Max length for input text</td> <td class="summary">Max length for input text</td>
</tr> </tr>
@@ -164,7 +196,7 @@
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_input_select">on_input_select</a></td> <td class="name" nowrap><a href="#on_input_select">on_input_select</a></td>
<td class="summary">On input field select callback(self, button_node)</td> <td class="summary">On input field select callback(self, input_instance)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_input_text">on_input_text</a></td> <td class="name" nowrap><a href="#on_input_text">on_input_text</a></td>
@@ -172,16 +204,36 @@
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_input_unselect">on_input_unselect</a></td> <td class="name" nowrap><a href="#on_input_unselect">on_input_unselect</a></td>
<td class="summary">On input field unselect callback(self, input_text)</td> <td class="summary">On input field unselect callback(self, input_text, input_instance)</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#on_input_wrong">on_input_wrong</a></td> <td class="name" nowrap><a href="#on_input_wrong">on_input_wrong</a></td>
<td class="summary">On trying user input with not allowed character callback(self, params, button_instance)</td> <td class="summary">On trying user input with not allowed character callback(self, params, input_text)</td>
</tr>
<tr>
<td class="name" nowrap><a href="#on_select_cursor_change">on_select_cursor_change</a></td>
<td class="summary">On cursor position change callback(self, cursor_index, start_index, end_index)</td>
</tr>
<tr>
<td class="name" nowrap><a href="#previous_value">previous_value</a></td>
<td class="summary">Previous input value</td>
</tr>
<tr>
<td class="name" nowrap><a href="#start_index">start_index</a></td>
<td class="summary">The selection start index.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#text">text</a></td> <td class="name" nowrap><a href="#text">text</a></td>
<td class="summary">Text component</td> <td class="summary">Text component</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#text_width">text_width</a></td>
<td class="summary">Text width</td>
</tr>
<tr>
<td class="name" nowrap><a href="#value">value</a></td>
<td class="summary">Current input value</td>
</tr>
</table> </table>
<br/> <br/>
@@ -217,6 +269,37 @@
</dd>
<dt>
<a name = "get_text_selected_replaced"></a>
<strong>get_text_selected_replaced(self, text)</strong>
</dt>
<dd>
Replace selected text with new text
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Input</span></span>
<a href="../modules/Input.html#">Input</a>
</li>
<li><span class="parameter">text</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The text to replace selected text
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
New input text
</ol>
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
@@ -250,6 +333,39 @@
</dd>
<dt>
<a name = "move_selection"></a>
<strong>move_selection(self, delta, is_add_to_selection, is_move_to_end)</strong>
</dt>
<dd>
Change cursor position by delta
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Input</span></span>
<a href="../modules/Input.html#">Input</a>
</li>
<li><span class="parameter">delta</span>
<span class="types"><span class="type">number</span></span>
side for cursor position, -1 for left, 1 for right
</li>
<li><span class="parameter">is_add_to_selection</span>
<span class="types"><span class="type">boolean</span></span>
(Shift key)
</li>
<li><span class="parameter">is_move_to_end</span>
<span class="types"><span class="type">boolean</span></span>
(Ctrl key)
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "reset_changes"></a> <a name = "reset_changes"></a>
@@ -267,6 +383,12 @@
</li> </li>
</ul> </ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.input</span></span>
Current input instance
</ol>
@@ -292,6 +414,45 @@
</dd>
<dt>
<a name = "select_cursor"></a>
<strong>select_cursor(self, cursor_index, start_index, end_index)</strong>
</dt>
<dd>
Set cursor position in input field
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Input</span></span>
<a href="../modules/Input.html#">Input</a>
</li>
<li><span class="parameter">cursor_index</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Cursor index for cursor position, if nil - will be set to the end of the text
</li>
<li><span class="parameter">start_index</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Start index for cursor position, if nil - will be set to the end of the text
</li>
<li><span class="parameter">end_index</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
End index for cursor position, if nil - will be set to the start_index
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.input</span></span>
Current input instance
</ol>
</dd> </dd>
<dt> <dt>
<a name = "set_allowed_characters"></a> <a name = "set_allowed_characters"></a>
@@ -422,23 +583,15 @@
<ul> <ul>
<li><span class="parameter">IS_LONGTAP_ERASE</span> <li><span class="parameter">IS_LONGTAP_ERASE</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span></span>
Is long tap will erase current input data Is long tap will erase current input data. Default: false
(<em>default</em> false)
</li> </li>
<li><span class="parameter">MASK_DEFAULT_CHAR</span> <li><span class="parameter">MASK_DEFAULT_CHAR</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
Default character mask for password input Default character mask for password input. Default: *]
(<em>default</em> *)
</li> </li>
<li><span class="parameter">IS_UNSELECT_ON_RESELECT</span> <li><span class="parameter">IS_UNSELECT_ON_RESELECT</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span></span>
If true, call unselect on select selected input If true, call unselect on select selected input. Default: false
(<em>default</em> false)
</li>
<li><span class="parameter">NO_CONSUME_INPUT_WHILE_SELECTED</span>
<span class="types"><span class="type">boolean</span></span>
If true, will not consume input while input is selected. It's allow to interact with other components while input is selected (text input still captured)
(<em>default</em> false)
</li> </li>
<li><span class="parameter">on_select</span> <li><span class="parameter">on_select</span>
<span class="types"><span class="type">function</span></span> <span class="types"><span class="type">function</span></span>
@@ -477,9 +630,8 @@
<ul> <ul>
<li><span class="parameter">allowerd_characters</span> <li><span class="parameter">allowerd_characters</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
(<em>optional</em>)
</li> </li>
</ul> </ul>
@@ -507,6 +659,66 @@
</dd>
<dt>
<a name = "current_value"></a>
<strong>current_value</strong>
</dt>
<dd>
Current input value with marked text
<ul>
<li><span class="parameter">current_value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
</li>
</ul>
</dd>
<dt>
<a name = "cursor_index"></a>
<strong>cursor_index</strong>
</dt>
<dd>
The cursor index. The index of letter cursor after. Leftmost cursor - 0
<ul>
<li><span class="parameter">cursor_index</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "end_index"></a>
<strong>end_index</strong>
</dt>
<dd>
Theselection end index. The index of letter cursor before. Rightmost selection - #text
<ul>
<li><span class="parameter">end_index</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "is_empty"></a> <a name = "is_empty"></a>
@@ -567,6 +779,46 @@
</dd>
<dt>
<a name = "marked_text_width"></a>
<strong>marked_text_width</strong>
</dt>
<dd>
Marked text width
<ul>
<li><span class="parameter">marked_text_width</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "marked_value"></a>
<strong>marked_value</strong>
</dt>
<dd>
Marked text for input field. Info: https://defold.com/manuals/input-key-and-text/#marked-text
<ul>
<li><span class="parameter">marked_value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "max_length"></a> <a name = "max_length"></a>
@@ -578,9 +830,8 @@
<ul> <ul>
<li><span class="parameter">max_length</span> <li><span class="parameter">max_length</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
(<em>optional</em>)
</li> </li>
</ul> </ul>
@@ -634,7 +885,7 @@
<strong>on_input_select</strong> <strong>on_input_select</strong>
</dt> </dt>
<dd> <dd>
On input field select callback(self, button_node) On input field select callback(self, input_instance)
<ul> <ul>
@@ -674,7 +925,7 @@
<strong>on_input_unselect</strong> <strong>on_input_unselect</strong>
</dt> </dt>
<dd> <dd>
On input field unselect callback(self, input_text) On input field unselect callback(self, input_text, input_instance)
<ul> <ul>
@@ -694,7 +945,7 @@
<strong>on_input_wrong</strong> <strong>on_input_wrong</strong>
</dt> </dt>
<dd> <dd>
On trying user input with not allowed character callback(self, params, button_instance) On trying user input with not allowed character callback(self, params, input_text)
<ul> <ul>
@@ -708,6 +959,66 @@
</dd>
<dt>
<a name = "on_select_cursor_change"></a>
<strong>on_select_cursor_change</strong>
</dt>
<dd>
On cursor position change callback(self, cursor_index, start_index, end_index)
<ul>
<li><span class="parameter">on_select_cursor_change</span>
<span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a>
</li>
</ul>
</dd>
<dt>
<a name = "previous_value"></a>
<strong>previous_value</strong>
</dt>
<dd>
Previous input value
<ul>
<li><span class="parameter">previous_value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
</li>
</ul>
</dd>
<dt>
<a name = "start_index"></a>
<strong>start_index</strong>
</dt>
<dd>
The selection start index. The index of letter cursor after. Leftmost selection - 0
<ul>
<li><span class="parameter">start_index</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "text"></a> <a name = "text"></a>
@@ -728,6 +1039,46 @@
</dd>
<dt>
<a name = "text_width"></a>
<strong>text_width</strong>
</dt>
<dd>
Text width
<ul>
<li><span class="parameter">text_width</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "value"></a>
<strong>value</strong>
</dt>
<dd>
Current input value
<ul>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
</li>
</ul>
</dd> </dd>
</dl> </dl>

View File

@@ -93,7 +93,7 @@
<td class="summary">Format string with new text params on localized text</td> <td class="summary">Format string with new text params on localized text</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, node[, locale_id=node_text[, adjust_type=downscale]])</a></td> <td class="name" nowrap><a href="#init">init(self, node, locale_id, adjust_type)</a></td>
<td class="summary">The <a href="../modules/LangText.html#">LangText</a> constructor</td> <td class="summary">The <a href="../modules/LangText.html#">LangText</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -185,7 +185,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, node[, locale_id=node_text[, adjust_type=downscale]])</strong> <strong>init(self, node, locale_id, adjust_type)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/LangText.html#">LangText</a> constructor The <a href="../modules/LangText.html#">LangText</a> constructor
@@ -202,14 +202,12 @@
The node_id or gui.get_node(node_id) The node_id or gui.get_node(node_id)
</li> </li>
<li><span class="parameter">locale_id</span> <li><span class="parameter">locale_id</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Default locale id or text from node as default Default locale id or text from node as default
(<em>default</em> node_text)
</li> </li>
<li><span class="parameter">adjust_type</span> <li><span class="parameter">adjust_type</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
(<em>default</em> downscale)
</li> </li>
</ul> </ul>

View File

@@ -32,7 +32,6 @@
<h2>Contents</h2> <h2>Contents</h2>
<ul> <ul>
<li><a href="#Functions">Functions</a></li>
<li><a href="#Fields">Fields</a></li> <li><a href="#Fields">Fields</a></li>
</ul> </ul>
@@ -79,45 +78,6 @@
<p> <a href="https://insality.github.io/druid/druid/index.html?example=general_layout" target="_blank"><b>Example Link</b></a></p> <p> <a href="https://insality.github.io/druid/druid/index.html?example=general_layout" target="_blank"><b>Example Link</b></a></p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#fit_into_node">fit_into_node(self, node)</a></td>
<td class="summary">Set node for layout node to fit inside it.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#fit_into_size">fit_into_size(self, target_size)</a></td>
<td class="summary">Set size for layout node to fit inside it</td>
</tr>
<tr>
<td class="name" nowrap><a href="#fit_into_window">fit_into_window(self)</a></td>
<td class="summary">Set current size for layout node to fit inside it</td>
</tr>
<tr>
<td class="name" nowrap><a href="#init">init(self, node, mode, on_size_changed_callback)</a></td>
<td class="summary">The <a href="../modules/Layout.html#">Layout</a> constructor</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_max_gui_upscale">set_max_gui_upscale(self, max_gui_upscale)</a></td>
<td class="summary">Set max gui upscale for FIT adjust mode (or side).</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_max_size">set_max_size(self, max_size)</a></td>
<td class="summary">Set maximum size of layout node</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_min_size">set_min_size(self, min_size)</a></td>
<td class="summary">Set minimal size of layout node</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_origin_position">set_origin_position(self, new_origin_position)</a></td>
<td class="summary">Set new origin position of layout node.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_origin_size">set_origin_size(self, new_origin_size)</a></td>
<td class="summary">Set new origin size of layout node.</td>
</tr>
</table>
<h2><a href="#Fields">Fields</a></h2> <h2><a href="#Fields">Fields</a></h2>
<table class="function_list"> <table class="function_list">
<tr> <tr>
@@ -128,297 +88,12 @@
<td class="name" nowrap><a href="#node">node</a></td> <td class="name" nowrap><a href="#node">node</a></td>
<td class="summary">Layout node</td> <td class="summary">Layout node</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#on_size_changed">on_size_changed</a></td>
<td class="summary">On window resize callback(self, new_size)</td>
</tr>
</table> </table>
<br/> <br/>
<br/> <br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "fit_into_node"></a>
<strong>fit_into_node(self, node)</strong>
</dt>
<dd>
Set node for layout node to fit inside it. Pass nil to reset
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">node</span>
<span class="types"><a class="type" href="../modules/Layout.html#node">node</a> or <span class="type">nil</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "fit_into_size"></a>
<strong>fit_into_size(self, target_size)</strong>
</dt>
<dd>
Set size for layout node to fit inside it
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">target_size</span>
<span class="types"><span class="type">vector3</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "fit_into_window"></a>
<strong>fit_into_window(self)</strong>
</dt>
<dd>
Set current size for layout node to fit inside it
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "init"></a>
<strong>init(self, node, mode, on_size_changed_callback)</strong>
</dt>
<dd>
The <a href="../modules/Layout.html#">Layout</a> constructor
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">node</span>
<span class="types"><a class="type" href="../modules/Layout.html#node">node</a></span>
Gui node
</li>
<li><span class="parameter">mode</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The layout mode (from const.LAYOUT_MODE)
</li>
<li><span class="parameter">on_size_changed_callback</span>
<span class="types"><span class="type">function</span> or <span class="type">nil</span></span>
The callback on window resize
</li>
</ul>
</dd>
<dt>
<a name = "set_max_gui_upscale"></a>
<strong>set_max_gui_upscale(self, max_gui_upscale)</strong>
</dt>
<dd>
Set max gui upscale for FIT adjust mode (or side). It happens on bigger render gui screen
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">max_gui_upscale</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "set_max_size"></a>
<strong>set_max_size(self, max_size)</strong>
</dt>
<dd>
Set maximum size of layout node
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">max_size</span>
<span class="types"><span class="type">vector3</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "set_min_size"></a>
<strong>set_min_size(self, min_size)</strong>
</dt>
<dd>
Set minimal size of layout node
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">min_size</span>
<span class="types"><span class="type">vector3</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "set_origin_position"></a>
<strong>set_origin_position(self, new_origin_position)</strong>
</dt>
<dd>
Set new origin position of layout node. You should apply this on node movement
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">new_origin_position</span>
<span class="types"><span class="type">vector3</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
<dt>
<a name = "set_origin_size"></a>
<strong>set_origin_size(self, new_origin_size)</strong>
</dt>
<dd>
Set new origin size of layout node. You should apply this on node manual size change
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</li>
<li><span class="parameter">new_origin_size</span>
<span class="types"><span class="type">vector3</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Layout</span></span>
<a href="../modules/Layout.html#">Layout</a>
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Fields"></a>Fields</h2> <h2 class="section-header "><a name="Fields"></a>Fields</h2>
<dl class="function"> <dl class="function">
@@ -461,26 +136,6 @@
</dd>
<dt>
<a name = "on_size_changed"></a>
<strong>on_size_changed</strong>
</dt>
<dd>
On window resize callback(self, new_size)
<ul>
<li><span class="parameter">on_size_changed</span>
<span class="types"><span class="type">DruidEvent</span></span>
<a href="../modules/DruidEvent.html#">DruidEvent</a>
</li>
</ul>
</dd> </dd>
</dl> </dl>

View File

@@ -91,7 +91,7 @@
<td class="summary">Set current and min/max angles for component</td> <td class="summary">Set current and min/max angles for component</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#set_friction">set_friction(self[, value=1])</a></td> <td class="name" nowrap><a href="#set_friction">set_friction(self, value)</a></td>
<td class="summary">Set current and min/max angles for component</td> <td class="summary">Set current and min/max angles for component</td>
</tr> </tr>
</table> </table>
@@ -192,7 +192,7 @@
</dd> </dd>
<dt> <dt>
<a name = "set_friction"></a> <a name = "set_friction"></a>
<strong>set_friction(self[, value=1])</strong> <strong>set_friction(self, value)</strong>
</dt> </dt>
<dd> <dd>
Set current and min/max angles for component Set current and min/max angles for component
@@ -205,9 +205,8 @@
<a href="../modules/PinKnob.html#">PinKnob</a> <a href="../modules/PinKnob.html#">PinKnob</a>
</li> </li>
<li><span class="parameter">value</span> <li><span class="parameter">value</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
The spin speed multiplier The spin speed multiplier. Default: 1
(<em>default</em> 1)
</li> </li>
</ul> </ul>

View File

@@ -103,7 +103,7 @@
<td class="summary">Return current progress bar value</td> <td class="summary">Return current progress bar value</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, node, key[, init_value=1])</a></td> <td class="name" nowrap><a href="#init">init(self, node, key, init_value)</a></td>
<td class="summary">The <a href="../modules/Progress.html#">Progress</a> constructor</td> <td class="summary">The <a href="../modules/Progress.html#">Progress</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -234,7 +234,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, node, key[, init_value=1])</strong> <strong>init(self, node, key, init_value)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/Progress.html#">Progress</a> constructor The <a href="../modules/Progress.html#">Progress</a> constructor
@@ -255,9 +255,8 @@
Progress bar direction: const.SIDE.X or const.SIDE.Y Progress bar direction: const.SIDE.X or const.SIDE.Y
</li> </li>
<li><span class="parameter">init_value</span> <li><span class="parameter">init_value</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Initial value of progress bar Initial value of progress bar. Default: 1
(<em>default</em> 1)
</li> </li>
</ul> </ul>
@@ -401,14 +400,12 @@
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">SPEED</span> <li><span class="parameter">SPEED</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Progress bas fill rate. More -> faster Progress bas fill rate. More -> faster. Default: 5
(<em>default</em> 5)
</li> </li>
<li><span class="parameter">MIN_DELTA</span> <li><span class="parameter">MIN_DELTA</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Minimum step to fill progress bar Minimum step to fill progress bar. Default: 0.005
(<em>default</em> 0.005)
</li> </li>
</ul> </ul>

View File

@@ -86,7 +86,7 @@
<td class="summary">Return radio group state</td> <td class="summary">Return radio group state</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, nodes, callback[, click_nodes=node])</a></td> <td class="name" nowrap><a href="#init">init(self, nodes, callback, click_nodes)</a></td>
<td class="summary">The <a href="../modules/RadioGroup.html#">RadioGroup</a> constructor</td> <td class="summary">The <a href="../modules/RadioGroup.html#">RadioGroup</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -142,7 +142,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, nodes, callback[, click_nodes=node])</strong> <strong>init(self, nodes, callback, click_nodes)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/RadioGroup.html#">RadioGroup</a> constructor The <a href="../modules/RadioGroup.html#">RadioGroup</a> constructor
@@ -163,9 +163,8 @@
Radio callback Radio callback
</li> </li>
<li><span class="parameter">click_nodes</span> <li><span class="parameter">click_nodes</span>
<span class="types"><span class="type">node[]</span></span> <span class="types"><span class="type">node[]</span> or <span class="type">nil</span></span>
Array of trigger nodes, by default equals to nodes Array of trigger nodes, by default equals to nodes. Default - nodes
(<em>default</em> node)
</li> </li>
</ul> </ul>

View File

@@ -84,20 +84,32 @@
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" nowrap><a href="#get_text">get_text(self)</a></td> <td class="name" nowrap><a href="#get_text">get_text(self)</a></td>
<td class="summary">GSet input field text</td> <td class="summary">Set input field text</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, template, nodes)</a></td> <td class="name" nowrap><a href="#init">init(self, template, nodes)</a></td>
<td class="summary">The <a href="../modules/RichInput.html#">RichInput</a> constructor</td> <td class="summary">The <a href="../modules/RichInput.html#">RichInput</a> constructor</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#select">select(self)</a></td>
<td class="summary">Select input field</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_allowed_characters">set_allowed_characters(self, characters)</a></td> <td class="name" nowrap><a href="#set_allowed_characters">set_allowed_characters(self, characters)</a></td>
<td class="summary">Set allowed charaters for input field.</td> <td class="summary">Set allowed charaters for input field.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#set_font">set_font(self, font)</a></td>
<td class="summary">Set input field font</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_placeholder">set_placeholder(self, placeholder_text)</a></td> <td class="name" nowrap><a href="#set_placeholder">set_placeholder(self, placeholder_text)</a></td>
<td class="summary">Set placeholder text</td> <td class="summary">Set placeholder text</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#set_text">set_text(self, text)</a></td>
<td class="summary">Set input field text</td>
</tr>
</table> </table>
<h2><a href="#Fields">Fields</a></h2> <h2><a href="#Fields">Fields</a></h2>
<table class="function_list"> <table class="function_list">
@@ -135,7 +147,7 @@
<strong>get_text(self)</strong> <strong>get_text(self)</strong>
</dt> </dt>
<dd> <dd>
GSet input field text Set input field text
<h3>Parameters:</h3> <h3>Parameters:</h3>
@@ -146,12 +158,6 @@
</li> </li>
</ul> </ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
Current input text
</ol>
@@ -185,6 +191,27 @@
</dd>
<dt>
<a name = "select"></a>
<strong>select(self)</strong>
</dt>
<dd>
Select input field
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">RichInput</span></span>
<a href="../modules/RichInput.html#">RichInput</a>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "set_allowed_characters"></a> <a name = "set_allowed_characters"></a>
@@ -218,6 +245,37 @@
</dd>
<dt>
<a name = "set_font"></a>
<strong>set_font(self, font)</strong>
</dt>
<dd>
Set input field font
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">RichInput</span></span>
<a href="../modules/RichInput.html#">RichInput</a>
</li>
<li><span class="parameter">font</span>
<span class="types"><span class="type">hash</span></span>
The font hash
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.input</span></span>
Current input instance
</ol>
</dd> </dd>
<dt> <dt>
<a name = "set_placeholder"></a> <a name = "set_placeholder"></a>
@@ -234,16 +292,41 @@
<a href="../modules/RichInput.html#">RichInput</a> <a href="../modules/RichInput.html#">RichInput</a>
</li> </li>
<li><span class="parameter">placeholder_text</span> <li><span class="parameter">placeholder_text</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The placeholder text The placeholder text
</li> </li>
</ul> </ul>
</dd>
<dt>
<a name = "set_text"></a>
<strong>set_text(self, text)</strong>
</dt>
<dd>
Set input field text
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">RichInput</span></span>
<a href="../modules/RichInput.html#">RichInput</a>
</li>
<li><span class="parameter">text</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The input text
</li>
</ul>
<h3>Returns:</h3> <h3>Returns:</h3>
<ol> <ol>
<span class="types"><span class="type">RichInput</span></span> <span class="types"><span class="type">druid.input</span></span>
Current instance Current input instance
</ol> </ol>

View File

@@ -81,19 +81,7 @@
<b># Overview #</b> <b># Overview #</b>
<p> This custom component is inspired by <a href="https://github.com/britzl/defold-richtext" target="_blank">defold-richtext</a> by britzl. <p> This custom component is inspired by <a href="https://github.com/britzl/defold-richtext" target="_blank">defold-richtext</a> by britzl.
It uses a similar syntax for tags but currently supports fewer tags. It uses a similar syntax for tags but currently supports fewer tags.
<p> All parameters for the Rich Text component are adjusted in the GUI scene. <p> Create Rich Text on your GUI Text Node. All properties of the text node will be used as default for the text.
<p> This component uses GUI component template. (/druid/custom/rich_text/rich_text.gui).
<p> You able to customize it or make your own with the next node scructure:
<p> root
<p> - text_prefab
<p> - icon_prefab
<p> <b># Rich Text Setup #</b>
<p> • Root node size: Set the maximum width and height of the text.
<p> • Root anchor: Define the alignment of the Rich Text inside the root node size area.
<p> • Text prefab: Configure all default text parameters for the text node.
<p> • Text prefab anchor: Set the anchor for each text node (adjust this only if animating text).
<p> • Icon prefab: Configure all default node parameters for the icon node.
<p> • Icon prefab anchor: Set the anchor for each icon node (adjust this only if animating the icon).
<p> <b># Notes #</b> <p> <b># Notes #</b>
<p> • Nested tags are supported <p> • Nested tags are supported
<p> <a href="https://insality.github.io/druid/druid/index.html?example=custom_rich_text" target="_blank"><b>Example Link</b></a></p> <p> <a href="https://insality.github.io/druid/druid/index.html?example=custom_rich_text" target="_blank"><b>Example Link</b></a></p>
@@ -119,7 +107,6 @@ self.rich_text:set_text(&quot;Hello, Druid Rich Text!&quot;)
outline: vector4, outline: vector4,
font: string, font: string,
image: druid.rich_text.image, image: druid.rich_text.image,
default_animation: string,
br: boolean, br: boolean,
nobr: boolean, nobr: boolean,
} }
@@ -150,6 +137,10 @@ type druid.rich_text.metrics = {
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
<table class="function_list"> <table class="function_list">
<tr>
<td class="name" nowrap><a href="#characters">characters(self, word)</a></td>
<td class="summary">Split a word into it's characters</td>
</tr>
<tr> <tr>
<td class="name" nowrap><a href="#clear">clear()</a></td> <td class="name" nowrap><a href="#clear">clear()</a></td>
<td class="summary">Clear all created words.</td> <td class="summary">Clear all created words.</td>
@@ -159,11 +150,15 @@ type druid.rich_text.metrics = {
<td class="summary">Get current line metrics</td> <td class="summary">Get current line metrics</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#get_text">get_text(self)</a></td>
<td class="summary">Get current text</td>
</tr>
<tr>
<td class="name" nowrap><a href="#get_words">get_words()</a></td> <td class="name" nowrap><a href="#get_words">get_words()</a></td>
<td class="summary">Get all current words.</td> <td class="summary">Get all current words.</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, template, nodes)</a></td> <td class="name" nowrap><a href="#init">init(self, text_node, value)</a></td>
<td class="summary">The <a href="../modules/RichText.html#">RichText</a> constructor</td> <td class="summary">The <a href="../modules/RichText.html#">RichText</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -171,7 +166,7 @@ type druid.rich_text.metrics = {
<td class="summary">Set text for Rich Text</td> <td class="summary">Set text for Rich Text</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#tagged">tagged(tag)</a></td> <td class="name" nowrap><a href="#tagged">tagged(self, tag)</a></td>
<td class="summary">Get all words, which has a passed tag.</td> <td class="summary">Get all words, which has a passed tag.</td>
</tr> </tr>
</table> </table>
@@ -188,6 +183,18 @@ type druid.rich_text.metrics = {
<td class="name" nowrap><a href="#druid">druid</a></td> <td class="name" nowrap><a href="#druid">druid</a></td>
<td class="summary">The component druid instance</td> <td class="summary">The component druid instance</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#icon_prefab">icon_prefab</a></td>
<td class="summary">The icon prefab node</td>
</tr>
<tr>
<td class="name" nowrap><a href="#root">root</a></td>
<td class="summary">The root node of the Rich Text</td>
</tr>
<tr>
<td class="name" nowrap><a href="#text_prefab">text_prefab</a></td>
<td class="summary">The text prefab node</td>
</tr>
</table> </table>
<br/> <br/>
@@ -197,6 +204,37 @@ type druid.rich_text.metrics = {
<h2 class="section-header "><a name="Functions"></a>Functions</h2> <h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function"> <dl class="function">
<dt>
<a name = "characters"></a>
<strong>characters(self, word)</strong>
</dt>
<dd>
Split a word into it's characters
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">RichText</span></span>
<a href="../modules/RichText.html#">RichText</a>
</li>
<li><span class="parameter">word</span>
<span class="types"><span class="type">druid.rich_text.word</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.rich_text.word[]</span></span>
characters
</ol>
</dd>
<dt> <dt>
<a name = "clear"></a> <a name = "clear"></a>
<strong>clear()</strong> <strong>clear()</strong>
@@ -230,6 +268,33 @@ type druid.rich_text.metrics = {
</dd>
<dt>
<a name = "get_text"></a>
<strong>get_text(self)</strong>
</dt>
<dd>
Get current text
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">RichText</span></span>
<a href="../modules/RichText.html#">RichText</a>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
text
</ol>
</dd> </dd>
<dt> <dt>
<a name = "get_words"></a> <a name = "get_words"></a>
@@ -253,7 +318,7 @@ type druid.rich_text.metrics = {
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, template, nodes)</strong> <strong>init(self, text_node, value)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/RichText.html#">RichText</a> constructor The <a href="../modules/RichText.html#">RichText</a> constructor
@@ -265,13 +330,13 @@ type druid.rich_text.metrics = {
<span class="types"><span class="type">RichText</span></span> <span class="types"><span class="type">RichText</span></span>
<a href="../modules/RichText.html#">RichText</a> <a href="../modules/RichText.html#">RichText</a>
</li> </li>
<li><span class="parameter">template</span> <li><span class="parameter">text_node</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><span class="type">node</span> or <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The Rich Text template name The text node to make Rich Text
</li> </li>
<li><span class="parameter">nodes</span> <li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
The node table, if prefab was copied by gui.clone_tree() The initial text value. Default will be gui.get_text(text_node)
</li> </li>
</ul> </ul>
@@ -295,7 +360,7 @@ type druid.rich_text.metrics = {
<a href="../modules/RichText.html#">RichText</a> <a href="../modules/RichText.html#">RichText</a>
</li> </li>
<li><span class="parameter">text</span> <li><span class="parameter">text</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
The text to set The text to set
</li> </li>
</ul> </ul>
@@ -361,7 +426,7 @@ Words &lt;nobr&gt;inside tag&lt;/nobr&gt; won't <span class="keyword">break</spa
</dd> </dd>
<dt> <dt>
<a name = "tagged"></a> <a name = "tagged"></a>
<strong>tagged(tag)</strong> <strong>tagged(self, tag)</strong>
</dt> </dt>
<dd> <dd>
Get all words, which has a passed tag. Get all words, which has a passed tag.
@@ -369,6 +434,10 @@ Words &lt;nobr&gt;inside tag&lt;/nobr&gt; won't <span class="keyword">break</spa
<h3>Parameters:</h3> <h3>Parameters:</h3>
<ul> <ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">RichText</span></span>
<a href="../modules/RichText.html#">RichText</a>
</li>
<li><span class="parameter">tag</span> <li><span class="parameter">tag</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
@@ -403,19 +472,16 @@ Words &lt;nobr&gt;inside tag&lt;/nobr&gt; won't <span class="keyword">break</spa
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">COLORS</span> <li><span class="parameter">COLORS</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
Rich Text color aliases Rich Text color aliases. Default: {}
(<em>default</em> {})
</li> </li>
<li><span class="parameter">ADJUST_STEPS</span> <li><span class="parameter">ADJUST_STEPS</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Amount steps of attemps text adjust by height Amount steps of attemps text adjust by height. Default: 20
(<em>default</em> 20)
</li> </li>
<li><span class="parameter">ADJUST_SCALE_DELTA</span> <li><span class="parameter">ADJUST_SCALE_DELTA</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Scale step on each height adjust step Scale step on each height adjust step. Default: 0.02
(<em>default</em> 0.02)
</li> </li>
</ul> </ul>
@@ -447,6 +513,66 @@ Words &lt;nobr&gt;inside tag&lt;/nobr&gt; won't <span class="keyword">break</spa
</dd>
<dt>
<a name = "icon_prefab"></a>
<strong>icon_prefab</strong>
</dt>
<dd>
The icon prefab node
<ul>
<li><span class="parameter">icon_prefab</span>
<span class="types"><span class="type">node</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "root"></a>
<strong>root</strong>
</dt>
<dd>
The root node of the Rich Text
<ul>
<li><span class="parameter">root</span>
<span class="types"><span class="type">node</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "text_prefab"></a>
<strong>text_prefab</strong>
</dt>
<dd>
The text prefab node
<ul>
<li><span class="parameter">text_prefab</span>
<span class="types"><span class="type">node</span></span>
</li>
</ul>
</dd> </dd>
</dl> </dl>

View File

@@ -167,6 +167,14 @@
<td class="name" nowrap><a href="#set_vertical_scroll">set_vertical_scroll(self, state)</a></td> <td class="name" nowrap><a href="#set_vertical_scroll">set_vertical_scroll(self, state)</a></td>
<td class="summary">Lock or unlock vertical scroll</td> <td class="summary">Lock or unlock vertical scroll</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#set_view_size">set_view_size(self, size)</a></td>
<td class="summary">Set new scroll view size in case the node size was changed.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#update_view_size">update_view_size(self)</a></td>
<td class="summary">Refresh scroll view size</td>
</tr>
</table> </table>
<h2><a href="#Tables">Tables</a></h2> <h2><a href="#Tables">Tables</a></h2>
<table class="function_list"> <table class="function_list">
@@ -177,6 +185,10 @@
</table> </table>
<h2><a href="#Fields">Fields</a></h2> <h2><a href="#Fields">Fields</a></h2>
<table class="function_list"> <table class="function_list">
<tr>
<td class="name" nowrap><a href="#_is_inert">_is_inert</a></td>
<td class="summary">Flag, if scroll now moving by inertion</td>
</tr>
<tr> <tr>
<td class="name" nowrap><a href="#available_pos">available_pos</a></td> <td class="name" nowrap><a href="#available_pos">available_pos</a></td>
<td class="summary">Available position for content node: (min_x, max_y, max_x, min_y)</td> <td class="summary">Available position for content node: (min_x, max_y, max_x, min_y)</td>
@@ -229,6 +241,10 @@
<td class="name" nowrap><a href="#view_node">view_node</a></td> <td class="name" nowrap><a href="#view_node">view_node</a></td>
<td class="summary">Scroll view node</td> <td class="summary">Scroll view node</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#view_size">view_size</a></td>
<td class="summary">Scroll view size</td>
</tr>
</table> </table>
<br/> <br/>
@@ -525,7 +541,7 @@
</li> </li>
<li><span class="parameter">node</span> <li><span class="parameter">node</span>
<span class="types"><span class="type">node</span></span> <span class="types"><span class="type">node</span> or <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
Gui node Gui node
</li> </li>
</ul> </ul>
@@ -683,7 +699,7 @@
The new size for content node The new size for content node
</li> </li>
<li><span class="parameter">offset</span> <li><span class="parameter">offset</span>
<span class="types"><span class="type">vector3</span></span> <span class="types"><span class="type">vector3</span> or <span class="type">nil</span></span>
Offset value to set, where content is starts Offset value to set, where content is starts
</li> </li>
</ul> </ul>
@@ -729,6 +745,58 @@
</dd>
<dt>
<a name = "set_view_size"></a>
<strong>set_view_size(self, size)</strong>
</dt>
<dd>
Set new scroll view size in case the node size was changed.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Scroll</span></span>
<a href="../modules/Scroll.html#">Scroll</a>
</li>
<li><span class="parameter">size</span>
<span class="types"><span class="type">vector3</span></span>
The new size for view node
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.scroll</span></span>
Current scroll instance
</ol>
</dd>
<dt>
<a name = "update_view_size"></a>
<strong>update_view_size(self)</strong>
</dt>
<dd>
Refresh scroll view size
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Scroll</span></span>
<a href="../modules/Scroll.html#">Scroll</a>
</li>
</ul>
</dd> </dd>
</dl> </dl>
<h2 class="section-header "><a name="Tables"></a>Tables</h2> <h2 class="section-header "><a name="Tables"></a>Tables</h2>
@@ -747,64 +815,52 @@
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">FRICT</span> <li><span class="parameter">FRICT</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Multiplier for free inertion Multiplier for free inertion. Default: 0
(<em>default</em> 0)
</li> </li>
<li><span class="parameter">FRICT_HOLD</span> <li><span class="parameter">FRICT_HOLD</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Multiplier for inertion, while touching Multiplier for inertion, while touching. Default: 0
(<em>default</em> 0)
</li> </li>
<li><span class="parameter">INERT_THRESHOLD</span> <li><span class="parameter">INERT_THRESHOLD</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Scroll speed to stop inertion Scroll speed to stop inertion. Default: 3
(<em>default</em> 3)
</li> </li>
<li><span class="parameter">INERT_SPEED</span> <li><span class="parameter">INERT_SPEED</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Multiplier for inertion speed Multiplier for inertion speed. Default: 30
(<em>default</em> 30)
</li> </li>
<li><span class="parameter">POINTS_DEADZONE</span> <li><span class="parameter">POINTS_DEADZONE</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Speed to check points of interests in no_inertion mode Speed to check points of interests in no_inertion mode. Default: 20
(<em>default</em> 20)
</li> </li>
<li><span class="parameter">BACK_SPEED</span> <li><span class="parameter">BACK_SPEED</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Scroll back returning lerp speed Scroll back returning lerp speed. Default: 35
(<em>default</em> 0.35)
</li> </li>
<li><span class="parameter">ANIM_SPEED</span> <li><span class="parameter">ANIM_SPEED</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Scroll gui.animation speed for scroll_to function Scroll gui.animation speed for scroll_to function. Default: 2
(<em>default</em> 0.2)
</li> </li>
<li><span class="parameter">EXTRA_STRETCH_SIZE</span> <li><span class="parameter">EXTRA_STRETCH_SIZE</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
extra size in pixels outside of scroll (stretch effect) extra size in pixels outside of scroll (stretch effect). Default: 0
(<em>default</em> 0)
</li> </li>
<li><span class="parameter">SMALL_CONTENT_SCROLL</span> <li><span class="parameter">SMALL_CONTENT_SCROLL</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If true, content node with size less than view node size can be scrolled If true, content node with size less than view node size can be scrolled. Default: false
(<em>default</em> false)
</li> </li>
<li><span class="parameter">WHEEL_SCROLL_SPEED</span> <li><span class="parameter">WHEEL_SCROLL_SPEED</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling. Default: 0
(<em>default</em> 0)
</li> </li>
<li><span class="parameter">WHEEL_SCROLL_INVERTED</span> <li><span class="parameter">WHEEL_SCROLL_INVERTED</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If true, invert direction for touchpad and mouse wheel scroll If true, invert direction for touchpad and mouse wheel scroll. Default: false
(<em>default</em> false)
</li> </li>
<li><span class="parameter">WHEEL_SCROLL_BY_INERTION</span> <li><span class="parameter">WHEEL_SCROLL_BY_INERTION</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If true, wheel will add inertion to scroll. Direct set position otherwise. If true, wheel will add inertion to scroll. Direct set position otherwise.. Default: false
(<em>default</em> false)
</li> </li>
</ul> </ul>
@@ -817,6 +873,26 @@
<h2 class="section-header "><a name="Fields"></a>Fields</h2> <h2 class="section-header "><a name="Fields"></a>Fields</h2>
<dl class="function"> <dl class="function">
<dt>
<a name = "_is_inert"></a>
<strong>_is_inert</strong>
</dt>
<dd>
Flag, if scroll now moving by inertion
<ul>
<li><span class="parameter">_is_inert</span>
<span class="types"><span class="type">boolean</span></span>
</li>
</ul>
</dd>
<dt> <dt>
<a name = "available_pos"></a> <a name = "available_pos"></a>
<strong>available_pos</strong> <strong>available_pos</strong>
@@ -1027,9 +1103,8 @@
<ul> <ul>
<li><span class="parameter">selected</span> <li><span class="parameter">selected</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
(<em>optional</em>)
</li> </li>
</ul> </ul>
@@ -1077,6 +1152,26 @@
</dd>
<dt>
<a name = "view_size"></a>
<strong>view_size</strong>
</dt>
<dd>
Scroll view size
<ul>
<li><span class="parameter">view_size</span>
<span class="types"><span class="type">vector3</span></span>
</li>
</ul>
</dd> </dd>
</dl> </dl>

View File

@@ -86,10 +86,18 @@
<td class="summary">The <a href="../modules/Slider.html#">Slider</a> constructor</td> <td class="summary">The <a href="../modules/Slider.html#">Slider</a> constructor</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#is_enabled">is_enabled(self)</a></td>
<td class="summary">Check if Slider component is enabled</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set">set(self, value, is_silent)</a></td> <td class="name" nowrap><a href="#set">set(self, value, is_silent)</a></td>
<td class="summary">Set value for slider</td> <td class="summary">Set value for slider</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#set_enabled">set_enabled(self, is_enabled)</a></td>
<td class="summary">Set Slider input enabled or disabled</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_input_node">set_input_node(self, input_node)</a></td> <td class="name" nowrap><a href="#set_input_node">set_input_node(self, input_node)</a></td>
<td class="summary">Set input zone for slider.</td> <td class="summary">Set input zone for slider.</td>
</tr> </tr>
@@ -177,6 +185,33 @@
</dd>
<dt>
<a name = "is_enabled"></a>
<strong>is_enabled(self)</strong>
</dt>
<dd>
Check if Slider component is enabled
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Slider</span></span>
<a href="../modules/Slider.html#">Slider</a>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">boolean</span></span>
</ol>
</dd> </dd>
<dt> <dt>
<a name = "set"></a> <a name = "set"></a>
@@ -206,6 +241,31 @@
</dd>
<dt>
<a name = "set_enabled"></a>
<strong>set_enabled(self, is_enabled)</strong>
</dt>
<dd>
Set Slider input enabled or disabled
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Slider</span></span>
<a href="../modules/Slider.html#">Slider</a>
</li>
<li><span class="parameter">is_enabled</span>
<span class="types"><span class="type">boolean</span></span>
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "set_input_node"></a> <a name = "set_input_node"></a>
@@ -225,7 +285,7 @@
<a href="../modules/Slider.html#">Slider</a> <a href="../modules/Slider.html#">Slider</a>
</li> </li>
<li><span class="parameter">input_node</span> <li><span class="parameter">input_node</span>
<span class="types"><a class="type" href="../modules/Slider.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Slider.html#node">node</a>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
</li> </li>
</ul> </ul>
@@ -291,7 +351,7 @@
<ul> <ul>
<li><span class="parameter">dist</span> <li><span class="parameter">dist</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">vector3</span></span>
</li> </li>
</ul> </ul>

View File

@@ -138,7 +138,7 @@
<td class="summary">Return grid content size</td> <td class="summary">Return grid content size</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, parent, element[, in_row=1])</a></td> <td class="name" nowrap><a href="#init">init(self, parent, element, in_row)</a></td>
<td class="summary">The <a href="../modules/StaticGrid.html#">StaticGrid</a> constructor</td> <td class="summary">The <a href="../modules/StaticGrid.html#">StaticGrid</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -154,9 +154,21 @@
<td class="summary">Set new in_row elements for grid</td> <td class="summary">Set new in_row elements for grid</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#set_item_size">set_item_size(self[, width[, height]])</a></td>
<td class="summary">Set new node size for grid</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_items">set_items(self, nodes[, is_instant=false])</a></td>
<td class="summary">Set new items to the grid.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#set_position_function">set_position_function(self, callback)</a></td> <td class="name" nowrap><a href="#set_position_function">set_position_function(self, callback)</a></td>
<td class="summary">Change set position function for grid nodes.</td> <td class="summary">Change set position function for grid nodes.</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#sort_nodes">sort_nodes(self, comparator)</a></td>
<td class="summary">Sort grid nodes by custom comparator function</td>
</tr>
</table> </table>
<h2><a href="#Tables">Tables</a></h2> <h2><a href="#Tables">Tables</a></h2>
<table class="function_list"> <table class="function_list">
@@ -496,7 +508,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, parent, element[, in_row=1])</strong> <strong>init(self, parent, element, in_row)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/StaticGrid.html#">StaticGrid</a> constructor The <a href="../modules/StaticGrid.html#">StaticGrid</a> constructor
@@ -517,9 +529,8 @@
Element prefab. Need to get it size Element prefab. Need to get it size
</li> </li>
<li><span class="parameter">in_row</span> <li><span class="parameter">in_row</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
How many nodes in row can be placed How many nodes in row can be placed. By default 1
(<em>default</em> 1)
</li> </li>
</ul> </ul>
@@ -622,6 +633,73 @@
</dd>
<dt>
<a name = "set_item_size"></a>
<strong>set_item_size(self[, width[, height]])</strong>
</dt>
<dd>
Set new node size for grid
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">StaticGrid</span></span>
<a href="../modules/StaticGrid.html#">StaticGrid</a>
</li>
<li><span class="parameter">width</span>
<span class="types"><span class="type">number</span></span>
The new node width
(<em>optional</em>)
</li>
<li><span class="parameter">height</span>
<span class="types"><span class="type">number</span></span>
The new node height
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.static_grid</span></span>
Current grid instance
</ol>
</dd>
<dt>
<a name = "set_items"></a>
<strong>set_items(self, nodes[, is_instant=false])</strong>
</dt>
<dd>
Set new items to the grid. All previous items will be removed
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">StaticGrid</span></span>
<a href="../modules/StaticGrid.html#">StaticGrid</a>
</li>
<li><span class="parameter">nodes</span>
<span class="types"><span class="type">node[]</span></span>
The new grid nodes
</li>
<li><span class="parameter">is_instant</span>
<span class="types"><span class="type">boolean</span></span>
If true, update node positions instantly
(<em>default</em> false)
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "set_position_function"></a> <a name = "set_position_function"></a>
@@ -654,6 +732,37 @@
</dd>
<dt>
<a name = "sort_nodes"></a>
<strong>sort_nodes(self, comparator)</strong>
</dt>
<dd>
Sort grid nodes by custom comparator function
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">StaticGrid</span></span>
<a href="../modules/StaticGrid.html#">StaticGrid</a>
</li>
<li><span class="parameter">comparator</span>
<span class="types"><span class="type">function</span></span>
The comparator function. (a, b) -> boolean
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">druid.static_grid</span></span>
Current grid instance
</ol>
</dd> </dd>
</dl> </dl>
<h2 class="section-header "><a name="Tables"></a>Tables</h2> <h2 class="section-header "><a name="Tables"></a>Tables</h2>
@@ -672,14 +781,12 @@
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">IS_DYNAMIC_NODE_POSES</span> <li><span class="parameter">IS_DYNAMIC_NODE_POSES</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If true, always center grid content as grid pivot sets If true, always center grid content as grid pivot sets. Default: false
(<em>default</em> false)
</li> </li>
<li><span class="parameter">IS_ALIGN_LAST_ROW</span> <li><span class="parameter">IS_ALIGN_LAST_ROW</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If true, always align last row of the grid as grid pivot sets If true, always align last row of the grid as grid pivot sets. Default: false
(<em>default</em> false)
</li> </li>
</ul> </ul>

View File

@@ -169,7 +169,7 @@
<a href="../modules/Swipe.html#">Swipe</a> <a href="../modules/Swipe.html#">Swipe</a>
</li> </li>
<li><span class="parameter">zone</span> <li><span class="parameter">zone</span>
<span class="types"><a class="type" href="../modules/Swipe.html#node">node</a></span> <span class="types"><a class="type" href="../modules/Swipe.html#node">node</a>, <a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Gui node Gui node
</li> </li>
</ul> </ul>
@@ -196,19 +196,16 @@
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">SWIPE_TIME</span> <li><span class="parameter">SWIPE_TIME</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Maximum time for swipe trigger Maximum time for swipe trigger. Default: 0.4
(<em>default</em> 0.4)
</li> </li>
<li><span class="parameter">SWIPE_THRESHOLD</span> <li><span class="parameter">SWIPE_THRESHOLD</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Minimum distance for swipe trigger Minimum distance for swipe trigger. Default: 50
(<em>default</em> 50)
</li> </li>
<li><span class="parameter">SWIPE_TRIGGER_ON_MOVE</span> <li><span class="parameter">SWIPE_TRIGGER_ON_MOVE</span>
<span class="types"><span class="type">boolean</span></span> <span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
If true, trigger on swipe moving, not only release action If true, trigger on swipe moving, not only release action. Default: false
(<em>default</em> false)
</li> </li>
</ul> </ul>

View File

@@ -105,11 +105,15 @@
<td class="summary">Return current text adjust type</td> <td class="summary">Return current text adjust type</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#get_text_index_by_width">get_text_index_by_width(self, width)</a></td>
<td class="summary">Get chars count by width</td>
</tr>
<tr>
<td class="name" nowrap><a href="#get_text_size">get_text_size(self, text)</a></td> <td class="name" nowrap><a href="#get_text_size">get_text_size(self, text)</a></td>
<td class="summary">Calculate text width with font with respect to trailing space</td> <td class="summary">Calculate text width with font with respect to trailing space</td>
</tr> </tr>
<tr> <tr>
<td class="name" nowrap><a href="#init">init(self, node, value[, adjust_type=downscale])</a></td> <td class="name" nowrap><a href="#init">init(self, node, value, adjust_type)</a></td>
<td class="summary">The <a href="../modules/Text.html#">Text</a> constructor</td> <td class="summary">The <a href="../modules/Text.html#">Text</a> constructor</td>
</tr> </tr>
<tr> <tr>
@@ -247,6 +251,37 @@
</dd>
<dt>
<a name = "get_text_index_by_width"></a>
<strong>get_text_index_by_width(self, width)</strong>
</dt>
<dd>
Get chars count by width
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">self</span>
<span class="types"><span class="type">Text</span></span>
<a href="../modules/Text.html#">Text</a>
</li>
<li><span class="parameter">width</span>
<span class="types"><span class="type">number</span></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">number</span></span>
Chars count
</ol>
</dd> </dd>
<dt> <dt>
<a name = "get_text_size"></a> <a name = "get_text_size"></a>
@@ -263,8 +298,8 @@
<a href="../modules/Text.html#">Text</a> <a href="../modules/Text.html#">Text</a>
</li> </li>
<li><span class="parameter">text</span> <li><span class="parameter">text</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
|nil
</li> </li>
</ul> </ul>
@@ -284,7 +319,7 @@
</dd> </dd>
<dt> <dt>
<a name = "init"></a> <a name = "init"></a>
<strong>init(self, node, value[, adjust_type=downscale])</strong> <strong>init(self, node, value, adjust_type)</strong>
</dt> </dt>
<dd> <dd>
The <a href="../modules/Text.html#">Text</a> constructor The <a href="../modules/Text.html#">Text</a> constructor
@@ -302,12 +337,11 @@
</li> </li>
<li><span class="parameter">value</span> <li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Initial text. Default value is node text from GUI scene. Initial text. Default value is node text from GUI scene. Default: nil
</li> </li>
<li><span class="parameter">adjust_type</span> <li><span class="parameter">adjust_type</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
(<em>default</em> downscale)
</li> </li>
</ul> </ul>
@@ -544,7 +578,7 @@
<a href="../modules/Text.html#">Text</a> <a href="../modules/Text.html#">Text</a>
</li> </li>
<li><span class="parameter">adjust_type</span> <li><span class="parameter">adjust_type</span>
<span class="types"><span class="type">number</span> or <span class="type">nil</span></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
See const.TEXT_ADJUST. If pass nil - use current adjust type See const.TEXT_ADJUST. If pass nil - use current adjust type
</li> </li>
<li><span class="parameter">minimal_scale</span> <li><span class="parameter">minimal_scale</span>
@@ -612,14 +646,20 @@
<h3>Fields:</h3> <h3>Fields:</h3>
<ul> <ul>
<li><span class="parameter">TRIM_POSTFIX</span> <li><span class="parameter">TRIM_POSTFIX</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
The postfix for TRIM adjust type The postfix for TRIM adjust type. Default: ...
(<em>default</em> ...)
</li> </li>
<li><span class="parameter">DEFAULT_ADJUST</span> <li><span class="parameter">DEFAULT_ADJUST</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
The default adjust type for any text component The default adjust type for any text component. Default: DOWNSCALE
(<em>default</em> DOWNSCALE) </li>
<li><span class="parameter">ADJUST_STEPS</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Amount of iterations for text adjust by height. Default: 20
</li>
<li><span class="parameter">ADJUST_SCALE_DELTA</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
Scale step on each height adjust step. Default: 0.02
</li> </li>
</ul> </ul>

View File

@@ -158,7 +158,7 @@
Gui text node Gui text node
</li> </li>
<li><span class="parameter">seconds_from</span> <li><span class="parameter">seconds_from</span>
<span class="types"><span class="type">number</span></span> <span class="types"><span class="type">number</span> or <span class="type">nil</span></span>
Start timer value in seconds Start timer value in seconds
</li> </li>
<li><span class="parameter">seconds_to</span> <li><span class="parameter">seconds_to</span>

View File

@@ -0,0 +1,95 @@
<!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 Framework</title>
<link rel="stylesheet" href="../ldoc_fixed.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>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/BackHandler.html">BackHandler</a></li>
<li><a href="../modules/BaseComponent.html">BaseComponent</a></li>
<li><a href="../modules/Blocker.html">Blocker</a></li>
<li><a href="../modules/Button.html">Button</a></li>
<li><a href="../modules/Checkbox.html">Checkbox</a></li>
<li><a href="../modules/CheckboxGroup.html">CheckboxGroup</a></li>
<li><a href="../modules/DataList.html">DataList</a></li>
<li><a href="../modules/Drag.html">Drag</a></li>
<li><a href="../modules/Druid.html">Druid</a></li>
<li><a href="../modules/DruidEvent.html">DruidEvent</a></li>
<li><a href="../modules/DruidInstance.html">DruidInstance</a></li>
<li><a href="../modules/DynamicGrid.html">DynamicGrid</a></li>
<li><a href="../modules/Helper.html">Helper</a></li>
<li><a href="../modules/Hotkey.html">Hotkey</a></li>
<li><a href="../modules/Hover.html">Hover</a></li>
<li><a href="../modules/Input.html">Input</a></li>
<li><a href="../modules/LangText.html">LangText</a></li>
<li><a href="../modules/PinKnob.html">PinKnob</a></li>
<li><a href="../modules/Progress.html">Progress</a></li>
<li><a href="../modules/RadioGroup.html">RadioGroup</a></li>
<li><a href="../modules/RichInput.html">RichInput</a></li>
<li><a href="../modules/RichText.html">RichText</a></li>
<li><a href="../modules/Scroll.html">Scroll</a></li>
<li><a href="../modules/Slider.html">Slider</a></li>
<li><a href="../modules/StaticGrid.html">StaticGrid</a></li>
<li><a href="../modules/Swipe.html">Swipe</a></li>
<li><a href="../modules/Text.html">Text</a></li>
<li><a href="../modules/Timer.html">Timer</a></li>
<li><strong>druid.extended.layout</strong></li>
</ul>
</div>
<div id="content">
<h1>Module <code>druid.extended.layout</code></h1>
<p>Druid layout module
<p> <b># Overview #</b>
<p> Layout component works like Dynamic Grid before - for aligning elements in a row or column.</p>
<p> Works like a Figma layout.
<p> <b># Notes</p>
<br/>
<br/>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc TESTING</a></i>
<i style="float:right;">Last updated 2015-01-01 12:00:00 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@@ -0,0 +1,93 @@
<!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 Framework</title>
<link rel="stylesheet" href="../ldoc_fixed.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>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/BackHandler.html">BackHandler</a></li>
<li><a href="../modules/BaseComponent.html">BaseComponent</a></li>
<li><a href="../modules/Blocker.html">Blocker</a></li>
<li><a href="../modules/Button.html">Button</a></li>
<li><a href="../modules/Checkbox.html">Checkbox</a></li>
<li><a href="../modules/CheckboxGroup.html">CheckboxGroup</a></li>
<li><a href="../modules/DataList.html">DataList</a></li>
<li><a href="../modules/Drag.html">Drag</a></li>
<li><a href="../modules/Druid.html">Druid</a></li>
<li><a href="../modules/DruidEvent.html">DruidEvent</a></li>
<li><a href="../modules/DruidInstance.html">DruidInstance</a></li>
<li><a href="../modules/DynamicGrid.html">DynamicGrid</a></li>
<li><a href="../modules/Helper.html">Helper</a></li>
<li><a href="../modules/Hotkey.html">Hotkey</a></li>
<li><a href="../modules/Hover.html">Hover</a></li>
<li><a href="../modules/Input.html">Input</a></li>
<li><a href="../modules/LangText.html">LangText</a></li>
<li><a href="../modules/Layout.html">Layout</a></li>
<li><a href="../modules/PinKnob.html">PinKnob</a></li>
<li><a href="../modules/Progress.html">Progress</a></li>
<li><a href="../modules/RadioGroup.html">RadioGroup</a></li>
<li><a href="../modules/RichInput.html">RichInput</a></li>
<li><a href="../modules/RichText.html">RichText</a></li>
<li><a href="../modules/Scroll.html">Scroll</a></li>
<li><a href="../modules/Slider.html">Slider</a></li>
<li><a href="../modules/StaticGrid.html">StaticGrid</a></li>
<li><a href="../modules/Swipe.html">Swipe</a></li>
<li><a href="../modules/Text.html">Text</a></li>
<li><a href="../modules/Timer.html">Timer</a></li>
<li><strong>druid.system.utf8</strong></li>
</ul>
</div>
<div id="content">
<h1>Module <code>druid.system.utf8</code></h1>
<p></p>
<p></p>
<br/>
<br/>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc TESTING</a></i>
<i style="float:right;">Last updated 2015-01-01 12:00:00 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@@ -14,21 +14,14 @@ A basic custom component template looks like this (you can copy it from `/druid/
```lua ```lua
local component = require("druid.component") local component = require("druid.component")
---@class component_name : druid.base_component ---@class component_name: druid.base_component
local Component = component.create("component_name") local Component = component.create("component_name")
local SCHEME = {
ROOT = "root",
BUTTON = "button",
}
function Component:init(template, nodes) function Component:init(template, nodes)
self:set_template(template) self.druid = self:get_druid(template, nodes)
self:set_nodes(nodes) self.root = self:get_node("root")
self.root = self:get_node(SCHEME.ROOT)
self.druid = self:get_druid()
self.button = self.druid:new_button(SCHEME.BUTTON, function() end) self.button = self.druid:new_button("button", function() end)
end end
function Component:on_remove() end function Component:on_remove() end
@@ -43,18 +36,12 @@ A full custom component template looks like this (you can copy it from `/druid/t
```lua ```lua
local component = require("druid.component") local component = require("druid.component")
---@class component_name : druid.base_component ---@class component_name: druid.base_component
local Component = component.create("component_name") local Component = component.create("component_name")
local SCHEME = {
ROOT = "root",
BUTTON = "button",
}
function Component:init(template, nodes) function Component:init(template, nodes)
self:set_template(template) self.druid = self:get_druid(template, nodes)
self:set_nodes(nodes) self.root = self:get_node("root")
self.root = self:get_node(SCHEME.ROOT)
self.druid = self:get_druid()
end end
function Component:update(dt) end function Component:update(dt) end
@@ -92,7 +79,7 @@ local my_component = require("my.amazing.component")
function init(self) function init(self)
self.druid = druid.new(self) self.druid = druid.new(self)
self.druid:new(my_component, "template_name", nodes) self.druid:new(my_component, "template_name")
end end
``` ```
@@ -107,6 +94,7 @@ local druid = require("druid.druid")
local my_component = require("my.amazing.component") local my_component = require("my.amazing.component")
function init(self) function init(self)
-- Register makes a "druid:new_{component_name}" function available
druid.register("my_component", my_component) druid.register("my_component", my_component)
end end
``` ```
@@ -145,36 +133,7 @@ Available keywords:
- `blocker`: Adds a [Druid Blocker](01-components.md#blocker) component. - `blocker`: Adds a [Druid Blocker](01-components.md#blocker) component.
- `slider`: Adds a [Druid Slider](01-components.md#slider) component. You should adjust the end position of the Slider after generating the file. - `slider`: Adds a [Druid Slider](01-components.md#slider) component. You should adjust the end position of the Slider after generating the file.
- `progress`: Adds a [Druid Progress](01-components.md#progress) component. - `progress`: Adds a [Druid Progress](01-components.md#progress) component.
- `timer`: Adds a [Dr - `timer`: Adds a [Druid Timer](01-components.md#timer) component.
uid Timer](01-components.md#timer) component.
## Best Practices for Custom Components
When working with each component, it's recommended to describe the component scheme in the following 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)
self:set_template(template_name)
self:set_nodes(node_table)
local root = self:get_node(SCHEME.ROOT)
local druid = self:get_druid()
-- Create components inside this component using the inner druid instance
end
```
## The Power of Using Templates ## The Power of Using Templates

View File

@@ -3,7 +3,7 @@
## Input Bindings ## Input Bindings
By default, **Druid** utilizes the `/builtins/input/all.input_binding` for input bindings. By default, **Druid** uses all key names from Defold's default `/builtins/input/all.input_binding` for input bindings.
**Druid** requires the following input bindings: **Druid** requires the following input bindings:
@@ -14,6 +14,11 @@ By default, **Druid** utilizes the `/builtins/input/all.input_binding` for input
- Key trigger: `Back` -> `key_back` (for BackHandler component, Android back button, input component) - Key trigger: `Back` -> `key_back` (for BackHandler component, Android back button, input component)
- Key trigger: `Enter` -> `key_enter` (for Input component, optional) - Key trigger: `Enter` -> `key_enter` (for Input component, optional)
- Key trigger: `Esc` -> `key_esc` (for Input component, optional) - Key trigger: `Esc` -> `key_esc` (for Input component, optional)
- Key trigger: `Left` -> `key_left` (for Rich Input component, optional)
- Key trigger: `Right` -> `key_right` (for Rich Input component, optional)
- Key trigger: `Shift` -> `key_lshift` (for Rich Input component, optional)
- Key trigger: `Ctrl` -> `key_lctrl` (for Rich Input component, optional)
- Key trigger: `Super` -> `key_lsuper` (for Rich Input component, optional)
- Touch triggers: `Touch multi` -> `touch_multi` (for Scroll component) - Touch triggers: `Touch multi` -> `touch_multi` (for Scroll component)
![](../media/input_binding_2.png) ![](../media/input_binding_2.png)
@@ -37,6 +42,11 @@ input_key_backspace = key_backspace
input_multitouch = touch_multi input_multitouch = touch_multi
input_scroll_up = mouse_wheel_up input_scroll_up = mouse_wheel_up
input_scroll_down = mouse_wheel_down input_scroll_down = mouse_wheel_down
input_key_left = key_left
input_key_right = key_right
input_key_lshift = key_lshift
input_key_lctrl = key_lctrl
input_key_lsuper = key_lsuper
``` ```

View File

@@ -500,3 +500,28 @@ Thanks to the my supporters:
Please support me if you like this project! It will help me keep engaged to update **Druid** and make it even better! Please support me if you like this project! It will help me keep engaged to update **Druid** and make it even better!
[![Github-sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/insality) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/insality) [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/insality) [![Github-sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/insality) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/insality) [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/insality)
### Druid 0.12.0
**Changelog 0.12.0**
- New Logo!
- [Example] New Example Page with 40+ examples
- [Data List] Rework Data List. Now only works with Static Grid only. Now the Data List more stable with extended API.
- Add Cached Data List option. This used less memory (it's really much optimized) but requires uses the `on_add_element` and `on_remove_element` events to setup your nodes. All components should be the same class.
- [Rich Text] The Rich Text now applied to the text node instead of Rich Text Template (contained 3 nodes before - root, text and image prefabs)
- [Rich Input] Updated Rich Input. Now it goes with selection and cursor navigation. Added new input keys for setup in Druid (arrows keys, ctrl, shift)
- [System] Updated and fixed annotations
- [System] Removed `middleclass.lua`
- [System] Add `self:get_druid(template, nodes)` to escape the `self:set_template(template)` and `self:set_nodes(nodes)` calls in custom components
- [Input] Now user can tap from one text input area to another with one click. Before first tap is closed the focus on selected input.
- [Layout] Removed Layout component. Add new Layout component what do a some different things. It's like Dynamic Grid but with more control and settings.
- [Dynamic Grid] Deprecated Dynamic Grid. Layout will be instead of it.
- [Drag] Add touch param to Drag callbacks, it's much easier to add custom logic with knowledge of input action data.
- [Scroll] Add `scroll.view_size`, `scroll:set_view_size(size)` and `scroll:update_view_size()` functions to manage with current scroll input area and scroll visible part
- [Static Grid] Add `grid:set_item_size(size)`, `grid:sort_nodes(comparator)` functions
- [Text] Seems adjust by height for multiline text is workings good now
- [Rich Input] Extended Rich Input API
- [Progress Bar] More accurate scaling for progress bars fow images with slice9 params
- [Slider] Fix several slider issues in slider setup

View File

@@ -1,8 +0,0 @@
# Game Examples
## Family Island
## Sea Battle: Universe
## Monkey Mart

File diff suppressed because it is too large Load Diff

View File

@@ -123,7 +123,7 @@
-- In default case equals to clickable node. -- In default case equals to clickable node.
-- --
-- Usecase: You have the big clickable panel, but want to animate only one small icon on it. -- Usecase: You have the big clickable panel, but want to animate only one small icon on it.
-- @tfield[opt=node] node anim_node -- @tfield node|nil anim_node Default node
---Custom args for any Button event. Setup in Button constructor ---Custom args for any Button event. Setup in Button constructor
-- @tfield any params -- @tfield any params
@@ -240,7 +240,12 @@ local function on_button_release(self)
is_double_click = is_double_click and self.on_double_click:is_exist() is_double_click = is_double_click and self.on_double_click:is_exist()
if is_long_click then if is_long_click then
local is_hold_complete = (time - self.last_pressed_time) >= self.style.AUTOHOLD_TRIGGER
if is_hold_complete then
on_button_long_click(self) on_button_long_click(self)
else
self.on_click_outside:trigger(self:get_context(), self.params, self)
end
elseif is_double_click then elseif is_double_click then
on_button_double_click(self) on_button_double_click(self)
else else
@@ -258,9 +263,9 @@ end
-- You can override this component styles params in Druid styles table -- You can override this component styles params in Druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=0.4] number LONGTAP_TIME Minimum time to trigger on_hold_callback -- @tfield number|nil LONGTAP_TIME Minimum time to trigger on_hold_callback. Default: 0.4
-- @tfield[opt=0.8] number AUTOHOLD_TRIGGER Maximum hold time to trigger button release while holding -- @tfield number|nil AUTOHOLD_TRIGGER Maximum hold time to trigger button release while holding. Default: 0.8
-- @tfield[opt=0.4] number DOUBLETAP_TIME Time between double taps -- @tfield number|nil DOUBLETAP_TIME Time between double taps. Default: 0.4
-- @tfield function on_click function(self, node) -- @tfield function on_click function(self, node)
-- @tfield function on_click_disabled function(self, node) -- @tfield function on_click_disabled function(self, node)
-- @tfield function on_hover function(self, node, hover_state) -- @tfield function on_hover function(self, node, hover_state)
@@ -339,10 +344,7 @@ function Button.on_input(self, action_id, action)
return false return false
end end
if not self:is_enabled() then local is_consume = true
return false
end
local is_pick = true local is_pick = true
local is_key_trigger = (action_id == self.key_trigger) local is_key_trigger = (action_id == self.key_trigger)
if not is_key_trigger then if not is_key_trigger then
@@ -365,6 +367,7 @@ function Button.on_input(self, action_id, action)
if is_key_trigger then if is_key_trigger then
self.hover:set_hover(not action.released) self.hover:set_hover(not action.released)
is_consume = false
end end
if action.pressed then if action.pressed then
@@ -380,19 +383,19 @@ function Button.on_input(self, action_id, action)
on_button_click(self) on_button_click(self)
end) end)
end end
return true return is_consume
end end
-- While hold button, repeat rate pick from input.repeat_interval -- While hold button, repeat rate pick from input.repeat_interval
if action.repeated then if action.repeated then
if self.on_repeated_click:is_exist() and self.can_action then if self.on_repeated_click:is_exist() and self.can_action then
on_button_repeated_click(self) on_button_repeated_click(self)
return true return is_consume
end end
end end
if action.released then if action.released then
return on_button_release(self) return on_button_release(self) and is_consume
end end
if self.can_action and self.on_long_click:is_exist() then if self.can_action and self.on_long_click:is_exist() then
@@ -400,21 +403,23 @@ function Button.on_input(self, action_id, action)
if self.style.AUTOHOLD_TRIGGER <= press_time then if self.style.AUTOHOLD_TRIGGER <= press_time then
on_button_release(self) on_button_release(self)
return true return is_consume
end end
if press_time >= self.style.LONGTAP_TIME then if press_time >= self.style.LONGTAP_TIME then
on_button_hold(self, press_time) on_button_hold(self, press_time)
return true return is_consume
end end
end end
return not self.disabled return not self.disabled and is_consume
end end
function Button.on_input_interrupt(self) function Button.on_input_interrupt(self)
self.can_action = false self.can_action = false
self.hover:set_hover(false)
self.hover:set_mouse_hover(false)
end end
@@ -478,7 +483,7 @@ end
-- --
-- This functions calls automatically if you don't disable it in game.project: druid.no_stencil_check -- This functions calls automatically if you don't disable it in game.project: druid.no_stencil_check
-- @tparam Button self @{Button} -- @tparam Button self @{Button}
-- @tparam node|nil zone Gui node -- @tparam node|string|nil zone Gui node
-- @treturn Button Current button instance -- @treturn Button Current button instance
-- @usage -- @usage
-- button:set_click_zone("stencil_node") -- button:set_click_zone("stencil_node")

View File

@@ -22,10 +22,10 @@
--- Event on drag start callback(self, touch) --- Event on drag start callback(self, touch)
-- @tfield DruidEvent on_drag_start @{DruidEvent} -- @tfield DruidEvent on_drag_start @{DruidEvent}
--- on drag progress callback(self, dx, dy, total_x, total_y) --- on drag progress callback(self, dx, dy, total_x, total_y, touch)
-- @tfield DruidEvent on_drag Event @{DruidEvent} -- @tfield DruidEvent on_drag Event @{DruidEvent}
--- Event on drag end callback(self, total_x, total_y) --- Event on drag end callback(self, total_x, total_y, touch)
-- @tfield DruidEvent on_drag_end @{DruidEvent} -- @tfield DruidEvent on_drag_end @{DruidEvent}
--- Is component now touching --- Is component now touching
@@ -175,8 +175,8 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=10] number DRAG_DEADZONE Distance in pixels to start dragging -- @tfield number|nil DRAG_DEADZONE Distance in pixels to start dragging. Default: 10
-- @tfield[opt=false] boolean NO_USE_SCREEN_KOEF If screen aspect ratio affects on drag values -- @tfield boolean|nil NO_USE_SCREEN_KOEF If screen aspect ratio affects on drag values. Default: false
function Drag.on_style_change(self, style) function Drag.on_style_change(self, style)
self.style = {} self.style = {}
self.style.DRAG_DEADZONE = style.DRAG_DEADZONE or 10 self.style.DRAG_DEADZONE = style.DRAG_DEADZONE or 10
@@ -324,7 +324,7 @@ end
--- Strict drag click area. Useful for --- Strict drag click area. Useful for
-- restrict events outside stencil node -- restrict events outside stencil node
-- @tparam Drag self @{Drag} -- @tparam Drag self @{Drag}
-- @tparam node node Gui node -- @tparam node|string|nil node Gui node
function Drag.set_click_zone(self, node) function Drag.set_click_zone(self, node)
self.click_zone = self:get_node(node) self.click_zone = self:get_node(node)
end end

View File

@@ -5,6 +5,9 @@
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.hover -- @alias druid.hover
--- Hover node
-- @tfield node node
--- On hover callback(self, state, hover_instance) --- On hover callback(self, state, hover_instance)
-- @tfield DruidEvent on_hover @{DruidEvent} -- @tfield DruidEvent on_hover @{DruidEvent}
@@ -25,7 +28,8 @@ local Hover = component.create("hover")
-- @tparam Hover self @{Hover} -- @tparam Hover self @{Hover}
-- @tparam node node Gui node -- @tparam node node Gui node
-- @tparam function on_hover_callback Hover callback -- @tparam function on_hover_callback Hover callback
function Hover.init(self, node, on_hover_callback) -- @tparam function on_mouse_hover On mouse hover callback
function Hover.init(self, node, on_hover_callback, on_mouse_hover)
self.node = self:get_node(node) self.node = self:get_node(node)
self._is_hovered = false self._is_hovered = false
@@ -34,7 +38,7 @@ function Hover.init(self, node, on_hover_callback)
self._is_mobile = helper.is_mobile() self._is_mobile = helper.is_mobile()
self.on_hover = Event(on_hover_callback) self.on_hover = Event(on_hover_callback)
self.on_mouse_hover = Event() self.on_mouse_hover = Event(on_mouse_hover)
end end
@@ -48,6 +52,19 @@ function Hover.on_late_init(self)
end end
--- Component style params.
-- You can override this component styles params in druid styles table
-- or create your own style
-- @table style
-- @tfield[opt] string ON_HOVER_CURSOR Mouse hover style on node hover
-- @tfield[opt] string ON_MOUSE_HOVER_CURSOR Mouse hover style on node mouse hover
function Hover.on_style_change(self, style)
self.style = {}
self.style.ON_HOVER_CURSOR = style.ON_HOVER_CURSOR or nil
self.style.ON_MOUSE_HOVER_CURSOR = style.ON_MOUSE_HOVER_CURSOR or nil
end
function Hover.on_input(self, action_id, action) function Hover.on_input(self, action_id, action)
if action_id ~= const.ACTION_TOUCH and action_id ~= nil then if action_id ~= const.ACTION_TOUCH and action_id ~= nil then
return false return false
@@ -91,9 +108,15 @@ end
-- @tparam Hover self @{Hover} -- @tparam Hover self @{Hover}
-- @tparam boolean|nil state The hover state -- @tparam boolean|nil state The hover state
function Hover.set_hover(self, state) function Hover.set_hover(self, state)
if self._is_hovered ~= state then if self._is_hovered == state then
return
end
self._is_hovered = state self._is_hovered = state
self.on_hover:trigger(self:get_context(), state, self) self.on_hover:trigger(self:get_context(), state, self)
if defos and self.style.ON_HOVER_CURSOR then
self:_set_cursor(3, state and self.style.ON_HOVER_CURSOR or nil)
end end
end end
@@ -110,9 +133,15 @@ end
-- @tparam Hover self @{Hover} -- @tparam Hover self @{Hover}
-- @tparam boolean|nil state The mouse hover state -- @tparam boolean|nil state The mouse hover state
function Hover.set_mouse_hover(self, state) function Hover.set_mouse_hover(self, state)
if self._is_mouse_hovered ~= state then if self._is_mouse_hovered == state then
return
end
self._is_mouse_hovered = state self._is_mouse_hovered = state
self.on_mouse_hover:trigger(self:get_context(), state, self) self.on_mouse_hover:trigger(self:get_context(), state, self)
if defos and self.style.ON_MOUSE_HOVER_CURSOR then
self:_set_cursor(2, state and self.style.ON_MOUSE_HOVER_CURSOR or nil)
end end
end end
@@ -128,7 +157,7 @@ end
--- Strict hover click area. Useful for --- Strict hover click area. Useful for
-- no click events outside stencil node -- no click events outside stencil node
-- @tparam Hover self @{Hover} -- @tparam Hover self @{Hover}
-- @tparam node zone Gui node -- @tparam node|string|nil zone Gui node
function Hover.set_click_zone(self, zone) function Hover.set_click_zone(self, zone)
self.click_zone = self:get_node(zone) self.click_zone = self:get_node(zone)
end end
@@ -161,4 +190,31 @@ function Hover.is_enabled(self)
end end
-- Internal cursor stack
local cursor_stack = {}
function Hover:_set_cursor(priority, cursor)
if not defos then
return
end
local uid = self:get_uid()
cursor_stack[uid] = cursor_stack[uid] or {}
cursor_stack[uid][priority] = cursor
-- set cursor with high priority via pairs
local priority = nil
local cursor_to_set = nil
for _, stack in pairs(cursor_stack) do
for pr, _ in pairs(stack) do
if pr > (priority or 0) then
priority = pr
cursor_to_set = stack[priority]
end
end
end
defos.set_cursor(cursor_to_set)
end
return Hover return Hover

View File

@@ -50,11 +50,14 @@
--- Scroll view node --- Scroll view node
-- @tfield node view_node -- @tfield node view_node
--- Scroll view size
-- @tfield vector3 view_size
--- Scroll content node --- Scroll content node
-- @tfield node content_node -- @tfield node content_node
--- Flag, if scroll now moving by inertion --- Flag, if scroll now moving by inertion
-- @tfield bool _is_inert -- @tfield boolean _is_inert
--- Current inert speed --- Current inert speed
-- @tfield vector3 inertion -- @tfield vector3 inertion
@@ -123,18 +126,18 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=0] number FRICT Multiplier for free inertion -- @tfield number|nil FRICT Multiplier for free inertion. Default: 0
-- @tfield[opt=0] number FRICT_HOLD Multiplier for inertion, while touching -- @tfield number|nil FRICT_HOLD Multiplier for inertion, while touching. Default: 0
-- @tfield[opt=3] number INERT_THRESHOLD Scroll speed to stop inertion -- @tfield number|nil INERT_THRESHOLD Scroll speed to stop inertion. Default: 3
-- @tfield[opt=30] number INERT_SPEED Multiplier for inertion speed -- @tfield number|nil INERT_SPEED Multiplier for inertion speed. Default: 30
-- @tfield[opt=20] number POINTS_DEADZONE Speed to check points of interests in no_inertion mode -- @tfield number|nil POINTS_DEADZONE Speed to check points of interests in no_inertion mode. Default: 20
-- @tfield[opt=0.35] number BACK_SPEED Scroll back returning lerp speed -- @tfield number|nil BACK_SPEED Scroll back returning lerp speed. Default: 35
-- @tfield[opt=0.2] number ANIM_SPEED Scroll gui.animation speed for scroll_to function -- @tfield number|nil ANIM_SPEED Scroll gui.animation speed for scroll_to function. Default: 2
-- @tfield[opt=0] number EXTRA_STRETCH_SIZE extra size in pixels outside of scroll (stretch effect) -- @tfield number|nil EXTRA_STRETCH_SIZE extra size in pixels outside of scroll (stretch effect). Default: 0
-- @tfield[opt=false] boolean SMALL_CONTENT_SCROLL If true, content node with size less than view node size can be scrolled -- @tfield boolean|nil SMALL_CONTENT_SCROLL If true, content node with size less than view node size can be scrolled. Default: false
-- @tfield[opt=0] boolean WHEEL_SCROLL_SPEED The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling -- @tfield boolean|nil WHEEL_SCROLL_SPEED The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling. Default: 0
-- @tfield[opt=false] boolean WHEEL_SCROLL_INVERTED If true, invert direction for touchpad and mouse wheel scroll -- @tfield boolean|nil WHEEL_SCROLL_INVERTED If true, invert direction for touchpad and mouse wheel scroll. Default: false
-- @tfield[opt=false] boolean WHEEL_SCROLL_BY_INERTION If true, wheel will add inertion to scroll. Direct set position otherwise. -- @tfield boolean|nil WHEEL_SCROLL_BY_INERTION If true, wheel will add inertion to scroll. Direct set position otherwise.. Default: false
function Scroll.on_style_change(self, style) function Scroll.on_style_change(self, style)
self.style = {} self.style = {}
self.style.EXTRA_STRETCH_SIZE = style.EXTRA_STRETCH_SIZE or 0 self.style.EXTRA_STRETCH_SIZE = style.EXTRA_STRETCH_SIZE or 0
@@ -216,6 +219,12 @@ end
function Scroll.update(self, dt) function Scroll.update(self, dt)
if self.is_animate then
self.position.x = gui.get(self.content_node, "position.x")
self.position.y = gui.get(self.content_node, "position.y")
self.on_scroll:trigger(self:get_context(), self.position)
end
if self.drag.is_drag then if self.drag.is_drag then
self:_update_hand_scroll(dt) self:_update_hand_scroll(dt)
else else
@@ -255,12 +264,12 @@ function Scroll.scroll_to(self, point, is_instant)
if is_instant then if is_instant then
self.target_position = target self.target_position = target
self:_set_scroll_position(target) self:_set_scroll_position(target.x, target.y)
else else
gui.animate(self.content_node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, self.style.ANIM_SPEED, 0, function() gui.animate(self.content_node, gui.PROP_POSITION, target, gui.EASING_OUTSINE, self.style.ANIM_SPEED, 0, function()
self.is_animate = false self.is_animate = false
self.target_position = target self.target_position = target
self:_set_scroll_position(target) self:_set_scroll_position(target.x, target.y)
end) end)
end end
@@ -305,6 +314,13 @@ function Scroll.scroll_to_percent(self, percent, is_instant)
0 0
) )
if not self.drag.can_x then
pos.x = self.position.x
end
if not self.drag.can_y then
pos.y = self.position.y
end
self:scroll_to(pos, is_instant) self:scroll_to(pos, is_instant)
end end
@@ -325,7 +341,7 @@ end
-- It will change content gui node size -- It will change content gui node size
-- @tparam Scroll self @{Scroll} -- @tparam Scroll self @{Scroll}
-- @tparam vector3 size The new size for content node -- @tparam vector3 size The new size for content node
-- @tparam vector3 offset Offset value to set, where content is starts -- @tparam vector3|nil offset Offset value to set, where content is starts
-- @treturn druid.scroll Current scroll instance -- @treturn druid.scroll Current scroll instance
function Scroll.set_size(self, size, offset) function Scroll.set_size(self, size, offset)
if offset then if offset then
@@ -338,6 +354,31 @@ function Scroll.set_size(self, size, offset)
end end
--- Set new scroll view size in case the node size was changed.
-- @tparam Scroll self @{Scroll}
-- @tparam vector3 size The new size for view node
-- @treturn druid.scroll Current scroll instance
function Scroll.set_view_size(self, size)
gui.set_size(self.view_node, size)
self.view_size = size
self.view_border = helper.get_border(self.view_node)
self:_update_size()
return self
end
--- Refresh scroll view size
-- @tparam Scroll self @{Scroll}
function Scroll.update_view_size(self)
self.view_size = helper.get_scaled_size(self.view_node)
self.view_border = helper.get_border(self.view_node)
self:_update_size()
return self
end
--- Enable or disable scroll inert. --- Enable or disable scroll inert.
-- If disabled, scroll through points (if exist) -- If disabled, scroll through points (if exist)
-- If no points, just simple drag without inertion -- If no points, just simple drag without inertion
@@ -464,7 +505,7 @@ end
--- Bind the grid component (Static or Dynamic) to recalculate --- Bind the grid component (Static or Dynamic) to recalculate
-- scroll size on grid changes -- scroll size on grid changes
-- @tparam Scroll self @{Scroll} -- @tparam Scroll self @{Scroll}
-- @tparam StaticGrid|DynamicGrid grid Druid grid component -- @tparam StaticGrid grid Druid grid component
-- @treturn druid.scroll Current scroll instance -- @treturn druid.scroll Current scroll instance
function Scroll.bind_grid(self, grid) function Scroll.bind_grid(self, grid)
if self._grid_on_change then if self._grid_on_change then
@@ -493,7 +534,7 @@ end
--- Strict drag scroll area. Useful for --- Strict drag scroll area. Useful for
-- restrict events outside stencil node -- restrict events outside stencil node
-- @tparam Drag self -- @tparam Drag self
-- @tparam node node Gui node -- @tparam node|string node Gui node
function Scroll.set_click_zone(self, node) function Scroll.set_click_zone(self, node)
self.drag:set_click_zone(node) self.drag:set_click_zone(node)
end end
@@ -583,14 +624,14 @@ function Scroll._cancel_animate(self)
end end
function Scroll._set_scroll_position(self, position) function Scroll._set_scroll_position(self, position_x, position_y)
local available_extra = self.available_pos_extra local available_extra = self.available_pos_extra
position.x = helper.clamp(position.x, available_extra.x, available_extra.z) position_x = helper.clamp(position_x, available_extra.x, available_extra.z)
position.y = helper.clamp(position.y, available_extra.w, available_extra.y) position_y = helper.clamp(position_y, available_extra.w, available_extra.y)
if self.position.x ~= position.x or self.position.y ~= position.y then if self.position.x ~= position_x or self.position.y ~= position_y then
self.position.x = position.x self.position.x = position_x
self.position.y = position.y self.position.y = position_y
gui.set_position(self.content_node, self.position) gui.set_position(self.content_node, self.position)
self.on_scroll:trigger(self:get_context(), self.position) self.on_scroll:trigger(self:get_context(), self.position)
@@ -677,6 +718,10 @@ end
function Scroll._update_free_scroll(self, dt) function Scroll._update_free_scroll(self, dt)
if self.is_animate then
return
end
local target = self.target_position local target = self.target_position
if self._is_inert and (self.inertion.x ~= 0 or self.inertion.y ~= 0) then if self._is_inert and (self.inertion.x ~= 0 or self.inertion.y ~= 0) then
@@ -692,19 +737,23 @@ function Scroll._update_free_scroll(self, dt)
self:_check_soft_zone() self:_check_soft_zone()
if self.position.x ~= target.x or self.position.y ~= target.y then if self.position.x ~= target.x or self.position.y ~= target.y then
self:_set_scroll_position(target) self:_set_scroll_position(target.x, target.y)
end end
end end
function Scroll._update_hand_scroll(self, dt) function Scroll._update_hand_scroll(self, dt)
if self.is_animate then
self:_cancel_animate()
end
local dx = self.target_position.x - self.position.x local dx = self.target_position.x - self.position.x
local dy = self.target_position.y - self.position.y local dy = self.target_position.y - self.position.y
self.inertion.x = (self.inertion.x + dx) * self.style.FRICT_HOLD self.inertion.x = (self.inertion.x + dx) * self.style.FRICT_HOLD
self.inertion.y = (self.inertion.y + dy) * self.style.FRICT_HOLD self.inertion.y = (self.inertion.y + dy) * self.style.FRICT_HOLD
self:_set_scroll_position(self.target_position) self:_set_scroll_position(self.target_position.x, self.target_position.y)
end end
@@ -746,14 +795,14 @@ function Scroll._update_size(self)
content_border_extra.w = content_border_extra.w - stretch_size * sign_y content_border_extra.w = content_border_extra.w - stretch_size * sign_y
if not self.style.SMALL_CONTENT_SCROLL then if not self.style.SMALL_CONTENT_SCROLL then
self.drag.can_x = content_size.x > self.view_size.x self.drag.can_x = content_size.x > self.view_size.x and self._is_horizontal_scroll
self.drag.can_y = content_size.y > self.view_size.y self.drag.can_y = content_size.y > self.view_size.y and self._is_vertical_scroll
end end
self.available_pos_extra = get_border_vector(self.view_border - content_border_extra, self._offset) self.available_pos_extra = get_border_vector(self.view_border - content_border_extra, self._offset)
self.available_size_extra = get_size_vector(self.available_pos_extra) self.available_size_extra = get_size_vector(self.available_pos_extra)
self:_set_scroll_position(self.position) self:_set_scroll_position(self.position.x, self.position.y)
self.target_position.x = self.position.x self.target_position.x = self.position.x
self.target_position.y = self.position.y self.target_position.y = self.position.y
end end
@@ -788,7 +837,7 @@ function Scroll._process_scroll_wheel(self, action_id, action)
self.inertion.x = 0 self.inertion.x = 0
end end
self:_set_scroll_position(self.target_position) self:_set_scroll_position(self.target_position.x, self.target_position.y)
end end
return true return true

View File

@@ -102,8 +102,8 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=false] boolean IS_DYNAMIC_NODE_POSES If true, always center grid content as grid pivot sets -- @tfield boolean|nil IS_DYNAMIC_NODE_POSES If true, always center grid content as grid pivot sets. Default: false
-- @tfield[opt=false] boolean IS_ALIGN_LAST_ROW If true, always align last row of the grid as grid pivot sets -- @tfield boolean|nil IS_ALIGN_LAST_ROW If true, always align last row of the grid as grid pivot sets. Default: false
function StaticGrid.on_style_change(self, style) function StaticGrid.on_style_change(self, style)
self.style = {} self.style = {}
self.style.IS_DYNAMIC_NODE_POSES = style.IS_DYNAMIC_NODE_POSES or false self.style.IS_DYNAMIC_NODE_POSES = style.IS_DYNAMIC_NODE_POSES or false
@@ -115,7 +115,7 @@ end
-- @tparam StaticGrid self @{StaticGrid} -- @tparam StaticGrid self @{StaticGrid}
-- @tparam string|node parent The GUI Node container, where grid's items will be placed -- @tparam string|node parent The GUI Node container, where grid's items will be placed
-- @tparam node element Element prefab. Need to get it size -- @tparam node element Element prefab. Need to get it size
-- @tparam[opt=1] number in_row How many nodes in row can be placed -- @tparam number|nil in_row How many nodes in row can be placed. By default 1
function StaticGrid.init(self, parent, element, in_row) function StaticGrid.init(self, parent, element, in_row)
self.parent = self:get_node(parent) self.parent = self:get_node(parent)
self.nodes = {} self.nodes = {}
@@ -171,8 +171,12 @@ end
-- @tparam vector3 pos The node position in the grid -- @tparam vector3 pos The node position in the grid
-- @treturn number The node index -- @treturn number The node index
function StaticGrid.get_index(self, pos) function StaticGrid.get_index(self, pos)
local col = pos.x / self.node_size.x + 1 -- Offset to left-top corner from node pivot
local row = -pos.y / self.node_size.y local node_offset_x = self.node_size.x * (-0.5 + self.node_pivot.x)
local node_offset_y = self.node_size.y * (0.5 - self.node_pivot.y)
local col = (pos.x + node_offset_x) / self.node_size.x + 1
local row = -(pos.y + node_offset_y) / self.node_size.y
col = helper.round(col) col = helper.round(col)
row = helper.round(row) row = helper.round(row)
@@ -236,6 +240,23 @@ function StaticGrid.add(self, item, index, shift_policy, is_instant)
end end
--- Set new items to the grid. All previous items will be removed
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam node[] nodes The new grid nodes
-- @tparam[opt=false] boolean is_instant If true, update node positions instantly
function StaticGrid.set_items(self, nodes, is_instant)
self.nodes = nodes
for index = 1, #nodes do
local item = nodes[index]
gui.set_parent(item, self.parent)
end
self:_update(is_instant)
self.on_change_items:trigger(self:get_context())
end
--- Remove the item from the grid. Note that gui node will be not deleted --- Remove the item from the grid. Note that gui node will be not deleted
-- @tparam StaticGrid self @{StaticGrid} -- @tparam StaticGrid self @{StaticGrid}
-- @tparam number index The grid node index to remove -- @tparam number index The grid node index to remove
@@ -337,6 +358,7 @@ function StaticGrid.clear(self)
self:_update() self:_update()
self.on_clear:trigger(self:get_context()) self.on_clear:trigger(self:get_context())
self.on_change_items:trigger(self:get_context())
return self return self
end end
@@ -377,6 +399,35 @@ function StaticGrid.set_in_row(self, in_row)
end end
--- Set new node size for grid
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam[opt] number width The new node width
-- @tparam[opt] number height The new node height
-- @treturn druid.static_grid Current grid instance
function StaticGrid.set_item_size(self, width, height)
if width then
self.node_size.x = width
end
if height then
self.node_size.y = height
end
self:_update()
self.on_change_items:trigger(self:get_context())
return self
end
--- Sort grid nodes by custom comparator function
-- @tparam StaticGrid self @{StaticGrid}
-- @tparam function comparator The comparator function. (a, b) -> boolean
-- @treturn druid.static_grid Current grid instance
function StaticGrid.sort_nodes(self, comparator)
table.sort(self.nodes, comparator)
self:_update(true)
end
--- Update grid inner state --- Update grid inner state
-- @tparam StaticGrid self @{StaticGrid} -- @tparam StaticGrid self @{StaticGrid}
-- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback -- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback

View File

@@ -81,12 +81,18 @@ local const = require("druid.const")
local helper = require("druid.helper") local helper = require("druid.helper")
local utf8_lua = require("druid.system.utf8") local utf8_lua = require("druid.system.utf8")
local component = require("druid.component") local component = require("druid.component")
local utf8 = utf8 or utf8_lua local utf8 = utf8 or utf8_lua --[[@as utf8]]
local Text = component.create("text") local Text = component.create("text")
local function update_text_size(self) local function update_text_size(self)
if self.scale.x == 0 or self.scale.y == 0 then
return
end
if self.start_scale.x == 0 or self.start_scale.y == 0 then
return
end
local size = vmath.vector3( local size = vmath.vector3(
self.start_size.x * (self.start_scale.x / self.scale.x), 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.y * (self.start_scale.y / self.scale.y),
@@ -98,19 +104,24 @@ end
--- Reset initial scale for text --- Reset initial scale for text
local function reset_default_scale(self) local function reset_default_scale(self)
self.scale = self.start_scale self.scale.x = self.start_scale.x
self.scale.y = self.start_scale.y
self.scale.z = self.start_scale.z
gui.set_scale(self.node, self.start_scale) gui.set_scale(self.node, self.start_scale)
gui.set_size(self.node, self.start_size) gui.set_size(self.node, self.start_size)
end end
local function is_fit_info_area(self, metrics)
return metrics.width * self.scale.x <= self.text_area.x and
metrics.height * self.scale.y <= self.text_area.y
end
--- Setup scale x, but can only be smaller, than start text scale --- Setup scale x, but can only be smaller, than start text scale
local function update_text_area_size(self) local function update_text_area_size(self)
reset_default_scale(self) reset_default_scale(self)
local max_width = self.text_area.x
local max_height = self.text_area.y
local metrics = helper.get_text_metrics_from_node(self.node) local metrics = helper.get_text_metrics_from_node(self.node)
if metrics.width == 0 then if metrics.width == 0 then
@@ -119,15 +130,56 @@ local function update_text_area_size(self)
return return
end end
local scale_modifier = max_width / metrics.width local text_area_width = self.text_area.x
local text_area_height = self.text_area.y
-- Adjust by width
local scale_modifier = text_area_width / metrics.width
-- Adjust by height
if self:is_multiline() then
-- Approximate scale by height to start adjust scale
scale_modifier = math.sqrt(text_area_height / metrics.height)
if metrics.width * scale_modifier > text_area_width then
scale_modifier = text_area_width / metrics.width
end
-- #RMME
if self._minimal_scale then
scale_modifier = math.max(scale_modifier, self._minimal_scale)
end
-- Limit max scale by initial scale
scale_modifier = math.min(scale_modifier, self.start_scale.x)
-- #RMME
local is_fit = is_fit_info_area(self, metrics)
local step = is_fit and self.style.ADJUST_SCALE_DELTA or -self.style.ADJUST_SCALE_DELTA
for i = 1, self.style.ADJUST_STEPS do
-- Grow down to check if we fit
if step < 0 and is_fit then
break
end
-- Grow up to check if we still fit
if step > 0 and not is_fit then
break
end
scale_modifier = scale_modifier + step
if self._minimal_scale then
scale_modifier = math.max(scale_modifier, self._minimal_scale)
end
-- Limit max scale by initial scale
scale_modifier = math.min(scale_modifier, self.start_scale.x) scale_modifier = math.min(scale_modifier, self.start_scale.x)
if self:is_multiline() then self.scale.x = scale_modifier
local scale_modifier_by_height = math.sqrt(max_height / metrics.height) self.scale.y = scale_modifier
scale_modifier = math.min(self.start_scale.y, scale_modifier_by_height) self.scale.z = self.start_scale.z
gui.set_scale(self.node, self.scale)
if metrics.width * scale_modifier > max_width then update_text_size(self)
scale_modifier = math.min(max_width / metrics.width, self.start_scale.x) metrics = helper.get_text_metrics_from_node(self.node)
is_fit = is_fit_info_area(self, metrics)
end end
end end
@@ -135,12 +187,16 @@ local function update_text_area_size(self)
scale_modifier = math.max(scale_modifier, self._minimal_scale) scale_modifier = math.max(scale_modifier, self._minimal_scale)
end end
local new_scale = vmath.vector3(scale_modifier, scale_modifier, self.start_scale.z) -- Limit max scale by initial scale
gui.set_scale(self.node, new_scale) scale_modifier = math.min(scale_modifier, self.start_scale.x)
self.scale = new_scale
self.scale.x = scale_modifier
self.scale.y = scale_modifier
self.scale.z = self.start_scale.z
gui.set_scale(self.node, self.scale)
update_text_size(self) update_text_size(self)
self.on_update_text_scale:trigger(self:get_context(), new_scale, metrics) self.on_update_text_scale:trigger(self:get_context(), self.scale, metrics)
end end
@@ -155,9 +211,14 @@ local function update_text_with_trim(self, trim_postfix)
text_length = text_length - 1 text_length = text_length - 1
new_text = utf8.sub(self.last_value, 1, text_length) new_text = utf8.sub(self.last_value, 1, text_length)
text_width = self:get_text_size(new_text .. trim_postfix) text_width = self:get_text_size(new_text .. trim_postfix)
if text_length == 0 then
break
end
end end
gui.set_text(self.node, new_text .. trim_postfix) gui.set_text(self.node, new_text .. trim_postfix)
else
gui.set_text(self.node, self.last_value)
end end
end end
@@ -171,18 +232,6 @@ local function update_text_with_anchor_shift(self)
end end
-- calculate space width with font
local function get_space_width(self, font)
if not self._space_width[font] then
local no_space = resource.get_text_metrics(font, "1").width
local with_space = resource.get_text_metrics(font, " 1").width
self._space_width[font] = with_space - no_space
end
return self._space_width[font]
end
local function update_adjust(self) local function update_adjust(self)
if not self.adjust_type or self.adjust_type == const.TEXT_ADJUST.NO_ADJUST then if not self.adjust_type or self.adjust_type == const.TEXT_ADJUST.NO_ADJUST then
reset_default_scale(self) reset_default_scale(self)
@@ -216,20 +265,24 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=...] string TRIM_POSTFIX The postfix for TRIM adjust type -- @tfield string|nil TRIM_POSTFIX The postfix for TRIM adjust type. Default: ...
-- @tfield[opt=DOWNSCALE] string DEFAULT_ADJUST The default adjust type for any text component -- @tfield string|nil DEFAULT_ADJUST The default adjust type for any text component. Default: DOWNSCALE
-- @tfield string|nil ADJUST_STEPS Amount of iterations for text adjust by height. Default: 20
-- @tfield string|nil ADJUST_SCALE_DELTA Scale step on each height adjust step. Default: 0.02
function Text.on_style_change(self, style) function Text.on_style_change(self, style)
self.style = {} self.style = {}
self.style.TRIM_POSTFIX = style.TRIM_POSTFIX or "..." self.style.TRIM_POSTFIX = style.TRIM_POSTFIX or "..."
self.style.DEFAULT_ADJUST = style.DEFAULT_ADJUST or const.TEXT_ADJUST.DOWNSCALE self.style.DEFAULT_ADJUST = style.DEFAULT_ADJUST or const.TEXT_ADJUST.DOWNSCALE
self.style.ADJUST_STEPS = style.ADJUST_STEPS or 20
self.style.ADJUST_SCALE_DELTA = style.ADJUST_SCALE_DELTA or 0.02
end end
--- The @{Text} constructor --- The @{Text} constructor
-- @tparam Text self @{Text} -- @tparam Text self @{Text}
-- @tparam string|node node Node name or GUI Text Node itself -- @tparam string|node node Node name or GUI Text Node itself
-- @tparam string|nil value Initial text. Default value is node text from GUI scene. -- @tparam string|nil value Initial text. Default value is node text from GUI scene. Default: nil
-- @tparam[opt=downscale] string adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference -- @tparam string|nil adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
function Text.init(self, node, value, adjust_type) function Text.init(self, node, value, adjust_type)
self.node = self:get_node(node) self.node = self:get_node(node)
self.pos = gui.get_position(self.node) self.pos = gui.get_position(self.node)
@@ -251,8 +304,6 @@ function Text.init(self, node, value, adjust_type)
self.on_set_pivot = Event() self.on_set_pivot = Event()
self.on_update_text_scale = Event() self.on_update_text_scale = Event()
self._space_width = {}
self:set_to(value or gui.get_text(self.node)) self:set_to(value or gui.get_text(self.node))
return self return self
end end
@@ -276,32 +327,60 @@ end
--- Calculate text width with font with respect to trailing space --- Calculate text width with font with respect to trailing space
-- @tparam Text self @{Text} -- @tparam Text self @{Text}
-- @tparam string|nil text -- @tparam string text|nil
-- @treturn number Width -- @treturn number Width
-- @treturn number Height -- @treturn number Height
function Text.get_text_size(self, text) function Text.get_text_size(self, text)
text = text or self.last_value text = text or self.last_value
local font_name = gui.get_font(self.node) local font_name = gui.get_font(self.node)
local font = gui.get_font_resource(font_name) local font = gui.get_font_resource(font_name)
local scale = gui.get_scale(self.node) local scale = self.last_scale or gui.get_scale(self.node)
local linebreak = gui.get_line_break(self.node) local linebreak = gui.get_line_break(self.node)
local metrics = resource.get_text_metrics(font, text, { local dot_width = resource.get_text_metrics(font, ".").width
local metrics = resource.get_text_metrics(font, text .. ".", {
line_break = linebreak, line_break = linebreak,
leading = 1, leading = 1,
tracking = 0, tracking = 0,
width = self.start_size.x width = self.start_size.x
}) })
local width = metrics.width
for i = #text, 1, -1 do local width = metrics.width - dot_width
local c = string.sub(text, i, i) return width * scale.x, metrics.height * scale.y
if c ~= ' ' then end
--- Get chars count by width
-- @tparam Text self @{Text}
-- @tparam number width
-- @treturn number Chars count
function Text.get_text_index_by_width(self, width)
local text = self.last_value
local font_name = gui.get_font(self.node)
local font = gui.get_font_resource(font_name)
local scale = self.last_scale or gui.get_scale(self.node)
local text_index = 0
local text_width = 0
local text_length = utf8.len(text)
local dot_width = resource.get_text_metrics(font, ".").width
local previous_width = 0
for i = 1, text_length do
local subtext = utf8.sub(text, 1, i) .. "."
local subtext_width = resource.get_text_metrics(font, subtext).width
subtext_width = subtext_width - dot_width
text_width = subtext_width * scale.x
local width_delta = text_width - previous_width
previous_width = text_width
if (text_width - width_delta/2) < width then
text_index = i
else
break break
end end
width = width + get_space_width(self, font)
end end
return width * scale.x, metrics.height * scale.y return text_index
end end

View File

@@ -19,13 +19,12 @@
-- @alias druid.base_component -- @alias druid.base_component
local const = require("druid.const") local const = require("druid.const")
local class = require("druid.system.middleclass")
local helper = require("druid.helper") local helper = require("druid.helper")
local BaseComponent = class("druid.component") local BaseComponent = {}
local INTERESTS = {} -- Cache interests per component class in runtime local INTERESTS = {} -- Cache interests per component class in runtime
local IS_AUTO_TEMPLATE = not (sys.get_config("druid.no_auto_template") == "1") local IS_AUTO_TEMPLATE = not (sys.get_config_int("druid.no_auto_template", 0) == 1)
-- Component Interests -- Component Interests
BaseComponent.ON_INPUT = const.ON_INPUT BaseComponent.ON_INPUT = const.ON_INPUT
@@ -205,10 +204,22 @@ end
--- Get Druid instance for inner component creation. --- Get Druid instance for inner component creation.
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @tparam string|nil template The template name
-- @tparam table|nil nodes The nodes table
-- @treturn DruidInstance Druid instance with component context -- @treturn DruidInstance Druid instance with component context
function BaseComponent.get_druid(self) function BaseComponent.get_druid(self, template, nodes)
local context = { _context = self } local context = { _context = self }
return setmetatable(context, { __index = self._meta.druid }) local druid_instance = setmetatable(context, { __index = self._meta.druid })
if template then
self:set_template(template)
end
if nodes then
self:set_nodes(nodes)
end
return druid_instance
end end
@@ -336,31 +347,13 @@ function BaseComponent.setup_component(self, druid_instance, context, style, ins
self:set_template("") self:set_template("")
if self._meta.parent then if self._meta.parent then
self._meta.parent:__add_children(self) self._meta.parent:__add_child(self)
end end
return self return self
end end
--- Basic constructor of component. It will call automaticaly
-- by `BaseComponent.create`
-- @tparam BaseComponent self @{BaseComponent}
-- @tparam string name BaseComponent name
-- @tparam number|nil input_priority The input priority. The bigger number processed first
-- @local
function BaseComponent.initialize(self, name, input_priority)
self._component = {
name = name,
input_priority = input_priority or const.PRIORITY_INPUT,
default_input_priority = input_priority or const.PRIORITY_INPUT,
is_debug = false,
_is_input_priority_changed = true, -- Default true for sort once time after GUI init
_uid = BaseComponent.create_uid()
}
end
--- Print log information if debug mode is enabled --- Print log information if debug mode is enabled
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @tparam string message -- @tparam string message
@@ -443,21 +436,22 @@ end
--- Add child to component children list --- Add child to component children list
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @tparam component children The druid component instance -- @tparam component child The druid component instance
-- @local -- @local
function BaseComponent.__add_children(self, children) function BaseComponent.__add_child(self, child)
table.insert(self._meta.children, children) table.insert(self._meta.children, child)
end end
--- Remove child from component children list --- Remove child from component children list
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @tparam component children The druid component instance -- @tparam component child The druid component instance
-- @local -- @local
function BaseComponent.__remove_children(self, children) function BaseComponent.__remove_child(self, child)
for i = #self._meta.children, 1, -1 do for i = #self._meta.children, 1, -1 do
if self._meta.children[i] == children then if self._meta.children[i] == child then
table.remove(self._meta.children, i) table.remove(self._meta.children, i)
return true
end end
end end
end end
@@ -486,12 +480,24 @@ end
-- @tparam number|nil input_priority The input priority. The bigger number processed first -- @tparam number|nil input_priority The input priority. The bigger number processed first
-- @local -- @local
function BaseComponent.create(name, input_priority) function BaseComponent.create(name, input_priority)
-- Yea, inheritance here local new_class = setmetatable({}, {
local new_class = class(name, BaseComponent) __index = BaseComponent,
__call = function(cls, ...)
new_class.initialize = function(self) local self = setmetatable({
BaseComponent.initialize(self, name, input_priority) _component = {
name = name,
input_priority = input_priority or const.PRIORITY_INPUT,
default_input_priority = input_priority or const.PRIORITY_INPUT,
is_debug = false,
_is_input_priority_changed = true, -- Default true for sort once time after GUI init
_uid = BaseComponent.create_uid()
}
}, {
__index = cls
})
return self
end end
})
return new_class return new_class
end end

View File

@@ -17,8 +17,13 @@ M.ACTION_MULTITOUCH = hash(sys.get_config_string("druid.input_multitouch", "touc
M.ACTION_BACKSPACE = hash(sys.get_config_string("druid.input_key_backspace", "key_backspace")) M.ACTION_BACKSPACE = hash(sys.get_config_string("druid.input_key_backspace", "key_backspace"))
M.ACTION_SCROLL_UP = hash(sys.get_config_string("druid.input_scroll_up", "mouse_wheel_up")) M.ACTION_SCROLL_UP = hash(sys.get_config_string("druid.input_scroll_up", "mouse_wheel_up"))
M.ACTION_SCROLL_DOWN = hash(sys.get_config_string("druid.input_scroll_down", "mouse_wheel_down")) M.ACTION_SCROLL_DOWN = hash(sys.get_config_string("druid.input_scroll_down", "mouse_wheel_down"))
M.ACTION_LEFT = hash(sys.get_config_string("druid.input_key_left", "key_left"))
M.ACTION_RIGHT = hash(sys.get_config_string("druid.input_key_right", "key_right"))
M.ACTION_LSHIFT = hash(sys.get_config_string("druid.input_key_lshift", "key_lshift"))
M.ACTION_LCTRL = hash(sys.get_config_string("druid.input_key_lctrl", "key_lctrl"))
M.ACTION_LCMD = hash(sys.get_config_string("druid.input_key_lsuper", "key_lsuper"))
M.IS_STENCIL_CHECK = not (sys.get_config_string("druid.no_stencil_check") == "1") M.IS_STENCIL_CHECK = not (sys.get_config_int("druid.no_stencil_check", 0) == 1)
M.ON_INPUT = "on_input" M.ON_INPUT = "on_input"

View File

@@ -1,182 +0,0 @@
script: ""
fonts {
name: "game"
font: "/example/assets/fonts/game.font"
}
textures {
name: "kenney"
texture: "/example/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: 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_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: 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: "pin"
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: 13.5
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.2
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 17.0
y: 17.0
z: 0.0
w: 1.0
}
color {
x: 0.101960786
y: 0.101960786
z: 0.101960786
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "kenney/tick"
id: "notch"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin"
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

View File

@@ -1,123 +0,0 @@
-- Copyright (c) 2022 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid pin knob custom component.
-- It's simple rotating input element
-- @module PinKnob
-- @within BaseComponent
-- @alias druid.pin_knob
--- The component druid instance
-- @tfield DruidInstance druid @{DruidInstance}
--- Is currently under user control
-- @tfield boolean is_drag
--- The pin node
-- @tfield node node
---
local const = require("druid.const")
local component = require("druid.component")
local PinKnob = component.create("druid.pin_knob", { const.ON_INPUT })
local SCHEME = {
ROOT = "root",
PIN = "pin",
}
local function update_visual(self)
local rotation = vmath.vector3(0, 0, self.angle)
gui.set_rotation(self.node, rotation)
end
local function set_angle(self, value)
local prev_value = self.angle
self.angle = value
self.angle = math.min(self.angle, self.angle_max)
self.angle = math.max(self.angle, self.angle_min)
update_visual(self)
if prev_value ~= self.angle and self.callback then
local output_value = self.angle
if output_value ~= 0 then
output_value = -output_value
end
self.callback(self:get_context(), output_value)
end
end
--- The @{PinKnob} constructor
-- @tparam PinKnob self @{PinKnob}
-- @tparam function callback Callback(self, value) on value changed
-- @tparam string template The template string name
-- @tparam table nodes Nodes table from gui.clone_tree
function PinKnob.init(self, callback, template, nodes)
self:set_template(template)
self:set_nodes(nodes)
self.druid = self:get_druid()
self.node = self:get_node(SCHEME.PIN)
self.is_drag = false
self.callback = callback
self:set_angle(0, -100, 100)
self._friction = 0.75
end
--- Set current and min/max angles for component
-- @tparam PinKnob self @{PinKnob}
-- @tparam number cur_value The new value for pin knob
-- @tparam number min The minimum value for pin knob
-- @tparam number max The maximum value for pin knob
-- @treturn PinKnob @{PinKnob}
function PinKnob.set_angle(self, cur_value, min, max)
self.angle_min = min or self.angle_min
self.angle_max = max or self.angle_max
set_angle(self, cur_value)
return self
end
--- Set current and min/max angles for component
-- @tparam PinKnob self @{PinKnob}
-- @tparam[opt=1] number value The spin speed multiplier
-- @treturn PinKnob @{PinKnob}
function PinKnob.set_friction(self, value)
self._friction = value or 1
return self
end
function PinKnob.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
set_angle(self, self.angle - action.dx * self._friction - action.dy * self._friction)
end
if action.released then
self.is_drag = false
end
return self.is_drag
end
return PinKnob

View File

@@ -3,7 +3,6 @@
--- Druid Rich Input custom component. --- Druid Rich Input custom component.
-- It's wrapper on Input component with cursor and placeholder text -- It's wrapper on Input component with cursor and placeholder text
-- @module RichInput -- @module RichInput
-- @within Input
-- @alias druid.rich_input -- @alias druid.rich_input
--- The component druid instance --- The component druid instance
@@ -18,13 +17,36 @@
--- On input field text change to empty string callback(self, input_text) --- On input field text change to empty string callback(self, input_text)
-- @tfield node cursor -- @tfield node cursor
--- On input field text change to empty string callback(self, input_text)
-- @tfield node cursor_text
--- On input field text change to empty string callback(self, input_text)
-- @tfield vector3 cursor_position
--- On input field text change to empty string callback(self, input_text)
-- @tfield druid.text input_text
--- On input field text change to empty string callback(self, input_text)
-- @tfield druid.drag drag
--- On input field text change to empty string callback(self, input_text)
-- @tfield druid.text placeholder
--- On input field text change to empty string callback(self, input_text)
-- @tfield vector3 text_position
--- On input field text change to max length string callback(self, input_text) --- On input field text change to max length string callback(self, input_text)
-- @tfield druid.text placeholder @{Text} -- @tfield druid.text placeholder @{Text}
--- ---
local component = require("druid.component") local component = require("druid.component")
local helper = require("druid.helper")
local const = require("druid.const")
local utf8_lua = require("druid.system.utf8")
local utf8 = utf8 or utf8_lua
local input = require("druid.extended.input")
local RichInput = component.create("druid.rich_input") local RichInput = component.create("druid.rich_input")
local SCHEME = { local SCHEME = {
@@ -33,34 +55,140 @@ local SCHEME = {
PLACEHOLDER = "placeholder_text", PLACEHOLDER = "placeholder_text",
INPUT = "input_text", INPUT = "input_text",
CURSOR = "cursor_node", CURSOR = "cursor_node",
CURSOR_TEXT = "cursor_text",
} }
local DOUBLE_CLICK_TIME = 0.35
local function animate_cursor(self) local function animate_cursor(self)
gui.cancel_animation(self.cursor, gui.PROP_COLOR) gui.cancel_animation(self.cursor_text, "color.w")
gui.set_color(self.cursor, vmath.vector4(1)) gui.set_alpha(self.cursor_text, 1)
gui.animate(self.cursor, gui.PROP_COLOR, vmath.vector4(1,1,1,0), gui.EASING_INSINE, 0.8, 0, nil, gui.PLAYBACK_LOOP_PINGPONG) gui.animate(self.cursor_text, "color.w", 0, gui.EASING_INSINE, 0.8, 0, nil, gui.PLAYBACK_LOOP_PINGPONG)
end end
local function update_text(self, text) local function set_selection_width(self, selection_width)
local text_width = self.input.total_width gui.set_visible(self.cursor, selection_width > 0)
animate_cursor(self)
gui.set_position(self.cursor, vmath.vector3(text_width/2, 0, 0)) local width = selection_width / self.input.text.scale.x
local height = gui.get_size(self.cursor).y
gui.set_size(self.cursor, vmath.vector3(width, height, 0))
local is_selection_to_right = self.input.cursor_index == self.input.end_index
gui.set_pivot(self.cursor, is_selection_to_right and gui.PIVOT_E or gui.PIVOT_W)
end
local function update_text(self)
local left_text_part = utf8.sub(self.input:get_text(), 0, self.input.cursor_index)
local selected_text_part = utf8.sub(self.input:get_text(), self.input.start_index + 1, self.input.end_index)
local left_part_width = self.input.text:get_text_size(left_text_part)
local selected_part_width = self.input.text:get_text_size(selected_text_part)
local pivot_text = gui.get_pivot(self.input.text.node)
local pivot_offset = helper.get_pivot_offset(pivot_text)
self.cursor_position.x = self.text_position.x - self.input.total_width * (0.5 + pivot_offset.x) + left_part_width
gui.set_position(self.cursor, self.cursor_position)
gui.set_scale(self.cursor, self.input.text.scale) gui.set_scale(self.cursor, self.input.text.scale)
set_selection_width(self, selected_part_width)
end end
local function on_select(self) local function on_select(self)
gui.set_enabled(self.cursor, true) gui.set_enabled(self.cursor, true)
gui.set_enabled(self.placeholder.node, false) gui.set_enabled(self.placeholder.node, false)
gui.set_enabled(self.input.button.node, true)
animate_cursor(self) animate_cursor(self)
self.drag:set_enabled(true)
end end
local function on_unselect(self) local function on_unselect(self)
gui.cancel_animation(self.cursor, gui.PROP_COLOR)
gui.set_enabled(self.cursor, false) gui.set_enabled(self.cursor, false)
gui.set_enabled(self.input.button.node, self.is_button_input_enabled)
gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0) gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0)
self.drag:set_enabled(false)
end
--- Update selection
local function update_selection(self)
update_text(self)
end
local TEMP_VECTOR = vmath.vector3(0)
local function get_index_by_touch(self, touch)
local text_node = self.input.text.node
TEMP_VECTOR.x = touch.screen_x
TEMP_VECTOR.y = touch.screen_y
-- Distance to the text node position
local scene_scale = helper.get_scene_scale(text_node)
local local_pos = gui.screen_to_local(text_node, TEMP_VECTOR)
local_pos.x = local_pos.x / scene_scale.x
-- Offset to the left side of the text node
local pivot_offset = helper.get_pivot_offset(gui.get_pivot(text_node))
local_pos.x = local_pos.x + self.input.total_width * (0.5 + pivot_offset.x)
local_pos.x = local_pos.x - self.text_position.x
local cursor_index = self.input.text:get_text_index_by_width(local_pos.x)
return cursor_index
end
local function on_touch_start_callback(self, touch)
local cursor_index = get_index_by_touch(self, touch)
if self._last_touch_info.cursor_index == cursor_index then
local time = socket.gettime()
if time - self._last_touch_info.time < DOUBLE_CLICK_TIME then
local len = utf8.len(self.input:get_text())
self.input:select_cursor(len, 0, len)
self._last_touch_info.cursor_index = nil
return
end
end
self._last_touch_info.cursor_index = cursor_index
self._last_touch_info.time = socket.gettime()
if self.input.is_lshift then
local start_index = self.input.start_index
local end_index = self.input.end_index
if cursor_index < start_index then
self.input:select_cursor(cursor_index, cursor_index, end_index)
elseif cursor_index > end_index then
self.input:select_cursor(cursor_index, start_index, cursor_index)
end
else
self.input:select_cursor(cursor_index)
end
end
local function on_drag_callback(self, dx, dy, x, y, touch)
if not self._last_touch_info.cursor_index then
return
end
local index = get_index_by_touch(self, touch)
if self._last_touch_info.cursor_index <= index then
self.input:select_cursor(index, self._last_touch_info.cursor_index, index)
else
self.input:select_cursor(index, index, self._last_touch_info.cursor_index)
end
end end
@@ -69,38 +197,111 @@ end
-- @tparam string template The template string name -- @tparam string template The template string name
-- @tparam table nodes Nodes table from gui.clone_tree -- @tparam table nodes Nodes table from gui.clone_tree
function RichInput.init(self, template, nodes) function RichInput.init(self, template, nodes)
self:set_template(template) self.druid = self:get_druid(template, nodes)
self:set_nodes(nodes)
self.druid = self:get_druid()
self.root = self:get_node(SCHEME.ROOT) self.root = self:get_node(SCHEME.ROOT)
self.input = self.druid:new_input(self:get_node(SCHEME.BUTTON), self:get_node(SCHEME.INPUT)) self._last_touch_info = {
cursor_index = nil,
time = 0,
}
self.is_lshift = false
self.is_lctrl = false
self.input = self.druid:new(input, self:get_node(SCHEME.BUTTON), self:get_node(SCHEME.INPUT))
self.is_button_input_enabled = gui.is_enabled(self.input.button.node)
self.cursor = self:get_node(SCHEME.CURSOR) self.cursor = self:get_node(SCHEME.CURSOR)
self.cursor_position = gui.get_position(self.cursor)
self.cursor_text = self:get_node(SCHEME.CURSOR_TEXT)
self.drag = self.druid:new_drag(self:get_node(SCHEME.BUTTON), on_drag_callback)
self.drag.on_touch_start:subscribe(on_touch_start_callback)
self.drag:set_input_priority(const.PRIORITY_INPUT_MAX + 1)
self.drag:set_enabled(false)
self.input:set_text("") self.input:set_text("")
self.placeholder = self.druid:new_text(self:get_node(SCHEME.PLACEHOLDER)) self.placeholder = self.druid:new_text(self:get_node(SCHEME.PLACEHOLDER))
self.text_position = gui.get_position(self.input.text.node)
self.input.on_input_text:subscribe(update_text) self.input.on_input_text:subscribe(update_text)
self.input.on_input_select:subscribe(on_select) self.input.on_input_select:subscribe(on_select)
self.input.on_input_unselect:subscribe(on_unselect) self.input.on_input_unselect:subscribe(on_unselect)
self.input.on_select_cursor_change:subscribe(update_selection)
on_unselect(self) on_unselect(self)
update_text(self, "") update_text(self)
end
function RichInput.on_input(self, action_id, action)
if action_id == const.ACTION_LSHIFT then
if action.pressed then
self.is_lshift = true
elseif action.released then
self.is_lshift = false
end
end
if action_id == const.ACTION_LCTRL or action_id == const.ACTION_LCMD then
if action.pressed then
self.is_lctrl = true
elseif action.released then
self.is_lctrl = false
end
end
if action_id == const.ACTION_LEFT and (action.pressed or action.repeated) then
self.input:move_selection(-1, self.is_lshift, self.is_lctrl)
end
if action_id == const.ACTION_RIGHT and (action.pressed or action.repeated) then
self.input:move_selection(1, self.is_lshift, self.is_lctrl)
end
end end
--- Set placeholder text --- Set placeholder text
-- @tparam RichInput self @{RichInput} -- @tparam RichInput self @{RichInput}
-- @tparam string|nil placeholder_text The placeholder text -- @tparam string placeholder_text The placeholder text
-- @treturn RichInput Current instance
function RichInput.set_placeholder(self, placeholder_text) function RichInput.set_placeholder(self, placeholder_text)
self.placeholder:set_to(placeholder_text) self.placeholder:set_to(placeholder_text)
return self return self
end end
---GSet input field text --- Select input field
-- @tparam RichInput self @{RichInput}
function RichInput.select(self)
self.input:select()
end
--- Set input field text
-- @tparam RichInput self @{RichInput}
-- @treturn druid.input Current input instance
-- @tparam string text The input text
function RichInput.set_text(self, text)
self.input:set_text(text)
gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0)
return self
end
--- Set input field font
-- @tparam RichInput self @{RichInput}
-- @tparam hash font The font hash
-- @treturn druid.input Current input instance
function RichInput.set_font(self, font)
gui.set_font(self.input.text.node, font)
gui.set_font(self.placeholder.node, font)
return self
end
--- Set input field text
-- @tparam RichInput self @{RichInput} -- @tparam RichInput self @{RichInput}
-- @treturn string Current input text
function RichInput.get_text(self) function RichInput.get_text(self)
return self.input:get_text() return self.input:get_text()
end end

View File

@@ -11,6 +11,9 @@ local parser = require("druid.custom.rich_text.module.rt_parse")
local utf8_lua = require("druid.system.utf8") local utf8_lua = require("druid.system.utf8")
local utf8 = utf8 or utf8_lua local utf8 = utf8 or utf8_lua
local VECTOR_ZERO = vmath.vector3(0)
local COLOR_WHITE = vmath.vector4(1)
local M = {} local M = {}
-- Trim spaces on string start -- Trim spaces on string start
@@ -71,18 +74,18 @@ function M.length(text)
end end
---@param word rich_text.word ---@param word druid.rich_text.word
---@param previous_word rich_text.word|nil ---@param previous_word druid.rich_text.word|nil
---@param settings rich_text.settings ---@param settings druid.rich_text.settings
---@return rich_text.metrics ---@return druid.rich_text.metrics
local function get_text_metrics(word, previous_word, settings) local function get_text_metrics(word, previous_word, settings)
local text = word.text local text = word.text
local font_resource = gui.get_font_resource(word.font) local font_resource = gui.get_font_resource(word.font)
---@type druid.rich_text.metrics ---@type druid.rich_text.metrics
local metrics local metrics
local word_scale_x = word.relative_scale * settings.text_scale.x * settings.adjust_scale local word_scale_x = word.relative_scale * settings.scale.x * settings.adjust_scale
local word_scale_y = word.relative_scale * settings.text_scale.y * settings.adjust_scale local word_scale_y = word.relative_scale * settings.scale.y * settings.adjust_scale
if utf8.len(text) == 0 then if utf8.len(text) == 0 then
metrics = resource.get_text_metrics(font_resource, "|") metrics = resource.get_text_metrics(font_resource, "|")
@@ -116,16 +119,17 @@ end
---@param settings druid.rich_text.settings ---@param settings druid.rich_text.settings
---@return druid.rich_text.metrics ---@return druid.rich_text.metrics
local function get_image_metrics(word, settings) local function get_image_metrics(word, settings)
local node_prefab = settings.node_prefab local node = word.node
gui.play_flipbook(node_prefab, word.image.anim) gui.set_texture(node, word.image.texture)
local node_size = gui.get_size(node_prefab) gui.play_flipbook(node, word.image.anim)
local node_size = gui.get_size(node)
local aspect = node_size.x / node_size.y local aspect = node_size.x / node_size.y
node_size.x = word.image.width or node_size.x node_size.x = word.image.width or node_size.x
node_size.y = word.image.height or (node_size.x / aspect) node_size.y = word.image.height or (node_size.x / aspect)
return { return {
width = node_size.x * word.relative_scale * settings.node_scale.x * settings.adjust_scale, width = node_size.x * word.relative_scale * settings.scale.x * settings.adjust_scale,
height = node_size.y * word.relative_scale * settings.node_scale.y * settings.adjust_scale, height = node_size.y * word.relative_scale * settings.scale.y * settings.adjust_scale,
node_size = node_size, node_size = node_size,
} }
end end
@@ -136,6 +140,16 @@ end
---@param previous_word druid.rich_text.word|nil ---@param previous_word druid.rich_text.word|nil
---@return druid.rich_text.metrics ---@return druid.rich_text.metrics
local function measure_node(word, settings, previous_word) local function measure_node(word, settings, previous_word)
do -- Clone node if required
local node
if word.image then
node = word.node or gui.new_box_node(vmath.vector3(0), vmath.vector3(word.image.width, word.image.height, 0))
else
node = word.node or gui.clone(settings.text_prefab)
end
word.node = node
end
local metrics = word.image and get_image_metrics(word, settings) or get_text_metrics(word, previous_word, settings) local metrics = word.image and get_image_metrics(word, settings) or get_text_metrics(word, previous_word, settings)
return metrics return metrics
end end
@@ -145,14 +159,14 @@ end
--- @param text string The text to create rich text nodes from --- @param text string The text to create rich text nodes from
--- @param settings table Optional settings table (refer to documentation for details) --- @param settings table Optional settings table (refer to documentation for details)
--- @param style druid.rich_text.style --- @param style druid.rich_text.style
--- @return words --- @return druid.rich_text.word[]
--- @return metrics --- @return druid.rich_text.settings
--- @return druid.rich_text.lines_metrics
function M.create(text, settings, style) function M.create(text, settings, style)
assert(text, "You must provide a text") assert(text, "You must provide a text")
-- default settings for a word -- default settings for a word
-- will be assigned to each word unless tags override the values -- will be assigned to each word unless tags override the values
local font = gui.get_font(settings.text_prefab)
local word_params = { local word_params = {
node = nil, -- Autofill on node creation node = nil, -- Autofill on node creation
relative_scale = 1, relative_scale = 1,
@@ -169,12 +183,10 @@ function M.create(text, settings, style)
text_color = gui.get_color(settings.text_prefab), text_color = gui.get_color(settings.text_prefab),
shadow = settings.shadow, shadow = settings.shadow,
outline = settings.outline, outline = settings.outline,
font = font, font = gui.get_font(settings.text_prefab),
-- Image params -- Image params
---@type rich_text.word.image ---@type druid.rich_text.image
image = nil, image = nil,
image_color = gui.get_color(settings.node_prefab),
default_animation = nil,
-- Tags -- Tags
br = nil, br = nil,
nobr = nil, nobr = nil,
@@ -203,8 +215,8 @@ function M._fill_properties(word, metrics, settings)
if word.image then if word.image then
-- Image properties -- Image properties
word.scale = gui.get_scale(settings.node_prefab) * word.relative_scale * settings.adjust_scale word.scale = vmath.vector3(word.relative_scale * settings.adjust_scale)
word.pivot = gui.get_pivot(settings.node_prefab) word.pivot = gui.PIVOT_CENTER
word.size = metrics.node_size word.size = metrics.node_size
word.offset = vmath.vector3(0, 0, 0) word.offset = vmath.vector3(0, 0, 0)
if word.image.width then if word.image.width then
@@ -213,8 +225,8 @@ function M._fill_properties(word, metrics, settings)
end end
else else
-- Text properties -- Text properties
word.scale = gui.get_scale(settings.text_prefab) * word.relative_scale * settings.adjust_scale word.scale = settings.scale * word.relative_scale * settings.adjust_scale
word.pivot = gui.get_pivot(settings.text_prefab) word.pivot = gui.PIVOT_SW -- With this pivot adjustments works more correctly than with other pivots
word.size = vmath.vector3(metrics.width, metrics.height, 0) word.size = vmath.vector3(metrics.width, metrics.height, 0)
word.offset = vmath.vector3(metrics.offset_x, metrics.offset_y, 0) word.offset = vmath.vector3(metrics.offset_x, metrics.offset_y, 0)
end end
@@ -234,8 +246,8 @@ function M._split_on_lines(words, settings)
repeat repeat
local word = words[i] local word = words[i]
if word.image then if word == nil then
word.default_animation = settings.default_animation break
end end
-- Reset texts to start measure again -- Reset texts to start measure again
@@ -305,9 +317,9 @@ function M._split_on_lines(words, settings)
end end
---@param lines rich_text.word[][] ---@param lines druid.rich_text.word[][]
---@param settings rich_text.settings ---@param settings druid.rich_text.settings
---@return rich_text.lines_metrics ---@return druid.rich_text.lines_metrics
function M._position_lines(lines, settings) function M._position_lines(lines, settings)
local lines_metrics = M._get_lines_metrics(lines, settings) local lines_metrics = M._get_lines_metrics(lines, settings)
-- current x-y is left top point of text spawn -- current x-y is left top point of text spawn
@@ -352,9 +364,9 @@ function M._position_lines(lines, settings)
end end
---@param lines rich_text.word[][] ---@param lines druid.rich_text.word[][]
---@param settings rich_text.settings ---@param settings druid.rich_text.settings
---@return rich_text.lines_metrics ---@return druid.rich_text.lines_metrics
function M._get_lines_metrics(lines, settings) function M._get_lines_metrics(lines, settings)
local metrics = {} local metrics = {}
local text_width = 0 local text_width = 0
@@ -386,7 +398,7 @@ function M._get_lines_metrics(lines, settings)
} }
end end
---@type rich_text.lines_metrics ---@type druid.rich_text.lines_metrics
local lines_metrics = { local lines_metrics = {
text_width = text_width, text_width = text_width,
text_height = text_height, text_height = text_height,
@@ -397,8 +409,8 @@ function M._get_lines_metrics(lines, settings)
end end
---@param lines rich_text.word[][] ---@param lines druid.rich_text.word[][]
---@param settings rich_text.settings ---@param settings druid.rich_text.settings
function M._update_nodes(lines, settings) function M._update_nodes(lines, settings)
for line_index = 1, #lines do for line_index = 1, #lines do
local line = lines[line_index] local line = lines[line_index]
@@ -406,10 +418,11 @@ function M._update_nodes(lines, settings)
local word = line[word_index] local word = line[word_index]
local node local node
if word.image then if word.image then
node = word.node or gui.clone(settings.node_prefab) node = word.node or gui.new_box_node(VECTOR_ZERO, word.size)
gui.set_size_mode(node, gui.SIZE_MODE_MANUAL) gui.set_size_mode(node, gui.SIZE_MODE_MANUAL)
gui.play_flipbook(node, hash(word.image.anim or word.default_animation)) gui.set_texture(node, word.image.texture)
gui.set_color(node, word.color or word.image_color) gui.play_flipbook(node, hash(word.image.anim))
gui.set_color(node, word.color or COLOR_WHITE)
else else
node = word.node or gui.clone(settings.text_prefab) node = word.node or gui.clone(settings.text_prefab)
gui.set_outline(node, word.outline) gui.set_outline(node, word.outline)
@@ -421,6 +434,7 @@ function M._update_nodes(lines, settings)
word.node = node word.node = node
gui.set_enabled(node, true) gui.set_enabled(node, true)
gui.set_parent(node, settings.parent) gui.set_parent(node, settings.parent)
gui.set_pivot(node, word.pivot)
gui.set_size(node, word.size) gui.set_size(node, word.size)
gui.set_scale(node, word.scale) gui.set_scale(node, word.scale)
gui.set_position(node, word.position) gui.set_position(node, word.position)
@@ -429,10 +443,10 @@ function M._update_nodes(lines, settings)
end end
---@param words rich_text.word[] ---@param words druid.rich_text.word[]
---@param settings rich_text.settings ---@param settings druid.rich_text.settings
---@param scale number ---@param scale number
---@return rich_text.lines_metrics ---@return druid.rich_text.lines_metrics
function M.set_text_scale(words, settings, scale) function M.set_text_scale(words, settings, scale)
settings.adjust_scale = scale settings.adjust_scale = scale
@@ -463,7 +477,7 @@ function M.adjust_to_area(words, settings, lines_metrics, style)
if lines_metrics.text_width * scale_koef > settings.width then if lines_metrics.text_width * scale_koef > settings.width then
scale_koef = math.sqrt(settings.width / lines_metrics.text_width) scale_koef = math.sqrt(settings.width / lines_metrics.text_width)
end end
local adjust_scale = math.min(scale_koef, 1) local adjust_scale = math.min(scale_koef, settings.scale.x)
local lines = M.apply_scale_without_update(words, settings, adjust_scale) local lines = M.apply_scale_without_update(words, settings, adjust_scale)
local is_fit = M.is_fit_info_area(lines, settings) local is_fit = M.is_fit_info_area(lines, settings)
@@ -496,15 +510,15 @@ function M.adjust_to_area(words, settings, lines_metrics, style)
end end
---@return boolean @If we fit into area size ---@return druid.rich_text.word[][] lines
function M.apply_scale_without_update(words, settings, scale) function M.apply_scale_without_update(words, settings, scale)
settings.adjust_scale = scale settings.adjust_scale = scale
return M._split_on_lines(words, settings) return M._split_on_lines(words, settings)
end end
---@param lines rich_text.word[][] ---@param lines druid.rich_text.word[][]
---@param settings rich_text.settings ---@param settings druid.rich_text.settings
function M.is_fit_info_area(lines, settings) function M.is_fit_info_area(lines, settings)
local lines_metrics = M._get_lines_metrics(lines, settings) local lines_metrics = M._get_lines_metrics(lines, settings)
local area_size = gui.get_size(settings.parent) local area_size = gui.get_size(settings.parent)

View File

@@ -117,6 +117,10 @@ function M.parse(text, default_settings, style)
assert(default_settings) assert(default_settings)
text = text:gsub("&zwsp;", "<zwsp>\226\128\139</zwsp>") text = text:gsub("&zwsp;", "<zwsp>\226\128\139</zwsp>")
-- Replace all \n with <br/> to make it easier to split the text
text = text:gsub("\n", "<br/>")
local all_words = {} local all_words = {}
local open_tags = {} local open_tags = {}
@@ -145,7 +149,7 @@ function M.parse(text, default_settings, style)
end end
-- parse the tag, split into name and optional parameters -- parse the tag, split into name and optional parameters
local endtag, name, params, empty = tag:match("<(/?)(%a+)=?(%S-)(/?)>") local endtag, name, params, empty = tag:match("<(/?)([%a_]+)=?(%S-)(/?)>")
local is_endtag = endtag == "/" local is_endtag = endtag == "/"
local is_empty = empty == "/" local is_empty = empty == "/"

View File

@@ -93,11 +93,6 @@ M.register("img", function(params, settings)
width, params = split(params, ",") width, params = split(params, ",")
height = split(params, ",") height = split(params, ",")
local texture, anim = split(texture_and_anim, ":") local texture, anim = split(texture_and_anim, ":")
if not anim then
anim = texture
texture = nil
end
width = width and tonumber(width) width = width and tonumber(width)
height = height and tonumber(height) height = height and tonumber(height)
@@ -105,7 +100,7 @@ M.register("img", function(params, settings)
texture = texture, texture = texture,
anim = anim, anim = anim,
width = width, width = width,
height = height height = height or width,
} }
end) end)

View File

@@ -1,199 +0,0 @@
script: ""
fonts {
name: "game"
font: "/example/assets/fonts/game.font"
}
textures {
name: "items"
texture: "/example/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: 400.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: "root"
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_MANUAL
custom_type: 0
enabled: true
visible: false
}
nodes {
position {
x: -200.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: 400.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: "Rich text"
font: "game"
id: "text_prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
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: "root"
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
custom_type: 0
enabled: true
visible: true
}
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: "items/checkmark"
id: "icon_prefab"
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
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -6,31 +6,7 @@
-- This custom component is inspired by <a href="https://github.com/britzl/defold-richtext" target="_blank">defold-richtext</a> by britzl. -- This custom component is inspired by <a href="https://github.com/britzl/defold-richtext" target="_blank">defold-richtext</a> by britzl.
-- It uses a similar syntax for tags but currently supports fewer tags. -- It uses a similar syntax for tags but currently supports fewer tags.
-- --
-- All parameters for the Rich Text component are adjusted in the GUI scene. -- Create Rich Text on your GUI Text Node. All properties of the text node will be used as default for the text.
--
-- This component uses GUI component template. (/druid/custom/rich_text/rich_text.gui).
--
-- You able to customize it or make your own with the next node scructure:
--
-- root
--
-- - text_prefab
--
-- - icon_prefab
--
-- <b># Rich Text Setup #</b>
--
-- • Root node size: Set the maximum width and height of the text.
--
-- • Root anchor: Define the alignment of the Rich Text inside the root node size area.
--
-- • Text prefab: Configure all default text parameters for the text node.
--
-- • Text prefab anchor: Set the anchor for each text node (adjust this only if animating text).
--
-- • Icon prefab: Configure all default node parameters for the icon node.
--
-- • Icon prefab anchor: Set the anchor for each icon node (adjust this only if animating the icon).
-- --
-- <b># Notes #</b> -- <b># Notes #</b>
-- --
@@ -58,7 +34,6 @@
-- outline: vector4, -- outline: vector4,
-- font: string, -- font: string,
-- image: druid.rich_text.image, -- image: druid.rich_text.image,
-- default_animation: string,
-- br: boolean, -- br: boolean,
-- nobr: boolean, -- nobr: boolean,
-- } -- }
@@ -90,6 +65,12 @@
--- The component druid instance --- The component druid instance
-- @tfield DruidInstance druid @{DruidInstance} -- @tfield DruidInstance druid @{DruidInstance}
--- The root node of the Rich Text
-- @tfield node root
--- The text prefab node
-- @tfield node text_prefab
-- --
local component = require("druid.component") local component = require("druid.component")
@@ -97,37 +78,28 @@ local rich_text = require("druid.custom.rich_text.module.rt")
local RichText = component.create("rich_text") local RichText = component.create("rich_text")
local SCHEME = {
ROOT = "root",
TEXT_PREFAB = "text_prefab",
ICON_PREFAB = "icon_prefab"
}
--- The @{RichText} constructor --- The @{RichText} constructor
-- @tparam RichText self @{RichText} -- @tparam RichText self @{RichText}
-- @tparam string template The Rich Text template name -- @tparam node|string text_node The text node to make Rich Text
-- @tparam table nodes The node table, if prefab was copied by gui.clone_tree() -- @tparam string|nil value The initial text value. Default will be gui.get_text(text_node)
function RichText.init(self, template, nodes) function RichText.init(self, text_node, value)
self:set_template(template) self.root = self:get_node(text_node)
self:set_nodes(nodes) self.text_prefab = self.root
self.root = self:get_node(SCHEME.ROOT)
self.druid = self:get_druid()
self.text_prefab = self:get_node(SCHEME.TEXT_PREFAB)
self.icon_prefab = self:get_node(SCHEME.ICON_PREFAB)
gui.set_enabled(self.text_prefab, false)
gui.set_enabled(self.icon_prefab, false)
self._last_value = value or gui.get_text(self.text_prefab)
self._settings = self:_create_settings() self._settings = self:_create_settings()
gui.set_text(self.root, "")
if value then
self:set_text(value)
end
end end
function RichText.on_layout_change(self) function RichText.on_layout_change(self)
gui.set_enabled(self.text_prefab, false)
gui.set_enabled(self.icon_prefab, false)
if self._last_value then if self._last_value then
self:set_text(self._last_value) self:set_text(self._last_value)
end end
@@ -138,9 +110,9 @@ end
-- You can override this component styles params in Druid styles table -- You can override this component styles params in Druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt={}] table COLORS Rich Text color aliases -- @tfield table|nil COLORS Rich Text color aliases. Default: {}
-- @tfield[opt=20] number ADJUST_STEPS Amount steps of attemps text adjust by height -- @tfield number|nil ADJUST_STEPS Amount steps of attemps text adjust by height. Default: 20
-- @tfield[opt=0.02] number ADJUST_SCALE_DELTA Scale step on each height adjust step -- @tfield number|nil ADJUST_SCALE_DELTA Scale step on each height adjust step. Default: 0.02
function RichText.on_style_change(self, style) function RichText.on_style_change(self, style)
self.style = {} self.style = {}
self.style.COLORS = style.COLORS or {} self.style.COLORS = style.COLORS or {}
@@ -151,7 +123,7 @@ end
--- Set text for Rich Text --- Set text for Rich Text
-- @tparam RichText self @{RichText} -- @tparam RichText self @{RichText}
-- @tparam string text The text to set -- @tparam string|nil text The text to set
-- @treturn druid.rich_text.word[] words -- @treturn druid.rich_text.word[] words
-- @treturn druid.rich_text.lines_metrics line_metrics -- @treturn druid.rich_text.lines_metrics line_metrics
-- @usage -- @usage
@@ -198,6 +170,7 @@ end
-- <img=texture:image,size/> -- <img=texture:image,size/>
-- <img=texture:image,width,height/> -- <img=texture:image,width,height/>
function RichText.set_text(self, text) function RichText.set_text(self, text)
text = text or ""
self:clear() self:clear()
self._last_value = text self._last_value = text
@@ -211,6 +184,14 @@ function RichText.set_text(self, text)
end end
--- Get current text
-- @tparam RichText self @{RichText}
-- @treturn string text
function RichText.get_text(self)
return self._last_value
end
function RichText:on_remove() function RichText:on_remove()
self:clear() self:clear()
end end
@@ -227,9 +208,10 @@ end
--- Get all words, which has a passed tag. --- Get all words, which has a passed tag.
-- @tparam RichText self @{RichText}
-- @tparam string tag -- @tparam string tag
-- @treturn druid.rich_text.word[] words -- @treturn druid.rich_text.word[] words
function RichText:tagged(tag) function RichText.tagged(self, tag)
if not self._words then if not self._words then
return return
end end
@@ -238,6 +220,15 @@ function RichText:tagged(tag)
end end
---Split a word into it's characters
-- @tparam RichText self @{RichText}
-- @tparam druid.rich_text.word word
-- @treturn druid.rich_text.word[] characters
function RichText.characters(self, word)
return rich_text.characters(word)
end
--- Get all current words. --- Get all current words.
-- @treturn table druid.rich_text.word[] -- @treturn table druid.rich_text.word[]
function RichText:get_words() function RichText:get_words()
@@ -254,29 +245,33 @@ end
function RichText:_create_settings() function RichText:_create_settings()
local root_size = gui.get_size(self.root) local root_size = gui.get_size(self.root)
local scale = gui.get_scale(self.root)
root_size.x = root_size.x * scale.x
root_size.y = root_size.y * scale.y
gui.set_size(self.root, root_size)
gui.set_scale(self.root, vmath.vector3(1))
return { return {
-- General settings -- General settings
-- Adjust scale using to fit the text to the root node area -- Adjust scale using to fit the text to the root node area
adjust_scale = 1, adjust_scale = 1,
parent = self.root, parent = self.root,
scale = scale,
width = root_size.x, width = root_size.x,
height = root_size.y, height = root_size.y,
combine_words = false, -- disabled now combine_words = false, -- disabled now
text_prefab = self.text_prefab, text_prefab = self.text_prefab,
node_prefab = self.icon_prefab, pivot = gui.get_pivot(self.root),
-- Text Settings -- Text Settings
shadow = gui.get_shadow(self.text_prefab), shadow = gui.get_shadow(self.root),
outline = gui.get_outline(self.text_prefab), outline = gui.get_outline(self.root),
text_scale = gui.get_scale(self.text_prefab), text_leading = gui.get_leading(self.root),
text_leading = gui.get_leading(self.text_prefab), is_multiline = gui.get_line_break(self.root),
is_multiline = gui.get_line_break(self.text_prefab),
-- Image settings -- Image settings
image_pixel_grid_snap = false, -- disabled now image_pixel_grid_snap = false, -- disabled now
node_scale = gui.get_scale(self.icon_prefab),
image_scale = gui.get_scale(self.icon_prefab),
default_animation = gui.get_flipbook(self.icon_prefab),
} }
end end

View File

@@ -107,7 +107,9 @@ function M.new(context, style)
M.set_default_style(default_style) M.set_default_style(default_style)
end end
local new_instance = druid_instance(context, style) local new_instance = setmetatable({}, { __index = druid_instance })
new_instance:initialize(context, style)
table.insert(_instances, new_instance) table.insert(_instances, new_instance)
return new_instance return new_instance
end end

View File

@@ -1,32 +1,22 @@
--- For component interest functions --- For component interest functions
--- see https://github.com/Insality/druid/blob/develop/docs_md/02-creating_custom_components.md --- see https://github.com/Insality/druid/blob/master/docs_md/02-creating_custom_components.md
--- Require this component in you gui file: --- Require this component in you gui file:
--- local {COMPONENT_NAME} = require("{COMPONENT_PATH}") --- $ local {COMPONENT_NAME} = require("{COMPONENT_PATH}")
--- And create this component via: --- And create this component via:
--- self.{COMPONENT_TYPE} = self.druid:new({COMPONENT_NAME}, template, nodes) --- $ self.{COMPONENT_TYPE} = self.druid:new({COMPONENT_NAME}, template, nodes)
local component = require("druid.component") local component = require("druid.component")
---@class {COMPONENT_TYPE}: druid.base_component{COMPONENT_ANNOTATIONS} ---@class {COMPONENT_TYPE}: druid.component
---@field druid druid_instance ---@field druid druid_instance{COMPONENT_ANNOTATIONS}
local {COMPONENT_NAME} = component.create("{COMPONENT_TYPE}") local M = component.create("{COMPONENT_TYPE}")
local SCHEME = {
{SCHEME_LIST}
}
---@param template string ---@param template string
---@param nodes table<hash, node> ---@param nodes table<hash, node>
function {COMPONENT_NAME}:init(template, nodes) function M:init(template, nodes)
self:set_template(template) self.druid = self:get_druid(template, nodes){COMPONENT_DEFINE}
self:set_nodes(nodes)
self.druid = self:get_druid(){COMPONENT_DEFINE}
end
function {COMPONENT_NAME}:on_remove()
end end
{COMPONENT_FUNCTIONS} {COMPONENT_FUNCTIONS}
return {COMPONENT_NAME} return M

View File

@@ -28,54 +28,54 @@ def process_component(node_name, component_name):
if node_name == "root": if node_name == "root":
component_annotations += "\n---@field root node" component_annotations += "\n---@field root node"
component_define += "\n\tself.root = self:get_node(SCHEME.ROOT)" component_define += "\n\tself.root = self:get_node(\"root\")"
if node_name.startswith("button"): if node_name.startswith("button"):
component_annotations += "\n---@field {0} druid.button".format(node_name) component_annotations += "\n---@field {0} druid.button".format(node_name)
component_functions += "\nfunction {1}:_on_{0}()\n\tprint(\"Click on {0}\")\nend\n\n".format(node_name, component_name) component_functions += "\nfunction M:_on_{0}()\n\tprint(\"Click on {0}\")\nend\n\n".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_button(SCHEME.{1}, self._on_{0})".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_button(\"{1}\", self._on_{0})".format(node_name, node_name)
if node_name.startswith("text"): if node_name.startswith("text"):
component_annotations += "\n---@field {0} druid.text".format(node_name) component_annotations += "\n---@field {0} druid.text".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_text(SCHEME.{1})".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_text(\"{1}\")".format(node_name, node_name)
if node_name.startswith("lang_text"): if node_name.startswith("lang_text"):
component_annotations += "\n---@field {0} druid.text".format(node_name) component_annotations += "\n---@field {0} druid.text".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_lang_text(SCHEME.{1}, \"lang_id\")".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_lang_text(\"{1}\", \"lang_id\")".format(node_name, node_name)
if node_name.startswith("grid") or node_name.startswith("static_grid"): if node_name.startswith("grid") or node_name.startswith("static_grid"):
component_annotations += "\n---@field {0} druid.static_grid".format(node_name) component_annotations += "\n---@field {0} druid.static_grid".format(node_name)
component_define += "\n--TODO: Replace prefab_name with grid element prefab" component_define += "\n--TODO: Replace prefab_name with grid element prefab"
component_define += "\n\tself.{0} = self.druid:new_static_grid(SCHEME.{1}, \"prefab_name\", 1)".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_static_grid(\"{1}\", \"prefab_name\", 1)".format(node_name, node_name)
if node_name.startswith("dynamic_grid"): if node_name.startswith("dynamic_grid"):
component_annotations += "\n---@field {0} druid.dynamic_grid".format(node_name) component_annotations += "\n---@field {0} druid.dynamic_grid".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_dynamic_grid(SCHEME.{1})".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_dynamic_grid(\"{1}\")".format(node_name, node_name)
if node_name.startswith("scroll_view"): if node_name.startswith("scroll_view"):
field_name = node_name.replace("_view", "") field_name = node_name.replace("_view", "")
content_name = node_name.replace("_view", "_content") content_name = node_name.replace("_view", "_content")
component_annotations += "\n---@field {0} druid.scroll".format(field_name) component_annotations += "\n---@field {0} druid.scroll".format(field_name)
component_define += "\n\tself.{0} = self.druid:new_scroll(SCHEME.{1}, SCHEME.{2})".format(field_name, get_id(node_name), get_id(content_name)) component_define += "\n\tself.{0} = self.druid:new_scroll(\"{1}\", \"{2}\")".format(field_name, node_name, content_name)
if node_name.startswith("blocker"): if node_name.startswith("blocker"):
component_annotations += "\n---@field {0} druid.blocker".format(node_name) component_annotations += "\n---@field {0} druid.blocker".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_blocker(SCHEME.{1})".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_blocker(\"{1}\")".format(node_name, node_name)
if node_name.startswith("slider"): if node_name.startswith("slider"):
component_annotations += "\n---@field {0} druid.slider".format(node_name) component_annotations += "\n---@field {0} druid.slider".format(node_name)
component_define += "\n--TODO: Replace slider end position. It should be only vertical or horizontal" component_define += "\n--TODO: Replace slider end position. It should be only vertical or horizontal"
component_define += "\n\tself.{0} = self.druid:new_slider(SCHEME.{1}, vmath.vector3(100, 0, 0), self._on_{0}_change)".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_slider(\"{1}\", vmath.vector3(100, 0, 0), self._on_{0}_change)".format(node_name, node_name)
component_functions += "\nfunction {1}:_on_{0}_change(value)\n\tprint(\"Slider change:\", value)\nend\n\n".format(node_name, component_name) component_functions += "\nfunction M:_on_{0}_change(value)\n\tprint(\"Slider change:\", value)\nend\n\n".format(node_name)
if node_name.startswith("progress"): if node_name.startswith("progress"):
component_annotations += "\n---@field {0} druid.progress".format(node_name) component_annotations += "\n---@field {0} druid.progress".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_progress(SCHEME.{1}, \"x\")".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_progress(\"{1}\", \"x\")".format(node_name, get_id(node_name))
if node_name.startswith("timer"): if node_name.startswith("timer"):
component_annotations += "\n---@field {0} druid.timer".format(node_name) component_annotations += "\n---@field {0} druid.timer".format(node_name)
component_define += "\n\tself.{0} = self.druid:new_timer(SCHEME.{1}, 59, 0, self._on_{0}_end)".format(node_name, get_id(node_name)) component_define += "\n\tself.{0} = self.druid:new_timer(\"{1}\", 59, 0, self._on_{0}_end)".format(node_name, get_id(node_name))
component_functions += "\nfunction {1}:_on_{0}_end()\n\tprint(\"Timer {0} trigger\")\nend\n\n".format(node_name, component_name) component_functions += "\nfunction M:_on_{0}_end()\n\tprint(\"Timer {0} trigger\")\nend\n\n".format(node_name)
def main(): def main():
@@ -126,7 +126,7 @@ def main():
filedata = filedata.replace("{COMPONENT_DEFINE}", component_define) filedata = filedata.replace("{COMPONENT_DEFINE}", component_define)
filedata = filedata.replace("{COMPONENT_FUNCTIONS}", component_functions) filedata = filedata.replace("{COMPONENT_FUNCTIONS}", component_functions)
filedata = filedata.replace("{COMPONENT_ANNOTATIONS}", component_annotations) filedata = filedata.replace("{COMPONENT_ANNOTATIONS}", component_annotations)
filedata = filedata.replace("{SCHEME_LIST}", ",\n".join(scheme_list)) #filedata = filedata.replace("{SCHEME_LIST}", ",\n".join(scheme_list))
output_file = open(output_full_path, "w") output_file = open(output_full_path, "w")
output_file.write(filedata) output_file.write(filedata)

View File

@@ -26,36 +26,7 @@ end
function M.get_commands() function M.get_commands()
return { return {
{ {
label = "Print GUI Scheme", label = "Assign Layers",
locations = { "Outline" },
query = {
selection = {type = "outline", cardinality = "many"}
},
active = function(opts)
return true
end,
run = function(opts)
print("local SCHEME = {")
for i = 1, #opts.selection do
local file = opts.selection[i]
if editor.can_get(file, "id") then
local id = editor.get(file, "id")
print("\t" .. string.upper(id) .. " = \"" .. id .. "\",")
end
end
print("}")
print("")
end
},
{
label = "Assign layers",
locations = {"Edit"}, locations = {"Edit"},

View File

@@ -5,11 +5,20 @@
echo "Run bash for $1" echo "Run bash for $1"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
is_defree_installed=$(pip3 list --disable-pip-version-check | grep -E "deftree") # Check if pip3 is installed
if command -v pip3 &> /dev/null; then
PIP_CMD="pip3"
PYTHON_CMD="python3"
else
PIP_CMD="pip"
PYTHON_CMD="python"
fi
is_defree_installed=$($PIP_CMD list --disable-pip-version-check | grep -E "deftree")
if [ -z "$is_defree_installed" ]; then if [ -z "$is_defree_installed" ]; then
echo "The python deftree is not installed. Please install it via" echo "The python deftree is not installed. Please install it via"
echo "pip3 install deftree" echo "$ $PIP_CMD install deftree"
exit 0 exit 0
fi fi
python3 $1 $2 $PYTHON_CMD $1 $2

View File

@@ -8,31 +8,62 @@
-- @module DruidEvent -- @module DruidEvent
-- @alias druid.event -- @alias druid.event
local class = require("druid.system.middleclass") local M = {}
M.COUNTER = 0
local DruidEvent = class("druid.event") -- Forward declaration
local EVENT_METATABLE
-- Local versions
local pcall = pcall
local tinsert = table.insert
local tremove = table.remove
--- DruidEvent constructor --- DruidEvent constructor
-- @tparam DruidEvent self @{DruidEvent} -- @tparam function|nil callback Subscribe the callback on new event, if callback exist
-- @tparam function|nil initial_callback Subscribe the callback on new event, if callback exist -- @tparam any|nil callback_context Additional context as first param to callback call
-- @usage -- @usage
-- local Event = require("druid.event") -- local Event = require("druid.event")
-- ... -- ...
-- local event = Event(initial_callback) -- local event = Event(callback)
function DruidEvent.initialize(self, initial_callback) function M.create(callback, callback_context)
self._callbacks = nil -- initialize later local instance = setmetatable({}, EVENT_METATABLE)
if initial_callback then if callback then
self:subscribe(initial_callback) instance:subscribe(callback, callback_context)
end end
M.COUNTER = M.COUNTER + 1
return instance
end
--- Check is event subscribed.
-- @tparam DruidEvent self @{DruidEvent}
-- @tparam function callback Callback itself
-- @tparam any|nil callback_context Additional context as first param to callback call
-- @treturn boolean, number|nil @Is event subscribed, return index of callback in event as second param
function M.is_subscribed(self, callback, callback_context)
if #self == 0 then
return false, nil
end
for index = 1, #self do
local cb = self[index]
if cb[1] == callback and cb[2] == callback_context then
return true, index
end
end
return false, nil
end end
--- Subscribe callback on event --- Subscribe callback on event
-- @tparam DruidEvent self @{DruidEvent} -- @tparam DruidEvent self @{DruidEvent}
-- @tparam function callback Callback itself -- @tparam function callback Callback itself
-- @tparam any|nil context Additional context as first param to callback call, usually it's self -- @tparam any|nil callback_context Additional context as first param to callback call, usually it's self
-- @treturn boolean True if callback was subscribed
-- @usage -- @usage
-- local function on_long_callback(self) -- local function on_long_callback(self)
-- print("Long click!") -- print("Long click!")
@@ -40,41 +71,39 @@ end
-- ... -- ...
-- local button = self.druid:new_button("button", callback) -- local button = self.druid:new_button("button", callback)
-- button.on_long_click:subscribe(on_long_callback, self) -- button.on_long_click:subscribe(on_long_callback, self)
function DruidEvent.subscribe(self, callback, context) function M.subscribe(self, callback, callback_context)
assert(type(self) == "table", "You should subscribe to event with : syntax") assert(type(self) == "table", "You should subscribe to event with : syntax")
assert(type(callback) == "function", "Callback should be function") assert(callback, "A function must be passed to subscribe to an event")
self._callbacks = self._callbacks or {} if self:is_subscribed(callback, callback_context) then
table.insert(self._callbacks, { return false
callback = callback, end
context = context
})
return callback tinsert(self, { callback, callback_context })
return true
end end
--- Unsubscribe callback on event --- Unsubscribe callback on event
-- @tparam DruidEvent self @{DruidEvent} -- @tparam DruidEvent self @{DruidEvent}
-- @tparam function callback Callback itself -- @tparam function callback Callback itself
-- @tparam any|nil context Additional context as first param to callback call -- @tparam any|nil callback_context Additional context as first param to callback call
-- @usage -- @usage
-- local function on_long_callback(self) -- local function on_long_callback(self)
-- print("Long click!") -- print("Long click!")
-- end -- end
-- ... -- ...
-- button.on_long_click:unsubscribe(on_long_callback, self) -- button.on_long_click:unsubscribe(on_long_callback, self)
function DruidEvent.unsubscribe(self, callback, context) function M.unsubscribe(self, callback, callback_context)
if not self._callbacks then assert(callback, "A function must be passed to subscribe to an event")
return
local _, event_index = self:is_subscribed(callback, callback_context)
if not event_index then
return false
end end
for index, callback_info in ipairs(self._callbacks) do tremove(self, event_index)
if callback_info.callback == callback and callback_info.context == context then return true
table.remove(self._callbacks, index)
return
end
end
end end
@@ -83,11 +112,18 @@ end
-- @treturn boolean True if event have handlers -- @treturn boolean True if event have handlers
-- @usage -- @usage
-- local is_long_click_handler_exists = button.on_long_click:is_exist() -- local is_long_click_handler_exists = button.on_long_click:is_exist()
function DruidEvent.is_exist(self) function M.is_exist(self)
if not self._callbacks then return #self > 0
return false end
end
return #self._callbacks > 0
--- Return true, if event not have handler
--- @tparam DruidEvent self @{DruidEvent}
--- @treturn boolean True if event not have handlers
--- @usage
--- local is_long_click_handler_not_exists = button.on_long_click:is_empty()
function M:is_empty()
return #self == 0
end end
@@ -95,8 +131,10 @@ end
-- @tparam DruidEvent self @{DruidEvent} -- @tparam DruidEvent self @{DruidEvent}
-- @usage -- @usage
-- button.on_long_click:clear() -- button.on_long_click:clear()
function DruidEvent.clear(self) function M.clear(self)
self._callbacks = nil for index = #self, 1, -1 do
self[index] = nil
end
end end
@@ -108,19 +146,60 @@ end
-- ... -- ...
-- local event = Event() -- local event = Event()
-- event:trigger("Param1", "Param2") -- event:trigger("Param1", "Param2")
function DruidEvent.trigger(self, ...) function M.trigger(self, ...)
if not self._callbacks then if #self == 0 then
return false return
end end
for _, callback_info in ipairs(self._callbacks) do local result = nil
if callback_info.context then
callback_info.callback(callback_info.context, ...) local call_callback = self.call_callback
else for index = 1, #self do
callback_info.callback(...) result = call_callback(self, self[index], ...)
end
end end
return result
end end
return DruidEvent -- @tparam table callback Callback data {function, context}
-- @tparam any ... All event params
-- @treturn any Result of the callback
-- @local
function M:call_callback(callback, ...)
local event_callback = callback[1]
local event_callback_context = callback[2]
-- Call callback
local ok, result_or_error
if event_callback_context then
ok, result_or_error = pcall(event_callback, event_callback_context, ...)
else
ok, result_or_error = pcall(event_callback, ...)
end
-- Handle errors
if not ok then
local caller_info = debug.getinfo(2)
pprint("An error occurred during event processing", {
trigger = caller_info.short_src .. ":" .. caller_info.currentline,
error = result_or_error,
})
pprint("Traceback", debug.traceback())
return nil
end
return result_or_error
end
-- Construct event metatable
EVENT_METATABLE = {
__index = M,
__call = M.trigger,
}
return setmetatable(M, {
__call = function(_, callback)
return M.create(callback)
end,
})

View File

@@ -14,7 +14,7 @@
-- @tfield node node -- @tfield node node
--- Button trigger node --- Button trigger node
-- @tfield[opt=node] node click_node -- @tfield node|nil click_node
--- Button component from click_node --- Button component from click_node
-- @tfield Button button @{Button} -- @tfield Button button @{Button}
@@ -50,8 +50,8 @@ end
-- @tparam Checkbox self @{Checkbox} -- @tparam Checkbox self @{Checkbox}
-- @tparam node node Gui node -- @tparam node node Gui node
-- @tparam function callback Checkbox callback -- @tparam function callback Checkbox callback
-- @tparam[opt=node] node click_node Trigger node, by default equals to node -- @tparam node|nil click_node Trigger node, by default equals to node. Default: node
-- @tparam[opt=false] boolean initial_state The initial state of checkbox, default - false -- @tparam boolean|nil initial_state The initial state of checkbox, default - false
function Checkbox.init(self, node, callback, click_node, initial_state) function Checkbox.init(self, node, callback, click_node, initial_state)
self.druid = self:get_druid() self.druid = self:get_druid()
self.node = self:get_node(node) self.node = self:get_node(node)

View File

@@ -25,7 +25,7 @@ local CheckboxGroup = component.create("checkbox_group")
-- @tparam CheckboxGroup self @{CheckboxGroup} -- @tparam CheckboxGroup self @{CheckboxGroup}
-- @tparam node[] nodes Array of gui node -- @tparam node[] nodes Array of gui node
-- @tparam function callback Checkbox callback -- @tparam function callback Checkbox callback
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes -- @tparam node[]|nil click_nodes Array of trigger nodes, by default equals to nodes
function CheckboxGroup.init(self, nodes, callback, click_nodes) function CheckboxGroup.init(self, nodes, callback, click_nodes)
self.druid = self:get_druid() self.druid = self:get_druid()
self.checkboxes = {} self.checkboxes = {}

View File

@@ -13,17 +13,17 @@
-- @tfield Scroll scroll @{Scroll} -- @tfield Scroll scroll @{Scroll}
--- The Druid Grid component --- The Druid Grid component
-- @tfield StaticGrid|DynamicGrid grid @{StaticGrid}, @{DynamicGrid} -- @tfield StaticGrid grid @{StaticGrid}, @{DynamicGrid}
--- The current visual top data index
-- @tfield number top_index
--- The current visual last data index
-- @tfield number last_index
--- The current progress of scroll posititon --- The current progress of scroll posititon
-- @tfield number scroll_progress -- @tfield number scroll_progress
--- The current top index of visual elements
-- @tfield number top_index
--- The current last index of visual elements
-- @tfield number last_index
--- Event triggered when scroll progress is changed; event(self, progress_value) --- Event triggered when scroll progress is changed; event(self, progress_value)
-- @tfield DruidEvent on_scroll_progress_change @{DruidEvent} -- @tfield DruidEvent on_scroll_progress_change @{DruidEvent}
@@ -46,16 +46,14 @@ local DataList = component.create("data_list")
--- The @{DataList} constructor --- The @{DataList} constructor
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam Scroll scroll The @{Scroll} instance for Data List component -- @tparam Scroll scroll The @{Scroll} instance for Data List component
-- @tparam StaticGrid|DynamicGrid grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component -- @tparam StaticGrid grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component
-- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component]) -- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component])
function DataList.init(self, scroll, grid, create_function) function DataList.init(self, scroll, grid, create_function)
self.druid = self:get_druid()
self.scroll = scroll self.scroll = scroll
self.grid = grid self.grid = grid
if self.grid.style then if self.grid.style then
self.grid.style.IS_DYNAMIC_NODE_POSES = false self.grid.style.IS_DYNAMIC_NODE_POSES = false
end end
self.scroll:bind_grid(grid)
-- Current visual elements indexes -- Current visual elements indexes
self.top_index = 1 self.top_index = 1
@@ -63,26 +61,34 @@ function DataList.init(self, scroll, grid, create_function)
self.scroll_progress = 0 self.scroll_progress = 0
self._create_function = create_function self._create_function = create_function
self._is_use_cache = false
self._cache = {}
self._data = {} self._data = {}
self._data_first_index = false
self._data_last_index = false
self._data_length = 0
self._data_visual = {} self._data_visual = {}
self.scroll.on_scroll:subscribe(self._check_elements, self) self.scroll.on_scroll:subscribe(self._refresh, self)
self.on_scroll_progress_change = Event() self.on_scroll_progress_change = Event()
self.on_element_add = Event() self.on_element_add = Event()
self.on_element_remove = Event() self.on_element_remove = Event()
self:set_data()
end end
--- Druid System on_remove function --- Druid System on_remove function
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
function DataList.on_remove(self) function DataList.on_remove(self)
self.scroll.on_scroll:unsubscribe(self._check_elements, self) self:clear()
self.scroll.on_scroll:unsubscribe(self._refresh, self)
end
--- Set refresh function for DataList component
-- @tparam DataList self @{DataList}
-- @tparam boolean is_use_cache Use cache version of DataList. Requires make setup of components in on_element_add callback and clean in on_element_remove
-- @treturn druid.data_list Current DataList instance
function DataList.set_use_cache(self, is_use_cache)
self._is_use_cache = is_use_cache
return self
end end
@@ -92,7 +98,6 @@ end
-- @treturn druid.data_list Current DataList instance -- @treturn druid.data_list Current DataList instance
function DataList.set_data(self, data) function DataList.set_data(self, data)
self._data = data or {} self._data = data or {}
self:_update_data_info()
self:_refresh() self:_refresh()
return self return self
@@ -110,42 +115,35 @@ end
--- Add element to DataList. Currenly untested --- Add element to DataList. Currenly untested
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam table data -- @tparam table data
-- @tparam number index -- @tparam number|nil index
-- @tparam number shift_policy The constant from const.SHIFT.* -- @tparam number|nil shift_policy The constant from const.SHIFT.*
-- @local
function DataList.add(self, data, index, shift_policy) function DataList.add(self, data, index, shift_policy)
index = index or self._data_last_index + 1 index = index or #self._data + 1
shift_policy = shift_policy or const.SHIFT.RIGHT shift_policy = shift_policy or const.SHIFT.RIGHT
helper.insert_with_shift(self._data, data, index, shift_policy) helper.insert_with_shift(self._data, data, index, shift_policy)
self:_update_data_info() self:_refresh()
self:_check_elements()
end end
--- Remove element from DataList. Currenly untested --- Remove element from DataList. Currenly untested
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam number index -- @tparam number|nil index
-- @tparam number shift_policy The constant from const.SHIFT.* -- @tparam number|nil shift_policy The constant from const.SHIFT.*
-- @local
function DataList.remove(self, index, shift_policy) function DataList.remove(self, index, shift_policy)
--self:_refresh()
helper.remove_with_shift(self._data, index, shift_policy) helper.remove_with_shift(self._data, index, shift_policy)
self:_update_data_info() self:_refresh()
end end
--- Remove element from DataList by data value. Currenly untested --- Remove element from DataList by data value. Currenly untested
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam tabe data -- @tparam table data
-- @tparam number shift_policy The constant from const.SHIFT.* -- @tparam number|nil shift_policy The constant from const.SHIFT.*
-- @local
function DataList.remove_by_data(self, data, shift_policy) function DataList.remove_by_data(self, data, shift_policy)
local index = helper.contains(self._data, data) local index = helper.contains(self._data, data)
if index then if index then
helper.remove_with_shift(self._data, index, shift_policy) helper.remove_with_shift(self._data, index, shift_policy)
self:_update_data_info()
self:_refresh() self:_refresh()
end end
end end
@@ -155,32 +153,10 @@ end
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
function DataList.clear(self) function DataList.clear(self)
self._data = {} self._data = {}
self:_update_data_info()
self:_refresh() self:_refresh()
end end
--- Return first index from data. It not always equals to 1
-- @tparam DataList self @{DataList}
function DataList.get_first_index(self)
return self._data_first_index
end
--- Return last index from data
-- @tparam DataList self @{DataList}
function DataList.get_last_index(self)
return self._data_last_index
end
--- Return amount of data
-- @tparam DataList self @{DataList}
function DataList.get_length(self)
return self._data_length
end
--- Return index for data value --- Return index for data value
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam table data -- @tparam table data
@@ -227,17 +203,12 @@ end
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam number index -- @tparam number index
function DataList.scroll_to_index(self, index) function DataList.scroll_to_index(self, index)
local target = helper.clamp(index, self:get_first_index(), self:get_last_index()) local pos = self.grid:get_pos(index)
self.top_index = target self.scroll:scroll_to(pos)
self:_refresh()
if self._data_visual[target] then
self.scroll:scroll_to(gui.get_position(self._data_visual[target].node), true)
end
end end
--- Add element at passed index --- Add element at passed index using cache or create new
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam number index -- @tparam number index
-- @local -- @local
@@ -246,137 +217,98 @@ function DataList._add_at(self, index)
self:_remove_at(index) self:_remove_at(index)
end end
local node, instance = self._create_function(self:get_context(), self._data[index], index, self) local data = self._data[index]
self.grid:add(node, index, const.SHIFT.NO_SHIFT) local node, instance
self._data_visual[index] = {
node = node,
component = instance
}
self.on_element_add:trigger(self:get_context(), index, node, instance) -- Use cache if available and is_use_cache is set
if #self._cache > 0 and self._is_use_cache then
local cached = table.remove(self._cache)
node = cached.node
instance = cached.component
gui.set_enabled(node, true)
else
-- Create a new element if no cache or refresh function is not set
node, instance = self._create_function(self:get_context(), data, index, self)
end
self._data_visual[index] = {
data = data,
node = node,
component = instance,
}
self.grid:add(node, index, const.SHIFT.NO_SHIFT)
self.on_element_add:trigger(self:get_context(), index, node, instance, data)
end end
--- Remove element from passed index --- Remove element from passed index and add it to cache if applicable
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @tparam number index -- @tparam number index
-- @local -- @local
function DataList._remove_at(self, index) function DataList._remove_at(self, index)
self.grid:remove(index, const.SHIFT.NO_SHIFT) self.grid:remove(index, const.SHIFT.NO_SHIFT)
local node = self._data_visual[index].node local visual_data = self._data_visual[index]
local node = visual_data.node
local instance = visual_data.component
local data = visual_data.data
self.on_element_remove:trigger(self:get_context(), index, node, instance, data)
if self._is_use_cache then
-- Disable the node and add it to the cache instead of deleting it
gui.set_enabled(node, false)
table.insert(self._cache, visual_data) -- Cache the removed element
else
-- If no refresh function, delete the node and component as usual
gui.delete_node(node) gui.delete_node(node)
local instance = self._data_visual[index].component
if instance then if instance then
self.druid:remove(instance) instance._meta.druid:remove(instance)
end
end end
self._data_visual[index] = nil
self.on_element_remove:trigger(self:get_context(), index) self._data_visual[index] = nil
end end
--- Refresh all elements in DataList --- Refresh all elements in DataList
-- @tparam DataList self @{DataList} -- @tparam DataList self @{DataList}
-- @local -- @local
function DataList._refresh(self) function DataList._refresh(self)
for index, _ in pairs(self._data_visual) do self.scroll:set_size(self.grid:get_size_for(#self._data))
local start_pos = -self.scroll.position --[[@as vector3]]
local start_index = self.grid:get_index(start_pos)
start_index = math.max(1, start_index)
local pivot = helper.get_pivot_offset(gui.get_pivot(self.scroll.view_node))
local offset_x = self.scroll.view_size.x * (0.5 - pivot.x)
local offset_y = self.scroll.view_size.y * (0.5 + pivot.y)
local end_pos = vmath.vector3(start_pos.x + offset_x, start_pos.y - offset_y, 0)
local end_index = self.grid:get_index(end_pos)
end_index = math.min(#self._data, end_index)
self.top_index = start_index
self.last_index = end_index
-- Clear from non range elements
for index, data in pairs(self._data_visual) do
if index < start_index or index > end_index then
self:_remove_at(index)
elseif self._data[index] ~= data.data then
-- TODO We want to find currently created data instances and move them to new positions
-- Now it will re-create them
self:_remove_at(index) self:_remove_at(index)
end end
self:_check_elements()
end
--- Check elements which should be created
-- @tparam DataList self @{DataList}
-- @local
function DataList._check_elements(self)
for index, data in pairs(self._data_visual) do
if self.scroll:is_node_in_view(data.node) then
self.top_index = index
self.last_index = index
end
end end
self:_check_elements_from(self.top_index, -1) -- Add new elements
self:_check_elements_from(self.top_index + 1, 1) for index = start_index, end_index do
if not self._data_visual[index] and self._data[index] then
for index, data in pairs(self._data_visual) do
self.top_index = math.min(self.top_index or index, index)
self.last_index = math.max(self.last_index or index, index)
end
-- Progress report
local middle_index = (self.last_index + self.top_index) / 2
local progress = (middle_index - self._data_first_index) / (self._data_last_index - self._data_first_index)
progress = helper.clamp(progress, 0, 1)
if self.last_index == self:get_last_index() then
progress = 1
end
if self.top_index == self:get_first_index() then
progress = 0
end
if self.scroll_progress ~= progress then
self.scroll_progress = progress
self.on_scroll_progress_change:trigger(self:get_context(), progress)
end
end
--- Check elements which should be created.
-- Start from index with step until element is outside of scroll view
-- @tparam DataList self @{DataList}
-- @tparam number index
-- @tparam number step
-- @local
function DataList._check_elements_from(self, index, step)
local is_outside = false
while not is_outside do
if not self._data[index] then
break
end
if not self._data_visual[index] then
self:_add_at(index) self:_add_at(index)
end end
if not self.scroll:is_node_in_view(self._data_visual[index].node) then
is_outside = true
-- remove nexts:
-- We add one more element, which is not in view to
-- check what it's always outside to stop spawning
local remove_index = index + step
while self._data_visual[remove_index] do
self:_remove_at(remove_index)
remove_index = remove_index + step
end
end
index = index + step
end
end
--- Update actual data params
-- @tparam DataList self @{DataList}
-- @local
function DataList._update_data_info(self)
self._data_first_index = false
self._data_last_index = false
self._data_length = 0
for index, data in pairs(self._data) do
self._data_first_index = math.min(self._data_first_index or index, index)
self._data_last_index = math.max(self._data_last_index or index, index)
self._data_length = self._data_length + 1
end
if self._data_length == 0 then
self._data_first_index = 0
self._data_last_index = 0
end end
end end

View File

@@ -101,7 +101,7 @@ end
-- @tparam number index The grid element index -- @tparam number index The grid element index
-- @tparam node node The node to be placed -- @tparam node node The node to be placed
-- @tparam number|nil origin_index Index of nearby node -- @tparam number|nil origin_index Index of nearby node
-- @treturn vector3 Node position -- @treturn vector3 node position
function DynamicGrid.get_pos(self, index, node, origin_index) function DynamicGrid.get_pos(self, index, node, origin_index)
local origin_node = self.nodes[origin_index] local origin_node = self.nodes[origin_index]

View File

@@ -7,14 +7,17 @@
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.hotkey -- @alias druid.hotkey
--- On change state callback(self, state) --- On hotkey released callback(self, argument)
-- @tfield DruidEvent on_change_state @{DruidEvent} -- @tfield DruidEvent on_hotkey_pressed @{DruidEvent}
--- On hotkey released callback(self, argument)
-- @tfield DruidEvent on_hotkey_released @{DruidEvent}
--- Visual node --- Visual node
-- @tfield node node -- @tfield node node
--- Button trigger node --- Button trigger node
-- @tfield[opt=node] node click_node -- @tfield node|nil click_node
--- Button component from click_node --- Button component from click_node
-- @tfield Button button @{Button} -- @tfield Button button @{Button}
@@ -24,7 +27,6 @@
local helper = require("druid.helper") local helper = require("druid.helper")
local component = require("druid.component") local component = require("druid.component")
local Event = require("druid.event") local Event = require("druid.event")
local const = require("druid.const")
local Hotkey = component.create("hotkey") local Hotkey = component.create("hotkey")

View File

@@ -9,10 +9,10 @@
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.input -- @alias druid.input
--- On input field select callback(self, button_node) --- On input field select callback(self, input_instance)
-- @tfield DruidEvent on_input_select @{DruidEvent} -- @tfield DruidEvent on_input_select @{DruidEvent}
--- On input field unselect callback(self, input_text) --- On input field unselect callback(self, input_text, input_instance)
-- @tfield DruidEvent on_input_unselect @{DruidEvent} -- @tfield DruidEvent on_input_unselect @{DruidEvent}
--- On input field text change callback(self, input_text) --- On input field text change callback(self, input_text)
@@ -24,12 +24,42 @@
--- On input field text change to max length string callback(self, input_text) --- On input field text change to max length string callback(self, input_text)
-- @tfield DruidEvent on_input_full @{DruidEvent} -- @tfield DruidEvent on_input_full @{DruidEvent}
--- On trying user input with not allowed character callback(self, params, button_instance) --- On trying user input with not allowed character callback(self, params, input_text)
-- @tfield DruidEvent on_input_wrong @{DruidEvent} -- @tfield DruidEvent on_input_wrong @{DruidEvent}
--- On cursor position change callback(self, cursor_index, start_index, end_index)
-- @tfield DruidEvent on_select_cursor_change @{DruidEvent}
--- The cursor index. The index of letter cursor after. Leftmost cursor - 0
-- @tfield number cursor_index
--- The selection start index. The index of letter cursor after. Leftmost selection - 0
-- @tfield number start_index
--- Theselection end index. The index of letter cursor before. Rightmost selection - #text
-- @tfield number end_index
--- Text component --- Text component
-- @tfield Text text @{Text} -- @tfield Text text @{Text}
--- Current input value
-- @tfield string value
--- Previous input value
-- @tfield string previous_value
--- Current input value with marked text
-- @tfield string current_value
--- Marked text for input field. Info: https://defold.com/manuals/input-key-and-text/#marked-text
-- @tfield string marked_value
--- Text width
-- @tfield number text_width
--- Marked text width
-- @tfield number marked_text_width
--- Button component --- Button component
-- @tfield Button button @{Button} -- @tfield Button button @{Button}
@@ -52,12 +82,21 @@
local Event = require("druid.event") local Event = require("druid.event")
local const = require("druid.const") local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component") local component = require("druid.component")
local utf8_lua = require("druid.system.utf8") local utf8_lua = require("druid.system.utf8")
local utf8 = utf8 or utf8_lua local utf8 = utf8 or utf8_lua
local Input = component.create("input") local Input = component.create("input")
Input.ALLOWED_ACTIONS = {
[const.ACTION_TOUCH] = true,
[const.ACTION_TEXT] = true,
[const.ACTION_MARKED_TEXT] = true,
[const.ACTION_BACKSPACE] = true,
[const.ACTION_ENTER] = true,
[const.ACTION_ESC] = true,
}
--- Mask text by replacing every character with a mask character --- Mask text by replacing every character with a mask character
-- @tparam string text -- @tparam string text
@@ -87,31 +126,22 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=false] boolean IS_LONGTAP_ERASE Is long tap will erase current input data -- @tfield boolean IS_LONGTAP_ERASE Is long tap will erase current input data. Default: false
-- @tfield[opt=*] string MASK_DEFAULT_CHAR Default character mask for password input -- @tfield string MASK_DEFAULT_CHAR Default character mask for password input. Default: *]
-- @tfield[opt=false] boolean IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input -- @tfield boolean IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input. Default: false
-- @tfield[opt=false] boolean NO_CONSUME_INPUT_WHILE_SELECTED If true, will not consume input while input is selected. It's allow to interact with other components while input is selected (text input still captured)
-- @tfield function on_select (self, button_node) Callback on input field selecting -- @tfield function on_select (self, button_node) Callback on input field selecting
-- @tfield function on_unselect (self, button_node) Callback on input field unselecting -- @tfield function on_unselect (self, button_node) Callback on input field unselecting
-- @tfield function on_input_wrong (self, button_node) Callback on wrong user input -- @tfield function on_input_wrong (self, button_node) Callback on wrong user input
-- @tfield table button_style Custom button style for input node
function Input.on_style_change(self, style) function Input.on_style_change(self, style)
self.style = {} self.style = {}
self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false
self.style.MASK_DEFAULT_CHAR = style.MASK_DEFAULT_CHAR or "*" self.style.MASK_DEFAULT_CHAR = style.MASK_DEFAULT_CHAR or "*"
self.style.IS_UNSELECT_ON_RESELECT = style.IS_UNSELECT_ON_RESELECT or false self.style.IS_UNSELECT_ON_RESELECT = style.IS_UNSELECT_ON_RESELECT or false
self.style.NO_CONSUME_INPUT_WHILE_SELECTED = style.NO_CONSUME_INPUT_WHILE_SELECTED or false
self.style.on_select = style.on_select or function(_, button_node) end self.style.on_select = style.on_select or function(_, button_node) end
self.style.on_unselect = style.on_unselect or function(_, button_node) end self.style.on_unselect = style.on_unselect or function(_, button_node) end
self.style.on_input_wrong = style.on_input_wrong or function(_, button_node) end self.style.on_input_wrong = style.on_input_wrong or function(_, button_node) end
self.style.button_style = style.button_style or {
LONGTAP_TIME = 0.4,
AUTOHOLD_TRIGGER = 0.8,
DOUBLETAP_TIME = 0.4
}
end end
@@ -121,7 +151,7 @@ end
-- @tparam node|Text text_node Text node what will be changed on user input. You can pass text component instead of text node name @{Text} -- @tparam node|Text text_node Text node what will be changed on user input. You can pass text component instead of text node name @{Text}
-- @tparam number|nil keyboard_type Gui keyboard type for input field -- @tparam number|nil keyboard_type Gui keyboard type for input field
function Input.init(self, click_node, text_node, keyboard_type) function Input.init(self, click_node, text_node, keyboard_type)
self.druid = self:get_druid(self) self.druid = self:get_druid()
if type(text_node) == "table" then if type(text_node) == "table" then
self.text = text_node self.text = text_node
@@ -139,6 +169,9 @@ function Input.init(self, click_node, text_node, keyboard_type)
self.text_width = 0 self.text_width = 0
self.market_text_width = 0 self.market_text_width = 0
self.total_width = 0 self.total_width = 0
self.cursor_index = utf8.len(self.value)
self.start_index = self.cursor_index
self.end_index = self.cursor_index
self.max_length = nil self.max_length = nil
self.allowed_characters = nil self.allowed_characters = nil
@@ -146,10 +179,14 @@ function Input.init(self, click_node, text_node, keyboard_type)
self.keyboard_type = keyboard_type or gui.KEYBOARD_TYPE_DEFAULT self.keyboard_type = keyboard_type or gui.KEYBOARD_TYPE_DEFAULT
self.button = self.druid:new_button(click_node, self.select) self.button = self.druid:new_button(click_node, self.select)
self.button:set_style(self.button_style)
self.button.on_click_outside:subscribe(self.unselect) self.button.on_click_outside:subscribe(self.unselect)
self.button.on_long_click:subscribe(clear_and_select) self.button.on_long_click:subscribe(clear_and_select)
if defos then
self.button.hover.style.ON_HOVER_CURSOR = defos.CURSOR_IBEAM
self.button.hover.style.ON_MOUSE_HOVER_CURSOR = defos.CURSOR_IBEAM
end
if html5 then if html5 then
self.button:set_web_user_interaction(true) self.button:set_web_user_interaction(true)
end end
@@ -160,29 +197,36 @@ function Input.init(self, click_node, text_node, keyboard_type)
self.on_input_empty = Event() self.on_input_empty = Event()
self.on_input_full = Event() self.on_input_full = Event()
self.on_input_wrong = Event() self.on_input_wrong = Event()
self.on_select_cursor_change = Event()
end end
function Input.on_input(self, action_id, action) function Input.on_input(self, action_id, action)
if not (action_id == nil or Input.ALLOWED_ACTIONS[action_id]) then
return false
end
if self.is_selected then if self.is_selected then
local input_text = nil local input_text = nil
local is_marked_text_changed = false
local cursor_shift_indexes = nil
if action_id == const.ACTION_TEXT then if action_id == const.ACTION_TEXT then
-- ignore return key -- ignore return key
if action.text == "\n" or action.text == "\r" then if action.text == "\n" or action.text == "\r" then
return true return true
end end
local hex = string.gsub(action.text,"(.)", function (c) local hex = string.gsub(action.text, "(.)", function(c)
return string.format("%02X%s",string.byte(c), "") return string.format("%02X%s",string.byte(c), "")
end) end)
-- ignore arrow keys -- ignore arrow keys
if not utf8.match(hex, "EF9C8[0-3]") then if not utf8.match(hex, "EF9C8[0-3]") then
if not self.allowed_characters or utf8.match(action.text, self.allowed_characters) then if not self.allowed_characters or utf8.match(action.text, self.allowed_characters) then
input_text = self.value .. action.text local shift_offset = self.cursor_index - self.start_index
if self.max_length then input_text = self:get_text_selected_replaced(action.text)
input_text = utf8.sub(input_text, 1, self.max_length) cursor_shift_indexes = utf8.len(action.text) - shift_offset
end
else else
self.on_input_wrong:trigger(self:get_context(), action.text) self.on_input_wrong:trigger(self:get_context(), action.text)
self.style.on_input_wrong(self, self.button.node) self.style.on_input_wrong(self, self.button.node)
@@ -196,10 +240,28 @@ function Input.on_input(self, action_id, action)
if self.max_length then if self.max_length then
self.marked_value = utf8.sub(self.marked_value, 1, self.max_length) self.marked_value = utf8.sub(self.marked_value, 1, self.max_length)
end end
is_marked_text_changed = true
end end
if action_id == const.ACTION_BACKSPACE and (action.pressed or action.repeated) then if action_id == const.ACTION_BACKSPACE and (action.pressed or action.repeated) then
input_text = utf8.sub(self.value, 1, -2) local start_index = self.start_index or utf8.len(self.value)
local end_index = self.end_index or utf8.len(self.value)
-- If start == end index, remove left of this selection letter, else delete all selection
if start_index == end_index then
local left_part = utf8.sub(self.value, 1, math.max(0, start_index - 1))
local right_part = utf8.sub(self.value, end_index + 1, utf8.len(self.value))
input_text = left_part .. right_part
cursor_shift_indexes = -1
else
local left_part = utf8.sub(self.value, 1, start_index)
local right_part = utf8.sub(self.value, end_index + 1, utf8.len(self.value))
input_text = left_part .. right_part
-- Calculate offsets from cursor pos to start index
cursor_shift_indexes = start_index - self.cursor_index
end
end end
if action_id == const.ACTION_ENTER and action.released then if action_id == const.ACTION_ENTER and action.released then
@@ -217,14 +279,23 @@ function Input.on_input(self, action_id, action)
return true return true
end end
if input_text or #self.marked_value > 0 then if input_text or is_marked_text_changed then
self:set_text(input_text) self:set_text(input_text)
if cursor_shift_indexes then
self:select_cursor(self.cursor_index + cursor_shift_indexes)
end
return true return true
end end
end end
local is_consume_input = not self.style.NO_CONSUME_INPUT_WHILE_SELECTED and self.is_selected local is_mouse_action = action_id == const.ACTION_TOUCH or not action_id
return is_consume_input if is_mouse_action then
return false
end
return self.is_selected
end end
@@ -234,7 +305,33 @@ end
function Input.on_input_interrupt(self) function Input.on_input_interrupt(self)
-- self:unselect() --self:unselect()
end
function Input.get_text_selected(self)
if self.start_index == self.end_index then
return self.value
end
return utf8.sub(self.value, self.start_index + 1, self.end_index)
end
--- Replace selected text with new text
-- @tparam Input self @{Input}
-- @tparam string text The text to replace selected text
-- @treturn string New input text
function Input.get_text_selected_replaced(self, text)
local left_part = utf8.sub(self.value, 1, self.start_index)
local right_part = utf8.sub(self.value, self.end_index + 1, utf8.len(self.value))
local result = left_part .. text .. right_part
if self.max_length then
result = utf8.sub(result, 1, self.max_length)
end
return result
end end
@@ -242,6 +339,8 @@ end
-- @tparam Input self @{Input} -- @tparam Input self @{Input}
-- @tparam string input_text The string to apply for input field -- @tparam string input_text The string to apply for input field
function Input.set_text(self, input_text) function Input.set_text(self, input_text)
input_text = tostring(input_text or "")
-- Case when update with marked text -- Case when update with marked text
if input_text then if input_text then
self.value = input_text self.value = input_text
@@ -297,8 +396,10 @@ function Input.select(self)
self.is_selected = true self.is_selected = true
gui.show_keyboard(self.keyboard_type, false) gui.show_keyboard(self.keyboard_type, false)
self.on_input_select:trigger(self:get_context())
local len = utf8.len(self.value)
self:select_cursor(len, len, len)
self.on_input_select:trigger(self:get_context(), self)
self.style.on_select(self, self.button.node) self.style.on_select(self, self.button.node)
else else
if self.style.IS_UNSELECT_ON_RESELECT then if self.style.IS_UNSELECT_ON_RESELECT then
@@ -313,13 +414,14 @@ end
function Input.unselect(self) function Input.unselect(self)
gui.reset_keyboard() gui.reset_keyboard()
self.marked_value = "" self.marked_value = ""
self.value = self.current_value
if self.is_selected then if self.is_selected then
self:reset_input_priority() self:reset_input_priority()
self.button:reset_input_priority() self.button:reset_input_priority()
self.is_selected = false self.is_selected = false
gui.hide_keyboard() gui.hide_keyboard()
self.on_input_unselect:trigger(self:get_context(), self:get_text()) self.on_input_unselect:trigger(self:get_context(), self:get_text(), self)
self.style.on_unselect(self, self.button.node) self.style.on_unselect(self, self.button.node)
end end
@@ -330,7 +432,11 @@ end
-- @tparam Input self @{Input} -- @tparam Input self @{Input}
-- @treturn string The current input field text -- @treturn string The current input field text
function Input.get_text(self) function Input.get_text(self)
if self.marked_value ~= "" then
return self.value .. self.marked_value return self.value .. self.marked_value
end
return self.value
end end
@@ -359,9 +465,97 @@ end
--- Reset current input selection and return previous value --- Reset current input selection and return previous value
-- @tparam Input self @{Input} -- @tparam Input self @{Input}
-- @treturn druid.input Current input instance
function Input.reset_changes(self) function Input.reset_changes(self)
self:set_text(self.previous_value) self:set_text(self.previous_value)
self:unselect() self:unselect()
return self
end
--- Set cursor position in input field
-- @tparam Input self @{Input}
-- @tparam number|nil cursor_index Cursor index for cursor position, if nil - will be set to the end of the text
-- @tparam number|nil start_index Start index for cursor position, if nil - will be set to the end of the text
-- @tparam number|nil end_index End index for cursor position, if nil - will be set to the start_index
-- @treturn druid.input Current input instance
function Input.select_cursor(self, cursor_index, start_index, end_index)
local len = utf8.len(self.value)
self.cursor_index = cursor_index or len
self.start_index = start_index or self.cursor_index
self.end_index = end_index or self.start_index
self.cursor_index = helper.clamp(self.cursor_index, 0, len)
self.start_index = helper.clamp(self.start_index, 0, len)
self.end_index = helper.clamp(self.end_index, 0, len)
self.on_select_cursor_change:trigger(self:get_context(), self.cursor_index, self.start_index, self.end_index)
return self
end
--- Change cursor position by delta
-- @tparam Input self @{Input}
-- @tparam number delta side for cursor position, -1 for left, 1 for right
-- @tparam boolean is_add_to_selection (Shift key)
-- @tparam boolean is_move_to_end (Ctrl key)
function Input.move_selection(self, delta, is_add_to_selection, is_move_to_end)
local len = utf8.len(self.value)
local cursor_index = self.cursor_index
local start_index, end_index -- if nil, the selection will be 0 at cursor position
local is_right = delta > 0
local target_index = cursor_index + delta
if is_move_to_end then
target_index = is_right and len or 0
end
-- The Shift is not pressed
if not is_add_to_selection then
cursor_index = target_index
if self.start_index ~= self.end_index then
-- Reset selection without moving cursor
cursor_index = self.cursor_index
end
end
-- The Shift is pressed
if is_add_to_selection then
cursor_index = target_index
start_index = self.start_index
end_index = self.end_index
local is_cursor_extends_selection = (self.cursor_index == (is_right and end_index or start_index))
if is_cursor_extends_selection then
if is_right then
end_index = cursor_index
else
start_index = cursor_index
end
else
if is_right then
start_index = cursor_index
if is_move_to_end then
start_index = end_index
end_index = cursor_index
end
else
end_index = cursor_index
if is_move_to_end then
end_index = start_index
start_index = cursor_index
end
end
end
end
self:select_cursor(cursor_index, start_index, end_index)
end end

View File

@@ -38,8 +38,8 @@ local LangText = component.create("lang_text")
--- The @{LangText} constructor --- The @{LangText} constructor
-- @tparam LangText self @{LangText} -- @tparam LangText self @{LangText}
-- @tparam string|node node The node_id or gui.get_node(node_id) -- @tparam string|node node The node_id or gui.get_node(node_id)
-- @tparam[opt=node_text] string locale_id Default locale id or text from node as default -- @tparam string|nil locale_id Default locale id or text from node as default
-- @tparam[opt=downscale] string adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference -- @tparam string|nil adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
function LangText.init(self, node, locale_id, adjust_type) function LangText.init(self, node, locale_id, adjust_type)
self.druid = self:get_druid() self.druid = self:get_druid()
self.text = self.druid:new_text(node, locale_id, adjust_type) self.text = self.druid:new_text(node, locale_id, adjust_type)

View File

@@ -1,4 +1,4 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2024 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Layout management on node --- Layout management on node
-- --
@@ -13,205 +13,411 @@
--- Current layout mode --- Current layout mode
-- @tfield string mode -- @tfield string mode
---On window resize callback(self, new_size)
-- @tfield DruidEvent on_size_changed @{DruidEvent}
--- ---
local const = require("druid.const")
local helper = require("druid.helper") local helper = require("druid.helper")
local component = require("druid.component") local component = require("druid.component")
local Event = require("druid.event")
-- @class druid.layout.row_data
-- @tfield width number
-- @tfield height number
-- @tfield count number
local Layout = component.create("layout") -- @class druid.layout.rows_data
-- @tfield total_width number
-- @tfield total_height number
-- @tfield nodes_width table<node, number>
-- @tfield nodes_height table<node, number>
-- @tfield rows druid.layout.row_data[]>
-- @class druid.layout: druid.base_component
local M = component.create("layout")
--- The @{Layout} constructor -- The @{Layout} constructor
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam node node Gui node -- @tparam node node Gui node
-- @tparam string mode The layout mode (from const.LAYOUT_MODE) -- @tparam string layout_type The layout mode (from const.LAYOUT_MODE)
-- @tparam function|nil on_size_changed_callback The callback on window resize -- @tparam function|nil on_size_changed_callback The callback on window resize
function Layout.init(self, node, mode, on_size_changed_callback) function M.init(self, node, layout_type)
self.node = self:get_node(node) self.node = self:get_node(node)
self._min_size = nil self.is_dirty = true
self._max_size = nil self.entities = {}
self._current_size = vmath.vector3(0) self.margin = { x = 0, y = 0 }
self._inited = false self.padding = gui.get_slice9(self.node)
self._max_gui_upscale = nil self.type = layout_type or "horizontal"
self._fit_node = nil self.is_resize_width = false
self.is_resize_height = false
self._anchors = {} self.is_justify = false
self.mode = mode or const.LAYOUT_MODE.FIT
self.on_size_changed = Event(on_size_changed_callback)
end end
function M:update()
function Layout.on_late_init(self) if not self.is_dirty then
self._inited = true
self.origin_size = self.origin_size or gui.get_size(self.node)
self.fit_size = self.fit_size or vmath.vector3(self.origin_size)
self.pivot = helper.get_pivot_offset(gui.get_pivot(self.node))
self.origin_position = gui.get_position(self.node)
self.position = vmath.vector3(self.origin_position)
gui.set_size_mode(self.node, gui.SIZE_MODE_MANUAL)
gui.set_adjust_mode(self.node, gui.ADJUST_FIT)
self:on_window_resized()
end
function Layout.on_window_resized(self)
if not self._inited then
return return
end end
local x_koef, y_koef = helper.get_screen_aspect_koef() self:refresh_layout()
local revert_scale = 1
if self._max_gui_upscale then
revert_scale = self._max_gui_upscale / helper.get_gui_scale()
revert_scale = math.min(revert_scale, 1)
end
gui.set_scale(self.node, vmath.vector3(revert_scale))
if self._fit_node then
self.fit_size = gui.get_size(self._fit_node)
self.fit_size.x = self.fit_size.x / x_koef
self.fit_size.y = self.fit_size.y / y_koef
end
x_koef = self.fit_size.x / self.origin_size.x * x_koef
y_koef = self.fit_size.y / self.origin_size.y * y_koef
local new_size = vmath.vector3(self.origin_size)
if self.mode == const.LAYOUT_MODE.STRETCH then
new_size.x = new_size.x * x_koef / revert_scale
new_size.y = new_size.y * y_koef / revert_scale
end
if self.mode == const.LAYOUT_MODE.STRETCH_X then
new_size.x = new_size.x * x_koef / revert_scale
end
if self.mode == const.LAYOUT_MODE.STRETCH_Y then
new_size.y = new_size.y * y_koef / revert_scale
end
-- Fit to the stretched container (node size or other defined)
if self.mode == const.LAYOUT_MODE.ZOOM_MIN then
new_size = new_size * math.min(x_koef, y_koef)
end
if self.mode == const.LAYOUT_MODE.ZOOM_MAX then
new_size = new_size * math.max(x_koef, y_koef)
end
if self._min_size then
new_size.x = math.max(new_size.x, self._min_size.x)
new_size.y = math.max(new_size.y, self._min_size.y)
end
if self._max_size then
new_size.x = math.min(new_size.x, self._max_size.x)
new_size.y = math.min(new_size.y, self._max_size.y)
end
self._current_size = new_size
gui.set_size(self.node, new_size)
self.position.x = self.origin_position.x + self.origin_position.x * (x_koef - 1)
self.position.y = self.origin_position.y + self.origin_position.y * (y_koef - 1)
gui.set_position(self.node, self.position)
self.on_size_changed:trigger(self:get_context(), new_size)
end end
--- Set minimal size of layout node
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam vector3 min_size -- @tparam number|nil margin_x
-- @treturn Layout @{Layout} -- @tparam number|nil margin_y
function Layout.set_min_size(self, min_size) -- @treturn druid.layout @{Layout}
self._min_size = min_size function M.set_margin(self, margin_x, margin_y)
self.margin.x = margin_x or self.margin.x
self.margin.y = margin_y or self.margin.y
self.is_dirty = true
return self return self
end end
--- Set maximum size of layout node
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam vector3 max_size -- @tparam vector4 padding The vector4 with padding values, where x - left, y - top, z - right, w - bottom
-- @treturn Layout @{Layout} -- @treturn druid.layout @{Layout}
function Layout.set_max_size(self, max_size) function M.set_padding(self, padding)
self._max_size = max_size self.padding = padding
self.is_dirty = true
return self return self
end end
--- Set new origin position of layout node. You should apply this on node movement
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam vector3 new_origin_position -- @treturn druid.layout @{Layout}
-- @treturn Layout @{Layout} function M.set_dirty(self)
function Layout.set_origin_position(self, new_origin_position) self.is_dirty = true
self.origin_position = new_origin_position or self.origin_position
self:on_window_resized()
return self return self
end end
--- Set new origin size of layout node. You should apply this on node manual size change
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam vector3 new_origin_size -- @tparam boolean is_justify
-- @treturn Layout @{Layout} -- @treturn druid.layout @{Layout}
function Layout.set_origin_size(self, new_origin_size) function M.set_justify(self, is_justify)
self.origin_size = new_origin_size or self.origin_size self.is_justify = is_justify
self:on_window_resized() self.is_dirty = true
return self return self
end end
--- Set max gui upscale for FIT adjust mode (or side). It happens on bigger render gui screen
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam number max_gui_upscale -- @tparam string type The layout type: "horizontal", "vertical", "horizontal_wrap"
-- @treturn Layout @{Layout} -- @treturn druid.layout @{Layout}
function Layout.set_max_gui_upscale(self, max_gui_upscale) function M.set_type(self, type)
self._max_gui_upscale = max_gui_upscale self.type = type
self:on_window_resized() self.is_dirty = true
end
--- Set size for layout node to fit inside it
-- @tparam Layout self @{Layout}
-- @tparam vector3 target_size
-- @treturn Layout @{Layout}
function Layout.fit_into_size(self, target_size)
self.fit_size = target_size
self:on_window_resized()
return self return self
end end
--- Set node for layout node to fit inside it. Pass nil to reset
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @tparam node|nil node -- @tparam boolean is_hug_width
-- @treturn Layout @{Layout} -- @tparam boolean is_hug_height
function Layout.fit_into_node(self, node) -- @treturn druid.layout @{Layout}
self._fit_node = node function M.set_hug_content(self, is_hug_width, is_hug_height)
self:on_window_resized() self.is_resize_width = is_hug_width or false
self.is_resize_height = is_hug_height or false
self.is_dirty = true
return self return self
end end
--- Set current size for layout node to fit inside it
-- @tparam Layout self @{Layout} -- @tparam Layout self @{Layout}
-- @treturn Layout @{Layout} -- @tparam string|node node_or_node_id
function Layout.fit_into_window(self) -- @treturn druid.layout @{Layout}
return self:fit_into_size(vmath.vector3( function M.add(self, node_or_node_id)
gui.get_width(), -- Acquire node from entity or by id
gui.get_height(), local node = node_or_node_id
0)) if type(node_or_node_id) == "table" then
assert(node_or_node_id.node, "The entity should have a node")
node = node_or_node_id.node
else
-- @cast node_or_node_id string|node
node = self:get_node(node_or_node_id)
end
-- @cast node node
table.insert(self.entities, node)
gui.set_parent(node, self.node)
self.is_dirty = true
return self
end end
return Layout -- @tparam Layout self @{Layout}
-- @treturn druid.layout @{Layout}
function M.refresh_layout(self)
local layout_node = self.node
local entities = self.entities
local type = self.type -- vertical, horizontal, horizontal_wrap
local margin = self.margin -- {x: horizontal, y: vertical} in pixels, between elements
local padding = self.padding -- {x: left, y: top, z: right, w: bottom} in pixels
local is_justify = self.is_justify
local size = gui.get_size(layout_node)
local max_width = size.x - padding.x - padding.z
local max_height = size.y - padding.y - padding.w
local layout_pivot_offset = helper.get_pivot_offset(gui.get_pivot(layout_node)) -- {x: -0.5, y: -0.5} - is left bot, {x: 0.5, y: 0.5} - is right top
local rows_data = self:calculate_rows_data()
local rows = rows_data.rows
local row_index = 1
local row = rows[row_index]
-- Current x and Current y is a top left corner of the node
local current_x = -row.width * (0.5 + layout_pivot_offset.x)
local current_y = rows_data.total_height * (0.5 - layout_pivot_offset.y)
if is_justify then
if (type == "horizontal" or type == "horizontal_wrap") and row.count > 1 then
current_x = -max_width * (0.5 + layout_pivot_offset.x)
end
if type == "vertical" then
current_y = max_height * (0.5 - layout_pivot_offset.y)
end
end
for index = 1, #entities do
local node = entities[index]
local node_width = rows_data.nodes_width[node]
local node_height = rows_data.nodes_height[node]
local pivot_offset = helper.get_pivot_offset(gui.get_pivot(node))
if node_width > 0 and node_height > 0 then
-- Calculate position for current node
local position_x, position_y
if type == "horizontal" then
position_x = current_x + node_width * (0.5 + pivot_offset.x)
position_y = current_y - row.height * (0.5 - pivot_offset.y)
local node_margin = margin.x
if is_justify and row.count > 1 then
node_margin = (max_width - row.width) / (row.count - 1) + margin.x
end
current_x = current_x + node_width + node_margin
end
if type == "vertical" then
local node_margin = margin.y
if is_justify then
node_margin = (max_height - rows_data.total_height) / (#rows - 1) + margin.y
end
current_x = -row.width * (0.5 + layout_pivot_offset.x)
position_x = current_x + row.width * (0.5 + pivot_offset.x)
position_y = current_y - node_height * (0.5 - pivot_offset.y)
current_y = current_y - node_height - node_margin
row_index = row_index + 1
row = rows[row_index]
end
if type == "horizontal_wrap" then
local width = row.width
if is_justify and row.count > 0 then
width = math.max(row.width, max_width)
end
local new_row_width = width * (0.5 - layout_pivot_offset.x)
-- Compare with eps due the float loss and element flickering
if current_x + node_width - new_row_width > 0.0001 then
if row_index < #rows then
row_index = row_index + 1
row = rows[row_index]
end
current_x = -row.width * (0.5 + layout_pivot_offset.x)
current_y = current_y - row.height - margin.y
if is_justify and row.count > 1 then
current_x = -max_width * (0.5 + layout_pivot_offset.x)
end
end
position_x = current_x + node_width * (0.5 + pivot_offset.x)
position_y = current_y - row.height * (0.5 - pivot_offset.y)
local node_margin = margin.x
if is_justify and row.count > 1 then
node_margin = (max_width - row.width) / (row.count - 1) + margin.x
end
current_x = current_x + node_width + node_margin
end
do -- Padding offset
if layout_pivot_offset.x == -0.5 then
position_x = position_x + padding.x
end
if layout_pivot_offset.y == 0.5 then
position_y = position_y - padding.y
end
if layout_pivot_offset.x == 0.5 then
position_x = position_x - padding.z
end
if layout_pivot_offset.y == -0.5 then
position_y = position_y + padding.w
end
end
self:set_node_position(node, position_x, position_y)
end
end
if self.is_resize_width or self.is_resize_height then
if self.is_resize_width then
size.x = rows_data.total_width + padding.x + padding.z
end
if self.is_resize_height then
size.y = rows_data.total_height + padding.y + padding.w
end
gui.set_size(layout_node, size)
end
self.is_dirty = false
return self
end
-- @tparam Layout self @{Layout}
-- @treturn druid.layout @{Layout}
function M.clear_layout(self)
for index = #self.entities, 1, -1 do
self.entities[index] = nil
end
self.is_dirty = true
return self
end
-- @tparam node node
-- @treturn number, number
-- @local
function M.get_node_size(node)
if not gui.is_enabled(node, false) then
return 0, 0
end
local scale = gui.get_scale(node)
-- If node has text - get text size instead of node size
if gui.get_text(node) then
local text_metrics = helper.get_text_metrics_from_node(node)
return text_metrics.width * scale.x, text_metrics.height * scale.y
end
local size = gui.get_size(node)
return size.x * scale.x, size.y * scale.y
end
-- @tparam Layout self @{Layout}
-- Calculate rows data for layout. Contains total width, height and rows info (width, height, count of elements in row)
-- @treturn druid.layout.rows_data
-- @local
function M.calculate_rows_data(self)
local entities = self.entities
local margin = self.margin
local type = self.type
local padding = self.padding
local size = gui.get_size(self.node)
local max_width = size.x - padding.x - padding.z
-- Collect rows info about width, height and count of elements in row
local current_row = { width = 0, height = 0, count = 0 }
local rows_data = {
total_width = 0,
total_height = 0,
nodes_width = {},
nodes_height = {},
rows = { current_row }
}
for index = 1, #entities do
local node = entities[index]
local node_width = rows_data.nodes_width[node]
local node_height = rows_data.nodes_height[node]
-- Get node size if it's not calculated yet
if not node_width or not node_height then
node_width, node_height = M.get_node_size(node)
rows_data.nodes_width[node] = node_width
rows_data.nodes_height[node] = node_height
end
if node_width > 0 and node_height > 0 then
if type == "horizontal" then
current_row.width = current_row.width + node_width + margin.x
current_row.height = math.max(current_row.height, node_height)
current_row.count = current_row.count + 1
end
if type == "vertical" then
if current_row.count > 0 then
current_row = { width = 0, height = 0, count = 0 }
table.insert(rows_data.rows, current_row)
end
current_row.width = math.max(current_row.width, node_width + margin.x)
current_row.height = node_height
current_row.count = current_row.count + 1
end
if type == "horizontal_wrap" then
if current_row.width + node_width > max_width and current_row.count > 0 then
current_row = { width = 0, height = 0, count = 0 }
table.insert(rows_data.rows, current_row)
end
current_row.width = current_row.width + node_width + margin.x
current_row.height = math.max(current_row.height, node_height)
current_row.count = current_row.count + 1
end
end
end
-- Remove last margin of each row
-- Calculate total width and height
local rows_count = #rows_data.rows
for index = 1, rows_count do
local row = rows_data.rows[index]
if row.width > 0 then
row.width = row.width - margin.x
end
rows_data.total_width = math.max(rows_data.total_width, row.width)
rows_data.total_height = rows_data.total_height + row.height
end
rows_data.total_height = rows_data.total_height + margin.y * (rows_count - 1)
return rows_data
end
-- @tparam node node
-- @tparam number x
-- @tparam number y
-- @treturn node
-- @local
function M:set_node_position(node, x, y)
local position = gui.get_position(node)
position.x = x
position.y = y
gui.set_position(node, position)
return node
end
return M

View File

@@ -76,15 +76,29 @@ end
local function set_bar_to(self, set_to, is_silent) local function set_bar_to(self, set_to, is_silent)
local prev_value = self.last_value local prev_value = self.last_value
local other_side = self.key == const.SIDE.X and const.SIDE.Y or const.SIDE.X
self.last_value = set_to self.last_value = set_to
local total_width = set_to * self.max_size local total_width = set_to * self.max_size[self.key]
local scale = math.min(total_width / self.slice_size, 1) local scale = 1
local size = math.max(total_width, self.slice_size) if self.slice_size[self.key] > 0 then
scale = math.min(total_width / self.slice_size[self.key], 1)
end
local size = math.max(total_width, self.slice_size[self.key])
do -- Scale other side
-- Decrease other side of progress bar to match the oppotize slice_size
local minimal_size = self.size[other_side] - self.slice_size[other_side]
local maximum_size = self.size[other_side]
local scale_diff = (maximum_size - minimal_size) / maximum_size
local other_scale = 1 - (scale_diff * (1 - scale))
self.scale[other_side] = other_scale
end
self.scale[self.key] = scale self.scale[self.key] = scale
gui.set_scale(self.node, self.scale) gui.set_scale(self.node, self.scale)
self.size[self.key] = size self.size[self.key] = size
gui.set_size(self.node, self.size) gui.set_size(self.node, self.size)
@@ -101,8 +115,8 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=5] number SPEED Progress bas fill rate. More -> faster -- @tfield number|nil SPEED Progress bas fill rate. More -> faster. Default: 5
-- @tfield[opt=0.005] number MIN_DELTA Minimum step to fill progress bar -- @tfield number|nil MIN_DELTA Minimum step to fill progress bar. Default: 0.005
function Progress.on_style_change(self, style) function Progress.on_style_change(self, style)
self.style = {} self.style = {}
self.style.SPEED = style.SPEED or 5 self.style.SPEED = style.SPEED or 5
@@ -114,7 +128,7 @@ end
-- @tparam Progress self @{Progress} -- @tparam Progress self @{Progress}
-- @tparam string|node node Node name or GUI Node itself. -- @tparam string|node node Node name or GUI Node itself.
-- @tparam string key Progress bar direction: const.SIDE.X or const.SIDE.Y -- @tparam string key Progress bar direction: const.SIDE.X or const.SIDE.Y
-- @tparam[opt=1] number init_value Initial value of progress bar -- @tparam number|nil init_value Initial value of progress bar. Default: 1
function Progress.init(self, node, key, init_value) function Progress.init(self, node, key, init_value)
assert(key == const.SIDE.X or const.SIDE.Y, "Progress bar key should be 'x' or 'y'") assert(key == const.SIDE.X or const.SIDE.Y, "Progress bar key should be 'x' or 'y'")
@@ -125,15 +139,15 @@ function Progress.init(self, node, key, init_value)
self.node = self:get_node(node) self.node = self:get_node(node)
self.scale = gui.get_scale(self.node) self.scale = gui.get_scale(self.node)
self.size = gui.get_size(self.node) self.size = gui.get_size(self.node)
self.max_size = self.size[self.key] self.max_size = gui.get_size(self.node)
self.slice = gui.get_slice9(self.node) self.slice = gui.get_slice9(self.node)
self.last_value = self._init_value self.last_value = self._init_value
if self.key == const.SIDE.X then self.slice_size = vmath.vector3(
self.slice_size = self.slice.x + self.slice.z self.slice.x + self.slice.z,
else self.slice.y + self.slice.w,
self.slice_size = self.slice.y + self.slice.w 0
end )
self.on_change = Event() self.on_change = Event()
@@ -146,6 +160,12 @@ function Progress.on_layout_change(self)
end end
function Progress.on_remove(self)
-- Return default size
gui.set_size(self.node, self.max_size)
end
function Progress.update(self, dt) function Progress.update(self, dt)
if self.target then if self.target then
local prev_value = self.last_value local prev_value = self.last_value
@@ -231,7 +251,7 @@ end
-- @tparam vector3 max_size The new node maximum (full) size -- @tparam vector3 max_size The new node maximum (full) size
-- @treturn Progress @{Progress} -- @treturn Progress @{Progress}
function Progress.set_max_size(self, max_size) function Progress.set_max_size(self, max_size)
self.max_size = max_size[self.key] self.max_size[self.key] = max_size[self.key]
self:set_to(self.last_value) self:set_to(self.last_value)
return self return self
end end

View File

@@ -34,7 +34,7 @@ end
-- @tparam RadioGroup self @{RadioGroup} -- @tparam RadioGroup self @{RadioGroup}
-- @tparam node[] nodes Array of gui node -- @tparam node[] nodes Array of gui node
-- @tparam function callback Radio callback -- @tparam function callback Radio callback
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes -- @tparam node[]|nil click_nodes Array of trigger nodes, by default equals to nodes. Default - nodes
function RadioGroup.init(self, nodes, callback, click_nodes) function RadioGroup.init(self, nodes, callback, click_nodes)
self.druid = self:get_druid() self.druid = self:get_druid()
self.checkboxes = {} self.checkboxes = {}

View File

@@ -26,7 +26,7 @@
-- @tfield vector3 end_pos -- @tfield vector3 end_pos
--- Length between start and end position --- Length between start and end position
-- @tfield number dist -- @tfield vector3 dist
--- Current drag state --- Current drag state
-- @tfield boolean is_drag -- @tfield boolean is_drag
@@ -68,6 +68,7 @@ function Slider.init(self, node, end_pos, callback)
self.pos = gui.get_position(self.node) self.pos = gui.get_position(self.node)
self.target_pos = vmath.vector3(self.pos) self.target_pos = vmath.vector3(self.pos)
self.end_pos = end_pos self.end_pos = end_pos
self._is_enabled = true
self.dist = self.end_pos - self.start_pos self.dist = self.end_pos - self.start_pos
self.is_drag = false self.is_drag = false
@@ -85,6 +86,12 @@ function Slider.on_layout_change(self)
end end
function Slider.on_remove(self)
-- Return pin to start position
gui.set_position(self.node, self.start_pos)
end
function Slider.on_window_resized(self) function Slider.on_window_resized(self)
local x_koef, y_koef = helper.get_screen_aspect_koef() local x_koef, y_koef = helper.get_screen_aspect_koef()
self._x_koef = x_koef self._x_koef = x_koef
@@ -98,6 +105,10 @@ function Slider.on_input(self, action_id, action)
return false return false
end end
if not self._is_enabled or not gui.is_enabled(self.node, true) then
return false
end
if gui.pick_node(self.node, action.x, action.y) then if gui.pick_node(self.node, action.x, action.y) then
if action.pressed then if action.pressed then
self.pos = gui.get_position(self.node) self.pos = gui.get_position(self.node)
@@ -132,14 +143,16 @@ function Slider.on_input(self, action_id, action)
if prev_x ~= self.target_pos.x or prev_y ~= self.target_pos.y then if prev_x ~= self.target_pos.x or prev_y ~= self.target_pos.y then
local prev_value = self.value local prev_value = self.value
if self.dist.x > 0 then if math.abs(self.dist.x) > 0 then
self.value = (self.target_pos.x - self.start_pos.x) / self.dist.x self.value = (self.target_pos.x - self.start_pos.x) / self.dist.x
end end
if self.dist.y > 0 then if math.abs(self.dist.y) > 0 then
self.value = (self.target_pos.y - self.start_pos.y) / self.dist.y self.value = (self.target_pos.y - self.start_pos.y) / self.dist.y
end end
self.value = math.abs(self.value)
if self.steps then if self.steps then
local closest_dist = 1000 local closest_dist = 1000
local closest = nil local closest = nil
@@ -202,7 +215,7 @@ end
-- move at this position and node drag will start. -- move at this position and node drag will start.
-- This function require the Defold version 1.3.0+ -- This function require the Defold version 1.3.0+
-- @tparam Slider self @{Slider} -- @tparam Slider self @{Slider}
-- @tparam node input_node -- @tparam node|string|nil input_node
-- @treturn Slider @{Slider} -- @treturn Slider @{Slider}
function Slider.set_input_node(self, input_node) function Slider.set_input_node(self, input_node)
self._input_node = self:get_node(input_node) self._input_node = self:get_node(input_node)
@@ -210,4 +223,20 @@ function Slider.set_input_node(self, input_node)
end end
--- Set Slider input enabled or disabled
-- @tparam Slider self @{Slider}
-- @tparam boolean is_enabled
function Slider.set_enabled(self, is_enabled)
self._is_enabled = is_enabled
end
--- Check if Slider component is enabled
-- @tparam Slider self @{Slider}
-- @treturn boolean
function Slider.is_enabled(self)
return self._is_enabled
end
return Slider return Slider

View File

@@ -74,9 +74,9 @@ end
-- You can override this component styles params in druid styles table -- You can override this component styles params in druid styles table
-- or create your own style -- or create your own style
-- @table style -- @table style
-- @tfield[opt=0.4] number SWIPE_TIME Maximum time for swipe trigger -- @tfield number|nil SWIPE_TIME Maximum time for swipe trigger. Default: 0.4
-- @tfield[opt=50] number SWIPE_THRESHOLD Minimum distance for swipe trigger -- @tfield number|nil SWIPE_THRESHOLD Minimum distance for swipe trigger. Default: 50
-- @tfield[opt=false] boolean SWIPE_TRIGGER_ON_MOVE If true, trigger on swipe moving, not only release action -- @tfield boolean|nil SWIPE_TRIGGER_ON_MOVE If true, trigger on swipe moving, not only release action. Default: false
function Swipe.on_style_change(self, style) function Swipe.on_style_change(self, style)
self.style = {} self.style = {}
self.style.SWIPE_TIME = style.SWIPE_TIME or 0.4 self.style.SWIPE_TIME = style.SWIPE_TIME or 0.4
@@ -150,7 +150,7 @@ end
--- Strict swipe click area. Useful for --- Strict swipe click area. Useful for
-- restrict events outside stencil node -- restrict events outside stencil node
-- @tparam Swipe self @{Swipe} -- @tparam Swipe self @{Swipe}
-- @tparam node zone Gui node -- @tparam node|string|nil zone Gui node
function Swipe.set_click_zone(self, zone) function Swipe.set_click_zone(self, zone)
self.click_zone = self:get_node(zone) self.click_zone = self:get_node(zone)
end end

View File

@@ -47,18 +47,19 @@ end
--- The @{Timer} constructor --- The @{Timer} constructor
-- @tparam Timer self @{Timer} -- @tparam Timer self @{Timer}
-- @tparam node node Gui text node -- @tparam node node Gui text node
-- @tparam number seconds_from Start timer value in seconds -- @tparam number|nil seconds_from Start timer value in seconds
-- @tparam number|nil seconds_to End timer value in seconds -- @tparam number|nil seconds_to End timer value in seconds
-- @tparam function|nil callback Function on timer end -- @tparam function|nil callback Function on timer end
function Timer.init(self, node, seconds_from, seconds_to, callback) function Timer.init(self, node, seconds_from, seconds_to, callback)
self.node = self: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) seconds_to = math.max(seconds_to or 0, 0)
self.on_tick = Event() self.on_tick = Event()
self.on_set_enabled = Event() self.on_set_enabled = Event()
self.on_timer_end = Event(callback) self.on_timer_end = Event(callback)
if seconds_from then
seconds_from = math.max(seconds_from, 0)
self:set_to(seconds_from) self:set_to(seconds_from)
self:set_interval(seconds_from, seconds_to) self:set_interval(seconds_from, seconds_to)
@@ -66,6 +67,7 @@ function Timer.init(self, node, seconds_from, seconds_to, callback)
self:set_state(false) self:set_state(false)
self.on_timer_end:trigger(self:get_context(), self) self.on_timer_end:trigger(self:get_context(), self)
end end
end
return self return self
end end

View File

@@ -10,12 +10,15 @@
local const = require("druid.const") local const = require("druid.const")
local M = {} local M = {}
local POSITION_X = hash("position.x")
local SCALE_X = hash("scale.x")
local SIZE_X = hash("size.x")
local function get_text_width(text_node) local function get_text_width(text_node)
if text_node then if text_node then
local text_metrics = M.get_text_metrics_from_node(text_node) local text_metrics = M.get_text_metrics_from_node(text_node)
local text_scale = gui.get_scale(text_node).x local text_scale = gui.get(text_node, SCALE_X)
return text_metrics.width * text_scale return text_metrics.width * text_scale
end end
@@ -25,8 +28,7 @@ end
local function get_icon_width(icon_node) local function get_icon_width(icon_node)
if icon_node then if icon_node then
local icon_scale_x = gui.get_scale(icon_node).x return gui.get(icon_node, SIZE_X) * gui.get(icon_node, SCALE_X) -- icon width
return gui.get_size(icon_node).x * icon_scale_x -- icon width
end end
return 0 return 0
@@ -97,13 +99,12 @@ function M.centrate_nodes(margin, ...)
for i = 1, count do for i = 1, count do
local node = select(i, ...) local node = select(i, ...)
local node_width = node_widths[i] local node_width = node_widths[i]
local pos = gui.get_position(node)
pos_x = pos_x + node_width/2 -- made offset for single item pos_x = pos_x + node_width/2 -- made offset for single item
local pivot_offset = M.get_pivot_offset(gui.get_pivot(node)) local pivot_offset = M.get_pivot_offset(gui.get_pivot(node))
pos.x = pos_x - width/2 + pivot_offset.x * node_width -- centrate node local new_pos_x = pos_x - width/2 + pivot_offset.x * node_width -- centrate node
gui.set_position(node, pos) gui.set(node, POSITION_X, new_pos_x)
pos_x = pos_x + node_widths[i]/2 + margin -- add second part of offset pos_x = pos_x + node_widths[i]/2 + margin -- add second part of offset
end end
@@ -369,6 +370,25 @@ function M.is_web()
end end
--- Check if device is HTML5 mobile
-- @function helper.is_web_mobile
-- @treturn boolean Is web mobile
function M.is_web_mobile()
if html5 then
return html5.run("(typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);") == "true"
end
return false
end
--- Check if device is mobile and can support multitouch
-- @function helper.is_multitouch_supported
-- @treturn boolean Is multitouch supported
function M.is_multitouch_supported()
return M.is_mobile() or M.is_web_mobile()
end
--- Simple table to one-line string converter --- Simple table to one-line string converter
-- @function helper.table_to_string -- @function helper.table_to_string
-- @tparam table t -- @tparam table t

View File

@@ -6,21 +6,11 @@ local settings = require("druid.system.settings")
local M = {} local M = {}
local function button_hover_scale(node, target, time)
gui.animate(node, "scale", target, gui.EASING_OUTSINE, time)
end
local function button_tap_anim(node, tap_scale, start_scale)
gui.animate(node, gui.PROP_SCALE, tap_scale, gui.EASING_INSINE, 0.1, 0, function()
gui.animate(node, gui.PROP_SCALE, start_scale, gui.EASING_INSINE, 0.1)
end)
end
M["button"] = { M["button"] = {
HOVER_SCALE = vmath.vector3(0.02, 0.02, 1), HOVER_SCALE = vmath.vector3(0.08, 0.08, 1),
HOVER_MOUSE_SCALE = vmath.vector3(0.01, 0.01, 1), HOVER_MOUSE_SCALE = vmath.vector3(0.04, 0.04, 1),
HOVER_TIME = 0.04, HOVER_TIME = 0.05,
SCALE_CHANGE = vmath.vector3(0.035, 0.035, 1), SCALE_CHANGE = vmath.vector3(0.12, 0.12, 1),
BTN_SOUND = "click", BTN_SOUND = "click",
BTN_SOUND_DISABLED = "click", BTN_SOUND_DISABLED = "click",
DISABLED_COLOR = vmath.vector4(0, 0, 0, 1), DISABLED_COLOR = vmath.vector4(0, 0, 0, 1),
@@ -33,35 +23,44 @@ M["button"] = {
local scale_to = self.start_scale + M.button.HOVER_SCALE local scale_to = self.start_scale + M.button.HOVER_SCALE
local target_scale = state and scale_to or self.start_scale local target_scale = state and scale_to or self.start_scale
button_hover_scale(node, target_scale, M.button.HOVER_TIME) gui.animate(node, "scale", target_scale, gui.EASING_OUTSINE, M.button.HOVER_TIME)
end, end,
on_mouse_hover = function(self, node, state) on_mouse_hover = function(self, node, state)
local scale_to = self.start_scale + M.button.HOVER_MOUSE_SCALE local scale_to = self.start_scale + M.button.HOVER_MOUSE_SCALE
local target_scale = state and scale_to or self.start_scale local target_scale = state and scale_to or self.start_scale
button_hover_scale(node, target_scale, M.button.HOVER_TIME) gui.animate(node, "scale", target_scale, gui.EASING_OUTSINE, M.button.HOVER_TIME)
end, end,
on_click = function(self, node) on_click = function(self, node)
local scale_to = self.start_scale + M.button.SCALE_CHANGE local scale_to = self.start_scale + M.button.SCALE_CHANGE
button_tap_anim(node, scale_to, self.start_scale) gui.set_scale(node, scale_to)
local is_hover = self.hover:is_mouse_hovered()
local target_scale = is_hover and self.start_scale + M.button.HOVER_MOUSE_SCALE or self.start_scale
gui.animate(node, gui.PROP_SCALE, target_scale, gui.EASING_OUTBACK, 0.24)
settings.play_sound(M.button.BTN_SOUND) settings.play_sound(M.button.BTN_SOUND)
end, end,
on_click_disabled = function(self, node) on_click_disabled = function(self, node)
settings.play_sound(M.button.BTN_SOUND_DISABLED) local start_pos = self.start_pos
gui.animate(node, "position.x", start_pos.x - 3, gui.EASING_OUTSINE, 0.05, 0, function()
gui.animate(node, "position.x", start_pos.x + 3, gui.EASING_OUTSINE, 0.1, 0, function()
gui.animate(node, "position.x", start_pos.x, gui.EASING_OUTSINE, 0.05)
end)
end)
end, end,
on_set_enabled = function(self, node, state) on_set_enabled = function(self, node, state)
if state then
gui.set_color(node, M.button.ENABLED_COLOR)
else
gui.set_color(node, M.button.DISABLED_COLOR)
end
end end
} }
M["hover"] = {
ON_HOVER_CURSOR = nil,
ON_MOUSE_HOVER_CURSOR = nil,
}
M["drag"] = { M["drag"] = {
DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone
@@ -84,8 +83,8 @@ M["scroll"] = {
INERT_SPEED = 30, -- koef. of inert speed INERT_SPEED = 30, -- koef. of inert speed
EXTRA_STRETCH_SIZE = 100, -- extra size in pixels outside of scroll (stretch effect) EXTRA_STRETCH_SIZE = 100, -- extra size in pixels outside of scroll (stretch effect)
POINTS_DEADZONE = 20, -- Speed to check points of interests in no_inertion mode POINTS_DEADZONE = 20, -- Speed to check points of interests in no_inertion mode
WHEEL_SCROLL_SPEED = 0, -- Amount of pixels to scroll by one wheel event (0 to disable) WHEEL_SCROLL_SPEED = 20, -- Amount of pixels to scroll by one wheel event (0 to disable)
WHEEL_SCROLL_INVERTED = false, -- Boolean to invert wheel scroll side WHEEL_SCROLL_INVERTED = true, -- Boolean to invert wheel scroll side
WHEEL_SCROLL_BY_INERTION = false, -- If true, wheel will add inertion to scroll. Direct set position otherwise. WHEEL_SCROLL_BY_INERTION = false, -- If true, wheel will add inertion to scroll. Direct set position otherwise.
SMALL_CONTENT_SCROLL = false, -- If true, content node with size less than view node size can be scrolled SMALL_CONTENT_SCROLL = false, -- If true, content node with size less than view node size can be scrolled
} }
@@ -119,11 +118,10 @@ M["swipe"] = {
M["input"] = { M["input"] = {
IS_LONGTAP_ERASE = true, IS_LONGTAP_ERASE = false,
BUTTON_SELECT_INCREASE = 1.06, BUTTON_SELECT_INCREASE = 1.08,
MASK_DEFAULT_CHAR = "*", MASK_DEFAULT_CHAR = "*",
IS_UNSELECT_ON_RESELECT = false, IS_UNSELECT_ON_RESELECT = false,
NO_CONSUME_INPUT_WHILE_SELECTED = false,
on_select = function(self, button_node) on_select = function(self, button_node)
local target_scale = self.button.start_scale local target_scale = self.button.start_scale
@@ -143,12 +141,6 @@ M["input"] = {
end) end)
end) end)
end, end,
button = {
LONGTAP_TIME = 0.4,
AUTOHOLD_TRIGGER = 0.8,
DOUBLETAP_TIME = 0.4,
}
} }

View File

@@ -1,26 +0,0 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
local M = {}
M["button"] = {
LONGTAP_TIME = 0.4,
DOUBLETAP_TIME = 0.4,
HOVER_MOUSE_IMAGE = "button_yellow",
DEFAULT_IMAGE = "button_blue",
HOVER_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,
on_mouse_hover = function(self, node, state)
local anim = state and M.button.HOVER_MOUSE_IMAGE or M.button.DEFAULT_IMAGE
gui.play_flipbook(node, anim)
end
}
return M

View File

@@ -68,7 +68,6 @@
-- @see Timer -- @see Timer
local helper = require("druid.helper") local helper = require("druid.helper")
local class = require("druid.system.middleclass")
local settings = require("druid.system.settings") local settings = require("druid.system.settings")
local base_component = require("druid.component") local base_component = require("druid.component")
@@ -94,7 +93,7 @@ local back_handler = require("druid.base.back_handler")
-- local dynamic_grid = require("druid.extended.dynamic_grid") -- local dynamic_grid = require("druid.extended.dynamic_grid")
-- local checkbox_group = require("druid.extended.checkbox_group") -- local checkbox_group = require("druid.extended.checkbox_group")
local DruidInstance = class("druid.druid_instance") local DruidInstance = {}
local MSG_ADD_FOCUS = hash("acquire_input_focus") local MSG_ADD_FOCUS = hash("acquire_input_focus")
local MSG_REMOVE_FOCUS = hash("release_input_focus") local MSG_REMOVE_FOCUS = hash("release_input_focus")
@@ -193,10 +192,6 @@ end
local function process_input(self, action_id, action, components) local function process_input(self, action_id, action, components)
local is_input_consumed = false local is_input_consumed = false
if #components == 0 then
return false
end
for i = #components, 1, -1 do for i = #components, 1, -1 do
local component = components[i] local component = components[i]
local meta = component._meta local meta = component._meta
@@ -252,7 +247,7 @@ function DruidInstance.initialize(self, context, style)
end end
--- Create new component. -- Create new component.
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam BaseComponent component Component module -- @tparam BaseComponent component Component module
-- @tparam any ... Other component params to pass it to component:init function -- @tparam any ... Other component params to pass it to component:init function
@@ -293,23 +288,27 @@ end
-- Component `on_remove` function will be invoked, if exist. -- Component `on_remove` function will be invoked, if exist.
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam BaseComponent component Component instance -- @tparam BaseComponent component Component instance
-- @treturn boolean True if component was removed
function DruidInstance.remove(self, component) function DruidInstance.remove(self, component)
if self._is_late_remove_enabled then if self._is_late_remove_enabled then
table.insert(self._late_remove, component) table.insert(self._late_remove, component)
return return false
end end
-- Recursive remove all children of component -- Recursive remove all children of component
local children = component._meta.children local children = component._meta.children
for i = #children, 1, -1 do for i = #children, 1, -1 do
self:remove(children[i]) self:remove(children[i])
local parent = children[i]:get_parent_component()
if parent then
parent:__remove_children(children[i])
end
children[i] = nil children[i] = nil
end end
local parent = component:get_parent_component()
if parent then
parent:__remove_child(component)
end
local is_removed = false
local all_components = self.components_all local all_components = self.components_all
for i = #all_components, 1, -1 do for i = #all_components, 1, -1 do
if all_components[i] == component then if all_components[i] == component then
@@ -317,6 +316,7 @@ function DruidInstance.remove(self, component)
component:on_remove() component:on_remove()
end end
table.remove(all_components, i) table.remove(all_components, i)
is_removed = true
end end
end end
@@ -330,6 +330,8 @@ function DruidInstance.remove(self, component)
end end
end end
end end
return is_removed
end end
@@ -473,10 +475,10 @@ end
-- If whitelist is not empty and component not contains in this list, -- If whitelist is not empty and component not contains in this list,
-- component will be not processed on input step -- component will be not processed on input step
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam[opt=nil] table|BaseComponent whitelist_components The array of component to whitelist -- @tparam table|BaseComponent|nil whitelist_components The array of component to whitelist
-- @treturn self @{DruidInstance} -- @treturn self @{DruidInstance}
function DruidInstance.set_whitelist(self, whitelist_components) function DruidInstance.set_whitelist(self, whitelist_components)
if whitelist_components and whitelist_components.isInstanceOf then if whitelist_components and whitelist_components._component then
whitelist_components = { whitelist_components } whitelist_components = { whitelist_components }
end end
@@ -495,10 +497,10 @@ end
-- If blacklist is not empty and component contains in this list, -- If blacklist is not empty and component contains in this list,
-- component will be not processed on input step -- component will be not processed on input step
-- @tparam DruidInstance self @{DruidInstance} -- @tparam DruidInstance self @{DruidInstance}
-- @tparam[opt=nil] table|BaseComponent blacklist_components The array of component to blacklist -- @tparam table|BaseComponent|nil blacklist_components The array of component to blacklist
-- @treturn self @{DruidInstance} -- @treturn self @{DruidInstance}
function DruidInstance.set_blacklist(self, blacklist_components) function DruidInstance.set_blacklist(self, blacklist_components)
if blacklist_components and blacklist_components.isInstanceOf then if blacklist_components and blacklist_components._component then
blacklist_components = { blacklist_components } blacklist_components = { blacklist_components }
end end
@@ -556,8 +558,8 @@ end
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam string|node node The node_id or gui.get_node(node_id) -- @tparam string|node node The node_id or gui.get_node(node_id)
-- @tparam function|nil callback Button callback -- @tparam function|nil callback Button callback
-- @tparam table|nil params Button callback params -- @tparam any|nil params Button callback params
-- @tparam node|nil anim_node Button anim node (node, if not provided) -- @tparam node|string|nil anim_node Button anim node (node, if not provided)
-- @treturn Button @{Button} component -- @treturn Button @{Button} component
function DruidInstance.new_button(self, node, callback, params, anim_node) function DruidInstance.new_button(self, node, callback, params, anim_node)
return DruidInstance.new(self, button, node, callback, params, anim_node) return DruidInstance.new(self, button, node, callback, params, anim_node)
@@ -587,9 +589,10 @@ end
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam string|node node The node_id or gui.get_node(node_id) -- @tparam string|node node The node_id or gui.get_node(node_id)
-- @tparam function|nil on_hover_callback Hover callback -- @tparam function|nil on_hover_callback Hover callback
-- @tparam function|nil on_mouse_hover_callback Mouse hover callback
-- @treturn Hover @{Hover} component -- @treturn Hover @{Hover} component
function DruidInstance.new_hover(self, node, on_hover_callback) function DruidInstance.new_hover(self, node, on_hover_callback, on_mouse_hover_callback)
return DruidInstance.new(self, hover, node, on_hover_callback) return DruidInstance.new(self, hover, node, on_hover_callback, on_mouse_hover_callback)
end end
@@ -705,7 +708,7 @@ end
--- Create @{Input} component --- Create @{Input} component
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam string|node click_node Button node to enabled input component -- @tparam string|node click_node Button node to enabled input component
-- @tparam string|node text_node Text node what will be changed on user input -- @tparam string|node|druid.text text_node Text node what will be changed on user input
-- @tparam number|nil keyboard_type Gui keyboard type for input field -- @tparam number|nil keyboard_type Gui keyboard type for input field
-- @treturn Input @{Input} component -- @treturn Input @{Input} component
function DruidInstance.new_input(self, click_node, text_node, keyboard_type) function DruidInstance.new_input(self, click_node, text_node, keyboard_type)
@@ -715,9 +718,9 @@ end
--- Create @{CheckboxGroup} component --- Create @{CheckboxGroup} component
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam node[] nodes Array of gui node -- @tparam (node|string)[] nodes Array of gui node
-- @tparam function callback Checkbox callback -- @tparam function callback Checkbox callback
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes -- @tparam (node|string)[]|nil click_nodes Array of trigger nodes, by default equals to nodes
-- @treturn CheckboxGroup @{CheckboxGroup} component -- @treturn CheckboxGroup @{CheckboxGroup} component
function DruidInstance.new_checkbox_group(self, nodes, callback, click_nodes) function DruidInstance.new_checkbox_group(self, nodes, callback, click_nodes)
return helper.require_component_message("checkbox_group") return helper.require_component_message("checkbox_group")
@@ -727,7 +730,7 @@ end
--- Create @{DataList} component --- Create @{DataList} component
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam Scroll druid_scroll The Scroll instance for Data List component -- @tparam Scroll druid_scroll The Scroll instance for Data List component
-- @tparam StaticGrid|DynamicGrid druid_grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component -- @tparam StaticGrid druid_grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component
-- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component]) -- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component])
-- @treturn DataList @{DataList} component -- @treturn DataList @{DataList} component
function DruidInstance.new_data_list(self, druid_scroll, druid_grid, create_function) function DruidInstance.new_data_list(self, druid_scroll, druid_grid, create_function)
@@ -737,9 +740,9 @@ end
--- Create @{RadioGroup} component --- Create @{RadioGroup} component
-- @tparam DruidInstance self -- @tparam DruidInstance self
-- @tparam node[] nodes Array of gui node -- @tparam (node|string)[] nodes Array of gui node
-- @tparam function callback Radio callback -- @tparam function callback Radio callback
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes -- @tparam (node|string)[]|nil click_nodes Array of trigger nodes, by default equals to nodes
-- @treturn RadioGroup @{RadioGroup} component -- @treturn RadioGroup @{RadioGroup} component
function DruidInstance.new_radio_group(self, nodes, callback, click_nodes) function DruidInstance.new_radio_group(self, nodes, callback, click_nodes)
return helper.require_component_message("radio_group") return helper.require_component_message("radio_group")

View File

@@ -1,156 +0,0 @@
-- Source: https://github.com/kikito/middleclass
local middleclass = {}
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:instantiate(...) 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,
instantiate = function(self, ...)
assert(type(self) == 'table', "Make sure that you are using 'Class:instantiate' instead of 'Class.instantiate'")
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

View File

@@ -688,7 +688,8 @@ local function matcherGenerator(regex, plain)
local sum = 0 local sum = 0
local bc, ec = utf8sub(str, 1, 1), utf8sub(str, 2, 2) local bc, ec = utf8sub(str, 1, 1), utf8sub(str, 2, 2)
local skip = len(bc) + len(ec) local skip = len(bc) + len(ec)
bc, ec = utf8unicode(bc), utf8unicode(ec) bc = utf8unicode(bc) --[[@as string]]
ec = utf8unicode(ec) --[[@as string]]
return function(cC) return function(cC)
if cC == ec and sum > 0 then if cC == ec and sum > 0 then
sum = sum - 1 sum = sum - 1

View File

@@ -3,20 +3,13 @@ local component = require("druid.component")
---@class component_name : druid.base_component ---@class component_name : druid.base_component
local Component = component.create("component_name") local Component = component.create("component_name")
local SCHEME = {
ROOT = "root",
BUTTON = "button",
}
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component -- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
function Component:init(template, nodes) function Component:init(template, nodes)
self:set_template(template) self.druid = self:get_druid(template, nodes)
self:set_nodes(nodes) self.root = self:get_node("root")
self.root = self:get_node(SCHEME.ROOT)
self.druid = self:get_druid()
self.button = self.druid:new_button(SCHEME.BUTTON, function() end) self.button = self.druid:new_button("button", function() end)
end end

View File

@@ -3,26 +3,16 @@ local component = require("druid.component")
---@class component_name : druid.base_component ---@class component_name : druid.base_component
local Component = component.create("component_name") local Component = component.create("component_name")
-- Scheme of component gui nodes
local SCHEME = {
ROOT = "root",
BUTTON = "button",
}
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component -- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
function Component:init(template, nodes) function Component:init(template, nodes)
-- If your component is gui template, pass the template name and set it -- If your component is gui template, pass the template name and set it
self:set_template(template)
-- If your component is cloned my gui.clone_tree, pass nodes to component and set it -- If your component is cloned my gui.clone_tree, pass nodes to component and set it
self:set_nodes(nodes) -- Use inner druid instance to create components inside this component
self.druid = self:get_druid(template, nodes)
-- self:get_node will auto process component template and nodes -- self:get_node will auto process component template and nodes
self.root = self:get_node(SCHEME.ROOT) self.root = self:get_node("root")
-- Use inner druid instance to create components inside this component
self.druid = self:get_druid()
end end

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +0,0 @@
name: "pin_knob"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"rich_input\"\n"
" component: \"/example/examples/custom/pin_knob/pin_knob.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
}
}

View File

@@ -1,677 +0,0 @@
script: "/example/examples/custom/pin_knob/pin_knob.gui_script"
fonts {
name: "game"
font: "/example/assets/fonts/game.font"
}
textures {
name: "kenney"
texture: "/example/assets/images/kenney.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 300.0
y: 415.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: 830.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_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_MANUAL
}
nodes {
position {
x: 0.0
y: 370.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 700.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: "Rich Input custom component"
font: "game"
id: "text_hint_horizontal"
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: "root"
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: -100.0
y: 230.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: "pin_knob1"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/druid/custom/pin_knob/pin_knob.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: 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: "pin_knob1/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin_knob1"
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: 2.0
y: 2.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/slider_move"
id: "pin_knob1/pin"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin_knob1/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: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 0.0
y: 13.5
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.2
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 17.0
y: 17.0
z: 0.0
w: 1.0
}
color {
x: 0.101960786
y: 0.101960786
z: 0.101960786
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "kenney/tick"
id: "pin_knob1/notch"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin_knob1/pin"
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: -100.0
y: 154.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 120.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_value1"
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: "root"
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: 100.0
y: 230.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: "pin_knob2"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/druid/custom/pin_knob/pin_knob.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: 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: "pin_knob2/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin_knob2"
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: 2.0
y: 2.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/slider_move"
id: "pin_knob2/pin"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin_knob2/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: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 0.0
y: 13.5
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.2
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 17.0
y: 17.0
z: 0.0
w: 1.0
}
color {
x: 0.101960786
y: 0.101960786
z: 0.101960786
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "kenney/tick"
id: "pin_knob2/notch"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "pin_knob2/pin"
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: 100.0
y: 154.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 120.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_value2"
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: "root"
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
}
layers {
name: "image"
}
layers {
name: "text"
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -1,49 +0,0 @@
local druid = require("druid.druid")
local pin_knob = require("druid.custom.pin_knob.pin_knob")
local function on_pin_change1(self, value)
self.text1:set_to(math.ceil(value))
end
local function on_pin_change2(self, value)
self.text2:set_to(math.ceil(value))
end
function init(self)
self.druid = druid.new(self)
self.text1 = self.druid:new_text("text_value1", 0)
---@type druid.pin_knob
self.pin_knob = self.druid:new(pin_knob, on_pin_change1, "pin_knob1")
self.pin_knob:set_angle(-10, -270, 270)
self.text2 = self.druid:new_text("text_value2", 0)
---@type druid.pin_knob
self.pin_knob2 = self.druid:new(pin_knob, on_pin_change2, "pin_knob2")
self.pin_knob2:set_angle(0, -90, 90)
self.pin_knob2:set_friction(0.15)
end
function final(self)
self.druid:final()
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)
return self.druid:on_input(action_id, action)
end

File diff suppressed because it is too large Load Diff

View File

@@ -14,24 +14,15 @@ local component = require("druid.component")
---@field druid druid_instance ---@field druid druid_instance
local ButtonComponent = component.create("button_component") local ButtonComponent = component.create("button_component")
local SCHEME = {
ROOT = "root",
TEXT = "text",
ICON = "icon",
CHECKBOX = "checkbox"
}
---@param template string ---@param template string
---@param nodes table<hash, node> ---@param nodes table<hash, node>
function ButtonComponent:init(template, nodes) function ButtonComponent:init(template, nodes)
self:set_template(template) self.druid = self:get_druid(template, nodes)
self:set_nodes(nodes)
self.druid = self:get_druid()
self.root = self:get_node(SCHEME.ROOT) self.root = self:get_node("root")
self.text = self.druid:new_text(SCHEME.TEXT) self.text = self.druid:new_text("text")
self.checkbox = self:get_node(SCHEME.CHECKBOX) self.checkbox = self:get_node("checkbox")
self.button = self.druid:new_button(self.root, self._on_click) self.button = self.druid:new_button(self.root, self._on_click)

View File

@@ -1,5 +1,4 @@
local druid = require("druid.druid") local druid = require("druid.druid")
local sprite_style = require("druid.styles.sprites.style")
local function usual_callback() local function usual_callback()
@@ -52,9 +51,6 @@ end
local function setup_buttons(self) local function setup_buttons(self)
self.druid:new_button("button_usual/button", usual_callback) 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_style)
local long_button = self.druid:new_button("button_long_tap/button", usual_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_hold_callback:subscribe(hold_callback)
long_button.on_long_click:subscribe(long_tap_callback) long_button.on_long_click:subscribe(long_tap_callback)

View File

@@ -54,9 +54,10 @@ function init(self)
self.druid:new_scroll("children_scroll_3", "children_scroll_content_3") self.druid:new_scroll("children_scroll_3", "children_scroll_content_3")
-- Content with less size than view -- Content with less size than view
self.druid:new_scroll("scroll_smaller_view", "scroll_smaller_content") local small_scroll = self.druid:new_scroll("scroll_smaller_view", "scroll_smaller_content") --[[@as druid.scroll]]
:set_extra_stretch_size(0) small_scroll.style.SMALL_CONTENT_SCROLL = true
:set_inert(false) small_scroll:set_extra_stretch_size(0) -- it also update scroll size due the change of SMALL_CONTENT_SCROLL
small_scroll:set_inert(false)
-- Scroll with points of interests -- Scroll with points of interests
self.druid:new_scroll("scroll_with_points", "scroll_with_points_content") self.druid:new_scroll("scroll_with_points", "scroll_with_points_content")

View File

@@ -1,4 +1,3 @@
script: ""
fonts { fonts {
name: "game" name: "game"
font: "/example/assets/fonts/game.font" font: "/example/assets/fonts/game.font"
@@ -7,423 +6,67 @@ textures {
name: "kenney" name: "kenney"
texture: "/example/assets/images/kenney.atlas" texture: "/example/assets/images/kenney.atlas"
} }
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes { 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 { size {
x: 600.0 x: 600.0
y: 200.0 y: 200.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
} }
type: TYPE_BOX type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "kenney/empty" texture: "kenney/empty"
id: "root" id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true 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
custom_type: 0
enabled: true
visible: false visible: false
} }
nodes { 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 { scale {
x: 0.8 x: 0.8
y: 0.8 y: 0.8
z: 1.0
w: 1.0
} }
size { size {
x: 750.0 x: 750.0
y: 100.0 y: 100.0
z: 0.0
w: 1.0
} }
color { color {
x: 1.0
y: 1.0
z: 0.9411765 z: 0.9411765
w: 1.0
} }
type: TYPE_TEXT type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Here is simple example with text" text: "Here is simple example with text"
font: "game" font: "game"
id: "hint" id: "hint"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N pivot: PIVOT_N
outline { outline {
x: 0.101960786 x: 0.101960786
y: 0.101960786 y: 0.101960786
z: 0.101960786 z: 0.101960786
w: 1.0
} }
shadow { shadow {
x: 1.0 x: 1.0
y: 1.0 y: 1.0
z: 1.0 z: 1.0
w: 1.0
} }
adjust_mode: ADJUST_MODE_FIT
line_break: true line_break: true
parent: "root" parent: "root"
layer: ""
inherit_alpha: true inherit_alpha: true
alpha: 1.0
outline_alpha: 0.7 outline_alpha: 0.7
shadow_alpha: 0.0 shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
} }
nodes { nodes {
position { position {
x: 0.0
y: -60.0 y: -60.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 { size {
x: 600.0 x: 600.0
y: 130.0 y: 130.0
z: 0.0
w: 1.0
} }
color { color {
x: 1.0
y: 1.0
z: 0.9411765 z: 0.9411765
w: 1.0
} }
type: TYPE_BOX type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "area" id: "area"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "root" parent: "root"
layer: ""
inherit_alpha: true 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
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: -65.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: "rich_text"
parent: "area"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/druid/custom/rich_text/rich_text.gui"
template_node_child: false
custom_type: 0
enabled: true
}
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: 500.0
y: 130.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: "rich_text/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_text"
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
overridden_fields: 4
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: 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: 300.0
y: 60.0
z: 0.0
w: 1.0
}
color {
x: 0.2
y: 0.2
z: 0.2
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Rich text"
font: "game"
id: "rich_text/text_prefab"
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: true
parent: "rich_text/root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 1
overridden_fields: 4
overridden_fields: 5
overridden_fields: 14
overridden_fields: 18
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
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_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "items/checkmark"
id: "rich_text/icon_prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_text/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: true
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
} }
material: "/builtins/materials/gui.material" material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +1,76 @@
platforms: platforms:
armv7-ios: armv7-ios:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
arm64-ios: arm64-ios:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
x86_64-ios: x86_64-ios:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
armv7-android: armv7-android:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeJars: [] excludeJars: []
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
arm64-android: arm64-android:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeJars: [] excludeJars: []
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
arm64-osx:
context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx, liveupdate]
excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, liveupdate_null]
x86_64-osx: x86_64-osx:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
x86_64-linux: x86_64-linux:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
x86-win32: x86-win32:
context: context:
excludeLibs: [libphysics, libLinearMath, libBulletDynamics, libBulletCollision, libBox2D, librecord, vpx, libprofilerext, libliveupdate] excludeLibs: [libliveupdate, libphysics, libLinearMath, libBulletDynamics, libBulletCollision, libBox2D, libscript_box2d, librecord, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [libphysics_null.lib, librecord_null.lib, libprofilerext_null.lib, libliveupdate_null.lib] libs: [libphysics_null.lib, libliveupdate_null.lib, librecord_null.lib]
linkFlags: [] linkFlags: []
x86_64-win32: x86_64-win32:
context: context:
excludeLibs: [libphysics, libLinearMath, libBulletDynamics, libBulletCollision, libBox2D, librecord, vpx, libprofilerext, libliveupdate] excludeLibs: [libliveupdate, libphysics, libLinearMath, libBulletDynamics, libBulletCollision, libBox2D, libscript_box2d, librecord, vpx]
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [libphysics_null.lib, librecord_null.lib, libprofilerext_null.lib, libliveupdate_null.lib] libs: [libphysics_null.lib, libliveupdate_null.lib, librecord_null.lib]
linkFlags: [] linkFlags: []
js-web: js-web:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeJsLibs: [] excludeJsLibs: []
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []
wasm-web: wasm-web:
context: context:
excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, Box2D, record, vpx, profilerext, liveupdate] excludeLibs: [liveupdate, physics, LinearMath, BulletDynamics, BulletCollision, Box2D, script_box2d, record, vpx]
excludeJsLibs: [] excludeJsLibs: []
excludeSymbols: [ProfilerExt] excludeSymbols: [ScriptBox2DExt]
libs: [physics_null, record_null, profilerext_null, liveupdate_null] libs: [physics_null, liveupdate_null, record_null]
linkFlags: [] linkFlags: []

View File

@@ -1,5 +1,5 @@
[bootstrap] [bootstrap]
main_collection = /example/example.collectionc main_collection = /test/test.collectionc
[script] [script]
shared_state = 1 shared_state = 1
@@ -15,7 +15,7 @@ high_dpi = 1
title = druid title = druid
version = 0.11.0 version = 0.11.0
publisher = Insality publisher = Insality
developer = Insality developer = Maksim Tuprikov
dependencies#0 = https://github.com/insalitygames/deftest/archive/master.zip dependencies#0 = https://github.com/insalitygames/deftest/archive/master.zip
dependencies#1 = https://github.com/britzl/monarch/archive/refs/tags/3.3.0.zip dependencies#1 = https://github.com/britzl/monarch/archive/refs/tags/3.3.0.zip

BIN
media/druid_hero.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 492 KiB

BIN
media/druid_thumb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@@ -1,17 +1,17 @@
#!/bin/bash # Path to bob folder. It will find and save new bob.jar files inside
bob_folder=./
# If true, it will check and download latest bob version. It will ignore bob_sha param
use_latest_bob=false
# Set patch (last value after dot) game version value as total git commits count (1.2.0 -> 1.2.{commits_count})
# You allow to get SHA commit from version via: git rev-list --all --reverse | sed -n {N}p
enable_incremental_version=true
# You can point bob version for project in format "filename:sha" # You can point bob version for project in format "filename:sha"
bob_sha="1.6.0:d9e9c49ab946c058f29a8b688c862d70f30e9c43" bob_sha="181:fd1ad4c17bfdcd890ea7176f2672c35102384419"
# Select Defold channel. Values: stable, beta, alpha # Select Defold channel. Values: stable, beta, alpha
bob_channel="stable" bob_channel="stable"
# If true, it will check and download latest bob version. It will ignore bob_sha param
use_latest_bob=false
# Select Defold build server
build_server="https://build.defold.com"
# Is need to build html report # Is need to build html report
is_build_html_report=true is_build_html_report=true

Some files were not shown because too many files have changed in this diff Show More