Merge pull request #231 from Insality/docs

Update documentation
This commit is contained in:
Maksim Tuprikov 2023-07-13 21:35:20 +03:00 committed by GitHub
commit 1cbe573763
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 838 additions and 460 deletions

222
README.md
View File

@ -7,18 +7,15 @@
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/insality/druid/ci-workflow.yml?branch=master)](https://github.com/Insality/druid/actions) [![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) [![codecov](https://codecov.io/gh/Insality/druid/branch/master/graph/badge.svg)](https://codecov.io/gh/Insality/druid)
**Druid** - powerful Defold component UI library. Use basic and extended **Druid** components or make your own game-specific components to make amazing GUI in your games. **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.
## Overview
Try the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Druid** example app.
## Setup ## Setup
### Dependency ### Dependency
You can use the **Druid** extension in your own project by adding this project as a [Defold library dependency](https://www.defold.com/manuals/libraries/). Open your `game.project` file and in the dependencies field under project add: 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.10.3** **Druid v0.10.3**
> [https://github.com/Insality/druid/archive/refs/tags/0.10.3.zip](https://github.com/Insality/druid/archive/refs/tags/0.10.3.zip) > [https://github.com/Insality/druid/archive/refs/tags/0.10.3.zip](https://github.com/Insality/druid/archive/refs/tags/0.10.3.zip)
@ -26,89 +23,52 @@ You can use the **Druid** extension in your own project by adding this project a
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).
### Input Bindings ### Input Bindings
Druid uses `/builtins/input/all.input_binding` input bindins. For advanced setup see the Input Binding section in Advanced Setup. **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)_**.
### Advanced Setup
If you need to customize **Druid** according to your specific requirements, you can refer to the **_[Advanced Setup](docs_md/advanced-setup.md)_** section.
## Usage ## Usage
Here only basic usage. ### Basic usage
How to read this doc.
Annotations.
Example of advanced usage - different doc.
Example of custom components - different doc.
## Components To utilize **Druid**, begin by creating a **Druid** instance to instantiate components and include the main functions of **Druid**: *update*, *final*, *on_message*, and *on_input*.
Here is full **Druid** components list: When using **Druid** components, provide a node name string as an argument. If you don't have the node name available in some cases, you can pass `gui.get_node()` instead.
### Basic Components All **Druid** and component methods are invoked using the `:` operator, such as `self.druid:new_button()`.
| Name | Description | Example | <div style="width:200px">Preview</div> |
|------|-------------|---------|---------|
| **[Button](https://insality.github.io/druid/modules/Button.html)** | Basic input component. Handles all types of interactions: click, long click, hold click, double click, etc | [Button Example](https://insality.github.io/druid/druid/?example=general_buttons) | <img src="media/preview/button.gif" width="200" height="100"> |
| **[Text](https://insality.github.io/druid/modules/Text.html)** | Wrap on GUI text node, handle different text size adjusting, providing additional text API | [Text Example](https://insality.github.io/druid/druid/?example=texts_general) | <img src="media/preview/text.gif" width="200" height="100"> |
| **[Scroll](https://insality.github.io/druid/modules/Scroll.html)** | Scroll component | [Scroll Example](https://insality.github.io/druid/druid/?example=general_scroll) | <img src="media/preview/scroll.gif" width="200" height="100"> |
| **[Blocker](https://insality.github.io/druid/modules/Blocker.html)** | Block user input in node zone area | ❌ | |
| **[Back Handler](https://insality.github.io/druid/modules/BackHandler.html)** | Handle back button (Android back button, backspace key) | ❌ | |
| **[Static Grid](https://insality.github.io/druid/modules/StaticGrid.html)** | Component to manage node positions with equal sizes | [Static Gid Example](https://insality.github.io/druid/druid/?example=general_grid) | <img src="media/preview/static_grid.gif" width="200" height="100"> |
| **[Hover](https://insality.github.io/druid/modules/Hover.html)** | Handle hover node state on node | ❌ | <img src="media/preview/hover.gif" width="200" height="100"> |
| **[Swipe](https://insality.github.io/druid/modules/Swipe.html)** | Handle swipe gestures on node | [Swipe Example](https://insality.github.io/druid/druid/?example=general_swipe) | <img src="media/preview/swipe.gif" width="200" height="100"> |
| **[Drag](https://insality.github.io/druid/modules/Drag.html)** | Handle drag input on node | [Drag Example](https://insality.github.io/druid/druid/?example=general_drag) | <img src="media/preview/drag.gif" width="200" height="100"> |
### Extended components
> Extended components before usage should be registered in **Druid** with `druid.register()` function.
| Name | Description | Example | <div style="width:200px">Preview</div> |
|------|-------------|---------|---------|
| **[Checkbox](https://insality.github.io/druid/modules/Checkbox.html)** | Checkbox component | [Checkbox Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | <img src="media/preview/checkbox.gif" width="200" height="100"> |
| **[Checkbox group](https://insality.github.io/druid/modules/CheckboxGroup.html)** | Several checkboxes in one group | [Checkbox group Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | <img src="media/preview/checkbox_group.gif" width="200" height="100"> |
| **[Radio group](https://insality.github.io/druid/modules/RadioGroup.html)** | Several checkboxes in one group with a single choice | [Radio Group Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | <img src="media/preview/radio_group.gif" width="200" height="100"> |
| **[Dynamic Grid](https://insality.github.io/druid/modules/DynamicGrid.html)** | Component to manage node positions with different sizes. Only in one row or column | [Dynamic Grid Example](https://insality.github.io/druid/druid/?example=general_grid) | <img src="media/preview/dynamic_grid.gif" width="200" height="100"> |
| **[Data List](https://insality.github.io/druid/modules/DataList.html)** | Component to manage data for huge datasets in scroll | [Data List Example](https://insality.github.io/druid/druid/?example=general_data_list) | <img src="media/preview/data_list.gif" width="200" height="100"> |
| **[Input](https://insality.github.io/druid/modules/Input.html)** | User text input component | [Input Example](https://insality.github.io/druid/druid/?example=general_input) | <img src="media/preview/input.gif" width="200" height="100"> |
| **[Lang text](https://insality.github.io/druid/modules/LangText.html)** | Wrap on Text component to handle localization | ❌ | <img src="media/preview/lang_text.gif" width="200" height="100"> |
| **[Progress](https://insality.github.io/druid/modules/Progress.html)** | Progress bar component | [Progress Example](https://insality.github.io/druid/druid/?example=general_progress_bar) | <img src="media/preview/progress.gif" width="200" height="100"> |
| **[Slider](https://insality.github.io/druid/modules/Slider.html)** | Slider component | [Slider Example]() | <img src="media/preview/slider.gif" width="200" height="100"> |
| **[Timer](https://insality.github.io/druid/modules/Timer.html)** | Handle timers on GUI text node | ❌ | <img src="media/preview/timer.gif" width="200" height="100"> |
| **[Hotkey](https://insality.github.io/druid/modules/Hotkey.html)** | Handle keyboard hotkeys with key modificators | [Hotkey Example](https://insality.github.io/druid/druid/?example=general_hokey) | <img src="media/preview/hotkey.gif" width="200" height="100"> |
| **[Layout](https://insality.github.io/druid/modules/Layout.html)** | Handle node size depends on layout mode and screen aspect ratio | [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)_**.
## Basic usage
To use **Druid**, first you should create a Druid instance to spawn components and add Druids main engine functions: *update*, *final*, *on_message* and *on_input*.
All **Druid** components take node name string as arguments, don't do `gui.get_node()` before.
All **Druid** and component methods are called with `:` like `self.druid:new_button()`.
```lua ```lua
local druid = require("druid.druid") local druid = require("druid.druid")
local function button_callback(self) -- All component callbacks pass "self" as first argument
print("Button was clicked!") -- This "self" is a context data passed in `druid.new(context)`
local function on_button_callback(self)
print("The button clicked!")
end end
function init(self) function init(self)
self.druid = druid.new(self) self.druid = druid.new(self)
self.druid:new_button("button_node_name", button_callback) self.button = self.druid:new_button("button_node_name", on_button_callback)
end end
-- "final" is a required function for the correct Druid workflow
function final(self) function final(self)
self.druid:final() self.druid:final()
end end
-- "update" is used in progress bar, scroll, and timer basic components
function update(self, dt) function update(self, dt)
self.druid:update(dt) self.druid:update(dt)
end end
-- "on_message" is used for specific Druid events, like language change or layout change
function on_message(self, message_id, message, sender) function on_message(self, message_id, message, sender)
self.druid:on_message(message_id, message, sender) self.druid:on_message(message_id, message, sender)
end end
-- "on_input" is used in almost all Druid components
function on_input(self, action_id, action) function on_input(self, action_id, action)
return self.druid:on_input(action_id, action) return self.druid:on_input(action_id, action)
end end
@ -117,9 +77,87 @@ end
For all **Druid** instance functions, [see here](https://insality.github.io/druid/modules/DruidInstance.html). For all **Druid** instance functions, [see here](https://insality.github.io/druid/modules/DruidInstance.html).
### API Documentation
**Druid** offers a wide range of components and functions. To facilitate usage, **Druid** provides comprehensive API documentation with examples and annotations.
Start reading the API documentation [here](https://insality.github.io/druid/modules/Druid.html).
### EmmyLua Annotations [optional]
[EmmyLua](https://emmylua.github.io/annotation.html) is a Lua annotation library. It is a useful tool for enabling Lua code autocompletion in editors such as [VSCode](https://github.com/EmmyLua/VSCode-EmmyLua) and [IntelliJ IDEA](https://github.com/EmmyLua/IntelliJ-EmmyLua).
Since dependencies cannot be processed by external editors, to use the EmmyLua annotations, you should copy the _druid/annotations.lua_ file to your project.
Remember that you can restart the EmmyLua server to refresh the changes if something goes wrong.
After the annotations are processed, you should specify the type of "Druid" in the "require" statement:
```lua
---@type druid
local druid = require("druid.druid")
-- Now the autocomplete is working
```
<img src="media/emmy_lua_preview.png" width="700">
### Create custom components
If you want to create your own components, refer to the [Create Custom Components](docs_md/create-custom-components.md) section in the documentation.
Custom components are one of the most powerful features of **Druid**. They allow you to create your own components effortlessly and utilize them in your game.
## Druid Components
Here is full **Druid** components list.
### Basic Components
> Basic components always included in the build and available for use.
| Name | Description | Example | <div style="width:200px">Preview</div> |
|------|-------------|---------|---------|
| **[Button](https://insality.github.io/druid/modules/Button.html)** | Logic over GUI Node. Handle the user click interactions: click, long click, double click, etc. | [Button Example](https://insality.github.io/druid/druid/?example=general_buttons) | <img src="media/preview/button.gif" width="200" height="100"> |
| **[Text](https://insality.github.io/druid/modules/Text.html)** | Logic over GUI Text. By default Text component fit the text inside text node size area with different adjust modes. | [Text Example](https://insality.github.io/druid/druid/?example=texts_general) | <img src="media/preview/text.gif" width="200" height="100"> |
| **[Scroll](https://insality.github.io/druid/modules/Scroll.html)** | Logic over two GUI Nodes: input and content. Provides basic behaviour for scrollable content. | [Scroll Example](https://insality.github.io/druid/druid/?example=general_scroll) | <img src="media/preview/scroll.gif" width="200" height="100"> |
| **[Blocker](https://insality.github.io/druid/modules/Blocker.html)** | Logic over GUI Node. Don't pass any user input below node area size. | ❌ | |
| **[Back Handler](https://insality.github.io/druid/modules/BackHandler.html)** | Call callback on user "Back" action. It's a Android back button or keyboard backspace key | ❌ | |
| **[Static Grid](https://insality.github.io/druid/modules/StaticGrid.html)** | Logic over GUI Node. Component to manage node positions with all equal node sizes. | [Static Gid Example](https://insality.github.io/druid/druid/?example=general_grid) | <img src="media/preview/static_grid.gif" width="200" height="100"> |
| **[Hover](https://insality.github.io/druid/modules/Hover.html)** | Logic over GUI Node. Handle hover action over node. For both: mobile touch and mouse cursor. | ❌ | <img src="media/preview/hover.gif" width="200" height="100"> |
| **[Swipe](https://insality.github.io/druid/modules/Swipe.html)** | Logic over GUI Node. Handle swipe gestures over node. | [Swipe Example](https://insality.github.io/druid/druid/?example=general_swipe) | <img src="media/preview/swipe.gif" width="200" height="100"> |
| **[Drag](https://insality.github.io/druid/modules/Drag.html)** | Logic over GUI Node. Handle drag input actions. Can be useful to make on screen controlls. | [Drag Example](https://insality.github.io/druid/druid/?example=general_drag) | <img src="media/preview/drag.gif" width="200" height="100"> |
### Extended components
> Extended components before usage should be registered in **Druid** with `druid.register()` function.
| Name | Description | Example | <div style="width:200px">Preview</div> |
|------|-------------|---------|---------|
| **[Checkbox](https://insality.github.io/druid/modules/Checkbox.html)** | Switch node state on click event. | [Checkbox Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | <img src="media/preview/checkbox.gif" width="200" height="100"> |
| **[Checkbox group](https://insality.github.io/druid/modules/CheckboxGroup.html)** | Group of checkbox components. | [Checkbox group Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | <img src="media/preview/checkbox_group.gif" width="200" height="100"> |
| **[Radio group](https://insality.github.io/druid/modules/RadioGroup.html)** | Like checkbox group but with single choise only. | [Radio Group Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | <img src="media/preview/radio_group.gif" width="200" height="100"> |
| **[Dynamic Grid](https://insality.github.io/druid/modules/DynamicGrid.html)** | Logic over GUI Node. Component to manage node positions with all different node sizes. Only one direction: horizontal or vertical. | [Dynamic Grid Example](https://insality.github.io/druid/druid/?example=general_grid) | <img src="media/preview/dynamic_grid.gif" width="200" height="100"> |
| **[Data List](https://insality.github.io/druid/modules/DataList.html)** | Logic over Scroll and Grid components. Create only visible GUI nodes or components to make "infinity" scroll befaviour | [Data List Example](https://insality.github.io/druid/druid/?example=general_data_list) | <img src="media/preview/data_list.gif" width="200" height="100"> |
| **[Input](https://insality.github.io/druid/modules/Input.html)** | Logic over GUI Node and GUI Text (or Text component). Provides basic user text input. | [Input Example](https://insality.github.io/druid/druid/?example=general_input) | <img src="media/preview/input.gif" width="200" height="100"> |
| **[Lang text](https://insality.github.io/druid/modules/LangText.html)** | Logic over Text component to handle localization. Can be translated in real-time with `druid.on_language_change` | ❌ | <img src="media/preview/lang_text.gif" width="200" height="100"> |
| **[Progress](https://insality.github.io/druid/modules/Progress.html)** | Logic over GUI Node. Handle node size and scale to handle progress node size. | [Progress Example](https://insality.github.io/druid/druid/?example=general_progress_bar) | <img src="media/preview/progress.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"> |
| **[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"> |
For a complete overview, see: **_[components.md](docs_md/01-components.md)_**.
## Druid Events ## Druid Events
Any **Druid** components as callbacks use [Druid Events](https://insality.github.io/druid/modules/DruidEvent.html). In component API ([button example](https://insality.github.io/druid/modules/Button.html#on_click)) pointed list of component events. You can manually subscribe to those events with the following API: Any **Druid** components as callbacks use [Druid Events](https://insality.github.io/druid/modules/DruidEvent.html). In component API ([button example](https://insality.github.io/druid/modules/Button.html#on_click)) pointed list of component events. You can manually subscribe to these events with the following API:
- **event:subscribe**(callback) - **event:subscribe**(callback)
@ -129,71 +167,43 @@ Any **Druid** components as callbacks use [Druid Events](https://insality.github
You can subscribe several callbacks to a single event. You can subscribe several callbacks to a single event.
## Druid Lifecycle
Here is full Druid lifecycle setup for your ***.gui_script** file:
```lua
local druid = require("druid.druid")
function init(self)
self.druid = druid.new(self)
end
function final(self)
self.druid:final()
end
function update(self, dt)
self.druid:update(dt)
end
function on_input(self, action_id, action)
return self.druid:on_input(action_id, action)
end
function on_message(self, message_id, message, sender)
self.druid:on_message(message_id, message, sender)
end
```
- *final* is a **required** function for a correct Druid lifecycle
- *on_input* is used in almost all Druid components
- *update* in used in progress bar, scroll and timer base components
- *on_message* is used for specific Druid events, like language change or layout change
It is recommended to fully integrate all **Druid** lifecycles functions.
## Details ## Details
- Druid input goes as stack. Last created button will checked first. So create your GUI from back - **Druid** processes input in a stack-based manner. The most recently created button will be checked first. Create your input GUI components from back to front.
- Don't forget about `return` in `on_input`: `return self.druid:on_input()`. It is needed if you have more than 1 acquire inputs (several Druid, other input system, etc) - Remember to include `return` in the `on_input` function: `return self.druid:on_input()`. This is necessary if you have multiple input sources (multiple Druid instances, other input systems, etc.).
- By default, Druid will automatically _acquire_input_focus_. So you don't need do it manually. But only if you have components which require _on_input_ - Druid automatically calls `acquire_input_focus` if you have input components. Therefore, manual calling of `acquire_input_focus` is not required.
- If you want to delete a node which has a Druid component, don't forget to remove it via `druid:remove(component)` - When deleting a **Druid** component node, make sure to remove it using `druid:remove(component)`.
[See full FAQ here](docs_md/FAQ.md) [See the full FAQ here](docs_md/FAQ.md)
## Examples ## Examples
See the [**example folder**](https://github.com/Insality/druid/tree/develop/example) for examples of how to use **Druid** ### HTML5 Live Examples
Try the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Druid** example app Try the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Druid** example app.
Each example page provides a direct link to the corresponding example code, making it easier for you to understand how to use **Druid**.
### Code Examples
Refer to the [**example folder**](https://github.com/Insality/druid/tree/develop/example) for code examples demonstrating how to use **Druid**.
## Documentation ## Documentation
To better understand **Druid**, read the following documentation: To better understand **Druid**, read the following documentation:
- [How To GUI in Defold](https://forum.defold.com/t/how-to-gui-in-defold/73256)
- [Druid components](docs_md/01-components.md) - [Druid components](docs_md/01-components.md)
- [Create custom components](docs_md/02-creating_custom_components.md) - [Create custom components](docs_md/02-creating_custom_components.md)
- [See FAQ article](docs_md/FAQ.md) - [See FAQ article](docs_md/FAQ.md)
- [Druid styles](docs_md/03-styles.md) - [Druid styles](docs_md/03-styles.md)
You can fund the full **Druid** documentation here: You can find the full **Druid** documentation here:
https://insality.github.io/druid/ https://insality.github.io/druid/modules/Druid.html
## License ## Licenses
- Developed and supported by [Insality](https://github.com/Insality) - Developed and supported by [Insality](https://github.com/Insality)
- Original idea by [AGulev](https://github.com/AGulev) - Original idea by [AGulev](https://github.com/AGulev)

View File

@ -9,3 +9,4 @@ date,sha,version,build_size,build_time,platform,mode,is_cache_using,commits_coun
2022-08-29T18:46:47Z,13003e472169cbd261e703eca7b133adf64a24f7,0.9.592,2316,40,js-web,release,true,592 2022-08-29T18:46:47Z,13003e472169cbd261e703eca7b133adf64a24f7,0.9.592,2316,40,js-web,release,true,592
2022-09-09T17:55:42Z,072507cc9e715541bdee7636d2e5eeeb3c22a57d,0.10.603,2340,43,js-web,release,true,603 2022-09-09T17:55:42Z,072507cc9e715541bdee7636d2e5eeeb3c22a57d,0.10.603,2340,43,js-web,release,true,603
2022-09-09T18:00:07Z,072507cc9e715541bdee7636d2e5eeeb3c22a57d,0.10.603,2340,5,js-web,release,true,603 2022-09-09T18:00:07Z,072507cc9e715541bdee7636d2e5eeeb3c22a57d,0.10.603,2340,5,js-web,release,true,603
2023-07-05T20:19:22Z,d0062c2a78e618871ebb4c8ee66b1509b763f069,0.10.671,3292,12,x86_64-linux,headless,true,671

1 date sha version build_size build_time platform mode is_cache_using commits_count
9 2022-08-29T18:46:47Z 13003e472169cbd261e703eca7b133adf64a24f7 0.9.592 2316 40 js-web release true 592
10 2022-09-09T17:55:42Z 072507cc9e715541bdee7636d2e5eeeb3c22a57d 0.10.603 2340 43 js-web release true 603
11 2022-09-09T18:00:07Z 072507cc9e715541bdee7636d2e5eeeb3c22a57d 0.10.603 2340 5 js-web release true 603
12 2023-07-05T20:19:22Z d0062c2a78e618871ebb4c8ee66b1509b763f069 0.10.671 3292 12 x86_64-linux headless true 671

View File

@ -133,7 +133,7 @@ Usually, Place _view_node_ and as children add _content_node_:
- *on_scroll_to* (self, position, is_instant) On scroll_to function callback - *on_scroll_to* (self, position, is_instant) On scroll_to function callback
- *on_point_scroll* (self, item_index, position) On scroll_to_index function callback - *on_point_scroll* (self, item_index, position) On scroll_to_index function callback
- You can adjust scroll content size by `scroll:set_size(node_size)`. It will setup new size to _content node_ - You can adjust scroll content size by `scroll:set_size(node_size)`. It will setup new size to _content node_
- You can enabled or disable inertion mode via `scroll:set_intert(state)` - You can enabled or disable inertion mode via `scroll:set_inert(state)`
- You can adjust extra stretch size via `scroll:set_extra_stretch_size` - You can adjust extra stretch size via `scroll:set_extra_stretch_size`
- Multitouch is required for scroll. Scroll is correctly handling touch_id swap while dragging scroll - Multitouch is required for scroll. Scroll is correctly handling touch_id swap while dragging scroll

View File

@ -1,23 +1,30 @@
## Input bindings # Advanced Druid Setup
## Input Bindings
By default, **Druid** utilizes the `/builtins/input/all.input_binding` for input bindings.
**Druid** requires the following input bindings: **Druid** requires the following input bindings:
- Mouse trigger - `Button 1` -> `touch` _For basic input components_ - Mouse trigger: `Button 1` -> `touch` (for basic input components)
- Mouse trigger - `Wheel up` -> `mouse_wheel_up` _For scroll component_ - Mouse trigger: `Wheel up` -> `mouse_wheel_up` (for Scroll component)
- Mouse trigger - `Wheel down` -> `mouse_wheel_down` _For scroll component_ - Mouse trigger: `Wheel down` -> `mouse_wheel_down` (for Scroll component)
- Key trigger - `Backspace` -> `key_backspace` _For back_handler component, input component_ - Key trigger: `Backspace` -> `key_backspace` (for BackHandler component, input component)
- Key trigger - `Back` -> `key_back` _For back_handler 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)
- 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)
![](media/input_binding_1.png) ![](media/input_binding_1.png)
## Change key bindings [optional]
If you have to use your own key bindings (and key name), you can change it in your *game.project* file.
Here is current default values for key bindings: ## Changing Key Bindings (optional)
If you need to use your own key bindings or key names, you can modify them in your *game.project* file.
Here are the default values for key bindings:
``` ```
[druid] [druid]
input_text = text input_text = text
@ -33,22 +40,22 @@ input_scroll_down = mouse_wheel_down
``` ```
## Input capturing [optional] ## Input Capturing (optional)
By default, **Druid** will auto-capture input focus, if any input component will be created. So you don't need to call `msg.post(".", "acquire_input_focus")` By default, **Druid** automatically captures input focus if any input component is created. Therefore, you do not need to call `msg.post(".", "acquire_input_focus")`.
If you don't need this behaviour, you can disable it by setting `druid.no_auto_input` field in _game.project_: If you do not require this behavior, you can disable it by setting the `druid.no_auto_input` field in the _game.project_ file:
``` ```
[druid] [druid]
no_auto_input = 1 no_auto_input = 1
``` ```
## Template name check [optional] ## Template Name Check (optional)
By default, **Druid** will auto check the parent component template name to build the full template name for component. By default, **Druid** automatically checks the parent component's template name to construct the full template name for the component. It's used in user custom components.
If for some reason you want to pass the full template name by yourself, you can disable it by setting `druid.no_auto_template` field in _game.project_: If, for some reason, you want to pass the full template name manually, you can disable this feature by setting the `druid.no_auto_template` field in the _game.project_ file:
``` ```
[druid] [druid]
@ -56,39 +63,49 @@ no_auto_template = 1
``` ```
## Stencil check [optional] ## Stencil Check (optional)
When creating input components inside stencil nodes, **Druid** automatically setup `component:set_click_zone()` on _late_init_ component step to restrict input clicks outside this stencil zone. When creating input components inside stencil nodes, **Druid** automatically sets up `component:set_click_zone()` during the _late_init_ component step to restrict input clicks outside of the stencil zone. This is particularly useful for buttons inside scroll stencil nodes.
To disable this feature add next field in your _game.project_ file
To disable this feature, add the following field to your _game.project_ file:
``` ```
[druid] [druid]
no_stencil_check = 1 no_stencil_check = 1
``` ```
## Code [optional] ## Code Bindings (optional)
Adjust **Druid** settings, if needed: Adjust **Druid** settings as needed:
```lua ```lua
local druid = require("druid.druid") local druid = require("druid.druid")
-- Used for button component and custom components -- Used for button component and custom components
-- Callback should play sound by name: function(sound_id) ... end -- The callback should play the sound by name: function(sound_id) ... end
druid.set_sound_function(callback) druid.set_sound_function(function(sound_id)
-- sound_system.play(sound_id)
end)
-- Used for lang_text component -- Used for lang_text component
-- Callback should return localized string by locale id: function(locale_id) ... end -- The callback should return the localized string by locale ID: function(locale_id) ... end
druid.set_text_function(callback) druid.set_text_function(function(locale_id)
-- return lang.get(locale_id)
end)
-- Used for change default Druid style -- Used to change the default Druid style
druid.set_default_style(your_style) druid.set_default_style(your_style)
-- Call this function on language changing in the game, -- Call this function when the language changes in the game,
-- to retranslate all lang_text components: -- to retranslate all lang_text components:
local function on_language_change()
druid.on_language_change() druid.on_language_change()
end
-- Call this function inside window.set_listener -- Call this function inside window.set_listener
-- to catch game focus lost/gained callbacks: -- to capture game focus lost/gained callbacks:
-- window.set_listener(function(self, event, data) druid.on_window_callback(event, data) end)) -- window.set_listener(function(self, event, data) druid.on_window_callback(event, data) end))
local function on_window_callback(self, event, data)
druid.on_window_callback(event) druid.on_window_callback(event)
end
window.set_listener(on_window_callback)
``` ```

View File

@ -1,59 +0,0 @@
# Druid Rich Text
## Links
[Rich Text API here](https://insality.github.io/druid/modules/RichText.html)
## Overview
## Setup
Rich Text requires the next GUI Node scheme:
```bash
root
├── text_prefab
└── node_prefab
```
or make the copy of `/druid/custom/rich_text/rich_text.gui` and adjust your default settings
Create Rich Text:
```lua
local RichText = require("druid.custom.rich_text.rich_text")
function init(self)
self.druid = druid.new(self)
self.rich_text = self.druid:new(RichText, "template_name")
self.rich_text:set_text("Insert your text here")
end
```
## Usage
| Tag | Description | Example |
|---------|------------------------------------------------|---------------------------------------------|
| a | Create a "hyperlink" that generates a message | `<a=message_id>Foobar</a>` |
| | when clicked (see `richtext.on_click`) | |
| br | Insert a line break (see notes on linebreak) | `<br/>` |
| color | Change text color | `<color=red>Foobar</color>` |
| | | `<color=1.0,0,0,1.0>Foobar</color>` |
| | | `<color=#ff0000>Foobar</color>` |
| | | `<color=#ff0000ff>Foobar</color>` |
| shadow | Change text shadow | `<shadow=red>Foobar</shadow>` |
| | | `<shadow=1.0,0,0,1.0>Foobar</shadow>` |
| | | `<shadow=#ff0000>Foobar</shadow>` |
| | | `<shadow=#ff0000ff>Foobar</shadow>` |
| outline | Change text shadow | `<outline=red>Foobar</outline>` |
| | | `<outline=1.0,0,0,1.0>Foobar</outline>` |
| | | `<outline=#ff0000>Foobar</outline>` |
| | | `<outline=#ff0000ff>Foobar</outline>` |
| font | Change font | `<font=MyCoolFont>Foobar</font>` |
| img | Display image | `<img=texture:image/>` |
| | Display image in fixed square | `<img=texture:image,size/>` |
| | Display image in fixed rectangle | `<img=texture:image,width,height/>` |
| nobr | Prevent the text from breaking | `Words <nobr>inside tag</nobr> won't break` |
| size | Change text size, relative to default size | `<size=2>Twice as large</size>` |
## Usecases
## Notes

View File

@ -22,6 +22,7 @@
"input": true, "input": true,
"media": true, "media": true,
"build": true, "build": true,
"docs": true,
".github": true, ".github": true,
".deployer_cache": true, ".deployer_cache": true,
"dist": true "dist": true

View File

@ -20,7 +20,7 @@ function druid.on_language_change() end
function druid.on_window_callback(event) end function druid.on_window_callback(event) end
--- Register a new external Druid component. --- Register a new external Druid component.
--- You can register your own components by creating them with the druid:new_{name} function. For example, if you want to register a component called "my_component", you can create it using druid:new_my_component(...). This can be useful if you have your own "basic" components that you don't want to re-create each time. --- You can register your own components to make new alias: the druid:new_{name} function. For example, if you want to register a component called "my_component", you can create it using druid:new_my_component(...). This can be useful if you have your own "basic" components that you don't want to re-create each time.
---@param name string module name ---@param name string module name
---@param module table lua table with component ---@param module table lua table with component
function druid.register(name, module) end function druid.register(name, module) end
@ -42,8 +42,8 @@ function druid.set_text_function(callback) end
---@class druid.back_handler : druid.base_component ---@class druid.back_handler : druid.base_component
---@field on_back druid.event @{DruidEvent} function(self, [params]) . ---@field on_back druid.event @{DruidEvent} Event on back handler action.
---@field params any Params to pass in the callback ---@field params any Custom args to pass in the callback
local druid__back_handler = {} local druid__back_handler = {}
@ -125,7 +125,7 @@ function druid__base_component.component:set_input_enabled(self, state) end
function druid__base_component.component:set_input_priority(self, value, is_temporary) end function druid__base_component.component:set_input_priority(self, value, is_temporary) end
--- Set current component nodes --- Set current component nodes
--- Used if your component nodes was cloned with `gui.clone_tree` --- Use if your component nodes was cloned with `gui.clone_tree` and you got the node tree.
---@param self druid.base_component @{BaseComponent} ---@param self druid.base_component @{BaseComponent}
---@param nodes table BaseComponent nodes table ---@param nodes table BaseComponent nodes table
---@return druid.base_component @{BaseComponent} ---@return druid.base_component @{BaseComponent}
@ -147,91 +147,96 @@ function druid__base_component.component:set_template(self, template) end
---@class druid.blocker : druid.base_component ---@class druid.blocker : druid.base_component
---@field node node Trigger node ---@field node node Blocker node
local druid__blocker = {} local druid__blocker = {}
--- @{Blocker} constructor
---@param self druid.blocker @{Blocker}
---@param node node Gui node
function druid__blocker.init(self, node) end
--- Return blocker enabled state --- Return blocker enabled state
---@param self druid.blocker @{Blocker} ---@param self druid.blocker @{Blocker}
---@return bool True, if blocker is enabled ---@return bool True, if blocker is enabled
function druid__blocker.is_enabled(self) end function druid__blocker.is_enabled(self) end
--- Set enabled blocker component state --- Set enabled blocker component state.
--- Don't change node enabled state itself.
---@param self druid.blocker @{Blocker} ---@param self druid.blocker @{Blocker}
---@param state bool Enabled state ---@param state bool Enabled state
function druid__blocker.set_enabled(self, state) end function druid__blocker.set_enabled(self, state) end
---@class druid.button : druid.base_component ---@class druid.button : druid.base_component
---@field anim_node node Animation node ---@field anim_node node Button animation node.
---@field click_zone node Restriction zone ---@field click_zone node Additional button click area, defined by another GUI Node
---@field hash node_id The hash of trigger node ---@field hover druid.hover @{Hover}: Button Hover component
---@field hover druid.hover Druid hover logic component ---@field node Node Button trigger node
---@field node node Trigger node ---@field node_id hash The GUI node id from button node
---@field on_click druid.event On release button callback(self, params, button_instance) ---@field on_click druid.event @{DruidEvent}: Event on successful release action over button.
---@field on_click_outside druid.event On click outside of button(self, params, button_instance) ---@field on_click_outside druid.event @{DruidEvent}: Event calls if click event was outside of button.
---@field on_double_click druid.event On double tap button callback(self, params, button_instance, click_amount) ---@field on_double_click druid.event @{DruidEvent}: Event on double tap action over button.
---@field on_hold_callback druid.event On button hold before long_click callback(self, params, button_instance, time) ---@field on_hold_callback druid.event @{DruidEvent}: Event calls every frame before on_long_click event.
---@field on_long_click druid.event On long tap button callback(self, params, button_instance, time) ---@field on_long_click druid.event @{DruidEvent}: Event on long tap action over button.
---@field on_pressed druid.event On pressed button callback(self, params, button_instance) ---@field on_pressed druid.event @{DruidEvent}: Event triggered if button was pressed by user.
---@field on_repeated_click druid.event On repeated action button callback(self, params, button_instance, click_amount) ---@field on_repeated_click druid.event @{DruidEvent}: Event on repeated action over button.
---@field params any Params to click callbacks ---@field params any Custom args for any Button event.
---@field pos vector3 Initial pos of anim_node
---@field start_pos vector3 Initial pos of anim_node
---@field start_scale vector3 Initial scale of anim_node
---@field style druid.button.style Component style params. ---@field style druid.button.style Component style params.
local druid__button = {} local druid__button = {}
--- Get key-code to trigger this button --- Get current key name to trigger this button.
---@param self druid.button ---@param self druid.button
---@return hash The action_id of the key ---@return hash The action_id of the input key
function druid__button.get_key_trigger(self) end function druid__button.get_key_trigger(self) end
--- Component init function --- @{Button} constructor
---@param self druid.button @{Button} ---@param self druid.button @{Button}
---@param node node Gui node ---@param node string|Node Node name or GUI Node itself
---@param callback function Button callback ---@param callback function On click button callback
---@param params table Button callback params ---@param custom_args any Button events custom arguments
---@param anim_node node Button anim node (node, if not provided) ---@param anim_node string|Node Node to animate instead of trigger node.
function druid__button.init(self, node, callback, params, anim_node) end function druid__button.init(self, node, callback, custom_args, anim_node) end
--- Return button enabled state --- Get button enabled state.
--- By default all Buttons is enabled on creating.
---@param self druid.button @{Button} ---@param self druid.button @{Button}
---@return bool True, if button is enabled ---@return bool True, if button is enabled now, False overwise
function druid__button.is_enabled(self) end function druid__button.is_enabled(self) end
--- Set function for additional check for button click availability --- Set function for additional check for button click availability
---@param self druid.button ---@param self druid.button
---@param check_function function Should return true or false. If true - button can be pressed. ---@param check_function function Should return true or false. If true - button can be pressed.
---@param failure_callback function Function what will be called on button click, if check function return false ---@param failure_callback function Function will be called on button click, if check function return false
---@return druid.button Current button instance ---@return druid.button Current button instance
function druid__button.set_check_function(self, check_function, failure_callback) end function druid__button.set_check_function(self, check_function, failure_callback) end
--- Strict button click area. --- Set additional button click area.
--- Useful for no click events outside stencil node --- Useful to restrict click outside out stencil node or scrollable content. This functions calls automatically if you don't disable it in game.project: druid.no_stencil_check
---@param self druid.button @{Button} ---@param self druid.button @{Button}
---@param zone node Gui node ---@param zone node Gui node
---@return druid.button Current button instance ---@return druid.button Current button instance
function druid__button.set_click_zone(self, zone) end function druid__button.set_click_zone(self, zone) end
--- Set enabled button component state --- Set button enabled state.
--- The style.on_set_enabled will be triggered. Disabled button is not clickable.
---@param self druid.button @{Button} ---@param self druid.button @{Button}
---@param state bool Enabled state ---@param state bool Enabled state
---@return druid.button Current button instance ---@return druid.button Current button instance
function druid__button.set_enabled(self, state) end function druid__button.set_enabled(self, state) end
--- Set buttom click mode to call itself inside html5 callback in user interaction event It required to do protected stuff like copy/paste text, show html keyboard, etc The HTML5 button don't call any events except on_click --- Set key name to trigger this button by keyboard.
---@protected
---@param self druid.button
---@param is_html_mode boolean If true - button will be called inside html5 callback
---@return druid.button Current button instance
function druid__button.set_html5_user_interaction(self, is_html_mode) end
--- Set key-code to trigger this button
---@param self druid.button @{Button} ---@param self druid.button @{Button}
---@param key hash The action_id of the key ---@param key hash The action_id of the input key
---@return druid.button Current button instance ---@return druid.button Current button instance
function druid__button.set_key_trigger(self, key) end function druid__button.set_key_trigger(self, key) end
--- Set Button mode to work inside user HTML5 interaction event.
--- It's required to make protected things like copy & paste text, show mobile keyboard, etc The HTML5 button's doesn't call any events except on_click event. If the game is not HTML, html mode will be not enabled
---@param self druid.button
---@param is_web_mode boolean If true - button will be called inside html5 callback
---@return druid.button Current button instance
function druid__button.set_web_user_interaction(self, is_web_mode) end
---@class druid.button.style ---@class druid.button.style
---@field AUTOHOLD_TRIGGER field Maximum hold time to trigger button release while holding ---@field AUTOHOLD_TRIGGER field Maximum hold time to trigger button release while holding
@ -647,7 +652,7 @@ function druid__input.get_text(self) end
--- Component init function --- Component init function
---@param self druid.input @{Input} ---@param self druid.input @{Input}
---@param click_node node Button node to enabled input component ---@param click_node node Node to enabled input component
---@param text_node node|druid.text Text node what will be changed on user input. You can pass text component instead of text node name @{Text} ---@param text_node node|druid.text Text node what will be changed on user input. You can pass text component instead of text node name @{Text}
---@param keyboard_type number Gui keyboard type for input field ---@param keyboard_type number Gui keyboard type for input field
function druid__input.init(self, click_node, text_node, keyboard_type) end function druid__input.init(self, click_node, text_node, keyboard_type) end
@ -715,12 +720,12 @@ local druid__lang_text = {}
---@return druid.lang_text Current instance ---@return druid.lang_text Current instance
function druid__lang_text.format(self, a, b, c, d, e, f, g) end function druid__lang_text.format(self, a, b, c, d, e, f, g) end
--- Component init function --- @{LangText} constructor
---@param self druid.lang_text @{LangText} ---@param self druid.lang_text @{LangText}
---@param node node The text node ---@param node string|node Node name or GUI Text Node itself
---@param locale_id string Default locale id or text from node as default ---@param locale_id string Default locale id or text from node as default
---@param no_adjust bool If true, will not correct text size ---@param adjust_type string Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
function druid__lang_text.init(self, node, locale_id, no_adjust) end function druid__lang_text.init(self, node, locale_id, adjust_type) end
--- Setup raw text to lang_text component --- Setup raw text to lang_text component
---@param self druid.lang_text @{LangText} ---@param self druid.lang_text @{LangText}
@ -836,7 +841,7 @@ function druid__pin_knob.set_friction(self, value) end
---@class druid.progress : druid.base_component ---@class druid.progress : druid.base_component
---@field key string The progress bar direction ---@field key string The progress bar direction.
---@field max_size number Maximum size of progress bar ---@field max_size number Maximum size of progress bar
---@field node node Progress bar fill node ---@field node node Progress bar fill node
---@field on_change druid.event On progress bar change callback(self, new_value) ---@field on_change druid.event On progress bar change callback(self, new_value)
@ -858,9 +863,9 @@ function druid__progress.fill(self) end
---@param self druid.progress @{Progress} ---@param self druid.progress @{Progress}
function druid__progress.get(self) end function druid__progress.get(self) end
--- Component init function --- @{Progress} constructor
---@param self druid.progress @{Progress} ---@param self druid.progress @{Progress}
---@param node string|node Progress bar fill node or node name ---@param node string|node Node name or GUI Node itself.
---@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y ---@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y
---@param init_value number Initial value of progress bar ---@param init_value number Initial value of progress bar
function druid__progress.init(self, node, key, init_value) end function druid__progress.init(self, node, key, init_value) end
@ -942,6 +947,31 @@ function druid__rich_input.set_placeholder(self, placeholder_text) end
---@field component field The component druid instance ---@field component field The component druid instance
local druid__rich_text = {} local druid__rich_text = {}
--- Clear all created words.
function druid__rich_text.clean() end
--- Get all current words.
---@return table Words
function druid__rich_text.get_words() end
--- Rich Text component constructor
---@param self druid.rich_text @{RichText}
---@param template string The Rich Text template name
---@param nodes table The node table, if prefab was copied by gui.clone_tree()
function druid__rich_text.init(self, template, nodes) end
--- Set text for Rich Text
---@param self druid.rich_text @{RichText}
---@param text string The text to set
---@return table words
---@return table line_metrics
function druid__rich_text.set_text(self, text) end
--- Get all words, which has a passed tag
---@param tag string
---@return table Words
function druid__rich_text.tagged(tag) end
---@class druid.scroll : druid.base_component ---@class druid.scroll : druid.base_component
---@field available_pos vector4 Available position for content node: (min_x, max_y, max_x, min_y) ---@field available_pos vector4 Available position for content node: (min_x, max_y, max_x, min_y)
@ -978,10 +1008,10 @@ function druid__scroll.get_percent(self) end
---@return vector3 Available scroll size ---@return vector3 Available scroll size
function druid__scroll.get_scroll_size(self) end function druid__scroll.get_scroll_size(self) end
--- Scroll constructor --- @{Scroll} constructor
---@param self druid.scroll @{Scroll} ---@param self druid.scroll @{Scroll}
---@param view_node node GUI view scroll node ---@param view_node string|node GUI view scroll node
---@param content_node node GUI content scroll node ---@param content_node string|node GUI content scroll node
function druid__scroll.init(self, view_node, content_node) end function druid__scroll.init(self, view_node, content_node) end
--- Return if scroll have inertion. --- Return if scroll have inertion.
@ -1187,9 +1217,9 @@ function druid__static_grid.get_pos(self, index) end
---@return vector3 The grid content size ---@return vector3 The grid content size
function druid__static_grid.get_size(self) end function druid__static_grid.get_size(self) end
--- Component init function --- @{StaticGrid} constructor
---@param self druid.static_grid @{StaticGrid} ---@param self druid.static_grid @{StaticGrid}
---@param parent node The gui node parent, where items will be placed ---@param parent string|Node The GUI Node container, where grid's items will be placed
---@param element node Element prefab. Need to get it size ---@param element node Element prefab. Need to get it size
---@param in_row number How many nodes in row can be placed ---@param in_row number How many nodes in row can be placed
function druid__static_grid.init(self, parent, element, in_row) end function druid__static_grid.init(self, parent, element, in_row) end
@ -1285,11 +1315,11 @@ function druid__text.get_text_adjust(self, adjust_type) end
---@return number Height ---@return number Height
function druid__text.get_text_size(self, text) end function druid__text.get_text_size(self, text) end
--- Component init function --- @{Text} constructor
---@param self druid.text @{Text} ---@param self druid.text @{Text}
---@param node node Gui text node ---@param node string|node Node name or GUI Text Node itself
---@param value string Initial text. Default value is node text from GUI scene. ---@param value string Initial text. Default value is node text from GUI scene.
---@param adjust_type int Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference ---@param adjust_type string Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
function druid__text.init(self, node, value, adjust_type) end function druid__text.init(self, node, value, adjust_type) end
--- Return true, if text with line break --- Return true, if text with line break
@ -1578,7 +1608,7 @@ function druid_instance.on_input(self, action_id, action) end
---@param sender hash Sender from on_message ---@param sender hash Sender from on_message
function druid_instance.on_message(self, message_id, message, sender) end function druid_instance.on_message(self, message_id, message, sender) end
--- Remove component from Druid instance. --- Remove created component from Druid instance.
--- Component `on_remove` function will be invoked, if exist. --- Component `on_remove` function will be invoked, if exist.
---@param self druid_instance ---@param self druid_instance
---@param component Component Component instance ---@param component Component Component instance

View File

@ -1,18 +1,16 @@
-- Copyright (c) 2023 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2023 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component with event on back and backspace button. --- Component with event on back and backspace button.
-- # Overview # -- <b># Overview #</b>
-- --
-- Back Handler is recommended to put in every game window to close it -- Back Handler is recommended to put in every game window to close it
-- or in main screen to call settings window. -- or in main screen to call settings window.
-- --
-- # Tech Info # -- <b># Notes #</b>
--
-- Back Handler react on release action ACTION_BACK or ACTION_BACKSPACE
--
-- # Notes #
-- --
-- • Back Handler inheritance @{BaseComponent}, you can use all of its methods in addition to those described here. -- • Back Handler inheritance @{BaseComponent}, you can use all of its methods in addition to those described here.
--
-- • Back Handler react on release action ACTION_BACK or ACTION_BACKSPACE
-- @usage -- @usage
-- local callback = function(self, params) ... end -- local callback = function(self, params) ... end
-- --
@ -22,7 +20,7 @@
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.back_handler -- @alias druid.back_handler
--- @{DruidEvent} function(self, [params]) . --- @{DruidEvent} Event on back handler action.
-- --
-- Trigger on input action ACTION_BACK or ACTION_BACKSPACE -- Trigger on input action ACTION_BACK or ACTION_BACKSPACE
-- @usage -- @usage
@ -30,7 +28,7 @@
-- back_handler.on_back:subscribe(callback) -- back_handler.on_back:subscribe(callback)
-- @tfield DruidEvent on_back @{DruidEvent} -- @tfield DruidEvent on_back @{DruidEvent}
--- Params to pass in the callback --- Custom args to pass in the callback
-- @usage -- @usage
-- -- Replace params on runtime: -- -- Replace params on runtime:
-- back_handler.params = { ... } -- back_handler.params = { ... }
@ -45,13 +43,13 @@ local component = require("druid.component")
local BackHandler = component.create("back_handler") local BackHandler = component.create("back_handler")
--- Component initialize function --- @{BackHandler} constructor
-- @tparam BackHandler self @{BackHandler} -- @tparam BackHandler self @{BackHandler}
-- @tparam callback callback On back button -- @tparam callback callback On back button
-- @tparam[opt] any params Callback argument -- @tparam[opt] any custom_args Button events custom arguments
-- @local -- @local
function BackHandler.init(self, callback, params) function BackHandler.init(self, callback, custom_args)
self.params = params self.params = custom_args
self.on_back = Event(callback) self.on_back = Event(callback)
end end

View File

@ -1,19 +1,17 @@
-- Copyright (c) 2023 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2023 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to block input in special zone defined by GUI node. --- Component to consume input in special zone defined by GUI node.
-- # Overview # -- <b># Overview #</b>
-- --
-- Blocker component необходим, чтобы блокировать пользовательский ввод в определенной зоне. -- <b># Notes #</b>
-- Зона задается размером ноды, на которой находится компонент. Blocker блокирует ввод только для тех
-- элементов, которые находятся перед ним in input stack (созданы до него).
--
-- # Tech Info #
-- --
-- Blocker consume input if `gui.pick_node` works on it. -- Blocker consume input if `gui.pick_node` works on it.
-- --
-- # Notes #
--
-- • Blocker inheritance @{BaseComponent}, you can use all of its methods in addition to those described here. -- • Blocker inheritance @{BaseComponent}, you can use all of its methods in addition to those described here.
--
-- • Blocker initial enabled state is `gui.is_enabled(node, true)`
--
-- • The Blocker node should be enabled to capture the input
-- @usage -- @usage
-- local node = gui.get_node("blocker_node") -- local node = gui.get_node("blocker_node")
-- local blocker = self.druid:new_blocker(node) -- local blocker = self.druid:new_blocker(node)
@ -21,7 +19,7 @@
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.blocker -- @alias druid.blocker
---Trigger node ---Blocker node
-- @tfield node node -- @tfield node node
--- ---
@ -32,12 +30,12 @@ local component = require("druid.component")
local Blocker = component.create("blocker") local Blocker = component.create("blocker")
--- Component initialize function --- @{Blocker} constructor
-- @tparam Blocker self @{Blocker} -- @tparam Blocker self @{Blocker}
-- @tparam node node Gui node -- @tparam node node Gui node
-- @local
function Blocker.init(self, node) function Blocker.init(self, node)
self.node = self:get_node(node) self.node = self:get_node(node)
self._is_enabled = gui.is_enabled(self.node, true)
end end
@ -57,6 +55,10 @@ function Blocker.on_input(self, action_id, action)
return false return false
end end
if 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
return true return true
end end
@ -65,11 +67,13 @@ function Blocker.on_input(self, action_id, action)
end end
--- Set enabled blocker component state --- Set enabled blocker component state.
--
-- Don't change node enabled state itself.
-- @tparam Blocker self @{Blocker} -- @tparam Blocker self @{Blocker}
-- @tparam bool state Enabled state -- @tparam bool state Enabled state
function Blocker.set_enabled(self, state) function Blocker.set_enabled(self, state)
gui.set_enabled(self.node, state) self._is_enabled = state
end end
@ -77,7 +81,7 @@ end
-- @tparam Blocker self @{Blocker} -- @tparam Blocker self @{Blocker}
-- @treturn bool True, if blocker is enabled -- @treturn bool True, if blocker is enabled
function Blocker.is_enabled(self) function Blocker.is_enabled(self)
return gui.is_enabled(self.node) return self._is_enabled
end end

View File

@ -1,56 +1,137 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to handle basic GUI button --- Druid Component for Handling User Click Interactions: Click, Long Click, Double Click, and More.
--
-- <b># Overview #</b>
--
-- This component provides a versatile solution for handling user click interactions.
-- It allows you to make any GUI node clickable and define various callbacks for different types of clicks.
--
-- <b># Notes #</b>
--
-- • The click callback will not trigger if the cursor moves outside the node's
-- area between the pressed and released states.
--
-- • If a button has a double click event subscriber and the double click event is triggered,
-- the regular click callback will not be triggered.
--
-- • Buttons can be triggered using a keyboard key by calling the button:set_key_trigger method.
--
-- • To animate a small icon on a big button panel, you can use an animation node.
-- The trigger node name should be set as "big panel," and the animation node should be set as "small icon."
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_buttons" target="_blank"><b>Example Link</b></a>
-- @usage
-- local function on_button_click(self, args, button)
-- print("Button has clicked with params: " .. args)
-- print("Also the button component is passed in callback params")
-- end
--
-- local custom_args = "Any variable to pass inside callback"
-- local button = self.druid:new_button("button_name", on_button_click, custom_args)
--
-- @module Button -- @module Button
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.button -- @alias druid.button
--- On release button callback(self, params, button_instance)
--- @{DruidEvent}: Event on successful release action over button.
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_click:subscribe(function(self, custom_args, button_instance)
-- print("On button click!")
-- end)
-- @tfield DruidEvent on_click @{DruidEvent} -- @tfield DruidEvent on_click @{DruidEvent}
--- On repeated action button callback(self, params, button_instance, click_amount)
--- @{DruidEvent}: Event on repeated action over button.
--
-- This callback will be triggered if user hold the button. The repeat rate pick from `input.repeat_interval` in game.project
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_repeated_click:subscribe(function(self, custom_args, button_instance, click_count)
-- print("On repeated Button click!")
-- end)
-- @tfield DruidEvent on_repeated_click @{DruidEvent} -- @tfield DruidEvent on_repeated_click @{DruidEvent}
---On long tap button callback(self, params, button_instance, time)
--- @{DruidEvent}: Event on long tap action over button.
--
-- This callback will be triggered if user pressed the button and hold the some amount of time.
-- The amount of time picked from button style param: LONGTAP_TIME
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_long_click:subscribe(function(self, custom_args, button_instance, hold_time)
-- print("On long Button click!")
-- end)
-- @tfield DruidEvent on_long_click @{DruidEvent} -- @tfield DruidEvent on_long_click @{DruidEvent}
---On double tap button callback(self, params, button_instance, click_amount)
--- @{DruidEvent}: Event on double tap action over button.
--
-- If secondary click was too fast after previous one, the double
-- click will be called instead usual click (if on_double_click subscriber exists)
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_double_click:subscribe(function(self, custom_args, button_instance, click_amount)
-- print("On double Button click!")
-- end)
-- @tfield DruidEvent on_double_click @{DruidEvent} -- @tfield DruidEvent on_double_click @{DruidEvent}
---On button hold before long_click callback(self, params, button_instance, time)
--- @{DruidEvent}: Event calls every frame before on_long_click event.
--
-- If long_click subscriber exists, the on_hold_callback will be called before long_click trigger.
--
-- Usecase: Animate button progress of long tap
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_double_click:subscribe(function(self, custom_args, button_instance, time)
-- print("On hold Button callback!")
-- end)
-- @tfield DruidEvent on_hold_callback @{DruidEvent} -- @tfield DruidEvent on_hold_callback @{DruidEvent}
---On click outside of button(self, params, button_instance)
--- @{DruidEvent}: Event calls if click event was outside of button.
--
-- This event will be triggered for each button what was not clicked on user click action
--
-- Usecase: Hide the popup when click outside
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_click_outside:subscribe(function(self, custom_args, button_instance)
-- print("On click Button outside!")
-- end)
-- @tfield DruidEvent on_click_outside @{DruidEvent} -- @tfield DruidEvent on_click_outside @{DruidEvent}
---On pressed button callback(self, params, button_instance)
--- @{DruidEvent}: Event triggered if button was pressed by user.
-- @usage
-- -- Custom args passed in Button constructor
-- button.on_pressed:subscribe(function(self, custom_args, button_instance)
-- print("On Button pressed!")
-- end)
-- @tfield DruidEvent on_pressed @{DruidEvent} -- @tfield DruidEvent on_pressed @{DruidEvent}
---Trigger node --- Button trigger node
-- @tfield node node -- @tfield Node node
---The hash of trigger node ---The GUI node id from button node
-- @tfield node_id hash -- @tfield hash node_id
---Animation node --- Button animation 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.
-- @tfield[opt=node] node anim_node -- @tfield[opt=node] node anim_node
---Initial scale of anim_node ---Custom args for any Button event. Setup in Button constructor
-- @tfield vector3 start_scale
---Initial pos of anim_node
-- @tfield vector3 start_pos
---Initial pos of anim_node
-- @tfield vector3 pos
---Params to click callbacks
-- @tfield any params -- @tfield any params
---Druid hover logic component --- @{Hover}: Button Hover component
-- @tfield Hover hover @{Hover} -- @tfield Hover hover @{Hover}
---Restriction zone --- Additional button click area, defined by another GUI Node
-- @tfield[opt] node click_zone -- @tfield[opt] node click_zone
--- ---
@ -170,7 +251,7 @@ end
--- Component style params. --- Component style params.
-- 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[opt=0.4] number LONGTAP_TIME Minimum time to trigger on_hold_callback
@ -195,13 +276,13 @@ function Button.on_style_change(self, style)
end end
--- Component init function --- @{Button} constructor
-- @tparam Button self @{Button} -- @tparam Button self @{Button}
-- @tparam node node Gui node -- @tparam string|Node node Node name or GUI Node itself
-- @tparam function callback Button callback -- @tparam function callback On click button callback
-- @tparam[opt] table params Button callback params -- @tparam[opt] any custom_args Button events custom arguments
-- @tparam[opt] node anim_node Button anim node (node, if not provided) -- @tparam[opt] string|Node anim_node Node to animate instead of trigger node.
function Button.init(self, node, callback, params, anim_node) function Button.init(self, node, callback, custom_args, anim_node)
self.druid = self:get_druid() self.druid = self:get_druid()
self.node = self:get_node(node) self.node = self:get_node(node)
self.node_id = gui.get_id(self.node) self.node_id = gui.get_id(self.node)
@ -209,7 +290,7 @@ function Button.init(self, node, callback, params, anim_node)
self.anim_node = anim_node and self:get_node(anim_node) or self.node self.anim_node = anim_node and self:get_node(anim_node) or self.node
self.start_scale = gui.get_scale(self.anim_node) self.start_scale = gui.get_scale(self.anim_node)
self.start_pos = gui.get_position(self.anim_node) self.start_pos = gui.get_position(self.anim_node)
self.params = params self.params = custom_args
self.hover = self.druid:new_hover(node, on_button_hover) self.hover = self.druid:new_hover(node, on_button_hover)
self.hover.on_mouse_hover:subscribe(on_button_mouse_hover) self.hover.on_mouse_hover:subscribe(on_button_mouse_hover)
self.click_zone = nil self.click_zone = nil
@ -222,7 +303,7 @@ function Button.init(self, node, callback, params, anim_node)
self._check_function = nil self._check_function = nil
self._failure_callback = nil self._failure_callback = nil
-- Event stubs -- Events
self.on_click = Event(callback) self.on_click = Event(callback)
self.on_pressed = Event() self.on_pressed = Event()
self.on_repeated_click = Event() self.on_repeated_click = Event()
@ -357,10 +438,15 @@ function Button.on_message_input(self, node_id, message)
end end
--- Set enabled button component state --- Set button enabled state.
-- The style.on_set_enabled will be triggered.
-- Disabled button is not clickable.
-- @tparam Button self @{Button} -- @tparam Button self @{Button}
-- @tparam bool state Enabled state -- @tparam bool state Enabled state
-- @treturn Button Current button instance -- @treturn Button Current button instance
-- @usage
-- button:set_enabled(false)
-- button:set_enabled(true)
function Button.set_enabled(self, state) function Button.set_enabled(self, state)
self.disabled = not state self.disabled = not state
self.hover:set_enabled(state) self.hover:set_enabled(state)
@ -370,19 +456,27 @@ function Button.set_enabled(self, state)
end end
--- Return button enabled state --- Get button enabled state.
--
-- By default all Buttons is enabled on creating.
-- @tparam Button self @{Button} -- @tparam Button self @{Button}
-- @treturn bool True, if button is enabled -- @treturn bool True, if button is enabled now, False overwise
-- @usage
-- local is_enabled = button:is_enabled()
function Button.is_enabled(self) function Button.is_enabled(self)
return not self.disabled return not self.disabled
end end
--- Strict button click area. Useful for --- Set additional button click area.
-- no click events outside stencil node -- Useful to restrict click outside out stencil node or scrollable content.
--
-- 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 zone Gui node -- @tparam node zone Gui node
-- @treturn Button Current button instance -- @treturn Button Current button instance
-- @usage
-- button:set_click_zone("stencil_node")
function Button.set_click_zone(self, zone) function Button.set_click_zone(self, zone)
self.click_zone = self:get_node(zone) self.click_zone = self:get_node(zone)
self.hover:set_click_zone(zone) self.hover:set_click_zone(zone)
@ -391,10 +485,12 @@ function Button.set_click_zone(self, zone)
end end
--- Set key-code to trigger this button --- Set key name to trigger this button by keyboard.
-- @tparam Button self @{Button} -- @tparam Button self @{Button}
-- @tparam hash key The action_id of the key -- @tparam hash key The action_id of the input key
-- @treturn Button Current button instance -- @treturn Button Current button instance
-- @usage
-- button:set_key_trigger("key_space")
function Button.set_key_trigger(self, key) function Button.set_key_trigger(self, key)
self.key_trigger = hash(key) self.key_trigger = hash(key)
@ -402,9 +498,11 @@ function Button.set_key_trigger(self, key)
end end
--- Get key-code to trigger this button --- Get current key name to trigger this button.
-- @tparam Button self -- @tparam Button self
-- @treturn hash The action_id of the key -- @treturn hash The action_id of the input key
-- @usage
-- local key_hash = button:get_key_trigger()
function Button.get_key_trigger(self) function Button.get_key_trigger(self)
return self.key_trigger return self.key_trigger
end end
@ -413,7 +511,7 @@ end
--- Set function for additional check for button click availability --- Set function for additional check for button click availability
-- @tparam Button self -- @tparam Button self
-- @tparam[opt] function check_function Should return true or false. If true - button can be pressed. -- @tparam[opt] function check_function Should return true or false. If true - button can be pressed.
-- @tparam[opt] function failure_callback Function what will be called on button click, if check function return false -- @tparam[opt] function failure_callback Function will be called on button click, if check function return false
-- @treturn Button Current button instance -- @treturn Button Current button instance
function Button.set_check_function(self, check_function, failure_callback) function Button.set_check_function(self, check_function, failure_callback)
self._check_function = check_function self._check_function = check_function
@ -421,14 +519,19 @@ function Button.set_check_function(self, check_function, failure_callback)
end end
--- Set buttom click mode to call itself inside html5 callback in user interaction event --- Set Button mode to work inside user HTML5 interaction event.
-- It required to do protected stuff like copy/paste text, show html keyboard, etc --
-- The HTML5 button don't call any events except on_click -- It's required to make protected things like copy & paste text, show mobile keyboard, etc
-- The HTML5 button's doesn't call any events except on_click event.
--
-- If the game is not HTML, html mode will be not enabled
-- @tparam Button self -- @tparam Button self
-- @tparam[opt] boolean is_html_mode If true - button will be called inside html5 callback -- @tparam[opt] boolean is_web_mode If true - button will be called inside html5 callback
-- @treturn Button Current button instance -- @treturn Button Current button instance
function Button.set_html5_user_interaction(self, is_html_mode) -- @usage
self._is_html5_mode = is_html_mode and html5 -- button:set_web_user_interaction(true)
function Button.set_web_user_interaction(self, is_web_mode)
self._is_html5_mode = is_web_mode and html5
return self return self
end end

View File

@ -4,6 +4,8 @@
-- Drag have correct handling for multitouch and swap -- Drag have correct handling for multitouch and swap
-- touched while dragging. Drag will be processed even -- touched while dragging. Drag will be processed even
-- the cursor is outside of node, if drag is already started -- the cursor is outside of node, if drag is already started
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_drag" target="_blank"><b>Example Link</b></a>
-- @module Drag -- @module Drag
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.drag -- @alias druid.drag

View File

@ -1,12 +1,38 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to handle scroll content. --- Component to handle scroll content.
-- Scroll consist from two nodes: scroll parent and scroll input -- <b># Overview #</b>
-- Scroll input the user input zone, it's static --
-- Scroll parent the scroll moving part, it will change position. -- The Scroll component is designed to handle scrollable content and consists of two nodes: the scroll parent and the scroll input.
-- Setup initial scroll size by changing scroll parent size. If scroll parent --
-- size will be less than scroll_input size, no scroll is available. For scroll -- The scroll input represents the user input zone and remains static.
-- parent size should be more than input size --
-- The scroll parent is the movable part of the scroll and changes its position.
--
-- The initial scroll size can be set by adjusting the size of the scroll parent.
-- If the size of the scroll parent is smaller than the scroll input size, scrolling is not available.
--
-- <b># Notes #</b>
--
-- • By default, the scroll style includes inertia and extra size for a stretching effect.
-- These settings can be adjusted using the scroll style settings.
-- For more details, refer to the scroll style settings.
--
-- • "Points of interest" can be set up for the scroll.
-- The scroll will always be centered on the closest point of interest.
-- This feature allows creating a slider without inertia and with points of interest on each scroll element.
--
-- • The scroll content size can be adjusted using the scroll:set_size(node_size) method.
-- This method sets a new size for the _content node.
--
-- • Inertial scrolling mode can be enabled or disabled using the scroll:set_inert(state) method.
--
-- • The extra stretch size can be adjusted using the scroll:set_extra_stretch_size method.
--
-- • Multitouch is required for scrolling. The scroll component correctly handles
-- touch ID swaps while dragging the scroll.
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_scroll" target="_blank"><b>Example Link</b></a>
-- @module Scroll -- @module Scroll
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.scroll -- @alias druid.scroll
@ -132,10 +158,10 @@ function Scroll.on_style_change(self, style)
end end
--- Scroll constructor --- @{Scroll} constructor
-- @tparam Scroll self @{Scroll} -- @tparam Scroll self @{Scroll}
-- @tparam node view_node GUI view scroll node -- @tparam string|node view_node GUI view scroll node
-- @tparam node content_node GUI content scroll node -- @tparam string|node content_node GUI content scroll node
function Scroll.init(self, view_node, content_node) function Scroll.init(self, view_node, content_node)
self.druid = self:get_druid() self.druid = self:get_druid()

View File

@ -1,7 +1,36 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to handle placing components by row and columns. --- Component to handle component's position by row and columns.
-- Grid can anchor your elements, get content size and other -- ## Overview ##
--
-- The Static Grid component allows for positioning components in rows and columns.
-- It provides a static grid layout with constant node sizes, allowing for pre-calculated
-- node positions and the option to include gaps between nodes.
--
-- ## Notes ##
--
-- • In a static grid, the node size remains constant, enabling the calculation of node
-- positions before placement. Nodes can be placed with gaps between them.
--
-- • The static grid can automatically shift elements when nodes are added or removed.
--
-- • When a node is added, the grid will set the node's parent to the specified parent_node.
--
-- • You can obtain an array of positions for each element, which can be used to set
-- points of interest in a scroll component.
--
-- • The size of all elements can be retrieved for setting up the size in a scroll component.
--
-- • The grid can be bound to a scroll component for automatic resizing of the scroll content size.
--
-- • The pivot of the parent_node affects the node placement within the grid.
--
-- • A prefab node is used to determine the node size and anchor.
--
-- • You can specify a position_function for animations using the
-- _static_grid:set_position_function(node, pos) callback. The default position function is gui.set_position().
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_grid" target="_blank"><b>Example Link</b></a>
-- @module StaticGrid -- @module StaticGrid
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.static_grid -- @alias druid.static_grid
@ -81,9 +110,9 @@ function StaticGrid.on_style_change(self, style)
end end
--- Component init function --- @{StaticGrid} constructor
-- @tparam StaticGrid self @{StaticGrid} -- @tparam StaticGrid self @{StaticGrid}
-- @tparam node parent The gui node parent, where 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[opt=1] number in_row How many nodes in row can be placed
function StaticGrid.init(self, parent, element, in_row) function StaticGrid.init(self, parent, element, in_row)

View File

@ -1,8 +1,36 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to handle all GUI texts. --- Component for Wrapping GUI Text Nodes: Druid Text
-- Druid text can adjust itself for text node size --
-- Text will never will be outside of his text size (even multiline) -- ## Overview ##
--
-- Druid Text is a component that provides various adjustment modes for text nodes. It allows text to be scaled down to fit within the size of the text node.
--
-- ## Notes ##
--
-- • The text pivot can be changed using the text:set_pivot method.
-- The anchoring will be inside the text node's area size.
--
-- • There are several text adjustment types available. The default is DOWNSCALE.
-- You can change the default adjustment type in the Text style. Refer to the example below to see all available adjustment types:
--
-- - const.TEXT_ADJUST.DOWNSCALE: Changes the text's scale to fit within the text node's size.
--
-- - const.TEXT_ADJUST.TRIM: Trims the text with a postfix (default: "...", can be overridden in styles)
-- to fit within the text node's size.
--
-- - const.TEXT_ADJUST.NO_ADJUST: No adjustment is applied, similar
-- to the default Defold Text Node behavior.
--
-- - const.TEXT_ADJUST.DOWNSCALE_LIMITED: Changes the text's scale
-- with a limited downscale. You can set the minimum scale using the text:set_minimal_scale() function.
--
-- - const.TEXT_ADJUST.SCROLL: Changes the text's pivot to imitate scrolling within the text box.
-- For better effect, use with a stencil node.
--
-- - const.TEXT_ADJUST.SCALE_THEN_SCROLL: Combines two modes: limited downscale first, then scroll.
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=texts_general" target="_blank"><b>Example Link</b></a>
-- @module Text -- @module Text
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.text -- @alias druid.text
@ -188,11 +216,11 @@ function Text.on_style_change(self, style)
end end
--- Component init function --- @{Text} constructor
-- @tparam Text self @{Text} -- @tparam Text self @{Text}
-- @tparam node node Gui text node -- @tparam string|node node Node name or GUI Text Node itself
-- @tparam[opt] string value Initial text. Default value is node text from GUI scene. -- @tparam[opt] string value Initial text. Default value is node text from GUI scene.
-- @tparam[opt=0] int adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference -- @tparam[opt=downscale] string adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
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)

View File

@ -64,7 +64,7 @@ BaseComponent.SPECIFIC_UI_MESSAGES = {
local uid = 0 local uid = 0
function BaseComponent.static.get_uid() function BaseComponent.create_uid()
uid = uid + 1 uid = uid + 1
return uid return uid
end end
@ -128,7 +128,7 @@ end
--- Set current component nodes --- Set current component nodes
-- --
-- Used if your component nodes was cloned with `gui.clone_tree` -- Use if your component nodes was cloned with `gui.clone_tree` and you got the node tree.
-- @function component:set_nodes -- @function component:set_nodes
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @tparam table nodes BaseComponent nodes table -- @tparam table nodes BaseComponent nodes table
@ -226,7 +226,7 @@ end
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @treturn string The component name -- @treturn string The component name
function BaseComponent.get_name(self) function BaseComponent.get_name(self)
return self._component.name .. self:get_uid() return self._component.name .. BaseComponent.create_uid()
end end
@ -362,7 +362,7 @@ end
--- Basic constructor of component. It will call automaticaly --- Basic constructor of component. It will call automaticaly
-- by `BaseComponent.static.create` -- by `BaseComponent.create`
-- @function component:initialize -- @function component:initialize
-- @tparam BaseComponent self @{BaseComponent} -- @tparam BaseComponent self @{BaseComponent}
-- @tparam string name BaseComponent name -- @tparam string name BaseComponent name
@ -375,7 +375,7 @@ function BaseComponent.initialize(self, name, input_priority)
default_input_priority = input_priority or const.PRIORITY_INPUT, default_input_priority = input_priority or const.PRIORITY_INPUT,
is_debug = false, is_debug = false,
_is_input_priority_changed = true, -- Default true for sort once time after GUI init _is_input_priority_changed = true, -- Default true for sort once time after GUI init
_uid = BaseComponent.get_uid() _uid = BaseComponent.create_uid()
} }
end end
@ -512,11 +512,11 @@ end
--- Create new component. It will inheritance from basic Druid component. --- Create new component. It will inheritance from basic Druid component.
-- @function BaseComponent.static.create -- @function BaseComponent.create
-- @tparam string name BaseComponent name -- @tparam string name BaseComponent name
-- @tparam[opt=DEFAULT] number input_priority The input priority. The bigger number processed first -- @tparam[opt=DEFAULT] number input_priority The input priority. The bigger number processed first
-- @local -- @local
function BaseComponent.static.create(name, input_priority) function BaseComponent.create(name, input_priority)
-- Yea, inheritance here -- Yea, inheritance here
local new_class = class(name, BaseComponent) local new_class = class(name, BaseComponent)

View File

@ -52,7 +52,6 @@ M.MESSAGE_INPUT = {
BUTTON_LONG_CLICK = "button_long_click", BUTTON_LONG_CLICK = "button_long_click",
BUTTON_DOUBLE_CLICK = "button_double_click", BUTTON_DOUBLE_CLICK = "button_double_click",
BUTTON_REPEATED_CLICK = "button_repeated_click", BUTTON_REPEATED_CLICK = "button_repeated_click",
-- (value)
TEXT_SET = "text_set", TEXT_SET = "text_set",
} }

View File

@ -449,9 +449,9 @@ function M.set_text_scale(words, settings, scale)
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 lines_metrics rich_text.lines_metrics ---@param lines_metrics druid.rich_text.lines_metrics
function M.adjust_to_area(words, settings, lines_metrics) function M.adjust_to_area(words, settings, lines_metrics)
local last_line_metrics = lines_metrics local last_line_metrics = lines_metrics
@ -486,7 +486,7 @@ function M.adjust_to_area(words, settings, lines_metrics)
end end
adjust_scale = adjust_scale + step adjust_scale = adjust_scale + step
local lines = M.apply_scale_without_update(words, settings, adjust_scale) lines = M.apply_scale_without_update(words, settings, adjust_scale)
is_fit = M.is_fit_info_area(lines, settings) is_fit = M.is_fit_info_area(lines, settings)
if i == M.ADJUST_STEPS then if i == M.ADJUST_STEPS then
@ -534,52 +534,6 @@ function M.tagged(words, tag)
end end
--- Split a word into it's characters
-- @param word The word to split
-- @return The individual characters
function M.characters(word)
assert(word)
local parent = gui.get_parent(word.node)
local font = gui.get_font(word.node)
local layer = gui.get_layer(word.node)
local pivot = gui.get_pivot(word.node)
local word_length = utf8.len(word.text)
-- exit early if word is a single character or empty
if word_length <= 1 then
local char = helper.deepcopy(word)
char.node, char.metrics = create_node(char, parent, font)
gui.set_pivot(char.node, pivot)
gui.set_position(char.node, gui.get_position(word.node))
gui.set_layer(char.node, layer)
return { char }
end
-- split word into characters
local chars = {}
local position = gui.get_position(word.node)
local position_x = position.x
for i = 1, word_length do
local char = helper.deepcopy(word)
chars[#chars + 1] = char
char.text = utf8.sub(word.text, i, i)
char.node, char.metrics = create_node(char, parent, font)
gui.set_layer(char.node, layer)
gui.set_pivot(char.node, pivot)
local sub_metrics = get_text_metrics(word, font, utf8.sub(word.text, 1, i))
position.x = position_x + sub_metrics.width - char.metrics.width
char.position = vmath.vector3(position)
gui.set_position(char.node, char.position)
end
return chars
end
---Removes the gui nodes created by rich text ---Removes the gui nodes created by rich text
function M.remove(words) function M.remove(words)
assert(words) assert(words)

View File

@ -1,6 +1,89 @@
-- Copyright (c) 2022 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2022 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid Rich Text custom component. --- Druid Rich Text Custom Component.
-- <b># Overview #</b>
--
-- 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.
--
-- All parameters for the Rich Text component are adjusted in the GUI scene.
--
-- 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>
--
-- • Nested tags are supported
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=custom_rich_text" target="_blank"><b>Example Link</b></a>
-- @usage
-- local RichText = require("druid.custom.rich_text.rich_text")
-- ...
-- self.rich_text = self.druid:new(RichText, "rich_text")
-- self.rich_text:set_text("Hello, Druid Rich Text!")
-- @usage
-- type druid.rich_text.word = {
-- node: Node,
-- relative_scale: number,
-- color: vector4,
-- position: vector3,
-- offset: vector3,
-- scale: vector3,
-- size: vector3,
-- metrics: druid.rich_text.metrics,
-- pivot: Pivot,
-- text: string,
-- shadow: vector4,
-- outline: vector4,
-- font: string,
-- image: druid.rich_text.image,
-- default_animation: string,
-- anchor: number,
-- br: boolean,
-- nobr: boolean,
-- }
--
-- type druid.rich_text.word.image = {
-- texture: string,
-- anim: string,
-- width: number,
-- height: number,
-- }
--
-- type druid.rich_text.lines_metrics = {
-- text_width: number,
-- text_height: number,
-- lines: table<number, druid.rich_text.metrics>,
-- }
--
-- type druid.rich_text.metrics = {
-- width: number,
-- height: number,
-- offset_x: number|nil,
-- offset_y: number|nil,
-- node_size: vector3|nil @For images only,
-- }
-- @module RichText -- @module RichText
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.rich_text -- @alias druid.rich_text
@ -21,7 +104,11 @@ local SCHEME = {
} }
function RichText:init(template, nodes) --- Rich Text component constructor
-- @tparam RichText self @{RichText}
-- @tparam string template The Rich Text template name
-- @tparam table nodes The node table, if prefab was copied by gui.clone_tree()
function RichText.init(self, template, nodes)
self:set_template(template) self:set_template(template)
self:set_nodes(nodes) self:set_nodes(nodes)
@ -38,7 +125,55 @@ function RichText:init(template, nodes)
end end
function RichText:set_text(text) --- Set text for Rich Text
-- @tparam RichText self @{RichText}
-- @tparam string text The text to set
-- @treturn druid.rich_text.word[] words
-- @treturn druid.rich_text.lines_metrics line_metrics
-- @usage
-- • color: Change text color
--
-- <color=red>Foobar</color>
-- <color=1.0,0,0,1.0>Foobar</color>
-- <color=#ff0000>Foobar</color>
-- <color=#ff0000ff>Foobar</color>
--
-- • shadow: Change text shadow
--
-- <shadow=red>Foobar</shadow>
-- <shadow=1.0,0,0,1.0>Foobar</shadow>
-- <shadow=#ff0000>Foobar</shadow>
-- <shadow=#ff0000ff>Foobar</shadow>
--
-- • outline: Change text shadow
--
-- <outline=red>Foobar</outline>
-- <outline=1.0,0,0,1.0>Foobar</outline>
-- <outline=#ff0000>Foobar</outline>
-- <outline=#ff0000ff>Foobar</outline>
--
-- • font: Change font
--
-- <font=MyCoolFont>Foobar</font>
--
-- • size: Change text size, relative to default size
--
-- <size=2>Twice as large</size>
--
-- • br: Insert a line break
--
-- <br/>
--
-- • nobr: Prevent the text from breaking
--
-- Words <nobr>inside tag</nobr> won't break
--
-- • img: Display image
--
-- <img=texture:image/>
-- <img=texture:image,size/>
-- <img=texture:image,width,height/>
function RichText.set_text(self, text)
self:clean() self:clean()
local words, settings, line_metrics = rich_text.create(text, self._settings) local words, settings, line_metrics = rich_text.create(text, self._settings)
@ -56,6 +191,9 @@ function RichText:on_remove()
end end
--- Get all words, which has a passed tag
-- @tparam string tag
-- @treturn table Words
function RichText:tagged(tag) function RichText:tagged(tag)
if not self._words then if not self._words then
return return
@ -65,6 +203,8 @@ function RichText:tagged(tag)
end end
--- Get all current words.
-- @treturn table Words
function RichText:get_words() function RichText:get_words()
return self._words return self._words
end end
@ -99,6 +239,7 @@ function RichText:_create_settings()
end end
--- Clear all created words.
function RichText:clean() function RichText:clean()
if self._words then if self._words then
rich_text.remove(self._words) rich_text.remove(self._words)

View File

@ -1,15 +1,15 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid UI Component Framework. --- Druid UI Component Framework.
-- # Overview # -- <b># Overview #</b>
-- --
-- Druid - powerful Defold component UI library. Use basic and extended -- Druid - powerful Defold component UI library. Use basic and extended
-- Druid components or make your own game-specific components to make -- Druid components or make your own game-specific components to make
-- amazing GUI in your games. -- amazing GUI in your games.
-- --
-- To start using Druid, please refer to the Basic Usage section below. -- To start using Druid, please refer to the Usage section below.
-- --
-- # Tech Info # -- <b># Notes #</b>
-- --
-- • Each Druid instance maintains the self context from the constructor and passes it to each Druid callback. -- • Each Druid instance maintains the self context from the constructor and passes it to each Druid callback.
-- --

View File

@ -1,9 +1,10 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid Event module. --- Druid Event Module
-- --
-- Event is a simple class to handle callbacks. It's used in many Druid components. -- The Event module provides a simple class for handling callbacks. It is used in many Druid components.
-- You can subscribe to event with `:subscribe` method and unsubscribe with `:unsubscribe`. --
-- You can subscribe to an event using the `:subscribe` method and unsubscribe using the `:unsubscribe` method.
-- @module DruidEvent -- @module DruidEvent
-- @alias druid.event -- @alias druid.event

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid checkbox component --- Druid checkbox component
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_checkboxes" target="_blank"><b>Example Link</b></a>
-- @module Checkbox -- @module Checkbox
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.checkbox -- @alias druid.checkbox

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Checkbox group module --- Checkbox group module
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_checkboxes" target="_blank"><b>Example Link</b></a>
-- @module CheckboxGroup -- @module CheckboxGroup
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.checkbox_group -- @alias druid.checkbox_group

View File

@ -2,6 +2,8 @@
--- Component to manage data for huge dataset in scroll. --- Component to manage data for huge dataset in scroll.
-- It requires Druid Scroll and Druid Grid (Static or Dynamic) components -- It requires Druid Scroll and Druid Grid (Static or Dynamic) components
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_data_list" target="_blank"><b>Example Link</b></a>
-- @module DataList -- @module DataList
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.data_list -- @alias druid.data_list

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to handle placing components in row --- Component to handle placing components in row
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_grid" target="_blank"><b>Example Link</b></a>
-- @module DynamicGrid -- @module DynamicGrid
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.dynamic_grid -- @alias druid.dynamic_grid

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid hotkey component --- Druid hotkey component
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_hotkey" target="_blank"><b>Example Link</b></a>
-- @module Hotkey -- @module Hotkey
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.hotkey -- @alias druid.hotkey

View File

@ -2,6 +2,8 @@
--- Druid input text component. --- Druid input text component.
-- Carry on user text input -- Carry on user text input
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_input" target="_blank"><b>Example Link</b></a>
-- @author Part of code from Britzl gooey input component -- @author Part of code from Britzl gooey input component
-- @module Input -- @module Input
-- @within BaseComponent -- @within BaseComponent
@ -115,7 +117,7 @@ end
--- Component init function --- Component init function
-- @tparam Input self @{Input} -- @tparam Input self @{Input}
-- @tparam node click_node Button node to enabled input component -- @tparam node click_node Node to enabled input component
-- @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[opt] number keyboard_type Gui keyboard type for input field -- @tparam[opt] number 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)

View File

@ -1,7 +1,18 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Component to handle all GUI texts --- Component to wrap over GUI Text nodes with localization helpers
-- Good working with localization system --
-- <b># Overview #</b>
--
-- • The initialization of druid.set_text_function is required to enable localization
-- using the localization ID.
--
-- • The LangText component supports up to 7 string format parameters.
-- This limitation exists due to certain issues with using ... arguments.
--
-- <b># Notes #</b>
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=texts_lang_text" target="_blank"><b>Example Link</b></a>
-- @module LangText -- @module LangText
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.lang_text -- @alias druid.lang_text
@ -21,14 +32,14 @@ local component = require("druid.component")
local LangText = component.create("lang_text") local LangText = component.create("lang_text")
--- Component init function --- @{LangText} constructor
-- @tparam LangText self @{LangText} -- @tparam LangText self @{LangText}
-- @tparam node node The text node -- @tparam string|node node Node name or GUI Text Node itself
-- @tparam string locale_id Default locale id or text from node as default -- @tparam string locale_id Default locale id or text from node as default
-- @tparam bool no_adjust If true, will not correct text size -- @tparam[opt=downscale] string adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
function LangText.init(self, node, locale_id, no_adjust) 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, no_adjust) self.text = self.druid:new_text(node, locale_id, adjust_type)
self.node = self.text.node self.node = self.text.node
self.last_locale_args = {} self.last_locale_args = {}

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Layout management on node --- Layout management on node
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_layout" target="_blank"><b>Example Link</b></a>
-- @module Layout -- @module Layout
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.layout -- @alias druid.layout

View File

@ -1,7 +1,20 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Basic progress bar component. --- Druid component to handle the progress bars.
-- For correct progress bar init it should be in max size from gui -- <b># Overview #</b>
--
-- <b># Notes #</b>
--
-- • Progress Node should be fully filled in your GUI scene node. It will be the progress maximum size
--
-- • Progress correct working with Slice9 nodes, it trying to set size by _set_size_ first, if it is not possible, it set up sizing via _set_scale_
--
-- • Progress bar can fill only by vertical or horizontal size. If you want make diagonal progress bar, just rotate node in GUI scene
--
-- • If you have glitchy or dark texture bug with progress bar, try to disable mipmaps in your texture profiles
--
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_progress_bar" target="_blank"><b>Example Link</b></a>
-- @module Progress -- @module Progress
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.progress -- @alias druid.progress
@ -12,7 +25,9 @@
--- Progress bar fill node --- Progress bar fill node
-- @tfield node node -- @tfield node node
--- The progress bar direction --- The progress bar direction.
--
-- The values are: "x" or "y". (const.SIDE.X or const.SIDE.Y)
-- @tfield string key -- @tfield string key
--- Current progress bar scale --- Current progress bar scale
@ -95,16 +110,16 @@ function Progress.on_style_change(self, style)
end end
--- Component init function --- @{Progress} constructor
-- @tparam Progress self @{Progress} -- @tparam Progress self @{Progress}
-- @tparam string|node node Progress bar fill node or node name -- @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[opt=1] number init_value Initial value of progress bar
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'")
self.prop = hash("scale."..key)
self.key = key self.key = key
self.prop = hash("scale." .. self.key)
self._init_value = init_value or 1 self._init_value = init_value or 1
self.node = self:get_node(node) self.node = self:get_node(node)
@ -114,7 +129,7 @@ function Progress.init(self, node, key, init_value)
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 key == const.SIDE.X then if self.key == const.SIDE.X then
self.slice_size = self.slice.x + self.slice.z self.slice_size = self.slice.x + self.slice.z
else else
self.slice_size = self.slice.y + self.slice.w self.slice_size = self.slice.y + self.slice.w

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Radio group module --- Radio group module
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_checkboxes" target="_blank"><b>Example Link</b></a>
-- @module RadioGroup -- @module RadioGroup
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.radio_group -- @alias druid.radio_group

View File

@ -1,6 +1,8 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Druid slider component --- Druid slider component
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_sliders" target="_blank"><b>Example Link</b></a>
-- @module Slider -- @module Slider
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.slider -- @alias druid.slider

View File

@ -3,6 +3,8 @@
--- Component to handle swipe gestures on node. --- Component to handle swipe gestures on node.
-- Swipe will be triggered, if swipe was started and -- Swipe will be triggered, if swipe was started and
-- ended on one node -- ended on one node
--
-- <a href="https://insality.github.io/druid/druid/index.html?example=general_swipe" target="_blank"><b>Example Link</b></a>
-- @module Swipe -- @module Swipe
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.swipe -- @alias druid.swipe

View File

@ -1,12 +1,16 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license -- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Helper module with various usefull GUI functions. --- Helper module with various usefull GUI functions.
-- @usage
-- local helper = require("druid.helper")
-- helper.centrate_nodes(0, node_1, node_2)
-- @module Helper -- @module Helper
-- @alias druid.helper -- @alias druid.helper
local const = require("druid.const") local const = require("druid.const")
local M = {} local M = {}
M._some = { pepepe = true }
local function get_text_width(text_node) local function get_text_width(text_node)
@ -390,7 +394,14 @@ end
--- Get text metric from GUI node. --- Get text metric from GUI node.
-- @function helper.get_text_metrics_from_node -- @function helper.get_text_metrics_from_node
-- @tparam Node text_node -- @tparam Node text_node
-- @treturn GUITextMetrics Fields: width, height, max_ascent, max_descent -- @treturn pepepe
-- @usage
-- type GUITextMetrics = {
-- width: number,
-- height: number,
-- max_ascent: number,
-- max_descent: number
-- }
function M.get_text_metrics_from_node(text_node) function M.get_text_metrics_from_node(text_node)
local font_resource = gui.get_font_resource(gui.get_font(text_node)) local font_resource = gui.get_font_resource(gui.get_font(text_node))
local options = { local options = {

View File

@ -150,7 +150,41 @@ M["text"] = {
M["hotkey"] = { M["hotkey"] = {
MODIFICATORS = { "key_lshift", "key_rshift", "key_lctrl", "key_rctrl", "key_lalt", "key_ralt", "key_lsuper", "key_rsuper" }, -- Add key ids to mark it as modificator keys -- Add key ids to mark it as modificator keys
MODIFICATORS = {
"key_lshift",
"key_rshift",
"key_lctrl",
"key_rctrl",
"key_lalt",
"key_ralt",
"key_lsuper",
"key_rsuper"
}
}
M["rich_text"] = {
COLORS = {
white = "#FFFFFF",
black = "#000000",
red = "#FF0000",
green = "#00FF00",
blue = "#0000FF",
yellow = "#FFFF00",
magenta = "#FF00FF",
cyan = "#00FFFF",
gray = "#808080",
dark_gray = "#404040",
light_gray = "#C0C0C0",
orange = "#FFA500",
pink = "#FFC0CB",
purple = "#800080",
brown = "#A52A2A",
olive = "#808000",
teal = "#008080",
navy = "#000080",
}
} }

View File

@ -6,7 +6,7 @@
-- --
-- For a list of all available components, please refer to the "See Also" section. -- For a list of all available components, please refer to the "See Also" section.
-- --
-- # Notes # -- <b># Notes #</b>
-- --
-- Please review the following API pages: -- Please review the following API pages:
-- --
@ -43,27 +43,29 @@
-- --
-- @module DruidInstance -- @module DruidInstance
-- @alias druid_instance -- @alias druid_instance
-- @see Button
-- @see Blocker
-- @see BackHandler -- @see BackHandler
-- @see Input -- @see Blocker
-- @see Text -- @see Button
-- @see LangText
-- @see Timer
-- @see Progress
-- @see StaticGrid
-- @see DynamicGrid
-- @see Scroll
-- @see Slider
-- @see Checkbox -- @see Checkbox
-- @see CheckboxGroup -- @see CheckboxGroup
-- @see RadioGroup
-- @see Swipe
-- @see Drag
-- @see DataList -- @see DataList
-- @see Hover -- @see Drag
-- @see Layout -- @see DynamicGrid
-- @see Hotkey -- @see Hotkey
-- @see Hover
-- @see Input
-- @see LangText
-- @see Layout
-- @see Progress
-- @see RadioGroup
-- @see RichInput
-- @see RichText
-- @see Scroll
-- @see Slider
-- @see StaticGrid
-- @see Swipe
-- @see Text
-- @see Timer
local helper = require("druid.helper") local helper = require("druid.helper")
local class = require("druid.system.middleclass") local class = require("druid.system.middleclass")
@ -288,7 +290,7 @@ function DruidInstance.final(self)
end end
--- Remove component from Druid instance. --- Remove created component from Druid instance.
-- --
-- Component `on_remove` function will be invoked, if exist. -- Component `on_remove` function will be invoked, if exist.
-- @tparam DruidInstance self -- @tparam DruidInstance self

View File

@ -85,7 +85,7 @@ local function init_top_panel(self)
gui.set_enabled(self.button_menu.node, false) gui.set_enabled(self.button_menu.node, false)
self.button_api = self.druid:new_button("button_api/button", function() self.button_api = self.druid:new_button("button_api/button", function()
sys.open_url("https://insality.github.io/druid/") sys.open_url("https://insality.github.io/druid/modules/Druid.html")
end) end)
self.button_code = self.druid:new_button("button_code/button", function() self.button_code = self.druid:new_button("button_code/button", function()
@ -311,5 +311,5 @@ end
function on_input(self, action_id, action) function on_input(self, action_id, action)
self.druid:on_input(action_id, action) return self.druid:on_input(action_id, action)
end end

BIN
media/emmy_lua_preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB