diff --git a/.defignore b/.defignore
index 3e22129..9447348 100644
--- a/.defignore
+++ b/.defignore
@@ -1 +1,2 @@
-/dist
\ No newline at end of file
+/dist
+/.deployer_cache
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 690997a..6dced02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,6 @@ deployer_version_settings.txt
.deployer_cache
bob*.jar
manifest.private.der
-manifest.public.der
\ No newline at end of file
+manifest.public.der
+/.editor_settings
+/.deployer_cache
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 28a4386..4c7b95d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -29,7 +29,7 @@
"utils/annotations_manual.lua"
],
"Lua.runtime.pathStrict": true,
- "Lua.diagnostics.libraryFiles": "Enable",
+ "Lua.diagnostics.libraryFiles": "Disable",
"Lua.runtime.version": "Lua 5.1",
"Lua.workspace.library": [
"~/Library/Application Support/Code/User/globalStorage/astronachos.defold",
diff --git a/README.md b/README.md
index 143999f..c79373d 100644
--- a/README.md
+++ b/README.md
@@ -17,13 +17,15 @@ In this example you can inspect a variety of **Druid** components and see how th
## Setup
-### Dependency
+### [Dependency](https://www.defold.com/manuals/libraries/)
-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:
+Open your `game.project` file and add the following line to the dependencies field under the project section:
-**Druid v1.0**
+**[Druid](https://github.com/Insality/druid/archive/refs/tags/1.0.zip)**
-> [https://github.com/Insality/druid/archive/refs/tags/1.0.zip](https://github.com/Insality/druid/archive/refs/tags/1.0.zip)
+```
+https://github.com/Insality/druid/archive/refs/tags/1.0.zip
+```
Here is a list of [all releases](https://github.com/Insality/druid/releases).
@@ -87,12 +89,60 @@ end
function on_input(self, action_id, action)
return self.druid:on_input(action_id, action)
end
-
```
For all **Druid** instance functions, [see here](https://insality.github.io/druid/modules/DruidInstance.html).
+### Default GUI Script
+
+Put the following code in your GUI script to start using **Druid**.
+
+```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_message(self, message_id, message, sender)
+ self.druid:on_message(message_id, message, sender)
+end
+
+function on_input(self, action_id, action)
+ return self.druid:on_input(action_id, action)
+end
+```
+
+
+### Default Widget Template
+
+Create a new lua file to create a new widget class. This widget can be created with `self.druid:new_widget(widget_class, [template], [nodes])`
+
+```lua
+local M = {}
+
+function M:init()
+ self.root = self:get_node("root")
+ self.button = self.druid:new_button("button", self.on_click)
+end
+
+function M:on_click()
+ print("Button clicked!")
+end
+
+return M
+```
+
+
### API Documentation
**Druid** offers a wide range of components and functions. To facilitate usage, **Druid** provides comprehensive API documentation with examples and annotations.
@@ -119,45 +169,38 @@ Here is full **Druid** components list.
| Name | Description | Example |
Preview
|
|------|-------------|---------|---------|
-| **[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) | |
-| **[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) | |
-| **[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) | |
-| **[Blocker](https://insality.github.io/druid/modules/Blocker.html)** | Logic over GUI Node. Don't pass any user input below node area size. | [Blocker Example](https://insality.github.io/druid/druid/?example=timer) | |
-| **[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 | [Back Handler Example](https://insality.github.io/druid/druid/?example=timer) | |
-| **[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) | |
-| **[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. | [Hover Example](https://insality.github.io/druid/druid/?example=timer) | |
-| **[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) | |
-| **[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) | |
+| **[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=ui_example_basic_button) | |
+| **[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=ui_example_basic_text) | |
+| **[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=ui_example_basic_scroll) | |
+| **[Blocker](https://insality.github.io/druid/modules/Blocker.html)** | Logic over GUI Node. Don't pass any user input below node area size. | [Blocker Example](https://insality.github.io/druid/druid/?example=ui_example_basic_blocker) | |
+| **[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 | [Back Handler Example](https://insality.github.io/druid/druid/?example=ui_example_basic_back_handler) | |
+| **[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=ui_example_basic_grid) | |
+| **[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. | [Hover Example](https://insality.github.io/druid/druid/?example=ui_example_basic_hover) | |
+| **[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=ui_example_basic_swipe) | |
+| **[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=ui_example_basic_drag) | |
### Extended components
-> Extended components before usage should be registered in **Druid** with [`druid.register()`](https://insality.github.io/druid/modules/Druid.html#druid.register) function.
-> On usage of unregistered **Druid** component the next log will be shown in the console.
-```
-local data_list = require("druid.extended.data_list")
-druid.register("data_list", data_list)
-```
-
| Name | Description | Example |
Preview
|
|------|-------------|---------|---------|
-| **[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) | |
-| **[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) | |
-| **[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` | [Lang Text Example](https://insality.github.io/druid/druid/?example=timer) | |
-| **[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) | |
-| **[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) | |
-| **[Timer](https://insality.github.io/druid/modules/Timer.html)** | Logic over GUI Text. Handle basic timer functions. | [Timer Example](https://insality.github.io/druid/druid/?example=timer) | |
-| **[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) | |
-| **[Layout](https://insality.github.io/druid/modules/Layout.html)** | Logic over GUI Node. Arrange nodes inside layout node with margin/paddings settings. | [Layout Example](https://insality.github.io/druid/druid/?example=general_layout) | |
-| **[Rich Input](https://insality.github.io/druid/modules/RichInput.html)** | Logic over GUI Node and GUI Text (or Text component). Provides rich text input with different styles and text formatting. | [Rich Input Example](https://insality.github.io/druid/druid/?example=general_rich_input) | |
-| **[Rich Text](https://insality.github.io/druid/modules/RichText.html)** | Logic over GUI Text. Provides rich text formatting with different styles and text formatting. | [Rich Text Example](https://insality.github.io/druid/druid/?example=general_rich_text) | |
+| **[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=ui_example_data_list_basic) | |
+| **[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=ui_example_basic_input) | |
+| **[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` | [Lang Text Example](https://insality.github.io/druid/druid/?example=ui_example_window_language) | |
+| **[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=ui_example_basic_progress_bar) | |
+| **[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=ui_example_basic_slider) | |
+| **[Timer](https://insality.github.io/druid/modules/Timer.html)** | Logic over GUI Text. Handle basic timer functions. | [Timer Example](https://insality.github.io/druid/druid/?example=ui_example_basic_timer) | |
+| **[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=ui_example_basic_hotkey) | |
+| **[Layout](https://insality.github.io/druid/modules/Layout.html)** | Logic over GUI Node. Arrange nodes inside layout node with margin/paddings settings. | [Layout Example](https://insality.github.io/druid/druid/?example=ui_example_layout_basic) | |
+| **[Rich Input](https://insality.github.io/druid/modules/RichInput.html)** | Logic over GUI Node and GUI Text (or Text component). Provides rich text input with different styles and text formatting. | [Rich Input Example](https://insality.github.io/druid/druid/?example=ui_example_basic_rich_input) | |
+| **[Rich Text](https://insality.github.io/druid/modules/RichText.html)** | Logic over GUI Text. Provides rich text formatting with different styles and text formatting. | [Rich Text Example](https://insality.github.io/druid/druid/?example=ui_example_basic_rich_text) | |
For a complete overview, see: **_[components.md](docs_md/01-components.md)_**.
## 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 these events with the following API:
+Any **Druid** components as callbacks use [Druid Events](https://insality.github.io/druid/modules/druid.event.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)
diff --git a/config.ld b/config.ld
deleted file mode 100644
index a487ec9..0000000
--- a/config.ld
+++ /dev/null
@@ -1,18 +0,0 @@
-project='Druid'
-title='Defold Druid UI Framework'
-description='Documentation for Druid Framework'
-file={"./druid",
- exclude = {
- "./druid/styles/",
- "./druid/templates/",
- "./druid/annotations.lua",
- "./druid/custom/rich_text/module",
- }
-}
-package='druid'
-sort=true
-dir='./docs'
-style='!fixed'
-topics={}
-use_markdown_titles=true
-no_space_before_args=true
diff --git a/docs_md/01-components.md b/docs_md/01-components.md
index 6aa0735..ce33f02 100644
--- a/docs_md/01-components.md
+++ b/docs_md/01-components.md
@@ -216,7 +216,7 @@ Static grid have constant node size, so it possible to calculate node positions
Static grid can shift elements on add/remove functions.
### Setup
-Create component with druid: `grid = druid:new_static_grid(parent_node, prefab_node, max_in_row_elements)`
+Create component with druid: `grid = druid:new_grid(parent_node, prefab_node, max_in_row_elements)`
### Notes
- On _add node_ grid will set nodeup parent to _parent_node_
@@ -227,33 +227,6 @@ Create component with druid: `grid = druid:new_static_grid(parent_node, prefab_
- _Prefab node_ used to get node size and anchor
- You can point *position_function* for animations with _static_grid:set_position_function(node, pos)_ callback. Default - *gui.set_position()*
-
-## Dynamic Grid
-[Dynamic Grid API here](https://insality.github.io/druid/modules/DynamicGrid.html)
-
-### Overview
-Component for manage node positions with different node sizes.
-Unlike Static Grid, Dynamic Grid can place nodes only in one row or in one column.
-Dynamic Grid can't have gaps between elements
-- you will get error, if try spawn element far away from others.
-Dynamic Grid should have __West__, __East__, __South__ or __North__ pivot (vertical or horizontal element placement)
-
-### Setup
-Create component with druid: `grid = druid:new_dynamic_grid(parent_node)`
-
-Check the _parent_node_ have correct pivot point. You will get the error otherwise.
-
-### Notes
-- On _add node_ grid will set node parent to _parent_node_
-- You can get array of position of every element for setup points of interest in scroll component
-- You can get size of all elements for setup size in scroll component
-- You can also bind the grid to the scroll component for auto resize scroll content size
-- Pivot of parent_node matter for node placement
-- You can point *position_function* for animations with _static_grid:set_position_function(node, pos)_ callback. Default - *gui.set_position()*
-- First node placed at Grid pivot point. Other nodes placed nearby of other nodes.
-- On *add/remove* nodes always shifted. You can point the shift side in this functions (*is_shift_left* boolean argumentp
-
-
## Data List
[Data List API here](https://insality.github.io/druid/modules/DataList.html)
diff --git a/docs_md/02-creating_custom_components.md b/docs_md/02-creating_custom_components.md
index 45e5a6b..bdb1ea9 100644
--- a/docs_md/02-creating_custom_components.md
+++ b/docs_md/02-creating_custom_components.md
@@ -148,7 +148,6 @@ Available keywords:
- `text`: Adds a [Druid Text](01-components.md#text) component.
- `lang_text`: Adds a [Druid Lang Text](01-components.md#lang-text) component.
- `grid` or `static_grid`: Adds a [Druid Static Grid](01-components.md#static-grid) component. You should set up the Grid prefab for this component after generating the file.
-- `dynamic_grid`: Adds a [Druid Dynamic Grid](01-components.md#dynamic-grid) component.
- `scroll_view`: Adds a [Druid Scroll](01-components.md#scroll) component. It also adds a `scroll_content` node with the same postfix. Ensure that it's the correct node.
- `blocker`: Adds a [Druid Blocker](01-components.md#blocker) component.
- `slider`: Adds a [Druid Slider](01-components.md#slider) component. You should adjust the end position of the Slider after generating the file.
diff --git a/docs_md/advanced-setup.md b/docs_md/advanced-setup.md
index 5e047a7..cf369d1 100644
--- a/docs_md/advanced-setup.md
+++ b/docs_md/advanced-setup.md
@@ -61,29 +61,6 @@ no_auto_input = 1
```
-## Template Name Check
-
-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 manually, you can disable this feature by setting the `druid.no_auto_template` field in the _game.project_ file:
-
-```
-[druid]
-no_auto_template = 1
-```
-
-
-## Stencil Check
-
-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 the following field to your _game.project_ file:
-```
-[druid]
-no_stencil_check = 1
-```
-
-
## Code Bindings
Adjust **Druid** settings as needed:
@@ -121,7 +98,7 @@ window.set_listener(on_window_callback)
```
-## EmmyLua Annotations
+## Lua Annotations
[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).
diff --git a/docs_md/api_reference/druid_button.md b/docs_md/api_reference/druid_button.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs_md/quick_api_reference.md b/docs_md/quick_api_reference.md
new file mode 100644
index 0000000..e53c5d1
--- /dev/null
+++ b/docs_md/quick_api_reference.md
@@ -0,0 +1,74 @@
+# Quick API Reference
+
+## Druid
+```lua
+local druid = require("druid.druid")
+
+druid.init_window_listener()
+druid.on_language_change()
+druid.on_window_callback(window_event)
+druid.set_default_style(style)
+druid.set_sound_function(callback)
+druid.set_text_function(callback)
+
+self.druid = druid.new(context, [style])
+```
+
+## Druid Instance
+```lua
+self.druid:final()
+self.druid:update(dt)
+self.druid:on_input(action_id, action)
+self.druid:on_message(message_id, message, sender)
+
+self.druid:new(component, ...)
+self.druid:new_back_handler([callback], [params])
+self.druid:new_blocker(node)
+self.druid:new_button(node, [callback], [params], [anim_node])
+self.druid:new_container(node, [mode], [callback])
+self.druid:new_data_list(druid_scroll, druid_grid, create_function)
+self.druid:new_drag(node, [on_drag_callback])
+self.druid:new_grid(parent_node, item, [in_row])
+self.druid:new_hotkey(keys_array, [callback], [callback_argument])
+self.druid:new_hover(node, [on_hover_callback], [on_mouse_hover_callback])
+self.druid:new_input(click_node, text_node, [keyboard_type])
+self.druid:new_lang_text(node, [locale_id], [adjust_type])
+self.druid:new_layout(node, [mode])
+self.druid:new_progress(node, key, [init_value])
+self.druid:new_rich_input(template, [nodes])
+self.druid:new_rich_text(text_node, [value])
+self.druid:new_scroll(view_node, content_node)
+self.druid:new_slider(pin_node, end_pos, [callback])
+self.druid:new_swipe(node, [on_swipe_callback])
+self.druid:new_text(node, [value], [no_adjust])
+self.druid:new_timer(node, [seconds_from], [seconds_to], [callback])
+self.druid:new_widget(widget, [template], [nodes], ...)
+self.druid:on_window_event([window_event])
+self.druid:remove(component)
+self.druid:set_blacklist(blacklist_components)
+self.druid:set_whitelist(whitelist_components)
+```
+
+## Components
+### Base Component
+### Blocker
+### Button
+### Container
+### Data List
+### Drag
+### Grid
+### Hotkey
+### Hover
+### Input
+### Lang Text
+### Layout
+### Progress
+### Rich Input
+### Rich Text
+### Scroll
+### Slider
+### Swipe
+### Text
+### Timer
+
+## Helper
diff --git a/druid/annotations.lua b/druid/annotations.lua
deleted file mode 100644
index 9ccff3c..0000000
--- a/druid/annotations.lua
+++ /dev/null
@@ -1,1902 +0,0 @@
--- luacheck: ignore
----@meta
-
----@class druid
-local druid = {}
-
---- Create a new Druid instance for creating GUI components.
----@param context table The Druid context. Usually, this is the self of the gui_script. It is passed into all Druid callbacks.
----@param style table|nil The Druid style table to override style parameters for this Druid instance.
----@return druid_instance The Druid instance @{DruidInstance}.
-function druid.new(context, style) end
-
---- Call this function when the game language changes.
---- This function will translate all current LangText components.
-function druid.on_language_change() end
-
---- Set the window callback to enable on_focus_gain and on_focus_lost functions.
---- This is used to trigger the on_focus_lost and on_focus_gain functions in Druid components.
----@param event string Event param from window listener
-function druid.on_window_callback(event) end
-
---- Register a new external Druid component.
---- 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 module table lua table with component
-function druid.register(name, module) end
-
---- Set your own default style for all Druid instances.
---- To create your own style file, copy the default style file and make changes to it. Register the new style before creating your Druid instances.
----@param style table Druid style module
-function druid.set_default_style(style) end
-
---- Set the Druid sound function to play UI sounds if used.
---- Set a function to play a sound given a sound_id. This function is used for button clicks to play the "click" sound. It can also be used to play sounds in your custom components (see the default Druid style file for an example).
----@param callback function Sound play callback
-function druid.set_sound_function(callback) end
-
---- Set the text function for the LangText component.
---- The Druid locale component will call this function to get translated text. After setting the text function, all existing locale components will be updated.
----@param callback function Get localized text function
-function druid.set_text_function(callback) end
-
-
----@class druid.back_handler : druid.base_component
----@field on_back druid.event The @{DruidEvent} Event on back handler action.
----@field params any|nil Custom args to pass in the callback
-local druid__back_handler = {}
-
-
----@class druid.base_component
-local druid__base_component = {}
-
---- Return all children components, recursive
----@param self druid.base_component @{BaseComponent}
----@return table Array of childrens if the Druid component instance
-function druid__base_component.get_childrens(self) end
-
---- Context used as first arg in all Druid events
---- Context is usually self of gui_script.
----@param self druid.base_component @{BaseComponent}
----@return table BaseComponent context
-function druid__base_component.get_context(self) end
-
---- Get Druid instance for inner component creation.
----@param self druid.base_component @{BaseComponent}
----@param template string|nil The template name
----@param nodes table|nil The nodes table
----@return druid_instance Druid instance with component context
-function druid__base_component.get_druid(self, template, nodes) end
-
---- Return component input priority
----@param self druid.base_component @{BaseComponent}
----@return number The component input priority
-function druid__base_component.get_input_priority(self) end
-
---- Return component name
----@param self druid.base_component @{BaseComponent}
----@return string The component name
-function druid__base_component.get_name(self) end
-
---- Get component node by name.
---- If component has nodes, node_or_name should be string It autopick node by template name or from nodes by gui.clone_tree if they was setup via component:set_nodes, component:set_template. If node is not found, the exception will fired
----@param self druid.base_component @{BaseComponent}
----@param node_or_name string|node Node name or node itself
----@return node Gui node
-function druid__base_component.get_node(self, node_or_name) end
-
---- Return the parent component if exist
----@param self druid.base_component @{BaseComponent}
----@return druid.base_component|nil The druid component instance or nil
-function druid__base_component.get_parent_component(self) end
-
---- Return parent component name
----@param self druid.base_component @{BaseComponent}
----@return string|nil The parent component name if exist or bil
-function druid__base_component.get_parent_name(self) end
-
---- Get current component template name.
----@param self druid.base_component @{BaseComponent}
----@return string Component full template name
-function druid__base_component.get_template(self) end
-
---- Return component UID.
---- UID generated in component creation order.
----@param self druid.base_component @{BaseComponent}
----@return number The component uid
-function druid__base_component.get_uid(self) end
-
---- Reset component input priority to default value
----@param self druid.base_component @{BaseComponent}
----@return number The component input priority
-function druid__base_component.reset_input_priority(self) end
-
---- Set component input state.
---- By default it enabled If input is disabled, the component will not receive input events
----@param self druid.base_component @{BaseComponent}
----@param state boolean|nil The component input state
----@return druid.base_component BaseComponent itself
-function druid__base_component.set_input_enabled(self, state) end
-
---- Set component input priority
---- Default value: 10
----@param self druid.base_component @{BaseComponent}
----@param value number The new input priority value
----@param is_temporary boolean|nil If true, the reset input priority will return to previous value
----@return number The component input priority
-function druid__base_component.set_input_priority(self, value, is_temporary) end
-
-
----@class druid.blocker : druid.base_component
----@field node node Blocker node
-local druid__blocker = {}
-
---- The @{Blocker} constructor
----@param self druid.blocker @{Blocker}
----@param node node Gui node
-function druid__blocker.init(self, node) end
-
---- Return blocker enabled state
----@param self druid.blocker @{Blocker}
----@return boolean @True, if blocker is enabled
-function druid__blocker.is_enabled(self) end
-
---- Set enabled blocker component state.
---- Don't change node enabled state itself.
----@param self druid.blocker @{Blocker}
----@param state boolean|nil Enabled state
-function druid__blocker.set_enabled(self, state) end
-
-
----@class druid.button : druid.base_component
----@field anim_node node|nil Button animation node.
----@field click_zone node|nil Additional button click area, defined by another GUI node
----@field hover druid.hover The @{Hover}: Button Hover component
----@field node node Button trigger node
----@field node_id hash The GUI node id from button node
----@field on_click druid.event The @{DruidEvent}: Event on successful release action over button.
----@field on_click_outside druid.event The @{DruidEvent}: Event calls if click event was outside of button.
----@field on_double_click druid.event The @{DruidEvent}: Event on double tap action over button.
----@field on_hold_callback druid.event The @{DruidEvent}: Event calls every frame before on_long_click event.
----@field on_long_click druid.event The @{DruidEvent}: Event on long tap action over button.
----@field on_pressed druid.event The @{DruidEvent}: Event triggered if button was pressed by user.
----@field on_repeated_click druid.event The @{DruidEvent}: Event on repeated action over button.
----@field params any Custom args for any Button event.
----@field style druid.button.style Component style params.
-local druid__button = {}
-
---- Get current key name to trigger this button.
----@param self druid.button
----@return hash The action_id of the input key
-function druid__button.get_key_trigger(self) end
-
---- The @{Button} constructor
----@param self druid.button @{Button}
----@param node string|node The node_id or gui.get_node(node_id)
----@param callback function On click button callback
----@param custom_args any|nil Button events custom arguments
----@param anim_node string|node|nil Node to animate instead of trigger node.
-function druid__button.init(self, node, callback, custom_args, anim_node) end
-
---- Get button enabled state.
---- By default all Buttons is enabled on creating.
----@param self druid.button @{Button}
----@return boolean @True, if button is enabled now, False overwise
-function druid__button.is_enabled(self) end
-
---- Set function for additional check for button click availability
----@param self druid.button
----@param check_function function|nil Should return true or false. If true - button can be pressed.
----@param failure_callback function|nil Function will be called on button click, if check function return false
----@return druid.button Current button instance
-function druid__button.set_check_function(self, check_function, failure_callback) end
-
---- Set additional button click area.
---- 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 zone node|string|nil Gui node
----@return druid.button Current button instance
-function druid__button.set_click_zone(self, zone) end
-
---- Set button enabled state.
---- The style.on_set_enabled will be triggered. Disabled button is not clickable.
----@param self druid.button @{Button}
----@param state boolean|nil Enabled state
----@return druid.button Current button instance
-function druid__button.set_enabled(self, state) end
-
---- Set key name to trigger this button by keyboard.
----@param self druid.button @{Button}
----@param key hash|string The action_id of the input key
----@return druid.button Current button instance
-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|nil 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
----@field AUTOHOLD_TRIGGER number|nil Maximum hold time to trigger button release while holding. Default: 0.8
----@field DOUBLETAP_TIME number|nil Time between double taps. Default: 0.4
----@field LONGTAP_TIME number|nil Minimum time to trigger on_hold_callback. Default: 0.4
----@field on_click function function(self, node)
----@field on_click_disabled function function(self, node)
----@field on_hover function function(self, node, hover_state)
----@field on_mouse_hover function function(self, node, hover_state)
----@field on_set_enabled function function(self, node, enabled_state)
-local druid__button__style = {}
-
-
----@class druid.data_list : druid.base_component
----@field grid druid.static_grid The Druid Grid component
----@field last_index number The current last index of visual elements
----@field on_element_add druid.event On DataList visual element created Event callback(self, index, node, instance)
----@field on_element_remove druid.event On DataList visual element created Event callback(self, index)
----@field on_scroll_progress_change druid.event Event triggered when scroll progress is changed; event(self, progress_value)
----@field scroll druid.scroll The Druid scroll component
----@field scroll_progress number The current progress of scroll posititon
----@field top_index number The current top index of visual elements
-local druid__data_list = {}
-
---- Add element to DataList.
---- Currenly untested
----@param self druid.data_list @{DataList}
----@param data table
----@param index number|nil
----@param shift_policy number|nil The constant from const.SHIFT.*
-function druid__data_list.add(self, data, index, shift_policy) end
-
---- Clear the DataList and refresh visuals
----@param self druid.data_list @{DataList}
-function druid__data_list.clear(self) end
-
---- Return all currenly created components in DataList
----@param self druid.data_list @{DataList}
----@return druid.base_component[] List of created nodes
-function druid__data_list.get_created_components(self) end
-
---- Return all currenly created nodes in DataList
----@param self druid.data_list @{DataList}
----@return node[] List of created nodes
-function druid__data_list.get_created_nodes(self) end
-
---- Return current data from DataList component
----@param self druid.data_list @{DataList}
----@return table The current data array
-function druid__data_list.get_data(self) end
-
---- Return index for data value
----@param self druid.data_list @{DataList}
----@param data table
-function druid__data_list.get_index(self, data) end
-
---- The @{DataList} constructor
----@param self druid.data_list @{DataList}
----@param scroll druid.scroll The @{Scroll} instance for Data List component
----@param grid druid.static_grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component
----@param create_function function The create function callback(self, data, index, data_list). Function should return (node, [component])
-function druid__data_list.init(self, scroll, grid, create_function) end
-
---- Druid System on_remove function
----@param self druid.data_list @{DataList}
-function druid__data_list.on_remove(self) end
-
---- Remove element from DataList.
---- Currenly untested
----@param self druid.data_list @{DataList}
----@param index number|nil
----@param shift_policy number|nil The constant from const.SHIFT.*
-function druid__data_list.remove(self, index, shift_policy) end
-
---- Remove element from DataList by data value.
---- Currenly untested
----@param self druid.data_list @{DataList}
----@param data table
----@param shift_policy number|nil The constant from const.SHIFT.*
-function druid__data_list.remove_by_data(self, data, shift_policy) end
-
---- Instant scroll to element with passed index
----@param self druid.data_list @{DataList}
----@param index number
-function druid__data_list.scroll_to_index(self, index) end
-
---- Set new data set for DataList component
----@param self druid.data_list @{DataList}
----@param data table The new data array
----@return druid.data_list Current DataList instance
-function druid__data_list.set_data(self, data) end
-
---- Set refresh function for DataList component
----@param self druid.data_list @{DataList}
----@param is_use_cache boolean Use cache version of DataList. Requires make setup of components in on_element_add callback and clean in on_element_remove
----@return druid.data_list Current DataList instance
-function druid__data_list.set_use_cache(self, is_use_cache) end
-
-
----@class druid.drag : druid.base_component
----@field can_x boolean Is drag component process vertical dragging.
----@field can_y boolean Is drag component process horizontal.
----@field is_drag boolean Is component now dragging
----@field is_touch boolean Is component now touching
----@field node node Drag node
----@field on_drag druid.event on drag progress callback(self, dx, dy, total_x, total_y, touch)
----@field on_drag_end druid.event Event on drag end callback(self, total_x, total_y, touch)
----@field on_drag_start druid.event Event on drag start callback(self, touch)
----@field on_touch_end druid.event Event on touch end callback(self)
----@field on_touch_start druid.event Event on touch start callback(self)
----@field screen_x number Current touch x screen position
----@field screen_y number Current touch y screen position
----@field style druid.drag.style Component style params.
----@field touch_start_pos vector3 Touch start position
----@field x number Current touch x position
----@field y number Current touch y position
-local druid__drag = {}
-
---- The @{Drag} constructor
----@param self druid.drag @{Drag}
----@param node node GUI node to detect dragging
----@param on_drag_callback function Callback for on_drag_event(self, dx, dy)
-function druid__drag.init(self, node, on_drag_callback) end
-
---- Check if Drag component is enabled
----@param self druid.drag @{Drag}
----@return boolean
-function druid__drag.is_enabled(self) end
-
---- Strict drag click area.
---- Useful for restrict events outside stencil node
----@param self druid.drag @{Drag}
----@param node node|string|nil Gui node
-function druid__drag.set_click_zone(self, node) end
-
---- Set Drag input enabled or disabled
----@param self druid.drag @{Drag}
----@param is_enabled boolean|nil
-function druid__drag.set_enabled(self, is_enabled) end
-
-
----@class druid.drag.style
----@field DRAG_DEADZONE number|nil Distance in pixels to start dragging. Default: 10
----@field NO_USE_SCREEN_KOEF boolean|nil If screen aspect ratio affects on drag values. Default: false
-local druid__drag__style = {}
-
-
----@class druid.dynamic_grid : druid.base_component
----@field border vector4 The size of item content
----@field first_index number The first index of node in grid
----@field last_index number The last index of node in grid
----@field node_size vector3 Item size
----@field nodes node[] List of all grid elements.
----@field on_add_item druid.event On item add callback(self, node, index)
----@field on_change_items druid.event On item add or remove callback(self, index)
----@field on_clear druid.event On grid clear callback(self)
----@field on_remove_item druid.event On item remove callback(self, index)
----@field on_update_positions druid.event On update item positions callback(self)
----@field parent node Parent gui node
-local druid__dynamic_grid = {}
-
---- Return side vector to correct node shifting
----@param self unknown
----@param side unknown
----@param is_forward unknown
-function druid__dynamic_grid._get_side_vector(self, side, is_forward) end
-
---- Add new node to the grid
----@param self druid.dynamic_grid @{DynamicGrid}
----@param node node Gui node
----@param index number|nil The node position. By default add as last node
----@param shift_policy number|nil How shift nodes, if required. Default: const.SHIFT.RIGHT
----@param is_instant boolean|nil If true, update node positions instantly
-function druid__dynamic_grid.add(self, node, index, shift_policy, is_instant) end
-
---- Clear grid nodes array.
---- GUI nodes will be not deleted! If you want to delete GUI nodes, use dynamic_grid.nodes array before grid:clear
----@param self druid.dynamic_grid @{DynamicGrid}
----@return druid.dynamic_grid Current grid instance
-function druid__dynamic_grid.clear(self) end
-
---- Return array of all node positions
----@param self druid.dynamic_grid @{DynamicGrid}
----@return vector3[] All grid node positions
-function druid__dynamic_grid.get_all_pos(self) end
-
---- Return grid content borders
----@param self druid.dynamic_grid @{DynamicGrid}
----@return vector3 The grid content borders
-function druid__dynamic_grid.get_borders(self) end
-
---- Return grid index by node
----@param self druid.dynamic_grid @{DynamicGrid}
----@param node node The gui node in the grid
----@return number The node index
-function druid__dynamic_grid.get_index_by_node(self, node) end
-
---- Return DynamicGrid offset, where DynamicGrid content starts.
----@param self druid.dynamic_grid @{DynamicGrid} The DynamicGrid instance
----@return vector3 The DynamicGrid offset
-function druid__dynamic_grid.get_offset(self) end
-
---- Return pos for grid node index
----@param self druid.dynamic_grid @{DynamicGrid}
----@param index number The grid element index
----@param node node The node to be placed
----@param origin_index number|nil Index of nearby node
----@return vector3 node position
-function druid__dynamic_grid.get_pos(self, index, node, origin_index) end
-
---- Return grid content size
----@param self druid.dynamic_grid @{DynamicGrid}
----@param border vector3
----@return vector3 The grid content size
-function druid__dynamic_grid.get_size(self, border) end
-
---- The @{DynamicGrid} constructor
----@param self druid.dynamic_grid @{DynamicGrid}
----@param parent node The gui node parent, where items will be placed
-function druid__dynamic_grid.init(self, parent) end
-
---- Remove the item from the grid.
---- Note that gui node will be not deleted
----@param self druid.dynamic_grid @{DynamicGrid}
----@param index number The grid node index to remove
----@param shift_policy number|nil How shift nodes, if required. Default: const.SHIFT.RIGHT
----@param is_instant boolean|nil If true, update node positions instantly
----@return node The deleted gui node from grid
-function druid__dynamic_grid.remove(self, index, shift_policy, is_instant) end
-
---- Change set position function for grid nodes.
---- It will call on update poses on grid elements. Default: gui.set_position
----@param self druid.dynamic_grid @{DynamicGrid}
----@param callback function Function on node set position
----@return druid.dynamic_grid Current grid instance
-function druid__dynamic_grid.set_position_function(self, callback) end
-
-
----@class druid.event
-local druid__event = {}
-
---- Clear the all event handlers
----@param self druid.event @{DruidEvent}
-function druid__event.clear(self) end
-
---- DruidEvent constructor
----@param callback function|nil Subscribe the callback on new event, if callback exist
----@param callback_context any|nil Additional context as first param to callback call
-function druid__event.create(callback, callback_context) end
-
---- Return true, if event not have handler
----@param self druid.event @{DruidEvent}
----@return boolean True if event not have handlers
-function druid__event.is_empty(self) end
-
---- Return true, if event have at lease one handler
----@param self druid.event @{DruidEvent}
----@return boolean True if event have handlers
-function druid__event.is_exist(self) end
-
---- Check is event subscribed.
----@param self druid.event @{DruidEvent}
----@param callback function Callback itself
----@param callback_context any|nil Additional context as first param to callback call
----@return boolean, number|nil @Is event subscribed, return index of callback in event as second param
-function druid__event.is_subscribed(self, callback, callback_context) end
-
---- Subscribe callback on event
----@param self druid.event @{DruidEvent}
----@param callback function Callback itself
----@param callback_context any|nil Additional context as first param to callback call, usually it's self
----@return boolean True if callback was subscribed
-function druid__event.subscribe(self, callback, callback_context) end
-
---- Trigger the event and call all subscribed callbacks
----@param self druid.event @{DruidEvent}
----@param ... any All event params
-function druid__event.trigger(self, ...) end
-
---- Unsubscribe callback on event
----@param self druid.event @{DruidEvent}
----@param callback function Callback itself
----@param callback_context any|nil Additional context as first param to callback call
-function druid__event.unsubscribe(self, callback, callback_context) end
-
-
----@class druid.hotkey : druid.base_component
----@field button druid.button Button component from click_node
----@field click_node node|nil Button trigger node
----@field node node Visual node
----@field on_hotkey_pressed druid.event On hotkey released callback(self, argument)
----@field on_hotkey_released druid.event On hotkey released callback(self, argument)
----@field style druid.hotkey.style Component style params.
-local druid__hotkey = {}
-
---- Add hotkey for component callback
----@param self druid.hotkey @{Hotkey}
----@param keys string[]|hash[]|string|hash that have to be pressed before key pressed to activate
----@param callback_argument any|nil The argument to pass into the callback function
----@return druid.hotkey Current instance
-function druid__hotkey.add_hotkey(self, keys, callback_argument) end
-
---- The @{Hotkey} constructor
----@param self druid.hotkey @{Hotkey}
----@param keys string[]|string The keys to be pressed for trigger callback. Should contains one key and any modificator keys
----@param callback function The callback function
----@param callback_argument any|nil The argument to pass into the callback function
-function druid__hotkey.init(self, keys, callback, callback_argument) end
-
---- If true, the callback will be triggered on action.repeated
----@param self druid.hotkey @{Hotkey}
----@param is_enabled_repeated bool The flag value
----@return druid.hotkey
-function druid__hotkey.set_repeat(self, is_enabled_repeated) end
-
-
----@class druid.hotkey.style
----@field MODIFICATORS string[] The list of action_id as hotkey modificators
-local druid__hotkey__style = {}
-
-
----@class druid.hover : druid.base_component
----@field node node Hover node
----@field on_hover druid.event On hover callback(self, state, hover_instance)
----@field on_mouse_hover druid.event On mouse hover callback(self, state, hover_instance)
----@field style druid.hover.style Component style params.
-local druid__hover = {}
-
---- The @{Hover} constructor
----@param self druid.hover @{Hover}
----@param node node Gui node
----@param on_hover_callback function Hover callback
----@param on_mouse_hover function On mouse hover callback
-function druid__hover.init(self, node, on_hover_callback, on_mouse_hover) end
-
---- Return current hover enabled state
----@param self druid.hover @{Hover}
----@return boolean The hover enabled state
-function druid__hover.is_enabled(self) end
-
---- Return current hover state.
---- True if touch action was on the node at current time
----@param self druid.hover @{Hover}
----@return boolean The current hovered state
-function druid__hover.is_hovered(self) end
-
---- Return current hover state.
---- True if nil action_id (usually desktop mouse) was on the node at current time
----@param self druid.hover @{Hover}
----@return boolean The current hovered state
-function druid__hover.is_mouse_hovered(self) end
-
---- Strict hover click area.
---- Useful for no click events outside stencil node
----@param self druid.hover @{Hover}
----@param zone node|string|nil Gui node
-function druid__hover.set_click_zone(self, zone) end
-
---- Set enable state of hover component.
---- If hover is not enabled, it will not generate any hover events
----@param self druid.hover @{Hover}
----@param state boolean|nil The hover enabled state
-function druid__hover.set_enabled(self, state) end
-
---- Set hover state
----@param self druid.hover @{Hover}
----@param state boolean|nil The hover state
-function druid__hover.set_hover(self, state) end
-
---- Set mouse hover state
----@param self druid.hover @{Hover}
----@param state boolean|nil The mouse hover state
-function druid__hover.set_mouse_hover(self, state) end
-
-
----@class druid.hover.style
----@field ON_HOVER_CURSOR string Mouse hover style on node hover
----@field ON_MOUSE_HOVER_CURSOR string Mouse hover style on node mouse hover
-local druid__hover__style = {}
-
-
----@class druid.input : druid.base_component
----@field allowerd_characters string|nil Pattern matching for user input
----@field button druid.button Button component
----@field current_value string Current input value with marked text
----@field cursor_index number The cursor index.
----@field end_index number Theselection end index.
----@field is_empty boolean Is current input is empty now
----@field is_selected boolean Is current input selected now
----@field keyboard_type number Gui keyboard type for input field
----@field marked_text_width number Marked text width
----@field marked_value string Marked text for input field.
----@field max_length number|nil Max length for input text
----@field on_input_empty druid.event On input field text change to empty string callback(self, input_text)
----@field on_input_full druid.event On input field text change to max length string callback(self, input_text)
----@field on_input_select druid.event On input field select callback(self, input_instance)
----@field on_input_text druid.event On input field text change callback(self, input_text)
----@field on_input_unselect druid.event On input field unselect callback(self, input_text, input_instance)
----@field on_input_wrong druid.event On trying user input with not allowed character callback(self, params, input_text)
----@field on_select_cursor_change druid.event On cursor position change callback(self, cursor_index, start_index, end_index)
----@field previous_value string Previous input value
----@field start_index number The selection start index.
----@field style druid.input.style Component style params.
----@field text druid.text Text component
----@field text_width number Text width
----@field value string Current input value
-local druid__input = {}
-
---- Return current input field text
----@param self druid.input @{Input}
----@return string The current input field text
-function druid__input.get_text(self) end
-
---- Replace selected text with new text
----@param self druid.input @{Input}
----@param text string The text to replace selected text
----@return string New input text
-function druid__input.get_text_selected_replaced(self, text) end
-
---- The @{Input} constructor
----@param self druid.input @{Input}
----@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 keyboard_type number|nil Gui keyboard type for input field
-function druid__input.init(self, click_node, text_node, keyboard_type) end
-
---- Change cursor position by delta
----@param self druid.input @{Input}
----@param delta number side for cursor position, -1 for left, 1 for right
----@param is_add_to_selection boolean (Shift key)
----@param is_move_to_end boolean (Ctrl key)
-function druid__input.move_selection(self, delta, is_add_to_selection, is_move_to_end) end
-
---- Reset current input selection and return previous value
----@param self druid.input @{Input}
----@return druid.input Current input instance
-function druid__input.reset_changes(self) end
-
---- Select input field.
---- It will show the keyboard and trigger on_select events
----@param self druid.input @{Input}
-function druid__input.select(self) end
-
---- Set cursor position in input field
----@param self druid.input @{Input}
----@param cursor_index number|nil Cursor index for cursor position, if nil - will be set to the end of the text
----@param start_index number|nil Start index for cursor position, if nil - will be set to the end of the text
----@param end_index number|nil End index for cursor position, if nil - will be set to the start_index
----@return druid.input Current input instance
-function druid__input.select_cursor(self, cursor_index, start_index, end_index) end
-
---- Set allowed charaters for input field.
---- See: https://defold.com/ref/stable/string/ ex: [%a%d] for alpha and numeric
----@param self druid.input @{Input}
----@param characters string Regulax exp. for validate user input
----@return druid.input Current input instance
-function druid__input.set_allowed_characters(self, characters) end
-
---- Set maximum length for input field.
---- Pass nil to make input field unliminted (by default)
----@param self druid.input @{Input}
----@param max_length number Maximum length for input text field
----@return druid.input Current input instance
-function druid__input.set_max_length(self, max_length) end
-
---- Set text for input field
----@param self druid.input @{Input}
----@param input_text string The string to apply for input field
-function druid__input.set_text(self, input_text) end
-
---- Remove selection from input.
---- It will hide the keyboard and trigger on_unselect events
----@param self druid.input @{Input}
-function druid__input.unselect(self) end
-
-
----@class druid.input.style
----@field IS_LONGTAP_ERASE boolean Is long tap will erase current input data. Default: false
----@field IS_UNSELECT_ON_RESELECT boolean If true, call unselect on select selected input. Default: false
----@field MASK_DEFAULT_CHAR string Default character mask for password input. Default: *]
----@field on_input_wrong function (self, button_node) Callback on wrong user input
----@field on_select function (self, button_node) Callback on input field selecting
----@field on_unselect function (self, button_node) Callback on input field unselecting
-local druid__input__style = {}
-
-
----@class druid.lang_text : druid.base_component
----@field node node Text node
----@field on_change druid.event On change text callback
----@field text druid.text The text component
-local druid__lang_text = {}
-
---- Format string with new text params on localized text
----@param self druid.lang_text @{LangText}
----@param a string|nil Optional param to string.format
----@param b string|nil Optional param to string.format
----@param c string|nil Optional param to string.format
----@param d string|nil Optional param to string.format
----@param e string|nil Optional param to string.format
----@param f string|nil Optional param to string.format
----@param g string|nil Optional param to string.format
----@return druid.lang_text Current instance
-function druid__lang_text.format(self, a, b, c, d, e, f, g) end
-
---- The @{LangText} constructor
----@param self druid.lang_text @{LangText}
----@param node string|node The node_id or gui.get_node(node_id)
----@param locale_id string|nil Default locale id or text from node as default
----@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
-function druid__lang_text.init(self, node, locale_id, adjust_type) end
-
---- Setup raw text to lang_text component
----@param self druid.lang_text @{LangText}
----@param text string Text for text node
----@return druid.lang_text Current instance
-function druid__lang_text.set_to(self, text) end
-
---- Translate the text by locale_id
----@param self druid.lang_text @{LangText}
----@param locale_id string Locale id
----@param a string|nil Optional param to string.format
----@param b string|nil Optional param to string.format
----@param c string|nil Optional param to string.format
----@param d string|nil Optional param to string.format
----@param e string|nil Optional param to string.format
----@param f string|nil Optional param to string.format
----@param g string|nil Optional param to string.format
----@return druid.lang_text Current instance
-function druid__lang_text.translate(self, locale_id, a, b, c, d, e, f, g) end
-
-
----@class druid.layout : druid.base_component
----@field mode string Current layout mode
----@field node node Layout node
-local druid__layout = {}
-
-
----@class druid.progress : druid.base_component
----@field key string The progress bar direction.
----@field max_size number Maximum size of progress bar
----@field node node Progress bar fill node
----@field on_change druid.event On progress bar change callback(self, new_value)
----@field scale vector3 Current progress bar scale
----@field size vector3 Current progress bar size
----@field slice vector4 Progress bar slice9 settings
----@field style druid.progress.style Component style params.
-local druid__progress = {}
-
---- Empty a progress bar
----@param self druid.progress @{Progress}
-function druid__progress.empty(self) end
-
---- Fill a progress bar and stop progress animation
----@param self druid.progress @{Progress}
-function druid__progress.fill(self) end
-
---- Return current progress bar value
----@param self druid.progress @{Progress}
-function druid__progress.get(self) end
-
---- The @{Progress} constructor
----@param self druid.progress @{Progress}
----@param node string|node Node name or GUI Node itself.
----@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y
----@param init_value number|nil Initial value of progress bar. Default: 1
-function druid__progress.init(self, node, key, init_value) end
-
---- Set progress bar max node size
----@param self druid.progress @{Progress}
----@param max_size vector3 The new node maximum (full) size
----@return druid.progress @{Progress}
-function druid__progress.set_max_size(self, max_size) end
-
---- Set points on progress bar to fire the callback
----@param self druid.progress @{Progress}
----@param steps number[] Array of progress bar values
----@param callback function Callback on intersect step value
-function druid__progress.set_steps(self, steps, callback) end
-
---- Instant fill progress bar to value
----@param self druid.progress @{Progress}
----@param to number Progress bar value, from 0 to 1
-function druid__progress.set_to(self, to) end
-
---- Start animation of a progress bar
----@param self druid.progress @{Progress}
----@param to number value between 0..1
----@param callback function|nil Callback on animation ends
-function druid__progress.to(self, to, callback) end
-
-
----@class druid.progress.style
----@field MIN_DELTA number|nil Minimum step to fill progress bar. Default: 0.005
----@field SPEED number|nil Progress bas fill rate. More -> faster. Default: 5
-local druid__progress__style = {}
-
-
----@class druid.rich_input
----@field cursor node On input field text change to empty string callback(self, input_text)
----@field cursor_position vector3 On input field text change to empty string callback(self, input_text)
----@field cursor_text node On input field text change to empty string callback(self, input_text)
----@field drag druid.drag On input field text change to empty string callback(self, input_text)
----@field druid druid_instance The component druid instance
----@field input druid.input On input field text change callback(self, input_text)
----@field input_text druid.text On input field text change to empty string callback(self, input_text)
----@field placeholder druid.text On input field text change to empty string callback(self, input_text)
----@field root node Root node
----@field text_position vector3 On input field text change to empty string callback(self, input_text)
-local druid__rich_input = {}
-
---- Set input field text
----@param self druid.rich_input @{RichInput}
-function druid__rich_input.get_text(self) end
-
---- The @{RichInput} constructor
----@param self druid.rich_input @{RichInput}
----@param template string The template string name
----@param nodes table Nodes table from gui.clone_tree
-function druid__rich_input.init(self, template, nodes) end
-
---- Select input field
----@param self druid.rich_input @{RichInput}
-function druid__rich_input.select(self) end
-
---- Set allowed charaters for input field.
---- See: https://defold.com/ref/stable/string/ ex: [%a%d] for alpha and numeric
----@param self druid.rich_input @{RichInput}
----@param characters string Regulax exp. for validate user input
----@return druid.rich_input Current instance
-function druid__rich_input.set_allowed_characters(self, characters) end
-
---- Set input field font
----@param self druid.rich_input @{RichInput}
----@param font hash The font hash
----@return druid.input Current input instance
-function druid__rich_input.set_font(self, font) end
-
---- Set placeholder text
----@param self druid.rich_input @{RichInput}
----@param placeholder_text string The placeholder text
-function druid__rich_input.set_placeholder(self, placeholder_text) end
-
---- Set input field text
----@param self druid.rich_input @{RichInput}
----@param text string The input text
----@return druid.input Current input instance
-function druid__rich_input.set_text(self, text) end
-
-
----@class druid.rich_text : druid.base_component
----@field druid druid_instance The component druid instance
----@field root node The root node of the Rich Text
----@field style druid.rich_text.style Component style params.
----@field text_prefab node The text prefab node
-local druid__rich_text = {}
-
---- Split a word into it's characters
----@param self druid.rich_text @{RichText}
----@param word druid.rich_text.word
----@return druid.rich_text.word[] characters
-function druid__rich_text.characters(self, word) end
-
---- Clear all created words.
-function druid__rich_text.clear() end
-
---- Get current line metrics
----@return druid.rich_text.lines_metrics
-function druid__rich_text.get_line_metric() end
-
---- Get current text
----@param self druid.rich_text @{RichText}
----@return string text
-function druid__rich_text.get_text(self) end
-
---- Get all current words.
----@return table druid.rich_text.word[]
-function druid__rich_text.get_words() end
-
---- The @{RichText} constructor
----@param self druid.rich_text @{RichText}
----@param text_node node|string The text node to make Rich Text
----@param value string|nil The initial text value. Default will be gui.get_text(text_node)
-function druid__rich_text.init(self, text_node, value) end
-
---- Set text for Rich Text
----@param self druid.rich_text @{RichText}
----@param text string|nil The text to set
----@return druid.rich_text.word[] words
----@return druid.rich_text.lines_metrics line_metrics
-function druid__rich_text.set_text(self, text) end
-
---- Get all words, which has a passed tag.
----@param self druid.rich_text @{RichText}
----@param tag string
----@return druid.rich_text.word[] words
-function druid__rich_text.tagged(self, tag) end
-
-
----@class druid.rich_text.style
----@field ADJUST_SCALE_DELTA number|nil Scale step on each height adjust step. Default: 0.02
----@field ADJUST_STEPS number|nil Amount steps of attemps text adjust by height. Default: 20
----@field COLORS table|nil Rich Text color aliases. Default: {}
-local druid__rich_text__style = {}
-
-
----@class druid.scroll : druid.base_component
----@field _is_inert boolean Flag, if scroll now moving by inertion
----@field available_pos vector4 Available position for content node: (min_x, max_y, max_x, min_y)
----@field available_size vector3 Size of available positions: (width, height, 0)
----@field content_node node Scroll content node
----@field drag druid.drag Drag Druid component
----@field inertion vector3 Current inert speed
----@field is_animate boolean Flag, if scroll now animating by gui.animate
----@field on_point_scroll druid.event On scroll_to_index function callback(self, index, point)
----@field on_scroll druid.event On scroll move callback(self, position)
----@field on_scroll_to druid.event On scroll_to function callback(self, target, is_instant)
----@field position vector3 Current scroll posisition
----@field selected number|nil Current index of points of interests
----@field style druid.scroll.style Component style params.
----@field target_position vector3 Current scroll target position
----@field view_node node Scroll view node
----@field view_size vector3 Scroll view size
-local druid__scroll = {}
-
---- Bind the grid component (Static or Dynamic) to recalculate scroll size on grid changes
----@param self druid.scroll @{Scroll}
----@param grid druid.static_grid Druid grid component
----@return druid.scroll Current scroll instance
-function druid__scroll.bind_grid(self, grid) end
-
---- Return current scroll progress status.
---- Values will be in [0..1] interval
----@param self druid.scroll @{Scroll}
----@return vector3 New vector with scroll progress values
-function druid__scroll.get_percent(self) end
-
---- Return vector of scroll size with width and height.
----@param self druid.scroll @{Scroll}
----@return vector3 Available scroll size
-function druid__scroll.get_scroll_size(self) end
-
---- The @{Scroll} constructor
----@param self druid.scroll @{Scroll}
----@param view_node string|node GUI view scroll node
----@param content_node string|node GUI content scroll node
-function druid__scroll.init(self, view_node, content_node) end
-
---- Return if scroll have inertion.
----@param self druid.scroll @{Scroll}
----@return boolean @If scroll have inertion
-function druid__scroll.is_inert(self) end
-
---- Check node if it visible now on scroll.
---- Extra border is not affected. Return true for elements in extra scroll zone
----@param self druid.scroll @{Scroll}
----@param node node The node to check
----@return boolean True if node in visible scroll area
-function druid__scroll.is_node_in_view(self, node) end
-
---- Start scroll to target point.
----@param self druid.scroll @{Scroll}
----@param point vector3 Target point
----@param is_instant boolean|nil Instant scroll flag
-function druid__scroll.scroll_to(self, point, is_instant) end
-
---- Scroll to item in scroll by point index.
----@param self druid.scroll @{Scroll}
----@param index number Point index
----@param skip_cb boolean|nil If true, skip the point callback
-function druid__scroll.scroll_to_index(self, index, skip_cb) end
-
---- Start scroll to target scroll percent
----@param self druid.scroll @{Scroll}
----@param percent vector3 target percent
----@param is_instant boolean|nil instant scroll flag
-function druid__scroll.scroll_to_percent(self, percent, is_instant) end
-
---- Strict drag scroll area.
---- Useful for restrict events outside stencil node
----@param self druid.drag
----@param node node|string Gui node
-function druid__scroll.set_click_zone(self, node) end
-
---- Set extra size for scroll stretching.
---- Set 0 to disable stretching effect
----@param self druid.scroll @{Scroll}
----@param stretch_size number|nil Size in pixels of additional scroll area
----@return druid.scroll Current scroll instance
-function druid__scroll.set_extra_stretch_size(self, stretch_size) end
-
---- Lock or unlock horizontal scroll
----@param self druid.scroll @{Scroll}
----@param state boolean|nil True, if horizontal scroll is enabled
----@return druid.scroll Current scroll instance
-function druid__scroll.set_horizontal_scroll(self, state) end
-
---- Enable or disable scroll inert.
---- If disabled, scroll through points (if exist) If no points, just simple drag without inertion
----@param self druid.scroll @{Scroll}
----@param state boolean|nil Inert scroll state
----@return druid.scroll Current scroll instance
-function druid__scroll.set_inert(self, state) end
-
---- Set points of interest.
---- Scroll will always centered on closer points
----@param self druid.scroll @{Scroll}
----@param points table Array of vector3 points
----@return druid.scroll Current scroll instance
-function druid__scroll.set_points(self, points) end
-
---- Set scroll content size.
---- It will change content gui node size
----@param self druid.scroll @{Scroll}
----@param size vector3 The new size for content node
----@param offset vector3|nil Offset value to set, where content is starts
----@return druid.scroll Current scroll instance
-function druid__scroll.set_size(self, size, offset) end
-
---- Lock or unlock vertical scroll
----@param self druid.scroll @{Scroll}
----@param state boolean|nil True, if vertical scroll is enabled
----@return druid.scroll Current scroll instance
-function druid__scroll.set_vertical_scroll(self, state) end
-
---- Set new scroll view size in case the node size was changed.
----@param self druid.scroll @{Scroll}
----@param size vector3 The new size for view node
----@return druid.scroll Current scroll instance
-function druid__scroll.set_view_size(self, size) end
-
---- Refresh scroll view size
----@param self druid.scroll @{Scroll}
-function druid__scroll.update_view_size(self) end
-
-
----@class druid.scroll.style
----@field ANIM_SPEED number|nil Scroll gui.animation speed for scroll_to function. Default: 2
----@field BACK_SPEED number|nil Scroll back returning lerp speed. Default: 35
----@field EXTRA_STRETCH_SIZE number|nil extra size in pixels outside of scroll (stretch effect). Default: 0
----@field FRICT number|nil Multiplier for free inertion. Default: 0
----@field FRICT_HOLD number|nil Multiplier for inertion, while touching. Default: 0
----@field INERT_SPEED number|nil Multiplier for inertion speed. Default: 30
----@field INERT_THRESHOLD number|nil Scroll speed to stop inertion. Default: 3
----@field POINTS_DEADZONE number|nil Speed to check points of interests in no_inertion mode. Default: 20
----@field SMALL_CONTENT_SCROLL boolean|nil If true, content node with size less than view node size can be scrolled. Default: false
----@field WHEEL_SCROLL_BY_INERTION boolean|nil If true, wheel will add inertion to scroll. Direct set position otherwise.. Default: false
----@field WHEEL_SCROLL_INVERTED boolean|nil If true, invert direction for touchpad and mouse wheel scroll. Default: false
----@field WHEEL_SCROLL_SPEED boolean|nil The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling. Default: 0
-local druid__scroll__style = {}
-
-
----@class druid.slider : druid.base_component
----@field dist vector3 Length between start and end position
----@field end_pos vector3 End pin node position
----@field is_drag boolean Current drag state
----@field node node Slider pin node
----@field on_change_value druid.event On change value callback(self, value)
----@field pos vector3 Current pin node position
----@field start_pos vector3 Start pin node position
----@field target_pos vector3 Targer pin node position
----@field value number Current slider value
-local druid__slider = {}
-
---- The @{Slider} constructor
----@param self druid.slider @{Slider}
----@param node node Gui pin node
----@param end_pos vector3 The end position of slider
----@param callback function|nil On slider change callback
-function druid__slider.init(self, node, end_pos, callback) end
-
---- Check if Slider component is enabled
----@param self druid.slider @{Slider}
----@return boolean
-function druid__slider.is_enabled(self) end
-
---- Set value for slider
----@param self druid.slider @{Slider}
----@param value number Value from 0 to 1
----@param is_silent boolean|nil Don't trigger event if true
-function druid__slider.set(self, value, is_silent) end
-
---- Set Slider input enabled or disabled
----@param self druid.slider @{Slider}
----@param is_enabled boolean
-function druid__slider.set_enabled(self, is_enabled) end
-
---- Set input zone for slider.
---- User can touch any place of node, pin instantly will move at this position and node drag will start. This function require the Defold version 1.3.0+
----@param self druid.slider @{Slider}
----@param input_node node|string|nil
----@return druid.slider @{Slider}
-function druid__slider.set_input_node(self, input_node) end
-
---- Set slider steps.
---- Pin node will apply closest step position
----@param self druid.slider @{Slider}
----@param steps number[] Array of steps
----@return druid.slider @{Slider}
-function druid__slider.set_steps(self, steps) end
-
-
----@class druid.static_grid : druid.base_component
----@field anchor vector3 Item anchor [0..1]
----@field border vector4 The size of item content
----@field first_index number The first index of node in grid
----@field last_index number The last index of node in grid
----@field node_size vector3 Item size
----@field nodes node[] List of all grid nodes
----@field on_add_item druid.event On item add callback(self, node, index)
----@field on_change_items druid.event On item add, remove or change in_row callback(self, index|nil)
----@field on_clear druid.event On grid clear callback(self)
----@field on_remove_item druid.event On item remove callback(self, index)
----@field on_update_positions druid.event On update item positions callback(self)
----@field parent node Parent gui node
----@field pivot vector3 Item pivot [-0.5..0.5]
----@field style druid.static_grid.style Component style params.
-local druid__static_grid = {}
-
---- Add new item to the grid
----@param self druid.static_grid @{StaticGrid}
----@param item node GUI node
----@param index number|nil The item position. By default add as last item
----@param shift_policy number|nil How shift nodes, if required. Default: const.SHIFT.RIGHT
----@param is_instant boolean|nil If true, update node positions instantly
-function druid__static_grid.add(self, item, index, shift_policy, is_instant) end
-
---- Clear grid nodes array.
---- GUI nodes will be not deleted! If you want to delete GUI nodes, use static_grid.nodes array before grid:clear
----@param self druid.static_grid @{StaticGrid}
----@return druid.static_grid Current grid instance
-function druid__static_grid.clear(self) end
-
---- Return array of all node positions
----@param self druid.static_grid @{StaticGrid}
----@return vector3[] All grid node positions
-function druid__static_grid.get_all_pos(self) end
-
---- Return grid content borders
----@param self druid.static_grid @{StaticGrid}
----@return vector3 The grid content borders
-function druid__static_grid.get_borders(self) end
-
---- Return index for grid pos
----@param self druid.static_grid @{StaticGrid}
----@param pos vector3 The node position in the grid
----@return number The node index
-function druid__static_grid.get_index(self, pos) end
-
---- Return grid index by node
----@param self druid.static_grid @{StaticGrid}
----@param node node The gui node in the grid
----@return number The node index
-function druid__static_grid.get_index_by_node(self, node) end
-
---- Return StaticGrid offset, where StaticGrid content starts.
----@param self druid.static_grid @{StaticGrid} The StaticGrid instance
----@return vector3 The StaticGrid offset
-function druid__static_grid.get_offset(self) end
-
---- Return pos for grid node index
----@param self druid.static_grid @{StaticGrid}
----@param index number The grid element index
----@return vector3 @Node position
-function druid__static_grid.get_pos(self, index) end
-
---- Return grid content size
----@param self druid.static_grid @{StaticGrid}
----@return vector3 The grid content size
-function druid__static_grid.get_size(self) end
-
---- The @{StaticGrid} constructor
----@param self druid.static_grid @{StaticGrid}
----@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 in_row number|nil How many nodes in row can be placed. By default 1
-function druid__static_grid.init(self, parent, element, in_row) end
-
---- Update grid content
----@param self druid.static_grid @{StaticGrid}
-function druid__static_grid.refresh(self) end
-
---- Remove the item from the grid.
---- Note that gui node will be not deleted
----@param self druid.static_grid @{StaticGrid}
----@param index number The grid node index to remove
----@param shift_policy number|nil How shift nodes, if required. Default: const.SHIFT.RIGHT
----@param is_instant boolean|nil If true, update node positions instantly
----@return node The deleted gui node from grid
-function druid__static_grid.remove(self, index, shift_policy, is_instant) end
-
---- Set grid anchor.
---- Default anchor is equal to anchor of grid parent node
----@param self druid.static_grid @{StaticGrid}
----@param anchor vector3 Anchor
-function druid__static_grid.set_anchor(self, anchor) end
-
---- Set new in_row elements for grid
----@param self druid.static_grid @{StaticGrid}
----@param in_row number The new in_row value
----@return druid.static_grid Current grid instance
-function druid__static_grid.set_in_row(self, in_row) end
-
---- Set new node size for grid
----@param self druid.static_grid @{StaticGrid}
----@param width number The new node width
----@param height number The new node height
----@return druid.static_grid Current grid instance
-function druid__static_grid.set_item_size(self, width, height) end
-
---- Set new items to the grid.
---- All previous items will be removed
----@param self druid.static_grid @{StaticGrid}
----@param nodes node[] The new grid nodes
----@param is_instant boolean If true, update node positions instantly
-function druid__static_grid.set_items(self, nodes, is_instant) end
-
---- Change set position function for grid nodes.
---- It will call on update poses on grid elements. Default: gui.set_position
----@param self druid.static_grid @{StaticGrid}
----@param callback function Function on node set position
----@return druid.static_grid Current grid instance
-function druid__static_grid.set_position_function(self, callback) end
-
---- Sort grid nodes by custom comparator function
----@param self druid.static_grid @{StaticGrid}
----@param comparator function The comparator function. (a, b) -> boolean
----@return druid.static_grid Current grid instance
-function druid__static_grid.sort_nodes(self, comparator) end
-
-
----@class druid.static_grid.style
----@field IS_ALIGN_LAST_ROW boolean|nil If true, always align last row of the grid as grid pivot sets. Default: false
----@field IS_DYNAMIC_NODE_POSES boolean|nil If true, always center grid content as grid pivot sets. Default: false
-local druid__static_grid__style = {}
-
-
----@class druid.swipe : druid.base_component
----@field click_zone node|nil Restriction zone
----@field node node Swipe node
----@field on_swipe druid.event Trigger on swipe event(self, swipe_side, dist, delta_time)
----@field style druid.swipe.style Component style params.
-local druid__swipe = {}
-
---- The @{Swipe} constructor
----@param self druid.swipe @{Swipe}
----@param node node Gui node
----@param on_swipe_callback function Swipe callback for on_swipe_end event
-function druid__swipe.init(self, node, on_swipe_callback) end
-
---- Strict swipe click area.
---- Useful for restrict events outside stencil node
----@param self druid.swipe @{Swipe}
----@param zone node|string|nil Gui node
-function druid__swipe.set_click_zone(self, zone) end
-
-
----@class druid.swipe.style
----@field SWIPE_THRESHOLD number|nil Minimum distance for swipe trigger. Default: 50
----@field SWIPE_TIME number|nil Maximum time for swipe trigger. Default: 0.4
----@field SWIPE_TRIGGER_ON_MOVE boolean|nil If true, trigger on swipe moving, not only release action. Default: false
-local druid__swipe__style = {}
-
-
----@class druid.text : druid.base_component
----@field adjust_type number Current text size adjust settings
----@field color vector3 Current text color
----@field last_value string The last text value
----@field node node Text node
----@field node_id hash The node id of text node
----@field on_set_pivot druid.event On change pivot callback(self, pivot)
----@field on_set_text druid.event On set text callback(self, text)
----@field on_update_text_scale druid.event On adjust text size callback(self, new_scale, text_metrics)
----@field pos vector3 Current text position
----@field scale vector3 Current text node scale
----@field start_scale vector3 Initial text node scale
----@field start_size vector3 Initial text node size
----@field style druid.text.style Component style params.
----@field text_area vector3 Current text node available are
-local druid__text = {}
-
---- Return current text adjust type
----@param self unknown
----@param adjust_type unknown
----@return number The current text adjust type
-function druid__text.get_text_adjust(self, adjust_type) end
-
---- Get chars count by width
----@param self druid.text @{Text}
----@param width number
----@return number Chars count
-function druid__text.get_text_index_by_width(self, width) end
-
---- Calculate text width with font with respect to trailing space
----@param self druid.text @{Text}
----@param text string |nil
----@return number Width
----@return number Height
-function druid__text.get_text_size(self, text) end
-
---- The @{Text} constructor
----@param self druid.text @{Text}
----@param node string|node Node name or GUI Text Node itself
----@param value string|nil Initial text. Default value is node text from GUI scene. Default: nil
----@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
-function druid__text.init(self, node, value, adjust_type) end
-
---- Return true, if text with line break
----@param self druid.text @{Text}
----@return boolean Is text node with line break
-function druid__text.is_multiline(self) end
-
---- Set alpha
----@param self druid.text @{Text}
----@param alpha number Alpha for node
----@return druid.text Current text instance
-function druid__text.set_alpha(self, alpha) end
-
---- Set color
----@param self druid.text @{Text}
----@param color vector4 Color for node
----@return druid.text Current text instance
-function druid__text.set_color(self, color) end
-
---- Set minimal scale for DOWNSCALE_LIMITED or SCALE_THEN_SCROLL adjust types
----@param self druid.text @{Text}
----@param minimal_scale number If pass nil - not use minimal scale
----@return druid.text Current text instance
-function druid__text.set_minimal_scale(self, minimal_scale) end
-
---- Set text pivot.
---- Text will re-anchor inside text area
----@param self druid.text @{Text}
----@param pivot number The gui.PIVOT_* constant
----@return druid.text Current text instance
-function druid__text.set_pivot(self, pivot) end
-
---- Set scale
----@param self druid.text @{Text}
----@param scale vector3 Scale for node
----@return druid.text Current text instance
-function druid__text.set_scale(self, scale) end
-
---- Set text area size
----@param self druid.text @{Text}
----@param size vector3 The new text area size
----@return druid.text Current text instance
-function druid__text.set_size(self, size) end
-
---- Set text adjust, refresh the current text visuals, if needed
----@param self druid.text @{Text}
----@param adjust_type string|nil See const.TEXT_ADJUST. If pass nil - use current adjust type
----@param minimal_scale number|nil If pass nil - not use minimal scale
----@return druid.text Current text instance
-function druid__text.set_text_adjust(self, adjust_type, minimal_scale) end
-
---- Set text to text field
----@param self druid.text @{Text}
----@param set_to string Text for node
----@return druid.text Current text instance
-function druid__text.set_to(self, set_to) end
-
-
----@class druid.text.style
----@field ADJUST_SCALE_DELTA string|nil Scale step on each height adjust step. Default: 0.02
----@field ADJUST_STEPS string|nil Amount of iterations for text adjust by height. Default: 20
----@field DEFAULT_ADJUST string|nil The default adjust type for any text component. Default: DOWNSCALE
----@field TRIM_POSTFIX string|nil The postfix for TRIM adjust type. Default: ...
-local druid__text__style = {}
-
-
----@class druid.timer : druid.base_component
----@field from number Initial timer value
----@field node node Trigger node
----@field on_set_enabled druid.event On timer change enabled state callback(self, is_enabled)
----@field on_tick druid.event On timer tick.
----@field on_timer_end druid.event On timer end callback
----@field target number Target timer value
----@field value number Current timer value
-local druid__timer = {}
-
---- The @{Timer} constructor
----@param self druid.timer @{Timer}
----@param node node Gui text node
----@param seconds_from number|nil Start timer value in seconds
----@param seconds_to number|nil End timer value in seconds
----@param callback function|nil Function on timer end
-function druid__timer.init(self, node, seconds_from, seconds_to, callback) end
-
---- Set time interval
----@param self druid.timer @{Timer}
----@param from number Start time in seconds
----@param to number Target time in seconds
-function druid__timer.set_interval(self, from, to) end
-
---- Called when update
----@param self druid.timer @{Timer}
----@param is_on boolean|nil Timer enable state
-function druid__timer.set_state(self, is_on) end
-
---- Set text to text field
----@param self druid.timer @{Timer}
----@param set_to number Value in seconds
-function druid__timer.set_to(self, set_to) end
-
-
----@class druid_instance
-local druid_instance = {}
-
---- Call this in gui_script final function.
----@param self druid_instance
-function druid_instance.final(self) end
-
---- Create @{BackHandler} component
----@param self druid_instance
----@param callback function|nil @The callback(self, custom_args) to call on back event
----@param params any|nil Callback argument
----@return druid.back_handler @{BackHandler} component
-function druid_instance.new_back_handler(self, callback, params) end
-
---- Create @{Blocker} component
----@param self druid_instance
----@param node string|node The node_id or gui.get_node(node_id)
----@return druid.blocker @{Blocker} component
-function druid_instance.new_blocker(self, node) end
-
---- Create @{Button} component
----@param self druid_instance
----@param node string|node The node_id or gui.get_node(node_id)
----@param callback function|nil Button callback
----@param params any|nil Button callback params
----@param anim_node node|string|nil Button anim node (node, if not provided)
----@return druid.button @{Button} component
-function druid_instance.new_button(self, node, callback, params, anim_node) end
-
---- Create @{DataList} component
----@param self druid_instance
----@param druid_scroll druid.scroll The Scroll instance for Data List component
----@param druid_grid druid.static_grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component
----@param create_function function The create function callback(self, data, index, data_list). Function should return (node, [component])
----@return druid.data_list @{DataList} component
-function druid_instance.new_data_list(self, druid_scroll, druid_grid, create_function) end
-
---- Create @{Drag} component
----@param self druid_instance
----@param node string|node The node_id or gui.get_node(node_id). Will used as user input node.
----@param on_drag_callback function|nil Callback for on_drag_event(self, dx, dy)
----@return druid.drag @{Drag} component
-function druid_instance.new_drag(self, node, on_drag_callback) end
-
---- Create @{DynamicGrid} component Deprecated
----@param self druid_instance
----@param parent_node string|node The node_id or gui.get_node(node_id). Parent of all Grid items.
----@return druid.dynamic_grid @{DynamicGrid} component
-function druid_instance.new_dynamic_grid(self, parent_node) end
-
---- Create @{Hotkey} component
----@param self druid_instance
----@param keys_array string|string[] Keys for trigger action. Should contains one action key and any amount of modificator keys
----@param callback function The callback function
----@param callback_argument any|nil The argument to pass into the callback function
----@return druid.hotkey @{Hotkey} component
-function druid_instance.new_hotkey(self, keys_array, callback, callback_argument) end
-
---- Create @{Hover} component
----@param self druid_instance
----@param node string|node The node_id or gui.get_node(node_id)
----@param on_hover_callback function|nil Hover callback
----@param on_mouse_hover_callback function|nil Mouse hover callback
----@return druid.hover @{Hover} component
-function druid_instance.new_hover(self, node, on_hover_callback, on_mouse_hover_callback) end
-
---- Create @{Input} component
----@param self druid_instance
----@param click_node string|node Button node to enabled input component
----@param text_node string|node|druid.text Text node what will be changed on user input
----@param keyboard_type number|nil Gui keyboard type for input field
----@return druid.input @{Input} component
-function druid_instance.new_input(self, click_node, text_node, keyboard_type) end
-
---- Create @{LangText} component
----@param self druid_instance
----@param node string|node The_node id or gui.get_node(node_id)
----@param locale_id string|nil Default locale id or text from node as default
----@param adjust_type string|nil Adjust type for text node. Default: const.TEXT_ADJUST.DOWNSCALE
----@return druid.lang_text @{LangText} component
-function druid_instance.new_lang_text(self, node, locale_id, adjust_type) end
-
---- Create @{Layout} component
----@param self druid_instance
----@param node string|node The_node id or gui.get_node(node_id).
----@param mode string The layout mode
----@return druid.layout @{Layout} component
-function druid_instance.new_layout(self, node, mode) end
-
---- Create @{Progress} component
----@param self druid_instance
----@param node string|node Progress bar fill node or node name
----@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y
----@param init_value number|nil Initial value of progress bar. Default: 1
----@return druid.progress @{Progress} component
-function druid_instance.new_progress(self, node, key, init_value) end
-
---- Create @{RichInput} component.
---- As a template please check rich_input.gui layout.
----@param self druid_instance
----@param template string The template string name
----@param nodes table Nodes table from gui.clone_tree
----@return druid.rich_input @{RichInput} component
-function druid_instance.new_rich_input(self, template, nodes) end
-
---- Create @{RichText} component.
----@param self druid_instance
----@param text_node string|node The text node to make Rich Text
----@param value string|nil The initial text value. Default will be gui.get_text(text_node)
----@return druid.rich_text @{RichText} component
-function druid_instance.new_rich_text(self, text_node, value) end
-
---- Create @{Scroll} component
----@param self druid_instance
----@param view_node string|node The node_id or gui.get_node(node_id). Will used as user input node.
----@param content_node string|node The node_id or gui.get_node(node_id). Will used as scrollable node inside view_node.
----@return druid.scroll @{Scroll} component
-function druid_instance.new_scroll(self, view_node, content_node) end
-
---- Create @{Slider} component
----@param self druid_instance
----@param pin_node string|node The_node id or gui.get_node(node_id).
----@param end_pos vector3 The end position of slider
----@param callback function|nil On slider change callback
----@return druid.slider @{Slider} component
-function druid_instance.new_slider(self, pin_node, end_pos, callback) end
-
---- Create @{StaticGrid} component
----@param self druid_instance
----@param parent_node string|node The node_id or gui.get_node(node_id). Parent of all Grid items.
----@param item string|node Item prefab. Required to get grid's item size. Can be adjusted separately.
----@param in_row number|nil How many nodes in row can be placed
----@return druid.static_grid @{StaticGrid} component
-function druid_instance.new_static_grid(self, parent_node, item, in_row) end
-
---- Create @{Swipe} component
----@param self druid_instance
----@param node string|node The node_id or gui.get_node(node_id). Will used as user input node.
----@param on_swipe_callback function|nil Swipe callback for on_swipe_end event
----@return druid.swipe @{Swipe} component
-function druid_instance.new_swipe(self, node, on_swipe_callback) end
-
---- Create @{Text} component
----@param self druid_instance
----@param node string|node The node_id or gui.get_node(node_id)
----@param value string|nil Initial text. Default value is node text from GUI scene.
----@param no_adjust boolean|nil If true, text will be not auto-adjust size
----@return druid.text @{Text} component
-function druid_instance.new_text(self, node, value, no_adjust) end
-
---- Create @{Timer} component
----@param self druid_instance
----@param node string|node Gui text node
----@param seconds_from number Start timer value in seconds
----@param seconds_to number|nil End timer value in seconds
----@param callback function|nil Function on timer end
----@return druid.timer @{Timer} component
-function druid_instance.new_timer(self, node, seconds_from, seconds_to, callback) end
-
---- Call this in gui_script on_input function.
---- Used for almost all components
----@param self druid_instance
----@param action_id hash Action_id from on_input
----@param action table Action from on_input
----@return boolean The boolean value is input was consumed
-function druid_instance.on_input(self, action_id, action) end
-
---- Call this in gui_script on_message function.
---- Used for special actions. See SPECIFIC_UI_MESSAGES table
----@param self druid_instance
----@param message_id hash Message_id from on_message
----@param message table Message from on_message
----@param sender url Sender from on_message
-function druid_instance.on_message(self, message_id, message, sender) end
-
---- Remove created component from Druid instance.
---- Component `on_remove` function will be invoked, if exist.
----@param self druid_instance
----@param component druid.base_component Component instance
----@return boolean True if component was removed
-function druid_instance.remove(self, component) end
-
---- Set blacklist components for input processing.
---- If blacklist is not empty and component contains in this list, component will be not processed on input step
----@param self druid_instance @{DruidInstance}
----@param blacklist_components table|druid.base_component|nil The array of component to blacklist
----@return self @{DruidInstance}
-function druid_instance.set_blacklist(self, blacklist_components) end
-
---- Set whitelist components for input processing.
---- If whitelist is not empty and component not contains in this list, component will be not processed on input step
----@param self druid_instance
----@param whitelist_components table|druid.base_component|nil The array of component to whitelist
----@return self @{DruidInstance}
-function druid_instance.set_whitelist(self, whitelist_components) end
-
---- Call this in gui_script update function.
---- Used for: scroll, progress, timer components
----@param self druid_instance
----@param dt number Delta time
-function druid_instance.update(self, dt) end
-
-
----@class helper
-local helper = {}
-
---- Add all elements from source array to the target array
----@param target any[] Array to put elements from source
----@param source any[]|nil The source array to get elements from
----@return any[] The target array
-function helper.add_array(target, source) end
-
---- Centerate nodes by x position with margin.
---- This functions calculate total width of nodes and set position for each node. The centrate will be around 0 x position.
----@param margin number|nil Offset between nodes
----@param ... unknown Gui nodes
-function helper.centrate_nodes(margin, ...) end
-
---- Clamp value between min and max
----@param a number Value
----@param min number Min value
----@param max number Max value
----@return number Clamped value
-function helper.clamp(a, min, max) end
-
---- Check if value is in array and return index of it
----@param t table Array
----@param value unknown Value
----@return number|nil Index of value or nil
-function helper.contains(t, value) end
-
---- Make a copy table with all nested tables
----@param orig_table table Original table
----@return table Copy of original table
-function helper.deepcopy(orig_table) end
-
---- Calculate distance between two points
----@param x1 number First point x
----@param y1 number First point y
----@param x2 number Second point x
----@param y2 number Second point y
----@return number Distance
-function helper.distance(x1, y1, x2, y2) end
-
---- Distance from node position to his borders
----@param node node GUI node
----@param offset vector3|nil Offset from node position. Pass current node position to get non relative border values
----@return vector4 Vector4 with border values (left, top, right, down)
-function helper.get_border(node, offset) end
-
---- Return closest non inverted clipping parent node for given node
----@param node node GUI node
----@return node|nil The closest stencil node or nil
-function helper.get_closest_stencil_node(node) end
-
---- Get current GUI scale for each side
----@return number scale_x
----@return number scale_y
-function helper.get_gui_scale() end
-
---- Get node offset for given GUI pivot.
---- Offset shown in [-0.5 .. 0.5] range, where -0.5 is left or bottom, 0.5 is right or top.
----@param pivot number The gui.PIVOT_* constant
----@return vector3 Vector offset with [-0.5..0.5] values
-function helper.get_pivot_offset(pivot) end
-
---- Get node size adjusted by scale
----@param node node GUI node
----@return vector3 Scaled size
-function helper.get_scaled_size(node) end
-
---- Get cumulative parent's node scale
----@param node node Gui node
----@param include_passed_node_scale boolean|nil True if add current node scale to result
----@return vector3 The scene node scale
-function helper.get_scene_scale(node, include_passed_node_scale) end
-
---- Get current screen stretch multiplier for each side
----@return number stretch_x
----@return number stretch_y
-function helper.get_screen_aspect_koef() end
-
---- Get text metric from GUI node.
----@param text_node node
----@return GUITextMetrics
-function helper.get_text_metrics_from_node(text_node) end
-
---- Add value to array with shift policy
---- Shift policy can be: left, right, no_shift
----@param array table Array
----@param any unknown Item to insert
----@param index number|nil Index to insert. If nil, item will be inserted at the end of array
----@param shift_policy number|nil The druid_const.SHIFT.* constant
----@return any Inserted item
-function helper.insert_with_shift(array, any, index, shift_policy) end
-
---- Check if device is native mobile (Android or iOS)
----@return boolean Is mobile
-function helper.is_mobile() end
-
---- Check if device is mobile and can support multitouch
----@return boolean Is multitouch supported
-function helper.is_multitouch_supported() end
-
---- Check if device is HTML5
----@return boolean Is web
-function helper.is_web() end
-
---- Check if device is HTML5 mobile
----@return boolean Is web mobile
-function helper.is_web_mobile() end
-
---- Lerp between two values
----@param a number First value
----@param b number Second value
----@param t number Lerp amount
----@return number Lerped value
-function helper.lerp(a, b, t) end
-
---- Remove value from array with shift policy
---- Shift policy can be: left, right, no_shift
----@param array table Array
----@param index number|nil Index to remove. If nil, item will be removed from the end of array
----@param shift_policy number|nil The druid_const.SHIFT.* constant
----@return any Removed item
-function helper.remove_with_shift(array, index, shift_policy) end
-
---- Round number to specified decimal places
----@param num number Number
----@param num_decimal_places number|nil Decimal places
----@return number Rounded number
-function helper.round(num, num_decimal_places) end
-
---- Return sign of value (-1, 0, 1)
----@param val number Value
----@return number Sign
-function helper.sign(val) end
-
---- Move value from current to target value with step amount
----@param current number Current value
----@param target number Target value
----@param step number Step amount
----@return number New value
-function helper.step(current, target, step) end
-
---- Simple table to one-line string converter
----@param t table
----@return string
-function helper.table_to_string(t) end
-
-
--- Manual Annotations --
-
----@class druid.component: druid.base_component
-
----@class druid.rich_text.metrics
----@field width number
----@field height number
----@field offset_x number|nil
----@field offset_y number|nil
----@field max_ascent number
----@field max_descent number
----@field node_size vector3|nil @For images only
-
----@class druid.rich_text.lines_metrics
----@field text_width number
----@field text_height number
----@field lines table
-
----@class druid.rich_text.word
----@field node node
----@field relative_scale number
----@field color vector4
----@field position vector3
----@field offset vector3
----@field scale vector3
----@field size vector3
----@field metrics druid.rich_text.metrics
----@field pivot userdata @ The gui.PIVOT_* constant
----@field text string
----@field shadow vector4
----@field outline vector4
----@field font string
----@field image druid.rich_text.image
----@field default_animation string
----@field anchor number
----@field br boolean
----@field nobr boolean
----@field source_text string
----@field image_color vector4
----@field text_color vector4
-
----@class druid.rich_text.image
----@field texture string
----@field anim string
----@field width number
----@field height number
-
----@class druid.rich_text.settings
----@field parent node
----@field size number
----@field fonts table
----@field scale vector3
----@field color vector4
----@field shadow vector4
----@field outline vector4
----@field position vector3
----@field image_pixel_grid_snap boolean
----@field combine_words boolean
----@field default_animation string
----@field text_prefab node
----@field adjust_scale number
----@field default_texture string
----@field is_multiline boolean
----@field text_leading number
----@field font hash
----@field width number
----@field height number
-
----@class GUITextMetrics
----@field width number
----@field height number
----@field max_ascent number
----@field max_descent number
-
----@class utf8
----@field len fun(s: string):number
----@field sub fun(s: string, start_index: number, length: number)
----@field reverse fun()
----@field char fun()
----@field unicode fun()
----@field gensub fun()
----@field byte fun()
----@field find fun()
----@field match fun(s: string, m: string)
----@field gmatch fun(s: string, m: string)
----@field gsub fun()
----@field dump fun()
----@field format fun()
----@field lower fun()
----@field upper fun()
----@field rep fun()
-
-
----Add generics to some functions.
-
----Create new component.
----@generic T: druid.base_component
----@param self druid_instance
----@param component T Component module
----@param ... any Other component params to pass it to component:init function
----@return T Component instance
-function druid_instance.new(self, component, ...) end
-
---- Set current component style table.
---- Invoke `on_style_change` on component, if exist. Component should handle their style changing and store all style params
----@generic T: druid.base_component
----@param self T @{BaseComponent}
----@param druid_style table|nil Druid style module
----@return T @{BaseComponent}
-function druid__base_component.set_style(self, druid_style) end
-
---- Set component template name.
---- Use on all your custom components with GUI layouts used as templates. It will check parent template name to build full template name in self:get_node()
----@generic T: druid.base_component
----@param self T @{BaseComponent}
----@param template string BaseComponent template name
----@return T @{BaseComponent}
-function druid__base_component.set_template(self, template) end
-
---- Set current component nodes.
---- Use if your component nodes was cloned with `gui.clone_tree` and you got the node tree.
----@generic T: druid.base_component
----@param self T @{BaseComponent}
----@param nodes table BaseComponent nodes table
----@return T @{BaseComponent}
-function druid__base_component.set_nodes(self, nodes) end
diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua
index 899e12e..534eae7 100644
--- a/druid/base/back_handler.lua
+++ b/druid/base/back_handler.lua
@@ -1,65 +1,24 @@
--- Copyright (c) 2023 Maksim Tuprikov . This code is licensed under MIT license
-
---- Component with event on back and backspace button.
--- # Overview #
---
--- Back Handler is recommended to put in every game window to close it
--- or in main screen to call settings window.
---
--- # Notes #
---
--- • 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
--- local callback = function(self, params) ... end
---
--- local params = {}
--- local back_handler = self.druid:new_back_handler(callback, [params])
--- @module BackHandler
--- @within BaseComponent
--- @alias druid.back_handler
-
---- The @{DruidEvent} Event on back handler action.
---
--- Trigger on input action ACTION_BACK or ACTION_BACKSPACE
--- @usage
--- -- Subscribe additional callbacks:
--- back_handler.on_back:subscribe(callback)
--- @tfield DruidEvent on_back @{DruidEvent}
-
---- Custom args to pass in the callback
--- @usage
--- -- Replace params on runtime:
--- back_handler.params = { ... }
--- @tfield any|nil params
-
----
-
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local component = require("druid.component")
-local BackHandler = component.create("back_handler")
+---@class druid.back_handler: druid.base_component
+---@field on_back event Trigger on back handler action, fun(self, params)
+---@field params any|nil Custom args to pass in the callback
+local M = component.create("back_handler")
---- The @{BackHandler} constructor
--- @tparam BackHandler self @{BackHandler}
--- @tparam function callback @The callback(self, custom_args) to call on back event
--- @tparam any|nil custom_args Button events custom arguments
--- @local
-function BackHandler.init(self, callback, custom_args)
- self.params = custom_args
- self.on_back = Event(callback)
+---@param callback function|nil
+---@param params any|nil
+function M:init(callback, params)
+ self.params = params
+ self.on_back = event.create(callback)
end
---- Component input handler
--- @tparam BackHandler self @{BackHandler}
--- @tparam string action_id on_input action id
--- @tparam table action on_input action
--- @local
-function BackHandler.on_input(self, action_id, action)
+---@param action_id string
+---@param action table
+function M:on_input(action_id, action)
if not action.released then
return false
end
@@ -73,4 +32,4 @@ function BackHandler.on_input(self, action_id, action)
end
-return BackHandler
+return M
diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua
index 92fc414..bbd1890 100644
--- a/druid/base/blocker.lua
+++ b/druid/base/blocker.lua
@@ -1,50 +1,22 @@
--- Copyright (c) 2023 Maksim Tuprikov . This code is licensed under MIT license
-
---- Component to consume input in special zone defined by GUI node.
--- # Overview #
---
--- # Notes #
---
--- Blocker consume input if `gui.pick_node` works on it.
---
--- • 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
--- local node = gui.get_node("blocker_node")
--- local blocker = self.druid:new_blocker(node)
--- @module Blocker
--- @within BaseComponent
--- @alias druid.blocker
-
----Blocker node
--- @tfield node node
-
----
-
local const = require("druid.const")
local component = require("druid.component")
-local Blocker = component.create("blocker")
+---@class druid.blocker: druid.base_component
+---@field node node
+---@field private _is_enabled boolean
+local M = component.create("blocker")
---- The @{Blocker} constructor
--- @tparam Blocker self @{Blocker}
--- @tparam node node Gui node
-function Blocker.init(self, node)
+---@param node node
+function M:init(node)
self.node = self:get_node(node)
self._is_enabled = gui.is_enabled(self.node, true)
end
---- Component input handler
--- @tparam Blocker self @{Blocker}
--- @tparam string action_id on_input action id
--- @tparam table action on_input action
--- @local
-function Blocker.on_input(self, action_id, action)
+---@param action_id string
+---@param action table
+function M:on_input(action_id, action)
if action_id ~= const.ACTION_TOUCH and
action_id ~= const.ACTION_MULTITOUCH and
action_id ~= nil then
@@ -67,22 +39,21 @@ function Blocker.on_input(self, action_id, action)
end
---- Set enabled blocker component state.
---
--- Don't change node enabled state itself.
--- @tparam Blocker self @{Blocker}
--- @tparam boolean|nil state Enabled state
-function Blocker.set_enabled(self, state)
+---Set blocker enabled state
+---@param state boolean
+---@return druid.blocker self
+function M:set_enabled(state)
self._is_enabled = state
+
+ return self
end
---- Return blocker enabled state
--- @tparam Blocker self @{Blocker}
--- @treturn boolean @True, if blocker is enabled
-function Blocker.is_enabled(self)
+---Get blocker enabled state
+---@return boolean
+function M:is_enabled()
return self._is_enabled
end
-return Blocker
+return M
diff --git a/druid/base/button.lua b/druid/base/button.lua
index 9b09c48..f1c48dc 100755
--- a/druid/base/button.lua
+++ b/druid/base/button.lua
@@ -35,16 +35,16 @@
-- @alias druid.button
---- The @{DruidEvent}: Event on successful release action over button.
+--- The event: 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 event on_click event
---- The @{DruidEvent}: Event on repeated action over button.
+--- The event: 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
@@ -52,10 +52,10 @@
-- 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 event on_repeated_click event
---- The @{DruidEvent}: Event on long tap action over button.
+--- The event: 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
@@ -64,10 +64,10 @@
-- 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 event on_long_click event
---- The @{DruidEvent}: Event on double tap action over button.
+--- The event: 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)
@@ -76,10 +76,10 @@
-- 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 event on_double_click event
---- The @{DruidEvent}: Event calls every frame before on_long_click event.
+--- The event: 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.
--
@@ -89,10 +89,10 @@
-- 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 event on_hold_callback event
---- The @{DruidEvent}: Event calls if click event was outside of button.
+--- The event: 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
--
@@ -102,16 +102,16 @@
-- button.on_click_outside:subscribe(function(self, custom_args, button_instance)
-- print("On click Button outside!")
-- end)
--- @tfield DruidEvent on_click_outside @{DruidEvent}
+-- @tfield event on_click_outside event
---- The @{DruidEvent}: Event triggered if button was pressed by user.
+--- The event: 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 event on_pressed event
--- Button trigger node
-- @tfield node node
@@ -128,20 +128,40 @@
---Custom args for any Button event. Setup in Button constructor
-- @tfield any params
---- The @{Hover}: Button Hover component
--- @tfield Hover hover @{Hover}
+--- The Hover: Button Hover component
+-- @tfield Hover hover Hover
--- Additional button click area, defined by another GUI node
-- @tfield node|nil click_zone
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Button = component.create("button")
+---Clickable node with various interaction callbacks
+---@class druid.button: druid.base_component
+---@field on_click event function(self, custom_args, button_instance)
+---@field on_pressed event
+---@field on_repeated_click event
+---@field on_long_click event
+---@field on_double_click event
+---@field on_hold_callback event
+---@field on_click_outside event
+---@field node node
+---@field node_id hash
+---@field anim_node node
+---@field params any
+---@field hover druid.hover
+---@field click_zone node|nil
+---@field start_scale vector3
+---@field start_pos vector3
+---@field disabled boolean
+---@field key_trigger hash
+---@field style table
+local M = component.create("button")
local function is_input_match(self, action_id)
@@ -210,6 +230,7 @@ local function on_button_hold(self, press_time)
end
+---@param self druid.button
local function on_button_release(self)
if self.is_repeated_started then
return false
@@ -234,10 +255,10 @@ local function on_button_release(self)
local time = socket.gettime()
local is_long_click = (time - self.last_pressed_time) >= self.style.LONGTAP_TIME
- is_long_click = is_long_click and self.on_long_click:is_exist()
+ is_long_click = is_long_click and not self.on_long_click:is_empty()
local is_double_click = (time - self.last_released_time) < self.style.DOUBLETAP_TIME
- is_double_click = is_double_click and self.on_double_click:is_exist()
+ is_double_click = is_double_click and not self.on_double_click:is_empty()
if is_long_click then
local is_hold_complete = (time - self.last_pressed_time) >= self.style.AUTOHOLD_TRIGGER
@@ -260,18 +281,20 @@ end
--- Component style params.
--- You can override this component styles params in Druid styles table
--- or create your own style
--- @table style
--- @tfield number|nil LONGTAP_TIME Minimum time to trigger on_hold_callback. Default: 0.4
--- @tfield number|nil AUTOHOLD_TRIGGER Maximum hold time to trigger button release while holding. Default: 0.8
--- @tfield number|nil DOUBLETAP_TIME Time between double taps. Default: 0.4
--- @tfield function on_click function(self, node)
--- @tfield function on_click_disabled function(self, node)
--- @tfield function on_hover function(self, node, hover_state)
--- @tfield function on_mouse_hover function(self, node, hover_state)
--- @tfield function on_set_enabled function(self, node, enabled_state)
-function Button.on_style_change(self, style)
+---You can override this component styles params in Druid styles table
+---or create your own style
+---@class druid.button.style
+---@field LONGTAP_TIME number|nil Minimum time to trigger on_hold_callback. Default: 0.4
+---@field AUTOHOLD_TRIGGER number|nil Maximum hold time to trigger button release while holding. Default: 0.8
+---@field DOUBLETAP_TIME number|nil Time between double taps. Default: 0.4
+---@field on_click fun(self, node)|nil
+---@field on_click_disabled fun(self, node)|nil
+---@field on_hover fun(self, node, hover_state)|nil
+---@field on_mouse_hover fun(self, node, hover_state)|nil
+---@field on_set_enabled fun(self, node, enabled_state)|nil
+
+---@param style druid.button.style
+function M:on_style_change(style)
self.style = {}
self.style.LONGTAP_TIME = style.LONGTAP_TIME or 0.4
self.style.AUTOHOLD_TRIGGER = style.AUTOHOLD_TRIGGER or 0.8
@@ -285,22 +308,21 @@ function Button.on_style_change(self, style)
end
---- The @{Button} constructor
--- @tparam Button self @{Button}
--- @tparam string|node node The node_id or gui.get_node(node_id)
--- @tparam function callback On click button callback
--- @tparam any|nil custom_args Button events custom arguments
--- @tparam string|node|nil anim_node Node to animate instead of trigger node.
-function Button.init(self, node, callback, custom_args, anim_node)
+---Button constructor
+---@param node_or_node_id node|string Node name or GUI Node itself.
+---@param callback fun()|nil Callback on button click
+---@param custom_args any|nil Custom args for any Button event
+---@param anim_node node|string|nil Node to animate instead of trigger node.
+function M:init(node_or_node_id, callback, custom_args, anim_node)
self.druid = self:get_druid()
- self.node = self:get_node(node)
+ self.node = self:get_node(node_or_node_id)
self.node_id = gui.get_id(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_pos = gui.get_position(self.anim_node)
self.params = custom_args
- self.hover = self.druid:new_hover(node, on_button_hover)
+ self.hover = self.druid:new_hover(node_or_node_id, on_button_hover)
self.hover.on_mouse_hover:subscribe(on_button_mouse_hover)
self.click_zone = nil
self.is_repeated_started = false
@@ -315,18 +337,18 @@ function Button.init(self, node, callback, custom_args, anim_node)
self._is_html5_listener_set = false
-- Events
- self.on_click = Event(callback)
- self.on_pressed = Event()
- self.on_repeated_click = Event()
- self.on_long_click = Event()
- self.on_double_click = Event()
- self.on_hold_callback = Event()
- self.on_click_outside = Event()
+ self.on_click = event.create(callback)
+ self.on_pressed = event.create()
+ self.on_repeated_click = event.create()
+ self.on_long_click = event.create()
+ self.on_double_click = event.create()
+ self.on_hold_callback = event.create()
+ self.on_click_outside = event.create()
end
-function Button.on_late_init(self)
- if not self.click_zone and const.IS_STENCIL_CHECK then
+function M:on_late_init()
+ if not self.click_zone then
local stencil_node = helper.get_closest_stencil_node(self.node)
if stencil_node then
self:set_click_zone(stencil_node)
@@ -335,7 +357,7 @@ function Button.on_late_init(self)
end
-function Button.on_input(self, action_id, action)
+function M:on_input(action_id, action)
if not is_input_match(self, action_id) then
return false
end
@@ -388,7 +410,7 @@ function Button.on_input(self, action_id, action)
-- While hold button, repeat rate pick from input.repeat_interval
if action.repeated then
- if self.on_repeated_click:is_exist() and self.can_action then
+ if not self.on_repeated_click:is_empty() and self.can_action then
on_button_repeated_click(self)
return is_consume
end
@@ -398,7 +420,7 @@ function Button.on_input(self, action_id, action)
return on_button_release(self) and is_consume
end
- if self.can_action and self.on_long_click:is_exist() then
+ if self.can_action and not self.on_long_click:is_empty() then
local press_time = socket.gettime() - self.last_pressed_time
if self.style.AUTOHOLD_TRIGGER <= press_time then
@@ -416,48 +438,19 @@ function Button.on_input(self, action_id, action)
end
-function Button.on_input_interrupt(self)
+function M:on_input_interrupt()
self.can_action = false
self.hover:set_hover(false)
self.hover:set_mouse_hover(false)
end
-function Button.on_message_input(self, node_id, message)
- if node_id ~= self.node_id or self.disabled or not gui.is_enabled(self.node) then
- return false
- end
-
- if message.action == const.MESSAGE_INPUT.BUTTON_CLICK then
- on_button_click(self)
- end
-
- if message.action == const.MESSAGE_INPUT.BUTTON_LONG_CLICK then
- on_button_long_click(self)
- end
-
- if message.action == const.MESSAGE_INPUT.BUTTON_DOUBLE_CLICK then
- on_button_double_click(self)
- end
-
- if message.action == const.MESSAGE_INPUT.BUTTON_REPEATED_CLICK then
- on_button_repeated_click(self)
- self.is_repeated_started = false
- self.last_pressed_time = socket.gettime()
- end
-end
-
-
--- Set button enabled state.
-- The style.on_set_enabled will be triggered.
-- Disabled button is not clickable.
--- @tparam Button self @{Button}
--- @tparam boolean|nil state Enabled state
--- @treturn Button Current button instance
--- @usage
--- button:set_enabled(false)
--- button:set_enabled(true)
-function Button.set_enabled(self, state)
+---@param state boolean|nil Enabled state
+---@return druid.button self
+function M:set_enabled(state)
self.disabled = not state
self.hover:set_enabled(state)
self.style.on_set_enabled(self, self.node, state)
@@ -469,11 +462,8 @@ end
--- Get button enabled state.
--
-- By default all Buttons is enabled on creating.
--- @tparam Button self @{Button}
--- @treturn boolean @True, if button is enabled now, False overwise
--- @usage
--- local is_enabled = button:is_enabled()
-function Button.is_enabled(self)
+---@return boolean @True, if button is enabled now, False overwise
+function M:is_enabled()
return not self.disabled
end
@@ -482,68 +472,61 @@ end
-- 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 node|string|nil zone Gui node
--- @treturn Button Current button instance
--- @usage
--- button:set_click_zone("stencil_node")
-function Button.set_click_zone(self, zone)
- self.click_zone = self:get_node(zone)
+---@param zone node|string|nil Gui node
+---@return druid.button self
+function M:set_click_zone(zone)
+ self.click_zone = zone and self:get_node(zone) or nil
self.hover:set_click_zone(zone)
return self
end
---- Set key name to trigger this button by keyboard.
--- @tparam Button self @{Button}
--- @tparam hash|string key The action_id of the input key
--- @treturn Button Current button instance
--- @usage
--- button:set_key_trigger("key_space")
-function Button.set_key_trigger(self, key)
- self.key_trigger = hash(key)
+---Set key name to trigger this button by keyboard.
+---@param key hash|string The action_id of the input key. Example: "key_space"
+---@return druid.button self
+function M:set_key_trigger(key)
+ if type(key) == "string" then
+ self.key_trigger = hash(key)
+ else
+ self.key_trigger = key
+ end
return self
end
--- Get current key name to trigger this button.
--- @tparam Button self
--- @treturn hash The action_id of the input key
--- @usage
--- local key_hash = button:get_key_trigger()
-function Button.get_key_trigger(self)
+---@return hash key_trigger The action_id of the input key
+function M:get_key_trigger()
return self.key_trigger
end
---- Set function for additional check for button click availability
--- @tparam Button self
--- @tparam function|nil check_function Should return true or false. If true - button can be pressed.
--- @tparam function|nil failure_callback Function will be called on button click, if check function return false
--- @treturn Button Current button instance
-function Button.set_check_function(self, check_function, failure_callback)
+---Set function for additional check for button click availability
+---@param check_function function|nil Should return true or false. If true - button can be pressed.
+---@param failure_callback function|nil Function will be called on button click, if check function return false
+---@return druid.button self
+function M:set_check_function(check_function, failure_callback)
self._check_function = check_function
self._failure_callback = failure_callback
+
+ return self
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
--- @tparam Button self
--- @tparam boolean|nil is_web_mode If true - button will be called inside html5 callback
--- @treturn Button Current button instance
--- @usage
--- button:set_web_user_interaction(true)
-function Button.set_web_user_interaction(self, is_web_mode)
+---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 is_web_mode boolean|nil If true - button will be called inside html5 callback
+---@return druid.button self
+function M:set_web_user_interaction(is_web_mode)
self._is_html5_mode = not not (is_web_mode and html5)
return self
end
-return Button
+return M
diff --git a/druid/base/drag.lua b/druid/base/drag.lua
index fd79105..ee5a3dc 100644
--- a/druid/base/drag.lua
+++ b/druid/base/drag.lua
@@ -14,19 +14,19 @@
-- @tfield node node
--- Event on touch start callback(self)
--- @tfield DruidEvent on_touch_start @{DruidEvent}
+-- @tfield event on_touch_start event
--- Event on touch end callback(self)
--- @tfield DruidEvent on_touch_end @{DruidEvent}
+-- @tfield event on_touch_end event
--- Event on drag start callback(self, touch)
--- @tfield DruidEvent on_drag_start @{DruidEvent}
+-- @tfield event on_drag_start event
--- on drag progress callback(self, dx, dy, total_x, total_y, touch)
--- @tfield DruidEvent on_drag Event @{DruidEvent}
+-- @tfield event on_drag Event event
--- Event on drag end callback(self, total_x, total_y, touch)
--- @tfield DruidEvent on_drag_end @{DruidEvent}
+-- @tfield event on_drag_end event
--- Is component now touching
-- @tfield boolean is_touch
@@ -57,12 +57,40 @@
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Drag = component.create("drag", const.PRIORITY_INPUT_HIGH)
+---@class druid.drag.style
+---@field DRAG_DEADZONE number Distance in pixels to start dragging. Default: 10
+---@field NO_USE_SCREEN_KOEF boolean If screen aspect ratio affects on drag values. Default: false
+
+---@class druid.drag: druid.base_component
+---@field node node
+---@field on_touch_start event
+---@field on_touch_end event
+---@field on_drag_start event
+---@field on_drag event
+---@field on_drag_end event
+---@field style druid.drag.style
+---@field click_zone node|nil
+---@field is_touch boolean
+---@field is_drag boolean
+---@field can_x boolean
+---@field can_y boolean
+---@field dx number
+---@field dy number
+---@field touch_id number
+---@field x number
+---@field y number
+---@field screen_x number
+---@field screen_y number
+---@field touch_start_pos vector3
+---@field private _is_enabled boolean
+---@field private _x_koef number
+---@field private _y_koef number
+local M = component.create("drag", const.PRIORITY_INPUT_HIGH)
local function start_touch(self, touch)
@@ -177,19 +205,21 @@ end
-- @table style
-- @tfield number|nil DRAG_DEADZONE Distance in pixels to start dragging. Default: 10
-- @tfield boolean|nil NO_USE_SCREEN_KOEF If screen aspect ratio affects on drag values. Default: false
-function Drag.on_style_change(self, style)
- self.style = {}
- self.style.DRAG_DEADZONE = style.DRAG_DEADZONE or 10
- self.style.NO_USE_SCREEN_KOEF = style.NO_USE_SCREEN_KOEF or false
+function M:on_style_change(style)
+ self.style = {
+ DRAG_DEADZONE = style.DRAG_DEADZONE or 10,
+ NO_USE_SCREEN_KOEF = style.NO_USE_SCREEN_KOEF or false,
+ }
end
---- The @{Drag} constructor
--- @tparam Drag self @{Drag}
--- @tparam node node GUI node to detect dragging
--- @tparam function on_drag_callback Callback for on_drag_event(self, dx, dy)
-function Drag.init(self, node, on_drag_callback)
- self.node = self:get_node(node)
+---Drag constructor
+---@param node_or_node_id node|string
+---@param on_drag_callback function
+function M:init(node_or_node_id, on_drag_callback)
+ self.druid = self:get_druid()
+ self.node = self:get_node(node_or_node_id)
+ self.hover = self.druid:new_hover(self.node)
self.dx = 0
self.dy = 0
@@ -209,18 +239,32 @@ function Drag.init(self, node, on_drag_callback)
self._scene_scale = helper.get_scene_scale(self.node)
self.click_zone = nil
- self.on_touch_start = Event()
- self.on_touch_end = Event()
- self.on_drag_start = Event()
- self.on_drag = Event(on_drag_callback)
- self.on_drag_end = Event()
+ self.on_touch_start = event.create()
+ self.on_touch_end = event.create()
+ self.on_drag_start = event.create()
+ self.on_drag = event.create(on_drag_callback)
+ self.on_drag_end = event.create()
self:on_window_resized()
+ self:set_drag_cursors(true)
end
-function Drag.on_late_init(self)
- if not self.click_zone and const.IS_STENCIL_CHECK then
+---Set Drag component enabled state.
+---@param is_enabled boolean
+function M:set_drag_cursors(is_enabled)
+ if defos and is_enabled then
+ self.hover.style.ON_HOVER_CURSOR = defos.CURSOR_CROSSHAIR
+ self.hover.style.ON_MOUSE_HOVER_CURSOR = defos.CURSOR_HAND
+ else
+ self.hover.style.ON_HOVER_CURSOR = nil
+ self.hover.style.ON_MOUSE_HOVER_CURSOR = nil
+ end
+end
+
+
+function M:on_late_init()
+ if not self.click_zone then
local stencil_node = helper.get_closest_stencil_node(self.node)
if stencil_node then
self:set_click_zone(stencil_node)
@@ -229,7 +273,7 @@ function Drag.on_late_init(self)
end
-function Drag.on_window_resized(self)
+function M:on_window_resized()
local x_koef, y_koef = helper.get_screen_aspect_koef()
self._x_koef = x_koef
self._y_koef = y_koef
@@ -237,14 +281,17 @@ function Drag.on_window_resized(self)
end
-function Drag.on_input_interrupt(self)
+function M:on_input_interrupt()
if self.is_drag or self.is_touch then
end_touch(self)
end
end
-function Drag.on_input(self, action_id, action)
+---@local
+---@param action_id string
+---@param action table
+function M:on_input(action_id, action)
if action_id ~= const.ACTION_TOUCH and action_id ~= const.ACTION_MULTITOUCH then
return false
end
@@ -321,29 +368,31 @@ function Drag.on_input(self, action_id, action)
end
---- Strict drag click area. Useful for
--- restrict events outside stencil node
--- @tparam Drag self @{Drag}
--- @tparam node|string|nil node Gui node
-function Drag.set_click_zone(self, node)
- self.click_zone = self:get_node(node)
+---Set Drag click zone
+---@param node node|string|nil
+---@return druid.drag self Current instance
+function M:set_click_zone(node)
+ self.click_zone = node and self:get_node(node) or nil
+
+ return self
end
---- Set Drag input enabled or disabled
--- @tparam Drag self @{Drag}
--- @tparam boolean|nil is_enabled
-function Drag.set_enabled(self, is_enabled)
+---Set Drag component enabled state.
+---@param is_enabled boolean
+---@return druid.drag self Current instance
+function M:set_enabled(is_enabled)
self._is_enabled = is_enabled
+
+ return self
end
---- Check if Drag component is enabled
--- @tparam Drag self @{Drag}
--- @treturn boolean
-function Drag.is_enabled(self)
+---Check if Drag component is enabled
+---@return boolean
+function M:is_enabled()
return self._is_enabled
end
-return Drag
+return M
diff --git a/druid/base/hover.lua b/druid/base/hover.lua
index f178cf2..4ca0849 100644
--- a/druid/base/hover.lua
+++ b/druid/base/hover.lua
@@ -9,27 +9,36 @@
-- @tfield node node
--- On hover callback(self, state, hover_instance)
--- @tfield DruidEvent on_hover @{DruidEvent}
+-- @tfield event on_hover event
--- On mouse hover callback(self, state, hover_instance)
--- @tfield DruidEvent on_mouse_hover @{DruidEvent}
+-- @tfield event on_mouse_hover event
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Hover = component.create("hover")
+---@class druid.hover: druid.base_component
+---@field node node
+---@field on_hover event
+---@field on_mouse_hover event
+---@field style table
+---@field click_zone node
+---@field private _is_hovered boolean|nil
+---@field private _is_mouse_hovered boolean|nil
+---@field private _is_enabled boolean|nil
+---@field private _is_mobile boolean
+local M = component.create("hover")
---- The @{Hover} constructor
--- @tparam Hover self @{Hover}
--- @tparam node node Gui node
--- @tparam function on_hover_callback Hover callback
--- @tparam function on_mouse_hover On mouse hover callback
-function Hover.init(self, node, on_hover_callback, on_mouse_hover)
+--- The Hover constructor
+---@param node node Gui node
+---@param on_hover_callback function Hover callback
+---@param on_mouse_hover function On mouse hover callback
+function M:init(node, on_hover_callback, on_mouse_hover)
self.node = self:get_node(node)
self._is_hovered = false
@@ -37,13 +46,13 @@ function Hover.init(self, node, on_hover_callback, on_mouse_hover)
self._is_enabled = true
self._is_mobile = helper.is_mobile()
- self.on_hover = Event(on_hover_callback)
- self.on_mouse_hover = Event(on_mouse_hover)
+ self.on_hover = event.create(on_hover_callback)
+ self.on_mouse_hover = event.create(on_mouse_hover)
end
-function Hover.on_late_init(self)
- if not self.click_zone and const.IS_STENCIL_CHECK then
+function M:on_late_init()
+ if not self.click_zone then
local stencil_node = helper.get_closest_stencil_node(self.node)
if stencil_node then
self:set_click_zone(stencil_node)
@@ -58,14 +67,14 @@ end
-- @table style
-- @tfield[opt] string ON_HOVER_CURSOR Mouse hover style on node hover
-- @tfield[opt] string ON_MOUSE_HOVER_CURSOR Mouse hover style on node mouse hover
-function Hover.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.ON_HOVER_CURSOR = style.ON_HOVER_CURSOR or nil
self.style.ON_MOUSE_HOVER_CURSOR = style.ON_MOUSE_HOVER_CURSOR or nil
end
-function Hover.on_input(self, action_id, action)
+function M:on_input(action_id, action)
if action_id ~= const.ACTION_TOUCH and action_id ~= nil then
return false
end
@@ -99,15 +108,14 @@ function Hover.on_input(self, action_id, action)
end
-function Hover.on_input_interrupt(self)
+function M:on_input_interrupt()
self:set_hover(false)
end
--- Set hover state
--- @tparam Hover self @{Hover}
--- @tparam boolean|nil state The hover state
-function Hover.set_hover(self, state)
+---@param state boolean|nil The hover state
+function M:set_hover(state)
if self._is_hovered == state then
return
end
@@ -122,17 +130,15 @@ end
--- Return current hover state. True if touch action was on the node at current time
--- @tparam Hover self @{Hover}
--- @treturn boolean The current hovered state
-function Hover.is_hovered(self)
+---@return boolean The current hovered state
+function M:is_hovered()
return self._is_hovered
end
--- Set mouse hover state
--- @tparam Hover self @{Hover}
--- @tparam boolean|nil state The mouse hover state
-function Hover.set_mouse_hover(self, state)
+---@param state boolean|nil The mouse hover state
+function M:set_mouse_hover(state)
if self._is_mouse_hovered == state then
return
end
@@ -147,18 +153,21 @@ end
--- Return current hover state. True if nil action_id (usually desktop mouse) was on the node at current time
--- @tparam Hover self @{Hover}
--- @treturn boolean The current hovered state
-function Hover.is_mouse_hovered(self)
+---@return boolean The current hovered state
+function M:is_mouse_hovered()
return self._is_mouse_hovered
end
--- Strict hover click area. Useful for
-- no click events outside stencil node
--- @tparam Hover self @{Hover}
--- @tparam node|string|nil zone Gui node
-function Hover.set_click_zone(self, zone)
+---@param zone node|string|nil Gui node
+function M:set_click_zone(zone)
+ if not zone then
+ self.click_zone = nil
+ return
+ end
+
self.click_zone = self:get_node(zone)
end
@@ -166,9 +175,8 @@ end
--- Set enable state of hover component.
-- If hover is not enabled, it will not generate
-- any hover events
--- @tparam Hover self @{Hover}
--- @tparam boolean|nil state The hover enabled state
-function Hover.set_enabled(self, state)
+---@param state boolean|nil The hover enabled state
+function M:set_enabled(state)
self._is_enabled = state
if not state then
@@ -183,16 +191,16 @@ end
--- Return current hover enabled state
--- @tparam Hover self @{Hover}
--- @treturn boolean The hover enabled state
-function Hover.is_enabled(self)
+---@return boolean The hover enabled state
+function M:is_enabled()
return self._is_enabled
end
-- Internal cursor stack
local cursor_stack = {}
-function Hover:_set_cursor(priority, cursor)
+---@local
+function M:_set_cursor(priority, cursor)
if not defos then
return
end
@@ -217,4 +225,4 @@ function Hover:_set_cursor(priority, cursor)
end
-return Hover
+return M
diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua
index 3aa9f77..4bd7f75 100755
--- a/druid/base/scroll.lua
+++ b/druid/base/scroll.lua
@@ -39,13 +39,13 @@
--- On scroll move callback(self, position)
--- @tfield DruidEvent on_scroll @{DruidEvent}
+-- @tfield event on_scroll event
--- On scroll_to function callback(self, target, is_instant)
--- @tfield DruidEvent on_scroll_to @{DruidEvent}
+-- @tfield event on_scroll_to event
--- On scroll_to_index function callback(self, index, point)
--- @tfield DruidEvent on_point_scroll @{DruidEvent}
+-- @tfield event on_point_scroll event
--- Scroll view node
-- @tfield node view_node
@@ -75,7 +75,7 @@
-- @tfield vector3 available_size
--- Drag Druid component
--- @tfield Drag drag @{Drag}
+-- @tfield Drag drag Drag
--- Current index of points of interests
-- @tfield number|nil selected
@@ -85,12 +85,37 @@
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Scroll = component.create("scroll")
+---@class druid.scroll: druid.base_component
+---@field node node The root node
+---@field click_zone node|nil Optional click zone to restrict scroll area
+---@field on_scroll event Triggered on scroll move with (self, position)
+---@field on_scroll_to event Triggered on scroll_to with (self, target, is_instant)
+---@field on_point_scroll event Triggered on scroll_to_index with (self, index, point)
+---@field view_node node The scroll view node (static part)
+---@field view_border vector4 The scroll view borders
+---@field content_node node The scroll content node (moving part)
+---@field view_size vector3 Size of the view node
+---@field position vector3 Current scroll position
+---@field target_position vector3 Target scroll position for animations
+---@field available_pos vector4 Available content position (min_x, max_y, max_x, min_y)
+---@field available_size vector3 Size of available positions (width, height, 0)
+---@field drag druid.drag The drag component instance
+---@field selected number|nil Current selected point of interest index
+---@field is_animate boolean True if scroll is animating
+---@field private _is_inert boolean True if inertial scrolling is enabled
+---@field private inertion vector3 Current inertial movement vector
+---@field private _is_horizontal_scroll boolean True if horizontal scroll enabled
+---@field private _is_vertical_scroll boolean True if vertical scroll enabled
+---@field private _grid_on_change event Grid items change event
+---@field private _grid_on_change_callback function Grid change callback
+---@field private _offset vector3 Content start offset
+---@field private style table Component style parameters
+local M = component.create("scroll")
local function inverse_lerp(min, max, current)
@@ -138,7 +163,7 @@ end
-- @tfield boolean|nil WHEEL_SCROLL_SPEED The scroll speed via mouse wheel scroll or touchpad. Set to 0 to disable wheel scrolling. Default: 0
-- @tfield boolean|nil WHEEL_SCROLL_INVERTED If true, invert direction for touchpad and mouse wheel scroll. Default: false
-- @tfield boolean|nil WHEEL_SCROLL_BY_INERTION If true, wheel will add inertion to scroll. Direct set position otherwise.. Default: false
-function Scroll.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.EXTRA_STRETCH_SIZE = style.EXTRA_STRETCH_SIZE or 0
self.style.ANIM_SPEED = style.ANIM_SPEED or 0.2
@@ -161,11 +186,10 @@ function Scroll.on_style_change(self, style)
end
---- The @{Scroll} constructor
--- @tparam Scroll self @{Scroll}
--- @tparam string|node view_node GUI view scroll node
--- @tparam string|node content_node GUI content scroll node
-function Scroll.init(self, view_node, content_node)
+--- The Scroll constructor
+---@param view_node string|node GUI view scroll node
+---@param content_node string|node GUI content scroll node
+function M:init(view_node, content_node)
self.druid = self:get_druid()
self.view_node = self:get_node(view_node)
@@ -186,9 +210,9 @@ function Scroll.init(self, view_node, content_node)
self.hover.on_mouse_hover:subscribe(self._on_mouse_hover)
self._is_mouse_hover = false
- self.on_scroll = Event()
- self.on_scroll_to = Event()
- self.on_point_scroll = Event()
+ self.on_scroll = event.create()
+ self.on_scroll_to = event.create()
+ self.on_point_scroll = event.create()
self.selected = nil
self.is_animate = false
@@ -203,8 +227,8 @@ function Scroll.init(self, view_node, content_node)
end
-function Scroll.on_late_init(self)
- if not self.click_zone and const.IS_STENCIL_CHECK then
+function M:on_late_init()
+ if not self.click_zone then
local stencil_node = helper.get_closest_stencil_node(self.node)
if stencil_node then
self:set_click_zone(stencil_node)
@@ -213,15 +237,15 @@ function Scroll.on_late_init(self)
end
-function Scroll.on_layout_change(self)
+function M:on_layout_change()
gui.set_position(self.content_node, self.position)
end
-function Scroll.update(self, dt)
+function M:update(dt)
if self.is_animate then
- self.position.x = gui.get(self.content_node, "position.x")
- self.position.y = gui.get(self.content_node, "position.y")
+ self.position.x = gui.get(self.content_node, "position.x") --[[@as number]]
+ self.position.y = gui.get(self.content_node, "position.y") --[[@as number]]
self.on_scroll:trigger(self:get_context(), self.position)
end
@@ -233,23 +257,22 @@ function Scroll.update(self, dt)
end
-function Scroll.on_input(self, action_id, action)
+function M:on_input(action_id, action)
return self:_process_scroll_wheel(action_id, action)
end
-function Scroll.on_remove(self)
+function M:on_remove()
self:bind_grid(nil)
end
--- Start scroll to target point.
--- @tparam Scroll self @{Scroll}
--- @tparam vector3 point Target point
--- @tparam boolean|nil is_instant Instant scroll flag
+---@param point vector3 Target point
+---@param is_instant boolean|nil Instant scroll flag
-- @usage scroll:scroll_to(vmath.vector3(0, 50, 0))
-- @usage scroll:scroll_to(vmath.vector3(0), true)
-function Scroll.scroll_to(self, point, is_instant)
+function M:scroll_to(point, is_instant)
local b = self.available_pos
local target = vmath.vector3(
self._is_horizontal_scroll and -point.x or self.target_position.x,
@@ -278,10 +301,9 @@ end
--- Scroll to item in scroll by point index.
--- @tparam Scroll self @{Scroll}
--- @tparam number index Point index
--- @tparam boolean|nil skip_cb If true, skip the point callback
-function Scroll.scroll_to_index(self, index, skip_cb)
+---@param index number Point index
+---@param skip_cb boolean|nil If true, skip the point callback
+function M:scroll_to_index(index, skip_cb)
if not self.points then
return
end
@@ -301,11 +323,10 @@ end
--- Start scroll to target scroll percent
--- @tparam Scroll self @{Scroll}
--- @tparam vector3 percent target percent
--- @tparam boolean|nil is_instant instant scroll flag
+---@param percent vector3 target percent
+---@param is_instant boolean|nil instant scroll flag
-- @usage scroll:scroll_to_percent(vmath.vector3(0.5, 0, 0))
-function Scroll.scroll_to_percent(self, percent, is_instant)
+function M:scroll_to_percent(percent, is_instant)
local border = self.available_pos
local pos = vmath.vector3(
@@ -327,9 +348,8 @@ end
--- Return current scroll progress status.
-- Values will be in [0..1] interval
--- @tparam Scroll self @{Scroll}
--- @treturn vector3 New vector with scroll progress values
-function Scroll.get_percent(self)
+---@return vector3 New vector with scroll progress values
+function M:get_percent()
local x_perc = 1 - inverse_lerp(self.available_pos.x, self.available_pos.z, self.position.x)
local y_perc = inverse_lerp(self.available_pos.w, self.available_pos.y, self.position.y)
@@ -339,11 +359,10 @@ end
--- Set scroll content size.
-- It will change content gui node size
--- @tparam Scroll self @{Scroll}
--- @tparam vector3 size The new size for content node
--- @tparam vector3|nil offset Offset value to set, where content is starts
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_size(self, size, offset)
+---@param size vector3 The new size for content node
+---@param offset vector3|nil Offset value to set, where content is starts
+---@return druid.scroll Current scroll instance
+function M:set_size(size, offset)
if offset then
self._offset = offset
end
@@ -355,10 +374,9 @@ end
--- Set new scroll view size in case the node size was changed.
--- @tparam Scroll self @{Scroll}
--- @tparam vector3 size The new size for view node
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_view_size(self, size)
+---@param size vector3 The new size for view node
+---@return druid.scroll Current scroll instance
+function M:set_view_size(size)
gui.set_size(self.view_node, size)
self.view_size = size
self.view_border = helper.get_border(self.view_node)
@@ -369,8 +387,7 @@ end
--- Refresh scroll view size
--- @tparam Scroll self @{Scroll}
-function Scroll.update_view_size(self)
+function M:update_view_size()
self.view_size = helper.get_scaled_size(self.view_node)
self.view_border = helper.get_border(self.view_node)
self:_update_size()
@@ -382,10 +399,9 @@ end
--- Enable or disable scroll inert.
-- If disabled, scroll through points (if exist)
-- If no points, just simple drag without inertion
--- @tparam Scroll self @{Scroll}
--- @tparam boolean|nil state Inert scroll state
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_inert(self, state)
+---@param state boolean Inert scroll state
+---@return druid.scroll Current scroll instance
+function M:set_inert(state)
self._is_inert = state
return self
@@ -393,19 +409,17 @@ end
--- Return if scroll have inertion.
--- @tparam Scroll self @{Scroll}
--- @treturn boolean @If scroll have inertion
-function Scroll.is_inert(self)
+---@return boolean @If scroll have inertion
+function M:is_inert()
return self._is_inert
end
--- Set extra size for scroll stretching.
-- Set 0 to disable stretching effect
--- @tparam Scroll self @{Scroll}
--- @tparam number|nil stretch_size Size in pixels of additional scroll area
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_extra_stretch_size(self, stretch_size)
+---@param stretch_size number|nil Size in pixels of additional scroll area
+---@return druid.scroll Current scroll instance
+function M:set_extra_stretch_size(stretch_size)
self.style.EXTRA_STRETCH_SIZE = stretch_size or 0
self:_update_size()
@@ -414,19 +428,17 @@ end
--- Return vector of scroll size with width and height.
--- @tparam Scroll self @{Scroll}
--- @treturn vector3 Available scroll size
-function Scroll.get_scroll_size(self)
+---@return vector3 Available scroll size
+function M:get_scroll_size()
return self.available_size
end
--- Set points of interest.
-- Scroll will always centered on closer points
--- @tparam Scroll self @{Scroll}
--- @tparam table points Array of vector3 points
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_points(self, points)
+---@param points table Array of vector3 points
+---@return druid.scroll Current scroll instance
+function M:set_points(points)
self.points = points
table.sort(self.points, function(a, b)
@@ -440,33 +452,30 @@ end
--- Lock or unlock horizontal scroll
--- @tparam Scroll self @{Scroll}
--- @tparam boolean|nil state True, if horizontal scroll is enabled
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_horizontal_scroll(self, state)
+---@param state boolean True, if horizontal scroll is enabled
+---@return druid.scroll Current scroll instance
+function M:set_horizontal_scroll(state)
self._is_horizontal_scroll = state
- self.drag.can_x = self.available_size.x > 0 and state
+ self.drag.can_x = self.available_size.x > 0 and state or false
return self
end
--- Lock or unlock vertical scroll
--- @tparam Scroll self @{Scroll}
--- @tparam boolean|nil state True, if vertical scroll is enabled
--- @treturn druid.scroll Current scroll instance
-function Scroll.set_vertical_scroll(self, state)
+---@param state boolean True, if vertical scroll is enabled
+---@return druid.scroll Current scroll instance
+function M:set_vertical_scroll(state)
self._is_vertical_scroll = state
- self.drag.can_y = self.available_size.y > 0 and state
+ self.drag.can_y = self.available_size.y > 0 and state or false
return self
end
--- Check node if it visible now on scroll.
-- Extra border is not affected. Return true for elements in extra scroll zone
--- @tparam Scroll self @{Scroll}
--- @tparam node node The node to check
--- @treturn boolean True if node in visible scroll area
-function Scroll.is_node_in_view(self, node)
+---@param node node The node to check
+---@return boolean True if node in visible scroll area
+function M:is_node_in_view(node)
local node_offset_for_view = gui.get_position(node)
local parent = gui.get_parent(node)
local is_parent_of_view = false
@@ -504,10 +513,9 @@ end
--- Bind the grid component (Static or Dynamic) to recalculate
-- scroll size on grid changes
--- @tparam Scroll self @{Scroll}
--- @tparam StaticGrid grid Druid grid component
--- @treturn druid.scroll Current scroll instance
-function Scroll.bind_grid(self, grid)
+---@param grid druid.grid|nil Druid grid component
+---@return druid.scroll Current scroll instance
+function M:bind_grid(grid)
if self._grid_on_change then
self._grid_on_change:unsubscribe(self._grid_on_change_callback)
@@ -516,15 +524,16 @@ function Scroll.bind_grid(self, grid)
end
if not grid then
- return
+ return self
end
self._grid_on_change = grid.on_change_items
- self._grid_on_change_callback = self._grid_on_change:subscribe(function()
+ self._grid_on_change_callback = function()
local size = grid:get_size()
local offset = grid:get_offset()
self:set_size(size, offset)
- end)
+ end
+ self._grid_on_change:subscribe(self._grid_on_change_callback)
self:set_size(grid:get_size(), grid:get_offset())
return self
@@ -533,14 +542,13 @@ end
--- Strict drag scroll area. Useful for
-- restrict events outside stencil node
--- @tparam Drag self
--- @tparam node|string node Gui node
-function Scroll.set_click_zone(self, node)
+---@param node node|string Gui node
+function M:set_click_zone(node)
self.drag:set_click_zone(node)
end
-function Scroll._on_scroll_drag(self, dx, dy)
+function M:_on_scroll_drag(dx, dy)
local t = self.target_position
local b = self.available_pos
local eb = self.available_pos_extra
@@ -581,7 +589,7 @@ function Scroll._on_scroll_drag(self, dx, dy)
end
-function Scroll._check_soft_zone(self)
+function M:_check_soft_zone()
local target = self.target_position
local border = self.available_pos
local speed = self.style.BACK_SPEED
@@ -610,7 +618,7 @@ end
-- Cancel animation on other animation or input touch
-function Scroll._cancel_animate(self)
+function M:_cancel_animate()
self.inertion.x = 0
self.inertion.y = 0
@@ -624,7 +632,7 @@ function Scroll._cancel_animate(self)
end
-function Scroll._set_scroll_position(self, position_x, position_y)
+function M:_set_scroll_position(position_x, position_y)
local available_extra = self.available_pos_extra
position_x = helper.clamp(position_x, available_extra.x, available_extra.z)
position_y = helper.clamp(position_y, available_extra.w, available_extra.y)
@@ -642,8 +650,8 @@ end
--- Find closer point of interest
-- if no inert, scroll to next point by scroll direction
-- if inert, find next point by scroll director
--- @local
-function Scroll._check_points(self)
+---@private
+function M:_check_points()
if not self.points then
return
end
@@ -699,7 +707,7 @@ function Scroll._check_points(self)
end
-function Scroll._check_threshold(self)
+function M:_check_threshold()
local is_stopped = false
if self.drag.can_x and math.abs(self.inertion.x) < self.style.INERT_THRESHOLD then
@@ -717,7 +725,7 @@ function Scroll._check_threshold(self)
end
-function Scroll._update_free_scroll(self, dt)
+function M:_update_free_scroll(dt)
if self.is_animate then
return
end
@@ -742,7 +750,7 @@ function Scroll._update_free_scroll(self, dt)
end
-function Scroll._update_hand_scroll(self, dt)
+function M:_update_hand_scroll(dt)
if self.is_animate then
self:_cancel_animate()
end
@@ -757,7 +765,7 @@ function Scroll._update_hand_scroll(self, dt)
end
-function Scroll._on_touch_start(self)
+function M:_on_touch_start()
self.inertion.x = 0
self.inertion.y = 0
self.target_position.x = self.position.x
@@ -765,12 +773,12 @@ function Scroll._on_touch_start(self)
end
-function Scroll._on_touch_end(self)
+function M:_on_touch_end()
self:_check_threshold()
end
-function Scroll._update_size(self)
+function M:_update_size()
local content_border = helper.get_border(self.content_node)
local content_size = helper.get_scaled_size(self.content_node)
@@ -805,10 +813,12 @@ function Scroll._update_size(self)
self:_set_scroll_position(self.position.x, self.position.y)
self.target_position.x = self.position.x
self.target_position.y = self.position.y
+
+ self.drag:set_drag_cursors(self.drag.can_x or self.drag.can_y)
end
-function Scroll._process_scroll_wheel(self, action_id, action)
+function M:_process_scroll_wheel(action_id, action)
if not self._is_mouse_hover or self.style.WHEEL_SCROLL_SPEED == 0 then
return false
end
@@ -845,9 +855,9 @@ function Scroll._process_scroll_wheel(self, action_id, action)
end
-function Scroll._on_mouse_hover(self, state)
+function M:_on_mouse_hover(state)
self._is_mouse_hover = state
end
-return Scroll
+return M
diff --git a/druid/base/static_grid.lua b/druid/base/static_grid.lua
index c602ce0..a138fe2 100644
--- a/druid/base/static_grid.lua
+++ b/druid/base/static_grid.lua
@@ -34,22 +34,22 @@
-- Example Link
-- @module StaticGrid
-- @within BaseComponent
--- @alias druid.static_grid
+-- @alias druid.grid
--- On item add callback(self, node, index)
--- @tfield DruidEvent on_add_item @{DruidEvent}
+-- @tfield event on_add_item event
--- On item remove callback(self, index)
--- @tfield DruidEvent on_remove_item @{DruidEvent}
+-- @tfield event on_remove_item event
--- On item add, remove or change in_row callback(self, index|nil)
--- @tfield DruidEvent on_change_items @{DruidEvent}
+-- @tfield event on_change_items event
--- On grid clear callback(self)
--- @tfield DruidEvent on_clear @{DruidEvent}
+-- @tfield event on_clear event
--- On update item positions callback(self)
--- @tfield DruidEvent on_update_positions @{DruidEvent}
+-- @tfield event on_update_positions event
--- Parent gui node
-- @tfield node parent
@@ -78,11 +78,27 @@
---
local const = require("druid.const")
-local Event = require("druid.event")
+local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
-local StaticGrid = component.create("static_grid")
+---@class druid.grid: druid.base_component
+---@field on_add_item event
+---@field on_remove_item event
+---@field on_change_items event
+---@field on_clear event
+---@field on_update_positions event
+---@field parent node
+---@field nodes node[]
+---@field first_index number
+---@field last_index number
+---@field anchor vector3
+---@field pivot vector3
+---@field node_size vector3
+---@field border vector4
+---@field in_row number
+---@field style table
+local M = component.create("static_grid")
local function _extend_border(border, pos, size, pivot)
@@ -104,23 +120,22 @@ end
-- @table style
-- @tfield boolean|nil IS_DYNAMIC_NODE_POSES If true, always center grid content as grid pivot sets. Default: false
-- @tfield boolean|nil IS_ALIGN_LAST_ROW If true, always align last row of the grid as grid pivot sets. Default: false
-function StaticGrid.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.IS_DYNAMIC_NODE_POSES = style.IS_DYNAMIC_NODE_POSES or false
self.style.IS_ALIGN_LAST_ROW = style.IS_ALIGN_LAST_ROW or false
end
---- The @{StaticGrid} constructor
--- @tparam StaticGrid self @{StaticGrid}
--- @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 number|nil in_row How many nodes in row can be placed. By default 1
-function StaticGrid.init(self, parent, element, in_row)
+--- The StaticGrid constructor
+---@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 in_row number|nil How many nodes in row can be placed. By default 1
+function M:init(parent, element, in_row)
self.parent = self:get_node(parent)
self.nodes = {}
- self.pivot = helper.get_pivot_offset(gui.get_pivot(self.parent))
+ self.pivot = helper.get_pivot_offset(self.parent)
self.anchor = vmath.vector3(0.5 + self.pivot.x, 0.5 - self.pivot.y, 0)
self.in_row = in_row or 1
@@ -137,11 +152,11 @@ function StaticGrid.init(self, parent, element, in_row)
self.border = vmath.vector4(0) -- Current grid content size
- self.on_add_item = Event()
- self.on_remove_item = Event()
- self.on_change_items = Event()
- self.on_clear = Event()
- self.on_update_positions = Event()
+ self.on_add_item = event.create()
+ self.on_remove_item = event.create()
+ self.on_change_items = event.create()
+ self.on_clear = event.create()
+ self.on_update_positions = event.create()
self._set_position_function = gui.set_position
end
@@ -149,10 +164,9 @@ end
local _temp_pos = vmath.vector3(0)
--- Return pos for grid node index
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam number index The grid element index
--- @treturn vector3 @Node position
-function StaticGrid.get_pos(self, index)
+---@param index number The grid element index
+---@return vector3 @Node position
+function M:get_pos(index)
local row = math.ceil(index / self.in_row) - 1
local col = (index - row * self.in_row) - 1
@@ -167,10 +181,9 @@ end
--- Return index for grid pos
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam vector3 pos The node position in the grid
--- @treturn number The node index
-function StaticGrid.get_index(self, pos)
+---@param pos vector3 The node position in the grid
+---@return number The node index
+function M:get_index(pos)
-- Offset to left-top corner from node pivot
local node_offset_x = self.node_size.x * (-0.5 + self.node_pivot.x)
local node_offset_y = self.node_size.y * (0.5 - self.node_pivot.y)
@@ -187,10 +200,9 @@ end
--- Return grid index by node
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam node node The gui node in the grid
--- @treturn number The node index
-function StaticGrid.get_index_by_node(self, node)
+---@param node node The gui node in the grid
+---@return number|nil index The node index
+function M:get_index_by_node(node)
for index, grid_node in pairs(self.nodes) do
if node == grid_node then
return index
@@ -201,28 +213,26 @@ function StaticGrid.get_index_by_node(self, node)
end
-function StaticGrid.on_layout_change(self)
+function M:on_layout_change()
self:_update(true)
end
--- Set grid anchor. Default anchor is equal to anchor of grid parent node
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam vector3 anchor Anchor
-function StaticGrid.set_anchor(self, anchor)
+---@param anchor vector3 Anchor
+function M:set_anchor(anchor)
self.anchor = anchor
self:_update()
end
--- Update grid content
--- @tparam StaticGrid self @{StaticGrid}
-function StaticGrid.refresh(self)
+function M:refresh()
self:_update(true)
end
-function StaticGrid.set_pivot(self, pivot)
+function M:set_pivot(pivot)
local prev_pivot = helper.get_pivot_offset(gui.get_pivot(self.parent))
self.pivot = helper.get_pivot_offset(pivot)
@@ -254,12 +264,11 @@ end
--- Add new item to the grid
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam node item GUI node
--- @tparam number|nil index The item position. By default add as last item
--- @tparam number|nil shift_policy How shift nodes, if required. Default: const.SHIFT.RIGHT
--- @tparam boolean|nil is_instant If true, update node positions instantly
-function StaticGrid.add(self, item, index, shift_policy, is_instant)
+---@param item node GUI node
+---@param index number|nil The item position. By default add as last item
+---@param shift_policy number|nil How shift nodes, if required. Default: const.SHIFT.RIGHT
+---@param is_instant boolean|nil If true, update node positions instantly
+function M:add(item, index, shift_policy, is_instant)
index = index or ((self.last_index or 0) + 1)
helper.insert_with_shift(self.nodes, item, index, shift_policy)
@@ -279,10 +288,9 @@ end
--- Set new items to the grid. All previous items will be removed
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam node[] nodes The new grid nodes
+---@param nodes node[] The new grid nodes
-- @tparam[opt=false] boolean is_instant If true, update node positions instantly
-function StaticGrid.set_items(self, nodes, is_instant)
+function M:set_items(nodes, is_instant)
self.nodes = nodes
for index = 1, #nodes do
local item = nodes[index]
@@ -296,12 +304,11 @@ end
--- Remove the item from the grid. Note that gui node will be not deleted
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam number index The grid node index to remove
--- @tparam number|nil shift_policy How shift nodes, if required. Default: const.SHIFT.RIGHT
--- @tparam boolean|nil is_instant If true, update node positions instantly
--- @treturn node The deleted gui node from grid
-function StaticGrid.remove(self, index, shift_policy, is_instant)
+---@param index number The grid node index to remove
+---@param shift_policy number|nil How shift nodes, if required. Default: const.SHIFT.RIGHT
+---@param is_instant boolean|nil If true, update node positions instantly
+---@return node The deleted gui node from grid
+function M:remove(index, shift_policy, is_instant)
assert(self.nodes[index], "No grid item at given index " .. index)
local remove_node = self.nodes[index]
@@ -317,9 +324,8 @@ end
--- Return grid content size
--- @tparam StaticGrid self @{StaticGrid}
--- @treturn vector3 The grid content size
-function StaticGrid.get_size(self)
+---@return vector3 The grid content size
+function M:get_size()
return vmath.vector3(
self.border.z - self.border.x,
self.border.y - self.border.w,
@@ -327,7 +333,7 @@ function StaticGrid.get_size(self)
end
-function StaticGrid.get_size_for(self, count)
+function M:get_size_for(count)
if not count or count == 0 then
return vmath.vector3(0)
end
@@ -350,17 +356,15 @@ end
--- Return grid content borders
--- @tparam StaticGrid self @{StaticGrid}
--- @treturn vector3 The grid content borders
-function StaticGrid.get_borders(self)
+---@return vector4 The grid content borders
+function M:get_borders()
return self.border
end
--- Return array of all node positions
--- @tparam StaticGrid self @{StaticGrid}
--- @treturn vector3[] All grid node positions
-function StaticGrid.get_all_pos(self)
+---@return vector3[] All grid node positions
+function M:get_all_pos()
local result = {}
for i, node in pairs(self.nodes) do
table.insert(result, gui.get_position(node))
@@ -372,10 +376,9 @@ end
--- Change set position function for grid nodes. It will call on
-- update poses on grid elements. Default: gui.set_position
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam function callback Function on node set position
--- @treturn druid.static_grid Current grid instance
-function StaticGrid.set_position_function(self, callback)
+---@param callback function Function on node set position
+---@return druid.grid Current grid instance
+function M:set_position_function(callback)
self._set_position_function = callback or gui.set_position
return self
@@ -384,9 +387,8 @@ end
--- Clear grid nodes array. GUI nodes will be not deleted!
-- If you want to delete GUI nodes, use static_grid.nodes array before grid:clear
--- @tparam StaticGrid self @{StaticGrid}
--- @treturn druid.static_grid Current grid instance
-function StaticGrid.clear(self)
+---@return druid.grid Current grid instance
+function M:clear()
self.border.x = 0
self.border.y = 0
self.border.w = 0
@@ -403,9 +405,8 @@ end
--- Return StaticGrid offset, where StaticGrid content starts.
--- @tparam StaticGrid self @{StaticGrid} The StaticGrid instance
--- @treturn vector3 The StaticGrid offset
-function StaticGrid:get_offset()
+---@return vector3 The StaticGrid offset
+function M:get_offset()
local borders = self:get_borders()
local size = self:get_size()
@@ -419,10 +420,9 @@ end
--- Set new in_row elements for grid
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam number in_row The new in_row value
--- @treturn druid.static_grid Current grid instance
-function StaticGrid.set_in_row(self, in_row)
+---@param in_row number The new in_row value
+---@return druid.grid Current grid instance
+function M:set_in_row(in_row)
self.in_row = in_row
self._grid_horizonal_offset = self.node_size.x * (self.in_row - 1) * self.anchor.x
self._zero_offset = vmath.vector3(
@@ -438,11 +438,10 @@ end
--- Set new node size for grid
--- @tparam StaticGrid self @{StaticGrid}
-- @tparam[opt] number width The new node width
-- @tparam[opt] number height The new node height
--- @treturn druid.static_grid Current grid instance
-function StaticGrid.set_item_size(self, width, height)
+---@return druid.grid Current grid instance
+function M:set_item_size(width, height)
if width then
self.node_size.x = width
end
@@ -463,20 +462,20 @@ end
--- Sort grid nodes by custom comparator function
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam function comparator The comparator function. (a, b) -> boolean
--- @treturn druid.static_grid Current grid instance
-function StaticGrid.sort_nodes(self, comparator)
+---@param comparator function The comparator function. (a, b) -> boolean
+---@return druid.grid self Current grid instance
+function M:sort_nodes(comparator)
table.sort(self.nodes, comparator)
self:_update(true)
+
+ return self
end
--- Update grid inner state
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback
--- @local
-function StaticGrid._update(self, is_instant)
+---@param is_instant boolean|nil If true, node position update instantly, otherwise with set_position_function callback
+---@private
+function M:_update(is_instant)
self:_update_indexes()
self:_update_borders()
self:_update_pos(is_instant)
@@ -484,9 +483,8 @@ end
--- Update first and last indexes of grid nodes
--- @tparam StaticGrid self @{StaticGrid}
--- @local
-function StaticGrid._update_indexes(self)
+---@private
+function M:_update_indexes()
self.first_index = nil
self.last_index = nil
for index in pairs(self.nodes) do
@@ -500,9 +498,8 @@ end
--- Update grid content borders, recalculate min and max values
--- @tparam StaticGrid self @{StaticGrid}
--- @local
-function StaticGrid._update_borders(self)
+---@private
+function M:_update_borders()
if not self.first_index then
self.border = vmath.vector4(0)
return
@@ -519,10 +516,9 @@ end
--- Update grid nodes position
--- @tparam StaticGrid self @{StaticGrid}
--- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback
--- @local
-function StaticGrid._update_pos(self, is_instant)
+---@param is_instant boolean|nil If true, node position update instantly, otherwise with set_position_function callback
+---@private
+function M:_update_pos(is_instant)
local zero_offset = self:_get_zero_offset()
for i, node in pairs(self.nodes) do
@@ -543,11 +539,11 @@ end
--- Return elements offset for correct posing nodes. Correct posing at
-- parent pivot node (0:0) with adjusting of node sizes and anchoring
--- @treturn vector3 The offset vector
--- @local
-function StaticGrid:_get_zero_offset()
+---@return vector3 The offset vector
+---@private
+function M:_get_zero_offset()
if not self.style.IS_DYNAMIC_NODE_POSES then
- return const.VECTOR_ZERO
+ return vmath.vector3(0)
end
-- zero offset: center pos - border size * anchor
@@ -560,9 +556,9 @@ end
--- Return offset x for last row in grid. Used to align this row accorting to grid's anchor
--- @treturn number The offset x value
--- @local
-function StaticGrid:_get_zero_offset_x(row_index)
+---@return number The offset x value
+---@private
+function M:_get_zero_offset_x(row_index)
if not self.style.IS_DYNAMIC_NODE_POSES or not self.style.IS_ALIGN_LAST_ROW then
return self._zero_offset.x
end
@@ -580,4 +576,4 @@ function StaticGrid:_get_zero_offset_x(row_index)
end
-return StaticGrid
+return M
diff --git a/druid/base/text.lua b/druid/base/text.lua
index 39188f4..a0cd877 100755
--- a/druid/base/text.lua
+++ b/druid/base/text.lua
@@ -36,13 +36,13 @@
-- @alias druid.text
--- On set text callback(self, text)
--- @tfield DruidEvent on_set_text @{DruidEvent}
+-- @tfield event on_set_text event
--- On adjust text size callback(self, new_scale, text_metrics)
--- @tfield DruidEvent on_update_text_scale @{DruidEvent}
+-- @tfield event on_update_text_scale event
--- On change pivot callback(self, pivot)
--- @tfield DruidEvent on_set_pivot @{DruidEvent}
+-- @tfield event on_set_pivot event
--- Text node
-- @tfield node node
@@ -76,14 +76,23 @@
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local utf8_lua = require("druid.system.utf8")
local component = require("druid.component")
local utf8 = utf8 or utf8_lua --[[@as utf8]]
-local Text = component.create("text")
+---@class druid.text: druid.base_component
+---@field node node
+---@field on_set_text event
+---@field on_update_text_scale event
+---@field on_set_pivot event
+---@field style table
+---@field private start_pivot userdata
+---@field private start_scale vector3
+---@field private scale vector3
+local M = component.create("text")
local function update_text_size(self)
if self.scale.x == 0 or self.scale.y == 0 then
@@ -200,6 +209,8 @@ local function update_text_area_size(self)
end
+---@param self druid.text
+---@param trim_postfix string
local function update_text_with_trim(self, trim_postfix)
local max_width = self.text_area.x
local text_width = self:get_text_size()
@@ -222,6 +233,24 @@ local function update_text_with_trim(self, trim_postfix)
end
end
+local function update_text_with_trim_left(self, trim_postfix)
+ local max_width = self.text_area.x
+ local text_width = self:get_text_size()
+ local text_length = utf8.len(self.last_value)
+ local trim_index = 1
+
+ if text_width > max_width then
+ local new_text = self.last_value
+ while text_width > max_width and trim_index < text_length do
+ trim_index = trim_index + 1
+ new_text = trim_postfix .. utf8.sub(self.last_value, trim_index, text_length)
+ text_width = self:get_text_size(new_text)
+ end
+
+ gui.set_text(self.node, new_text)
+ end
+end
+
local function update_text_with_anchor_shift(self)
if self:get_text_size() >= self.text_area.x then
@@ -232,6 +261,7 @@ local function update_text_with_anchor_shift(self)
end
+---@param self druid.text
local function update_adjust(self)
if not self.adjust_type or self.adjust_type == const.TEXT_ADJUST.NO_ADJUST then
reset_default_scale(self)
@@ -246,6 +276,10 @@ local function update_adjust(self)
update_text_with_trim(self, self.style.TRIM_POSTFIX)
end
+ if self.adjust_type == const.TEXT_ADJUST.TRIM_LEFT then
+ update_text_with_trim_left(self, self.style.TRIM_POSTFIX)
+ end
+
if self.adjust_type == const.TEXT_ADJUST.DOWNSCALE_LIMITED then
update_text_area_size(self)
end
@@ -258,6 +292,16 @@ local function update_adjust(self)
update_text_area_size(self)
update_text_with_anchor_shift(self)
end
+
+ if self.adjust_type == const.TEXT_ADJUST.SCALE_THEN_TRIM then
+ update_text_area_size(self)
+ update_text_with_trim(self, self.style.TRIM_POSTFIX)
+ end
+
+ if self.adjust_type == const.TEXT_ADJUST.SCALE_THEN_TRIM_LEFT then
+ update_text_area_size(self)
+ update_text_with_trim_left(self, self.style.TRIM_POSTFIX)
+ end
end
@@ -269,7 +313,7 @@ end
-- @tfield string|nil DEFAULT_ADJUST The default adjust type for any text component. Default: DOWNSCALE
-- @tfield string|nil ADJUST_STEPS Amount of iterations for text adjust by height. Default: 20
-- @tfield string|nil ADJUST_SCALE_DELTA Scale step on each height adjust step. Default: 0.02
-function Text.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.TRIM_POSTFIX = style.TRIM_POSTFIX or "..."
self.style.DEFAULT_ADJUST = style.DEFAULT_ADJUST or const.TEXT_ADJUST.DOWNSCALE
@@ -278,12 +322,11 @@ function Text.on_style_change(self, style)
end
---- The @{Text} constructor
--- @tparam Text self @{Text}
--- @tparam string|node node Node name or GUI Text Node itself
--- @tparam string|nil value Initial text. Default value is node text from GUI scene. Default: nil
--- @tparam string|nil adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
-function Text.init(self, node, value, adjust_type)
+--- The Text constructor
+---@param node string|node Node name or GUI Text Node itself
+---@param value string|nil Initial text. Default value is node text from GUI scene. Default: nil
+---@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
+function M:init(node, value, adjust_type)
self.node = self:get_node(node)
self.pos = gui.get_position(self.node)
self.node_id = gui.get_id(self.node)
@@ -300,37 +343,25 @@ function Text.init(self, node, value, adjust_type)
self.adjust_type = adjust_type or self.style.DEFAULT_ADJUST
self.color = gui.get_color(self.node)
- self.on_set_text = Event()
- self.on_set_pivot = Event()
- self.on_update_text_scale = Event()
+ self.on_set_text = event.create()
+ self.on_set_pivot = event.create()
+ self.on_update_text_scale = event.create()
- self:set_to(value or gui.get_text(self.node))
+ self:set_text(value or gui.get_text(self.node))
return self
end
-function Text.on_layout_change(self)
- self:set_to(self.last_value)
-end
-
-
-function Text.on_message_input(self, node_id, message)
- if node_id ~= self.node_id then
- return false
- end
-
- if message.action == const.MESSAGE_INPUT.TEXT_SET then
- Text.set_to(self, message.value)
- end
+function M:on_layout_change()
+ self:set_text(self.last_value)
end
--- Calculate text width with font with respect to trailing space
--- @tparam Text self @{Text}
--- @tparam string text|nil
--- @treturn number Width
--- @treturn number Height
-function Text.get_text_size(self, text)
+---@param text string|nil
+---@return number Width
+---@return number Height
+function M:get_text_size(text)
text = text or self.last_value
local font_name = gui.get_font(self.node)
local font = gui.get_font_resource(font_name)
@@ -351,10 +382,9 @@ end
--- Get chars count by width
--- @tparam Text self @{Text}
--- @tparam number width
--- @treturn number Chars count
-function Text.get_text_index_by_width(self, width)
+---@param width number
+---@return number Chars count
+function M:get_text_index_by_width(width)
local text = self.last_value
local font_name = gui.get_font(self.node)
local font = gui.get_font_resource(font_name)
@@ -385,11 +415,11 @@ end
--- Set text to text field
--- @tparam Text self @{Text}
--- @tparam string set_to Text for node
--- @treturn Text Current text instance
-function Text.set_to(self, set_to)
- set_to = set_to or ""
+---@deprecated
+---@param set_to string Text for node
+---@return druid.text Current text instance
+function M:set_to(set_to)
+ set_to = tostring(set_to or "")
self.last_value = set_to
gui.set_text(self.node, set_to)
@@ -402,24 +432,35 @@ function Text.set_to(self, set_to)
end
+function M:set_text(new_text)
+---@diagnostic disable-next-line: deprecated
+ return self:set_to(new_text)
+end
+
+
+function M:get_text()
+ return self.last_value
+end
+
+
--- Set text area size
--- @tparam Text self @{Text}
--- @tparam vector3 size The new text area size
--- @treturn Text Current text instance
-function Text.set_size(self, size)
+---@param size vector3 The new text area size
+---@return druid.text self Current text instance
+function M:set_size(size)
self.start_size = size
self.text_area = vmath.vector3(size)
self.text_area.x = self.text_area.x * self.start_scale.x
self.text_area.y = self.text_area.y * self.start_scale.y
update_adjust(self)
+
+ return self
end
--- Set color
--- @tparam Text self @{Text}
--- @tparam vector4 color Color for node
--- @treturn Text Current text instance
-function Text.set_color(self, color)
+---@param color vector4 Color for node
+---@return druid.text Current text instance
+function M:set_color(color)
self.color = color
gui.set_color(self.node, color)
@@ -428,10 +469,9 @@ end
--- Set alpha
--- @tparam Text self @{Text}
--- @tparam number alpha Alpha for node
--- @treturn Text Current text instance
-function Text.set_alpha(self, alpha)
+---@param alpha number Alpha for node
+---@return druid.text Current text instance
+function M:set_alpha(alpha)
self.color.w = alpha
gui.set_color(self.node, self.color)
@@ -440,10 +480,9 @@ end
--- Set scale
--- @tparam Text self @{Text}
--- @tparam vector3 scale Scale for node
--- @treturn Text Current text instance
-function Text.set_scale(self, scale)
+---@param scale vector3 Scale for node
+---@return druid.text Current text instance
+function M:set_scale(scale)
self.last_scale = scale
gui.set_scale(self.node, scale)
@@ -452,10 +491,9 @@ end
--- Set text pivot. Text will re-anchor inside text area
--- @tparam Text self @{Text}
--- @tparam number pivot The gui.PIVOT_* constant
--- @treturn Text Current text instance
-function Text.set_pivot(self, pivot)
+---@param pivot userdata The gui.PIVOT_* constant
+---@return druid.text Current text instance
+function M:set_pivot(pivot)
local prev_pivot = gui.get_pivot(self.node)
local prev_offset = const.PIVOTS[prev_pivot]
@@ -477,33 +515,32 @@ function Text.set_pivot(self, pivot)
end
---- Return true, if text with line break
--- @tparam Text self @{Text}
--- @treturn boolean Is text node with line break
-function Text.is_multiline(self)
+---Return true, if text with line break
+---@return boolean Is text node with line break
+function M:is_multiline()
return gui.get_line_break(self.node)
end
---- Set text adjust, refresh the current text visuals, if needed
--- @tparam Text self @{Text}
--- @tparam string|nil adjust_type See const.TEXT_ADJUST. If pass nil - use current adjust type
--- @tparam number|nil minimal_scale If pass nil - not use minimal scale
--- @treturn Text Current text instance
-function Text.set_text_adjust(self, adjust_type, minimal_scale)
+---Set text adjust, refresh the current text visuals, if needed
+---Values are: "downscale", "trim", "no_adjust", "downscale_limited",
+---"scroll", "scale_then_scroll", "trim_left", "scale_then_trim", "scale_then_trim_left"
+---@param adjust_type string|nil See const.TEXT_ADJUST. If pass nil - use current adjust type
+---@param minimal_scale number|nil To remove minimal scale, use `text:set_minimal_scale(nil)`, if pass nil - not change minimal scale
+---@return druid.text self Current text instance
+function M:set_text_adjust(adjust_type, minimal_scale)
self.adjust_type = adjust_type
- self._minimal_scale = minimal_scale
- self:set_to(self.last_value)
+ self._minimal_scale = minimal_scale or self._minimal_scale
+ self:set_text(self.last_value)
return self
end
--- Set minimal scale for DOWNSCALE_LIMITED or SCALE_THEN_SCROLL adjust types
--- @tparam Text self @{Text}
--- @tparam number minimal_scale If pass nil - not use minimal scale
--- @treturn Text Current text instance
-function Text.set_minimal_scale(self, minimal_scale)
+---@param minimal_scale number If pass nil - not use minimal scale
+---@return druid.text Current text instance
+function M:set_minimal_scale(minimal_scale)
self._minimal_scale = minimal_scale
return self
@@ -511,10 +548,10 @@ end
--- Return current text adjust type
--- @treturn number The current text adjust type
-function Text.get_text_adjust(self, adjust_type)
+---@return string adjust_type The current text adjust type
+function M:get_text_adjust()
return self.adjust_type
end
-return Text
+return M
diff --git a/druid/bindings.lua b/druid/bindings.lua
new file mode 100644
index 0000000..e63a11e
--- /dev/null
+++ b/druid/bindings.lua
@@ -0,0 +1,48 @@
+local event = require("event.event")
+
+local M = {}
+local WRAPPED_WIDGETS = {}
+
+---Set a widget to the current game object. The game object can acquire the widget by calling `bindings.get_widget`
+---It wraps with events only top level functions cross-context, so no access to nested widgets functions
+---@param widget druid.widget
+function M.set_widget(widget)
+ local object = msg.url()
+ object.fragment = nil
+
+ -- Make a copy of the widget with all functions wrapped in events
+ -- It makes available to call gui functions from game objects
+ local wrapped_widget = setmetatable({}, { __index = widget })
+ local parent_table = getmetatable(widget).__index
+
+ -- Go through all functions and wrap them in events
+ for key, value in pairs(parent_table) do
+ if type(value) == "function" then
+ wrapped_widget[key] = event.create(function(_, ...)
+ return value(widget, ...)
+ end)
+ end
+ end
+
+ WRAPPED_WIDGETS[object.socket] = WRAPPED_WIDGETS[object.socket] or {}
+ WRAPPED_WIDGETS[object.socket][object.path] = wrapped_widget
+end
+
+
+---@param object_url string|userdata|url @root object
+---@return druid.widget|nil
+function M.get_widget(object_url)
+ assert(object_url, "You must provide an object_url")
+
+ object_url = msg.url(object_url --[[@as string]])
+
+ local socket_widgets = WRAPPED_WIDGETS[object_url.socket]
+ if not socket_widgets then
+ return nil
+ end
+
+ return socket_widgets[object_url.path]
+end
+
+
+return M
diff --git a/druid/color.lua b/druid/color.lua
new file mode 100644
index 0000000..8a1ccc9
--- /dev/null
+++ b/druid/color.lua
@@ -0,0 +1,229 @@
+---@type table>
+local PALETTE_DATA
+local CURRENT_PALETTE = "default"
+local DEFAULT_COLOR = vmath.vector4(1, 1, 1, 1)
+local COLOR_X = hash("color.x")
+local COLOR_Y = hash("color.y")
+local COLOR_Z = hash("color.z")
+
+local M = {}
+
+
+---Get color color by id
+---@param color_id string
+---@return vector4
+function M.get(color_id)
+ -- Check is it hex: starts with "#" or contains only 3 or 6 hex symbols
+ if type(color_id) == "string" then
+ if string.sub(color_id, 1, 1) == "#" or string.match(color_id, "^[0-9a-fA-F]+$") then
+ return M.hex2vector4(color_id)
+ end
+ end
+
+ return PALETTE_DATA[CURRENT_PALETTE] and PALETTE_DATA[CURRENT_PALETTE][color_id] or DEFAULT_COLOR
+end
+
+
+---Add palette to palette data
+---@param palette_name string
+---@param palette_data table
+function M.add_palette(palette_name, palette_data)
+ PALETTE_DATA[palette_name] = PALETTE_DATA[palette_name] or {}
+ local palette = PALETTE_DATA[palette_name]
+
+ for color_id, color in pairs(palette_data) do
+ if type(color) == "string" then
+ palette[color_id] = M.hex2vector4(color)
+ else
+ palette[color_id] = color
+ end
+ end
+end
+
+
+function M.set_palette(palette_name)
+ if PALETTE_DATA[palette_name] then
+ CURRENT_PALETTE = palette_name
+ end
+end
+
+
+function M.get_palette()
+ return CURRENT_PALETTE
+end
+
+
+---Set color of gui node without changing alpha
+---@param gui_node node
+---@param color vector4|vector3|string Color in vector4, vector3 or color id from palette
+function M.set_color(gui_node, color)
+ if type(color) == "string" then
+ color = M.get(color)
+ end
+
+ gui.set(gui_node, COLOR_X, color.x)
+ gui.set(gui_node, COLOR_Y, color.y)
+ gui.set(gui_node, COLOR_Z, color.z)
+end
+
+
+function M.get_random_color()
+ return vmath.vector4(math.random(), math.random(), math.random(), 1)
+end
+
+
+---Lerp colors via color HSB values
+function M.lerp(t, color1, color2)
+ local h1, s1, v1 = M.rgb2hsb(color1.x, color1.y, color1.z)
+ local h2, s2, v2 = M.rgb2hsb(color2.x, color2.y, color2.z)
+
+ local h = h1 + (h2 - h1) * t
+ local s = s1 + (s2 - s1) * t
+ local v = v1 + (v2 - v1) * t
+
+ local r, g, b, a = M.hsb2rgb(h, s, v)
+ a = a or 1
+ return vmath.vector4(r, g, b, a)
+end
+
+
+---@param hex string
+---@param alpha number|nil
+---@return number, number, number, number
+function M.hex2rgb(hex, alpha)
+ alpha = alpha or 1
+ if alpha > 1 then
+ alpha = alpha / 100
+ end
+
+ -- Remove leading #
+ if string.sub(hex, 1, 1) == "#" then
+ hex = string.sub(hex, 2)
+ end
+
+ -- Expand 3-digit hex codes to 6 digits
+ if #hex == 3 then
+ hex = string.rep(string.sub(hex, 1, 1), 2) ..
+ string.rep(string.sub(hex, 2, 2), 2) ..
+ string.rep(string.sub(hex, 3, 3), 2)
+ end
+
+ local r = tonumber("0x" .. string.sub(hex, 1, 2)) / 255
+ local g = tonumber("0x" .. string.sub(hex, 3, 4)) / 255
+ local b = tonumber("0x" .. string.sub(hex, 5, 6)) / 255
+ return r, g, b, alpha
+end
+
+
+---@param hex string
+---@param alpha number|nil
+---@return vector4
+function M.hex2vector4(hex, alpha)
+ local r, g, b, a = M.hex2rgb(hex, alpha)
+ return vmath.vector4(r, g, b, a)
+end
+
+
+---Convert hsb color to rgb color
+---@param r number @Red value
+---@param g number @Green value
+---@param b number @Blue value
+---@param alpha number|nil @Alpha value. Default is 1
+function M.rgb2hsb(r, g, b, alpha)
+ alpha = alpha or 1
+ local min, max = math.min(r, g, b), math.max(r, g, b)
+ local delta = max - min
+ local h, s, v = 0, max, max
+
+ s = max ~= 0 and delta / max or 0
+
+ if delta ~= 0 then
+ if r == max then
+ h = (g - b) / delta
+ elseif g == max then
+ h = 2 + (b - r) / delta
+ else
+ h = 4 + (r - g) / delta
+ end
+ h = (h / 6) % 1
+ end
+
+ alpha = alpha > 1 and alpha / 100 or alpha
+
+ return h, s, v, alpha
+end
+
+
+---Convert hsb color to rgb color
+---@param h number @Hue
+---@param s number @Saturation
+---@param v number @Value
+---@param alpha number|nil @Alpha value. Default is 1
+function M.hsb2rgb(h, s, v, alpha)
+ local r, g, b
+ local i = math.floor(h * 6)
+ local f = h * 6 - i
+ local p = v * (1 - s)
+ local q = v * (1 - f * s)
+ local t = v * (1 - (1 - f) * s)
+
+ i = i % 6
+
+ if i == 0 then r, g, b = v, t, p
+ elseif i == 1 then r, g, b = q, v, p
+ elseif i == 2 then r, g, b = p, v, t
+ elseif i == 3 then r, g, b = p, q, v
+ elseif i == 4 then r, g, b = t, p, v
+ elseif i == 5 then r, g, b = v, p, q
+ end
+
+ return r, g, b, alpha
+end
+
+
+---Convert rgb color to hex color
+---@param red number @Red value
+---@param green number @Green value
+---@param blue number @Blue value
+function M.rgb2hex(red, green, blue)
+ local r = string.format("%x", math.floor(red * 255))
+ local g = string.format("%x", math.floor(green * 255))
+ local b = string.format("%x", math.floor(blue * 255))
+ return string.upper((#r == 1 and "0" or "") .. r .. (#g == 1 and "0" or "") .. g .. (#b == 1 and "0" or "") .. b)
+end
+
+
+function M.load_palette()
+ local PALETTE_PATH = sys.get_config_string("fluid.palette")
+ if PALETTE_PATH then
+ PALETTE_DATA = M.load_json(PALETTE_PATH) --[[@as table>]]
+ end
+ PALETTE_DATA = PALETTE_DATA or {}
+
+ for _, palette_data in pairs(PALETTE_DATA) do
+ for color_id, color in pairs(palette_data) do
+ if type(color) == "string" then
+ palette_data[color_id] = M.hex2vector4(color)
+ end
+ end
+ end
+end
+
+
+---Load JSON file from game resources folder (by relative path to game.project)
+---Return nil if file not found or error
+---@param json_path string
+---@return table|nil
+function M.load_json(json_path)
+ local resource, is_error = sys.load_resource(json_path)
+ if is_error or not resource then
+ return nil
+ end
+
+ return json.decode(resource)
+end
+
+
+M.load_palette()
+
+return M
\ No newline at end of file
diff --git a/druid/component.lua b/druid/component.lua
index 0672303..3c82000 100644
--- a/druid/component.lua
+++ b/druid/component.lua
@@ -1,83 +1,61 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Basic class for all Druid components.
--- To create you custom component, use static function `component.create`
--- @usage
--- -- Create your component:
--- local component = require("druid.component")
---
--- local AwesomeComponent = component.create("awesome_component")
---
--- function AwesomeComponent:init(template, nodes)
--- self:set_template(template)
--- self:set_nodes(nodes)
--- self.druid = self:get_druid()
--- end
---
--- return AwesomeComponent
--- @module BaseComponent
--- @alias druid.base_component
-
local const = require("druid.const")
local helper = require("druid.helper")
-local BaseComponent = {}
+---@class druid.base_component.meta
+---@field template string
+---@field context table
+---@field nodes table|nil
+---@field style table|nil
+---@field druid druid_instance
+---@field input_enabled boolean
+---@field children table
+---@field parent druid.base_component|nil
+---@field instance_class table
+
+---@class druid.base_component.component
+---@field name string
+---@field input_priority number
+---@field default_input_priority number
+---@field _is_input_priority_changed boolean
+---@field _uid number
+
+---@class druid.base_component
+---@field druid druid_instance Druid instance to create inner components
+---@field init fun(self:druid.base_component, ...)|nil
+---@field update fun(self:druid.base_component, dt:number)|nil
+---@field on_remove fun(self:druid.base_component)|nil
+---@field on_input fun(self:druid.base_component, action_id:number, action:table)|nil
+---@field on_message fun(self:druid.base_component, message_id:hash, message:table, sender:url)|nil
+---@field on_late_init fun(self:druid.base_component)|nil
+---@field on_focus_lost fun(self:druid.base_component)|nil
+---@field on_focus_gained fun(self:druid.base_component)|nil
+---@field on_style_change fun(self:druid.base_component, style: table)|nil
+---@field on_layout_change fun(self:druid.base_component)|nil
+---@field on_window_resized fun(self:druid.base_component)|nil
+---@field on_language_change fun(self:druid.base_component)|nil
+---@field private _component druid.base_component.component
+---@field private _meta druid.base_component.meta
+local M = {}
local INTERESTS = {} -- Cache interests per component class in runtime
-local IS_AUTO_TEMPLATE = not (sys.get_config_int("druid.no_auto_template", 0) == 1)
-
--- Component Interests
-BaseComponent.ON_INPUT = const.ON_INPUT
-BaseComponent.ON_UPDATE = const.ON_UPDATE
-BaseComponent.ON_MESSAGE = const.ON_MESSAGE
-BaseComponent.ON_LATE_INIT = const.ON_LATE_INIT
-BaseComponent.ON_FOCUS_LOST = const.ON_FOCUS_LOST
-BaseComponent.ON_FOCUS_GAINED = const.ON_FOCUS_GAINED
-BaseComponent.ON_LAYOUT_CHANGE = const.ON_LAYOUT_CHANGE
-BaseComponent.ON_MESSAGE_INPUT = const.ON_MESSAGE_INPUT
-BaseComponent.ON_WINDOW_RESIZED = const.ON_WINDOW_RESIZED
-BaseComponent.ON_LANGUAGE_CHANGE = const.ON_LANGUAGE_CHANGE
-
-BaseComponent.ALL_INTERESTS = {
- BaseComponent.ON_INPUT,
- BaseComponent.ON_UPDATE,
- BaseComponent.ON_MESSAGE,
- BaseComponent.ON_LATE_INIT,
- BaseComponent.ON_FOCUS_LOST,
- BaseComponent.ON_FOCUS_GAINED,
- BaseComponent.ON_LAYOUT_CHANGE,
- BaseComponent.ON_MESSAGE_INPUT,
- BaseComponent.ON_WINDOW_RESIZED,
- BaseComponent.ON_LANGUAGE_CHANGE,
-}
-
--- Mapping from on_message method to specific method name
-BaseComponent.SPECIFIC_UI_MESSAGES = {
- [hash("layout_changed")] = BaseComponent.ON_LAYOUT_CHANGE, -- The message_id from Defold
- [hash(BaseComponent.ON_FOCUS_LOST)] = BaseComponent.ON_FOCUS_LOST,
- [hash(BaseComponent.ON_FOCUS_GAINED)] = BaseComponent.ON_FOCUS_GAINED,
- [hash(BaseComponent.ON_WINDOW_RESIZED)] = BaseComponent.ON_WINDOW_RESIZED,
- [hash(BaseComponent.ON_MESSAGE_INPUT)] = BaseComponent.ON_MESSAGE_INPUT,
- [hash(BaseComponent.ON_LANGUAGE_CHANGE)] = BaseComponent.ON_LANGUAGE_CHANGE,
-}
local uid = 0
-function BaseComponent.create_uid()
+---@private
+function M.create_uid()
uid = uid + 1
return uid
end
---- Set current component style table.
---
--- Invoke `on_style_change` on component, if exist. Component should handle
--- their style changing and store all style params
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam table|nil druid_style Druid style module
--- @treturn BaseComponent @{BaseComponent}
--- @local
-function BaseComponent.set_style(self, druid_style)
+---Set component style. Pass nil to clear style
+---@generic T
+---@param self T
+---@param druid_style table|nil
+---@return T self The component itself for chaining
+function M:set_style(druid_style)
+ ---@cast self druid.base_component
+
self._meta.style = druid_style or {}
local component_style = self._meta.style[self._component.name] or {}
@@ -89,21 +67,22 @@ function BaseComponent.set_style(self, druid_style)
end
---- Set component template name.
---
--- Use on all your custom components with GUI layouts used as templates.
--- It will check parent template name to build full template name in self:get_node()
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam string template BaseComponent template name
--- @treturn BaseComponent @{BaseComponent}
--- @local
-function BaseComponent.set_template(self, template)
+---Set component template name. Pass nil to clear template.
+---This template id used to access nodes inside the template on GUI scene.
+---Parent template will be added automatically if exist.
+---@generic T
+---@param self T
+---@param template string|nil
+---@return T self The component itself for chaining
+function M:set_template(template)
+ ---@cast self druid.base_component
+
template = template or ""
local parent = self:get_parent_component()
- if parent and IS_AUTO_TEMPLATE then
+ if parent then
local parent_template = parent:get_template()
- if #parent_template > 0 then
+ if parent_template and #parent_template > 0 then
if #template > 0 then
template = "/" .. template
end
@@ -111,106 +90,52 @@ function BaseComponent.set_template(self, template)
end
end
- self._meta.template = template
+ if template ~= "" then
+ self._meta.template = template
+ else
+ self._meta.template = nil
+ end
+
return self
end
---- Get current component template name.
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn string Component full template name
-function BaseComponent.get_template(self)
+---Get full template name.
+---@return string
+function M:get_template()
return self._meta.template
end
---- Set current component nodes.
--- Use if your component nodes was cloned with `gui.clone_tree` and you got the node tree.
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam table nodes BaseComponent nodes table
--- @treturn BaseComponent @{BaseComponent}
--- @usage
--- local nodes = gui.clone_tree(self.prefab)
--- ... In your component:
--- self:set_nodes(nodes)
--- @local
-function BaseComponent.set_nodes(self, nodes)
+---Set current component nodes, returned from `gui.clone_tree` function.
+---@param nodes table
+---@return druid.base_component
+function M:set_nodes(nodes)
self._meta.nodes = nodes
-
- -- When we use gui.clone_tree in inner template (template inside other template)
- -- this nodes have no id. We have table: hash(correct_id) : hash("")
- -- It's wrong and we use this hack to fix this
- if nodes then
- for id, node in pairs(nodes) do
- gui.set_id(node, id)
- end
- end
-
return self
end
---- Context used as first arg in all Druid events
---
--- Context is usually self of gui_script.
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn table BaseComponent context
-function BaseComponent.get_context(self)
+---Return current component context
+---@return any context Usually it's self of script but can be any other Druid component
+function M:get_context()
return self._meta.context
end
---- Increase input priority in input stack
--- @tparam BaseComponent self @{BaseComponent}
--- @local
-function BaseComponent.increase_input_priority(self)
- helper.deprecated("The component:increase_input_priority is deprecated. Please use component:set_input_priority(druid_const.PRIORITY_INPUT_MAX) instead")
+---Get component node by node_id. Respect to current template and nodes.
+---@param node_id string|node
+---@return node
+function M:get_node(node_id)
+ return helper.get_node(node_id, self:get_template(), self:get_nodes())
end
---- Get component node by name.
---
--- If component has nodes, node_or_name should be string
--- It autopick node by template name or from nodes by gui.clone_tree
--- if they was setup via component:set_nodes, component:set_template.
--- If node is not found, the exception will fired
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam string|node node_or_name Node name or node itself
--- @treturn node Gui node
-function BaseComponent.get_node(self, node_or_name)
- if type(node_or_name) ~= "string" then
- -- Assume it's already node from gui.get_node
- return node_or_name
- end
-
- local template_name = self:get_template()
- local nodes = self:__get_nodes()
-
- if #template_name > 0 then
- template_name = template_name .. "/"
- end
-
- local node
- if nodes then
- node = nodes[template_name .. node_or_name]
- else
- node = gui.get_node(template_name .. node_or_name)
- end
-
- if not node then
- assert(node, "No component with name: " .. (template_name or "") .. (node_or_name or ""))
- end
-
- return node
-end
-
-
---- Get Druid instance for inner component creation.
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam string|nil template The template name
--- @tparam table|nil nodes The nodes table
--- @treturn DruidInstance Druid instance with component context
-function BaseComponent.get_druid(self, template, nodes)
+---Get Druid instance for inner component creation.
+---@param template string|nil
+---@param nodes table|nil
+---@return druid_instance
+function M:get_druid(template, nodes)
local context = { _context = self }
local druid_instance = setmetatable(context, { __index = self._meta.druid })
@@ -226,39 +151,33 @@ function BaseComponent.get_druid(self, template, nodes)
end
---- Return component name
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn string The component name
-function BaseComponent.get_name(self)
- return self._component.name .. BaseComponent.create_uid()
+---Get component name
+---@return string name The component name + uid
+function M:get_name()
+ return self._component.name .. M.create_uid()
end
---- Return parent component name
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn string|nil The parent component name if exist or bil
-function BaseComponent.get_parent_name(self)
+---Get parent component name
+---@return string|nil parent_name The parent component name if exist or nil
+function M:get_parent_name()
local parent = self:get_parent_component()
return parent and parent:get_name()
end
---- Return component input priority
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn number The component input priority
-function BaseComponent.get_input_priority(self)
+---Get component input priority, the bigger number processed first. Default value: 10
+---@return number
+function M:get_input_priority()
return self._component.input_priority
end
---- Set component input priority
---
--- Default value: 10
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam number value The new input priority value
--- @tparam boolean|nil is_temporary If true, the reset input priority will return to previous value
--- @treturn number The component input priority
-function BaseComponent.set_input_priority(self, value, is_temporary)
+---Set component input priority, the bigger number processed first. Default value: 10
+---@param value number
+---@param is_temporary boolean|nil If true, the reset input priority will return to previous value
+---@return druid.base_component self The component itself for chaining
+function M:set_input_priority(value, is_temporary)
assert(value)
if self._component.input_priority == value then
@@ -281,32 +200,27 @@ function BaseComponent.set_input_priority(self, value, is_temporary)
end
---- Reset component input priority to default value
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn number The component input priority
-function BaseComponent.reset_input_priority(self)
+---Reset component input priority to it's default value, that was set in `create` function or `set_input_priority`
+---@return druid.base_component self The component itself for chaining
+function M:reset_input_priority()
self:set_input_priority(self._component.default_input_priority)
return self
end
---- Return component UID.
---
--- UID generated in component creation order.
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn number The component uid
-function BaseComponent.get_uid(self)
+---Get component UID, unique identifier created in component creation order.
+---@return number uid The component uid
+function M:get_uid()
return self._component._uid
end
---- Set component input state. By default it enabled
---
--- If input is disabled, the component will not receive input events
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam boolean|nil state The component input state
--- @treturn BaseComponent BaseComponent itself
-function BaseComponent.set_input_enabled(self, state)
+---Set component input state. By default it's enabled.
+---If input is disabled, the component will not receive input events.
+---Recursive for all children components.
+---@param state boolean
+---@return druid.base_component self The component itself for chaining
+function M:set_input_enabled(state)
self._meta.input_enabled = state
for index = 1, #self._meta.children do
@@ -317,23 +231,21 @@ function BaseComponent.set_input_enabled(self, state)
end
---- Return the parent component if exist
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn BaseComponent|nil The druid component instance or nil
-function BaseComponent.get_parent_component(self)
+---Get parent component
+---@return druid.base_component|nil parent The parent component if exist or nil
+function M:get_parent_component()
return self._meta.parent
end
--- Setup component context and his style table
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam table druid_instance The parent druid instance
--- @tparam table context Druid context. Usually it is self of script
--- @tparam table style Druid style module
--- @tparam table instance_class The component instance class
--- @treturn component BaseComponent itself
--- @local
-function BaseComponent.setup_component(self, druid_instance, context, style, instance_class)
+---@param druid_instance table The parent druid instance
+---@param context table Druid context. Usually it is self of script
+---@param style table Druid style module
+---@param instance_class table The component instance class
+---@return druid.base_component BaseComponent itself
+---@private
+function M:setup_component(druid_instance, context, style, instance_class)
self._meta = {
template = "",
context = context,
@@ -342,7 +254,7 @@ function BaseComponent.setup_component(self, druid_instance, context, style, ins
druid = druid_instance,
input_enabled = true,
children = {},
- parent = type(context) ~= "userdata" and context,
+ parent = type(context) ~= "userdata" and context --[[@as druid.base_component]],
instance_class = instance_class
}
@@ -357,62 +269,32 @@ function BaseComponent.setup_component(self, druid_instance, context, style, ins
end
---- Print log information if debug mode is enabled
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam string message
--- @tparam table context
--- @local
-function BaseComponent.log_message(self, message, context)
- if not self._component.is_debug then
- return
- end
- print("[" .. self:get_name() .. "]:", message, helper.table_to_string(context))
-end
-
-
---- Set debug logs for component enabled or disabled
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam boolean|nil is_debug
--- @local
-function BaseComponent.set_debug(self, is_debug)
- self._component.is_debug = is_debug
-end
-
-
--- Return true, if input priority was changed
--- @tparam BaseComponent self @{BaseComponent}
--- @local
-function BaseComponent._is_input_priority_changed(self)
+---@private
+function M:_is_input_priority_changed()
return self._component._is_input_priority_changed
end
--- Reset is_input_priority_changed field
--- @tparam BaseComponent self @{BaseComponent}
--- @local
-function BaseComponent._reset_input_priority_changed(self)
+---@private
+function M:_reset_input_priority_changed()
self._component._is_input_priority_changed = false
end
-function BaseComponent.__tostring(self)
- return self._component.name
-end
-
-
--- Get current component interests
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn table List of component interests
--- @local
-function BaseComponent.__get_interests(self)
+---@return table List of component interests
+---@private
+function M:__get_interests()
local instance_class = self._meta.instance_class
if INTERESTS[instance_class] then
return INTERESTS[instance_class]
end
local interests = {}
- for index = 1, #BaseComponent.ALL_INTERESTS do
- local interest = BaseComponent.ALL_INTERESTS[index]
+ for index = 1, #const.ALL_INTERESTS do
+ local interest = const.ALL_INTERESTS[index]
if self[interest] and type(self[interest]) == "function" then
table.insert(interests, interest)
end
@@ -423,47 +305,52 @@ function BaseComponent.__get_interests(self)
end
---- Get current component nodes
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn table BaseComponent nodes table
--- @local
-function BaseComponent.__get_nodes(self)
+---Get current component nodes
+---@return table|nil
+function M:get_nodes()
local nodes = self._meta.nodes
local parent = self:get_parent_component()
if parent then
- nodes = nodes or parent:__get_nodes()
+ nodes = nodes or parent:get_nodes()
end
+
return nodes
end
---- Add child to component children list
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam component child The druid component instance
--- @local
-function BaseComponent.__add_child(self, child)
+---Add child to component children list
+---@generic T: druid.base_component
+---@param child T The druid component instance
+---@return T self The component itself for chaining
+---@private
+function M:__add_child(child)
table.insert(self._meta.children, child)
+
+ return self
end
---- Remove child from component children list
--- @tparam BaseComponent self @{BaseComponent}
--- @tparam component child The druid component instance
--- @local
-function BaseComponent.__remove_child(self, child)
+
+---Remove child from component children list
+---@generic T: druid.base_component
+---@param child T The druid component instance
+---@return boolean true if child was removed
+---@private
+function M:__remove_child(child)
for i = #self._meta.children, 1, -1 do
if self._meta.children[i] == child then
table.remove(self._meta.children, i)
return true
end
end
+
+ return false
end
--- Return all children components, recursive
--- @tparam BaseComponent self @{BaseComponent}
--- @treturn table Array of childrens if the Druid component instance
-function BaseComponent.get_childrens(self)
+---@return table Array of childrens if the Druid component instance
+function M:get_childrens()
local childrens = {}
for i = 1, #self._meta.children do
@@ -477,23 +364,21 @@ function BaseComponent.get_childrens(self)
end
---- Create new component. It will inheritance from basic Druid component.
--- @function BaseComponent.create
--- @tparam string name BaseComponent name
--- @tparam number|nil input_priority The input priority. The bigger number processed first
--- @local
-function BaseComponent.create(name, input_priority)
+---Сreate a new component class, which will inherit from the base Druid component.
+---@param name string|nil The name of the component
+---@param input_priority number|nil The input priority. The bigger number processed first. Default value: 10
+---@return druid.base_component
+function M.create(name, input_priority)
local new_class = setmetatable({}, {
- __index = BaseComponent,
+ __index = M,
__call = function(cls, ...)
local self = setmetatable({
_component = {
- name = name,
+ name = name or "Druid Component",
input_priority = input_priority or const.PRIORITY_INPUT,
default_input_priority = input_priority or const.PRIORITY_INPUT,
- is_debug = false,
_is_input_priority_changed = true, -- Default true for sort once time after GUI init
- _uid = BaseComponent.create_uid()
+ _uid = M.create_uid()
}
}, {
__index = cls
@@ -506,4 +391,4 @@ function BaseComponent.create(name, input_priority)
end
-return BaseComponent
+return M
diff --git a/druid/const.lua b/druid/const.lua
index 70667de..46ac38c 100755
--- a/druid/const.lua
+++ b/druid/const.lua
@@ -1,10 +1,4 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Druid constants
--- @local
--- @module DruidConst
--- @alias druid_const
-
+---@class druid.system.const
local M = {}
M.ACTION_TEXT = hash(sys.get_config_string("druid.input_text", "text"))
@@ -23,9 +17,6 @@ M.ACTION_LSHIFT = hash(sys.get_config_string("druid.input_key_lshift", "key_lshi
M.ACTION_LCTRL = hash(sys.get_config_string("druid.input_key_lctrl", "key_lctrl"))
M.ACTION_LCMD = hash(sys.get_config_string("druid.input_key_lsuper", "key_lsuper"))
-M.IS_STENCIL_CHECK = not (sys.get_config_int("druid.no_stencil_check", 0) == 1)
-
-
M.ON_INPUT = "on_input"
M.ON_UPDATE = "update"
M.ON_MESSAGE = "on_message"
@@ -33,23 +24,28 @@ M.ON_LATE_INIT = "on_late_init"
M.ON_FOCUS_LOST = "on_focus_lost"
M.ON_FOCUS_GAINED = "on_focus_gained"
M.ON_LAYOUT_CHANGE = "on_layout_change"
-M.ON_MESSAGE_INPUT = "on_message_input"
M.ON_WINDOW_RESIZED = "on_window_resized"
M.ON_LANGUAGE_CHANGE = "on_language_change"
+M.ALL_INTERESTS = {
+ M.ON_INPUT,
+ M.ON_UPDATE,
+ M.ON_MESSAGE,
+ M.ON_LATE_INIT,
+ M.ON_FOCUS_LOST,
+ M.ON_FOCUS_GAINED,
+ M.ON_LAYOUT_CHANGE,
+ M.ON_WINDOW_RESIZED,
+ M.ON_LANGUAGE_CHANGE,
+}
+
+M.MSG_LAYOUT_CHANGED = hash("layout_changed")
+
-- Components with higher priority value processed first
M.PRIORITY_INPUT = 10
M.PRIORITY_INPUT_HIGH = 20
M.PRIORITY_INPUT_MAX = 100
-M.MESSAGE_INPUT = {
- BUTTON_CLICK = "button_click",
- BUTTON_LONG_CLICK = "button_long_click",
- BUTTON_DOUBLE_CLICK = "button_double_click",
- BUTTON_REPEATED_CLICK = "button_repeated_click",
- TEXT_SET = "text_set",
-}
-
M.PIVOTS = {
[gui.PIVOT_CENTER] = vmath.vector3(0),
[gui.PIVOT_N] = vmath.vector3(0, 0.5, 0),
@@ -83,7 +79,6 @@ M.LAYOUT_MODE = {
STRETCH = gui.ADJUST_STRETCH,
}
-M.VECTOR_ZERO = vmath.vector3(0)
M.SYS_INFO = sys.get_sys_info()
M.CURRENT_SYSTEM_NAME = M.SYS_INFO.system_name
@@ -104,10 +99,13 @@ M.SHIFT = {
M.TEXT_ADJUST = {
DOWNSCALE = "downscale",
- TRIM = "trim",
NO_ADJUST = "no_adjust",
DOWNSCALE_LIMITED = "downscale_limited",
SCROLL = "scroll",
+ TRIM = "trim",
+ TRIM_LEFT = "trim_left",
+ SCALE_THEN_TRIM = "scale_then_trim",
+ SCALE_THEN_TRIM_LEFT = "scale_then_trim_left",
SCALE_THEN_SCROLL = "scale_then_scroll",
}
@@ -116,17 +114,5 @@ M.SIDE = {
Y = "y"
}
-M.SWIPE = {
- UP = "up",
- DOWN = "down",
- LEFT = "left",
- RIGHT = "right",
-}
-
-M.ERRORS = {
- GRID_DYNAMIC_ANCHOR = "The pivot of dynamic grid node should be West, East, South or North"
-}
-
-M.EMPTY_FUNCTION = function() end
return M
diff --git a/druid/custom/rich_input/rich_input.gui b/druid/custom/rich_input/rich_input.gui
index b511cec..c179f20 100644
--- a/druid/custom/rich_input/rich_input.gui
+++ b/druid/custom/rich_input/rich_input.gui
@@ -1,371 +1,160 @@
-script: ""
fonts {
- name: "game"
- font: "/example/assets/fonts/game.font"
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
}
textures {
- name: "kenney"
- texture: "/example/assets/images/kenney.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid"
+ texture: "/druid/druid.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
- x: 1.0
- y: 1.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: 200.0
+ y: 40.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "kenney/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_AUTO
+ visible: false
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
- x: 190.0
- y: 45.0
- z: 0.0
- w: 1.0
+ x: 200.0
+ y: 40.0
}
color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: 0.31
+ y: 0.318
+ z: 0.322
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "kenney/progress_back"
+ texture: "druid/rect_round2_width2"
id: "button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ x: 4.0
+ y: 4.0
+ z: 4.0
+ w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_AUTO
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
scale {
x: 0.5
y: 0.5
- z: 1.0
- w: 1.0
}
size {
- x: 300.0
- y: 60.0
- z: 0.0
- w: 1.0
+ x: 380.0
+ y: 50.0
}
color {
- x: 0.9490196
- y: 0.9490196
- z: 0.9490196
- w: 1.0
+ x: 0.31
+ y: 0.318
+ z: 0.322
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Placeholder"
- font: "game"
+ font: "druid_text_bold"
id: "placeholder_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 0.4
y: 0.4
z: 0.4
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button"
- layer: ""
+ parent: "root"
inherit_alpha: true
- alpha: 1.0
- outline_alpha: 1.0
+ outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
scale {
- x: 0.6
- y: 0.6
- z: 1.0
- w: 1.0
+ x: 0.5
+ y: 0.5
}
size {
- x: 300.0
- y: 60.0
- z: 0.0
- w: 1.0
+ x: 380.0
+ y: 50.0
}
color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: 0.722
+ y: 0.741
+ z: 0.761
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "User input"
- font: "game"
+ font: "druid_text_bold"
id: "input_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button"
- layer: ""
+ parent: "root"
inherit_alpha: true
- alpha: 1.0
- outline_alpha: 1.0
+ outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
}
nodes {
position {
- x: 67.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
+ x: 61.0
}
scale {
- x: 0.6
- y: 0.6
- z: 1.0
- w: 1.0
+ x: 0.5
+ y: 0.5
}
size {
- x: 1.0
- y: 1.0
- z: 0.0
- w: 1.0
+ x: 16.0
+ y: 50.0
}
color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: 0.631
+ y: 0.843
+ z: 0.961
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "kenney/empty"
+ texture: "druid/ui_circle_16"
id: "cursor_node"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button"
- layer: ""
+ parent: "root"
inherit_alpha: true
slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ x: 8.0
+ y: 8.0
+ z: 8.0
+ w: 8.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_AUTO
+ alpha: 0.5
}
nodes {
position {
- x: 0.0
- y: 2.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: -1.4
+ y: 4.0
}
size {
x: 20.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
- x: 0.2
- y: 0.2
- z: 0.2
- w: 1.0
+ x: 0.722
+ y: 0.741
+ z: 0.761
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "|"
- font: "game"
+ font: "druid_text_bold"
id: "cursor_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "cursor_node"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/druid/custom/rich_input/rich_input.lua b/druid/custom/rich_input/rich_input.lua
index c42b637..fdc5f10 100644
--- a/druid/custom/rich_input/rich_input.lua
+++ b/druid/custom/rich_input/rich_input.lua
@@ -6,13 +6,13 @@
-- @alias druid.rich_input
--- The component druid instance
--- @tfield DruidInstance druid @{DruidInstance}
+-- @tfield DruidInstance druid DruidInstance
--- Root node
-- @tfield node root
--- On input field text change callback(self, input_text)
--- @tfield Input input @{Input}
+-- @tfield Input input Input
--- On input field text change to empty string callback(self, input_text)
-- @tfield node cursor
@@ -43,17 +43,22 @@ local const = require("druid.const")
local utf8_lua = require("druid.system.utf8")
local utf8 = utf8 or utf8_lua
-local input = require("druid.extended.input")
-local RichInput = component.create("druid.rich_input")
+---@class druid.rich_input: druid.base_component
+---@field root node
+---@field input druid.input
+---@field cursor node
+---@field cursor_text node
+---@field cursor_position vector3
+local M = component.create("druid.rich_input")
-local SCHEME = {
- ROOT = "root",
- BUTTON = "button",
- PLACEHOLDER = "placeholder_text",
- INPUT = "input_text",
- CURSOR = "cursor_node",
- CURSOR_TEXT = "cursor_text",
-}
+--local SCHEME = {
+-- ROOT = "root",
+-- BUTTON = "button",
+-- PLACEHOLDER = "placeholder_text",
+-- INPUT = "input_text",
+-- CURSOR = "cursor_node",
+-- CURSOR_TEXT = "cursor_text",
+--}
local DOUBLE_CLICK_TIME = 0.35
@@ -189,13 +194,11 @@ local function on_drag_callback(self, dx, dy, x, y, touch)
end
---- The @{RichInput} constructor
--- @tparam RichInput self @{RichInput}
--- @tparam string template The template string name
--- @tparam table nodes Nodes table from gui.clone_tree
-function RichInput.init(self, template, nodes)
+---@param template string The template string name
+---@param nodes table Nodes table from gui.clone_tree
+function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self:get_node(SCHEME.ROOT)
+ self.root = self:get_node("root")
self._last_touch_info = {
cursor_index = nil,
@@ -204,20 +207,20 @@ function RichInput.init(self, template, nodes)
self.is_lshift = false
self.is_lctrl = false
- self.input = self.druid:new(input, self:get_node(SCHEME.BUTTON), self:get_node(SCHEME.INPUT))
+ self.input = self.druid:new_input("button", "input_text")
self.is_button_input_enabled = gui.is_enabled(self.input.button.node)
- self.cursor = self:get_node(SCHEME.CURSOR)
+ self.cursor = self:get_node("cursor_node")
self.cursor_position = gui.get_position(self.cursor)
- self.cursor_text = self:get_node(SCHEME.CURSOR_TEXT)
+ self.cursor_text = self:get_node("cursor_text")
- self.drag = self.druid:new_drag(self:get_node(SCHEME.BUTTON), on_drag_callback)
+ self.drag = self.druid:new_drag("button", on_drag_callback)
self.drag.on_touch_start:subscribe(on_touch_start_callback)
self.drag:set_input_priority(const.PRIORITY_INPUT_MAX + 1)
self.drag:set_enabled(false)
self.input:set_text("")
- self.placeholder = self.druid:new_text(self:get_node(SCHEME.PLACEHOLDER))
+ self.placeholder = self.druid:new_text("placeholder_text")
self.text_position = gui.get_position(self.input.text.node)
self.input.on_input_text:subscribe(update_text)
@@ -230,7 +233,7 @@ function RichInput.init(self, template, nodes)
end
-function RichInput.on_input(self, action_id, action)
+function M:on_input(action_id, action)
if action_id == const.ACTION_LSHIFT then
if action.pressed then
self.is_lshift = true
@@ -247,37 +250,38 @@ function RichInput.on_input(self, action_id, action)
end
end
- if action_id == const.ACTION_LEFT and (action.pressed or action.repeated) then
- self.input:move_selection(-1, self.is_lshift, self.is_lctrl)
- end
+ if self.input.is_selected then
+ if action_id == const.ACTION_LEFT and (action.pressed or action.repeated) then
+ self.input:move_selection(-1, self.is_lshift, self.is_lctrl)
+ return true
+ end
- if action_id == const.ACTION_RIGHT and (action.pressed or action.repeated) then
- self.input:move_selection(1, self.is_lshift, self.is_lctrl)
+ if action_id == const.ACTION_RIGHT and (action.pressed or action.repeated) then
+ self.input:move_selection(1, self.is_lshift, self.is_lctrl)
+ return true
+ end
end
end
--- Set placeholder text
--- @tparam RichInput self @{RichInput}
--- @tparam string placeholder_text The placeholder text
-function RichInput.set_placeholder(self, placeholder_text)
- self.placeholder:set_to(placeholder_text)
+---@param placeholder_text string The placeholder text
+function M:set_placeholder(placeholder_text)
+ self.placeholder:set_text(placeholder_text)
return self
end
--- Select input field
--- @tparam RichInput self @{RichInput}
-function RichInput.select(self)
+function M:select()
self.input:select()
end
--- Set input field text
--- @tparam RichInput self @{RichInput}
--- @treturn druid.input Current input instance
--- @tparam string text The input text
-function RichInput.set_text(self, text)
+---@param text string The input text
+---@return druid.rich_input self Current instance
+function M:set_text(text)
self.input:set_text(text)
gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0)
@@ -286,10 +290,9 @@ end
--- Set input field font
--- @tparam RichInput self @{RichInput}
--- @tparam hash font The font hash
--- @treturn druid.input Current input instance
-function RichInput.set_font(self, font)
+---@param font hash The font hash
+---@return druid.rich_input self Current instance
+function M:set_font(font)
gui.set_font(self.input.text.node, font)
gui.set_font(self.placeholder.node, font)
@@ -298,8 +301,7 @@ end
--- Set input field text
--- @tparam RichInput self @{RichInput}
-function RichInput.get_text(self)
+function M:get_text()
return self.input:get_text()
end
@@ -307,14 +309,13 @@ end
--- Set allowed charaters for input field.
-- See: https://defold.com/ref/stable/string/
-- ex: [%a%d] for alpha and numeric
--- @tparam RichInput self @{RichInput}
--- @tparam string characters Regulax exp. for validate user input
--- @treturn RichInput Current instance
-function RichInput.set_allowed_characters(self, characters)
+---@param characters string Regulax exp. for validate user input
+---@return druid.rich_input Current instance
+function M:set_allowed_characters(characters)
self.input:set_allowed_characters(characters)
return self
end
-return RichInput
+return M
diff --git a/druid/custom/rich_text/module/rt.lua b/druid/custom/rich_text/module/rt.lua
index 8baa48c..8239877 100755
--- a/druid/custom/rich_text/module/rt.lua
+++ b/druid/custom/rich_text/module/rt.lua
@@ -2,10 +2,6 @@
-- Author: Britzl
-- Modified by: Insality
---- RT
--- @module rich_text.rt
--- @local
-
local helper = require("druid.helper")
local parser = require("druid.custom.rich_text.module.rt_parse")
local utf8_lua = require("druid.system.utf8")
@@ -185,7 +181,7 @@ function M.create(text, settings, style)
outline = settings.outline,
font = gui.get_font(settings.text_prefab),
-- Image params
- ---@type druid.rich_text.image
+ ---@type druid.rich_text.word.image
image = nil,
-- Tags
br = nil,
@@ -428,7 +424,7 @@ function M._update_nodes(lines, settings)
gui.set_outline(node, word.outline)
gui.set_shadow(node, word.shadow)
gui.set_text(node, word.text)
- gui.set_color(node, word.color or word.text_color)
+ gui.set_color(node, word.color)
gui.set_font(node, word.font or settings.font)
end
word.node = node
diff --git a/druid/custom/rich_text/rich_text.lua b/druid/custom/rich_text/rich_text.lua
index 4ed7198..6e2fb8d 100644
--- a/druid/custom/rich_text/rich_text.lua
+++ b/druid/custom/rich_text/rich_text.lua
@@ -63,7 +63,7 @@
-- @alias druid.rich_text
--- The component druid instance
--- @tfield DruidInstance druid @{DruidInstance}
+-- @tfield DruidInstance druid DruidInstance
--- The root node of the Rich Text
-- @tfield node root
@@ -76,14 +76,83 @@
local component = require("druid.component")
local rich_text = require("druid.custom.rich_text.module.rt")
-local RichText = component.create("rich_text")
+---@class druid.rich_text.settings
+---@field parent node
+---@field size number
+---@field fonts table
+---@field scale vector3
+---@field color vector4
+---@field shadow vector4
+---@field outline vector4
+---@field position vector3
+---@field image_pixel_grid_snap boolean
+---@field combine_words boolean
+---@field default_animation string
+---@field text_prefab node
+---@field adjust_scale number
+---@field default_texture string
+---@field is_multiline boolean
+---@field text_leading number
+---@field font hash
+---@field width number
+---@field height number
+
+---@class druid.rich_text.word
+---@field node node
+---@field relative_scale number
+---@field source_text string
+---@field color vector4
+---@field position vector3
+---@field offset vector3
+---@field scale vector3
+---@field size vector3
+---@field metrics druid.rich_text.metrics
+---@field pivot userdata
+---@field text string
+---@field shadow vector4
+---@field outline vector4
+---@field font string
+---@field image druid.rich_text.word.image
+---@field br boolean
+---@field nobr boolean
+
+---@class druid.rich_text.word.image
+---@field texture string
+---@field anim string
+---@field width number
+---@field height number
+
+---@class druid.rich_text.style
+---@field COLORS table
+---@field ADJUST_STEPS number
+---@field ADJUST_SCALE_DELTA number
+---@field ADJUST_TYPE string
+---@field ADJUST_SCALE number
+
+---@class druid.rich_text.lines_metrics
+---@field text_width number
+---@field text_height number
+---@field lines table
+
+---@class druid.rich_text.metrics
+---@field width number
+---@field height number
+---@field offset_x number|nil
+---@field offset_y number|nil
+---@field node_size vector3|nil
+
+---@class druid.rich_text: druid.base_component
+---@field root node
+---@field text_prefab node
+---@field private _last_value string
+---@field private _settings table
+local M = component.create("rich_text")
---- The @{RichText} constructor
--- @tparam RichText self @{RichText}
--- @tparam node|string text_node The text node to make Rich Text
--- @tparam string|nil value The initial text value. Default will be gui.get_text(text_node)
-function RichText.init(self, text_node, value)
+--- The RichText constructor
+---@param text_node node|string The text node to make Rich Text
+---@param value string|nil The initial text value. Default will be gui.get_text(text_node)
+function M:init(text_node, value)
self.root = self:get_node(text_node)
self.text_prefab = self.root
@@ -98,7 +167,7 @@ function RichText.init(self, text_node, value)
end
-function RichText.on_layout_change(self)
+function M:on_layout_change()
if self._last_value then
self:set_text(self._last_value)
end
@@ -112,7 +181,7 @@ end
-- @tfield table|nil COLORS Rich Text color aliases. Default: {}
-- @tfield number|nil ADJUST_STEPS Amount steps of attemps text adjust by height. Default: 20
-- @tfield number|nil ADJUST_SCALE_DELTA Scale step on each height adjust step. Default: 0.02
-function RichText.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.COLORS = style.COLORS or {}
self.style.ADJUST_STEPS = style.ADJUST_STEPS or 20
@@ -121,10 +190,9 @@ end
--- Set text for Rich Text
--- @tparam RichText self @{RichText}
--- @tparam string|nil text The text to set
--- @treturn druid.rich_text.word[] words
--- @treturn druid.rich_text.lines_metrics line_metrics
+---@param text string|nil The text to set
+---@return druid.rich_text.word[] words
+---@return druid.rich_text.lines_metrics line_metrics
-- @usage
-- • color: Change text color
--
@@ -168,7 +236,7 @@ end
--
--
--
-function RichText.set_text(self, text)
+function M:set_text(text)
text = text or ""
self:clear()
self._last_value = text
@@ -184,14 +252,13 @@ end
--- Get current text
--- @tparam RichText self @{RichText}
--- @treturn string text
-function RichText.get_text(self)
+---@return string text
+function M:get_text()
return self._last_value
end
-function RichText:on_remove()
+function M:on_remove()
gui.set_scale(self.root, self._default_scale)
gui.set_size(self.root, self._default_size)
self:clear()
@@ -199,7 +266,7 @@ end
--- Clear all created words.
-function RichText:clear()
+function M:clear()
if self._words then
rich_text.remove(self._words)
self._words = nil
@@ -209,12 +276,11 @@ end
--- Get all words, which has a passed tag.
--- @tparam RichText self @{RichText}
--- @tparam string tag
--- @treturn druid.rich_text.word[] words
-function RichText.tagged(self, tag)
+---@param tag string
+---@return druid.rich_text.word[] words
+function M:tagged(tag)
if not self._words then
- return
+ return {}
end
return rich_text.tagged(self._words, tag)
@@ -222,29 +288,28 @@ end
---Split a word into it's characters
--- @tparam RichText self @{RichText}
--- @tparam druid.rich_text.word word
--- @treturn druid.rich_text.word[] characters
-function RichText.characters(self, word)
+---@param word druid.rich_text.word
+---@return druid.rich_text.word[] characters
+function M:characters(word)
return rich_text.characters(word)
end
--- Get all current words.
--- @treturn table druid.rich_text.word[]
-function RichText:get_words()
+---@return druid.rich_text.word[]
+function M:get_words()
return self._words
end
--- Get current line metrics
---- @treturn druid.rich_text.lines_metrics
-function RichText:get_line_metric()
+----@return druid.rich_text.lines_metrics
+function M:get_line_metric()
return self._line_metrics
end
-function RichText:_create_settings()
+function M:_create_settings()
local root_size = gui.get_size(self.root)
local scale = gui.get_scale(self.root)
@@ -280,4 +345,4 @@ function RichText:_create_settings()
end
-return RichText
+return M
diff --git a/druid/druid.atlas b/druid/druid.atlas
index ce36b4e..10868c4 100644
--- a/druid/druid.atlas
+++ b/druid/druid.atlas
@@ -19,4 +19,13 @@ images {
images {
image: "/druid/images/pixel.png"
}
+images {
+ image: "/druid/images/panels/rect_round2_width2.png"
+}
+images {
+ image: "/druid/images/icons/icon_drag.png"
+}
+images {
+ image: "/druid/images/icons/icon_arrow.png"
+}
extrude_borders: 2
diff --git a/druid/druid.lua b/druid/druid.lua
index 37997d4..ce3f034 100644
--- a/druid/druid.lua
+++ b/druid/druid.lua
@@ -1,115 +1,18 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Druid UI Component Framework.
--- # Overview #
---
--- 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.
---
--- To start using Druid, please refer to the Usage section below.
---
--- # Notes #
---
--- • Each Druid instance maintains the self context from the constructor and passes it to each Druid callback.
---
--- See next: @{DruidInstance}
---
--- @usage
--- local druid = require("druid.druid")
---
--- local function on_play(self)
--- print("Gonna play!")
--- end
---
--- function init(self)
--- self.druid = druid.new(self)
--- self.druid:new_button("button_play", on_play)
--- end
---
--- function final(self)
--- self.druid:final()
--- end
---
--- function update(self, dt)
--- self.druid:update(dt)
--- end
---
--- function on_message(self, message_id, message, sender)
--- self.druid:on_message(message_id, message, sender)
--- end
---
--- function on_input(self, action_id, action)
--- return self.druid:on_input(action_id, action)
--- end
---
--- @module Druid
-
-local const = require("druid.const")
-local base_component = require("druid.component")
+local events = require("event.events")
local settings = require("druid.system.settings")
local druid_instance = require("druid.system.druid_instance")
local default_style = require("druid.styles.default.style")
+---@class druid
local M = {}
-local _instances = {}
-
-local function clean_deleted_druid_instances()
- for i = #_instances, 1, -1 do
- if _instances[i]._deleted then
- table.remove(_instances, i)
- end
- end
-end
-
-
-local function get_druid_instances()
- clean_deleted_druid_instances()
- return _instances
-end
-
-
---- Register a new external Druid component.
---
--- 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.
--- @function druid.register
--- @tparam string name module name
--- @tparam table module lua table with component
--- @usage
--- local my_component = require("path.to.my.component")
--- druid.register("my_component", my_component)
--- ...
--- local druid = druid.new(self)
--- local component_instance = self.druid:new_my_component(...)
-function M.register(name, module)
- druid_instance["new_" .. name] = function(self, ...)
- return druid_instance.new(self, module, ...)
- end
-
- return druid_instance["new_" .. name]
-end
-
-
---- Create a new Druid instance for creating GUI components.
---
--- @function druid.new
--- @tparam table context The Druid context. Usually, this is the self of the gui_script. It is passed into all Druid callbacks.
--- @tparam table|nil style The Druid style table to override style parameters for this Druid instance.
--- @treturn druid_instance The Druid instance @{DruidInstance}.
--- @usage
--- local druid = require("druid.druid")
---
--- function init(self)
--- self.druid = druid.new(self)
--- end
+---Create a new Druid instance for creating GUI components.
+---@param context table The Druid context. Usually, this is the self of the gui_script. It is passed into all Druid callbacks.
+---@param style table|nil The Druid style table to override style parameters for this Druid instance.
+---@return druid_instance druid_instance The new Druid instance
function M.new(context, style)
- clean_deleted_druid_instances()
-
if settings.default_style == nil then
M.set_default_style(default_style)
end
@@ -117,96 +20,66 @@ function M.new(context, style)
local new_instance = setmetatable({}, { __index = druid_instance })
new_instance:initialize(context, style)
- table.insert(_instances, new_instance)
return new_instance
end
---- Set your own default style for all Druid instances.
---
--- To create your own style file, copy the default style file and make changes to it.
--- Register the new style before creating your Druid instances.
--- @function druid.set_default_style
--- @tparam table style Druid style module
--- @usage
--- local my_style = require("path.to.my.style")
--- druid.set_default_style(my_style)
+---Register a new external Druid component.
+---Register component just makes the druid:new_{name} function.
+---For example, if you 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 require in every file.
+---The default way to create component is `druid_instance:new(component_class, ...)`.
+---@param name string Module name
+---@param module table Lua table with component
+function M.register(name, module)
+ druid_instance["new_" .. name] = function(self, ...)
+ return druid_instance.new(self, module, ...)
+ end
+end
+
+
+---Set the default style for all Druid instances.
+---@param style table Default style
function M.set_default_style(style)
settings.default_style = style or {}
end
---- Set the text function for the LangText component.
---
--- The Druid locale component will call this function to get translated text.
--- After setting the text function, all existing locale components will be updated.
--- @function druid.set_text_function
--- @tparam function callback Get localized text function
--- @usage
--- druid.set_text_function(function(text_id)
--- return lang_data[text_id] -- Replace with your real function
--- end)
+---Set the text function for the LangText component.
+---@param callback fun(text_id: string): string Get localized text function
function M.set_text_function(callback)
- settings.get_text = callback or const.EMPTY_FUNCTION
+ settings.get_text = callback or function() end
M.on_language_change()
end
---- Set the Druid sound function to play UI sounds if used.
---
--- Set a function to play a sound given a sound_id. This function is used for button clicks to play the "click" sound.
--- It can also be used to play sounds in your custom components (see the default Druid style file for an example).
--- @function druid.set_sound_function
--- @tparam function callback Sound play callback
--- @usage
--- druid.set_sound_function(function(sound_id)
--- sound.play(sound_id) -- Replace with your real function
--- end)
+---Set the sound function to able components to play sounds.
+---@param callback fun(sound_id: string) Sound play callback
function M.set_sound_function(callback)
- settings.play_sound = callback or const.EMPTY_FUNCTION
+ settings.play_sound = callback or function() end
end
---- Set the window callback to enable on_focus_gain and on_focus_lost functions.
---
--- This is used to trigger the on_focus_lost and on_focus_gain functions in Druid components.
--- @function druid.on_window_callback
--- @tparam string event Event param from window listener
--- @usage
--- window.set_listener(function(_, event)
--- druid.on_window_callback(event)
--- end)
-function M.on_window_callback(event)
- local instances = get_druid_instances()
-
- if event == window.WINDOW_EVENT_FOCUS_LOST then
- for i = 1, #instances do
- msg.post(instances[i].url, base_component.ON_FOCUS_LOST)
- end
- elseif event == window.WINDOW_EVENT_FOCUS_GAINED then
- for i = 1, #instances do
- msg.post(instances[i].url, base_component.ON_FOCUS_GAINED)
- end
- elseif event == window.WINDOW_EVENT_RESIZED then
- for i = 1, #instances do
- msg.post(instances[i].url, base_component.ON_WINDOW_RESIZED)
- end
- end
+---Subscribe Druid to the window listener. It will override your previous
+---window listener, so if you have one, you should call M.on_window_callback manually.
+function M.init_window_listener()
+ window.set_listener(function(_, window_event)
+ events.trigger("druid.window_event", window_event)
+ end)
end
---- Call this function when the game language changes.
---
--- This function will translate all current LangText components.
--- @function druid.on_language_change
--- @usage
--- druid.on_language_change()
+---Set the window callback to enable Druid window events.
+---@param window_event constant Event param from window listener
+function M.on_window_callback(window_event)
+ events.trigger("druid.window_event", window_event)
+end
+
+
+---Call this function when the game language changes.
+---It will notify all Druid instances to update the lang text components.
function M.on_language_change()
- local instances = get_druid_instances()
-
- for i = 1, #instances do
- msg.post(instances[i].url, base_component.ON_LANGUAGE_CHANGE)
- end
+ events.trigger("druid.language_change")
end
diff --git a/druid/druid.script b/druid/druid.script
new file mode 100644
index 0000000..209ba74
--- /dev/null
+++ b/druid/druid.script
@@ -0,0 +1,37 @@
+-- Place this script nearby with the gui component to able make requests
+-- To the go namespace from GUI with events systems (cross context)
+
+local event_queue = require("druid.event_queue")
+
+---Usage: event_queue.request("druid.get_atlas_path", callback, gui.get_texture(self.node), msg.url())
+---Pass texture name to get atlas info and sender url to check if the request is valid
+local MESSAGE_GET_ATLAS_PATH = "druid.get_atlas_path"
+
+
+---@param texture_name hash The name from gui.get_texture(node)
+---@param sender hash Just msg.url from the caller
+local function get_atlas_path(texture_name, sender)
+ local my_url = msg.url()
+ my_url.fragment = nil
+
+ local copy_url = msg.url(sender)
+ copy_url.fragment = nil
+
+ -- This check should works well
+ local is_my_url = my_url == copy_url
+ if not is_my_url then
+ return nil
+ end
+
+ return go.get(sender, "textures", { key = texture_name })
+end
+
+
+function init(self)
+ event_queue.subscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path)
+end
+
+
+function final(self)
+ event_queue.unsubscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path)
+end
\ No newline at end of file
diff --git a/druid/editor_scripts/component.lua_template b/druid/editor_scripts/component.lua_template
index f33bae3..560dc2a 100644
--- a/druid/editor_scripts/component.lua_template
+++ b/druid/editor_scripts/component.lua_template
@@ -7,7 +7,7 @@
local component = require("druid.component")
----@class {COMPONENT_TYPE}: druid.component
+---@class {COMPONENT_TYPE}: druid.base_component
---@field druid druid_instance{COMPONENT_ANNOTATIONS}
local M = component.create("{COMPONENT_TYPE}")
diff --git a/druid/editor_scripts/create_druid_component.py b/druid/editor_scripts/create_druid_component.py
index 24d1203..f27d57f 100644
--- a/druid/editor_scripts/create_druid_component.py
+++ b/druid/editor_scripts/create_druid_component.py
@@ -1,12 +1,9 @@
-# @license MIT, Insality 2021
-# @source https://github.com/Insality/druid
-
import os
import sys
import deftree
current_filepath = os.path.abspath(os.path.dirname(__file__))
-TEMPLATE_PATH = current_filepath + "/component.lua_template"
+TEMPLATE_PATH = current_filepath + "/widget.lua_template"
component_annotations = ""
component_functions = ""
@@ -44,13 +41,9 @@ def process_component(node_name, component_name):
component_define += "\n\tself.{0} = self.druid:new_lang_text(\"{1}\", \"lang_id\")".format(node_name, node_name)
if node_name.startswith("grid") or node_name.startswith("static_grid"):
- component_annotations += "\n---@field {0} druid.static_grid".format(node_name)
+ component_annotations += "\n---@field {0} druid.grid".format(node_name)
component_define += "\n--TODO: Replace prefab_name with grid element prefab"
- component_define += "\n\tself.{0} = self.druid:new_static_grid(\"{1}\", \"prefab_name\", 1)".format(node_name, node_name)
-
- if node_name.startswith("dynamic_grid"):
- component_annotations += "\n---@field {0} druid.dynamic_grid".format(node_name)
- component_define += "\n\tself.{0} = self.druid:new_dynamic_grid(\"{1}\")".format(node_name, node_name)
+ component_define += "\n\tself.{0} = self.druid:new_grid(\"{1}\", \"prefab_name\", 1)".format(node_name, node_name)
if node_name.startswith("scroll_view"):
field_name = node_name.replace("_view", "")
diff --git a/druid/editor_scripts/druid.editor_script b/druid/editor_scripts/druid.editor_script
index 2f63c92..96076c5 100644
--- a/druid/editor_scripts/druid.editor_script
+++ b/druid/editor_scripts/druid.editor_script
@@ -1,6 +1,3 @@
---- @license MIT, Insality 2021
---- @source https://github.com/Insality/druid
-
local M = {}
@@ -27,18 +24,12 @@ function M.get_commands()
return {
{
label = "Assign Layers",
-
- locations = {"Edit"},
-
- query = {
- selection = {type = "resource", cardinality = "one"}
- },
-
+ locations = { "Edit" },
+ query = { selection = {type = "resource", cardinality = "one"} },
active = function(opts)
local path = editor.get(opts.selection, "path")
return ends_with(path, ".gui")
end,
-
run = function(opts)
local file = opts.selection
print("Run script for", editor.get(file, "path"))
@@ -59,25 +50,19 @@ function M.get_commands()
},
{
- label = "Create Druid Component",
-
- locations = {"Edit"},
-
- query = {
- selection = {type = "resource", cardinality = "one"}
- },
-
+ label = "Create Druid Widget",
+ locations = { "Edit", "Assets" },
+ query = { selection = {type = "resource", cardinality = "one"} },
active = function(opts)
local path = editor.get(opts.selection, "path")
return ends_with(path, ".gui")
end,
-
run = function(opts)
local file = opts.selection
print("Run script for", editor.get(file, "path"))
save_file_from_dependency('/druid/editor_scripts/run_python_script_on_gui.sh', "./build/run_python_script_on_gui.sh")
save_file_from_dependency('/druid/editor_scripts/create_druid_component.py', "./build/create_druid_component.py")
- save_file_from_dependency('/druid/editor_scripts/component.lua_template', "./build/component.lua_template")
+ save_file_from_dependency('/druid/editor_scripts/widget.lua_template', "./build/widget.lua_template")
return {
{
action = "shell",
diff --git a/druid/editor_scripts/setup_layers.py b/druid/editor_scripts/setup_layers.py
index dd0d580..4af9cff 100644
--- a/druid/editor_scripts/setup_layers.py
+++ b/druid/editor_scripts/setup_layers.py
@@ -31,7 +31,7 @@ def main():
texture = node.get_attribute("texture")
font = node.get_attribute("font")
- if texture:
+ if texture and texture.value:
layer = texture.value.split("/")[0]
node.set_attribute("layer", layer)
diff --git a/druid/editor_scripts/widget.lua_template b/druid/editor_scripts/widget.lua_template
new file mode 100644
index 0000000..dfbc7ed
--- /dev/null
+++ b/druid/editor_scripts/widget.lua_template
@@ -0,0 +1,26 @@
+---This is a template for a {COMPONENT_NAME} Druid widget.
+---Instantiate this template with `druid.new_widget(widget_module, [template_id], [nodes])`.
+---Read more about Druid Widgets here: ...
+
+---@class widget.{COMPONENT_TYPE}: druid.widget
+local M = {}
+
+
+function M:init()
+ -- Now we have next functions to use here:
+ -- self:get_node([node_id]) -- Get node inside widget by id
+ -- self.druid to access Druid Instance API, like:
+ -- self.druid:new_button([node_id], [callback])
+ -- self.druid:new_text([node_id], [text])
+ -- And all functions from component.lua file
+ self.root = self:get_node("root")
+ self.button = self.druid:new_button("button", self.on_button, self)
+end
+
+
+function M:on_button()
+ print("Root node", self.root)
+end
+
+
+return M
\ No newline at end of file
diff --git a/druid/event.lua b/druid/event.lua
deleted file mode 100644
index ef79c86..0000000
--- a/druid/event.lua
+++ /dev/null
@@ -1,205 +0,0 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Druid Event Module
---
--- The Event module provides a simple class for handling callbacks. It is used in many Druid components.
---
--- You can subscribe to an event using the `:subscribe` method and unsubscribe using the `:unsubscribe` method.
--- @module DruidEvent
--- @alias druid.event
-
-local M = {}
-M.COUNTER = 0
-
--- Forward declaration
-local EVENT_METATABLE
-
--- Local versions
-local pcall = pcall
-local tinsert = table.insert
-local tremove = table.remove
-
---- DruidEvent constructor
--- @tparam function|nil callback Subscribe the callback on new event, if callback exist
--- @tparam any|nil callback_context Additional context as first param to callback call
--- @usage
--- local Event = require("druid.event")
--- ...
--- local event = Event(callback)
-function M.create(callback, callback_context)
- local instance = setmetatable({}, EVENT_METATABLE)
-
- if callback then
- instance:subscribe(callback, callback_context)
- end
-
- M.COUNTER = M.COUNTER + 1
- return instance
-end
-
-
---- Check is event subscribed.
--- @tparam DruidEvent self @{DruidEvent}
--- @tparam function callback Callback itself
--- @tparam any|nil callback_context Additional context as first param to callback call
--- @treturn boolean, number|nil @Is event subscribed, return index of callback in event as second param
-function M.is_subscribed(self, callback, callback_context)
- if #self == 0 then
- return false, nil
- end
-
- for index = 1, #self do
- local cb = self[index]
- if cb[1] == callback and cb[2] == callback_context then
- return true, index
- end
- end
-
- return false, nil
-end
-
-
---- Subscribe callback on event
--- @tparam DruidEvent self @{DruidEvent}
--- @tparam function callback Callback itself
--- @tparam any|nil callback_context Additional context as first param to callback call, usually it's self
--- @treturn boolean True if callback was subscribed
--- @usage
--- local function on_long_callback(self)
--- print("Long click!")
--- end
--- ...
--- local button = self.druid:new_button("button", callback)
--- button.on_long_click:subscribe(on_long_callback, self)
-function M.subscribe(self, callback, callback_context)
- assert(type(self) == "table", "You should subscribe to event with : syntax")
- assert(callback, "A function must be passed to subscribe to an event")
-
- if self:is_subscribed(callback, callback_context) then
- return false
- end
-
- tinsert(self, { callback, callback_context })
- return true
-end
-
-
---- Unsubscribe callback on event
--- @tparam DruidEvent self @{DruidEvent}
--- @tparam function callback Callback itself
--- @tparam any|nil callback_context Additional context as first param to callback call
--- @usage
--- local function on_long_callback(self)
--- print("Long click!")
--- end
--- ...
--- button.on_long_click:unsubscribe(on_long_callback, self)
-function M.unsubscribe(self, callback, callback_context)
- assert(callback, "A function must be passed to subscribe to an event")
-
- local _, event_index = self:is_subscribed(callback, callback_context)
- if not event_index then
- return false
- end
-
- tremove(self, event_index)
- return true
-end
-
-
---- Return true, if event have at lease one handler
--- @tparam DruidEvent self @{DruidEvent}
--- @treturn boolean True if event have handlers
--- @usage
--- local is_long_click_handler_exists = button.on_long_click:is_exist()
-function M.is_exist(self)
- return #self > 0
-end
-
-
---- Return true, if event not have handler
---- @tparam DruidEvent self @{DruidEvent}
---- @treturn boolean True if event not have handlers
---- @usage
---- local is_long_click_handler_not_exists = button.on_long_click:is_empty()
-function M:is_empty()
- return #self == 0
-end
-
-
---- Clear the all event handlers
--- @tparam DruidEvent self @{DruidEvent}
--- @usage
--- button.on_long_click:clear()
-function M.clear(self)
- for index = #self, 1, -1 do
- self[index] = nil
- end
-end
-
-
---- Trigger the event and call all subscribed callbacks
--- @tparam DruidEvent self @{DruidEvent}
--- @tparam any ... All event params
--- @usage
--- local Event = require("druid.event")
--- ...
--- local event = Event()
--- event:trigger("Param1", "Param2")
-function M.trigger(self, ...)
- if #self == 0 then
- return
- end
-
- local result = nil
-
- local call_callback = self.call_callback
- for index = 1, #self do
- result = call_callback(self, self[index], ...)
- end
-
- return result
-end
-
-
--- @tparam table callback Callback data {function, context}
--- @tparam any ... All event params
--- @treturn any Result of the callback
--- @local
-function M:call_callback(callback, ...)
- local event_callback = callback[1]
- local event_callback_context = callback[2]
-
- -- Call callback
- local ok, result_or_error
- if event_callback_context then
- ok, result_or_error = pcall(event_callback, event_callback_context, ...)
- else
- ok, result_or_error = pcall(event_callback, ...)
- end
-
- -- Handle errors
- if not ok then
- local caller_info = debug.getinfo(2)
- pprint("An error occurred during event processing", {
- trigger = caller_info.short_src .. ":" .. caller_info.currentline,
- error = result_or_error,
- })
- pprint("Traceback", debug.traceback())
- return nil
- end
-
- return result_or_error
-end
-
--- Construct event metatable
-EVENT_METATABLE = {
- __index = M,
- __call = M.trigger,
-}
-
-return setmetatable(M, {
- __call = function(_, callback)
- return M.create(callback)
- end,
-})
diff --git a/druid/event_queue.lua b/druid/event_queue.lua
new file mode 100644
index 0000000..cdeb7c2
--- /dev/null
+++ b/druid/event_queue.lua
@@ -0,0 +1,84 @@
+local event = require("event.event")
+
+---@class event.queue
+local M = {}
+
+local event_handlers = {}
+local pending_callbacks = {}
+
+
+---Request to handle a specified event and processes the queue of callbacks associated with it.
+---If event has already been triggered, the callback will be executed immediately.
+---If event not triggered yet, callback will be executed when event will be triggered.
+---It triggered only once and then removed from the queue.
+---@param event_name string The name of the event to trigger.
+---@param callback fun() The callback function to execute upon triggering.
+---@param ... any Additional arguments for the callback.
+function M.request(event_name, callback, ...)
+ pending_callbacks[event_name] = pending_callbacks[event_name] or {}
+ table.insert(pending_callbacks[event_name], { event.create(callback), ... })
+
+ M.process_pending_callbacks(event_name)
+end
+
+
+---Subscribes to a specified event and executes a callback when the event is triggered.
+-- If the event has already been triggered, the callback will be executed immediately.
+---@param event_name string The name of the event to subscribe to.
+---@param callback fun() The function to call when the event is triggered.
+function M.subscribe(event_name, callback)
+ event_handlers[event_name] = event_handlers[event_name] or event.create()
+
+ if event_handlers[event_name] then
+ event_handlers[event_name]:subscribe(callback)
+ end
+
+ M.process_pending_callbacks(event_name)
+end
+
+
+---Unsubscribes a callback function from a specified event.
+---@param event_name string The name of the event to unsubscribe from.
+---@param callback fun() The function to remove from the event's subscription list.
+function M.unsubscribe(event_name, callback)
+ if event_handlers[event_name] then
+ event_handlers[event_name]:unsubscribe(callback)
+ end
+end
+
+
+---Processes the queue for a given event name, executing callbacks and handling results.
+---Processed callbacks are removed from the queue.
+---@param event_name string The name of the event for which to process the queue.
+function M.process_pending_callbacks(event_name)
+ local callbacks_to_process = pending_callbacks[event_name]
+ local event_handler = event_handlers[event_name]
+
+ if not callbacks_to_process or not event_handler then
+ return
+ end
+
+ -- Loop through the queue in reverse to prevent index errors during removal
+ for i = #callbacks_to_process, 1, -1 do
+ local callback_entry = callbacks_to_process[i]
+ -- Better to figure out how to make it without 2 unpacks, but ok for all our cases now
+ local args = { unpack(callback_entry, 2) }
+
+ -- Safely call the event handler and handle errors
+ local success, result = pcall(event_handler.trigger, event_handler, unpack(args))
+
+ if success and result then
+ local callback_function = callback_entry[1]
+ pcall(callback_function, result) -- Safely invoke the callback, catching any errors
+ table.remove(callbacks_to_process, i) -- Remove the processed callback from the queue
+ end
+ end
+
+ -- Clean up if the callback queue is empty
+ if #callbacks_to_process == 0 then
+ pending_callbacks[event_name] = nil
+ end
+end
+
+
+return M
diff --git a/example/components/container/container.lua b/druid/extended/container.lua
similarity index 92%
rename from example/components/container/container.lua
rename to druid/extended/container.lua
index 8e0c977..c9f07c9 100644
--- a/example/components/container/container.lua
+++ b/druid/extended/container.lua
@@ -13,7 +13,7 @@
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Event = require("druid.event")
+local event = require("event.event")
---@class druid.container: druid.base_component
---@field node node
@@ -29,7 +29,7 @@ local Event = require("druid.event")
---@field fit_size vector3
---@field min_size_x number|nil
---@field min_size_y number|nil
----@field on_size_changed druid.event @function on_size_changed(size)
+---@field on_size_changed event @function on_size_changed(size)
---@field _parent_container druid.container
---@field _containers table
---@field _draggable_corners table
@@ -50,7 +50,7 @@ local CORNER_PIVOTS = {
--- The Container init
---@param node node Gui node
---@param mode string Layout mode
----@param callback fun(self: druid.container, size: vector3) Callback on size changed
+---@param callback fun(self: druid.container, size: vector3)|nil Callback on size changed
function M:init(node, mode, callback)
self.node = self:get_node(node)
self.druid = self:get_druid()
@@ -82,7 +82,7 @@ function M:init(node, mode, callback)
gui.set_size_mode(self.node, gui.SIZE_MODE_MANUAL)
gui.set_adjust_mode(self.node, gui.ADJUST_FIT)
- self.on_size_changed = Event(callback)
+ self.on_size_changed = event.create(callback)
self.pivot_offset = helper.get_pivot_offset(gui.get_pivot(self.node))
self.center_offset = -vmath.vector3(self.size.x * self.pivot_offset.x, self.size.y * self.pivot_offset.y, 0)
@@ -134,8 +134,9 @@ end
--- Set new size of layout node
---@param width number|nil
---@param height number|nil
----@return druid.container @{Container}
-function M:set_size(width, height)
+---@param anchor_pivot constant|nil If set will keep the corner possition relative to the new size
+---@return druid.container Container
+function M:set_size(width, height, anchor_pivot)
width = width or self.size.x
height = height or self.size.y
@@ -149,11 +150,23 @@ function M:set_size(width, height)
if (width and width ~= self.size.x) or (height and height ~= self.size.y) then
self.center_offset.x = -width * self.pivot_offset.x
self.center_offset.y = -height * self.pivot_offset.y
+ local dx = self.size.x - width
+ local dy = self.size.y - height
self.size.x = width
self.size.y = height
self.size.z = 0
gui.set_size(self.node, self.size)
+ if anchor_pivot then
+ local pivot = gui.get_pivot(self.node)
+ local pivot_offset = helper.get_pivot_offset(pivot)
+ local new_pivot_offset = helper.get_pivot_offset(anchor_pivot)
+
+ local position_dx = dx * (pivot_offset.x - new_pivot_offset.x)
+ local position_dy = dy * (pivot_offset.y - new_pivot_offset.y)
+ self:set_position(self._position.x + position_dx, self._position.y - position_dy)
+ end
+
self:update_child_containers()
self.on_size_changed:trigger(self:get_context(), self.size)
end
@@ -162,6 +175,11 @@ function M:set_size(width, height)
end
+function M:get_position()
+ return self._position
+end
+
+
---@param pos_x number
---@param pos_y number
function M:set_position(pos_x, pos_y)
@@ -178,7 +196,7 @@ end
---Get current size of layout node
---@return vector3 size
function M:get_size()
- return self.size
+ return vmath.vector3(self.size)
end
@@ -191,22 +209,22 @@ end
--- Set size for layout node to fit inside it
---@param target_size vector3
----@return druid.container @{Container}
+---@return druid.container Container
function M:fit_into_size(target_size)
self.fit_size = target_size
self:refresh()
+
return self
end
--- Set current size for layout node to fit inside it
----@return druid.container @{Container}
+---@return druid.container Container
function M:fit_into_window()
return self:fit_into_size(vmath.vector3(gui.get_width(), gui.get_height(), 0))
end
----@param self druid.container
function M:on_window_resized()
local x_koef, y_koef = helper.get_screen_aspect_koef()
self.x_koef = x_koef
@@ -221,7 +239,7 @@ end
---@param node_or_container node|string|druid.container|table
---@param mode string|nil stretch, fit, stretch_x, stretch_y. Default: Pick from node, "fit" or "stretch"
---@param on_resize_callback fun(self: userdata, size: vector3)|nil
----@return druid.container @{Container} New created layout instance
+---@return druid.container Container New created layout instance
function M:add_container(node_or_container, mode, on_resize_callback)
local container = nil
local node = node_or_container
@@ -422,7 +440,7 @@ function M:update_child_containers()
end
----@return druid.container @{Container}
+---@return druid.container Container
function M:create_draggable_corners()
self:clear_draggable_corners()
@@ -452,7 +470,7 @@ function M:create_draggable_corners()
end
----@return druid.container @{Container}
+---@return druid.container Container
function M:clear_draggable_corners()
for index = 1, #self._draggable_corners do
local drag_component = self._draggable_corners[index]
@@ -505,7 +523,7 @@ end
--- Set node for layout node to fit inside it. Pass nil to reset
---@param node string|node The node_id or gui.get_node(node_id)
----@return druid.container @{Layout}
+---@return druid.container Layout
function M:fit_into_node(node)
self._fit_node = self:get_node(node)
self:refresh_scale()
diff --git a/druid/extended/data_list.lua b/druid/extended/data_list.lua
index 81bf959..c7ece01 100644
--- a/druid/extended/data_list.lua
+++ b/druid/extended/data_list.lua
@@ -10,10 +10,10 @@
--- The Druid scroll component
--- @tfield Scroll scroll @{Scroll}
+-- @tfield Scroll scroll Scroll
--- The Druid Grid component
--- @tfield StaticGrid grid @{StaticGrid}, @{DynamicGrid}
+-- @tfield StaticGrid grid StaticGrid}, @{DynamicGrid
--- The current progress of scroll posititon
-- @tfield number scroll_progress
@@ -25,30 +25,41 @@
-- @tfield number last_index
--- Event triggered when scroll progress is changed; event(self, progress_value)
--- @tfield DruidEvent on_scroll_progress_change @{DruidEvent}
+-- @tfield event on_scroll_progress_change event
---On DataList visual element created Event callback(self, index, node, instance)
--- @tfield DruidEvent on_element_add @{DruidEvent}
+-- @tfield event on_element_add event
---On DataList visual element created Event callback(self, index)
--- @tfield DruidEvent on_element_remove @{DruidEvent}
+-- @tfield event on_element_remove event
---
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Event = require("druid.event")
+local event = require("event.event")
-local DataList = component.create("data_list")
+---@class druid.data_list: druid.base_component
+---@field scroll druid.scroll
+---@field grid druid.grid
+---@field on_scroll_progress_change event
+---@field on_element_add event
+---@field on_element_remove event
+---@field private _create_function function
+---@field private _is_use_cache boolean
+---@field private _cache table
+---@field private _data table
+---@field private _data_visual table
+---@field top_index number
+local M = component.create("data_list")
---- The @{DataList} constructor
--- @tparam DataList self @{DataList}
--- @tparam Scroll scroll The @{Scroll} instance for Data List component
--- @tparam StaticGrid grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component
--- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component])
-function DataList.init(self, scroll, grid, create_function)
+--- The DataList constructor
+---@param scroll druid.scroll The Scroll instance for Data List component
+---@param grid druid.grid The StaticGrid} or @{DynamicGrid instance for Data List component
+---@param create_function function The create function callback(self, data, index, data_list). Function should return (node, [component])
+function M:init(scroll, grid, create_function)
self.scroll = scroll
self.grid = grid
if self.grid.style then
@@ -68,35 +79,32 @@ function DataList.init(self, scroll, grid, create_function)
self.scroll.on_scroll:subscribe(self._refresh, self)
- self.on_scroll_progress_change = Event()
- self.on_element_add = Event()
- self.on_element_remove = Event()
+ self.on_scroll_progress_change = event.create()
+ self.on_element_add = event.create()
+ self.on_element_remove = event.create()
end
--- Druid System on_remove function
--- @tparam DataList self @{DataList}
-function DataList.on_remove(self)
+function M:on_remove()
self:clear()
self.scroll.on_scroll:unsubscribe(self._refresh, self)
end
--- Set refresh function for DataList component
--- @tparam DataList self @{DataList}
--- @tparam boolean is_use_cache Use cache version of DataList. Requires make setup of components in on_element_add callback and clean in on_element_remove
--- @treturn druid.data_list Current DataList instance
-function DataList.set_use_cache(self, is_use_cache)
+---@param is_use_cache boolean Use cache version of DataList. Requires make setup of components in on_element_add callback and clean in on_element_remove
+---@return druid.data_list Current DataList instance
+function M:set_use_cache(is_use_cache)
self._is_use_cache = is_use_cache
return self
end
--- Set new data set for DataList component
--- @tparam DataList self @{DataList}
--- @tparam table data The new data array
--- @treturn druid.data_list Current DataList instance
-function DataList.set_data(self, data)
+---@param data table The new data array
+---@return druid.data_list Current DataList instance
+function M:set_data(data)
self._data = data or {}
self:_refresh()
@@ -105,19 +113,17 @@ end
--- Return current data from DataList component
--- @tparam DataList self @{DataList}
--- @treturn table The current data array
-function DataList.get_data(self)
+---@return table The current data array
+function M:get_data()
return self._data
end
--- Add element to DataList. Currenly untested
--- @tparam DataList self @{DataList}
--- @tparam table data
--- @tparam number|nil index
--- @tparam number|nil shift_policy The constant from const.SHIFT.*
-function DataList.add(self, data, index, shift_policy)
+---@param data table
+---@param index number|nil
+---@param shift_policy number|nil The constant from const.SHIFT.*
+function M:add(data, index, shift_policy)
index = index or #self._data + 1
shift_policy = shift_policy or const.SHIFT.RIGHT
@@ -127,20 +133,18 @@ end
--- Remove element from DataList. Currenly untested
--- @tparam DataList self @{DataList}
--- @tparam number|nil index
--- @tparam number|nil shift_policy The constant from const.SHIFT.*
-function DataList.remove(self, index, shift_policy)
+---@param index number|nil
+---@param shift_policy number|nil The constant from const.SHIFT.*
+function M:remove(index, shift_policy)
helper.remove_with_shift(self._data, index, shift_policy)
self:_refresh()
end
--- Remove element from DataList by data value. Currenly untested
--- @tparam DataList self @{DataList}
--- @tparam table data
--- @tparam number|nil shift_policy The constant from const.SHIFT.*
-function DataList.remove_by_data(self, data, shift_policy)
+---@param data table
+---@param shift_policy number|nil The constant from const.SHIFT.*
+function M:remove_by_data(data, shift_policy)
local index = helper.contains(self._data, data)
if index then
helper.remove_with_shift(self._data, index, shift_policy)
@@ -150,17 +154,15 @@ end
--- Clear the DataList and refresh visuals
--- @tparam DataList self @{DataList}
-function DataList.clear(self)
+function M:clear()
self._data = {}
self:_refresh()
end
--- Return index for data value
--- @tparam DataList self @{DataList}
--- @tparam table data
-function DataList.get_index(self, data)
+---@param data table
+function M:get_index(data)
for index, value in pairs(self._data) do
if value == data then
return index
@@ -172,9 +174,8 @@ end
--- Return all currenly created nodes in DataList
--- @tparam DataList self @{DataList}
--- @treturn node[] List of created nodes
-function DataList.get_created_nodes(self)
+---@return node[] List of created nodes
+function M:get_created_nodes()
local nodes = {}
for index, data in pairs(self._data_visual) do
@@ -186,9 +187,8 @@ end
--- Return all currenly created components in DataList
--- @tparam DataList self @{DataList}
--- @treturn druid.base_component[] List of created nodes
-function DataList.get_created_components(self)
+---@return druid.base_component[] List of created nodes
+function M:get_created_components()
local components = {}
for index, data in pairs(self._data_visual) do
@@ -200,19 +200,17 @@ end
--- Instant scroll to element with passed index
--- @tparam DataList self @{DataList}
--- @tparam number index
-function DataList.scroll_to_index(self, index)
+---@param index number
+function M:scroll_to_index(index)
local pos = self.grid:get_pos(index)
self.scroll:scroll_to(pos)
end
--- Add element at passed index using cache or create new
--- @tparam DataList self @{DataList}
--- @tparam number index
--- @local
-function DataList._add_at(self, index)
+---@param index number
+---@private
+function M:_add_at(index)
if self._data_visual[index] then
self:_remove_at(index)
end
@@ -243,10 +241,9 @@ end
--- Remove element from passed index and add it to cache if applicable
--- @tparam DataList self @{DataList}
--- @tparam number index
--- @local
-function DataList._remove_at(self, index)
+---@param index number
+---@private
+function M:_remove_at(index)
self.grid:remove(index, const.SHIFT.NO_SHIFT)
local visual_data = self._data_visual[index]
@@ -274,9 +271,8 @@ end
--- Refresh all elements in DataList
--- @tparam DataList self @{DataList}
--- @local
-function DataList._refresh(self)
+---@private
+function M:_refresh()
self.scroll:set_size(self.grid:get_size_for(#self._data))
local start_pos = -self.scroll.position --[[@as vector3]]
@@ -313,4 +309,4 @@ function DataList._refresh(self)
end
-return DataList
+return M
diff --git a/druid/extended/dynamic_grid.lua b/druid/extended/dynamic_grid.lua
deleted file mode 100644
index c4f0c76..0000000
--- a/druid/extended/dynamic_grid.lua
+++ /dev/null
@@ -1,427 +0,0 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Component to handle placing components in row
---
--- Example Link
--- @module DynamicGrid
--- @within BaseComponent
--- @alias druid.dynamic_grid
-
---- On item add callback(self, node, index)
--- @tfield DruidEvent on_add_item @{DruidEvent}
-
---- On item remove callback(self, index)
--- @tfield DruidEvent on_remove_item @{DruidEvent}
-
---- On item add or remove callback(self, index)
--- @tfield DruidEvent on_change_items @{DruidEvent}
-
---- On grid clear callback(self)
--- @tfield DruidEvent on_clear @{DruidEvent}
-
---- On update item positions callback(self)
--- @tfield DruidEvent on_update_positions @{DruidEvent}
-
---- Parent gui node
--- @tfield node parent
-
---- List of all grid elements. Contains from node, pos, size, pivot
--- @tfield node[] nodes
-
---- The first index of node in grid
--- @tfield number first_index
-
---- The last index of node in grid
--- @tfield number last_index
-
---- Item size
--- @tfield vector3 node_size
-
---- The size of item content
--- @tfield vector4 border
-
----
-
-local const = require("druid.const")
-local Event = require("druid.event")
-local helper = require("druid.helper")
-local component = require("druid.component")
-
-local DynamicGrid = component.create("dynamic_grid")
-
-
-local SIDE_VECTORS = {
- LEFT = vmath.vector3(-1, 0, 0),
- RIGHT = vmath.vector3(1, 0, 0),
- TOP = vmath.vector3(0, -1, 0),
- BOT = vmath.vector3(0, 1, 0),
-}
-
-local AVAILABLE_PIVOTS = {
- gui.PIVOT_N,
- gui.PIVOT_S,
- gui.PIVOT_W,
- gui.PIVOT_E,
-}
-
-
---- The @{DynamicGrid} constructor
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam node parent The gui node parent, where items will be placed
-function DynamicGrid.init(self, parent)
- self.parent = self:get_node(parent)
-
- local parent_pivot = gui.get_pivot(self.parent)
- self.pivot = helper.get_pivot_offset(parent_pivot)
-
- assert(helper.contains(AVAILABLE_PIVOTS, parent_pivot), const.ERRORS.GRID_DYNAMIC_ANCHOR)
- self.side = ((parent_pivot == gui.PIVOT_W or parent_pivot == gui.PIVOT_E)
- and const.SIDE.X or const.SIDE.Y)
-
- self.nodes = {}
- self.border = vmath.vector4(0) -- Current grid content size
-
- self.on_add_item = Event()
- self.on_remove_item = Event()
- self.on_change_items = Event()
- self.on_clear = Event()
- self.on_update_positions = Event()
-
- self._set_position_function = gui.set_position
-end
-
-
-function DynamicGrid.on_layout_change(self)
- self:_update(true)
-end
-
-
---- Return pos for grid node index
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam number index The grid element index
--- @tparam node node The node to be placed
--- @tparam number|nil origin_index Index of nearby node
--- @treturn vector3 node position
-function DynamicGrid.get_pos(self, index, node, origin_index)
- local origin_node = self.nodes[origin_index]
-
- -- If anchor node is not exist, check around nodes
- if not origin_node then
- if self.nodes[index + 1] then
- origin_index = index + 1
- end
- if self.nodes[index - 1] then
- origin_index = index - 1
- end
- origin_node = self.nodes[origin_index]
- end
-
- if not origin_node then
- assert(not self.first_index, "Dynamic Grid can't have gaps between nodes. Error on grid:add")
-
- -- If not origin node, so it should be first element in the grid
- local size = helper.get_scaled_size(node)
- local pivot = const.PIVOTS[gui.get_pivot(node)]
- return vmath.vector3(
- size.x * pivot.x - size.x * self.pivot.x,
- size.y * pivot.y - size.y * self.pivot.y,
- 0)
- end
-
- if origin_node then
- -- Other nodes spawn from other side of the origin node
- local is_forward = origin_index < index
- local delta = is_forward and 1 or -1
- return self:_get_next_node_pos(index - delta, node, self:_get_side_vector(self.side, is_forward))
- end
-end
-
-
---- Add new node to the grid
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam node node Gui node
--- @tparam number|nil index The node position. By default add as last node
--- @tparam number|nil shift_policy How shift nodes, if required. Default: const.SHIFT.RIGHT
--- @tparam boolean|nil is_instant If true, update node positions instantly
-function DynamicGrid.add(self, node, index, shift_policy, is_instant)
- shift_policy = shift_policy or const.SHIFT.RIGHT
- local delta = shift_policy -- -1 or 1 or 0
-
- -- By default add node at end
- index = index or ((self.last_index or 0) + 1)
-
- -- If node exist at index place, shifting them
- local is_shift = self.nodes[index] and shift_policy ~= const.SHIFT.NO_SHIFT
- if is_shift then
- -- We need to iterate from index to start or end grid, depends of shift side
- local start_index = shift_policy == const.SHIFT.LEFT and self.first_index or self.last_index
- for i = start_index, index, -delta do
- self.nodes[i + delta] = self.nodes[i]
- end
- end
-
- self:_add_node(node, index, index - delta)
-
- -- After shifting we should recalc node poses
- if is_shift then
- -- We need to iterate from placed node to start or end grid, depends of shift side
- local target_index = shift_policy == const.SHIFT.LEFT and self.first_index or self.last_index
- for i = index + delta, target_index + delta, delta do
- local move_node = self.nodes[i]
- move_node.pos = self:get_pos(i, move_node.node, i - delta)
- end
- end
-
- -- Sync grid data
- self:_update(is_instant)
-
- self.on_add_item:trigger(self:get_context(), node, index)
- self.on_change_items:trigger(self:get_context(), index)
-end
-
-
---- Remove the item from the grid. Note that gui node will be not deleted
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam number index The grid node index to remove
--- @tparam number|nil shift_policy How shift nodes, if required. Default: const.SHIFT.RIGHT
--- @tparam boolean|nil is_instant If true, update node positions instantly
--- @treturn node The deleted gui node from grid
-function DynamicGrid.remove(self, index, shift_policy, is_instant)
- shift_policy = shift_policy or const.SHIFT.RIGHT
- local delta = shift_policy -- -1 or 1 or 0
-
- assert(self.nodes[index], "No grid item at given index " .. index)
-
- -- Just set nil for delete node data
- local removed_node = self.nodes[index].node
- self.nodes[index] = nil
-
- -- After delete node, we should shift nodes and recalc their poses, depends from is_shift_left
- if shift_policy ~= const.SHIFT.NO_SHIFT then
- local target_index = shift_policy == const.SHIFT.LEFT and self.first_index or self.last_index
- for i = index, target_index, delta do
- self.nodes[i] = self.nodes[i + delta]
- if self.nodes[i] then
- self.nodes[i].pos = self:get_pos(i, self.nodes[i].node, i - delta)
- end
- end
- end
-
- -- Sync grid data
- self:_update(is_instant)
-
- self.on_remove_item:trigger(self:get_context(), index)
- self.on_change_items:trigger(self:get_context(), index)
-
- return removed_node
-end
-
-
---- Return grid content size
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam vector3 border
--- @treturn vector3 The grid content size
-function DynamicGrid.get_size(self, border)
- border = border or self.border
- return vmath.vector3(
- border.z - border.x,
- border.y - border.w,
- 0)
-end
-
-
---- Return DynamicGrid offset, where DynamicGrid content starts.
--- @tparam DynamicGrid self @{DynamicGrid} The DynamicGrid instance
--- @treturn vector3 The DynamicGrid offset
-function DynamicGrid.get_offset(self)
- local size = self:get_size()
- local borders = self:get_borders()
- local offset = vmath.vector3(
- (borders.z + borders.x)/2 + size.x * self.pivot.x,
- (borders.y + borders.w)/2 + size.y * self.pivot.y,
- 0)
-
- return offset
-end
-
-
---- Return grid content borders
--- @tparam DynamicGrid self @{DynamicGrid}
--- @treturn vector3 The grid content borders
-function DynamicGrid.get_borders(self)
- return self.border
-end
-
-
---- Return grid index by node
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam node node The gui node in the grid
--- @treturn number The node index
-function DynamicGrid.get_index_by_node(self, node)
- for index, node_info in pairs(self.nodes) do
- if node == node_info.node then
- return index
- end
- end
-
- return nil
-end
-
-
---- Return array of all node positions
--- @tparam DynamicGrid self @{DynamicGrid}
--- @treturn vector3[] All grid node positions
-function DynamicGrid.get_all_pos(self)
- local result = {}
- for i, node in pairs(self.nodes) do
- table.insert(result, gui.get_position(node.node))
- end
-
- return result
-end
-
-
---- Change set position function for grid nodes. It will call on
--- update poses on grid elements. Default: gui.set_position
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam function callback Function on node set position
--- @treturn druid.dynamic_grid Current grid instance
-function DynamicGrid.set_position_function(self, callback)
- self._set_position_function = callback or gui.set_position
- return self
-end
-
-
---- Clear grid nodes array. GUI nodes will be not deleted!
--- If you want to delete GUI nodes, use dynamic_grid.nodes array before grid:clear
--- @tparam DynamicGrid self @{DynamicGrid}
--- @treturn druid.dynamic_grid Current grid instance
-function DynamicGrid.clear(self)
- self.nodes = {}
- self:_update()
-
- self.on_clear:trigger(self:get_context())
-
- return self
-end
-
-
-function DynamicGrid._add_node(self, node, index, origin_index)
- self.nodes[index] = {
- node = node,
- pos = self:get_pos(index, node, origin_index),
- size = helper.get_scaled_size(node),
- pivot = const.PIVOTS[gui.get_pivot(node)]
- }
-
- -- Add new item instantly in new pos
- gui.set_parent(node, self.parent)
- gui.set_position(node, self.nodes[index].pos)
-end
-
-
---- Update grid inner state
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback
--- @local
-function DynamicGrid._update(self, is_instant)
- self:_update_indexes()
- self:_update_borders()
- self:_update_pos(is_instant)
-end
-
-
---- Update first and last indexes of grid nodes
--- @tparam DynamicGrid self @{DynamicGrid}
--- @local
-function DynamicGrid._update_indexes(self)
- self.first_index = nil
- self.last_index = nil
- for index in pairs(self.nodes) do
- self.first_index = self.first_index or index
- self.last_index = self.last_index or index
-
- self.first_index = math.min(self.first_index, index)
- self.last_index = math.max(self.last_index, index)
- end
-end
-
-
---- Update grid content borders, recalculate min and max values
--- @tparam DynamicGrid self @{DynamicGrid}
--- @local
-function DynamicGrid._update_borders(self)
- if not self.first_index then
- self.border = vmath.vector4(0)
- return
- end
-
- self.border = vmath.vector4(math.huge, -math.huge, -math.huge, math.huge)
-
- for index, node in pairs(self.nodes) do
- local pos = node.pos
- local size = node.size
- local pivot = node.pivot
-
- local left = pos.x - size.x/2 - (size.x * pivot.x)
- local right = pos.x + size.x/2 - (size.x * pivot.x)
- local top = pos.y + size.y/2 - (size.y * pivot.y)
- local bottom = pos.y - size.y/2 - (size.y * pivot.y)
-
- self.border.x = math.min(self.border.x, left)
- self.border.y = math.max(self.border.y, top)
- self.border.z = math.max(self.border.z, right)
- self.border.w = math.min(self.border.w, bottom)
- end
-end
-
-
---- Update grid nodes position
--- @tparam DynamicGrid self @{DynamicGrid}
--- @tparam boolean|nil is_instant If true, node position update instantly, otherwise with set_position_function callback
--- @local
-function DynamicGrid._update_pos(self, is_instant)
- for index, node in pairs(self.nodes) do
- if is_instant then
- gui.set_position(node.node, node.pos)
- else
- self._set_position_function(node.node, node.pos)
- end
- end
-
- self.on_update_positions:trigger(self:get_context())
-end
-
-
-function DynamicGrid._get_next_node_pos(self, origin_node_index, new_node, place_side)
- local node = self.nodes[origin_node_index]
-
- local new_node_size = helper.get_scaled_size(new_node)
- local new_pivot = const.PIVOTS[gui.get_pivot(new_node)]
-
- local dist_x = (node.size.x/2 + new_node_size.x/2) * place_side.x
- local dist_y = (node.size.y/2 + new_node_size.y/2) * place_side.y
- local node_center_x = node.pos.x - node.size.x * node.pivot.x
- local node_center_y = node.pos.y - node.size.y * node.pivot.y
-
- return vmath.vector3(
- node_center_x + dist_x + new_node_size.x * new_pivot.x,
- node_center_y - dist_y + new_node_size.y * new_pivot.y,
- 0
- )
-end
-
-
---- Return side vector to correct node shifting
-function DynamicGrid._get_side_vector(self, side, is_forward)
- if side == const.SIDE.X then
- return is_forward and SIDE_VECTORS.RIGHT or SIDE_VECTORS.LEFT
- end
-
- if side == const.SIDE.Y then
- return is_forward and SIDE_VECTORS.BOT or SIDE_VECTORS.TOP
- end
-end
-
-
-return DynamicGrid
diff --git a/druid/extended/hotkey.lua b/druid/extended/hotkey.lua
index 41507bd..b06f1fe 100644
--- a/druid/extended/hotkey.lua
+++ b/druid/extended/hotkey.lua
@@ -8,10 +8,10 @@
-- @alias druid.hotkey
--- On hotkey released callback(self, argument)
--- @tfield DruidEvent on_hotkey_pressed @{DruidEvent}
+-- @tfield event on_hotkey_pressed event
--- On hotkey released callback(self, argument)
--- @tfield DruidEvent on_hotkey_released @{DruidEvent}
+-- @tfield event on_hotkey_released event
--- Visual node
-- @tfield node node
@@ -20,30 +20,35 @@
-- @tfield node|nil click_node
--- Button component from click_node
--- @tfield Button button @{Button}
+-- @tfield Button button Button
---
local helper = require("druid.helper")
local component = require("druid.component")
-local Event = require("druid.event")
+local event = require("event.event")
-local Hotkey = component.create("hotkey")
+---@class druid.hotkey: druid.base_component
+---@field on_hotkey_pressed event
+---@field on_hotkey_released event
+---@field style table
+---@field private _hotkeys table
+---@field private _modificators table
+local M = component.create("hotkey")
---- The @{Hotkey} constructor
--- @tparam Hotkey self @{Hotkey}
--- @tparam string[]|string keys The keys to be pressed for trigger callback. Should contains one key and any modificator keys
--- @tparam function callback The callback function
--- @tparam any|nil callback_argument The argument to pass into the callback function
-function Hotkey.init(self, keys, callback, callback_argument)
+--- The Hotkey constructor
+---@param keys string[]|string The keys to be pressed for trigger callback. Should contains one key and any modificator keys
+---@param callback function The callback function
+---@param callback_argument any|nil The argument to pass into the callback function
+function M:init(keys, callback, callback_argument)
self.druid = self:get_druid()
self._hotkeys = {}
self._modificators = {}
- self.on_hotkey_pressed = Event()
- self.on_hotkey_released = Event(callback)
+ self.on_hotkey_pressed = event.create()
+ self.on_hotkey_released = event.create(callback)
if keys then
self:add_hotkey(keys, callback_argument)
@@ -56,7 +61,7 @@ end
-- or create your own style
-- @table style
-- @tfield string[] MODIFICATORS The list of action_id as hotkey modificators
-function Hotkey.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.MODIFICATORS = style.MODIFICATORS or {}
@@ -67,11 +72,10 @@ end
--- Add hotkey for component callback
--- @tparam Hotkey self @{Hotkey}
--- @tparam string[]|hash[]|string|hash keys that have to be pressed before key pressed to activate
--- @tparam any|nil callback_argument The argument to pass into the callback function
--- @treturn Hotkey Current instance
-function Hotkey.add_hotkey(self, keys, callback_argument)
+---@param keys string[]|hash[]|string|hash that have to be pressed before key pressed to activate
+---@param callback_argument any|nil The argument to pass into the callback function
+---@return druid.hotkey Current instance
+function M:add_hotkey(keys, callback_argument)
keys = keys or {}
if type(keys) == "string" then
keys = { keys }
@@ -82,7 +86,7 @@ function Hotkey.add_hotkey(self, keys, callback_argument)
for index = 1, #keys do
local key_hash = hash(keys[index])
- if helper.contains(self.style.MODIFICATORS, key_hash) then
+ if #keys > 1 and helper.contains(self.style.MODIFICATORS, key_hash) then
table.insert(modificators, key_hash)
else
if not key then
@@ -110,40 +114,51 @@ function Hotkey.add_hotkey(self, keys, callback_argument)
end
-function Hotkey.on_focus_gained(self)
+function M:is_processing()
+ for index = 1, #self._hotkeys do
+ if self._hotkeys[index].is_processing then
+ return true
+ end
+ end
+
+ return false
+end
+
+
+function M:on_focus_gained()
for k, v in pairs(self._modificators) do
self._modificators[k] = false
end
end
-function Hotkey.on_input(self, action_id, action)
- if not action_id or #self._hotkeys == 0 then
+function M:on_input(action_id, action)
+ if not action_id then
return false
end
- if self._modificators[action_id] ~= nil then
- if action.pressed then
- self._modificators[action_id] = true
- end
- if action.released then
- self._modificators[action_id] = false
- end
+ if self._modificators[action_id] ~= nil and action.pressed then
+ self._modificators[action_id] = true
end
for index = 1, #self._hotkeys do
local hotkey = self._hotkeys[index]
- if action_id == hotkey.key then
+ local is_relative_key = helper.contains(self.style.MODIFICATORS, action_id) or action_id == hotkey.key
+
+ if is_relative_key and (action_id == hotkey.key or not hotkey.key) then
local is_modificator_ok = true
+ local is_consume = not not (hotkey.key)
-- Check only required modificators pressed
- for i = 1, #self.style.MODIFICATORS do
- local mod = self.style.MODIFICATORS[i]
- if helper.contains(hotkey.modificators, mod) and self._modificators[mod] == false then
- is_modificator_ok = false
- end
- if not helper.contains(hotkey.modificators, mod) and self._modificators[mod] == true then
- is_modificator_ok = false
+ if hotkey.key and #hotkey.modificators > 0 then
+ for i = 1, #self.style.MODIFICATORS do
+ local mod = self.style.MODIFICATORS[i]
+ if helper.contains(hotkey.modificators, mod) and self._modificators[mod] == false then
+ is_modificator_ok = false
+ end
+ if not helper.contains(hotkey.modificators, mod) and self._modificators[mod] == true then
+ is_modificator_ok = false
+ end
end
end
@@ -153,28 +168,31 @@ function Hotkey.on_input(self, action_id, action)
end
if not action.pressed and self._is_process_repeated and action.repeated and is_modificator_ok and hotkey.is_processing then
self.on_hotkey_released:trigger(self:get_context(), hotkey.callback_argument)
- return true
+ return is_consume
end
if action.released and is_modificator_ok and hotkey.is_processing then
- hotkey.is_processing = false
self.on_hotkey_released:trigger(self:get_context(), hotkey.callback_argument)
- return true
+ hotkey.is_processing = false
+ return is_consume
end
end
end
+ if self._modificators[action_id] ~= nil and action.released then
+ self._modificators[action_id] = false
+ end
+
return false
end
--- If true, the callback will be triggered on action.repeated
--- @tparam Hotkey self @{Hotkey}
--- @tparam bool is_enabled_repeated The flag value
--- @treturn Hotkey
-function Hotkey.set_repeat(self, is_enabled_repeated)
+---@param is_enabled_repeated bool The flag value
+---@return druid.hotkey
+function M:set_repeat(is_enabled_repeated)
self._is_process_repeated = is_enabled_repeated
return self
end
-return Hotkey
+return M
diff --git a/druid/extended/input.lua b/druid/extended/input.lua
index db608e1..ae243a2 100755
--- a/druid/extended/input.lua
+++ b/druid/extended/input.lua
@@ -10,25 +10,25 @@
-- @alias druid.input
--- On input field select callback(self, input_instance)
--- @tfield DruidEvent on_input_select @{DruidEvent}
+-- @tfield event on_input_select event
--- On input field unselect callback(self, input_text, input_instance)
--- @tfield DruidEvent on_input_unselect @{DruidEvent}
+-- @tfield event on_input_unselect event
--- On input field text change callback(self, input_text)
--- @tfield DruidEvent on_input_text @{DruidEvent}
+-- @tfield event on_input_text event
--- On input field text change to empty string callback(self, input_text)
--- @tfield DruidEvent on_input_empty @{DruidEvent}
+-- @tfield event on_input_empty event
--- On input field text change to max length string callback(self, input_text)
--- @tfield DruidEvent on_input_full @{DruidEvent}
+-- @tfield event on_input_full event
--- On trying user input with not allowed character callback(self, params, input_text)
--- @tfield DruidEvent on_input_wrong @{DruidEvent}
+-- @tfield event on_input_wrong event
--- On cursor position change callback(self, cursor_index, start_index, end_index)
--- @tfield DruidEvent on_select_cursor_change @{DruidEvent}
+-- @tfield event on_select_cursor_change event
--- The cursor index. The index of letter cursor after. Leftmost cursor - 0
-- @tfield number cursor_index
@@ -40,7 +40,7 @@
-- @tfield number end_index
--- Text component
--- @tfield Text text @{Text}
+-- @tfield Text text Text
--- Current input value
-- @tfield string value
@@ -61,7 +61,7 @@
-- @tfield number marked_text_width
--- Button component
--- @tfield Button button @{Button}
+-- @tfield Button button Button
--- Is current input selected now
-- @tfield boolean is_selected
@@ -80,16 +80,26 @@
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
local utf8_lua = require("druid.system.utf8")
local utf8 = utf8 or utf8_lua
-local Input = component.create("input")
+---@class druid.input: druid.base_component
+---@field on_input_select event
+---@field on_input_unselect event
+---@field on_input_text event
+---@field on_input_empty event
+---@field on_input_full event
+---@field on_input_wrong event
+---@field on_select_cursor_change event
+---@field style table
+---@field text druid.text
+local M = component.create("input")
-Input.ALLOWED_ACTIONS = {
+M.ALLOWED_ACTIONS = {
[const.ACTION_TOUCH] = true,
[const.ACTION_TEXT] = true,
[const.ACTION_MARKED_TEXT] = true,
@@ -99,9 +109,9 @@ Input.ALLOWED_ACTIONS = {
}
--- Mask text by replacing every character with a mask character
--- @tparam string text
--- @tparam string mask
--- @treturn string Masked text
+---@param text string
+---@param mask string
+---@return string Masked text
local function mask_text(text, mask)
mask = mask or "*"
local masked_text = ""
@@ -132,7 +142,7 @@ end
-- @tfield function on_select (self, button_node) Callback on input field selecting
-- @tfield function on_unselect (self, button_node) Callback on input field unselecting
-- @tfield function on_input_wrong (self, button_node) Callback on wrong user input
-function Input.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false
@@ -145,12 +155,11 @@ function Input.on_style_change(self, style)
end
---- The @{Input} constructor
--- @tparam Input self @{Input}
--- @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 number|nil keyboard_type Gui keyboard type for input field
-function Input.init(self, click_node, text_node, keyboard_type)
+--- The Input constructor
+---@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 keyboard_type number|nil Gui keyboard type for input field
+function M:init(click_node, text_node, keyboard_type)
self.druid = self:get_druid()
if type(text_node) == "table" then
@@ -191,18 +200,18 @@ function Input.init(self, click_node, text_node, keyboard_type)
self.button:set_web_user_interaction(true)
end
- self.on_input_select = Event()
- self.on_input_unselect = Event()
- self.on_input_text = Event()
- self.on_input_empty = Event()
- self.on_input_full = Event()
- self.on_input_wrong = Event()
- self.on_select_cursor_change = Event()
+ self.on_input_select = event.create()
+ self.on_input_unselect = event.create()
+ self.on_input_text = event.create()
+ self.on_input_empty = event.create()
+ self.on_input_full = event.create()
+ self.on_input_wrong = event.create()
+ self.on_select_cursor_change = event.create()
end
-function Input.on_input(self, action_id, action)
- if not (action_id == nil or Input.ALLOWED_ACTIONS[action_id]) then
+function M:on_input(action_id, action)
+ if not (action_id == nil or M.ALLOWED_ACTIONS[action_id]) then
return false
end
@@ -299,17 +308,17 @@ function Input.on_input(self, action_id, action)
end
-function Input.on_focus_lost(self)
+function M:on_focus_lost()
self:unselect()
end
-function Input.on_input_interrupt(self)
+function M:on_input_interrupt()
--self:unselect()
end
-function Input.get_text_selected(self)
+function M:get_text_selected()
if self.start_index == self.end_index then
return self.value
end
@@ -318,10 +327,9 @@ function Input.get_text_selected(self)
end
--- Replace selected text with new text
--- @tparam Input self @{Input}
--- @tparam string text The text to replace selected text
--- @treturn string New input text
-function Input.get_text_selected_replaced(self, text)
+---@param text string The text to replace selected text
+---@return string New input text
+function M:get_text_selected_replaced(text)
local left_part = utf8.sub(self.value, 1, self.start_index)
local right_part = utf8.sub(self.value, self.end_index + 1, utf8.len(self.value))
local result = left_part .. text .. right_part
@@ -336,9 +344,8 @@ end
--- Set text for input field
--- @tparam Input self @{Input}
--- @tparam string input_text The string to apply for input field
-function Input.set_text(self, input_text)
+---@param input_text string The string to apply for input field
+function M:set_text(input_text)
input_text = tostring(input_text or "")
-- Case when update with marked text
@@ -366,7 +373,7 @@ function Input.set_text(self, input_text)
self.is_empty = #value == 0 and #marked_value == 0
local final_text = value .. marked_value
- self.text:set_to(final_text)
+ self.text:set_text(final_text)
-- measure it
self.text_width = self.text:get_text_size(value)
@@ -385,8 +392,7 @@ end
--- Select input field. It will show the keyboard and trigger on_select events
--- @tparam Input self @{Input}
-function Input.select(self)
+function M:select()
gui.reset_keyboard()
self.marked_value = ""
if not self.is_selected then
@@ -410,8 +416,7 @@ end
--- Remove selection from input. It will hide the keyboard and trigger on_unselect events
--- @tparam Input self @{Input}
-function Input.unselect(self)
+function M:unselect()
gui.reset_keyboard()
self.marked_value = ""
self.value = self.current_value
@@ -429,9 +434,8 @@ end
--- Return current input field text
--- @tparam Input self @{Input}
--- @treturn string The current input field text
-function Input.get_text(self)
+---@return string The current input field text
+function M:get_text()
if self.marked_value ~= "" then
return self.value .. self.marked_value
end
@@ -442,10 +446,9 @@ end
--- Set maximum length for input field.
-- Pass nil to make input field unliminted (by default)
--- @tparam Input self @{Input}
--- @tparam number max_length Maximum length for input text field
--- @treturn druid.input Current input instance
-function Input.set_max_length(self, max_length)
+---@param max_length number Maximum length for input text field
+---@return druid.input Current input instance
+function M:set_max_length(max_length)
self.max_length = max_length
return self
end
@@ -454,19 +457,17 @@ end
--- Set allowed charaters for input field.
-- See: https://defold.com/ref/stable/string/
-- ex: [%a%d] for alpha and numeric
--- @tparam Input self @{Input}
--- @tparam string characters Regulax exp. for validate user input
--- @treturn druid.input Current input instance
-function Input.set_allowed_characters(self, characters)
+---@param characters string Regulax exp. for validate user input
+---@return druid.input Current input instance
+function M:set_allowed_characters(characters)
self.allowed_characters = characters
return self
end
--- Reset current input selection and return previous value
--- @tparam Input self @{Input}
--- @treturn druid.input Current input instance
-function Input.reset_changes(self)
+---@return druid.input Current input instance
+function M:reset_changes()
self:set_text(self.previous_value)
self:unselect()
return self
@@ -474,12 +475,11 @@ end
--- Set cursor position in input field
--- @tparam Input self @{Input}
--- @tparam number|nil cursor_index Cursor index for cursor position, if nil - will be set to the end of the text
--- @tparam number|nil start_index Start index for cursor position, if nil - will be set to the end of the text
--- @tparam number|nil end_index End index for cursor position, if nil - will be set to the start_index
--- @treturn druid.input Current input instance
-function Input.select_cursor(self, cursor_index, start_index, end_index)
+---@param cursor_index number|nil Cursor index for cursor position, if nil - will be set to the end of the text
+---@param start_index number|nil Start index for cursor position, if nil - will be set to the end of the text
+---@param end_index number|nil End index for cursor position, if nil - will be set to the start_index
+---@return druid.input Current input instance
+function M:select_cursor(cursor_index, start_index, end_index)
local len = utf8.len(self.value)
self.cursor_index = cursor_index or len
@@ -497,11 +497,10 @@ end
--- Change cursor position by delta
--- @tparam Input self @{Input}
--- @tparam number delta side for cursor position, -1 for left, 1 for right
--- @tparam boolean is_add_to_selection (Shift key)
--- @tparam boolean is_move_to_end (Ctrl key)
-function Input.move_selection(self, delta, is_add_to_selection, is_move_to_end)
+---@param delta number side for cursor position, -1 for left, 1 for right
+---@param is_add_to_selection boolean (Shift key)
+---@param is_move_to_end boolean (Ctrl key)
+function M:move_selection(delta, is_add_to_selection, is_move_to_end)
local len = utf8.len(self.value)
local cursor_index = self.cursor_index
local start_index, end_index -- if nil, the selection will be 0 at cursor position
@@ -559,4 +558,4 @@ function Input.move_selection(self, delta, is_add_to_selection, is_move_to_end)
end
-return Input
+return M
diff --git a/druid/extended/lang_text.lua b/druid/extended/lang_text.lua
index 6d38f83..d0745c9 100755
--- a/druid/extended/lang_text.lua
+++ b/druid/extended/lang_text.lua
@@ -18,35 +18,40 @@
-- @alias druid.lang_text
--- On change text callback
--- @tfield DruidEvent on_change @{DruidEvent}
+-- @tfield event on_change event
--- The text component
--- @tfield Text text @{Text}
+-- @tfield Text text Text
--- Text node
-- @tfield node node
---
-local Event = require("druid.event")
+local event = require("event.event")
local settings = require("druid.system.settings")
local component = require("druid.component")
-local LangText = component.create("lang_text")
+---@class druid.lang_text: druid.base_component
+---@field text druid.text
+---@field node node
+---@field on_change event
+---@field private last_locale_args table
+---@field private last_locale string
+local M = component.create("lang_text")
---- The @{LangText} constructor
--- @tparam LangText self @{LangText}
--- @tparam string|node node The node_id or gui.get_node(node_id)
--- @tparam string|nil locale_id Default locale id or text from node as default
--- @tparam string|nil adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
-function LangText.init(self, node, locale_id, adjust_type)
+--- The LangText constructor
+---@param node string|node The node_id or gui.get_node(node_id)
+---@param locale_id string|nil Default locale id or text from node as default
+---@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
+function M:init(node, locale_id, adjust_type)
self.druid = self:get_druid()
self.text = self.druid:new_text(node, locale_id, adjust_type)
self.node = self.text.node
self.last_locale_args = {}
- self.on_change = Event()
+ self.on_change = event.create()
self:translate(locale_id or gui.get_text(self.node))
self.text.on_set_text:subscribe(self.on_change.trigger, self.on_change)
@@ -55,7 +60,7 @@ function LangText.init(self, node, locale_id, adjust_type)
end
-function LangText.on_language_change(self)
+function M:on_language_change()
if self.last_locale then
self:translate(self.last_locale, unpack(self.last_locale_args))
end
@@ -63,53 +68,58 @@ end
--- Setup raw text to lang_text component
--- @tparam LangText self @{LangText}
--- @tparam string text Text for text node
--- @treturn LangText Current instance
-function LangText.set_to(self, text)
- self.last_locale = false
- self.text:set_to(text)
+---@param text string Text for text node
+---@return druid.lang_text Current instance
+function M:set_to(text)
+ self.last_locale = nil
+ self.text:set_text(text)
self.on_change:trigger()
return self
end
+--- Setup raw text to lang_text component
+---@param text string Text for text node
+---@return druid.lang_text Current instance
+function M:set_text(text)
+ return self:set_to(text)
+end
+
+
--- Translate the text by locale_id
--- @tparam LangText self @{LangText}
--- @tparam string locale_id Locale id
--- @tparam string|nil a Optional param to string.format
--- @tparam string|nil b Optional param to string.format
--- @tparam string|nil c Optional param to string.format
--- @tparam string|nil d Optional param to string.format
--- @tparam string|nil e Optional param to string.format
--- @tparam string|nil f Optional param to string.format
--- @tparam string|nil g Optional param to string.format
--- @treturn LangText Current instance
-function LangText.translate(self, locale_id, a, b, c, d, e, f, g)
+---@param locale_id string Locale id
+---@param a string|nil Optional param to string.format
+---@param b string|nil Optional param to string.format
+---@param c string|nil Optional param to string.format
+---@param d string|nil Optional param to string.format
+---@param e string|nil Optional param to string.format
+---@param f string|nil Optional param to string.format
+---@param g string|nil Optional param to string.format
+---@return druid.lang_text Current instance
+function M:translate(locale_id, a, b, c, d, e, f, g)
self.last_locale_args = { a, b, c, d, e, f, g }
self.last_locale = locale_id or self.last_locale
- self.text:set_to(settings.get_text(self.last_locale, a, b, c, d, e, f, g) or "")
+ self.text:set_text(settings.get_text(self.last_locale, a, b, c, d, e, f, g) or "")
return self
end
--- Format string with new text params on localized text
--- @tparam LangText self @{LangText}
--- @tparam string|nil a Optional param to string.format
--- @tparam string|nil b Optional param to string.format
--- @tparam string|nil c Optional param to string.format
--- @tparam string|nil d Optional param to string.format
--- @tparam string|nil e Optional param to string.format
--- @tparam string|nil f Optional param to string.format
--- @tparam string|nil g Optional param to string.format
--- @treturn LangText Current instance
-function LangText.format(self, a, b, c, d, e, f, g)
+---@param a string|nil Optional param to string.format
+---@param b string|nil Optional param to string.format
+---@param c string|nil Optional param to string.format
+---@param d string|nil Optional param to string.format
+---@param e string|nil Optional param to string.format
+---@param f string|nil Optional param to string.format
+---@param g string|nil Optional param to string.format
+---@return druid.lang_text Current instance
+function M:format(a, b, c, d, e, f, g)
self.last_locale_args = { a, b, c, d, e, f, g }
- self.text:set_to(settings.get_text(self.last_locale, a, b, c, d, e, f, g) or "")
+ self.text:set_text(settings.get_text(self.last_locale, a, b, c, d, e, f, g) or "")
return self
end
-return LangText
+return M
diff --git a/druid/extended/layout.lua b/druid/extended/layout.lua
index dea876b..33d023d 100644
--- a/druid/extended/layout.lua
+++ b/druid/extended/layout.lua
@@ -1,56 +1,66 @@
--- Copyright (c) 2024 Maksim Tuprikov . This code is licensed under MIT license
-
---- Layout management on node
---
--- Example Link
--- @module Layout
--- @within BaseComponent
--- @alias druid.layout
-
---- Layout node
--- @tfield node node
-
---- Current layout mode
--- @tfield string mode
-
----
-
+local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
--- @class druid.layout.row_data
--- @tfield width number
--- @tfield height number
--- @tfield count number
+---@alias druid.layout.mode "horizontal"|"vertical"|"horizontal_wrap"
--- @class druid.layout.rows_data
--- @tfield total_width number
--- @tfield total_height number
--- @tfield nodes_width table
--- @tfield nodes_height table
--- @tfield rows druid.layout.row_data[]>
+---@class event.on_size_changed: event
+---@field subscribe fun(_, callback: fun(new_size: vector3), context: any|nil)
--- @class druid.layout: druid.base_component
+---@class druid.layout.row_data
+---@field width number
+---@field height number
+---@field count number
+
+---@class druid.layout.rows_data
+---@field total_width number
+---@field total_height number
+---@field nodes_width table
+---@field nodes_height table
+---@field rows druid.layout.row_data[]>
+
+---@class druid.layout: druid.base_component
+---@field node node
+---@field rows_data druid.layout.rows_data Last calculated rows data
+---@field is_dirty boolean
+---@field entities node[]
+---@field margin {x: number, y: number}
+---@field padding vector4
+---@field type string
+---@field is_resize_width boolean
+---@field is_resize_height boolean
+---@field is_justify boolean
+---@field on_size_changed event.on_size_changed
local M = component.create("layout")
--- The @{Layout} constructor
--- @tparam Layout self @{Layout}
--- @tparam node node Gui node
--- @tparam string layout_type The layout mode (from const.LAYOUT_MODE)
--- @tparam function|nil on_size_changed_callback The callback on window resize
-function M.init(self, node, layout_type)
- self.node = self:get_node(node)
+---Layout component constructor
+---@local
+---@param node_or_node_id node|string
+---@param layout_type druid.layout.mode
+function M:init(node_or_node_id, layout_type)
+ self.node = self:get_node(node_or_node_id)
self.is_dirty = true
self.entities = {}
- self.margin = { x = 0, y = 0 }
+ self.size = gui.get_size(self.node)
+
self.padding = gui.get_slice9(self.node)
+ -- Grab default margins from slice9 z/w values
+ self.margin = { x = self.padding.z, y = self.padding.w }
+ -- Use symmetrical padding from x/z
+ self.padding.z = self.padding.x
+ self.padding.w = self.padding.y
+
self.type = layout_type or "horizontal"
self.is_resize_width = false
self.is_resize_height = false
self.is_justify = false
+
+ self.on_size_changed = event.create() --[[@as event.on_size_changed]]
end
+
+---@local
function M:update()
if not self.is_dirty then
return
@@ -60,11 +70,26 @@ function M:update()
end
--- @tparam Layout self @{Layout}
--- @tparam number|nil margin_x
--- @tparam number|nil margin_y
--- @treturn druid.layout @{Layout}
-function M.set_margin(self, margin_x, margin_y)
+function M:get_entities()
+ return self.entities
+end
+
+
+function M:set_node_index(node, index)
+ for i = 1, #self.entities do
+ if self.entities[i] == node then
+ table.remove(self.entities, i)
+ table.insert(self.entities, index, node)
+ break
+ end
+ end
+end
+
+
+---@param margin_x number|nil
+---@param margin_y number|nil
+---@return druid.layout
+function M:set_margin(margin_x, margin_y)
self.margin.x = margin_x or self.margin.x
self.margin.y = margin_y or self.margin.y
self.is_dirty = true
@@ -73,30 +98,33 @@ function M.set_margin(self, margin_x, margin_y)
end
--- @tparam Layout self @{Layout}
--- @tparam vector4 padding The vector4 with padding values, where x - left, y - top, z - right, w - bottom
--- @treturn druid.layout @{Layout}
-function M.set_padding(self, padding)
- self.padding = padding
+---@param padding_x number|nil
+---@param padding_y number|nil
+---@param padding_z number|nil
+---@param padding_w number|nil
+---@return druid.layout
+function M:set_padding(padding_x, padding_y, padding_z, padding_w)
+ self.padding.x = padding_x or self.padding.x
+ self.padding.y = padding_y or self.padding.y
+ self.padding.z = padding_z or self.padding.z
+ self.padding.w = padding_w or self.padding.w
self.is_dirty = true
return self
end
--- @tparam Layout self @{Layout}
--- @treturn druid.layout @{Layout}
-function M.set_dirty(self)
+---@return druid.layout
+function M:set_dirty()
self.is_dirty = true
return self
end
--- @tparam Layout self @{Layout}
--- @tparam boolean is_justify
--- @treturn druid.layout @{Layout}
-function M.set_justify(self, is_justify)
+---@param is_justify boolean
+---@return druid.layout
+function M:set_justify(is_justify)
self.is_justify = is_justify
self.is_dirty = true
@@ -104,10 +132,9 @@ function M.set_justify(self, is_justify)
end
--- @tparam Layout self @{Layout}
--- @tparam string type The layout type: "horizontal", "vertical", "horizontal_wrap"
--- @treturn druid.layout @{Layout}
-function M.set_type(self, type)
+---@param type string The layout type: "horizontal", "vertical", "horizontal_wrap"
+---@return druid.layout
+function M:set_type(type)
self.type = type
self.is_dirty = true
@@ -115,11 +142,10 @@ function M.set_type(self, type)
end
--- @tparam Layout self @{Layout}
--- @tparam boolean is_hug_width
--- @tparam boolean is_hug_height
--- @treturn druid.layout @{Layout}
-function M.set_hug_content(self, is_hug_width, is_hug_height)
+---@param is_hug_width boolean
+---@param is_hug_height boolean
+---@return druid.layout
+function M:set_hug_content(is_hug_width, is_hug_height)
self.is_resize_width = is_hug_width or false
self.is_resize_height = is_hug_height or false
self.is_dirty = true
@@ -128,33 +154,63 @@ function M.set_hug_content(self, is_hug_width, is_hug_height)
end
--- @tparam Layout self @{Layout}
--- @tparam string|node node_or_node_id
--- @treturn druid.layout @{Layout}
-function M.add(self, node_or_node_id)
+---Add node to layout
+---@param node_or_node_id node|string node_or_node_id
+---@return druid.layout
+function M:add(node_or_node_id)
-- Acquire node from entity or by id
local node = node_or_node_id
if type(node_or_node_id) == "table" then
assert(node_or_node_id.node, "The entity should have a node")
node = node_or_node_id.node
else
- -- @cast node_or_node_id string|node
+ ---@cast node_or_node_id string|node
node = self:get_node(node_or_node_id)
end
- -- @cast node node
+ ---@cast node node
table.insert(self.entities, node)
gui.set_parent(node, self.node)
-
self.is_dirty = true
return self
end
--- @tparam Layout self @{Layout}
--- @treturn druid.layout @{Layout}
-function M.refresh_layout(self)
+---Remove node from layout
+---@param node_or_node_id node|string node_or_node_id
+---@return druid.layout self for chaining
+function M:remove(node_or_node_id)
+ local node = type(node_or_node_id) == "table" and node_or_node_id.node or self:get_node(node_or_node_id)
+
+ for index = #self.entities, 1, -1 do
+ if self.entities[index] == node then
+ table.remove(self.entities, index)
+ self.is_dirty = true
+ break
+ end
+ end
+
+ return self
+end
+
+
+---@return vector3
+function M:get_size()
+ return self.size
+end
+
+
+---@return number, number
+function M:get_content_size()
+ local width = self.size.x - self.padding.x - self.padding.z
+ local height = self.size.y - self.padding.y - self.padding.w
+ return width, height
+end
+
+
+---@return druid.layout
+function M:refresh_layout()
local layout_node = self.node
local entities = self.entities
@@ -168,6 +224,7 @@ function M.refresh_layout(self)
local layout_pivot_offset = helper.get_pivot_offset(gui.get_pivot(layout_node)) -- {x: -0.5, y: -0.5} - is left bot, {x: 0.5, y: 0.5} - is right top
local rows_data = self:calculate_rows_data()
+ self.rows_data = rows_data
local rows = rows_data.rows
local row_index = 1
local row = rows[row_index]
@@ -191,7 +248,7 @@ function M.refresh_layout(self)
local node_height = rows_data.nodes_height[node]
local pivot_offset = helper.get_pivot_offset(gui.get_pivot(node))
- if node_width > 0 and node_height > 0 then
+ if node_width > 0 or node_height > 0 then
-- Calculate position for current node
local position_x, position_y
@@ -281,6 +338,9 @@ function M.refresh_layout(self)
size.y = rows_data.total_height + padding.y + padding.w
end
gui.set_size(layout_node, size)
+ self.size = size
+
+ self.on_size_changed(size)
end
self.is_dirty = false
@@ -289,9 +349,8 @@ function M.refresh_layout(self)
end
--- @tparam Layout self @{Layout}
--- @treturn druid.layout @{Layout}
-function M.clear_layout(self)
+---@return druid.layout
+function M:clear_layout()
for index = #self.entities, 1, -1 do
self.entities[index] = nil
end
@@ -302,10 +361,9 @@ function M.clear_layout(self)
end
--- @tparam node node
--- @treturn number, number
--- @local
-function M.get_node_size(node)
+---@param node node
+---@return number, number
+function M:get_node_size(node)
if not gui.is_enabled(node, false) then
return 0, 0
end
@@ -323,11 +381,10 @@ function M.get_node_size(node)
end
--- @tparam Layout self @{Layout}
--- Calculate rows data for layout. Contains total width, height and rows info (width, height, count of elements in row)
--- @treturn druid.layout.rows_data
--- @local
-function M.calculate_rows_data(self)
+---Calculate rows data for layout. Contains total width, height and rows info (width, height, count of elements in row)
+---@local
+---@return druid.layout.rows_data
+function M:calculate_rows_data()
local entities = self.entities
local margin = self.margin
local type = self.type
@@ -353,12 +410,12 @@ function M.calculate_rows_data(self)
-- Get node size if it's not calculated yet
if not node_width or not node_height then
- node_width, node_height = M.get_node_size(node)
+ node_width, node_height = self:get_node_size(node)
rows_data.nodes_width[node] = node_width
rows_data.nodes_height[node] = node_height
end
- if node_width > 0 and node_height > 0 then
+ if node_width > 0 or node_height > 0 then
if type == "horizontal" then
current_row.width = current_row.width + node_width + margin.x
current_row.height = math.max(current_row.height, node_height)
@@ -407,16 +464,16 @@ function M.calculate_rows_data(self)
end
--- @tparam node node
--- @tparam number x
--- @tparam number y
--- @treturn node
--- @local
+---Will reset z value to 0!
+local TEMP_VECTOR = vmath.vector3(0, 0, 0)
+---@param node node
+---@param x number
+---@param y number
+---@return node
function M:set_node_position(node, x, y)
- local position = gui.get_position(node)
- position.x = x
- position.y = y
- gui.set_position(node, position)
+ TEMP_VECTOR.x = x
+ TEMP_VECTOR.y = y
+ gui.set_position(node, TEMP_VECTOR)
return node
end
diff --git a/druid/extended/progress.lua b/druid/extended/progress.lua
index 163b017..bac6d3c 100644
--- a/druid/extended/progress.lua
+++ b/druid/extended/progress.lua
@@ -20,7 +20,7 @@
-- @alias druid.progress
--- On progress bar change callback(self, new_value)
--- @tfield DruidEvent on_change @{DruidEvent}
+-- @tfield event on_change event
--- Progress bar fill node
-- @tfield node node
@@ -44,12 +44,18 @@
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Progress = component.create("progress")
+---@class druid.progress: druid.base_component
+---@field node node
+---@field on_change event
+---@field style table
+---@field key string
+---@field prop hash
+local M = component.create("progress")
local function check_steps(self, from, to, exactly)
@@ -117,19 +123,18 @@ end
-- @table style
-- @tfield number|nil SPEED Progress bas fill rate. More -> faster. Default: 5
-- @tfield number|nil MIN_DELTA Minimum step to fill progress bar. Default: 0.005
-function Progress.on_style_change(self, style)
+function M:on_style_change(style)
self.style = {}
self.style.SPEED = style.SPEED or 5
self.style.MIN_DELTA = style.MIN_DELTA or 0.005
end
---- The @{Progress} constructor
--- @tparam Progress self @{Progress}
--- @tparam string|node node Node name or GUI Node itself.
--- @tparam string key Progress bar direction: const.SIDE.X or const.SIDE.Y
--- @tparam number|nil init_value Initial value of progress bar. Default: 1
-function Progress.init(self, node, key, init_value)
+--- The Progress constructor
+---@param node string|node Node name or GUI Node itself.
+---@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y
+---@param init_value number|nil Initial value of progress bar. Default: 1
+function M:init(node, key, init_value)
assert(key == const.SIDE.X or const.SIDE.Y, "Progress bar key should be 'x' or 'y'")
self.key = key
@@ -149,24 +154,24 @@ function Progress.init(self, node, key, init_value)
0
)
- self.on_change = Event()
+ self.on_change = event.create()
self:set_to(self.last_value)
end
-function Progress.on_layout_change(self)
+function M:on_layout_change()
self:set_to(self.last_value)
end
-function Progress.on_remove(self)
+function M:on_remove()
-- Return default size
gui.set_size(self.node, self.max_size)
end
-function Progress.update(self, dt)
+function M:update(dt)
if self.target then
local prev_value = self.last_value
local step = math.abs(self.last_value - self.target) * (self.style.SPEED*dt)
@@ -187,51 +192,45 @@ end
--- Fill a progress bar and stop progress animation
--- @tparam Progress self @{Progress}
-function Progress.fill(self)
+function M:fill()
set_bar_to(self, 1, true)
end
--- Empty a progress bar
--- @tparam Progress self @{Progress}
-function Progress.empty(self)
+function M:empty()
set_bar_to(self, 0, true)
end
--- Instant fill progress bar to value
--- @tparam Progress self @{Progress}
--- @tparam number to Progress bar value, from 0 to 1
-function Progress.set_to(self, to)
+---@param to number Progress bar value, from 0 to 1
+function M:set_to(to)
to = helper.clamp(to, 0, 1)
set_bar_to(self, to)
end
--- Return current progress bar value
--- @tparam Progress self @{Progress}
-function Progress.get(self)
+function M:get()
return self.last_value
end
--- Set points on progress bar to fire the callback
--- @tparam Progress self @{Progress}
--- @tparam number[] steps Array of progress bar values
--- @tparam function callback Callback on intersect step value
+---@param steps number[] Array of progress bar values
+---@param callback function Callback on intersect step value
-- @usage progress:set_steps({0, 0.3, 0.6, 1}, function(self, step) end)
-function Progress.set_steps(self, steps, callback)
+function M:set_steps(steps, callback)
self.steps = steps
self.step_callback = callback
end
--- Start animation of a progress bar
--- @tparam Progress self @{Progress}
--- @tparam number to value between 0..1
--- @tparam function|nil callback Callback on animation ends
-function Progress.to(self, to, callback)
+---@param to number value between 0..1
+---@param callback function|nil Callback on animation ends
+function M:to(to, callback)
to = helper.clamp(to, 0, 1)
-- cause of float error
local value = helper.round(to, 5)
@@ -247,14 +246,13 @@ end
--- Set progress bar max node size
--- @tparam Progress self @{Progress}
--- @tparam vector3 max_size The new node maximum (full) size
--- @treturn Progress @{Progress}
-function Progress.set_max_size(self, max_size)
+---@param max_size vector3 The new node maximum (full) size
+---@return druid.progress Progress
+function M:set_max_size(max_size)
self.max_size[self.key] = max_size[self.key]
self:set_to(self.last_value)
return self
end
-return Progress
+return M
diff --git a/druid/extended/slider.lua b/druid/extended/slider.lua
index 7af97d3..197d57f 100644
--- a/druid/extended/slider.lua
+++ b/druid/extended/slider.lua
@@ -8,7 +8,7 @@
-- @alias druid.slider
--- On change value callback(self, value)
--- @tfield DruidEvent on_change_value @{DruidEvent}
+-- @tfield event on_change_value event
--- Slider pin node
-- @tfield node node
@@ -37,12 +37,24 @@
---
-local Event = require("druid.event")
+local event = require("event.event")
local helper = require("druid.helper")
local const = require("druid.const")
local component = require("druid.component")
-local Slider = component.create("slider", const.PRIORITY_INPUT_HIGH)
+---@class druid.slider: druid.base_component
+---@field node node
+---@field on_change_value event
+---@field style table
+---@field private start_pos vector3
+---@field private pos vector3
+---@field private target_pos vector3
+---@field private end_pos vector3
+---@field private dist vector3
+---@field private is_drag boolean
+---@field private value number
+---@field private steps number[]
+local M = component.create("slider", const.PRIORITY_INPUT_HIGH)
local function on_change_value(self)
@@ -56,12 +68,11 @@ local function set_position(self, value)
end
---- The @{Slider} constructor
--- @tparam Slider self @{Slider}
--- @tparam node node Gui pin node
--- @tparam vector3 end_pos The end position of slider
--- @tparam function|nil callback On slider change callback
-function Slider.init(self, node, end_pos, callback)
+--- The Slider constructor
+---@param node node Gui pin node
+---@param end_pos vector3 The end position of slider
+---@param callback function|nil On slider change callback
+function M:init(node, end_pos, callback)
self.node = self:get_node(node)
self.start_pos = gui.get_position(self.node)
@@ -74,25 +85,25 @@ function Slider.init(self, node, end_pos, callback)
self.is_drag = false
self.value = 0
- self.on_change_value = Event(callback)
+ self.on_change_value = event.create(callback)
self:on_window_resized()
assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal")
end
-function Slider.on_layout_change(self)
+function M:on_layout_change()
self:set(self.value)
end
-function Slider.on_remove(self)
+function M:on_remove()
-- Return pin to start position
gui.set_position(self.node, self.start_pos)
end
-function Slider.on_window_resized(self)
+function M:on_window_resized()
local x_koef, y_koef = helper.get_screen_aspect_koef()
self._x_koef = x_koef
self._y_koef = y_koef
@@ -100,7 +111,7 @@ function Slider.on_window_resized(self)
end
-function Slider.on_input(self, action_id, action)
+function M:on_input(action_id, action)
if action_id ~= const.ACTION_TOUCH then
return false
end
@@ -185,10 +196,9 @@ end
--- Set value for slider
--- @tparam Slider self @{Slider}
--- @tparam number value Value from 0 to 1
--- @tparam boolean|nil is_silent Don't trigger event if true
-function Slider.set(self, value, is_silent)
+---@param value number Value from 0 to 1
+---@param is_silent boolean|nil Don't trigger event if true
+function M:set(value, is_silent)
value = helper.clamp(value, 0, 1)
set_position(self, value)
self.value = value
@@ -200,11 +210,10 @@ end
--- Set slider steps. Pin node will
-- apply closest step position
--- @tparam Slider self @{Slider}
--- @tparam number[] steps Array of steps
+---@param steps number[] Array of steps
-- @usage slider:set_steps({0, 0.2, 0.6, 1})
--- @treturn Slider @{Slider}
-function Slider.set_steps(self, steps)
+---@return druid.slider Slider
+function M:set_steps(steps)
self.steps = steps
return self
end
@@ -214,29 +223,31 @@ end
-- User can touch any place of node, pin instantly will
-- move at this position and node drag will start.
-- This function require the Defold version 1.3.0+
--- @tparam Slider self @{Slider}
--- @tparam node|string|nil input_node
--- @treturn Slider @{Slider}
-function Slider.set_input_node(self, input_node)
+---@param input_node node|string|nil
+---@return druid.slider Slider
+function M:set_input_node(input_node)
+ if not input_node then
+ self._input_node = nil
+ return self
+ end
+
self._input_node = self:get_node(input_node)
return self
end
--- Set Slider input enabled or disabled
--- @tparam Slider self @{Slider}
--- @tparam boolean is_enabled
-function Slider.set_enabled(self, is_enabled)
+---@param is_enabled boolean
+function M:set_enabled(is_enabled)
self._is_enabled = is_enabled
end
--- Check if Slider component is enabled
--- @tparam Slider self @{Slider}
--- @treturn boolean
-function Slider.is_enabled(self)
+---@return boolean
+function M:is_enabled()
return self._is_enabled
end
-return Slider
+return M
diff --git a/druid/extended/swipe.lua b/druid/extended/swipe.lua
index 110d9f4..fb65293 100644
--- a/druid/extended/swipe.lua
+++ b/druid/extended/swipe.lua
@@ -10,22 +10,32 @@
-- @alias druid.swipe
--- Swipe node
--- @tparam node node
+--@param node node
--- Restriction zone
--- @tparam node|nil click_zone
+--@param click_zone node|nil
--- Trigger on swipe event(self, swipe_side, dist, delta_time)
--- @tfield DruidEvent on_swipe) @{DruidEvent}
+--@param event event on_swipe
---
-local Event = require("druid.event")
+local event = require("event.event")
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
-local Swipe = component.create("swipe")
+---@class druid.swipe: druid.base_component
+---@field node node
+---@field on_swipe event function(side, dist, dt), side - "left", "right", "up", "down"
+---@field style table
+---@field click_zone node
+---@field private _trigger_on_move boolean
+---@field private _swipe_start_time number
+---@field private _start_pos vector3
+---@field private _is_enabled boolean
+---@field private _is_mobile boolean
+local M = component.create("swipe")
local function start_swipe(self, action)
@@ -36,7 +46,7 @@ end
local function reset_swipe(self, action)
- self._swipe_start_time = false
+ self._swipe_start_time = 0
end
@@ -49,19 +59,19 @@ local function check_swipe(self, action)
if is_swipe then
local is_x_swipe = math.abs(dx) >= math.abs(dy)
- local swipe_side = false
+ local swipe_side = "undefined"
if is_x_swipe and dx > 0 then
- swipe_side = const.SWIPE.RIGHT
+ swipe_side = "right"
end
if is_x_swipe and dx < 0 then
- swipe_side = const.SWIPE.LEFT
+ swipe_side = "left"
end
if not is_x_swipe and dy > 0 then
- swipe_side = const.SWIPE.UP
+ swipe_side = "up"
end
if not is_x_swipe and dy < 0 then
- swipe_side = const.SWIPE.DOWN
+ swipe_side = "down"
end
self.on_swipe:trigger(self:get_context(), swipe_side, dist, delta_time)
@@ -73,11 +83,13 @@ end
--- Component style params.
-- You can override this component styles params in druid styles table
-- or create your own style
--- @table style
--- @tfield number|nil SWIPE_TIME Maximum time for swipe trigger. Default: 0.4
--- @tfield number|nil SWIPE_THRESHOLD Minimum distance for swipe trigger. Default: 50
--- @tfield boolean|nil SWIPE_TRIGGER_ON_MOVE If true, trigger on swipe moving, not only release action. Default: false
-function Swipe.on_style_change(self, style)
+---@class druid.swipe.style
+---@field SWIPE_TIME number|nil Maximum time for swipe trigger. Default: 0.4
+---@field SWIPE_THRESHOLD number|nil Minimum distance for swipe trigger. Default: 50
+---@field SWIPE_TRIGGER_ON_MOVE boolean|nil If true, trigger on swipe moving, not only release action. Default: false
+
+---@param style druid.swipe.style
+function M:on_style_change(style)
self.style = {}
self.style.SWIPE_TIME = style.SWIPE_TIME or 0.4
self.style.SWIPE_THRESHOLD = style.SWIPE_THRESHOLD or 50
@@ -85,24 +97,23 @@ function Swipe.on_style_change(self, style)
end
---- The @{Swipe} constructor
--- @tparam Swipe self @{Swipe}
--- @tparam node node Gui node
--- @tparam function on_swipe_callback Swipe callback for on_swipe_end event
-function Swipe.init(self, node, on_swipe_callback)
+---Swipe constructor
+---@param node_or_node_id node|string
+---@param on_swipe_callback function
+function M:init(node_or_node_id, on_swipe_callback)
self._trigger_on_move = self.style.SWIPE_TRIGGER_ON_MOVE
- self.node = self:get_node(node)
+ self.node = self:get_node(node_or_node_id)
- self._swipe_start_time = false
+ self._swipe_start_time = 0
self._start_pos = vmath.vector3(0)
self.click_zone = nil
- self.on_swipe = Event(on_swipe_callback)
+ self.on_swipe = event.create(on_swipe_callback)
end
-function Swipe.on_late_init(self)
- if not self.click_zone and const.IS_STENCIL_CHECK then
+function M:on_late_init()
+ if not self.click_zone then
local stencil_node = helper.get_closest_stencil_node(self.node)
if stencil_node then
self:set_click_zone(stencil_node)
@@ -111,7 +122,9 @@ function Swipe.on_late_init(self)
end
-function Swipe.on_input(self, action_id, action)
+---@param action_id hash
+---@param action action
+function M:on_input(action_id, action)
if action_id ~= const.ACTION_TOUCH then
return false
end
@@ -126,7 +139,7 @@ function Swipe.on_input(self, action_id, action)
return false
end
- if self._swipe_start_time and (self._trigger_on_move or action.released) then
+ if self._swipe_start_time ~= 0 and (self._trigger_on_move or action.released) then
check_swipe(self, action)
end
@@ -142,18 +155,22 @@ function Swipe.on_input(self, action_id, action)
end
-function Swipe.on_input_interrupt(self)
+function M:on_input_interrupt()
reset_swipe(self)
end
--- Strict swipe click area. Useful for
-- restrict events outside stencil node
--- @tparam Swipe self @{Swipe}
--- @tparam node|string|nil zone Gui node
-function Swipe.set_click_zone(self, zone)
+---@param zone node|string|nil Gui node
+function M:set_click_zone(zone)
+ if not zone then
+ self.click_zone = nil
+ return
+ end
+
self.click_zone = self:get_node(zone)
end
-return Swipe
+return M
diff --git a/druid/extended/timer.lua b/druid/extended/timer.lua
index 235f4be..e4e95c4 100644
--- a/druid/extended/timer.lua
+++ b/druid/extended/timer.lua
@@ -1,40 +1,18 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Component to handle GUI timers.
--- Timer updating by game delta time. If game is not focused -
--- timer will be not updated.
--- @module Timer
--- @within BaseComponent
--- @alias druid.timer
-
---- On timer tick. Fire every second callback(self, value)
--- @tfield DruidEvent on_tick @{DruidEvent}
-
---- On timer change enabled state callback(self, is_enabled)
--- @tfield DruidEvent on_set_enabled @{DruidEvent}
-
---- On timer end callback
--- @tfield DruidEvent on_timer_end(self, Timer) @{DruidEvent}
-
---- Trigger node
--- @tfield node node
-
---- Initial timer value
--- @tfield number from
-
---- Target timer value
--- @tfield number target
-
---- Current timer value
--- @tfield number value
-
----
-
-local Event = require("druid.event")
+local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
-local Timer = component.create("timer")
+---@class druid.timer: druid.base_component
+---@field on_tick event
+---@field on_set_enabled event
+---@field on_timer_end event
+---@field style table
+---@field node node
+---@field from number
+---@field target number
+---@field value number
+---@field is_on boolean|nil
+local M = component.create("timer")
local function second_string_min(sec)
@@ -44,19 +22,18 @@ local function second_string_min(sec)
end
---- The @{Timer} constructor
--- @tparam Timer self @{Timer}
--- @tparam node node Gui text node
--- @tparam number|nil seconds_from Start timer value in seconds
--- @tparam number|nil seconds_to End timer value in seconds
--- @tparam function|nil callback Function on timer end
-function Timer.init(self, node, seconds_from, seconds_to, callback)
+---The Timer constructor
+---@param node node Gui text node
+---@param seconds_from number|nil Start timer value in seconds
+---@param seconds_to number|nil End timer value in seconds
+---@param callback function|nil Function on timer end
+function M:init(node, seconds_from, seconds_to, callback)
self.node = self:get_node(node)
seconds_to = math.max(seconds_to or 0, 0)
- self.on_tick = Event()
- self.on_set_enabled = Event()
- self.on_timer_end = Event(callback)
+ self.on_tick = event.create()
+ self.on_set_enabled = event.create()
+ self.on_timer_end = event.create(callback)
if seconds_from then
seconds_from = math.max(seconds_from, 0)
@@ -73,7 +50,7 @@ function Timer.init(self, node, seconds_from, seconds_to, callback)
end
-function Timer.update(self, dt)
+function M:update(dt)
if not self.is_on then
return
end
@@ -96,42 +73,44 @@ function Timer.update(self, dt)
end
-function Timer.on_layout_change(self)
+function M:on_layout_change()
self:set_to(self.last_value)
end
---- Set text to text field
--- @tparam Timer self @{Timer}
--- @tparam number set_to Value in seconds
-function Timer.set_to(self, set_to)
+---@param set_to number Value in seconds
+---@return druid.timer self
+function M:set_to(set_to)
self.last_value = set_to
gui.set_text(self.node, second_string_min(set_to))
+
+ return self
end
---- Called when update
--- @tparam Timer self @{Timer}
--- @tparam boolean|nil is_on Timer enable state
-function Timer.set_state(self, is_on)
+---@param is_on boolean|nil Timer enable state
+---@return druid.timer self
+function M:set_state(is_on)
self.is_on = is_on
-
self.on_set_enabled:trigger(self:get_context(), is_on)
+
+ return self
end
---- Set time interval
--- @tparam Timer self @{Timer}
--- @tparam number from Start time in seconds
--- @tparam number to Target time in seconds
-function Timer.set_interval(self, from, to)
+---@param from number Start time in seconds
+---@param to number Target time in seconds
+---@return druid.timer self
+function M:set_interval(from, to)
self.from = from
self.value = from
self.temp = 0
self.target = to
self:set_state(true)
self:set_to(from)
+
+ return self
end
-return Timer
+return M
diff --git a/druid/fonts/druid_text_bold.font b/druid/fonts/druid_text_bold.font
new file mode 100644
index 0000000..a8546d6
--- /dev/null
+++ b/druid/fonts/druid_text_bold.font
@@ -0,0 +1,10 @@
+font: "/druid/fonts/Roboto-Bold.ttf"
+material: "/builtins/fonts/font-df.material"
+size: 40
+outline_alpha: 1.0
+outline_width: 2.0
+shadow_alpha: 1.0
+shadow_blur: 2
+output_format: TYPE_DISTANCE_FIELD
+render_mode: MODE_MULTI_LAYER
+characters: "\302\241\302\253\302\273\302\277\303\200\303\202\303\206\303\207\303\210\303\211\303\212\303\213\303\216\303\217\303\224\303\231\303\233\303\234\303\237\303\240\303\241\303\242\303\243\303\244\303\246\303\247\303\250\303\251\303\252\303\253\303\255\303\256\303\257\303\261\303\262\303\263\303\264\303\265\303\266\303\271\303\273\303\274\303\277\305\222\305\223\305\270\320\201\320\220\320\221\320\222\320\223\320\224\320\225\320\226\320\227\320\230\320\231\320\232\320\233\320\234\320\235\320\236\320\237\320\240\320\241\320\242\320\243\320\244\320\245\320\246\320\247\320\250\320\251\320\252\320\253\320\254\320\255\320\256\320\257\320\260\320\261\320\262\320\263\320\264\320\265\320\266\320\267\320\270\320\271\320\272\320\273\320\274\320\275\320\276\320\277\321\200\321\201\321\202\321\203\321\204\321\205\321\206\321\207\321\210\321\211\321\212\321\213\321\214\321\215\321\216\321\217\321\221\342\200\224\343\200\201\343\200\202\343\200\214\343\200\215\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\343\201\213\343\201\214\343\201\215\343\201\217\343\201\223\343\201\225\343\201\227\343\201\230\343\201\231\343\201\233\343\201\237\343\201\240\343\201\244\343\201\246\343\201\247\343\201\250\343\201\251\343\201\252\343\201\253\343\201\256\343\201\257\343\201\263\343\201\276\343\202\200\343\202\201\343\202\202\343\202\210\343\202\211\343\202\212\343\202\213\343\202\214\343\202\222\343\202\223\343\202\241\343\202\242\343\202\243\343\202\244\343\202\246\343\202\250\343\202\251\343\202\254\343\202\255\343\202\257\343\202\260\343\202\261\343\202\262\343\202\263\343\202\265\343\202\267\343\202\270\343\202\271\343\202\272\343\202\273\343\202\277\343\203\200\343\203\201\343\203\203\343\203\206\343\203\207\343\203\210\343\203\211\343\203\213\343\203\215\343\203\216\343\203\220\343\203\221\343\203\224\343\203\225\343\203\226\343\203\227\343\203\231\343\203\233\343\203\234\343\203\235\343\203\236\343\203\240\343\203\241\343\203\242\343\203\243\343\203\245\343\203\247\343\203\251\343\203\252\343\203\253\343\203\254\343\203\255\343\203\257\343\203\263\343\203\274\344\270\200\344\270\207\344\270\212\344\270\213\344\270\215\344\270\216\344\270\241\344\270\244\344\270\252\344\270\255\344\270\272\344\271\211\344\271\260\344\272\213\344\272\216\344\273\213\344\273\216\344\273\230\344\273\243\344\273\245\344\273\254\344\273\266\344\275\206\344\275\223\344\275\225\344\275\234\344\275\240\344\275\277\344\276\213\344\277\241\345\200\244\345\200\274\345\201\234\345\205\203\345\205\205\345\205\245\345\205\266\345\206\205\345\207\246\345\207\272\345\207\273\345\210\206\345\210\227\345\210\233\345\210\235\345\210\240\345\210\245\345\210\260\345\210\266\345\211\212\345\211\215\345\211\252\345\212\233\345\212\237\345\212\240\345\212\250\345\212\271\345\214\272\345\215\225\345\215\230\345\217\214\345\217\221\345\217\226\345\217\243\345\217\246\345\217\257\345\220\210\345\220\214\345\220\221\345\220\227\345\220\253\345\220\257\345\222\214\345\231\250\345\233\236\345\234\250\345\235\227\345\236\202\345\236\213\345\237\237\345\237\272\345\240\261\345\241\253\345\244\204\345\244\232\345\244\247\345\245\275\345\246\202\345\247\213\345\255\227\345\255\230\345\256\203\345\256\232\345\257\206\345\257\214\345\257\271\345\260\206\345\260\217\345\260\261\345\261\200\345\261\217\345\261\236\345\267\245\345\270\203\345\270\246\345\271\225\345\271\263\345\271\266\345\272\246\345\273\272\345\274\200\345\274\271\345\276\227\345\277\205\345\277\253\346\200\201\346\200\247\346\201\257\346\202\254\346\203\205\346\210\217\346\210\220\346\211\200\346\211\213\346\212\236\346\212\274\346\213\226\346\213\251\346\214\201\346\214\211\346\215\256\346\215\267\346\216\247\346\217\203\346\220\255\346\221\270\346\223\215\346\224\257\346\224\276\346\225\210\346\225\260\346\225\264\346\226\207\346\226\271\346\227\245\346\227\266\346\230\216\346\230\257\346\230\276\346\233\264\346\234\200\346\234\211\346\234\254\346\235\206\346\235\241\346\236\220\346\237\204\346\237\245\346\240\207\346\240\274\346\243\200\346\251\237\346\254\241\346\255\244\346\255\245\346\260\264\346\261\275\346\262\241\346\263\225\346\264\262\346\265\213\346\266\210\346\267\267\346\267\273\346\270\205\346\270\270\346\273\221\346\273\232\347\202\271\347\211\210\347\216\207\347\220\206\347\224\250\347\224\273\347\225\260\347\231\276\347\232\204\347\233\264\347\233\270\347\234\213\347\240\201\347\241\200\347\241\256\347\242\272\347\244\272\347\247\222\347\247\273\347\252\227\347\253\257\347\255\276\347\256\200\347\260\241\347\261\273\347\264\224\347\264\240\347\264\271\347\272\265\347\273\204\347\273\215\347\273\221\347\274\223\347\274\251\347\275\221\347\275\256\347\276\216\347\276\251\350\203\275\350\211\257\350\211\262\350\212\202\350\216\267\350\241\214\350\241\250\350\243\201\350\244\207\350\246\201\350\246\213\350\247\246\350\250\200\350\250\255\350\252\215\350\252\236\350\252\254\350\252\277\350\256\241\350\256\244\350\256\276\350\257\225\350\257\255\350\257\264\350\257\267\350\260\203\350\261\271\350\263\274\350\264\255\350\267\235\350\273\212\350\273\270\350\275\246\350\275\264\350\276\223\350\276\271\350\277\207\350\277\231\350\277\233\350\277\275\351\200\211\351\200\232\351\201\270\351\205\215\351\207\214\351\222\256\351\224\256\351\225\267\351\225\277\351\231\244\351\234\200\351\235\231\351\235\242\351\240\230\351\242\204\351\242\234\351\252\244\351\253\230\351\274\240\351\275\220\352\260\200\352\260\204\352\260\222\352\260\231\352\260\234\352\261\260\352\262\203\352\262\214\352\262\240\352\263\204\352\263\240\352\263\274\352\265\254\352\265\255\352\267\270\352\270\200\352\270\260\352\271\214\352\273\230\352\274\264\353\202\230\353\202\264\353\204\214\353\205\270\353\206\223\353\210\204\353\212\224\353\212\245\353\213\210\353\213\244\353\213\250\353\213\254\353\213\271\353\214\200\353\215\224\353\215\260\353\217\204\353\217\231\353\220\230\353\220\234\353\220\251\353\221\220\353\223\234\353\223\244\353\224\251\353\225\214\353\226\273\353\235\274\353\236\230\353\236\265\353\237\254\353\240\210\353\240\244\353\240\245\353\240\254\353\241\234\353\241\235\353\241\244\353\245\264\353\245\270\353\245\274\353\246\254\353\246\255\353\247\210\353\247\214\353\247\216\353\247\244\353\250\270\353\251\224\353\251\264\353\252\205\353\252\250\353\252\251\353\260\200\353\260\217\353\260\224\353\260\233\353\260\251\353\260\260\353\260\261\353\262\204\353\262\210\353\262\225\353\262\227\353\262\244\353\263\264\353\263\270\353\270\224\353\271\204\354\202\254\354\203\201\354\203\211\354\204\234\354\204\240\354\204\244\354\204\261\354\204\270\354\205\230\354\206\214\354\206\215\354\210\230\354\212\244\354\212\254\354\212\265\354\213\234\354\213\240\354\213\255\354\225\204\354\225\240\354\226\221\354\226\264\354\226\270\354\227\206\354\227\220\354\227\254\354\227\255\354\230\201\354\230\210\354\230\244\354\230\254\354\231\200\354\232\224\354\232\251\354\232\260\354\233\203\354\234\204\354\234\210\354\234\240\354\234\250\354\234\274\354\235\200\354\235\204\354\235\214\354\235\230\354\235\264\354\235\270\354\235\274\354\236\204\354\236\205\354\236\210\354\236\220\354\236\221\354\236\230\354\236\245\354\240\201\354\240\204\354\240\225\354\240\234\354\241\260\354\242\213\354\244\221\354\247\200\354\247\201\354\247\204\354\247\210\354\260\250\354\260\275\354\262\230\354\264\210\354\265\234\354\266\224\354\266\225\354\266\234\354\267\250\354\271\230\354\272\220\354\273\250\354\273\264\354\274\200\354\275\224\354\275\234\355\201\254\355\201\264\355\202\244\355\203\200\355\203\204\355\203\234\355\203\235\355\204\260\355\205\214\355\205\215\355\212\270\355\212\274\355\213\261\355\214\214\355\214\250\355\214\254\355\217\211\355\217\254\355\221\234\355\224\204\355\224\274\355\225\204\355\225\221\355\225\230\355\225\234\355\225\240\355\225\250\355\225\251\355\225\264\355\226\211\355\230\225\355\230\270\355\230\274\355\231\224\355\231\225\355\231\234\355\232\250\357\274\201\357\274\214\357\274\237 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}"
diff --git a/druid/fonts/druid_text_regular.font b/druid/fonts/druid_text_regular.font
new file mode 100644
index 0000000..ec01934
--- /dev/null
+++ b/druid/fonts/druid_text_regular.font
@@ -0,0 +1,8 @@
+font: "/druid/fonts/Roboto-Regular.ttf"
+material: "/builtins/fonts/font-df.material"
+size: 40
+outline_alpha: 1.0
+outline_width: 2.0
+output_format: TYPE_DISTANCE_FIELD
+render_mode: MODE_MULTI_LAYER
+characters: "\302\241\302\253\302\273\302\277\303\200\303\202\303\206\303\207\303\210\303\211\303\212\303\213\303\216\303\217\303\224\303\231\303\233\303\234\303\237\303\240\303\241\303\242\303\243\303\244\303\246\303\247\303\250\303\251\303\252\303\253\303\255\303\256\303\257\303\261\303\262\303\263\303\264\303\265\303\266\303\271\303\273\303\274\303\277\305\222\305\223\305\270\320\201\320\220\320\221\320\222\320\223\320\224\320\225\320\226\320\227\320\230\320\231\320\232\320\233\320\234\320\235\320\236\320\237\320\240\320\241\320\242\320\243\320\244\320\245\320\246\320\247\320\250\320\251\320\252\320\253\320\254\320\255\320\256\320\257\320\260\320\261\320\262\320\263\320\264\320\265\320\266\320\267\320\270\320\271\320\272\320\273\320\274\320\275\320\276\320\277\321\200\321\201\321\202\321\203\321\204\321\205\321\206\321\207\321\210\321\211\321\212\321\213\321\214\321\215\321\216\321\217\321\221\342\200\224\343\200\201\343\200\202\343\200\214\343\200\215\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\343\201\213\343\201\214\343\201\215\343\201\217\343\201\223\343\201\225\343\201\227\343\201\230\343\201\231\343\201\233\343\201\237\343\201\240\343\201\244\343\201\246\343\201\247\343\201\250\343\201\251\343\201\252\343\201\253\343\201\256\343\201\257\343\201\263\343\201\276\343\202\200\343\202\201\343\202\202\343\202\210\343\202\211\343\202\212\343\202\213\343\202\214\343\202\222\343\202\223\343\202\241\343\202\242\343\202\243\343\202\244\343\202\246\343\202\250\343\202\251\343\202\254\343\202\255\343\202\257\343\202\260\343\202\261\343\202\262\343\202\263\343\202\265\343\202\267\343\202\270\343\202\271\343\202\272\343\202\273\343\202\277\343\203\200\343\203\201\343\203\203\343\203\206\343\203\207\343\203\210\343\203\211\343\203\213\343\203\215\343\203\216\343\203\220\343\203\221\343\203\224\343\203\225\343\203\226\343\203\227\343\203\231\343\203\233\343\203\234\343\203\235\343\203\236\343\203\240\343\203\241\343\203\242\343\203\243\343\203\245\343\203\247\343\203\251\343\203\252\343\203\253\343\203\254\343\203\255\343\203\257\343\203\263\343\203\274\344\270\200\344\270\207\344\270\212\344\270\213\344\270\215\344\270\216\344\270\241\344\270\244\344\270\252\344\270\255\344\270\272\344\271\211\344\271\260\344\272\213\344\272\216\344\273\213\344\273\216\344\273\230\344\273\243\344\273\245\344\273\254\344\273\266\344\275\206\344\275\223\344\275\225\344\275\234\344\275\240\344\275\277\344\276\213\344\277\241\345\200\244\345\200\274\345\201\234\345\205\203\345\205\205\345\205\245\345\205\266\345\206\205\345\207\246\345\207\272\345\207\273\345\210\206\345\210\227\345\210\233\345\210\235\345\210\240\345\210\245\345\210\260\345\210\266\345\211\212\345\211\215\345\211\252\345\212\233\345\212\237\345\212\240\345\212\250\345\212\271\345\214\272\345\215\225\345\215\230\345\217\214\345\217\221\345\217\226\345\217\243\345\217\246\345\217\257\345\220\210\345\220\214\345\220\221\345\220\227\345\220\253\345\220\257\345\222\214\345\231\250\345\233\236\345\234\250\345\235\227\345\236\202\345\236\213\345\237\237\345\237\272\345\240\261\345\241\253\345\244\204\345\244\232\345\244\247\345\245\275\345\246\202\345\247\213\345\255\227\345\255\230\345\256\203\345\256\232\345\257\206\345\257\214\345\257\271\345\260\206\345\260\217\345\260\261\345\261\200\345\261\217\345\261\236\345\267\245\345\270\203\345\270\246\345\271\225\345\271\263\345\271\266\345\272\246\345\273\272\345\274\200\345\274\271\345\276\227\345\277\205\345\277\253\346\200\201\346\200\247\346\201\257\346\202\254\346\203\205\346\210\217\346\210\220\346\211\200\346\211\213\346\212\236\346\212\274\346\213\226\346\213\251\346\214\201\346\214\211\346\215\256\346\215\267\346\216\247\346\217\203\346\220\255\346\221\270\346\223\215\346\224\257\346\224\276\346\225\210\346\225\260\346\225\264\346\226\207\346\226\271\346\227\245\346\227\266\346\230\216\346\230\257\346\230\276\346\233\264\346\234\200\346\234\211\346\234\254\346\235\206\346\235\241\346\236\220\346\237\204\346\237\245\346\240\207\346\240\274\346\243\200\346\251\237\346\254\241\346\255\244\346\255\245\346\260\264\346\261\275\346\262\241\346\263\225\346\264\262\346\265\213\346\266\210\346\267\267\346\267\273\346\270\205\346\270\270\346\273\221\346\273\232\347\202\271\347\211\210\347\216\207\347\220\206\347\224\250\347\224\273\347\225\260\347\231\276\347\232\204\347\233\264\347\233\270\347\234\213\347\240\201\347\241\200\347\241\256\347\242\272\347\244\272\347\247\222\347\247\273\347\252\227\347\253\257\347\255\276\347\256\200\347\260\241\347\261\273\347\264\224\347\264\240\347\264\271\347\272\265\347\273\204\347\273\215\347\273\221\347\274\223\347\274\251\347\275\221\347\275\256\347\276\216\347\276\251\350\203\275\350\211\257\350\211\262\350\212\202\350\216\267\350\241\214\350\241\250\350\243\201\350\244\207\350\246\201\350\246\213\350\247\246\350\250\200\350\250\255\350\252\215\350\252\236\350\252\254\350\252\277\350\256\241\350\256\244\350\256\276\350\257\225\350\257\255\350\257\264\350\257\267\350\260\203\350\261\271\350\263\274\350\264\255\350\267\235\350\273\212\350\273\270\350\275\246\350\275\264\350\276\223\350\276\271\350\277\207\350\277\231\350\277\233\350\277\275\351\200\211\351\200\232\351\201\270\351\205\215\351\207\214\351\222\256\351\224\256\351\225\267\351\225\277\351\231\244\351\234\200\351\235\231\351\235\242\351\240\230\351\242\204\351\242\234\351\252\244\351\253\230\351\274\240\351\275\220\352\260\200\352\260\204\352\260\222\352\260\231\352\260\234\352\261\260\352\262\203\352\262\214\352\262\240\352\263\204\352\263\240\352\263\274\352\265\254\352\265\255\352\267\270\352\270\200\352\270\260\352\271\214\352\273\230\352\274\264\353\202\230\353\202\264\353\204\214\353\205\270\353\206\223\353\210\204\353\212\224\353\212\245\353\213\210\353\213\244\353\213\250\353\213\254\353\213\271\353\214\200\353\215\224\353\215\260\353\217\204\353\217\231\353\220\230\353\220\234\353\220\251\353\221\220\353\223\234\353\223\244\353\224\251\353\225\214\353\226\273\353\235\274\353\236\230\353\236\265\353\237\254\353\240\210\353\240\244\353\240\245\353\240\254\353\241\234\353\241\235\353\241\244\353\245\264\353\245\270\353\245\274\353\246\254\353\246\255\353\247\210\353\247\214\353\247\216\353\247\244\353\250\270\353\251\224\353\251\264\353\252\205\353\252\250\353\252\251\353\260\200\353\260\217\353\260\224\353\260\233\353\260\251\353\260\260\353\260\261\353\262\204\353\262\210\353\262\225\353\262\227\353\262\244\353\263\264\353\263\270\353\270\224\353\271\204\354\202\254\354\203\201\354\203\211\354\204\234\354\204\240\354\204\244\354\204\261\354\204\270\354\205\230\354\206\214\354\206\215\354\210\230\354\212\244\354\212\254\354\212\265\354\213\234\354\213\240\354\213\255\354\225\204\354\225\240\354\226\221\354\226\264\354\226\270\354\227\206\354\227\220\354\227\254\354\227\255\354\230\201\354\230\210\354\230\244\354\230\254\354\231\200\354\232\224\354\232\251\354\232\260\354\233\203\354\234\204\354\234\210\354\234\240\354\234\250\354\234\274\354\235\200\354\235\204\354\235\214\354\235\230\354\235\264\354\235\270\354\235\274\354\236\204\354\236\205\354\236\210\354\236\220\354\236\221\354\236\230\354\236\245\354\240\201\354\240\204\354\240\225\354\240\234\354\241\260\354\242\213\354\244\221\354\247\200\354\247\201\354\247\204\354\247\210\354\260\250\354\260\275\354\262\230\354\264\210\354\265\234\354\266\224\354\266\225\354\266\234\354\267\250\354\271\230\354\272\220\354\273\250\354\273\264\354\274\200\354\275\224\354\275\234\355\201\254\355\201\264\355\202\244\355\203\200\355\203\204\355\203\234\355\203\235\355\204\260\355\205\214\355\205\215\355\212\270\355\212\274\355\213\261\355\214\214\355\214\250\355\214\254\355\217\211\355\217\254\355\221\234\355\224\204\355\224\274\355\225\204\355\225\221\355\225\230\355\225\234\355\225\240\355\225\250\355\225\251\355\225\264\355\226\211\355\230\225\355\230\270\355\230\274\355\231\224\355\231\225\355\231\234\355\232\250\357\274\201\357\274\214\357\274\237 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}"
diff --git a/druid/fonts/text_bold.font b/druid/fonts/text_bold.font
deleted file mode 100644
index 3bae9c5..0000000
--- a/druid/fonts/text_bold.font
+++ /dev/null
@@ -1,10 +0,0 @@
-font: "/druid/fonts/Roboto-Bold.ttf"
-material: "/builtins/fonts/font-df.material"
-size: 40
-outline_alpha: 1.0
-outline_width: 2.0
-shadow_alpha: 1.0
-shadow_blur: 2
-output_format: TYPE_DISTANCE_FIELD
-render_mode: MODE_MULTI_LAYER
-characters: " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\302\241\302\277\303\200\303\202\303\206\303\207\303\210\303\211\303\212\303\213\303\216\303\217\303\224\303\231\303\233\303\234\303\240\303\241\303\242\303\243\303\244\303\246\303\247\303\250\303\251\303\252\303\253\303\255\303\256\303\257\303\261\303\263\303\264\303\271\303\273\303\274\303\277\305\222\305\223\305\270\320\201\320\220\320\221\320\222\320\223\320\224\320\225\320\226\320\227\320\230\320\231\320\232\320\233\320\234\320\235\320\236\320\237\320\240\320\241\320\242\320\243\320\244\320\245\320\246\320\247\320\250\320\251\320\252\320\253\320\254\320\255\320\256\320\257\320\260\320\261\320\262\320\263\320\264\320\265\320\266\320\267\320\270\320\271\320\272\320\273\320\274\320\275\320\276\320\277\321\200\321\201\321\202\321\203\321\204\321\205\321\206\321\207\321\210\321\211\321\212\321\213\321\214\321\215\321\216\321\217\321\221\343\200\202\357\274\201\357\274\237"
diff --git a/druid/fonts/text_regular.font b/druid/fonts/text_regular.font
deleted file mode 100644
index 3decaf2..0000000
--- a/druid/fonts/text_regular.font
+++ /dev/null
@@ -1,8 +0,0 @@
-font: "/druid/fonts/Roboto-Regular.ttf"
-material: "/builtins/fonts/font-df.material"
-size: 40
-outline_alpha: 1.0
-outline_width: 2.0
-output_format: TYPE_DISTANCE_FIELD
-render_mode: MODE_MULTI_LAYER
-characters: " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\302\241\302\277\303\200\303\202\303\206\303\207\303\210\303\211\303\212\303\213\303\216\303\217\303\224\303\231\303\233\303\234\303\240\303\241\303\242\303\243\303\244\303\246\303\247\303\250\303\251\303\252\303\253\303\255\303\256\303\257\303\261\303\263\303\264\303\271\303\273\303\274\303\277\305\222\305\223\305\270\320\201\320\220\320\221\320\222\320\223\320\224\320\225\320\226\320\227\320\230\320\231\320\232\320\233\320\234\320\235\320\236\320\237\320\240\320\241\320\242\320\243\320\244\320\245\320\246\320\247\320\250\320\251\320\252\320\253\320\254\320\255\320\256\320\257\320\260\320\261\320\262\320\263\320\264\320\265\320\266\320\267\320\270\320\271\320\272\320\273\320\274\320\275\320\276\320\277\321\200\321\201\321\202\321\203\321\204\321\205\321\206\321\207\321\210\321\211\321\212\321\213\321\214\321\215\321\216\321\217\321\221\343\200\202\357\274\201\357\274\237"
diff --git a/druid/helper.lua b/druid/helper.lua
index 827e9cf..9f5c5c2 100644
--- a/druid/helper.lua
+++ b/druid/helper.lua
@@ -1,24 +1,26 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Helper module with various usefull GUI functions.
--- @usage
--- local helper = require("druid.helper")
--- helper.centrate_nodes(0, node_1, node_2)
--- @module Helper
--- @alias druid.helper
-
local const = require("druid.const")
+-- Localize functions for better performance
+local gui_get_node = gui.get_node
+local gui_get = gui.get
+local gui_pick_node = gui.pick_node
+
+---@class druid.system.helper
local M = {}
+
local POSITION_X = hash("position.x")
local SCALE_X = hash("scale.x")
local SIZE_X = hash("size.x")
+M.PROP_SIZE_X = hash("size.x")
+M.PROP_SIZE_Y = hash("size.y")
+M.PROP_SCALE_X = hash("scale.x")
+M.PROP_SCALE_Y = hash("scale.y")
local function get_text_width(text_node)
if text_node then
local text_metrics = M.get_text_metrics_from_node(text_node)
- local text_scale = gui.get(text_node, SCALE_X)
+ local text_scale = gui_get(text_node, SCALE_X)
return text_metrics.width * text_scale
end
@@ -28,7 +30,7 @@ end
local function get_icon_width(icon_node)
if icon_node then
- return gui.get(icon_node, SIZE_X) * gui.get(icon_node, SCALE_X) -- icon width
+ return gui_get(icon_node, SIZE_X) * gui_get(icon_node, SCALE_X) -- icon width
end
return 0
@@ -46,39 +48,36 @@ local function get_width(node)
end
---- Center two nodes.
--- Nodes will be center around 0 x position
--- text_node will be first (at left side)
--- @function helper.centrate_text_with_icon
--- @tparam text|nil text_node Gui text node
--- @tparam box|nil icon_node Gui box node
--- @tparam number margin Offset between nodes
--- @local
+---Center two nodes.
+--Nodes will be center around 0 x position
+--text_node will be first (at left side)
+---@param text_node node|nil Gui text node
+---@param icon_node node|nil Gui box node
+---@param margin number Offset between nodes
+---@local
function M.centrate_text_with_icon(text_node, icon_node, margin)
return M.centrate_nodes(margin, text_node, icon_node)
end
---- Center two nodes.
--- Nodes will be center around 0 x position
--- icon_node will be first (at left side)
--- @function helper.centrate_icon_with_text
--- @tparam box|nil icon_node Gui box node
--- @tparam text|nil text_node Gui text node
--- @tparam number|nil margin Offset between nodes
--- @local
+---Center two nodes.
+--Nodes will be center around 0 x position
+--icon_node will be first (at left side)
+---@param icon_node node|nil Gui box node
+---@param text_node node|nil Gui text node
+---@param margin number|nil Offset between nodes
+---@local
function M.centrate_icon_with_text(icon_node, text_node, margin)
return M.centrate_nodes(margin, icon_node, text_node)
end
---- Centerate nodes by x position with margin.
---
--- This functions calculate total width of nodes and set position for each node.
--- The centrate will be around 0 x position.
--- @function helper.centrate_nodes
--- @tparam number|nil margin Offset between nodes
--- @param ... Gui nodes
+---Centerate nodes by x position with margin.
+---
+---This functions calculate total width of nodes and set position for each node.
+---The centrate will be around 0 x position.
+---@param margin number|nil Offset between nodes
+---@param ... node Nodes to centrate
function M.centrate_nodes(margin, ...)
margin = margin or 0
@@ -113,36 +112,60 @@ function M.centrate_nodes(margin, ...)
end
---- Get current screen stretch multiplier for each side
--- @function helper.get_screen_aspect_koef
--- @treturn number stretch_x
--- @treturn number stretch_y
+---@param node_id string|node
+---@param template string|nil @Full Path to the template
+---@param nodes table|nil @Nodes what created with gui.clone_tree
+---@return node
+function M.get_node(node_id, template, nodes)
+ if type(node_id) ~= "string" then
+ -- Assume it's already node from gui.get_node
+ return node_id
+ end
+
+ -- If template is set, then add it to the node_id
+ if template and #template > 0 then
+ node_id = template .. "/" .. node_id
+ end
+
+ -- If nodes is set, then try to find node in it
+ if nodes then
+ return nodes[node_id]
+ end
+
+ return gui_get_node(node_id)
+end
+
+
+---Get current screen stretch multiplier for each side
+---@return number stretch_x
+---@return number stretch_y
function M.get_screen_aspect_koef()
local window_x, window_y = window.get_size()
+
local stretch_x = window_x / gui.get_width()
local stretch_y = window_y / gui.get_height()
- return stretch_x / math.min(stretch_x, stretch_y),
- stretch_y / math.min(stretch_x, stretch_y)
+ local stretch_koef = math.min(stretch_x, stretch_y)
+
+ local koef_x = window_x / (stretch_koef * sys.get_config_int("display.width"))
+ local koef_y = window_y / (stretch_koef * sys.get_config_int("display.height"))
+
+ return koef_x, koef_y
end
---- Get current GUI scale for each side
--- @function helper.get_gui_scale
--- @treturn number scale_x
--- @treturn number scale_y
+---Get current GUI scale for each side
+---@return number scale_x
function M.get_gui_scale()
local window_x, window_y = window.get_size()
- return math.min(window_x / gui.get_width(),
- window_y / gui.get_height())
+ return math.min(window_x / gui.get_width(), window_y / gui.get_height())
end
---- Move value from current to target value with step amount
--- @function helper.step
--- @tparam number current Current value
--- @tparam number target Target value
--- @tparam number step Step amount
--- @treturn number New value
+---Move value from current to target value with step amount
+---@param current number Current value
+---@param target number Target value
+---@param step number Step amount
+---@return number New value
function M.step(current, target, step)
if current < target then
return math.min(current + step, target)
@@ -152,43 +175,44 @@ function M.step(current, target, step)
end
---- Clamp value between min and max
--- @function helper.clamp
--- @tparam number a Value
--- @tparam number min Min value
--- @tparam number max Max value
--- @treturn number Clamped value
-function M.clamp(a, min, max)
- if min > max then
- min, max = max, min
+---Clamp value between min and max
+---@param value number Value
+---@param v1 number|nil Min value. If nil, value will be clamped to positive infinity
+---@param v2 number|nil Max value If nil, value will be clamped to negative infinity
+---@return number value Clamped value
+function M.clamp(value, v1, v2)
+ if v1 and v2 then
+ if v1 > v2 then
+ v1, v2 = v2, v1
+ end
end
- if a >= min and a <= max then
- return a
- elseif a < min then
- return min
- else
- return max
+ if v1 and value < v1 then
+ return v1
end
+
+ if v2 and value > v2 then
+ return v2
+ end
+
+ return value
end
---- Calculate distance between two points
--- @function helper.distance
--- @tparam number x1 First point x
--- @tparam number y1 First point y
--- @tparam number x2 Second point x
--- @tparam number y2 Second point y
--- @treturn number Distance
+---Calculate distance between two points
+---@param x1 number First point x
+---@param y1 number First point y
+---@param x2 number Second point x
+---@param y2 number Second point y
+---@return number Distance
function M.distance(x1, y1, x2, y2)
return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
end
---- Return sign of value (-1, 0, 1)
--- @function helper.sign
--- @tparam number val Value
--- @treturn number Sign
+---Return sign of value
+---@param val number Value
+---@return number sign Sign of value, -1, 0 or 1
function M.sign(val)
if val == 0 then
return 0
@@ -198,47 +222,42 @@ function M.sign(val)
end
---- Round number to specified decimal places
--- @function helper.round
--- @tparam number num Number
--- @tparam number|nil num_decimal_places Decimal places
--- @treturn number Rounded number
+---Round number to specified decimal places
+---@param num number Number
+---@param num_decimal_places number|nil Decimal places
+---@return number value Rounded number
function M.round(num, num_decimal_places)
local mult = 10^(num_decimal_places or 0)
return math.floor(num * mult + 0.5) / mult
end
---- Lerp between two values
--- @function helper.lerp
--- @tparam number a First value
--- @tparam number b Second value
--- @tparam number t Lerp amount
--- @treturn number Lerped value
+---Lerp between two values
+---@param a number First value
+---@param b number Second value
+---@param t number Lerp amount
+---@return number value Lerped value
function M.lerp(a, b, t)
return a + (b - a) * t
end
---- Check if value is in array and return index of it
--- @function helper.contains
--- @tparam table t Array
--- @param value Value
--- @treturn number|nil Index of value or nil
-function M.contains(t, value)
- for i = 1, #t do
- if t[i] == value then
- return i
+---Check if value contains in array
+---@param array any[] Array to check
+---@param value any Value
+function M.contains(array, value)
+ for index = 1, #array do
+ if array[index] == value then
+ return index
end
end
return nil
end
---- Make a copy table with all nested tables
--- @function helper.deepcopy
--- @tparam table orig_table Original table
--- @treturn table Copy of original table
+---Make a copy table with all nested tables
+---@param orig_table table Original table
+---@return table Copy of original table
function M.deepcopy(orig_table)
local orig_type = type(orig_table)
local copy
@@ -254,11 +273,10 @@ function M.deepcopy(orig_table)
end
---- Add all elements from source array to the target array
--- @function helper.add_array
--- @tparam any[] target Array to put elements from source
--- @tparam any[]|nil source The source array to get elements from
--- @treturn any[] The target array
+---Add all elements from source array to the target array
+---@param target any[] Array to put elements from source
+---@param source any[]|nil The source array to get elements from
+---@return any[] The target array
function M.add_array(target, source)
assert(target)
@@ -274,37 +292,35 @@ function M.add_array(target, source)
end
---- Make a check with gui.pick_node, but with additional node_click_area check.
--- @function helper.pick_node
--- @tparam node node
--- @tparam number x
--- @tparam number y
--- @tparam node|nil node_click_area
--- @local
+---Make a check with gui.pick_node, but with additional node_click_area check.
+---@param node node
+---@param x number
+---@param y number
+---@param node_click_area node|nil
+---@local
function M.pick_node(node, x, y, node_click_area)
- local is_pick = gui.pick_node(node, x, y)
+ local is_pick = gui_pick_node(node, x, y)
if node_click_area then
- is_pick = is_pick and gui.pick_node(node_click_area, x, y)
+ is_pick = is_pick and gui_pick_node(node_click_area, x, y)
end
return is_pick
end
---- Get node size adjusted by scale
--- @function helper.get_scaled_size
--- @tparam node node GUI node
--- @treturn vector3 Scaled size
+
+---Get size of node with scale multiplier
+---@param node node GUI node
+---@return vector3 scaled_size
function M.get_scaled_size(node)
- return vmath.mul_per_elem(gui.get_size(node), gui.get_scale(node))
+ return vmath.mul_per_elem(gui.get_size(node), gui.get_scale(node)) --[[@as vector3]]
end
---- Get cumulative parent's node scale
--- @function helper.get_scene_scale
--- @tparam node node Gui node
--- @tparam boolean|nil include_passed_node_scale True if add current node scale to result
--- @treturn vector3 The scene node scale
+---Get cumulative parent's node scale
+---@param node node Gui node
+---@param include_passed_node_scale boolean|nil True if add current node scale to result
+---@return vector3 The scene node scale
function M.get_scene_scale(node, include_passed_node_scale)
local scale = include_passed_node_scale and gui.get_scale(node) or vmath.vector3(1)
local parent = gui.get_parent(node)
@@ -317,10 +333,9 @@ function M.get_scene_scale(node, include_passed_node_scale)
end
---- Return closest non inverted clipping parent node for given node
--- @function helper.get_closest_stencil_node
--- @tparam node node GUI node
--- @treturn node|nil The closest stencil node or nil
+---Return closest non inverted clipping parent node for given node
+---@param node node GUI node
+---@return node|nil stencil_node The closest stencil node or nil
function M.get_closest_stencil_node(node)
if not node then
return nil
@@ -342,37 +357,35 @@ function M.get_closest_stencil_node(node)
end
---- Get node offset for given GUI pivot.
---
--- Offset shown in [-0.5 .. 0.5] range, where -0.5 is left or bottom, 0.5 is right or top.
--- @function helper.get_pivot_offset
--- @tparam number pivot The gui.PIVOT_* constant
--- @treturn vector3 Vector offset with [-0.5..0.5] values
-function M.get_pivot_offset(pivot)
- return const.PIVOTS[pivot]
+---Get pivot offset for given pivot or node
+---Offset shown in [-0.5 .. 0.5] range, where -0.5 is left or bottom, 0.5 is right or top.
+---@param pivot_or_node number|node GUI pivot or node
+---@return vector3 offset The pivot offset
+function M.get_pivot_offset(pivot_or_node)
+ if type(pivot_or_node) == "number" then
+ return const.PIVOTS[pivot_or_node]
+ end
+ return const.PIVOTS[gui.get_pivot(pivot_or_node)]
end
---- Check if device is native mobile (Android or iOS)
--- @function helper.is_mobile
--- @treturn boolean Is mobile
+---Check if device is native mobile (Android or iOS)
+---@return boolean Is mobile
function M.is_mobile()
- return const.CURRENT_SYSTEM_NAME == const.OS.IOS or
- const.CURRENT_SYSTEM_NAME == const.OS.ANDROID
+ local sys_name = const.CURRENT_SYSTEM_NAME
+ return sys_name == const.OS.IOS or sys_name == const.OS.ANDROID
end
---- Check if device is HTML5
--- @function helper.is_web
--- @treturn boolean Is web
+---Check if device is HTML5
+---@return boolean
function M.is_web()
return const.CURRENT_SYSTEM_NAME == const.OS.BROWSER
end
---- Check if device is HTML5 mobile
--- @function helper.is_web_mobile
--- @treturn boolean Is web mobile
+---Check if device is HTML5 mobile
+---@return boolean
function M.is_web_mobile()
if html5 then
return html5.run("(typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);") == "true"
@@ -381,18 +394,16 @@ function M.is_web_mobile()
end
---- Check if device is mobile and can support multitouch
--- @function helper.is_multitouch_supported
--- @treturn boolean Is multitouch supported
+---Check if device is mobile and can support multitouch
+---@return boolean is_multitouch Is multitouch supported
function M.is_multitouch_supported()
return M.is_mobile() or M.is_web_mobile()
end
---- Simple table to one-line string converter
--- @function helper.table_to_string
--- @tparam table t
--- @treturn string
+---Simple table to one-line string converter
+---@param t table
+---@return string
function M.table_to_string(t)
if not t then
return ""
@@ -411,11 +422,10 @@ function M.table_to_string(t)
end
---- Distance from node position to his borders
--- @function helper.get_border
--- @tparam node node GUI node
--- @tparam vector3|nil offset Offset from node position. Pass current node position to get non relative border values
--- @treturn vector4 Vector4 with border values (left, top, right, down)
+---Distance from node position to his borders
+---@param node node GUI node
+---@param offset vector3|nil Offset from node position. Pass current node position to get non relative border values
+---@return vector4 border Vector4 with border values (left, top, right, down)
function M.get_border(node, offset)
local pivot = gui.get_pivot(node)
local pivot_offset = M.get_pivot_offset(pivot)
@@ -438,17 +448,9 @@ function M.get_border(node, offset)
end
---- Get text metric from GUI node.
--- @function helper.get_text_metrics_from_node
--- @tparam node text_node
--- @treturn GUITextMetrics
--- @usage
--- type GUITextMetrics = {
--- width: number,
--- height: number,
--- max_ascent: number,
--- max_descent: number
--- }
+---Get text metric from GUI node.
+---@param text_node node
+---@return GUITextMetrics
function M.get_text_metrics_from_node(text_node)
local font_resource = gui.get_font_resource(gui.get_font(text_node))
local options = {
@@ -466,15 +468,13 @@ function M.get_text_metrics_from_node(text_node)
end
---- Add value to array with shift policy
---
--- Shift policy can be: left, right, no_shift
--- @function helper.insert_with_shift
--- @tparam table array Array
--- @param any Item to insert
--- @tparam number|nil index Index to insert. If nil, item will be inserted at the end of array
--- @tparam number|nil shift_policy The druid_const.SHIFT.* constant
--- @treturn any Inserted item
+---Add value to array with shift policy
+---Shift policy can be: left, right, no_shift
+---@param array table Array
+---@param item any Item to insert
+---@param index number|nil Index to insert. If nil, item will be inserted at the end of array
+---@param shift_policy number|nil The druid_const.SHIFT.* constant
+---@return any Inserted item
function M.insert_with_shift(array, item, index, shift_policy)
shift_policy = shift_policy or const.SHIFT.RIGHT
@@ -498,14 +498,12 @@ function M.insert_with_shift(array, item, index, shift_policy)
end
---- Remove value from array with shift policy
---
+---Remove value from array with shift policy
-- Shift policy can be: left, right, no_shift
--- @function helper.remove_with_shift
--- @tparam table array Array
--- @tparam number|nil index Index to remove. If nil, item will be removed from the end of array
--- @tparam number|nil shift_policy The druid_const.SHIFT.* constant
--- @treturn any Removed item
+---@param array any[] Array
+---@param index number|nil Index to remove. If nil, item will be removed from the end of array
+---@param shift_policy number|nil The druid_const.SHIFT.* constant
+---@return any Removed item
function M.remove_with_shift(array, index, shift_policy)
shift_policy = shift_policy or const.SHIFT.RIGHT
@@ -530,30 +528,137 @@ function M.remove_with_shift(array, index, shift_policy)
end
---- Show deprecated message. Once time per message
--- @function helper.deprecated
--- @tparam string message The deprecated message
--- @local
-local _deprecated_messages = {}
-function M.deprecated(message)
- if _deprecated_messages[message] then
- return
+---Get full position of node in the GUI tree
+---@param node node GUI node
+---@param root node|nil GUI root node to stop search
+function M.get_full_position(node, root)
+ local position = gui.get_position(node)
+ local parent = gui.get_parent(node)
+ while parent and parent ~= root do
+ local parent_position = gui.get_position(parent)
+ position.x = position.x + parent_position.x
+ position.y = position.y + parent_position.y
+ parent = gui.get_parent(parent)
end
- print("[Druid]: " .. message)
- _deprecated_messages[message] = true
+ return position
end
---- Show message to require component
--- @local
-function M.require_component_message(component_name, component_type)
- component_type = component_type or "extended"
+---@class druid.animation_data
+---@field frames table> @List of frames with uv coordinates and size
+---@field width number @Width of the animation
+---@field height number @Height of the animation
+---@field fps number @Frames per second
+---@field current_frame number @Current frame
+---@field node node @Node with flipbook animation
+---@field v vector4 @Vector with UV coordinates and size
- print(string.format("[Druid]: The component %s is %s component. You have to register it via druid.register to use it", component_name, component_type))
- print("[Druid]: Use next code:")
- print(string.format('local %s = require("druid.%s.%s")', component_name, component_type, component_name))
- print(string.format('druid.register("%s", %s)', component_name, component_name))
+---@param node node
+---@param atlas_path string @Path to the atlas
+---@return druid.animation_data
+function M.get_animation_data_from_node(node, atlas_path)
+ local atlas_data = resource.get_atlas(atlas_path)
+ local tex_info = resource.get_texture_info(atlas_data.texture)
+ local tex_w = tex_info.width
+ local tex_h = tex_info.height
+
+ local animation_data
+
+ local sprite_image_id = gui.get_flipbook(node)
+ for _, animation in ipairs(atlas_data.animations) do
+ if hash(animation.id) == sprite_image_id then
+ animation_data = animation
+ break
+ end
+ end
+ assert(animation_data, "Unable to find image " .. sprite_image_id)
+
+ local frames = {}
+ for index = animation_data.frame_start, animation_data.frame_end - 1 do
+ local uvs = atlas_data.geometries[index].uvs
+ assert(#uvs == 8, "Sprite trim mode should be disabled for the images.")
+
+ -- UV texture coordinates
+ -- 1
+ -- ^ V
+ -- |
+ -- |
+ -- | U
+ -- 0-------> 1
+
+ -- uvs = {
+ -- 0, 0,
+ -- 0, height,
+ -- width, height,
+ -- width, 0
+ -- },
+ -- Point indeces (Point number {uv_index_x, uv_index_y})
+ -- geometries.indices = {0 (1,2), 1(3,4), 2(5,6), 0(1,2), 2(5,6), 3(7,8)}
+ -- 1------2
+ -- | / |
+ -- | A / |
+ -- | / B |
+ -- | / |
+ -- 0------3
+
+ local width = uvs[5] - uvs[1] -- Width of sprite region
+ local height = uvs[2] - uvs[4] -- Height of sprite region
+ local is_rotated = height < 0 -- In case of rotated sprite
+
+ local x_left = uvs[1]
+ local y_bottom = uvs[2]
+ local x_right = uvs[5]
+ local y_top = uvs[6]
+
+ -- Okay now it's correct for non rotated
+ local uv_coord = vmath.vector4(
+ x_left / tex_w,
+ (tex_h - y_bottom) / tex_h,
+ x_right / tex_w,
+ (tex_h - y_top) / tex_h
+ )
+
+ if is_rotated then
+ -- In case the atlas has clockwise rotated sprite.
+ -- 0---------------1
+ -- | \ A |
+ -- | \ |
+ -- | \ |
+ -- | B \ |
+ -- 3---------------2
+ height = -height
+
+ uv_coord.x, uv_coord.y, uv_coord.z, uv_coord.w = uv_coord.y, uv_coord.z, uv_coord.w, uv_coord.x
+
+ -- Update uv_coord
+ --uv_coord = vmath.vector4(
+ -- u1 / tex_w,
+ -- (tex_h - v2) / tex_h,
+ -- u2 / tex_w,
+ -- (tex_h - v1) / tex_h
+ --)
+ end
+
+ local frame = {
+ uv_coord = uv_coord,
+ w = width,
+ h = height,
+ uv_rotated = is_rotated and vmath.vector4(0, 1, 0, 0) or vmath.vector4(1, 0, 0, 0)
+ }
+
+ table.insert(frames, frame)
+ end
+
+ return {
+ frames = frames,
+ width = animation_data.width,
+ height = animation_data.height,
+ fps = animation_data.fps,
+ v = vmath.vector4(1, 1, animation_data.width, animation_data.height),
+ current_frame = 1,
+ node = node,
+ }
end
diff --git a/druid/images/icons/icon_arrow.png b/druid/images/icons/icon_arrow.png
new file mode 100644
index 0000000..40fbf2a
Binary files /dev/null and b/druid/images/icons/icon_arrow.png differ
diff --git a/druid/images/icons/icon_drag.png b/druid/images/icons/icon_drag.png
new file mode 100644
index 0000000..3bd2c35
Binary files /dev/null and b/druid/images/icons/icon_drag.png differ
diff --git a/druid/images/panels/rect_round2_width2.png b/druid/images/panels/rect_round2_width2.png
new file mode 100644
index 0000000..8084114
Binary files /dev/null and b/druid/images/panels/rect_round2_width2.png differ
diff --git a/druid/materials/gui_repeat/gui_repeat.fp b/druid/materials/gui_repeat/gui_repeat.fp
new file mode 100644
index 0000000..fb355aa
--- /dev/null
+++ b/druid/materials/gui_repeat/gui_repeat.fp
@@ -0,0 +1,84 @@
+#version 140
+
+uniform sampler2D texture_sampler;
+
+in vec2 var_texcoord0;
+in vec4 var_color;
+in vec4 var_uv;
+in vec4 var_repeat; // [repeat_x, repeat_y, anchor_x, anchor_y]
+in vec4 var_params; // [margin_x, margin_y, offset_x, offset_y]
+in vec4 var_perspective;
+in vec4 var_uv_rotated;
+
+out vec4 color_out;
+
+void main() {
+ vec2 pivot = var_repeat.zw;
+ // Margin is a value between 0 and 1 that means offset/padding from the one image to another
+ vec2 margin = var_params.xy;
+ vec2 offset = var_params.zw;
+ vec2 repeat = var_repeat.xy;
+
+ // Atlas UV to local UV [0, 1]
+ float u = (var_texcoord0.x - var_uv.x) / (var_uv.z - var_uv.x);
+ float v = (var_texcoord0.y - var_uv.y) / (var_uv.w - var_uv.y);
+
+ // Adjust local UV by the pivot point. So 0:0 will be at the pivot point of node
+ u = u - (0.5 + pivot.x);
+ v = v - (0.5 - pivot.y);
+
+ // If rotated, swap UV
+ if (var_uv_rotated.y < 0.5) {
+ float temp = u;
+ u = v;
+ v = temp;
+ }
+
+ // Adjust repeat by the margin
+ repeat.x = repeat.x / (1.0 + margin.x);
+ repeat.y = repeat.y / (1.0 + margin.y);
+
+ // Repeat is a value between 0 and 1 that represents the number of times the texture is repeated in the atlas.
+ float tile_u = fract(u * repeat.x);
+ float tile_v = fract(v * repeat.y);
+
+ float tile_width = 1.0 / repeat.x;
+ float tile_height = 1.0 / repeat.y;
+
+ // Adjust tile UV by the pivot point.
+ // Not center is left top corner, need to adjust it to pivot point
+ tile_u = fract(tile_u + pivot.x + 0.5);
+ tile_v = fract(tile_v - pivot.y + 0.5);
+
+ // Apply offset
+ tile_u = fract(tile_u + offset.x);
+ tile_v = fract(tile_v + offset.y);
+
+ // Extend margins
+ margin = margin * 0.5;
+ tile_u = mix(0.0 - margin.x, 1.0 + margin.x, tile_u);
+ tile_v = mix(0.0 - margin.y, 1.0 + margin.y, tile_v);
+ float alpha = 0.0;
+ // If the tile is outside the margins, make it transparent, without IF
+ alpha = step(0.0, tile_u) * step(tile_u, 1.0) * step(0.0, tile_v) * step(tile_v, 1.0);
+
+ tile_u = clamp(tile_u, 0.0, 1.0); // Keep borders in the range 0-1
+ tile_v = clamp(tile_v, 0.0, 1.0); // Keep borders in the range 0-1
+
+ if (var_uv_rotated.y < 0.5) {
+ float temp = tile_u;
+ tile_u = tile_v;
+ tile_v = temp;
+ }
+
+ // Remap local UV to the atlas UV
+ vec2 uv = vec2(
+ mix(var_uv.x, var_uv.z, tile_u), // Get texture coordinate from the atlas
+ mix(var_uv.y, var_uv.w, tile_v) // Get texture coordinate from the atlas
+ //mix(var_uv.x, var_uv.z, tile_u * var_uv_rotated.x + tile_v * var_uv_rotated.z),
+ //mix(var_uv.y, var_uv.w, 1.0 - (tile_u * var_uv_rotated.y + tile_v * var_uv_rotated.x))
+ );
+
+ lowp vec4 tex = texture(texture_sampler, uv);
+ color_out = tex * var_color;
+}
\ No newline at end of file
diff --git a/druid/materials/gui_repeat/gui_repeat.material b/druid/materials/gui_repeat/gui_repeat.material
new file mode 100644
index 0000000..213467e
--- /dev/null
+++ b/druid/materials/gui_repeat/gui_repeat.material
@@ -0,0 +1,43 @@
+name: "repeat"
+tags: "gui"
+vertex_program: "/druid/materials/gui_repeat/gui_repeat.vp"
+fragment_program: "/druid/materials/gui_repeat/gui_repeat.fp"
+vertex_constants {
+ name: "view_proj"
+ type: CONSTANT_TYPE_VIEWPROJ
+}
+vertex_constants {
+ name: "uv_coord"
+ type: CONSTANT_TYPE_USER
+ value {
+ z: 1.0
+ w: 1.0
+ }
+}
+vertex_constants {
+ name: "uv_repeat"
+ type: CONSTANT_TYPE_USER
+ value {
+ x: 1.0
+ y: 1.0
+ }
+}
+vertex_constants {
+ name: "params"
+ type: CONSTANT_TYPE_USER
+ value {
+ }
+}
+vertex_constants {
+ name: "perspective"
+ type: CONSTANT_TYPE_USER
+ value {
+ }
+}
+vertex_constants {
+ name: "uv_rotated"
+ type: CONSTANT_TYPE_USER
+ value {
+ x: 1.0
+ }
+}
diff --git a/druid/materials/gui_repeat/gui_repeat.vp b/druid/materials/gui_repeat/gui_repeat.vp
new file mode 100644
index 0000000..12c1460
--- /dev/null
+++ b/druid/materials/gui_repeat/gui_repeat.vp
@@ -0,0 +1,50 @@
+#version 140
+
+in mediump vec3 position;
+in mediump vec2 texcoord0;
+in lowp vec4 color;
+
+uniform vertex_inputs
+{
+ highp mat4 view_proj;
+ highp vec4 uv_coord;
+ highp vec4 uv_repeat; // [repeat_x, repeat_y, pivot_x, pivot_y]
+ vec4 uv_rotated;
+ vec4 params; // [margin_x, margin_y, offset_x, offset_y]
+ vec4 perspective; // [perspective_x, perspective_y, zoom, offset_y]
+};
+
+out mediump vec2 var_texcoord0;
+out lowp vec4 var_color;
+out highp vec4 var_uv;
+out highp vec4 var_repeat;
+out vec4 var_params;
+out vec4 var_perspective;
+out vec4 var_uv_rotated;
+
+void main()
+{
+ var_texcoord0 = texcoord0;
+ var_color = vec4(color.rgb * color.a, color.a);
+ var_uv = uv_coord;
+ var_repeat = uv_repeat;
+ var_params = params;
+ var_perspective = perspective;
+ var_uv_rotated = uv_rotated;
+
+ mat4 transform = mat4(
+ 1.0, 0, 0, 0.0,
+ 0, 1.0, 0, 0.0,
+ 0, 0, 1, 0,
+ 0.0, position.z, 0, 1.0
+ );
+
+ // Matrix Info = mat4(
+ // scale_x, skew_x, 0, offset_x,
+ // skew_y, scale_y, 0, offset_y,
+ // 0, 0, scale_z, offset_z,
+ // perspective_x, perspective_y, perspective_z, zoom
+ //)
+
+ gl_Position = view_proj * vec4(position.xyz, 1.0) * transform;
+}
diff --git a/druid/materials/gui_world/gui_world.fp b/druid/materials/gui_world/gui_world.fp
new file mode 100644
index 0000000..aeddd5d
--- /dev/null
+++ b/druid/materials/gui_world/gui_world.fp
@@ -0,0 +1,10 @@
+varying mediump vec2 var_texcoord0;
+varying lowp vec4 var_color;
+
+uniform lowp sampler2D texture_sampler;
+
+void main()
+{
+ lowp vec4 tex = texture2D(texture_sampler, var_texcoord0.xy);
+ gl_FragColor = tex * var_color;
+}
diff --git a/druid/materials/gui_world/gui_world.material b/druid/materials/gui_world/gui_world.material
new file mode 100644
index 0000000..f609d2e
--- /dev/null
+++ b/druid/materials/gui_world/gui_world.material
@@ -0,0 +1,8 @@
+name: "gui_world"
+tags: "tile"
+vertex_program: "/druid/materials/gui_world/gui_world.vp"
+fragment_program: "/druid/materials/gui_world/gui_world.fp"
+vertex_constants {
+ name: "view_proj"
+ type: CONSTANT_TYPE_VIEWPROJ
+}
diff --git a/druid/materials/gui_world/gui_world.vp b/druid/materials/gui_world/gui_world.vp
new file mode 100644
index 0000000..5e71498
--- /dev/null
+++ b/druid/materials/gui_world/gui_world.vp
@@ -0,0 +1,16 @@
+uniform highp mat4 view_proj;
+
+// positions are in world space
+attribute highp vec3 position;
+attribute mediump vec2 texcoord0;
+attribute lowp vec4 color;
+
+varying mediump vec2 var_texcoord0;
+varying lowp vec4 var_color;
+
+void main()
+{
+ var_texcoord0 = texcoord0;
+ var_color = vec4(color.rgb * color.a, color.a);
+ gl_Position = view_proj * vec4(position.xyz, 1.0);
+}
diff --git a/druid/materials/skew/gui_skew.fp b/druid/materials/skew/gui_skew.fp
new file mode 100644
index 0000000..c3d593d
--- /dev/null
+++ b/druid/materials/skew/gui_skew.fp
@@ -0,0 +1,18 @@
+#version 140
+
+uniform sampler2D texture_sampler;
+
+in vec2 var_texcoord0;
+in vec4 var_color;
+
+out vec4 color_out;
+
+void main() {
+ lowp vec4 tex = texture(texture_sampler, var_texcoord0.xy);
+ if (tex.a < 0.5) {
+ discard;
+ }
+
+ // Final color of stencil texture
+ color_out = tex * var_color;
+}
\ No newline at end of file
diff --git a/druid/materials/skew/gui_skew.material b/druid/materials/skew/gui_skew.material
new file mode 100644
index 0000000..5575ae1
--- /dev/null
+++ b/druid/materials/skew/gui_skew.material
@@ -0,0 +1,8 @@
+name: "repeat"
+tags: "gui"
+vertex_program: "/druid/materials/stencil/gui_stencil.vp"
+fragment_program: "/druid/materials/stencil/gui_stencil.fp"
+vertex_constants {
+ name: "view_proj"
+ type: CONSTANT_TYPE_VIEWPROJ
+}
diff --git a/druid/materials/skew/gui_skew.vp b/druid/materials/skew/gui_skew.vp
new file mode 100644
index 0000000..382c88b
--- /dev/null
+++ b/druid/materials/skew/gui_skew.vp
@@ -0,0 +1,20 @@
+#version 140
+
+uniform vertex_inputs {
+ highp mat4 view_proj;
+};
+
+// positions are in world space
+in mediump vec3 position;
+in mediump vec2 texcoord0;
+in lowp vec4 color;
+
+out mediump vec2 var_texcoord0;
+out lowp vec4 var_color;
+
+void main()
+{
+ var_texcoord0 = texcoord0;
+ var_color = vec4(color.rgb * color.a, color.a);
+ gl_Position = view_proj * vec4(position.xyz, 1.0);
+}
diff --git a/druid/materials/stencil/gui_stencil.fp b/druid/materials/stencil/gui_stencil.fp
new file mode 100644
index 0000000..c3d593d
--- /dev/null
+++ b/druid/materials/stencil/gui_stencil.fp
@@ -0,0 +1,18 @@
+#version 140
+
+uniform sampler2D texture_sampler;
+
+in vec2 var_texcoord0;
+in vec4 var_color;
+
+out vec4 color_out;
+
+void main() {
+ lowp vec4 tex = texture(texture_sampler, var_texcoord0.xy);
+ if (tex.a < 0.5) {
+ discard;
+ }
+
+ // Final color of stencil texture
+ color_out = tex * var_color;
+}
\ No newline at end of file
diff --git a/druid/materials/stencil/gui_stencil.material b/druid/materials/stencil/gui_stencil.material
new file mode 100644
index 0000000..5575ae1
--- /dev/null
+++ b/druid/materials/stencil/gui_stencil.material
@@ -0,0 +1,8 @@
+name: "repeat"
+tags: "gui"
+vertex_program: "/druid/materials/stencil/gui_stencil.vp"
+fragment_program: "/druid/materials/stencil/gui_stencil.fp"
+vertex_constants {
+ name: "view_proj"
+ type: CONSTANT_TYPE_VIEWPROJ
+}
diff --git a/druid/materials/stencil/gui_stencil.vp b/druid/materials/stencil/gui_stencil.vp
new file mode 100644
index 0000000..382c88b
--- /dev/null
+++ b/druid/materials/stencil/gui_stencil.vp
@@ -0,0 +1,20 @@
+#version 140
+
+uniform vertex_inputs {
+ highp mat4 view_proj;
+};
+
+// positions are in world space
+in mediump vec3 position;
+in mediump vec2 texcoord0;
+in lowp vec4 color;
+
+out mediump vec2 var_texcoord0;
+out lowp vec4 var_color;
+
+void main()
+{
+ var_texcoord0 = texcoord0;
+ var_color = vec4(color.rgb * color.a, color.a);
+ gl_Position = view_proj * vec4(position.xyz, 1.0);
+}
diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua
index 03c722d..7398c74 100644
--- a/druid/styles/default/style.lua
+++ b/druid/styles/default/style.lua
@@ -1,5 +1,3 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
local const = require("druid.const")
local settings = require("druid.system.settings")
@@ -63,7 +61,7 @@ M["hover"] = {
}
M["drag"] = {
- DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone
+ DRAG_DEADZONE = 4, -- Size in pixels of drag deadzone
NO_USE_SCREEN_KOEF = false,
}
diff --git a/druid/system/druid_annotations.lua b/druid/system/druid_annotations.lua
new file mode 100644
index 0000000..a08b449
--- /dev/null
+++ b/druid/system/druid_annotations.lua
@@ -0,0 +1,29 @@
+---@class druid.widget: druid.base_component
+---@field druid druid_instance Ready to use druid instance
+---@field root node
+
+---@class GUITextMetrics
+---@field width number
+---@field height number
+---@field max_ascent number
+---@field max_descent number
+---@field offset_x number
+---@field offset_y number
+
+---@class utf8
+---@field len fun(s: string):number
+---@field sub fun(s: string, start_index: number, length: number)
+---@field reverse fun()
+---@field char fun()
+---@field unicode fun()
+---@field gensub fun()
+---@field byte fun()
+---@field find fun()
+---@field match fun(s: string, m: string)
+---@field gmatch fun(s: string, m: string)
+---@field gsub fun()
+---@field dump fun()
+---@field format fun()
+---@field lower fun()
+---@field upper fun()
+---@field rep fun()
diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua
index 56de63f..beca2d1 100755
--- a/druid/system/druid_instance.lua
+++ b/druid/system/druid_instance.lua
@@ -1,95 +1,24 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Druid Instance which you use for component creation.
---
--- # Component List #
---
--- For a list of all available components, please refer to the "See Also" section.
---
--- # Notes #
---
--- Please review the following API pages:
---
--- @{Helper} - A useful set of functions for working with GUI nodes, such as centering nodes, get GUI scale ratio, etc
---
--- @{DruidEvent} - The core event system in Druid. Learn how to subscribe to any event in every Druid component.
---
--- @{BaseComponent} - The parent class of all Druid components. You can find all default component methods there.
---
--- # Tech Info #
---
--- • To use Druid, you need to create a Druid instance first. This instance is used to spawn components.
---
--- • When using Druid components, provide the node name as a string argument directly. Avoid calling gui.get_node() before passing it to the component. Because Druid can get nodes from template and cloned gui nodes.
---
--- • All Druid and component methods are called using the colon operator (e.g., self.druid:new_button()).
--- @usage
--- local druid = require("druid.druid")
---
--- local function close_window(self)
--- print("Yeah! You closed the game!")
--- end
---
--- function init(self)
--- self.druid = druid.new(self)
---
--- -- Call all druid instance function with ":" syntax:
--- local text = self.druid:new_text("text_header", "Hello Druid!")
--- local button = self.druid:new_button("button_close", close_window)
---
--- -- You not need to save component reference if not need it
--- self.druid:new_back_handler(close_window)
--- end
---
--- @module DruidInstance
--- @alias druid_instance
--- @see BackHandler
--- @see Blocker
--- @see Button
--- @see Checkbox
--- @see CheckboxGroup
--- @see DataList
--- @see Drag
--- @see DynamicGrid
--- @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 events = require("event.events")
+local const = require("druid.const")
local helper = require("druid.helper")
local settings = require("druid.system.settings")
local base_component = require("druid.component")
-local drag = require("druid.base.drag")
-local text = require("druid.base.text")
-local hover = require("druid.base.hover")
-local scroll = require("druid.base.scroll")
-local button = require("druid.base.button")
-local blocker = require("druid.base.blocker")
-local static_grid = require("druid.base.static_grid")
-local back_handler = require("druid.base.back_handler")
-
--- To use this components, you should register them first
--- local input = require("druid.extended.input")
--- local swipe = require("druid.extended.swipe")
--- local slider = require("druid.extended.slider")
--- local progress = require("druid.extended.progress")
--- local data_list = require("druid.extended.data_list")
--- local lang_text = require("druid.extended.lang_text")
--- local timer_component = require("druid.extended.timer")
-
-local DruidInstance = {}
+---@class druid_instance
+---@field components_all druid.base_component[] All created components
+---@field components_interest table All components sorted by interest
+---@field url url
+---@field private _context table Druid context
+---@field private _style table Druid style table
+---@field private _deleted boolean
+---@field private _is_late_remove_enabled boolean
+---@field private _late_remove druid.base_component[]
+---@field private _input_blacklist druid.base_component[]|nil
+---@field private _input_whitelist druid.base_component[]|nil
+---@field private input_inited boolean
+---@field private _late_init_timer_id number
+---@field private _input_components druid.base_component[]
+local M = {}
local MSG_ADD_FOCUS = hash("acquire_input_focus")
local MSG_REMOVE_FOCUS = hash("release_input_focus")
@@ -106,7 +35,7 @@ end
-- The a and b - two Druid components
--- @local
+---@private
local function sort_input_comparator(a, b)
local a_priority = a:get_input_priority()
local b_priority = b:get_input_priority()
@@ -120,7 +49,7 @@ end
local function sort_input_stack(self)
- local input_components = self.components_interest[base_component.ON_INPUT]
+ local input_components = self.components_interest[const.ON_INPUT]
if not input_components then
return
end
@@ -146,7 +75,55 @@ local function create(self, instance_class)
end
--- Before processing any input check if we need to update input stack
+local WIDGET_METATABLE = { __index = base_component }
+
+---Create the Druid component instance
+---@param self druid_instance
+---@param widget_class druid.base_component
+local function create_widget(self, widget_class)
+ local instance = setmetatable({}, {
+ __index = setmetatable(widget_class, WIDGET_METATABLE)
+ })
+
+ instance._component = {
+ _uid = base_component.create_uid(),
+ name = "Druid Widget",
+ input_priority = const.PRIORITY_INPUT,
+ default_input_priority = const.PRIORITY_INPUT,
+ _is_input_priority_changed = true, -- Default true for sort once time after GUI init
+ }
+ instance._meta = {
+ druid = self,
+ template = "",
+ nodes = nil,
+ context = self._context,
+ style = nil,
+ input_enabled = true,
+ children = {},
+ parent = type(self._context) ~= "userdata" and self._context,
+ instance_class = widget_class
+ }
+
+ -- Register
+ if instance._meta.parent then
+ instance._meta.parent:__add_child(instance)
+ end
+
+ table.insert(self.components_all, instance)
+
+ local register_to = instance:__get_interests()
+ for i = 1, #register_to do
+ local interest = register_to[i]
+ table.insert(self.components_interest[interest], instance)
+ end
+
+ return instance
+end
+
+
+---Before processing any input check if we need to update input stack
+---@param self druid_instance
+---@param components table[]
local function check_sort_input_stack(self, components)
if not components or #components == 0 then
return
@@ -168,8 +145,10 @@ local function check_sort_input_stack(self, components)
end
---- Check whitelists and blacklists for input components
-local function can_use_input_component(self, component)
+---Check whitelists and blacklists for input components
+---@param component druid.base_component
+---@return boolean
+function M:_can_use_input_component(component)
local can_by_whitelist = true
local can_by_blacklist = true
@@ -185,13 +164,13 @@ local function can_use_input_component(self, component)
end
-local function process_input(self, action_id, action, components)
+function M:_process_input(action_id, action, components)
local is_input_consumed = false
for i = #components, 1, -1 do
local component = components[i]
local meta = component._meta
- if meta.input_enabled and can_use_input_component(self, component) then
+ if meta.input_enabled and self:_can_use_input_component(component) then
if not is_input_consumed then
is_input_consumed = component:on_input(action_id, action) or false
else
@@ -219,36 +198,35 @@ end
--- Druid class constructor
--- @tparam DruidInstance self
--- @tparam table context Druid context. Usually it is self of gui script
--- @tparam table style Druid style table
--- @local
-function DruidInstance.initialize(self, context, style)
+---@param context table Druid context. Usually it is self of gui script
+---@param style table? Druid style table
+function M:initialize(context, style)
self._context = context
self._style = style or settings.default_style
self._deleted = false
self._is_late_remove_enabled = false
self._late_remove = {}
- self._is_debug = false
- self.url = msg.url()
self._input_blacklist = nil
self._input_whitelist = nil
self.components_all = {}
self.components_interest = {}
- for i = 1, #base_component.ALL_INTERESTS do
- self.components_interest[base_component.ALL_INTERESTS[i]] = {}
+ for i = 1, #const.ALL_INTERESTS do
+ self.components_interest[const.ALL_INTERESTS[i]] = {}
end
+
+ events.subscribe("druid.window_event", self.on_window_event, self)
+ events.subscribe("druid.language_change", self.on_language_change, self)
end
--- Create new component.
--- @tparam DruidInstance self
--- @tparam BaseComponent component Component module
--- @tparam any ... Other component params to pass it to component:init function
--- @treturn BaseComponent Component instance
-function DruidInstance.new(self, component, ...)
+---Create new Druid component instance
+---@generic T: druid.base_component
+---@param component T
+---@vararg any
+---@return T
+function M:new(component, ...)
local instance = create(self, component)
if instance.init then
@@ -263,8 +241,7 @@ end
--- Call this in gui_script final function.
--- @tparam DruidInstance self
-function DruidInstance.final(self)
+function M:final()
local components = self.components_all
for i = #components, 1, -1 do
@@ -276,16 +253,19 @@ function DruidInstance.final(self)
self._deleted = true
set_input_state(self, false)
+
+ events.unsubscribe("druid.window_event", self.on_window_event, self)
+ events.unsubscribe("druid.language_change", self.on_language_change, self)
end
--- Remove created component from Druid instance.
--
-- Component `on_remove` function will be invoked, if exist.
--- @tparam DruidInstance self
--- @tparam BaseComponent component Component instance
--- @treturn boolean True if component was removed
-function DruidInstance.remove(self, component)
+---@generic T: druid.base_component
+---@param component T Component instance
+---@return boolean True if component was removed
+function M:remove(component)
if self._is_late_remove_enabled then
table.insert(self._late_remove, component)
return false
@@ -334,31 +314,27 @@ end
--- Druid late update function called after initialization and before the regular update step
-- This function is used to check the GUI state and perform actions after all components and nodes have been created.
-- An example use case is performing an auto stencil check in the GUI hierarchy for input components.
--- @tparam DruidInstance self
--- @local
-function DruidInstance.late_init(self)
- local late_init_components = self.components_interest[base_component.ON_LATE_INIT]
+---@private
+function M:late_init()
+ local late_init_components = self.components_interest[const.ON_LATE_INIT]
while late_init_components[1] do
late_init_components[1]:on_late_init()
table.remove(late_init_components, 1)
end
- if not self.input_inited and #self.components_interest[base_component.ON_INPUT] > 0 then
+ if not self.input_inited and #self.components_interest[const.ON_INPUT] > 0 then
-- Input init on late init step, to be sure it goes after user go acquire input
set_input_state(self, true)
end
end
---- Call this in gui_script update function.
---
--- Used for: scroll, progress, timer components
--- @tparam DruidInstance self
--- @tparam number dt Delta time
-function DruidInstance.update(self, dt)
+---Call this in gui_script update function.
+---@param dt number Delta time
+function M:update(dt)
self._is_late_remove_enabled = true
- local components = self.components_interest[base_component.ON_UPDATE]
+ local components = self.components_interest[const.ON_UPDATE]
for i = 1, #components do
components[i]:update(dt)
end
@@ -368,19 +344,16 @@ function DruidInstance.update(self, dt)
end
---- Call this in gui_script on_input function.
---
--- Used for almost all components
--- @tparam DruidInstance self
--- @tparam hash action_id Action_id from on_input
--- @tparam table action Action from on_input
--- @treturn boolean The boolean value is input was consumed
-function DruidInstance.on_input(self, action_id, action)
+---Call this in gui_script on_input function.
+---@param action_id hash Action_id from on_input
+---@param action table Action from on_input
+---@return boolean The boolean value is input was consumed
+function M:on_input(action_id, action)
self._is_late_remove_enabled = true
- local components = self.components_interest[base_component.ON_INPUT]
+ local components = self.components_interest[const.ON_INPUT]
check_sort_input_stack(self, components)
- local is_input_consumed = process_input(self, action_id, action, components)
+ local is_input_consumed = self:_process_input(action_id, action, components)
self._is_late_remove_enabled = false
self:_clear_late_remove()
@@ -390,38 +363,19 @@ end
--- Call this in gui_script on_message function.
---
--- Used for special actions. See SPECIFIC_UI_MESSAGES table
--- @tparam DruidInstance self
--- @tparam hash message_id Message_id from on_message
--- @tparam table message Message from on_message
--- @tparam url sender Sender from on_message
-function DruidInstance.on_message(self, message_id, message, sender)
- local specific_ui_message = base_component.SPECIFIC_UI_MESSAGES[message_id]
-
- if specific_ui_message == base_component.ON_MESSAGE_INPUT then
- -- ON_MESSAGE_INPUT is special message, need to perform additional logic
- local components = self.components_interest[base_component.ON_MESSAGE_INPUT]
- if components then
- for i = 1, #components do
- local component = components[i]
- if can_use_input_component(self, component) then
- component[specific_ui_message](component, hash(message.node_id), message)
- end
- end
- end
- elseif specific_ui_message then
+---@param message_id hash Message_id from on_message
+---@param message table Message from on_message
+---@param sender url Sender from on_message
+function M:on_message(message_id, message, sender)
+ if message_id == const.MSG_LAYOUT_CHANGED then
-- Resend special message to all components with the related interest
- local components = self.components_interest[specific_ui_message]
- if components then
- for i = 1, #components do
- local component = components[i]
- component[specific_ui_message](component, message, sender)
- end
+ local components = self.components_interest[const.ON_LAYOUT_CHANGE]
+ for i = 1, #components do
+ components[i]:on_layout_change()
end
else
-- Resend message to all components with on_message interest
- local components = self.components_interest[base_component.ON_MESSAGE]
+ local components = self.components_interest[const.ON_MESSAGE]
for i = 1, #components do
components[i]:on_message(message_id, message, sender)
end
@@ -429,26 +383,22 @@ function DruidInstance.on_message(self, message_id, message, sender)
end
---- Calls the on_focus_lost function in all related components
--- This one called by on_window_callback by global window listener
--- @tparam DruidInstance self
--- @local
-function DruidInstance.on_focus_lost(self)
- local components = self.components_interest[base_component.ON_FOCUS_LOST]
- for i = 1, #components do
- components[i]:on_focus_lost()
- end
-end
-
-
---- Calls the on_focus_gained function in all related components
--- This one called by on_window_callback by global window listener
--- @tparam DruidInstance self
--- @local
-function DruidInstance.on_focus_gained(self)
- local components = self.components_interest[base_component.ON_FOCUS_GAINED]
- for i = 1, #components do
- components[i]:on_focus_gained()
+function M:on_window_event(window_event)
+ if window_event == window.WINDOW_EVENT_FOCUS_LOST then
+ local components = self.components_interest[const.ON_FOCUS_LOST]
+ for i = 1, #components do
+ components[i]:on_focus_lost()
+ end
+ elseif window_event == window.WINDOW_EVENT_FOCUS_GAINED then
+ local components = self.components_interest[const.ON_FOCUS_GAINED]
+ for i = 1, #components do
+ components[i]:on_focus_gained()
+ end
+ elseif window_event == window.WINDOW_EVENT_RESIZED then
+ local components = self.components_interest[const.ON_WINDOW_RESIZED]
+ for i = 1, #components do
+ components[i]:on_window_resized()
+ end
end
end
@@ -456,24 +406,21 @@ end
--- Calls the on_language_change function in all related components
-- This one called by global druid.on_language_change, but can be
-- call manualy to update all translations
--- @tparam DruidInstance self
--- @local
-function DruidInstance.on_language_change(self)
- local components = self.components_interest[base_component.ON_LANGUAGE_CHANGE]
+---@private
+function M:on_language_change()
+ local components = self.components_interest[const.ON_LANGUAGE_CHANGE]
for i = 1, #components do
components[i]:on_language_change()
end
end
---- Set whitelist components for input processing.
---
--- If whitelist is not empty and component not contains in this list,
--- component will be not processed on input step
--- @tparam DruidInstance self
--- @tparam table|BaseComponent|nil whitelist_components The array of component to whitelist
--- @treturn self @{DruidInstance}
-function DruidInstance.set_whitelist(self, whitelist_components)
+---Set whitelist components for input processing.
+---If whitelist is not empty and component not contains in this list,
+---component will be not processed on input step
+---@param whitelist_components table|druid.base_component[] The array of component to whitelist
+---@return druid_instance
+function M:set_whitelist(whitelist_components)
if whitelist_components and whitelist_components._component then
whitelist_components = { whitelist_components }
end
@@ -488,14 +435,12 @@ function DruidInstance.set_whitelist(self, whitelist_components)
end
---- Set blacklist components for input processing.
---
--- If blacklist is not empty and component contains in this list,
--- component will be not processed on input step
--- @tparam DruidInstance self @{DruidInstance}
--- @tparam table|BaseComponent|nil blacklist_components The array of component to blacklist
--- @treturn self @{DruidInstance}
-function DruidInstance.set_blacklist(self, blacklist_components)
+---Set blacklist components for input processing.
+---If blacklist is not empty and component contains in this list,
+---component will be not processed on input step DruidInstance
+---@param blacklist_components table|druid.base_component[] The array of component to blacklist
+---@return druid_instance
+function M:set_blacklist(blacklist_components)
if blacklist_components and blacklist_components._component then
blacklist_components = { blacklist_components }
end
@@ -510,35 +455,9 @@ function DruidInstance.set_blacklist(self, blacklist_components)
end
---- Set debug mode for current Druid instance. It's enable debug log messages
--- @tparam DruidInstance self @{DruidInstance}
--- @tparam boolean|nil is_debug
--- @treturn self @{DruidInstance}
--- @local
-function DruidInstance.set_debug(self, is_debug)
- self._is_debug = is_debug
- return self
-end
-
-
---- Log message, if is_debug mode is enabled
--- @tparam DruidInstance self @{DruidInstance}
--- @tparam string message
--- @tparam table|nil context
--- @local
-function DruidInstance.log_message(self, message, context)
- if not self._is_debug then
- return
- end
-
- print("[Druid]:", message, helper.table_to_string(context))
-end
-
-
---- Remove all components on late remove step
--- @tparam DruidInstance self @{DruidInstance}
--- @local
-function DruidInstance._clear_late_remove(self)
+--- Remove all components on late remove step DruidInstance
+---@private
+function M:_clear_late_remove()
if #self._late_remove == 0 then
return
end
@@ -550,229 +469,245 @@ function DruidInstance._clear_late_remove(self)
end
---- Create @{Button} component
--- @tparam DruidInstance self
--- @tparam string|node node The node_id or gui.get_node(node_id)
--- @tparam function|nil callback Button callback
--- @tparam any|nil params Button callback params
--- @tparam node|string|nil anim_node Button anim node (node, if not provided)
--- @treturn Button @{Button} component
-function DruidInstance.new_button(self, node, callback, params, anim_node)
- return DruidInstance.new(self, button, node, callback, params, anim_node)
+---Create new Druid widget instance
+---@generic T: druid.base_component
+---@param widget T
+---@param template string|nil The template name used by widget
+---@param nodes table|node|nil The nodes table from gui.clone_tree or prefab node to use for clone
+---@vararg any
+---@return T
+function M:new_widget(widget, template, nodes, ...)
+ local instance = create_widget(self, widget)
+
+ if type(nodes) == "userdata" then
+ nodes = gui.clone_tree(nodes) --[[@as table]]
+ end
+
+ instance.druid = instance:get_druid(template, nodes)
+
+ if instance.init then
+ instance:init(...)
+ end
+ if instance.on_late_init or (not self.input_inited and instance.on_input) then
+ schedule_late_init(self)
+ end
+
+ return instance
end
---- Create @{Blocker} component
--- @tparam DruidInstance self
--- @tparam string|node node The node_id or gui.get_node(node_id)
--- @treturn Blocker @{Blocker} component
-function DruidInstance.new_blocker(self, node)
- return DruidInstance.new(self, blocker, node)
+local button = require("druid.base.button")
+---Create Button component
+---@param node string|node The node_id or gui.get_node(node_id)
+---@param callback function|nil Button callback
+---@param params any|nil Button callback params
+---@param anim_node node|string|nil Button anim node (node, if not provided)
+---@return druid.button Button component
+function M:new_button(node, callback, params, anim_node)
+ return self:new(button, node, callback, params, anim_node)
end
---- Create @{BackHandler} component
--- @tparam DruidInstance self
--- @tparam function|nil callback @The callback(self, custom_args) to call on back event
--- @tparam any|nil params Callback argument
--- @treturn BackHandler @{BackHandler} component
-function DruidInstance.new_back_handler(self, callback, params)
- return DruidInstance.new(self, back_handler, callback, params)
+local blocker = require("druid.base.blocker")
+---Create Blocker component
+---@param node string|node The node_id or gui.get_node(node_id)
+---@return druid.blocker component Blocker component
+function M:new_blocker(node)
+ return self:new(blocker, node)
end
---- Create @{Hover} component
--- @tparam DruidInstance self
--- @tparam string|node node The node_id or gui.get_node(node_id)
--- @tparam function|nil on_hover_callback Hover callback
--- @tparam function|nil on_mouse_hover_callback Mouse hover callback
--- @treturn Hover @{Hover} component
-function DruidInstance.new_hover(self, node, on_hover_callback, on_mouse_hover_callback)
- return DruidInstance.new(self, hover, node, on_hover_callback, on_mouse_hover_callback)
+local back_handler = require("druid.base.back_handler")
+---Create BackHandler component
+---@param callback function|nil The callback(self, custom_args) to call on back event
+---@param params any|nil Callback argument
+---@return druid.back_handler component BackHandler component
+function M:new_back_handler(callback, params)
+ return self:new(back_handler, callback, params)
end
---- Create @{Text} component
--- @tparam DruidInstance self
--- @tparam string|node node The node_id or gui.get_node(node_id)
--- @tparam string|nil value Initial text. Default value is node text from GUI scene.
--- @tparam boolean|nil no_adjust If true, text will be not auto-adjust size
--- @treturn Text @{Text} component
-function DruidInstance.new_text(self, node, value, no_adjust)
- return DruidInstance.new(self, text, node, value, no_adjust)
+local hover = require("druid.base.hover")
+---Create Hover component
+---@param node string|node The node_id or gui.get_node(node_id)
+---@param on_hover_callback function|nil Hover callback
+---@param on_mouse_hover_callback function|nil Mouse hover callback
+---@return druid.hover component Hover component
+function M:new_hover(node, on_hover_callback, on_mouse_hover_callback)
+ return self:new(hover, node, on_hover_callback, on_mouse_hover_callback)
end
---- Create @{StaticGrid} component
--- @tparam DruidInstance self
--- @tparam string|node parent_node The node_id or gui.get_node(node_id). Parent of all Grid items.
--- @tparam node item Element prefab. Required to get grid's item size. Can be adjusted separately.
--- @tparam number|nil in_row How many nodes in row can be placed
--- @treturn StaticGrid @{StaticGrid} component
--- @local
-function DruidInstance.new_grid(self, parent_node, item, in_row)
- return DruidInstance.new(self, static_grid, parent_node, item, in_row)
+local text = require("druid.base.text")
+---Create Text component
+---@param node string|node The node_id or gui.get_node(node_id)
+---@param value string|nil Initial text. Default value is node text from GUI scene.
+---@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
+---@return druid.text component Text component
+function M:new_text(node, value, adjust_type)
+ return self:new(text, node, value, adjust_type)
end
---- Create @{StaticGrid} component
--- @tparam DruidInstance self
--- @tparam string|node parent_node The node_id or gui.get_node(node_id). Parent of all Grid items.
--- @tparam string|node item Item prefab. Required to get grid's item size. Can be adjusted separately.
--- @tparam number|nil in_row How many nodes in row can be placed
--- @treturn StaticGrid @{StaticGrid} component
-function DruidInstance.new_static_grid(self, parent_node, item, in_row)
- return DruidInstance.new(self, static_grid, parent_node, item, in_row)
+local static_grid = require("druid.base.static_grid")
+---Create Grid component
+---@param parent_node string|node The node_id or gui.get_node(node_id). Parent of all Grid items.
+---@param item string|node Item prefab. Required to get grid's item size. Can be adjusted separately.
+---@param in_row number|nil How many nodes in row can be placed
+---@return druid.grid component Grid component
+function M:new_grid(parent_node, item, in_row)
+ return self:new(static_grid, parent_node, item, in_row)
end
---- Create @{Scroll} component
--- @tparam DruidInstance self
--- @tparam string|node view_node The node_id or gui.get_node(node_id). Will used as user input node.
--- @tparam string|node content_node The node_id or gui.get_node(node_id). Will used as scrollable node inside view_node.
--- @treturn Scroll @{Scroll} component
-function DruidInstance.new_scroll(self, view_node, content_node)
- return DruidInstance.new(self, scroll, view_node, content_node)
+local scroll = require("druid.base.scroll")
+---Create Scroll component
+---@param view_node string|node The node_id or gui.get_node(node_id). Will used as user input node.
+---@param content_node string|node The node_id or gui.get_node(node_id). Will used as scrollable node inside view_node.
+---@return druid.scroll component Scroll component
+function M:new_scroll(view_node, content_node)
+ return self:new(scroll, view_node, content_node)
end
---- Create @{Drag} component
--- @tparam DruidInstance self
--- @tparam string|node node The node_id or gui.get_node(node_id). Will used as user input node.
--- @tparam function|nil on_drag_callback Callback for on_drag_event(self, dx, dy)
--- @treturn Drag @{Drag} component
-function DruidInstance.new_drag(self, node, on_drag_callback)
- return DruidInstance.new(self, drag, node, on_drag_callback)
+local drag = require("druid.base.drag")
+---Create Drag component
+---@param node string|node The node_id or gui.get_node(node_id). Will used as user input node.
+---@param on_drag_callback function|nil Callback for on_drag_event(self, dx, dy)
+---@return druid.drag component Drag component
+function M:new_drag(node, on_drag_callback)
+ return self:new(drag, node, on_drag_callback)
end
---- Create @{Swipe} component
--- @tparam DruidInstance self
--- @tparam string|node node The node_id or gui.get_node(node_id). Will used as user input node.
--- @tparam function|nil on_swipe_callback Swipe callback for on_swipe_end event
--- @treturn Swipe @{Swipe} component
-function DruidInstance.new_swipe(self, node, on_swipe_callback)
- return helper.require_component_message("swipe")
+local swipe = require("druid.extended.swipe")
+---Create Swipe component
+---@param node string|node The node_id or gui.get_node(node_id). Will used as user input node.
+---@param on_swipe_callback function|nil Swipe callback for on_swipe_end event
+---@return druid.swipe component Swipe component
+function M:new_swipe(node, on_swipe_callback)
+ return self:new(swipe, node, on_swipe_callback)
end
---- Create @{DynamicGrid} component
--- Deprecated
--- @tparam DruidInstance self
--- @tparam string|node parent_node The node_id or gui.get_node(node_id). Parent of all Grid items.
--- @treturn DynamicGrid @{DynamicGrid} component
-function DruidInstance.new_dynamic_grid(self, parent_node)
- return helper.require_component_message("dynamic_grid")
+local lang_text = require("druid.extended.lang_text")
+---Create LangText component
+---@param node string|node The_node id or gui.get_node(node_id)
+---@param locale_id string|nil Default locale id or text from node as default
+---@param adjust_type string|nil Adjust type for text node. Default: const.TEXT_ADJUST.DOWNSCALE
+---@return druid.lang_text component LangText component
+function M:new_lang_text(node, locale_id, adjust_type)
+ return self:new(lang_text, node, locale_id, adjust_type)
end
---- Create @{LangText} component
--- @tparam DruidInstance self
--- @tparam string|node node The_node id or gui.get_node(node_id)
--- @tparam string|nil locale_id Default locale id or text from node as default
--- @tparam string|nil adjust_type Adjust type for text node. Default: const.TEXT_ADJUST.DOWNSCALE
--- @treturn LangText @{LangText} component
-function DruidInstance.new_lang_text(self, node, locale_id, adjust_type)
- return helper.require_component_message("lang_text")
+local slider = require("druid.extended.slider")
+---Create Slider component
+---@param pin_node string|node The_node id or gui.get_node(node_id).
+---@param end_pos vector3 The end position of slider
+---@param callback function|nil On slider change callback
+---@return druid.slider component Slider component
+function M:new_slider(pin_node, end_pos, callback)
+ return self:new(slider, pin_node, end_pos, callback)
end
---- Create @{Slider} component
--- @tparam DruidInstance self
--- @tparam string|node pin_node The_node id or gui.get_node(node_id).
--- @tparam vector3 end_pos The end position of slider
--- @tparam function|nil callback On slider change callback
--- @treturn Slider @{Slider} component
-function DruidInstance.new_slider(self, pin_node, end_pos, callback)
- return helper.require_component_message("slider")
+local input = require("druid.extended.input")
+---Create Input component
+---@param click_node string|node Button node to enabled input component
+---@param text_node string|node|druid.text Text node what will be changed on user input
+---@param keyboard_type number|nil Gui keyboard type for input field
+---@return druid.input component Input component
+function M:new_input(click_node, text_node, keyboard_type)
+ return self:new(input, click_node, text_node, keyboard_type)
end
---- Create @{Input} component
--- @tparam DruidInstance self
--- @tparam string|node click_node Button node to enabled input component
--- @tparam string|node|druid.text text_node Text node what will be changed on user input
--- @tparam number|nil keyboard_type Gui keyboard type for input field
--- @treturn Input @{Input} component
-function DruidInstance.new_input(self, click_node, text_node, keyboard_type)
- return helper.require_component_message("input")
+local data_list = require("druid.extended.data_list")
+---Create DataList component
+---@param druid_scroll druid.scroll The Scroll instance for Data List component
+---@param druid_grid druid.grid The StaticGrid} or @{DynamicGrid instance for Data List component
+---@param create_function function The create function callback(self, data, index, data_list). Function should return (node, [component])
+---@return druid.data_list component DataList component
+function M:new_data_list(druid_scroll, druid_grid, create_function)
+ return self:new(data_list, druid_scroll, druid_grid, create_function)
end
---- Create @{DataList} component
--- @tparam DruidInstance self
--- @tparam Scroll druid_scroll The Scroll instance for Data List component
--- @tparam StaticGrid druid_grid The @{StaticGrid} or @{DynamicGrid} instance for Data List component
--- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component])
--- @treturn DataList @{DataList} component
-function DruidInstance.new_data_list(self, druid_scroll, druid_grid, create_function)
- return helper.require_component_message("data_list")
+local timer_component = require("druid.extended.timer")
+---Create Timer component
+---@param node string|node Gui text node
+---@param seconds_from number|nil Start timer value in seconds
+---@param seconds_to number|nil End timer value in seconds
+---@param callback function|nil Function on timer end
+---@return druid.timer component Timer component
+function M:new_timer(node, seconds_from, seconds_to, callback)
+ return self:new(timer_component, node, seconds_from, seconds_to, callback)
end
---- Create @{Timer} component
--- @tparam DruidInstance self
--- @tparam string|node node Gui text node
--- @tparam number seconds_from Start timer value in seconds
--- @tparam number|nil seconds_to End timer value in seconds
--- @tparam function|nil callback Function on timer end
--- @treturn Timer @{Timer} component
-function DruidInstance.new_timer(self, node, seconds_from, seconds_to, callback)
- return helper.require_component_message("timer")
+local progress = require("druid.extended.progress")
+---Create Progress component
+---@param node string|node Progress bar fill node or node name
+---@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y
+---@param init_value number|nil Initial value of progress bar. Default: 1
+---@return druid.progress component Progress component
+function M:new_progress(node, key, init_value)
+ return self:new(progress, node, key, init_value)
end
---- Create @{Progress} component
--- @tparam DruidInstance self
--- @tparam string|node node Progress bar fill node or node name
--- @tparam string key Progress bar direction: const.SIDE.X or const.SIDE.Y
--- @tparam number|nil init_value Initial value of progress bar. Default: 1
--- @treturn Progress @{Progress} component
-function DruidInstance.new_progress(self, node, key, init_value)
- return helper.require_component_message("progress")
+local layout = require("druid.extended.layout")
+---Create Layout component
+---@param node string|node The_node id or gui.get_node(node_id).
+---@param mode string|nil vertical|horizontal|horizontal_wrap. Default: horizontal
+---@return druid.layout component Layout component
+function M:new_layout(node, mode)
+ return self:new(layout, node, mode)
end
---- Create @{Layout} component
--- @tparam DruidInstance self
--- @tparam string|node node The_node id or gui.get_node(node_id).
--- @tparam string mode The layout mode
--- @treturn Layout @{Layout} component
-function DruidInstance.new_layout(self, node, mode)
- return helper.require_component_message("layout")
+local container = require("druid.extended.container")
+---Create Container component
+---@param node string|node The_node id or gui.get_node(node_id).
+---@param mode string|nil Layout mode
+---@param callback fun(self: druid.container, size: vector3)|nil Callback on size changed
+---@return druid.container container component
+function M:new_container(node, mode, callback)
+ return self:new(container, node, mode, callback)
end
---- Create @{Hotkey} component
--- @tparam DruidInstance self
--- @tparam string|string[] keys_array Keys for trigger action. Should contains one action key and any amount of modificator keys
--- @tparam function callback The callback function
--- @tparam any|nil callback_argument The argument to pass into the callback function
--- @treturn Hotkey @{Hotkey} component
-function DruidInstance.new_hotkey(self, keys_array, callback, callback_argument)
- return helper.require_component_message("hotkey")
+local hotkey = require("druid.extended.hotkey")
+---Create Hotkey component
+---@param keys_array string|string[] Keys for trigger action. Should contains one action key and any amount of modificator keys
+---@param callback function|nil The callback function
+---@param callback_argument any|nil The argument to pass into the callback function
+---@return druid.hotkey component Hotkey component
+function M:new_hotkey(keys_array, callback, callback_argument)
+ return self:new(hotkey, keys_array, callback, callback_argument)
end
---- Create @{RichText} component.
--- @tparam DruidInstance self
--- @tparam string|node text_node The text node to make Rich Text
--- @tparam string|nil value The initial text value. Default will be gui.get_text(text_node)
--- @treturn RichText @{RichText} component
-function DruidInstance.new_rich_text(self, text_node, value)
- return helper.require_component_message("rich_text", "custom")
+local rich_text = require("druid.custom.rich_text.rich_text")
+---Create RichText component.
+---@param text_node string|node The text node to make Rich Text
+---@param value string|nil The initial text value. Default will be gui.get_text(text_node)
+---@return druid.rich_text component RichText component
+function M:new_rich_text(text_node, value)
+ return self:new(rich_text, text_node, value)
end
---- Create @{RichInput} component.
+local rich_input = require("druid.custom.rich_input.rich_input")
+---Create RichInput component.
-- As a template please check rich_input.gui layout.
--- @tparam DruidInstance self
--- @tparam string template The template string name
--- @tparam table nodes Nodes table from gui.clone_tree
--- @treturn RichInput @{RichInput} component
-function DruidInstance.new_rich_input(self, template, nodes)
- return helper.require_component_message("rich_input", "custom")
+---@param template string The template string name
+---@param nodes table|nil Nodes table from gui.clone_tree
+---@return druid.rich_input component RichInput component
+function M:new_rich_input(template, nodes)
+ return self:new(rich_input, template, nodes)
end
-return DruidInstance
+return M
diff --git a/druid/system/settings.lua b/druid/system/settings.lua
index 384a706..ea8f8b6 100755
--- a/druid/system/settings.lua
+++ b/druid/system/settings.lua
@@ -1,21 +1,15 @@
--- Copyright (c) 2021 Maksim Tuprikov . This code is licensed under MIT license
-
---- Druid settings file
--- @module settings
--- @local
-
+---@class druid.system.settings
local M = {}
M.default_style = nil
-
-function M.get_text(name, a, b, c, d, e, f, g)
+---@param text_id string
+---@vararg any
+function M.get_text(text_id, ...)
return "[Druid]: locales not inited"
end
-
-function M.play_sound(name)
+function M.play_sound(sound_id)
end
-
return M
diff --git a/druid/templates/component.template.lua b/druid/templates/component.template.lua
index d67bf32..202cd42 100644
--- a/druid/templates/component.template.lua
+++ b/druid/templates/component.template.lua
@@ -1,21 +1,16 @@
-local component = require("druid.component")
-
----@class component_name : druid.base_component
-local Component = component.create("component_name")
+---@class widget.TEMPLATE: druid.widget
+local M = {}
--- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
-function Component:init(template, nodes)
- self.druid = self:get_druid(template, nodes)
- self.root = self:get_node("root")
-
- self.button = self.druid:new_button("button", function() end)
+function M:init()
+ self.root = self:get_node("root")
+ self.button = self.druid:new_button("button", self.on_button, self)
end
--- [OPTIONAL] Call on component remove or on druid:final
-function Component:on_remove()
+function M:on_button()
+ print("Root node", self.root)
end
-return Component
+return M
\ No newline at end of file
diff --git a/druid/templates/component_full.template.lua b/druid/templates/component_full.template.lua
index 1978cf2..81fd322 100644
--- a/druid/templates/component_full.template.lua
+++ b/druid/templates/component_full.template.lua
@@ -1,10 +1,10 @@
local component = require("druid.component")
----@class component_name : druid.base_component
-local Component = component.create("component_name")
+---@class new_component: druid.base_component
+local M = component.create("new_component")
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
-function Component:init(template, nodes)
+function M:init(template, nodes)
-- If your component is gui template, pass the template name and set it
-- If your component is cloned my gui.clone_tree, pass nodes to component and set it
-- Use inner druid instance to create components inside this component
@@ -17,55 +17,55 @@ end
-- [OPTIONAL] Call every update step
-function Component:update(dt)
+function M:update(dt)
end
-- [OPTIONAL] Call default on_input from gui script
-function Component:on_input(action_id, action)
+function M:on_input(action_id, action)
return false
end
-- [OPTIONAL] Call on component creation and on component:set_style() function
-function Component:on_style_change(style)
+function M:on_style_change(style)
end
-- [OPTIONAL] Call default on_message from gui script
-function Component:on_message(message_id, message, sender)
+function M:on_message(message_id, message, sender)
end
-- [OPTIONAL] Call if druid has triggered on_language_change
-function Component:on_language_change()
+function M:on_language_change()
end
-- [OPTIONAL] Call if game layout has changed and need to restore values in component
-function Component:on_layout_change()
+function M:on_layout_change()
end
-- [OPTIONAL] Call, if input was capturing before this component
-- Example: scroll is start scrolling, so you need unhover button
-function Component:on_input_interrupt()
+function M:on_input_interrupt()
end
-- [OPTIONAL] Call, if game lost focus
-function Component:on_focus_lost()
+function M:on_focus_lost()
end
-- [OPTIONAL] Call, if game gained focus
-function Component:on_focus_gained()
+function M:on_focus_gained()
end
-- [OPTIONAL] Call on component remove or on druid:final
-function Component:on_remove()
+function M:on_remove()
end
-return Component
+return M
diff --git a/druid/widget/fps_panel/fps_panel.gui b/druid/widget/fps_panel/fps_panel.gui
new file mode 100644
index 0000000..5b85967
--- /dev/null
+++ b/druid/widget/fps_panel/fps_panel.gui
@@ -0,0 +1,222 @@
+fonts {
+ name: "druid_text_regular"
+ font: "/druid/fonts/druid_text_regular.font"
+}
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 200.0
+ y: 140.0
+ }
+ type: TYPE_BOX
+ id: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "mini_graph"
+ parent: "root"
+ inherit_alpha: true
+ template: "/druid/widget/mini_graph/mini_graph.gui"
+}
+nodes {
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ id: "mini_graph/root"
+ parent: "mini_graph"
+ overridden_fields: 5
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/header"
+ parent: "mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ text: "FPS"
+ id: "mini_graph/text_header"
+ parent: "mini_graph/header"
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/icon_drag"
+ parent: "mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/content"
+ parent: "mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ color {
+ x: 0.525
+ y: 0.525
+ z: 0.525
+ }
+ type: TYPE_BOX
+ id: "mini_graph/prefab_line"
+ parent: "mini_graph/content"
+ overridden_fields: 5
+ template_node_child: true
+}
+nodes {
+ color {
+ x: 0.957
+ y: 0.608
+ z: 0.608
+ }
+ type: TYPE_BOX
+ id: "mini_graph/color_low"
+ parent: "mini_graph/content"
+ overridden_fields: 5
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 200.0
+ y: 100.0
+ }
+ type: TYPE_BOX
+ id: "content"
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -96.0
+ y: 12.0
+ }
+ scale {
+ x: 0.3
+ y: 0.3
+ }
+ size {
+ x: 260.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "12 FPS"
+ font: "druid_text_regular"
+ id: "text_min_fps"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "content"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ y: 12.0
+ }
+ scale {
+ x: 0.3
+ y: 0.3
+ }
+ size {
+ x: 260.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "60 FPS"
+ font: "druid_text_bold"
+ id: "text_fps"
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "content"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: -33.4
+ y: 30.0
+ }
+ size {
+ x: 3.0
+ y: 8.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "line_second_1"
+ pivot: PIVOT_N
+ parent: "content"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: 33.2
+ y: 30.0
+ }
+ size {
+ x: 3.0
+ y: 8.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "line_second_2"
+ pivot: PIVOT_N
+ parent: "content"
+ inherit_alpha: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/fps_panel/fps_panel.lua b/druid/widget/fps_panel/fps_panel.lua
new file mode 100644
index 0000000..c86c66b
--- /dev/null
+++ b/druid/widget/fps_panel/fps_panel.lua
@@ -0,0 +1,101 @@
+local helper = require("druid.helper")
+local mini_graph = require("druid.widget.mini_graph.mini_graph")
+
+---@class widget.fps_panel: druid.widget
+---@field root node
+local M = {}
+
+local TARGET_FPS = sys.get_config_int("display.update_frequency", 60)
+if TARGET_FPS == 0 then
+ TARGET_FPS = 60
+end
+
+function M:init()
+ self.root = self:get_node("root")
+
+ self.delta_time = 0.1 -- in seconds
+ self.collect_time = 3 -- in seconds
+ self.collect_time_counter = 0
+ self.graph_samples = self.collect_time / self.delta_time
+
+ -- Store frame time in seconds last collect_time seconds
+ self.fps_samples = {}
+
+ self.mini_graph = self.druid:new_widget(mini_graph, "mini_graph")
+ self.mini_graph:set_samples(self.graph_samples) -- show last 30 seconds
+ self.mini_graph:set_max_value(TARGET_FPS)
+
+ do -- Set parent manually
+ local parent_node = self.mini_graph.content
+ local position = helper.get_full_position(parent_node, self.mini_graph.root)
+ local content = self:get_node("content")
+ gui.set_parent(content, self.mini_graph.content)
+ gui.set_position(content, -position)
+ end
+
+ self.text_min_fps = self.druid:new_text("text_min_fps")
+ self.text_fps = self.druid:new_text("text_fps")
+
+ self.timer_id = timer.delay(self.delta_time, true, function()
+ self:push_fps_value()
+ end)
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container(self.mini_graph.container)
+end
+
+
+function M:on_remove()
+ timer.cancel(self.timer_id)
+end
+
+
+function M:update(dt)
+ if not self.previous_time then
+ self.previous_time = socket.gettime()
+ return
+ end
+
+ local current_time = socket.gettime()
+ local delta_time = current_time - self.previous_time
+ self.previous_time = current_time
+ self.collect_time_counter = self.collect_time_counter + delta_time
+
+ table.insert(self.fps_samples, 1, delta_time)
+
+ while self.collect_time_counter > self.collect_time do
+ -- Remove last
+ local removed_value = table.remove(self.fps_samples)
+ self.collect_time_counter = self.collect_time_counter - removed_value
+ end
+end
+
+
+function M:push_fps_value()
+ if #self.fps_samples == 0 then
+ return
+ end
+
+ local max_frame_time = 0
+ local average_frame_time = 0
+ local average_samples_count = self.delta_time
+ local average_collected = 0
+ for index = 1, #self.fps_samples do
+ if average_frame_time < average_samples_count then
+ average_frame_time = average_frame_time + self.fps_samples[index]
+ average_collected = average_collected + 1
+ end
+ max_frame_time = math.max(max_frame_time, self.fps_samples[index])
+ end
+
+ average_frame_time = average_frame_time / average_collected
+
+ self.mini_graph:push_line_value(1 / average_frame_time)
+
+ self.text_fps:set_text(tostring(math.ceil(1 / average_frame_time) .. " FPS"))
+ local lowest_value = math.ceil(self.mini_graph:get_lowest_value())
+ self.text_min_fps:set_text(lowest_value .. " lowest")
+end
+
+
+return M
\ No newline at end of file
diff --git a/druid/widget/memory_panel/memory_panel.gui b/druid/widget/memory_panel/memory_panel.gui
new file mode 100644
index 0000000..80b3b4a
--- /dev/null
+++ b/druid/widget/memory_panel/memory_panel.gui
@@ -0,0 +1,242 @@
+fonts {
+ name: "druid_text_regular"
+ font: "/druid/fonts/druid_text_regular.font"
+}
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 200.0
+ y: 140.0
+ }
+ type: TYPE_BOX
+ id: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "mini_graph"
+ parent: "root"
+ inherit_alpha: true
+ template: "/druid/widget/mini_graph/mini_graph.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/root"
+ parent: "mini_graph"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/header"
+ parent: "mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ text: "Memory"
+ id: "mini_graph/text_header"
+ parent: "mini_graph/header"
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/icon_drag"
+ parent: "mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/content"
+ parent: "mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/prefab_line"
+ parent: "mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/color_low"
+ parent: "mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 200.0
+ y: 100.0
+ }
+ type: TYPE_BOX
+ id: "content"
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -96.0
+ y: 12.0
+ }
+ scale {
+ x: 0.3
+ y: 0.3
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "120.23 KB"
+ font: "druid_text_regular"
+ id: "text_max_value"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "content"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 96.0
+ y: 12.0
+ }
+ scale {
+ x: 0.3
+ y: 0.3
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "120 KB/s"
+ font: "druid_text_regular"
+ id: "text_per_second"
+ pivot: PIVOT_E
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "content"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: -33.4
+ y: 30.0
+ }
+ size {
+ x: 3.0
+ y: 8.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "line_second_1"
+ pivot: PIVOT_N
+ parent: "content"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: 33.2
+ y: 30.0
+ }
+ size {
+ x: 3.0
+ y: 8.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "line_second_2"
+ pivot: PIVOT_N
+ parent: "content"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ y: 12.0
+ }
+ scale {
+ x: 0.3
+ y: 0.3
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "120 KB"
+ font: "druid_text_bold"
+ id: "text_memory"
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "content"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/memory_panel/memory_panel.lua b/druid/widget/memory_panel/memory_panel.lua
new file mode 100644
index 0000000..3a72ae0
--- /dev/null
+++ b/druid/widget/memory_panel/memory_panel.lua
@@ -0,0 +1,96 @@
+local helper = require("druid.helper")
+local mini_graph = require("druid.widget.mini_graph.mini_graph")
+
+---@class widget.memory_panel: druid.widget
+---@field root node
+local M = {}
+
+function M:init()
+ self.root = self:get_node("root")
+ self.delta_time = 0.1
+ self.samples_count = 30
+ self.memory_limit = 100
+
+ self.mini_graph = self.druid:new_widget(mini_graph, "mini_graph")
+ self.mini_graph:set_samples(self.samples_count)
+
+ -- This one is not works with scaled root
+ --gui.set_parent(self:get_node("content"), self.mini_graph.content, true)
+
+ do -- Set parent manually
+ local parent_node = self.mini_graph.content
+ local position = helper.get_full_position(parent_node, self.mini_graph.root)
+ local content = self:get_node("content")
+ gui.set_parent(content, self.mini_graph.content)
+ gui.set_position(content, -position)
+ end
+
+ self.max_value = self.druid:new_text("text_max_value")
+ self.text_per_second = self.druid:new_text("text_per_second")
+ self.text_memory = self.druid:new_text("text_memory")
+
+ self.memory = collectgarbage("count")
+ self.memory_samples = {}
+
+ self:update_text_memory()
+
+ self.timer_id = timer.delay(self.delta_time, true, function()
+ self:push_next_value()
+ end)
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container(self.mini_graph.container)
+end
+
+
+function M:on_remove()
+ timer.cancel(self.timer_id)
+end
+
+
+function M:set_low_memory_limit(limit)
+ self.memory_limit = limit
+end
+
+
+function M:push_next_value()
+ local memory = collectgarbage("count")
+ local diff = math.max(0, memory - self.memory)
+ self.memory = memory
+ self:update_text_memory()
+
+ table.insert(self.memory_samples, diff)
+ if #self.memory_samples > self.samples_count then
+ table.remove(self.memory_samples, 1)
+ end
+
+ self.mini_graph:push_line_value(diff)
+
+ local max_value = math.max(unpack(self.memory_samples))
+ max_value = math.max(max_value, self.memory_limit) -- low limit to display
+ self.mini_graph:set_max_value(max_value)
+
+ local max_memory = math.ceil(self.mini_graph:get_highest_value())
+ self.max_value:set_text(max_memory .. " KB")
+
+ local last_second = 0
+ local last_second_samples = math.ceil(1 / self.delta_time)
+ for index = #self.memory_samples - last_second_samples + 1, #self.memory_samples do
+ last_second = last_second + (self.memory_samples[index] or 0)
+ end
+ self.text_per_second:set_text(math.ceil(last_second) .. " KB/s")
+end
+
+
+function M:update_text_memory()
+ local memory = math.ceil(collectgarbage("count")) -- in KB
+ if memory > 1024 then
+ memory = memory / 1024
+ self.text_memory:set_text(string.format("%.2f", memory) .. " MB")
+ else
+ self.text_memory:set_text(memory .. " KB")
+ end
+end
+
+
+return M
\ No newline at end of file
diff --git a/druid/widget/mini_graph/mini_graph.gui b/druid/widget/mini_graph/mini_graph.gui
new file mode 100644
index 0000000..11ad730
--- /dev/null
+++ b/druid/widget/mini_graph/mini_graph.gui
@@ -0,0 +1,176 @@
+fonts {
+ name: "druid_text_regular"
+ font: "/druid/fonts/druid_text_regular.font"
+}
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 200.0
+ y: 140.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid/ui_circle_16"
+ id: "root"
+ inherit_alpha: true
+ slice9 {
+ x: 8.0
+ y: 8.0
+ z: 8.0
+ w: 8.0
+ }
+}
+nodes {
+ position {
+ y: 70.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "header"
+ pivot: PIVOT_N
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -92.0
+ y: -8.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 260.0
+ y: 50.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Mini Graph"
+ font: "druid_text_bold"
+ id: "text_header"
+ pivot: PIVOT_NW
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "header"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 96.0
+ y: -4.0
+ }
+ color {
+ x: 0.306
+ y: 0.31
+ z: 0.314
+ }
+ type: TYPE_BOX
+ texture: "druid/icon_drag"
+ id: "icon_drag"
+ pivot: PIVOT_NE
+ parent: "header"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ y: -70.0
+ }
+ size {
+ x: 200.0
+ y: 100.0
+ }
+ color {
+ x: 0.129
+ y: 0.141
+ z: 0.157
+ }
+ type: TYPE_BOX
+ texture: "druid/ui_circle_16"
+ id: "content"
+ pivot: PIVOT_S
+ parent: "root"
+ inherit_alpha: true
+ slice9 {
+ x: 8.0
+ y: 8.0
+ z: 8.0
+ w: 8.0
+ }
+ clipping_mode: CLIPPING_MODE_STENCIL
+ material: "gui_stencil"
+}
+nodes {
+ size {
+ x: 8.0
+ y: 70.0
+ }
+ color {
+ x: 0.957
+ y: 0.608
+ z: 0.608
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "prefab_line"
+ pivot: PIVOT_S
+ parent: "content"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: -10.0
+ y: 4.0
+ }
+ size {
+ x: 8.0
+ y: 8.0
+ }
+ color {
+ x: 0.557
+ y: 0.835
+ z: 0.62
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "color_low"
+ parent: "content"
+ inherit_alpha: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
+materials {
+ name: "gui_stencil"
+ material: "/druid/materials/stencil/gui_stencil.material"
+}
diff --git a/druid/widget/mini_graph/mini_graph.lua b/druid/widget/mini_graph/mini_graph.lua
new file mode 100644
index 0000000..3cebd5b
--- /dev/null
+++ b/druid/widget/mini_graph/mini_graph.lua
@@ -0,0 +1,162 @@
+local color = require("druid.color")
+local helper = require("druid.helper")
+
+---@class widget.mini_graph: druid.widget
+local M = {}
+
+local SIZE_Y = hash("size.y")
+
+
+function M:init()
+ self.root = self:get_node("root")
+ self.text_header = self.druid:new_text("text_header")
+
+ self.druid:new_drag("header", self.on_drag_widget)
+ self.druid:new_button("icon_drag", self.toggle_hide)
+ :set_style(nil)
+
+ self.content = self:get_node("content")
+ self.layout = self.druid:new_layout(self.content, "horizontal")
+ :set_margin(0, 0)
+ :set_padding(0, 0, 0, 0)
+
+ self.prefab_line = self:get_node("prefab_line")
+ gui.set_enabled(self.prefab_line, false)
+
+ local node_color_low = self:get_node("color_low")
+ self.color_zero = gui.get_color(node_color_low)
+ self.color_one = gui.get_color(self.prefab_line)
+ gui.set_enabled(node_color_low, false)
+
+ self.is_hidden = false
+ self.max_value = 1 -- in this value line will be at max height
+ self.lines = {}
+ self.values = {}
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("header")
+ self.default_size = self.container:get_size()
+end
+
+
+function M:on_remove()
+ self:clear()
+end
+
+
+function M:clear()
+ self.layout:clear_layout()
+ for index = 1, #self.lines do
+ gui.delete_node(self.lines[index])
+ end
+
+ self.lines = {}
+end
+
+
+function M:set_samples(samples)
+ self.samples = samples
+ self:clear()
+
+ local line_width = self.layout:get_size().x / self.samples
+ for index = 1, self.samples do
+ local line = gui.clone(self.prefab_line)
+ gui.set_enabled(line, true)
+ gui.set(line, "size.x", line_width)
+ self.layout:add(line)
+ table.insert(self.lines, line)
+ end
+end
+
+
+function M:get_samples()
+ return self.samples
+end
+
+
+---Set normalized to control the color of the line
+--- for index = 1, mini_graph:get_samples() do
+--- mini_graph:set_line_value(index, math.random())
+--- end
+---@param index number
+---@param value number The normalized value from 0 to 1
+function M:set_line_value(index, value)
+ local line = self.lines[index]
+ if not line then
+ return
+ end
+
+ self.values[index] = value
+
+ local normalized = helper.clamp(value/self.max_value, 0, 1)
+ local target_color = color.lerp(normalized, self.color_zero, self.color_one)
+ gui.set_color(line, target_color)
+ self:set_line_height(index)
+end
+
+
+---@return number
+function M:get_line_value(index)
+ return self.values[index] or 0
+end
+
+
+function M:push_line_value(value)
+ for index = 1, self.samples - 1 do
+ self:set_line_value(index, self:get_line_value(index + 1))
+ end
+
+ self:set_line_value(self.samples, value)
+end
+
+
+function M:set_max_value(max_value)
+ if self.max_value == max_value then
+ return
+ end
+
+ self.max_value = max_value
+ for index = 1, self.samples do
+ self:set_line_height(index)
+ end
+end
+
+
+function M:set_line_height(index)
+ local value = self.values[index] or 0
+ local normalized = helper.clamp(value / self.max_value, 0, 1)
+ local size_y = normalized * 70
+ gui.set(self.lines[index], SIZE_Y, size_y)
+end
+
+
+function M:get_lowest_value()
+ return math.min(unpack(self.values))
+end
+
+
+function M:get_highest_value()
+ return math.max(unpack(self.values))
+end
+
+
+function M:on_drag_widget(dx, dy)
+ local position = self.container:get_position()
+ self.container:set_position(position.x + dx, position.y + dy)
+end
+
+
+function M:toggle_hide()
+ self.is_hidden = not self.is_hidden
+ local hidden_size = gui.get_size(self:get_node("header"))
+
+ local new_size = self.is_hidden and hidden_size or self.default_size
+ self.container:set_size(new_size.x, new_size.y, gui.PIVOT_N)
+
+ gui.set_enabled(self.content, not self.is_hidden)
+
+ return self
+end
+
+
+return M
\ No newline at end of file
diff --git a/druid/widget/node_repeat/node_repeat.lua b/druid/widget/node_repeat/node_repeat.lua
new file mode 100644
index 0000000..353517d
--- /dev/null
+++ b/druid/widget/node_repeat/node_repeat.lua
@@ -0,0 +1,195 @@
+local helper = require("druid.helper")
+local event_queue = require("druid.event_queue")
+
+---@class druid.node_repeat: druid.widget
+---@field animation table
+---@field node node
+---@field params vector4
+---@field time number
+local M = {}
+
+function M:init(node)
+ self.node = self:get_node(node)
+ self.animation = nil
+ gui.set_material(self.node, hash("gui_repeat"))
+ self.time = 0
+ self.margin = 0
+
+ self.params = gui.get(self.node, "params") --[[@as vector4]]
+ self:get_atlas_path(function(atlas_path)
+ self.is_inited = self:init_tiling_animation(atlas_path)
+ local repeat_x, repeat_y = self:get_repeat()
+ self:animate(repeat_x, repeat_y)
+ end)
+
+ --self.druid.events.on_node_property_changed:subscribe(self.on_node_property_changed, self)
+end
+
+
+function M:on_node_property_changed(node, property)
+ if not self.is_inited or node ~= self.node then
+ return
+ end
+
+ if property == "size" or property == "scale" then
+ local repeat_x, repeat_y = self:get_repeat()
+ self:set_repeat(repeat_x, repeat_y)
+ end
+end
+
+
+function M:get_repeat()
+ if not self.is_inited then
+ return 1, 1
+ end
+ local size_x = gui.get(self.node, helper.PROP_SIZE_X)
+ local size_y = gui.get(self.node, helper.PROP_SIZE_Y)
+ local scale_x = gui.get(self.node, helper.PROP_SCALE_X)
+ local scale_y = gui.get(self.node, helper.PROP_SCALE_Y)
+
+ local repeat_x = (size_x / self.animation.width) / scale_x
+ local repeat_y = (size_y / self.animation.height) / scale_y
+
+ return repeat_x, repeat_y
+end
+
+
+function M:get_atlas_path(callback)
+ event_queue.request("druid.get_atlas_path", callback, gui.get_texture(self.node), msg.url())
+end
+
+
+---@return boolean
+function M:init_tiling_animation(atlas_path)
+ if not atlas_path then
+ print("No atlas path found for node", gui.get_id(self.node), gui.get_texture(self.node))
+ print("Probably you should add druid.script at window collection to access resources")
+ return false
+ end
+
+ self.animation = helper.get_animation_data_from_node(self.node, atlas_path)
+ return true
+end
+
+-- Start our repeat shader work
+-- @param repeat_x -- X factor
+-- @param repeat_y -- Y factor
+function M:animate(repeat_x, repeat_y)
+ if not self.is_inited then
+ return
+ end
+
+ local node = self.node
+ local animation = self.animation
+
+ local frame = animation.frames[1]
+ gui.set(node, "uv_coord", frame.uv_coord)
+ self:set_repeat(repeat_x, repeat_y)
+
+ if #animation.frames > 1 and animation.fps > 0 then
+ animation.handle =
+ timer.delay(1/animation.fps, true, function(self, handle, time_elapsed)
+ local next_rame = animation.frames[animation.current_frame]
+ gui.set(node, "uv_coord", next_rame.uv_coord)
+
+ animation.current_frame = animation.current_frame + 1
+ if animation.current_frame > #animation.frames then
+ animation.current_frame = 1
+ end
+ end)
+ end
+end
+
+
+function M:final()
+ local animation = self.animation
+ if animation.handle then
+ timer.cancel(animation.handle)
+ animation.handle = nil
+ end
+end
+
+
+-- Update repeat factor values
+-- @param repeat_x
+-- @param repeat_y
+function M:set_repeat(repeat_x, repeat_y)
+ local animation = self.animation
+ animation.v.x = repeat_x or animation.v.x
+ animation.v.y = repeat_y or animation.v.y
+
+ local anchor = helper.get_pivot_offset(gui.get_pivot(self.node))
+ animation.v.z = anchor.x
+ animation.v.w = anchor.y
+
+ gui.set(self.node, "uv_repeat", animation.v)
+end
+
+
+function M:set_perpective(perspective_x, perspective_y)
+ if perspective_x then
+ gui.set(self.node, "perspective.x", perspective_x)
+ end
+
+ if perspective_y then
+ gui.set(self.node, "perspective.y", perspective_y)
+ end
+
+ return self
+end
+
+
+function M:set_perpective_offset(offset_x, offset_y)
+ if offset_x then
+ gui.set(self.node, "perspective.z", offset_x)
+ end
+
+ if offset_y then
+ gui.set(self.node, "perspective.w", offset_y)
+ end
+
+ return self
+end
+
+
+function M:set_offset(offset_perc_x, offset_perc_y)
+ self.params.z = offset_perc_x or self.params.z
+ self.params.w = offset_perc_y or self.params.w
+ gui.set(self.node, "params", self.params)
+ return self
+end
+
+
+function M:set_margin(margin_x, margin_y)
+ self.params.x = margin_x or self.params.x
+ self.params.y = margin_y or self.params.y
+ gui.set(self.node, "params", self.params)
+ return self
+end
+
+
+---@param scale number
+function M:set_scale(scale)
+ local current_scale_x = gui.get(self.node, helper.PROP_SCALE_X)
+ local current_scale_y = gui.get(self.node, helper.PROP_SCALE_Y)
+ local current_size_x = gui.get(self.node, helper.PROP_SIZE_X)
+ local current_size_y = gui.get(self.node, helper.PROP_SIZE_Y)
+
+ local delta_scale_x = scale / current_scale_x
+ local delta_scale_y = scale / current_scale_y
+ gui.set(self.node, helper.PROP_SCALE_X, scale)
+ gui.set(self.node, helper.PROP_SCALE_Y, scale)
+ gui.set(self.node, helper.PROP_SIZE_X, current_size_x / delta_scale_x)
+ gui.set(self.node, helper.PROP_SIZE_Y, current_size_y / delta_scale_y)
+
+ --self.druid:on_node_property_changed(self.node, "scale")
+ --self.druid:on_node_property_changed(self.node, "size")
+
+ --local repeat_x, repeat_y = self:get_repeat()
+ --self:set_repeat(repeat_x, repeat_y)
+
+ return self
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_button.gui b/druid/widget/properties_panel/properties/property_button.gui
new file mode 100644
index 0000000..a7e55c8
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_button.gui
@@ -0,0 +1,155 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 350.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Button"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "E_Anchor"
+ pivot: PIVOT_E
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -100.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_BOX
+ texture: "druid/rect_round2_width2"
+ id: "button"
+ parent: "E_Anchor"
+ inherit_alpha: true
+ slice9 {
+ x: 5.0
+ y: 5.0
+ z: 5.0
+ w: 5.0
+ }
+}
+nodes {
+ position {
+ y: -20.0
+ }
+ size {
+ x: 200.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "button"
+ inherit_alpha: true
+}
+nodes {
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 380.0
+ y: 50.0
+ }
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_TEXT
+ text: "Button"
+ font: "druid_text_bold"
+ id: "text_button"
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "button"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_button.lua b/druid/widget/properties_panel/properties/property_button.lua
new file mode 100644
index 0000000..eefa866
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_button.lua
@@ -0,0 +1,58 @@
+local color = require("druid.color")
+
+---@class widget.property_button: druid.widget
+---@field root node
+---@field container druid.container
+---@field text_name druid.text
+---@field button druid.button
+---@field text_button druid.text
+---@field druid druid_instance
+local M = {}
+
+function M:init()
+ self.root = self:get_node("root")
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_then_trim", 0.3)
+
+ self.selected = self:get_node("selected")
+ gui.set_alpha(self.selected, 0)
+
+ self.button = self.druid:new_button("button", self.on_click)
+ self.text_button = self.druid:new_text("text_button")
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name", nil, function(_, size)
+ self.text_button:set_size(size)
+ end)
+ self.container:add_container("E_Anchor")
+end
+
+
+function M:on_click()
+ gui.set_alpha(self.selected, 1)
+ gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
+end
+
+
+---@param text string
+---@return widget.property_button
+function M:set_text_property(text)
+ self.text_name:set_text(text)
+ return self
+end
+
+
+---@param text string
+---@return widget.property_button
+function M:set_text_button(text)
+ self.text_button:set_text(text)
+ return self
+end
+
+
+function M:set_color(color_value)
+ color.set_color(self:get_node("button"), color_value)
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_checkbox.gui b/druid/widget/properties_panel/properties/property_checkbox.gui
new file mode 100644
index 0000000..aeb1180
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_checkbox.gui
@@ -0,0 +1,134 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 360.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Checkbox"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "E_Anchor"
+ pivot: PIVOT_E
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -180.0
+ }
+ size {
+ x: 40.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_BOX
+ texture: "druid/rect_round2_width2"
+ id: "button"
+ parent: "E_Anchor"
+ inherit_alpha: true
+ slice9 {
+ x: 5.0
+ y: 5.0
+ z: 5.0
+ w: 5.0
+ }
+}
+nodes {
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_BOX
+ texture: "druid/ui_circle_16"
+ id: "icon"
+ parent: "button"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ y: -20.0
+ }
+ size {
+ x: 40.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "button"
+ inherit_alpha: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_checkbox.lua b/druid/widget/properties_panel/properties/property_checkbox.lua
new file mode 100644
index 0000000..a0fc7ea
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_checkbox.lua
@@ -0,0 +1,76 @@
+local event = require("event.event")
+
+---@class widget.property_checkbox: druid.widget
+---@field root node
+---@field druid druid_instance
+---@field text_name druid.text
+---@field button druid.button
+---@field selected node
+local M = {}
+
+
+function M:init()
+ self.root = self:get_node("root")
+
+ self.icon = self:get_node("icon")
+ gui.set_enabled(self.icon, false)
+
+ self.selected = self:get_node("selected")
+ gui.set_alpha(self.selected, 0)
+
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_then_trim", 0.3)
+
+ self.button = self.druid:new_button("button", self.on_click)
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name")
+ self.container:add_container("E_Anchor")
+
+ self.on_change_value = event.create()
+end
+
+
+---@param value boolean
+function M:set_value(value, is_instant)
+ if self._value == value then
+ return
+ end
+
+ self._value = value
+ gui.set_enabled(self.icon, value)
+ self.on_change_value:trigger(value)
+
+ if not is_instant then
+ gui.set_alpha(self.selected, 1)
+ gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
+ end
+end
+
+
+---@return boolean
+function M:get_value()
+ return self._value
+end
+
+
+function M:on_click()
+ self:set_value(not self:get_value())
+end
+
+
+--- Set the text property of the checkbox
+---@param text string
+function M:set_text_property(text)
+ self.text_name:set_text(text)
+end
+
+
+--- Set the callback function for when the checkbox value changes
+---@param callback function
+function M:on_change(callback)
+ self.on_change_value:subscribe(callback)
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_input.gui b/druid/widget/properties_panel/properties/property_input.gui
new file mode 100644
index 0000000..c204d30
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_input.gui
@@ -0,0 +1,143 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 350.0
+ y: 50.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Input"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "E_Anchor"
+ pivot: PIVOT_E
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -100.0
+ }
+ type: TYPE_TEMPLATE
+ id: "rich_input"
+ parent: "E_Anchor"
+ inherit_alpha: true
+ template: "/druid/custom/rich_input/rich_input.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "rich_input/root"
+ parent: "rich_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "rich_input/button"
+ parent: "rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "rich_input/placeholder_text"
+ parent: "rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "rich_input/input_text"
+ parent: "rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "rich_input/cursor_node"
+ parent: "rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "rich_input/cursor_text"
+ parent: "rich_input/cursor_node"
+ template_node_child: true
+}
+nodes {
+ position {
+ x: -100.0
+ y: -20.0
+ }
+ size {
+ x: 200.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "E_Anchor"
+ inherit_alpha: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_input.lua b/druid/widget/properties_panel/properties/property_input.lua
new file mode 100644
index 0000000..e09b1f0
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_input.lua
@@ -0,0 +1,46 @@
+---@class widget.property_input: druid.widget
+---@field root node
+---@field container druid.container
+---@field text_name druid.text
+---@field button druid.button
+---@field druid druid_instance
+local M = {}
+
+function M:init()
+ self.root = self:get_node("root")
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_then_trim", 0.3)
+
+ self.selected = self:get_node("selected")
+ gui.set_alpha(self.selected, 0)
+
+ self.rich_input = self.druid:new_rich_input("rich_input")
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name")
+ self.container:add_container("E_Anchor")
+end
+
+
+---@param text string
+---@return widget.property_input
+function M:set_text_property(text)
+ self.text_name:set_text(text)
+ return self
+end
+
+
+---@param text string
+---@return widget.property_input
+function M:set_text_value(text)
+ self.rich_input:set_text(text)
+ return self
+end
+
+
+function M:on_change(callback, callback_context)
+ self.rich_input.input.on_input_unselect:subscribe(callback, callback_context)
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_left_right_selector.gui b/druid/widget/properties_panel/properties/property_left_right_selector.gui
new file mode 100644
index 0000000..69f8b73
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_left_right_selector.gui
@@ -0,0 +1,212 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 360.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Left Right Selector"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "E_Anchor"
+ pivot: PIVOT_E
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -180.0
+ }
+ size {
+ x: 40.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_BOX
+ texture: "druid/rect_round2_width2"
+ id: "button_left"
+ parent: "E_Anchor"
+ inherit_alpha: true
+ slice9 {
+ x: 5.0
+ y: 5.0
+ z: 5.0
+ w: 5.0
+ }
+}
+nodes {
+ rotation {
+ z: 180.0
+ }
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_BOX
+ texture: "druid/icon_arrow"
+ id: "icon_left"
+ parent: "button_left"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ x: -20.0
+ }
+ size {
+ x: 40.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_BOX
+ texture: "druid/rect_round2_width2"
+ id: "button_right"
+ parent: "E_Anchor"
+ inherit_alpha: true
+ slice9 {
+ x: 5.0
+ y: 5.0
+ z: 5.0
+ w: 5.0
+ }
+}
+nodes {
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_BOX
+ texture: "druid/icon_arrow"
+ id: "icon_right"
+ parent: "button_right"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ x: -100.0
+ y: -20.0
+ }
+ size {
+ x: 120.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "E_Anchor"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: -100.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 220.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "42"
+ font: "druid_text_bold"
+ id: "text_value"
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "E_Anchor"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_left_right_selector.lua b/druid/widget/properties_panel/properties/property_left_right_selector.lua
new file mode 100644
index 0000000..6cb79b5
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_left_right_selector.lua
@@ -0,0 +1,211 @@
+local event = require("event.event")
+
+---@class widget.property_left_right_selector: druid.widget
+---@field root node
+---@field druid druid_instance
+---@field text_name druid.text
+---@field button druid.button
+---@field selected node
+---@field value string|number
+---@field on_change_value event fun(value: string|number)
+local M = {}
+
+
+function M:init()
+ self.root = self:get_node("root")
+ self.selected = self:get_node("selected")
+ gui.set_alpha(self.selected, 0)
+
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_then_trim", 0.3)
+
+ self.text_value = self.druid:new_text("text_value")
+ self.button_left = self.druid:new_button("button_left", self.on_button_left)
+ self.button_left.on_repeated_click:subscribe(self.on_button_left, self)
+
+ self.button_right = self.druid:new_button("button_right", self.on_button_right)
+ self.button_right.on_repeated_click:subscribe(self.on_button_right, self)
+
+ self.on_change_value = event.create()
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name")
+ self.container:add_container("E_Anchor")
+end
+
+
+function M:set_text(text)
+ self.text_name:set_text(text)
+ return self
+end
+
+
+---Helper to cycle number in range
+---@param value number Current value
+---@param min number Min range value
+---@param max number Max range value
+---@param step number Step size
+---@param is_loop boolean Is looped
+---@return number Cycled value
+local function step_number(value, min, max, step, is_loop)
+ local range = max - min + 1
+ if is_loop then
+ -- Normalize step within range
+ local effective_step = step
+ if math.abs(step) >= range then
+ effective_step = step % range
+ if effective_step == 0 then
+ effective_step = step > 0 and range or -range
+ end
+ end
+
+ value = value + effective_step
+ -- Handle wrapping
+ if max then
+ while value > max do
+ value = min + (value - max - 1)
+ end
+ end
+ if min then
+ while value < min do
+ value = max - (min - value - 1)
+ end
+ end
+ else
+ -- Clamp values
+ value = value + step
+ if max and value > max then
+ return max
+ elseif min and value < min then
+ return min
+ end
+ end
+ return value
+end
+
+
+---Helper to cycle array index with proper step wrapping
+---@param array table Array to cycle through
+---@param current_value any Current value to find index for
+---@param step number Step direction
+---@param is_loop boolean If true, cycle values. If false, clamp at ends
+---@return any Next value in cycle
+local function step_array(array, current_value, step, is_loop)
+ local index = 1
+ for i, v in ipairs(array) do
+ if v == current_value then
+ index = i
+ break
+ end
+ end
+
+ if is_loop then
+ -- Normalize step within array length
+ local range = #array
+ local effective_step = step
+ if math.abs(step) >= range then
+ effective_step = step % range
+ if effective_step == 0 then
+ effective_step = step > 0 and range or -range
+ end
+ end
+
+ index = index + effective_step
+ -- Handle wrapping
+ while index > range do
+ index = 1 + (index - range - 1)
+ end
+ while index < 1 do
+ index = range - (1 - index - 1)
+ end
+ else
+ -- Clamp values
+ index = index + step
+ if index > #array then
+ index = #array
+ elseif index < 1 then
+ index = 1
+ end
+ end
+
+ return array[index]
+end
+
+
+function M:on_button_left()
+ self:add_step(-1)
+end
+
+function M:on_button_right()
+ self:add_step(1)
+end
+
+
+---@param koef number -1 0 1, on 0 will not move
+function M:add_step(koef)
+ local array_type = self.array_type
+ if array_type then
+ local value = self.value
+ local new_value = step_array(array_type.array, value, koef * array_type.steps, array_type.is_loop)
+ self:set_value(new_value)
+ return
+ end
+
+
+ local number_type = self.number_type
+ if number_type then
+ local value = tonumber(self.value) --[[@as number]]
+ local new_value = step_number(value, number_type.min, number_type.max, koef * number_type.steps, number_type.is_loop)
+ self:set_value(new_value)
+ return
+ end
+end
+
+
+function M:set_number_type(min, max, is_loop, steps)
+ self.number_type = {
+ min = min,
+ max = max,
+ steps = steps or 1,
+ is_loop = is_loop,
+ }
+
+ return self
+end
+
+
+function M:set_array_type(array, is_loop, steps)
+ self.array_type = {
+ array = array,
+ steps = steps or 1,
+ is_loop = is_loop,
+ }
+
+ return self
+end
+
+
+---@param value string|number
+function M:set_value(value, is_instant)
+ if self.value == value then
+ return
+ end
+
+ self.value = value
+ self.text_value:set_text(tostring(value))
+ self.on_change_value:trigger(value)
+
+ if not is_instant then
+ gui.set_alpha(self.selected, 1)
+ gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
+ end
+end
+
+
+---@return string|number
+function M:get_value()
+ return self.value
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_slider.gui b/druid/widget/properties_panel/properties/property_slider.gui
new file mode 100644
index 0000000..4a2f739
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_slider.gui
@@ -0,0 +1,222 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 380.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Slider"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "E_Anchor"
+ pivot: PIVOT_E
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -133.0
+ }
+ size {
+ x: 134.0
+ y: 40.0
+ }
+ color {
+ x: 0.129
+ y: 0.141
+ z: 0.157
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "slider"
+ parent: "E_Anchor"
+ inherit_alpha: true
+}
+nodes {
+ size {
+ x: 134.0
+ y: 8.0
+ }
+ color {
+ x: 0.129
+ y: 0.141
+ z: 0.157
+ }
+ type: TYPE_BOX
+ texture: "druid/ui_circle_8"
+ id: "slider_back"
+ parent: "slider"
+ inherit_alpha: true
+ slice9 {
+ x: 4.0
+ y: 4.0
+ z: 4.0
+ w: 4.0
+ }
+}
+nodes {
+ position {
+ x: -55.0
+ }
+ size {
+ x: 24.0
+ y: 24.0
+ }
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_BOX
+ texture: "druid/ui_circle_8"
+ id: "slider_pin"
+ parent: "slider"
+ inherit_alpha: true
+ slice9 {
+ x: 4.0
+ y: 4.0
+ z: 4.0
+ w: 4.0
+ }
+}
+nodes {
+ size {
+ x: 60.0
+ y: 40.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_BOX
+ texture: "druid/rect_round2_width2"
+ id: "button"
+ pivot: PIVOT_E
+ parent: "E_Anchor"
+ inherit_alpha: true
+ slice9 {
+ x: 4.0
+ y: 4.0
+ z: 4.0
+ w: 4.0
+ }
+}
+nodes {
+ position {
+ y: -20.0
+ }
+ size {
+ x: 60.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected"
+ pivot: PIVOT_SE
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "button"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: -30.0
+ }
+ scale {
+ x: 0.55
+ y: 0.55
+ }
+ size {
+ x: 100.0
+ y: 40.0
+ }
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_TEXT
+ text: "25 %"
+ font: "druid_text_bold"
+ id: "text_value"
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "button"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_slider.lua b/druid/widget/properties_panel/properties/property_slider.lua
new file mode 100644
index 0000000..844cb94
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_slider.lua
@@ -0,0 +1,125 @@
+local event = require("event.event")
+local helper = require("druid.helper")
+
+---@class widget.property_slider: druid.widget
+---@field root node
+---@field container druid.container
+---@field druid druid_instance
+---@field text_name druid.text
+---@field text_value druid.text
+---@field slider druid.slider
+local M = {}
+
+
+function M:init()
+ self.root = self:get_node("root")
+ self.selected = self:get_node("selected")
+ gui.set_alpha(self.selected, 0)
+ self._value = 0
+
+ self.min = 0
+ self.max = 1
+ self.step = 0.01
+
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_then_trim", 0.3)
+
+ self.text_value = self.druid:new_text("text_value")
+ self.slider = self.druid:new_slider("slider_pin", vmath.vector3(55, 0, 0), self.update_value) --[[@as druid.slider]]
+ self.slider:set_input_node("slider")
+
+ self:set_text_function(function(value)
+ return math.floor(value * 100) .. "%"
+ end)
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name")
+ self.container:add_container("E_Anchor")
+
+ self.on_change_value = event.create()
+end
+
+
+---@param callback fun(value:number):string
+function M:set_text_function(callback)
+ self._text_function = callback
+ self.text_value:set_text(self._text_function(self._value))
+end
+
+
+--- Sets the text property of the slider
+---@param text string
+function M:set_text_property(text)
+ self.text_name:set_text(text)
+end
+
+
+--- Sets the callback function for when the slider value changes
+---@param callback fun(value:number)
+function M:on_change(callback)
+ self.on_change_value:subscribe(callback)
+end
+
+
+---@param value number
+function M:set_value(value, is_instant)
+ local diff = math.abs(self.max - self.min)
+ self.slider:set((value - self.min) / diff, true)
+
+ local is_changed = self._value ~= value
+ if not is_changed then
+ return
+ end
+
+ self._value = value
+ self.text_value:set_text(self._text_function(value))
+ self.on_change_value:trigger(value)
+
+ if not is_instant then
+ gui.set_alpha(self.selected, 1)
+ gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
+ end
+end
+
+
+---@return number
+function M:get_value()
+ return self._value
+end
+
+
+function M:update_value(value)
+ local current_value = self._value
+
+ local diff = math.abs(self.max - self.min)
+ -- [0..1] To range
+ value = value * diff + self.min
+
+ -- Round to steps value (0.1, or 5. Should be divided on this value)
+ value = math.floor(value / self.step + 0.5) * self.step
+
+ value = helper.clamp(value, self.min, self.max)
+
+ self:set_value(value)
+end
+
+
+function M:set_number_type(min, max, step)
+ self.min = min or 0
+ self.max = max or 1
+ self.step = step
+
+ self:set_text_function(function(value)
+ return tostring(value)
+ end)
+
+ self:set_value(self._value, true)
+end
+
+
+function M:_on_slider_change_by_user(value)
+ self:set_value(value)
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_text.gui b/druid/widget/properties_panel/properties/property_text.gui
new file mode 100644
index 0000000..1f1af0a
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_text.gui
@@ -0,0 +1,96 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 400.0
+ y: 50.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Text"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 350.0
+ y: 50.0
+ }
+ color {
+ x: 0.722
+ y: 0.741
+ z: 0.761
+ }
+ type: TYPE_TEXT
+ text: "Text"
+ font: "druid_text_bold"
+ id: "text_right"
+ pivot: PIVOT_E
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_text.lua b/druid/widget/properties_panel/properties/property_text.lua
new file mode 100644
index 0000000..cb73678
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_text.lua
@@ -0,0 +1,42 @@
+---@class widget.property_text: druid.widget
+---@field root node
+---@field container druid.container
+---@field text_name druid.text
+---@field text_right druid.text
+local M = {}
+
+function M:init()
+ self.root = self:get_node("root")
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_when_trim_left", 0.3)
+
+ self.text_right = self.druid:new_text("text_right", "")
+ --:set_text_adjust("scale_when_trim_left", 0.3) -- TODO: not works? why?
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name", nil, function(_, size)
+ self.text_name:set_size(size)
+ end)
+ self.container:add_container("text_right", nil, function(_, size)
+ self.text_right:set_size(size)
+ end)
+end
+
+
+---@param text string
+---@return widget.property_text
+function M:set_text_property(text)
+ self.text_name:set_text(text)
+ return self
+end
+
+
+---@param text string|nil
+---@return widget.property_text
+function M:set_text_value(text)
+ self.text_right:set_text(text or "")
+ return self
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties/property_vector3.gui b/druid/widget/properties_panel/properties/property_vector3.gui
new file mode 100644
index 0000000..71b30f2
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_vector3.gui
@@ -0,0 +1,490 @@
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+fonts {
+ name: "druid_text_regular"
+ font: "/druid/fonts/druid_text_regular.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "root"
+ adjust_mode: ADJUST_MODE_STRETCH
+ inherit_alpha: true
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 350.0
+ y: 50.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Vector3"
+ font: "druid_text_bold"
+ id: "text_name"
+ pivot: PIVOT_W
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 200.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "E_Anchor"
+ pivot: PIVOT_E
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ size {
+ x: 66.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "field_x"
+ pivot: PIVOT_W
+ parent: "E_Anchor"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: 7.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 30.0
+ y: 40.0
+ }
+ color {
+ x: 0.31
+ y: 0.318
+ z: 0.322
+ }
+ type: TYPE_TEXT
+ text: "X"
+ font: "druid_text_regular"
+ id: "text_x"
+ parent: "field_x"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 40.0
+ }
+ type: TYPE_TEMPLATE
+ id: "rich_input_x"
+ parent: "field_x"
+ inherit_alpha: true
+ template: "/druid/custom/rich_input/rich_input.gui"
+}
+nodes {
+ size {
+ x: 50.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_x/root"
+ parent: "rich_input_x"
+ overridden_fields: 4
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 50.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_x/button"
+ parent: "rich_input_x/root"
+ overridden_fields: 4
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 70.0
+ y: 50.0
+ }
+ type: TYPE_TEXT
+ id: "rich_input_x/placeholder_text"
+ parent: "rich_input_x/root"
+ overridden_fields: 4
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 70.0
+ y: 50.0
+ }
+ type: TYPE_TEXT
+ text: "20.0"
+ id: "rich_input_x/input_text"
+ parent: "rich_input_x/root"
+ overridden_fields: 4
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ position {
+ x: 18.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_x/cursor_node"
+ parent: "rich_input_x/root"
+ overridden_fields: 1
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "rich_input_x/cursor_text"
+ parent: "rich_input_x/cursor_node"
+ template_node_child: true
+}
+nodes {
+ position {
+ x: 40.0
+ y: -20.0
+ }
+ size {
+ x: 50.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected_x"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "field_x"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: -132.0
+ }
+ size {
+ x: 66.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "field_y"
+ pivot: PIVOT_W
+ parent: "E_Anchor"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: 7.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 30.0
+ y: 40.0
+ }
+ color {
+ x: 0.31
+ y: 0.318
+ z: 0.322
+ }
+ type: TYPE_TEXT
+ text: "Y"
+ font: "druid_text_regular"
+ id: "text_y"
+ parent: "field_y"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 40.0
+ }
+ type: TYPE_TEMPLATE
+ id: "rich_input_y"
+ parent: "field_y"
+ inherit_alpha: true
+ template: "/druid/custom/rich_input/rich_input.gui"
+}
+nodes {
+ size {
+ x: 50.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_y/root"
+ parent: "rich_input_y"
+ overridden_fields: 4
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 50.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_y/button"
+ parent: "rich_input_y/root"
+ overridden_fields: 4
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 70.0
+ y: 50.0
+ }
+ type: TYPE_TEXT
+ id: "rich_input_y/placeholder_text"
+ parent: "rich_input_y/root"
+ overridden_fields: 4
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 70.0
+ y: 50.0
+ }
+ type: TYPE_TEXT
+ text: "20.0"
+ id: "rich_input_y/input_text"
+ parent: "rich_input_y/root"
+ overridden_fields: 4
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ position {
+ x: 18.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_y/cursor_node"
+ parent: "rich_input_y/root"
+ overridden_fields: 1
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "rich_input_y/cursor_text"
+ parent: "rich_input_y/cursor_node"
+ template_node_child: true
+}
+nodes {
+ position {
+ x: 40.0
+ y: -20.0
+ }
+ size {
+ x: 50.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected_y"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "field_y"
+ inherit_alpha: true
+}
+nodes {
+ position {
+ x: -66.0
+ }
+ size {
+ x: 66.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "field_z"
+ pivot: PIVOT_W
+ parent: "E_Anchor"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: 7.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 30.0
+ y: 40.0
+ }
+ color {
+ x: 0.31
+ y: 0.318
+ z: 0.322
+ }
+ type: TYPE_TEXT
+ text: "Z"
+ font: "druid_text_regular"
+ id: "text_z"
+ parent: "field_z"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 40.0
+ }
+ type: TYPE_TEMPLATE
+ id: "rich_input_z"
+ parent: "field_z"
+ inherit_alpha: true
+ template: "/druid/custom/rich_input/rich_input.gui"
+}
+nodes {
+ size {
+ x: 50.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_z/root"
+ parent: "rich_input_z"
+ overridden_fields: 4
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 50.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_z/button"
+ parent: "rich_input_z/root"
+ overridden_fields: 4
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 70.0
+ y: 50.0
+ }
+ type: TYPE_TEXT
+ id: "rich_input_z/placeholder_text"
+ parent: "rich_input_z/root"
+ overridden_fields: 4
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ size {
+ x: 70.0
+ y: 50.0
+ }
+ type: TYPE_TEXT
+ text: "20.0"
+ id: "rich_input_z/input_text"
+ parent: "rich_input_z/root"
+ overridden_fields: 4
+ overridden_fields: 8
+ template_node_child: true
+}
+nodes {
+ position {
+ x: 18.0
+ }
+ type: TYPE_BOX
+ id: "rich_input_z/cursor_node"
+ parent: "rich_input_z/root"
+ overridden_fields: 1
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "rich_input_z/cursor_text"
+ parent: "rich_input_z/cursor_node"
+ template_node_child: true
+}
+nodes {
+ position {
+ x: 40.0
+ y: -20.0
+ }
+ size {
+ x: 50.0
+ y: 4.0
+ }
+ color {
+ x: 0.894
+ y: 0.506
+ z: 0.333
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "selected_z"
+ pivot: PIVOT_S
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "field_z"
+ inherit_alpha: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties/property_vector3.lua b/druid/widget/properties_panel/properties/property_vector3.lua
new file mode 100644
index 0000000..56ccf9d
--- /dev/null
+++ b/druid/widget/properties_panel/properties/property_vector3.lua
@@ -0,0 +1,75 @@
+local event = require("event.event")
+
+
+---@class widget.property_vector3: druid.widget
+---@field root node
+---@field container druid.container
+---@field text_name druid.text
+---@field button druid.button
+---@field druid druid_instance
+local M = {}
+
+function M:init()
+ self.root = self:get_node("root")
+ self.text_name = self.druid:new_text("text_name")
+ :set_text_adjust("scale_then_trim", 0.3)
+
+ self.selected_x = self:get_node("selected_x")
+ gui.set_alpha(self.selected_x, 0)
+
+ self.selected_y = self:get_node("selected_y")
+ gui.set_alpha(self.selected_y, 0)
+
+ self.selected_z = self:get_node("selected_z")
+ gui.set_alpha(self.selected_z, 0)
+
+ self.rich_input_x = self.druid:new_rich_input("rich_input_x")
+ self.rich_input_y = self.druid:new_rich_input("rich_input_y")
+ self.rich_input_z = self.druid:new_rich_input("rich_input_z")
+
+ self.value = vmath.vector3(0)
+
+ self.rich_input_x.input.on_input_unselect:subscribe(function()
+ self.value.x = tonumber(self.rich_input_x.input:get_text()) or 0
+ self.on_change:trigger(self.value)
+ end)
+
+ self.rich_input_y.input.on_input_unselect:subscribe(function()
+ self.value.y = tonumber(self.rich_input_y.input:get_text()) or 0
+ self.on_change:trigger(self.value)
+ end)
+
+ self.rich_input_z.input.on_input_unselect:subscribe(function()
+ self.value.z = tonumber(self.rich_input_z.input:get_text()) or 0
+ self.on_change:trigger(self.value)
+ end)
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("text_name")
+ self.container:add_container("E_Anchor")
+
+ self.on_change = event.create()
+end
+
+
+---@param text string
+---@return widget.property_vector3
+function M:set_text_property(text)
+ self.text_name:set_text(text)
+ return self
+end
+
+
+---@param x number
+---@param y number
+---@param z number
+---@return widget.property_vector3
+function M:set_value(x, y, z)
+ self.rich_input_x:set_text(tostring(x))
+ self.rich_input_y:set_text(tostring(y))
+ self.rich_input_z:set_text(tostring(z))
+ return self
+end
+
+
+return M
diff --git a/druid/widget/properties_panel/properties_panel.gui b/druid/widget/properties_panel/properties_panel.gui
new file mode 100644
index 0000000..7ba5a5c
--- /dev/null
+++ b/druid/widget/properties_panel/properties_panel.gui
@@ -0,0 +1,702 @@
+fonts {
+ name: "druid_text_regular"
+ font: "/druid/fonts/druid_text_regular.font"
+}
+fonts {
+ name: "druid_text_bold"
+ font: "/druid/fonts/druid_text_bold.font"
+}
+textures {
+ name: "druid"
+ texture: "/druid/druid.atlas"
+}
+nodes {
+ size {
+ x: 400.0
+ y: 240.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid/ui_circle_16"
+ id: "root"
+ inherit_alpha: true
+ slice9 {
+ x: 8.0
+ y: 8.0
+ z: 8.0
+ w: 8.0
+ }
+}
+nodes {
+ position {
+ y: 120.0
+ }
+ size {
+ x: 400.0
+ y: 40.0
+ }
+ type: TYPE_BOX
+ id: "header"
+ pivot: PIVOT_N
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -192.0
+ y: -8.0
+ }
+ scale {
+ x: 0.5
+ y: 0.5
+ }
+ size {
+ x: 500.0
+ y: 50.0
+ }
+ color {
+ x: 0.463
+ y: 0.475
+ z: 0.49
+ }
+ type: TYPE_TEXT
+ text: "Properties"
+ font: "druid_text_regular"
+ id: "text_header"
+ pivot: PIVOT_NW
+ outline {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ shadow {
+ x: 1.0
+ y: 1.0
+ z: 1.0
+ }
+ parent: "header"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: 192.0
+ y: -4.0
+ }
+ color {
+ x: 0.306
+ y: 0.31
+ z: 0.314
+ }
+ type: TYPE_BOX
+ texture: "druid/icon_drag"
+ id: "icon_drag"
+ pivot: PIVOT_NE
+ parent: "header"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ y: -120.0
+ }
+ size {
+ x: 400.0
+ y: 190.0
+ }
+ type: TYPE_BOX
+ id: "content"
+ pivot: PIVOT_S
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -200.0
+ y: 190.0
+ }
+ size {
+ x: 400.0
+ y: 190.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "scroll_view"
+ xanchor: XANCHOR_LEFT
+ pivot: PIVOT_NW
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "content"
+ inherit_alpha: true
+ clipping_mode: CLIPPING_MODE_STENCIL
+}
+nodes {
+ size {
+ x: 400.0
+ y: 190.0
+ }
+ type: TYPE_BOX
+ texture: "druid/pixel"
+ id: "scroll_content"
+ pivot: PIVOT_NW
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "scroll_view"
+ inherit_alpha: true
+ slice9 {
+ x: 8.0
+ y: 8.0
+ w: 6.0
+ }
+ visible: false
+}
+nodes {
+ position {
+ y: 170.0
+ }
+ type: TYPE_BOX
+ texture: "druid/empty"
+ id: "propeties"
+ parent: "content"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "property_slider"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_slider.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/root"
+ parent: "property_slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_slider/text_name"
+ parent: "property_slider/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/E_Anchor"
+ parent: "property_slider/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/slider"
+ parent: "property_slider/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/slider_back"
+ parent: "property_slider/slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/slider_pin"
+ parent: "property_slider/slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/button"
+ parent: "property_slider/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_slider/selected"
+ parent: "property_slider/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_slider/text_value"
+ parent: "property_slider/button"
+ template_node_child: true
+}
+nodes {
+ position {
+ y: -50.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_checkbox"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_checkbox.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_checkbox/root"
+ parent: "property_checkbox"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_checkbox/text_name"
+ parent: "property_checkbox/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_checkbox/E_Anchor"
+ parent: "property_checkbox/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_checkbox/button"
+ parent: "property_checkbox/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_checkbox/icon"
+ parent: "property_checkbox/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_checkbox/selected"
+ parent: "property_checkbox/button"
+ template_node_child: true
+}
+nodes {
+ position {
+ y: -100.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_button"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_button.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_button/root"
+ parent: "property_button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_button/text_name"
+ parent: "property_button/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_button/E_Anchor"
+ parent: "property_button/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_button/button"
+ parent: "property_button/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_button/selected"
+ parent: "property_button/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_button/text_button"
+ parent: "property_button/button"
+ template_node_child: true
+}
+nodes {
+ position {
+ y: -150.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_input"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_input.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/root"
+ parent: "property_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/text_name"
+ parent: "property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/E_Anchor"
+ parent: "property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "property_input/rich_input"
+ parent: "property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/rich_input/root"
+ parent: "property_input/rich_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/rich_input/button"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/rich_input/placeholder_text"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/rich_input/input_text"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/rich_input/cursor_node"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/rich_input/cursor_text"
+ parent: "property_input/rich_input/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/selected"
+ parent: "property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ position {
+ y: -200.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_text"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_text.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_text/root"
+ parent: "property_text"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_text/text_name"
+ parent: "property_text/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_text/text_right"
+ parent: "property_text/root"
+ template_node_child: true
+}
+nodes {
+ position {
+ y: -250.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_left_right_selector"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_left_right_selector.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/root"
+ parent: "property_left_right_selector"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_left_right_selector/text_name"
+ parent: "property_left_right_selector/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/E_Anchor"
+ parent: "property_left_right_selector/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/button_left"
+ parent: "property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/icon_left"
+ parent: "property_left_right_selector/button_left"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/button_right"
+ parent: "property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/icon_right"
+ parent: "property_left_right_selector/button_right"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_left_right_selector/selected"
+ parent: "property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_left_right_selector/text_value"
+ parent: "property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ position {
+ y: -300.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_vector3"
+ parent: "propeties"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_vector3.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/root"
+ parent: "property_vector3"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/text_name"
+ parent: "property_vector3/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/E_Anchor"
+ parent: "property_vector3/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/field_x"
+ parent: "property_vector3/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/text_x"
+ parent: "property_vector3/field_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "property_vector3/rich_input_x"
+ parent: "property_vector3/field_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_x/root"
+ parent: "property_vector3/rich_input_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_x/button"
+ parent: "property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_x/placeholder_text"
+ parent: "property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_x/input_text"
+ parent: "property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_x/cursor_node"
+ parent: "property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_x/cursor_text"
+ parent: "property_vector3/rich_input_x/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/selected_x"
+ parent: "property_vector3/field_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/field_y"
+ parent: "property_vector3/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/text_y"
+ parent: "property_vector3/field_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "property_vector3/rich_input_y"
+ parent: "property_vector3/field_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_y/root"
+ parent: "property_vector3/rich_input_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_y/button"
+ parent: "property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_y/placeholder_text"
+ parent: "property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_y/input_text"
+ parent: "property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_y/cursor_node"
+ parent: "property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_y/cursor_text"
+ parent: "property_vector3/rich_input_y/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/selected_y"
+ parent: "property_vector3/field_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/field_z"
+ parent: "property_vector3/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/text_z"
+ parent: "property_vector3/field_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "property_vector3/rich_input_z"
+ parent: "property_vector3/field_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_z/root"
+ parent: "property_vector3/rich_input_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_z/button"
+ parent: "property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_z/placeholder_text"
+ parent: "property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_z/input_text"
+ parent: "property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/rich_input_z/cursor_node"
+ parent: "property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_vector3/rich_input_z/cursor_text"
+ parent: "property_vector3/rich_input_z/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_vector3/selected_z"
+ parent: "property_vector3/field_z"
+ template_node_child: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/druid/widget/properties_panel/properties_panel.lua b/druid/widget/properties_panel/properties_panel.lua
new file mode 100644
index 0000000..cae5d3f
--- /dev/null
+++ b/druid/widget/properties_panel/properties_panel.lua
@@ -0,0 +1,319 @@
+local property_checkbox = require("druid.widget.properties_panel.properties.property_checkbox")
+local property_slider = require("druid.widget.properties_panel.properties.property_slider")
+local property_button = require("druid.widget.properties_panel.properties.property_button")
+local property_input = require("druid.widget.properties_panel.properties.property_input")
+local property_text = require("druid.widget.properties_panel.properties.property_text")
+local property_left_right_selector = require("druid.widget.properties_panel.properties.property_left_right_selector")
+local property_vector3 = require("druid.widget.properties_panel.properties.property_vector3")
+
+---@class widget.properties_panel: druid.widget
+---@field root node
+---@field scroll druid.scroll
+---@field layout druid.layout
+---@field container druid.container
+---@field container_content druid.container
+---@field container_scroll_view druid.container
+---@field contaienr_scroll_content druid.container
+---@field text_header druid.text
+---@field paginator widget.property_left_right_selector
+---@field properties druid.widget[] List of created properties
+---@field properties_constructors fun()[] List of properties functions to create a new widget. Used to not spawn non-visible widgets but keep the reference
+local M = {}
+
+
+function M:init()
+ self.root = self:get_node("root")
+ self.content = self:get_node("content")
+
+ self.container = self.druid:new_container(self.root)
+ self.container:add_container("header")
+ self.container_content = self.container:add_container("content")
+ self.container_scroll_view = self.container_content:add_container("scroll_view")
+ self.contaienr_scroll_content = self.container_scroll_view:add_container("scroll_content")
+
+ self.default_size = self.container:get_size()
+
+ self.properties = {}
+ self.properties_constructors = {}
+ self.current_page = 1
+ self.properties_per_page = 15
+
+ self.text_header = self.druid:new_text("text_header")
+ self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
+ self.layout = self.druid:new_layout("scroll_content", "vertical")
+ :set_hug_content(false, true)
+ :set_padding(nil, 0)
+
+ self.layout.on_size_changed:subscribe(self.on_size_changed, self)
+
+ self.druid:new_drag("header", self.on_drag_widget)
+ self.druid:new_button("icon_drag", self.toggle_hide)
+ :set_style(nil)
+
+ self.property_checkbox_prefab = self:get_node("property_checkbox/root")
+ gui.set_enabled(self.property_checkbox_prefab, false)
+
+ self.property_slider_prefab = self:get_node("property_slider/root")
+ gui.set_enabled(self.property_slider_prefab, false)
+
+ self.property_button_prefab = self:get_node("property_button/root")
+ gui.set_enabled(self.property_button_prefab, false)
+
+ self.property_input_prefab = self:get_node("property_input/root")
+ gui.set_enabled(self.property_input_prefab, false)
+
+ self.property_text_prefab = self:get_node("property_text/root")
+ gui.set_enabled(self.property_text_prefab, false)
+
+ self.property_left_right_selector_prefab = self:get_node("property_left_right_selector/root")
+ gui.set_enabled(self.property_left_right_selector_prefab, false)
+
+ self.property_vector3_prefab = self:get_node("property_vector3/root")
+ gui.set_enabled(self.property_vector3_prefab, false)
+
+ -- We not using as a part of properties, since it handled in a way to be paginable
+ self.paginator = self.druid:new_widget(property_left_right_selector, "property_left_right_selector", self.property_left_right_selector_prefab)
+ self.paginator:set_text("Page")
+ self.paginator:set_number_type(1, 1, true)
+ self.paginator:set_value(self.current_page)
+ self.paginator.on_change_value:subscribe(function(value)
+ self:set_page(value)
+ end)
+ local width = self.layout:get_content_size()
+ self.paginator.container:set_size(width)
+
+ gui.set_enabled(self.paginator.root, false)
+end
+
+
+function M:on_remove()
+ self:clear()
+end
+
+
+function M:on_drag_widget(dx, dy)
+ local position = self.container:get_position()
+ self.container:set_position(position.x + dx, position.y + dy)
+end
+
+
+function M:clear_created_properties()
+ for index = 1, #self.properties do
+ local property = self.properties[index]
+
+ -- If prefab used clone nodes we can remove it
+ if property:get_nodes() then
+ gui.delete_node(property.root)
+ else
+ -- Probably we have component placed on scene directly
+ gui.set_enabled(property.root, false)
+ end
+
+ self.druid:remove(self.properties[index])
+ end
+ self.properties = {}
+
+ self.layout:clear_layout()
+
+ -- Use paginator as "pinned" widget
+ self.layout:add(self.paginator.root)
+end
+
+
+function M:clear()
+ self:clear_created_properties()
+ self.properties_constructors = {}
+end
+
+
+function M:on_size_changed(new_size)
+ self.container_content:set_size(new_size.x, new_size.y, gui.PIVOT_N)
+
+ self.default_size = vmath.vector3(new_size.x, new_size.y + 50, 0)
+ if not self.is_hidden then
+ self.container:set_size(self.default_size.x, self.default_size.y, gui.PIVOT_N)
+ end
+
+ local width = self.layout:get_size().x - self.layout.padding.x - self.layout.padding.z
+ for index = 1, #self.properties do
+ local property = self.properties[index]
+ if property.container then
+ property.container:set_size(width)
+ end
+ end
+ self.paginator.container:set_size(width)
+end
+
+
+function M:update(dt)
+ if self.is_dirty then
+ self.is_dirty = false
+
+ self:clear_created_properties()
+
+ local properties_count = #self.properties_constructors
+
+ -- Render all current properties
+ local start_index = (self.current_page - 1) * self.properties_per_page + 1
+ local end_index = start_index + self.properties_per_page - 1
+ end_index = math.min(end_index, properties_count)
+
+ local is_paginator_visible = properties_count > self.properties_per_page
+ gui.set_enabled(self.paginator.root, is_paginator_visible)
+ self.paginator:set_number_type(1, math.ceil(properties_count / self.properties_per_page), true)
+ self.paginator.text_value:set_text(self.current_page .. " / " .. math.ceil(properties_count / self.properties_per_page))
+
+ for index = start_index, end_index do
+ self.properties_constructors[index]()
+ end
+ end
+end
+
+
+---@param on_create fun(checkbox: widget.property_checkbox)|nil
+---@return widget.properties_panel
+function M:add_checkbox(on_create)
+ return self:add_inner_widget(property_checkbox, "property_checkbox", self.property_checkbox_prefab, on_create)
+end
+
+
+---@param on_create fun(slider: widget.property_slider)|nil
+---@return widget.properties_panel
+function M:add_slider(on_create)
+ return self:add_inner_widget(property_slider, "property_slider", self.property_slider_prefab, on_create)
+end
+
+
+---@param on_create fun(button: widget.property_button)|nil
+---@return widget.properties_panel
+function M:add_button(on_create)
+ return self:add_inner_widget(property_button, "property_button", self.property_button_prefab, on_create)
+end
+
+
+---@param on_create fun(input: widget.property_input)|nil
+---@return widget.properties_panel
+function M:add_input(on_create)
+ return self:add_inner_widget(property_input, "property_input", self.property_input_prefab, on_create)
+end
+
+
+---@param on_create fun(text: widget.property_text)|nil
+function M:add_text(on_create)
+ return self:add_inner_widget(property_text, "property_text", self.property_text_prefab, on_create)
+end
+
+
+---@param on_create fun(selector: widget.property_left_right_selector)|nil
+function M:add_left_right_selector(on_create)
+ return self:add_inner_widget(property_left_right_selector, "property_left_right_selector", self.property_left_right_selector_prefab, on_create)
+end
+
+
+---@param on_create fun(vector3: widget.property_vector3)|nil
+function M:add_vector3(on_create)
+ return self:add_inner_widget(property_vector3, "property_vector3", self.property_vector3_prefab, on_create)
+end
+
+
+---@generic T: druid.widget
+---@param widget_class T
+---@param template string|nil
+---@param nodes table|node|nil
+---@param on_create fun(widget: T)|nil
+---@return widget.properties_panel
+function M:add_inner_widget(widget_class, template, nodes, on_create)
+ table.insert(self.properties_constructors, function()
+ local widget = self.druid:new_widget(widget_class, template, nodes)
+
+ self:add_property(widget)
+ if on_create then
+ on_create(widget)
+ end
+ end)
+
+ self.is_dirty = true
+
+ return self
+end
+
+
+---@param create_widget_callback fun(): druid.widget
+---@return widget.properties_panel
+function M:add_widget(create_widget_callback)
+ table.insert(self.properties_constructors, function()
+ local widget = create_widget_callback()
+ self:add_property(widget)
+ end)
+
+ self.is_dirty = true
+
+ return self
+end
+
+
+---@private
+function M:create_from_prefab(widget_class, template, nodes)
+ return self:add_property(self.druid:new_widget(widget_class, template, nodes))
+end
+
+
+---@private
+function M:add_property(widget)
+ gui.set_enabled(widget.root, true)
+ table.insert(self.properties, widget)
+ local width = self.layout:get_content_size()
+ widget.container:set_size(width)
+
+ self.layout:add(widget.root)
+
+ return widget
+end
+
+
+function M:remove(widget)
+ for index = 1, #self.properties do
+ if self.properties[index] == widget then
+ self.druid:remove(widget)
+ self.layout:remove(widget.root)
+
+ -- If prefab used clone nodes we can remove it
+ if widget:get_nodes() then
+ gui.delete_node(widget.root)
+ else
+ -- Probably we have component placed on scene directly
+ gui.set_enabled(widget.root, false)
+ end
+
+ table.remove(self.properties, index)
+ break
+ end
+ end
+end
+
+
+function M:toggle_hide()
+ self.is_hidden = not self.is_hidden
+ local hidden_size = gui.get_size(self:get_node("header"))
+
+ local new_size = self.is_hidden and hidden_size or self.default_size
+ self.container:set_size(new_size.x, new_size.y, gui.PIVOT_N)
+
+ gui.set_enabled(self.content, not self.is_hidden)
+ return self
+end
+
+
+---@param properties_per_page number
+function M:set_properties_per_page(properties_per_page)
+ self.properties_per_page = properties_per_page
+end
+
+
+function M:set_page(page)
+ self.current_page = page
+ self.is_dirty = true
+end
+
+
+return M
diff --git a/example/assets/druid.atlas b/example/assets/druid_example.atlas
similarity index 100%
rename from example/assets/druid.atlas
rename to example/assets/druid_example.atlas
diff --git a/example/components/druid_logo/druid_logo.gui b/example/components/druid_logo/druid_logo.gui
index 15b549d..7680ab4 100644
--- a/example/components/druid_logo/druid_logo.gui
+++ b/example/components/druid_logo/druid_logo.gui
@@ -1,4 +1,3 @@
-script: ""
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
@@ -8,434 +7,129 @@ textures {
texture: "/example/assets/druid_logo.atlas"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 170.0
- z: 0.0
- w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 200.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 16.0
y: 16.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "E_Anchor"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_E
adjust_mode: ADJUST_MODE_STRETCH
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: 10.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
texture: "druid_logo/icon_druid"
id: "icon_druid_right"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "E_Anchor"
layer: "druid_logo"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
alpha: 0.5
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -200.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 16.0
y: 16.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "W_Anchor"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_STRETCH
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: -10.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
texture: "druid_logo/icon_druid"
id: "icon_druid_left"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "W_Anchor"
layer: "druid_logo"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
alpha: 0.5
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
texture: "druid_logo/logo_druid"
id: "icon_logo"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "druid_logo"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -50.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.6
y: 0.6
- z: 1.0
- w: 1.0
}
size {
x: 400.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Defold UI Framework"
font: "text_regular"
id: "text_description"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_regular"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -448,4 +142,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/druid_logo/druid_logo.lua b/example/components/druid_logo/druid_logo.lua
index 4784a80..c2eb7d2 100644
--- a/example/components/druid_logo/druid_logo.lua
+++ b/example/components/druid_logo/druid_logo.lua
@@ -2,7 +2,6 @@ local panthera = require("panthera.panthera")
local component = require("druid.component")
local druid_logo_panthera = require("example.components.druid_logo.druid_logo_panthera")
-local container = require("example.components.container.container")
---@class druid_logo: druid.base_component
---@field root druid.container
@@ -16,7 +15,7 @@ local DruidLogo = component.create("druid_logo")
function DruidLogo:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.root:add_container("E_Anchor")
self.root:add_container("W_Anchor")
diff --git a/example/components/example_scene/example_scene.lua b/example/components/example_scene/example_scene.lua
index a237456..394ccc1 100644
--- a/example/components/example_scene/example_scene.lua
+++ b/example/components/example_scene/example_scene.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local container = require("example.components.container.container")
---@class example_scene: druid.base_component
---@field root druid.container
@@ -14,7 +13,7 @@ local M = component.create("example_scene")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.root:add_container("text_debug_info")
self.root:add_container("text_gui_path")
@@ -25,7 +24,7 @@ end
---@param info string
function M:set_debug_info(info)
- self.text_debug_info:set_to(info)
+ self.text_debug_info:set_text(info)
end
@@ -35,7 +34,7 @@ function M:set_gui_path(path)
-- We need add "/" before path and replace .lua to .gui
path = "/" .. path:gsub(".lua", ".gui")
- self.text_gui_path:set_to(path)
+ self.text_gui_path:set_text(path)
end
diff --git a/example/components/examples_list_view/examples_list_view.gui b/example/components/examples_list_view/examples_list_view.gui
index 750684c..cadc473 100644
--- a/example/components/examples_list_view/examples_list_view.gui
+++ b/example/components/examples_list_view/examples_list_view.gui
@@ -1,605 +1,110 @@
-script: ""
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 910.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -190.0
y: 445.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.9
y: 0.9
- z: 1.0
- w: 1.0
}
size {
x: 250.0
y: 60.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Examples"
font: "text_regular"
id: "text_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_regular"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -200.0
y: 395.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 400.0
y: 850.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
parent: "root"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 850.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
parent: "scroll_view"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -52.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "examples_list_view_item"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/components/examples_list_view/examples_list_view_item.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 400.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.173
- y: 0.184
- z: 0.204
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "examples_list_view_item/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "examples_list_view_item"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 400.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
- id: "examples_list_view_item/panel_highlight"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
- parent: "examples_list_view_item/root"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 0.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 4.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.894
- y: 0.506
- z: 0.333
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
- id: "examples_list_view_item/panel_selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
- parent: "examples_list_view_item/root"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: false
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 18.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.6
- y: 0.6
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.851
- y: 0.851
- z: 0.851
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_arrow"
- id: "examples_list_view_item/icon"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "examples_list_view_item/root"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: false
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 36.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.7
- y: 0.7
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 60.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Basic"
- font: "text_bold"
- id: "examples_list_view_item/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 0.941
- y: 0.984
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "examples_list_view_item/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -609,4 +114,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/examples_list_view/examples_list_view.lua b/example/components/examples_list_view/examples_list_view.lua
index 7f66b4d..d5f98d2 100644
--- a/example/components/examples_list_view/examples_list_view.lua
+++ b/example/components/examples_list_view/examples_list_view.lua
@@ -1,7 +1,5 @@
-local event = require("druid.event")
+local event = require("event.event")
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
local storage = require("saver.storage")
local examples_list_view_item = require("example.components.examples_list_view.examples_list_view_item")
@@ -10,7 +8,7 @@ local examples_list_view_item = require("example.components.examples_list_view.e
---@field root druid.container
---@field druid druid_instance
---@field scroll druid.scroll
----@field grid druid.static_grid
+---@field grid druid.grid
local M = component.create("examples_list_view")
@@ -19,17 +17,17 @@ local M = component.create("examples_list_view")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.root:add_container("text_header")
- self.druid:new(lang_text, "text_header", "ui_examples")
+ self.druid:new_lang_text("text_header", "ui_examples")
self.druid:new(examples_list_view_item, "examples_list_view_item")
self.prefab = self:get_node("examples_list_view_item/root")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
- self.grid = self.druid:new_static_grid("scroll_content", self.prefab, 1)
+ self.grid = self.druid:new_grid("scroll_content", self.prefab, 1)
self.scroll:bind_grid(self.grid)
self.root:add_container("scroll_view", nil, function(_, size)
@@ -39,9 +37,9 @@ function M:init(template, nodes)
self.selected_example = nil
self.examples = {}
- self.on_debug_info = event()
- self.on_set_information = event()
- self.add_log_text = event()
+ self.on_debug_info = event.create()
+ self.on_set_information = event.create()
+ self.add_log_text = event.create()
timer.delay(0.1, true, function()
self:update_debug_info()
@@ -90,7 +88,13 @@ function M:add_example(examples, druid_example)
local root = gui.get_node(example_data.root)
gui.set_enabled(root, true)
- local instance = druid_example.druid:new(example_data.component_class, example_data.template)
+
+ local instance
+ if example_data.widget_class then
+ instance = druid_example.druid:new_widget(example_data.widget_class, example_data.template)
+ else
+ instance = druid_example.druid:new(example_data.component_class, example_data.template)
+ end
self.selected_example = {
data = example_data,
diff --git a/example/components/examples_list_view/examples_list_view_item.gui b/example/components/examples_list_view/examples_list_view_item.gui
index 2cef928..b562ad0 100644
--- a/example/components/examples_list_view/examples_list_view_item.gui
+++ b/example/components/examples_list_view/examples_list_view_item.gui
@@ -1,319 +1,127 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_STRETCH
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "panel_highlight"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
alpha: 0.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 4.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.894
y: 0.506
z: 0.333
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "panel_selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
enabled: false
- visible: true
- material: ""
}
nodes {
position {
x: 18.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.6
y: 0.6
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
}
color {
x: 0.851
y: 0.851
z: 0.851
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_arrow"
+ texture: "druid_example/icon_arrow"
id: "icon"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
enabled: false
- visible: true
- material: ""
}
nodes {
position {
x: 36.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.7
y: 0.7
- z: 1.0
- w: 1.0
}
size {
x: 500.0
y: 60.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Basic"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 0.941
y: 0.984
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -323,4 +131,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/examples_list_view/examples_list_view_item.lua b/example/components/examples_list_view/examples_list_view_item.lua
index 4793fb5..1b4edc1 100644
--- a/example/components/examples_list_view/examples_list_view_item.lua
+++ b/example/components/examples_list_view/examples_list_view_item.lua
@@ -1,12 +1,10 @@
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
---@class examples_list_view_item: druid.base_component
---@field root druid.container
---@field text druid.lang_text
---@field druid druid_instance
----@field on_click druid.event
+---@field on_click event
local M = component.create("examples_list_view_item")
---@param template string
@@ -14,8 +12,8 @@ local M = component.create("examples_list_view_item")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
- self.text = self.druid:new(lang_text, "text") --[[ @as druid.lang_text]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
+ self.text = self.druid:new_lang_text("text") --[[ @as druid.lang_text]]
self.icon = self:get_node("icon")
self.selected = self:get_node("panel_selected")
self.highlight = self:get_node("panel_highlight")
diff --git a/example/components/output_list/output_list.gui b/example/components/output_list/output_list.gui
index 5063895..19456e3 100644
--- a/example/components/output_list/output_list.gui
+++ b/example/components/output_list/output_list.gui
@@ -7,8 +7,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -21,7 +21,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "root"
adjust_mode: ADJUST_MODE_STRETCH
layer: "druid"
@@ -76,7 +76,7 @@ nodes {
y: 190.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_view"
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
@@ -91,7 +91,7 @@ nodes {
y: 190.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_content"
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
@@ -150,7 +150,7 @@ nodes {
z: 0.157
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "separator"
pivot: PIVOT_N
parent: "root"
diff --git a/example/components/output_list/output_list.lua b/example/components/output_list/output_list.lua
index 3dabc2a..c7e0802 100644
--- a/example/components/output_list/output_list.lua
+++ b/example/components/output_list/output_list.lua
@@ -1,6 +1,4 @@
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
---@class output_list: druid.base_component
---@field root druid.container
@@ -14,7 +12,7 @@ local M = component.create("output_list")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.root:add_container("text_header")
self.root:add_container("separator")
@@ -22,12 +20,12 @@ function M:init(template, nodes)
self.prefab = self:get_node("text")
gui.set_enabled(self.prefab, false)
- self.grid = self.druid:new_static_grid("scroll_content", "text", 1)
+ self.grid = self.druid:new_grid("scroll_content", "text", 1)
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
self.scroll:bind_grid(self.grid)
self.scroll:set_horizontal_scroll(false)
- self.druid:new(lang_text, "text_header", "ui_output")
+ self.druid:new_lang_text("text_header", "ui_output")
local defold_version = sys.get_engine_info().version
gui.set_text(self:get_node("text_version_defold"), "Defold v" .. defold_version)
diff --git a/example/components/panel_druid_profiler/panel_druid_profiler.gui b/example/components/panel_druid_profiler/panel_druid_profiler.gui
index e157c46..3824272 100644
--- a/example/components/panel_druid_profiler/panel_druid_profiler.gui
+++ b/example/components/panel_druid_profiler/panel_druid_profiler.gui
@@ -1,981 +1,385 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1080.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
+ texture: "druid_example/pixel"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+}
+nodes {
+ size {
+ x: 1040.0
+ y: 50.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
+ type: TYPE_BOX
+ id: "layout"
+ xanchor: XANCHOR_LEFT
+ adjust_mode: ADJUST_MODE_STRETCH
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
}
nodes {
position {
x: -530.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 16.0
y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "group_memory"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
- parent: "root"
- layer: ""
+ parent: "layout"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: 89.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.306
y: 0.31
z: 0.314
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Memory"
font: "text_bold"
id: "text_memory"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_memory"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 199.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "2048"
font: "text_bold"
id: "text_memory_amount"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_memory"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 273.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.306
y: 0.31
z: 0.314
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "KB"
font: "text_bold"
id: "text_memory_kb"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_memory"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: -130.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: -31.0
}
size {
x: 16.0
y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "group_fps"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "root"
- layer: ""
+ parent: "layout"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: -50.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 120.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.306
y: 0.31
z: 0.314
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "FPS"
font: "text_bold"
id: "text_fps"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_fps"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 17.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "60"
font: "text_bold"
id: "text_fps_amount"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_S
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_fps"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 65.0
y: -17.5
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.6
y: 0.6
- z: 1.0
- w: 1.0
}
size {
x: 100.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "/60"
font: "text_bold"
id: "text_fps_min"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_S
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_fps"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 130.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
+ x: 355.0
}
size {
x: 16.0
y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "group_components"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "root"
- layer: ""
+ parent: "layout"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: -50.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 350.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.306
y: 0.31
z: 0.314
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Components"
font: "text_bold"
id: "text_components"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_components"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 90.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.8
y: 0.8
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "2004"
font: "text_bold"
id: "text_components_amount"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "group_components"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 530.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 16.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
- id: "group_events"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_E
- adjust_mode: ADJUST_MODE_FIT
- parent: "root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: -163.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.8
- y: 0.8
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.306
- y: 0.31
- z: 0.314
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Events"
- font: "text_bold"
- id: "text_events"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "group_events"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -59.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.8
- y: 0.8
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "6000"
- font: "text_bold"
- id: "text_events_amount"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "group_events"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -985,4 +389,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/panel_druid_profiler/panel_druid_profiler.lua b/example/components/panel_druid_profiler/panel_druid_profiler.lua
index 974aaf3..233e50b 100644
--- a/example/components/panel_druid_profiler/panel_druid_profiler.lua
+++ b/example/components/panel_druid_profiler/panel_druid_profiler.lua
@@ -1,8 +1,6 @@
-local event = require("druid.event")
+local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
---@class panel_druid_profiler: druid.base_component
@@ -16,29 +14,34 @@ local FPS_SAMPLES = 60
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.group_memory = self.root:add_container("group_memory")
self.group_fps = self.root:add_container("group_fps")
self.group_components = self.root:add_container("group_components")
- self.group_events = self.root:add_container("group_events")
+
+ self.root:add_container("layout", nil, function()
+ self.layout:set_dirty()
+ end)
+ self.layout = self.druid:new_layout("layout", "horizontal")
+ self.layout:add(self.group_memory.node)
+ self.layout:add(self.group_fps.node)
+ self.layout:add(self.group_components.node)
+ self.layout:set_justify(true)
self.druid:new_button("group_memory", self.run_collectgarbage)
self.group_memory:set_min_size(270, nil)
self.group_fps:set_min_size(270, nil)
self.group_components:set_min_size(270, nil)
- self.group_events:set_min_size(270, nil)
self.text_memory_amount = self.druid:new_text("text_memory_amount")
self.text_fps_amount = self.druid:new_text("text_fps_amount")
self.text_fps_min = self.druid:new_text("text_fps_min")
self.text_components_amount = self.druid:new_text("text_components_amount")
- self.text_events_amount = self.druid:new_text("text_events_amount")
- self.druid:new(lang_text, "text_memory", "ui_profiler_memory")
- self.druid:new(lang_text, "text_fps", "ui_profiler_fps")
- self.druid:new(lang_text, "text_components", "ui_profiler_components")
- self.druid:new(lang_text, "text_events", "ui_profiler_events")
+ self.druid:new_lang_text("text_memory", "ui_profiler_memory")
+ self.druid:new_lang_text("text_fps", "ui_profiler_fps")
+ self.druid:new_lang_text("text_components", "ui_profiler_components")
self.previous_time = nil
self.fps_samples = {}
@@ -57,17 +60,12 @@ function M:init(template, nodes)
self:get_node("text_components"),
self:get_node("text_components_amount"),
}
- self.nodes_events = {
- self:get_node("text_events"),
- self:get_node("text_events_amount"),
- }
timer.delay(0.16, true, function()
self:update_memory()
self:update_fps()
self:update_components()
- self:update_events()
- self:align_fps_components()
+ self.layout:set_dirty()
end)
end
@@ -76,14 +74,13 @@ function M:on_language_change()
self:update_memory()
self:update_fps()
self:update_components()
- self:update_events()
- self:align_fps_components()
+ self.layout:set_dirty()
end
function M:update_memory()
local memory = collectgarbage("count")
- self.text_memory_amount:set_to(tostring(math.ceil(memory)))
+ self.text_memory_amount:set_text(tostring(math.ceil(memory)))
local width = helper.centrate_nodes(2, unpack(self.nodes_memory))
for index = 1, #self.nodes_memory do
@@ -104,8 +101,8 @@ function M:update_fps()
end
average_frame_time = average_frame_time / #self.fps_samples
- self.text_fps_amount:set_to(tostring(math.ceil(1 / average_frame_time)))
- self.text_fps_min:set_to("/ " .. tostring(math.ceil(1 / max_frame_time)))
+ self.text_fps_amount:set_text(tostring(math.ceil(1 / average_frame_time)))
+ self.text_fps_min:set_text("/ " .. tostring(math.ceil(1 / max_frame_time)))
local width = helper.centrate_nodes(2, unpack(self.nodes_fps))
self.group_fps:set_size(width, nil)
@@ -116,40 +113,12 @@ function M:update_components()
---@diagnostic disable-next-line: undefined-field
local components = #self.druid.components_all
- self.text_components_amount:set_to(tostring(components))
+ self.text_components_amount:set_text(tostring(components))
local width = helper.centrate_nodes(2, unpack(self.nodes_components))
self.group_components:set_size(width, nil)
end
-function M:update_events()
- self.text_events_amount:set_to(tostring(event.COUNTER))
-
- local width = helper.centrate_nodes(2, unpack(self.nodes_events))
- for index = 1, #self.nodes_events do
- local node = self.nodes_events[index]
- local position_x = gui.get(node, "position.x")
- gui.set(node, "position.x", position_x - width/2)
- end
- self.group_events:set_size(width, nil)
-end
-
-
-function M:align_fps_components()
- local pos_x_memory = gui.get(self.group_memory.node, "position.x") + gui.get(self.group_memory.node, "size.x")
- local pos_x_events = gui.get(self.group_events.node, "position.x") - gui.get(self.group_events.node, "size.x")
- local width = pos_x_events - pos_x_memory
-
- -- Align FPS and Components
- local fps_size = gui.get(self.group_fps.node, "size.x")
- local components_size = gui.get(self.group_components.node, "size.x")
-
- local free_width = width - fps_size - components_size
- gui.set(self.group_fps.node, "position.x", pos_x_memory + fps_size/2 + free_width/3)
- gui.set(self.group_components.node, "position.x", pos_x_events - components_size/2 - free_width/3)
-end
-
-
function M:update()
self:sample_fps()
end
diff --git a/example/components/panel_information/panel_information.gui b/example/components/panel_information/panel_information.gui
index e9df7b8..5cf8924 100644
--- a/example/components/panel_information/panel_information.gui
+++ b/example/components/panel_information/panel_information.gui
@@ -7,8 +7,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -21,7 +21,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "root"
adjust_mode: ADJUST_MODE_STRETCH
layer: "druid"
@@ -92,27 +92,15 @@ nodes {
template: "/example/templates/button_text_blue.gui"
}
nodes {
- size {
- x: 240.0
- y: 80.0
- }
type: TYPE_BOX
id: "button_view_code/root"
parent: "button_view_code"
- overridden_fields: 4
template_node_child: true
}
nodes {
- scale {
- x: 0.75
- y: 0.75
- }
type: TYPE_TEXT
- text: "View code"
id: "button_view_code/text"
parent: "button_view_code/root"
- overridden_fields: 3
- overridden_fields: 8
template_node_child: true
}
nodes {
@@ -136,6 +124,10 @@ nodes {
x: -85.0
y: -32.5
}
+ scale {
+ x: 0.5
+ y: 0.5
+ }
type: TYPE_TEMPLATE
id: "button_profiler"
parent: "NE_Anchor"
@@ -143,41 +135,15 @@ nodes {
template: "/example/templates/button_text_yellow.gui"
}
nodes {
- size {
- x: 130.0
- y: 35.0
- }
type: TYPE_BOX
- texture: "druid/ui_circle_8"
id: "button_profiler/root"
parent: "button_profiler"
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- overridden_fields: 4
- overridden_fields: 9
- overridden_fields: 22
template_node_child: true
}
nodes {
- scale {
- x: 0.6
- y: 0.6
- }
- size {
- x: 190.0
- y: 50.0
- }
type: TYPE_TEXT
- text: "Profiler"
id: "button_profiler/text"
parent: "button_profiler/root"
- overridden_fields: 3
- overridden_fields: 4
- overridden_fields: 8
template_node_child: true
}
nodes {
@@ -190,7 +156,7 @@ nodes {
y: 250.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_view"
pivot: PIVOT_NW
parent: "root"
@@ -203,7 +169,7 @@ nodes {
y: 250.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_content"
pivot: PIVOT_NW
parent: "scroll_view"
diff --git a/example/components/panel_information/panel_information.lua b/example/components/panel_information/panel_information.lua
index fd0a35e..cd799dd 100644
--- a/example/components/panel_information/panel_information.lua
+++ b/example/components/panel_information/panel_information.lua
@@ -1,10 +1,6 @@
local lang = require("lang.lang")
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
-local rich_text = require("druid.custom.rich_text.rich_text")
-
---@class panel_information: druid.base_component
---@field root druid.container
---@field text_header druid.lang_text
@@ -17,17 +13,17 @@ local PanelInformation = component.create("panel_information")
function PanelInformation:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.root:add_container("text_header")
self.root:add_container("scroll_view")
self.root:add_container("S_Anchor")
self.root:add_container("NE_Anchor")
- self.druid:new(lang_text, "text_header", "ui_information")
- self.druid:new(lang_text, "button_profiler/text", "ui_profiler")
+ self.druid:new_lang_text("text_header", "ui_information")
+ self.druid:new_lang_text("button_profiler/text", "ui_profiler")
- --self.text_description = self.druid:new(lang_text, "text_description", "") --[[@as druid.lang_text]]
- self.rich_text = self.druid:new(rich_text, "text_description")
+ --self.text_description = self.druid:new_lang_text("text_description", "") --[[@as druid.lang_text]]
+ self.rich_text = self.druid:new_rich_text("text_description")
self.button_profiler = self.druid:new_button("button_profiler/root", self.on_profiler_click)
self.button_profiler:set_key_trigger("key_p")
self.button_view_code = self.druid:new_button("button_view_code/root")
diff --git a/example/components/properties_panel/properties/property_button.gui b/example/components/properties_panel/properties/property_button.gui
index 20e4680..061bd7a 100644
--- a/example/components/properties_panel/properties/property_button.gui
+++ b/example/components/properties_panel/properties/property_button.gui
@@ -1,184 +1,79 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.65
y: 0.65
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Button"
font: "text_bold"
id: "text_name"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 267.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 226.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
+ texture: "druid_example/rect_round2_width1"
id: "button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 4.0
@@ -186,143 +81,60 @@ nodes {
z: 4.0
w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 226.0
y: 4.0
- z: 0.0
- w: 1.0
}
color {
x: 0.894
y: 0.506
z: 0.333
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_S
adjust_mode: ADJUST_MODE_STRETCH
parent: "button"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
scale {
x: 0.65
y: 0.65
- z: 1.0
- w: 1.0
}
size {
x: 250.0
y: 30.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Button"
font: "text_bold"
id: "text_button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/properties_panel/properties/property_button.lua b/example/components/properties_panel/properties/property_button.lua
index 9ffa273..6dcc2ab 100644
--- a/example/components/properties_panel/properties/property_button.lua
+++ b/example/components/properties_panel/properties/property_button.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local lang_text = require("druid.extended.lang_text")
---@class property_button: druid.base_component
---@field root node
@@ -15,7 +14,7 @@ function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
- self.text_name = self.druid:new(lang_text, "text_name") --[[@as druid.lang_text]]
+ self.text_name = self.druid:new_lang_text("text_name") --[[@as druid.lang_text]]
self.selected = self:get_node("selected")
gui.set_alpha(self.selected, 0)
diff --git a/example/components/properties_panel/properties/property_checkbox.gui b/example/components/properties_panel/properties/property_checkbox.gui
index 69de501..bcab99a 100644
--- a/example/components/properties_panel/properties/property_checkbox.gui
+++ b/example/components/properties_panel/properties/property_checkbox.gui
@@ -1,184 +1,79 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.65
y: 0.65
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Checkbox"
font: "text_bold"
id: "text_name"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 174.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 40.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
+ texture: "druid_example/rect_round2_width1"
id: "button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 4.0
@@ -186,135 +81,40 @@ nodes {
z: 4.0
w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_check"
+ texture: "druid_example/icon_check"
id: "icon"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 40.0
y: 4.0
- z: 0.0
- w: 1.0
}
color {
x: 0.894
y: 0.506
z: 0.333
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_S
adjust_mode: ADJUST_MODE_STRETCH
parent: "button"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/properties_panel/properties/property_checkbox.lua b/example/components/properties_panel/properties/property_checkbox.lua
index fbe92c5..d3e9ce8 100644
--- a/example/components/properties_panel/properties/property_checkbox.lua
+++ b/example/components/properties_panel/properties/property_checkbox.lua
@@ -1,6 +1,4 @@
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
---@class property_checkbox: druid.base_component
---@field druid druid_instance
@@ -15,7 +13,7 @@ local M = component.create("property_checkbox")
---@param nodes table
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.icon = self:get_node("icon")
gui.set_enabled(self.icon, false)
@@ -23,7 +21,7 @@ function M:init(template, nodes)
self.selected = self:get_node("selected")
gui.set_alpha(self.selected, 0)
- self.text_name = self.druid:new(lang_text, "text_name") --[[@as druid.lang_text]]
+ self.text_name = self.druid:new_lang_text("text_name") --[[@as druid.lang_text]]
self.button = self.druid:new_button("button", self.on_click)
end
diff --git a/example/components/properties_panel/properties/property_slider.gui b/example/components/properties_panel/properties/property_slider.gui
index 4c47d1b..f4579ae 100644
--- a/example/components/properties_panel/properties/property_slider.gui
+++ b/example/components/properties_panel/properties/property_slider.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -12,7 +12,7 @@ nodes {
y: 40.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
@@ -62,7 +62,7 @@ nodes {
y: -20.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "E_Anchor"
pivot: PIVOT_E
adjust_mode: ADJUST_MODE_STRETCH
@@ -85,7 +85,7 @@ nodes {
z: 0.49
}
type: TYPE_BOX
- texture: "druid/rect_round2_width1"
+ texture: "druid_example/rect_round2_width1"
id: "button"
pivot: PIVOT_E
parent: "E_Anchor"
@@ -111,7 +111,7 @@ nodes {
z: 0.333
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "selected"
pivot: PIVOT_SE
adjust_mode: ADJUST_MODE_STRETCH
@@ -169,7 +169,7 @@ nodes {
z: 0.157
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "slider"
parent: "root"
inherit_alpha: true
@@ -185,7 +185,7 @@ nodes {
z: 0.157
}
type: TYPE_BOX
- texture: "druid/ui_circle_8"
+ texture: "druid_example/ui_circle_8"
id: "slider_back"
parent: "slider"
inherit_alpha: true
@@ -210,7 +210,7 @@ nodes {
z: 0.761
}
type: TYPE_BOX
- texture: "druid/ui_circle_8"
+ texture: "druid_example/ui_circle_8"
id: "slider_pin"
parent: "slider"
inherit_alpha: true
diff --git a/example/components/properties_panel/properties/property_slider.lua b/example/components/properties_panel/properties/property_slider.lua
index d5ada5f..9784d24 100644
--- a/example/components/properties_panel/properties/property_slider.lua
+++ b/example/components/properties_panel/properties/property_slider.lua
@@ -1,7 +1,4 @@
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
-local slider = require("druid.extended.slider")
---@class property_slider: druid.base_component
---@field druid druid_instance
@@ -17,14 +14,14 @@ local M = component.create("property_slider")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.selected = self:get_node("selected")
gui.set_alpha(self.selected, 0)
self._value = 0
- self.text_name = self.druid:new(lang_text, "text_name") --[[@as druid.lang_text]]
+ self.text_name = self.druid:new_lang_text("text_name") --[[@as druid.lang_text]]
self.text_value = self.druid:new_text("text_value")
- self.slider = self.druid:new(slider, "slider_pin", vmath.vector3(68, 0, 0), self._on_slider_change_by_user) --[[@as druid.slider]]
+ self.slider = self.druid:new_slider("slider_pin", vmath.vector3(68, 0, 0), self._on_slider_change_by_user) --[[@as druid.slider]]
self.slider:set_input_node("slider")
self:set_text_function(function(value)
@@ -36,7 +33,7 @@ end
---@param callback fun(value:number):string
function M:set_text_function(callback)
self._text_function = callback
- self.text_value:set_to(self._text_function(self._value))
+ self.text_value:set_text(self._text_function(self._value))
end
@@ -48,7 +45,7 @@ function M:set_value(value, is_instant)
self._value = value
self.slider:set(value, true)
- self.text_value:set_to(self._text_function(value))
+ self.text_value:set_text(self._text_function(value))
if not is_instant then
gui.set_alpha(self.selected, 1)
@@ -65,7 +62,7 @@ end
function M:_on_slider_change_by_user(value)
self._value = value
- self.text_value:set_to(self._text_function(value))
+ self.text_value:set_text(self._text_function(value))
gui.set_alpha(self.selected, 1)
gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
diff --git a/example/components/properties_panel/properties_panel.gui b/example/components/properties_panel/properties_panel.gui
index 49cc600..5e59d95 100644
--- a/example/components/properties_panel/properties_panel.gui
+++ b/example/components/properties_panel/properties_panel.gui
@@ -1,1791 +1,216 @@
-script: ""
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 440.0
y: 350.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -210.0
y: 165.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.9
y: 0.9
- z: 1.0
- w: 1.0
}
size {
x: 245.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Properties"
font: "text_regular"
id: "text_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_regular"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -200.0
y: 115.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 400.0
y: 290.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_view"
xanchor: XANCHOR_LEFT
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
parent: "root"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 290.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
parent: "scroll_view"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -35.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 400.0
y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "item_size"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
- adjust_mode: ADJUST_MODE_FIT
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 175.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 440.0
y: 4.0
- z: 0.0
- w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "separator"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "druid"
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "propeties"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "property_slider"
parent: "propeties"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/components/properties_panel/properties/property_slider.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 400.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "property_slider/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_NW
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_slider"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.65
- y: 0.65
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Checkbox"
- font: "text_bold"
- id: "property_slider/text_name"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "property_slider/root"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 400.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "property_slider/E_Anchor"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_E
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_slider/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: -20.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 60.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "property_slider/button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_E
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_slider/E_Anchor"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 60.0
- y: 4.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.894
- y: 0.506
- z: 0.333
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
- id: "property_slider/selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_SE
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_slider/button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -30.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.55
- y: 0.55
- z: 1.0
- w: 1.0
- }
- size {
- x: 100.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "25 %"
- font: "text_bold"
- id: "property_slider/text_value"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "property_slider/button"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 234.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 160.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.129
- y: 0.141
- z: 0.157
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "property_slider/slider"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_slider/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 160.0
- y: 8.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.129
- y: 0.141
- z: 0.157
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
- id: "property_slider/slider_back"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_slider/slider"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -68.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 24.0
- y: 24.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
- id: "property_slider/slider_pin"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_slider/slider"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -50.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "property_checkbox"
parent: "propeties"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/components/properties_panel/properties/property_checkbox.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 400.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "property_checkbox/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_NW
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_checkbox"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.65
- y: 0.65
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Checkbox"
- font: "text_bold"
- id: "property_checkbox/text_name"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "property_checkbox/root"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 174.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 40.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "property_checkbox/button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_checkbox/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_check"
- id: "property_checkbox/icon"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_checkbox/button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 40.0
- y: 4.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.894
- y: 0.506
- z: 0.333
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
- id: "property_checkbox/selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_S
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_checkbox/button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "property_button"
parent: "propeties"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/components/properties_panel/properties/property_button.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 400.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "property_button/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_NW
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.65
- y: 0.65
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Button"
- font: "text_bold"
- id: "property_button/text_name"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "property_button/root"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 267.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 226.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "property_button/button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "property_button/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: -20.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 226.0
- y: 4.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.894
- y: 0.506
- z: 0.333
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
- id: "property_button/selected"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_S
- adjust_mode: ADJUST_MODE_STRETCH
- parent: "property_button/button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.65
- y: 0.65
- z: 1.0
- w: 1.0
- }
- size {
- x: 250.0
- y: 30.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Button"
- font: "text_bold"
- id: "property_button/text_button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "property_button/button"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -200.0
y: 115.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 0.7
y: 0.7
- z: 1.0
- w: 1.0
}
size {
x: 570.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "No properties for this example"
font: "text_regular"
id: "text_no_properties"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_regular"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -1795,4 +220,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/components/properties_panel/properties_panel.lua b/example/components/properties_panel/properties_panel.lua
index 60a9f78..2d370d1 100644
--- a/example/components/properties_panel/properties_panel.lua
+++ b/example/components/properties_panel/properties_panel.lua
@@ -1,6 +1,4 @@
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
local property_checkbox = require("example.components.properties_panel.properties.property_checkbox")
local property_slider = require("example.components.properties_panel.properties.property_slider")
@@ -18,7 +16,7 @@ local M = component.create("properties_panel")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.root = self.druid:new_container("root") --[[@as druid.container]]
self.root:add_container("text_header")
self.root:add_container("separator")
--self.root:add_container("scroll_view", nil, function()
@@ -27,11 +25,11 @@ function M:init(template, nodes)
self.properties = {}
- self.druid:new(lang_text, "text_header", "ui_properties_panel")
- self.text_no_properties = self.druid:new(lang_text, "text_no_properties", "ui_no_properties") --[[@as druid.lang_text]]
+ self.druid:new_lang_text("text_header", "ui_properties_panel")
+ self.text_no_properties = self.druid:new_lang_text("text_no_properties", "ui_no_properties") --[[@as druid.lang_text]]
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
- self.grid = self.druid:new_static_grid("scroll_content", "item_size", 1)
+ self.grid = self.druid:new_grid("scroll_content", "item_size", 1)
self.scroll:bind_grid(self.grid)
self.property_checkbox_prefab = self:get_node("property_checkbox/root")
diff --git a/example/druid.gui b/example/druid.gui
index 4918bc8..1538aa4 100644
--- a/example/druid.gui
+++ b/example/druid.gui
@@ -8,8 +8,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
textures {
name: "druid_logo"
@@ -39,7 +39,7 @@ nodes {
y: 1080.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_left"
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_STRETCH
@@ -56,7 +56,7 @@ nodes {
y: 170.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_logo"
pivot: PIVOT_NW
parent: "container_left"
@@ -125,7 +125,7 @@ nodes {
y: 910.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_examples"
pivot: PIVOT_NW
adjust_mode: ADJUST_MODE_STRETCH
@@ -213,7 +213,7 @@ nodes {
y: 1080.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_right"
pivot: PIVOT_E
adjust_mode: ADJUST_MODE_STRETCH
@@ -230,7 +230,7 @@ nodes {
y: 450.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_info"
pivot: PIVOT_NE
adjust_mode: ADJUST_MODE_STRETCH
@@ -336,7 +336,7 @@ nodes {
y: 630.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_group_settings_output"
pivot: PIVOT_SE
adjust_mode: ADJUST_MODE_STRETCH
@@ -353,7 +353,7 @@ nodes {
y: 350.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_settings"
pivot: PIVOT_NE
adjust_mode: ADJUST_MODE_STRETCH
@@ -367,189 +367,189 @@ nodes {
y: -175.0
}
type: TYPE_TEMPLATE
- id: "properties_panel"
+ id: "example_properties_panel"
parent: "container_settings"
inherit_alpha: true
template: "/example/components/properties_panel/properties_panel.gui"
}
nodes {
type: TYPE_BOX
- id: "properties_panel/root"
- parent: "properties_panel"
+ id: "example_properties_panel/root"
+ parent: "example_properties_panel"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/text_header"
- parent: "properties_panel/root"
+ id: "example_properties_panel/text_header"
+ parent: "example_properties_panel/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/scroll_view"
- parent: "properties_panel/root"
+ id: "example_properties_panel/scroll_view"
+ parent: "example_properties_panel/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/scroll_content"
- parent: "properties_panel/scroll_view"
+ id: "example_properties_panel/scroll_content"
+ parent: "example_properties_panel/scroll_view"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/item_size"
- parent: "properties_panel/scroll_content"
+ id: "example_properties_panel/item_size"
+ parent: "example_properties_panel/scroll_content"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/separator"
- parent: "properties_panel/root"
+ id: "example_properties_panel/separator"
+ parent: "example_properties_panel/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/propeties"
- parent: "properties_panel/root"
+ id: "example_properties_panel/propeties"
+ parent: "example_properties_panel/root"
template_node_child: true
}
nodes {
type: TYPE_TEMPLATE
- id: "properties_panel/property_slider"
- parent: "properties_panel/propeties"
+ id: "example_properties_panel/property_slider"
+ parent: "example_properties_panel/propeties"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/root"
- parent: "properties_panel/property_slider"
+ id: "example_properties_panel/property_slider/root"
+ parent: "example_properties_panel/property_slider"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/property_slider/text_name"
- parent: "properties_panel/property_slider/root"
+ id: "example_properties_panel/property_slider/text_name"
+ parent: "example_properties_panel/property_slider/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/E_Anchor"
- parent: "properties_panel/property_slider/root"
+ id: "example_properties_panel/property_slider/E_Anchor"
+ parent: "example_properties_panel/property_slider/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/button"
- parent: "properties_panel/property_slider/E_Anchor"
+ id: "example_properties_panel/property_slider/button"
+ parent: "example_properties_panel/property_slider/E_Anchor"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/selected"
- parent: "properties_panel/property_slider/button"
+ id: "example_properties_panel/property_slider/selected"
+ parent: "example_properties_panel/property_slider/button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/property_slider/text_value"
- parent: "properties_panel/property_slider/button"
+ id: "example_properties_panel/property_slider/text_value"
+ parent: "example_properties_panel/property_slider/button"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/slider"
- parent: "properties_panel/property_slider/root"
+ id: "example_properties_panel/property_slider/slider"
+ parent: "example_properties_panel/property_slider/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/slider_back"
- parent: "properties_panel/property_slider/slider"
+ id: "example_properties_panel/property_slider/slider_back"
+ parent: "example_properties_panel/property_slider/slider"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_slider/slider_pin"
- parent: "properties_panel/property_slider/slider"
+ id: "example_properties_panel/property_slider/slider_pin"
+ parent: "example_properties_panel/property_slider/slider"
template_node_child: true
}
nodes {
type: TYPE_TEMPLATE
- id: "properties_panel/property_checkbox"
- parent: "properties_panel/propeties"
+ id: "example_properties_panel/property_checkbox"
+ parent: "example_properties_panel/propeties"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_checkbox/root"
- parent: "properties_panel/property_checkbox"
+ id: "example_properties_panel/property_checkbox/root"
+ parent: "example_properties_panel/property_checkbox"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/property_checkbox/text_name"
- parent: "properties_panel/property_checkbox/root"
+ id: "example_properties_panel/property_checkbox/text_name"
+ parent: "example_properties_panel/property_checkbox/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_checkbox/button"
- parent: "properties_panel/property_checkbox/root"
+ id: "example_properties_panel/property_checkbox/button"
+ parent: "example_properties_panel/property_checkbox/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_checkbox/icon"
- parent: "properties_panel/property_checkbox/button"
+ id: "example_properties_panel/property_checkbox/icon"
+ parent: "example_properties_panel/property_checkbox/button"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_checkbox/selected"
- parent: "properties_panel/property_checkbox/button"
+ id: "example_properties_panel/property_checkbox/selected"
+ parent: "example_properties_panel/property_checkbox/button"
template_node_child: true
}
nodes {
type: TYPE_TEMPLATE
- id: "properties_panel/property_button"
- parent: "properties_panel/propeties"
+ id: "example_properties_panel/property_button"
+ parent: "example_properties_panel/propeties"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_button/root"
- parent: "properties_panel/property_button"
+ id: "example_properties_panel/property_button/root"
+ parent: "example_properties_panel/property_button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/property_button/text_name"
- parent: "properties_panel/property_button/root"
+ id: "example_properties_panel/property_button/text_name"
+ parent: "example_properties_panel/property_button/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_button/button"
- parent: "properties_panel/property_button/root"
+ id: "example_properties_panel/property_button/button"
+ parent: "example_properties_panel/property_button/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
- id: "properties_panel/property_button/selected"
- parent: "properties_panel/property_button/button"
+ id: "example_properties_panel/property_button/selected"
+ parent: "example_properties_panel/property_button/button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/property_button/text_button"
- parent: "properties_panel/property_button/button"
+ id: "example_properties_panel/property_button/text_button"
+ parent: "example_properties_panel/property_button/button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
- id: "properties_panel/text_no_properties"
- parent: "properties_panel/root"
+ id: "example_properties_panel/text_no_properties"
+ parent: "example_properties_panel/root"
template_node_child: true
}
nodes {
@@ -558,7 +558,7 @@ nodes {
y: 280.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_output"
pivot: PIVOT_SE
adjust_mode: ADJUST_MODE_STRETCH
@@ -635,7 +635,7 @@ nodes {
y: 1030.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_center"
xanchor: XANCHOR_LEFT
yanchor: YANCHOR_BOTTOM
@@ -683,7 +683,7 @@ nodes {
}
nodes {
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "intro_examples"
parent: "examples"
inherit_alpha: true
@@ -2447,7 +2447,6 @@ nodes {
type: TYPE_BOX
id: "window_language/root"
parent: "window_language"
- overridden_fields: 1
template_node_child: true
}
nodes {
@@ -2521,7 +2520,6 @@ nodes {
type: TYPE_BOX
id: "window_confirmation/root"
parent: "window_confirmation"
- overridden_fields: 1
template_node_child: true
}
nodes {
@@ -2613,7 +2611,6 @@ nodes {
type: TYPE_BOX
id: "window_info/root"
parent: "window_info"
- overridden_fields: 1
template_node_child: true
}
nodes {
@@ -2868,7 +2865,7 @@ nodes {
}
nodes {
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "gamepad"
parent: "examples"
inherit_alpha: true
@@ -3673,7 +3670,7 @@ nodes {
}
nodes {
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "layout"
parent: "examples"
inherit_alpha: true
@@ -3707,7 +3704,7 @@ nodes {
}
nodes {
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "widgets"
parent: "examples"
inherit_alpha: true
@@ -3919,6 +3916,878 @@ nodes {
parent: "property_slider/slider"
template_node_child: true
}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "fps_panel"
+ parent: "widgets"
+ inherit_alpha: true
+ template: "/druid/widget/fps_panel/fps_panel.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/root"
+ parent: "fps_panel"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "fps_panel/mini_graph"
+ parent: "fps_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/root"
+ parent: "fps_panel/mini_graph"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/header"
+ parent: "fps_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "fps_panel/mini_graph/text_header"
+ parent: "fps_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/icon_drag"
+ parent: "fps_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/content"
+ parent: "fps_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/prefab_line"
+ parent: "fps_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/color_low"
+ parent: "fps_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/content"
+ parent: "fps_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "fps_panel/text_min_fps"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "fps_panel/text_fps"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/line_second_1"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/line_second_2"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel"
+ parent: "widgets"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties_panel.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/root"
+ parent: "properties_panel"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/header"
+ parent: "properties_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/text_header"
+ parent: "properties_panel/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/icon_drag"
+ parent: "properties_panel/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/content"
+ parent: "properties_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/scroll_view"
+ parent: "properties_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/scroll_content"
+ parent: "properties_panel/scroll_view"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/propeties"
+ parent: "properties_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_slider"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/root"
+ parent: "properties_panel/property_slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_slider/text_name"
+ parent: "properties_panel/property_slider/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/E_Anchor"
+ parent: "properties_panel/property_slider/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/slider"
+ parent: "properties_panel/property_slider/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/slider_back"
+ parent: "properties_panel/property_slider/slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/slider_pin"
+ parent: "properties_panel/property_slider/slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/button"
+ parent: "properties_panel/property_slider/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/selected"
+ parent: "properties_panel/property_slider/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_slider/text_value"
+ parent: "properties_panel/property_slider/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_checkbox"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/root"
+ parent: "properties_panel/property_checkbox"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_checkbox/text_name"
+ parent: "properties_panel/property_checkbox/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/E_Anchor"
+ parent: "properties_panel/property_checkbox/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/button"
+ parent: "properties_panel/property_checkbox/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/icon"
+ parent: "properties_panel/property_checkbox/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/selected"
+ parent: "properties_panel/property_checkbox/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_button"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/root"
+ parent: "properties_panel/property_button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_button/text_name"
+ parent: "properties_panel/property_button/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/E_Anchor"
+ parent: "properties_panel/property_button/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/button"
+ parent: "properties_panel/property_button/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/selected"
+ parent: "properties_panel/property_button/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_button/text_button"
+ parent: "properties_panel/property_button/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_input"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/root"
+ parent: "properties_panel/property_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/text_name"
+ parent: "properties_panel/property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/E_Anchor"
+ parent: "properties_panel/property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_input/rich_input"
+ parent: "properties_panel/property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/rich_input/root"
+ parent: "properties_panel/property_input/rich_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/rich_input/button"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/rich_input/placeholder_text"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/rich_input/input_text"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/rich_input/cursor_node"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/rich_input/cursor_text"
+ parent: "properties_panel/property_input/rich_input/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/selected"
+ parent: "properties_panel/property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_text"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_text/root"
+ parent: "properties_panel/property_text"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_text/text_name"
+ parent: "properties_panel/property_text/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_text/text_right"
+ parent: "properties_panel/property_text/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_left_right_selector"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/root"
+ parent: "properties_panel/property_left_right_selector"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_left_right_selector/text_name"
+ parent: "properties_panel/property_left_right_selector/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/E_Anchor"
+ parent: "properties_panel/property_left_right_selector/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/button_left"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/icon_left"
+ parent: "properties_panel/property_left_right_selector/button_left"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/button_right"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/icon_right"
+ parent: "properties_panel/property_left_right_selector/button_right"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/selected"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_left_right_selector/text_value"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_vector3"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/root"
+ parent: "properties_panel/property_vector3"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/text_name"
+ parent: "properties_panel/property_vector3/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/E_Anchor"
+ parent: "properties_panel/property_vector3/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/field_x"
+ parent: "properties_panel/property_vector3/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/text_x"
+ parent: "properties_panel/property_vector3/field_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_vector3/rich_input_x"
+ parent: "properties_panel/property_vector3/field_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_x/root"
+ parent: "properties_panel/property_vector3/rich_input_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_x/button"
+ parent: "properties_panel/property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_x/placeholder_text"
+ parent: "properties_panel/property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_x/input_text"
+ parent: "properties_panel/property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_x/cursor_node"
+ parent: "properties_panel/property_vector3/rich_input_x/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_x/cursor_text"
+ parent: "properties_panel/property_vector3/rich_input_x/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/selected_x"
+ parent: "properties_panel/property_vector3/field_x"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/field_y"
+ parent: "properties_panel/property_vector3/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/text_y"
+ parent: "properties_panel/property_vector3/field_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_vector3/rich_input_y"
+ parent: "properties_panel/property_vector3/field_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_y/root"
+ parent: "properties_panel/property_vector3/rich_input_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_y/button"
+ parent: "properties_panel/property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_y/placeholder_text"
+ parent: "properties_panel/property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_y/input_text"
+ parent: "properties_panel/property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_y/cursor_node"
+ parent: "properties_panel/property_vector3/rich_input_y/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_y/cursor_text"
+ parent: "properties_panel/property_vector3/rich_input_y/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/selected_y"
+ parent: "properties_panel/property_vector3/field_y"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/field_z"
+ parent: "properties_panel/property_vector3/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/text_z"
+ parent: "properties_panel/property_vector3/field_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_vector3/rich_input_z"
+ parent: "properties_panel/property_vector3/field_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_z/root"
+ parent: "properties_panel/property_vector3/rich_input_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_z/button"
+ parent: "properties_panel/property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_z/placeholder_text"
+ parent: "properties_panel/property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_z/input_text"
+ parent: "properties_panel/property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/rich_input_z/cursor_node"
+ parent: "properties_panel/property_vector3/rich_input_z/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_vector3/rich_input_z/cursor_text"
+ parent: "properties_panel/property_vector3/rich_input_z/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_vector3/selected_z"
+ parent: "properties_panel/property_vector3/field_z"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "memory_panel"
+ parent: "widgets"
+ inherit_alpha: true
+ template: "/druid/widget/memory_panel/memory_panel.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/root"
+ parent: "memory_panel"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "memory_panel/mini_graph"
+ parent: "memory_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/root"
+ parent: "memory_panel/mini_graph"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/header"
+ parent: "memory_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/mini_graph/text_header"
+ parent: "memory_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/icon_drag"
+ parent: "memory_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/content"
+ parent: "memory_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/prefab_line"
+ parent: "memory_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/color_low"
+ parent: "memory_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/content"
+ parent: "memory_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/text_max_value"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/text_per_second"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/line_second_1"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/line_second_2"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/text_memory"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "mini_graph"
+ parent: "widgets"
+ inherit_alpha: true
+ template: "/druid/widget/mini_graph/mini_graph.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/root"
+ parent: "mini_graph"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/header"
+ parent: "mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "mini_graph/text_header"
+ parent: "mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/icon_drag"
+ parent: "mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/content"
+ parent: "mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/prefab_line"
+ parent: "mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "mini_graph/color_low"
+ parent: "mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ position {
+ x: -200.0
+ }
+ type: TYPE_TEMPLATE
+ id: "property_input"
+ parent: "widgets"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties/property_input.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/root"
+ parent: "property_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/text_name"
+ parent: "property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/E_Anchor"
+ parent: "property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "property_input/rich_input"
+ parent: "property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/rich_input/root"
+ parent: "property_input/rich_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/rich_input/button"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/rich_input/placeholder_text"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/rich_input/input_text"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/rich_input/cursor_node"
+ parent: "property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "property_input/rich_input/cursor_text"
+ parent: "property_input/rich_input/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "property_input/selected"
+ parent: "property_input/E_Anchor"
+ template_node_child: true
+}
nodes {
position {
x: -20.0
@@ -3929,7 +4798,7 @@ nodes {
y: 50.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "container_status"
xanchor: XANCHOR_LEFT
pivot: PIVOT_S
@@ -3955,10 +4824,16 @@ nodes {
}
nodes {
type: TYPE_BOX
- id: "panel_druid_profiler/group_memory"
+ id: "panel_druid_profiler/layout"
parent: "panel_druid_profiler/root"
template_node_child: true
}
+nodes {
+ type: TYPE_BOX
+ id: "panel_druid_profiler/group_memory"
+ parent: "panel_druid_profiler/layout"
+ template_node_child: true
+}
nodes {
type: TYPE_TEXT
id: "panel_druid_profiler/text_memory"
@@ -3980,7 +4855,7 @@ nodes {
nodes {
type: TYPE_BOX
id: "panel_druid_profiler/group_fps"
- parent: "panel_druid_profiler/root"
+ parent: "panel_druid_profiler/layout"
template_node_child: true
}
nodes {
@@ -4004,7 +4879,7 @@ nodes {
nodes {
type: TYPE_BOX
id: "panel_druid_profiler/group_components"
- parent: "panel_druid_profiler/root"
+ parent: "panel_druid_profiler/layout"
template_node_child: true
}
nodes {
@@ -4019,24 +4894,6 @@ nodes {
parent: "panel_druid_profiler/group_components"
template_node_child: true
}
-nodes {
- type: TYPE_BOX
- id: "panel_druid_profiler/group_events"
- parent: "panel_druid_profiler/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "panel_druid_profiler/text_events"
- parent: "panel_druid_profiler/group_events"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "panel_druid_profiler/text_events_amount"
- parent: "panel_druid_profiler/group_events"
- template_node_child: true
-}
layers {
name: "druid"
}
@@ -4051,4 +4908,4 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 2048
+max_nodes: 4096
diff --git a/example/druid.gui_script b/example/druid.gui_script
index ff90b43..4b5c865 100644
--- a/example/druid.gui_script
+++ b/example/druid.gui_script
@@ -3,7 +3,6 @@ local saver = require("saver.saver")
local storage = require("saver.storage")
local druid = require("druid.druid")
-local container = require("example.components.container.container")
local druid_logo = require("example.components.druid_logo.druid_logo")
local panel_information = require("example.components.panel_information.panel_information")
local example_scene = require("example.components.example_scene.example_scene")
@@ -56,7 +55,7 @@ end
--- This allow easily move components in the GUI scene and change the size of each section
---@param self druid.example
local function setup_layout(self)
- self.container_root = self.druid:new(container, "root") --[[@as druid.container]]
+ self.container_root = self.druid:new_container("root") --[[@as druid.container]]
self.container_left = self.container_root:add_container("container_left", "stretch_y")
self.container_logo = self.container_left:add_container("container_logo")
self.container_examples = self.container_left:add_container("container_examples")
@@ -90,7 +89,7 @@ local function setup_components(self)
self.examples_list_view = self.druid:new(examples_list_view, "examples_list_view") --[[@as examples_list_view]]
self.container_examples:add_container(self.examples_list_view.root)
- self.properties_panel = self.druid:new(properties_panel, "properties_panel") --[[@as properties_panel]]
+ self.properties_panel = self.druid:new(properties_panel, "example_properties_panel") --[[@as properties_panel]]
self.container_settings:add_container(self.properties_panel.root)
self.output_list = self.druid:new(output_list, "output_list") --[[@as output_list]]
diff --git a/example/examples/basic/back_handler/basic_back_handler.gui b/example/examples/basic/back_handler/basic_back_handler.gui
index 06c7705..0ba266c 100644
--- a/example/examples/basic/back_handler/basic_back_handler.gui
+++ b/example/examples/basic/back_handler/basic_back_handler.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -17,7 +17,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
diff --git a/example/examples/basic/blocker/basic_blocker.gui b/example/examples/basic/blocker/basic_blocker.gui
index 96a1886..8736e65 100644
--- a/example/examples/basic/blocker/basic_blocker.gui
+++ b/example/examples/basic/blocker/basic_blocker.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -17,7 +17,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
@@ -38,7 +38,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "blocker"
parent: "root"
inherit_alpha: true
@@ -56,18 +56,6 @@ nodes {
inherit_alpha: true
template: "/example/templates/button_text_green.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button/root"
- parent: "button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button/text"
- parent: "button/root"
- template_node_child: true
-}
nodes {
position {
x: -246.0
diff --git a/example/examples/basic/blocker/basic_blocker.lua b/example/examples/basic/blocker/basic_blocker.lua
index 1885d91..57bcfc0 100644
--- a/example/examples/basic/blocker/basic_blocker.lua
+++ b/example/examples/basic/blocker/basic_blocker.lua
@@ -1,6 +1,6 @@
local component = require("druid.component")
----@class basic_blocker: druid.component
+---@class basic_blocker: druid.base_component
---@field druid druid_instance
---@field root node
---@field blocker druid.blocker
diff --git a/example/examples/basic/button/basic_button.gui b/example/examples/basic/button/basic_button.gui
index d96efe6..b6e5721 100644
--- a/example/examples/basic/button/basic_button.gui
+++ b/example/examples/basic/button/basic_button.gui
@@ -1,236 +1,20 @@
-script: ""
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
-}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "button"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Confirm"
- font: "text_bold"
- id: "button/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/button/basic_button_double_click.gui b/example/examples/basic/button/basic_button_double_click.gui
index d96efe6..b6e5721 100644
--- a/example/examples/basic/button/basic_button_double_click.gui
+++ b/example/examples/basic/button/basic_button_double_click.gui
@@ -1,236 +1,20 @@
-script: ""
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
-}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "button"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Confirm"
- font: "text_bold"
- id: "button/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/button/basic_button_hold.gui b/example/examples/basic/button/basic_button_hold.gui
index 23d6be9..2234bea 100644
--- a/example/examples/basic/button/basic_button_hold.gui
+++ b/example/examples/basic/button/basic_button_hold.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -28,7 +28,7 @@ nodes {
z: 0.624
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "button"
parent: "root"
inherit_alpha: true
@@ -63,7 +63,7 @@ nodes {
z: 0.62
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "button_image"
parent: "mask"
inherit_alpha: true
diff --git a/example/examples/basic/checkbox/checkbox.gui b/example/examples/basic/checkbox/checkbox.gui
index 287fcdb..445fc15 100644
--- a/example/examples/basic/checkbox/checkbox.gui
+++ b/example/examples/basic/checkbox/checkbox.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -28,7 +28,7 @@ nodes {
z: 0.49
}
type: TYPE_BOX
- texture: "druid/rect_round2_width1"
+ texture: "druid_example/rect_round2_width1"
id: "button"
parent: "root"
inherit_alpha: true
@@ -46,7 +46,7 @@ nodes {
z: 0.761
}
type: TYPE_BOX
- texture: "druid/icon_check"
+ texture: "druid_example/icon_check"
id: "icon"
parent: "button"
inherit_alpha: true
@@ -66,7 +66,7 @@ nodes {
z: 0.333
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "selected"
pivot: PIVOT_S
adjust_mode: ADJUST_MODE_STRETCH
diff --git a/example/examples/basic/checkbox/checkbox.lua b/example/examples/basic/checkbox/checkbox.lua
index 32bee28..cd27d26 100644
--- a/example/examples/basic/checkbox/checkbox.lua
+++ b/example/examples/basic/checkbox/checkbox.lua
@@ -1,5 +1,5 @@
local component = require("druid.component")
-local event = require("druid.event")
+local event = require("event.event")
---@class checkbox: druid.base_component
---@field druid druid_instance
diff --git a/example/examples/basic/checkbox_group/checkbox_group.gui b/example/examples/basic/checkbox_group/checkbox_group.gui
index 275a269..a51e797 100644
--- a/example/examples/basic/checkbox_group/checkbox_group.gui
+++ b/example/examples/basic/checkbox_group/checkbox_group.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -27,30 +27,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/basic/checkbox/checkbox.gui"
}
-nodes {
- type: TYPE_BOX
- id: "checkbox_1/root"
- parent: "checkbox_1"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_1/button"
- parent: "checkbox_1/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_1/icon"
- parent: "checkbox_1/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_1/selected"
- parent: "checkbox_1/button"
- template_node_child: true
-}
nodes {
type: TYPE_TEMPLATE
id: "checkbox_2"
@@ -58,30 +34,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/basic/checkbox/checkbox.gui"
}
-nodes {
- type: TYPE_BOX
- id: "checkbox_2/root"
- parent: "checkbox_2"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_2/button"
- parent: "checkbox_2/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_2/icon"
- parent: "checkbox_2/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_2/selected"
- parent: "checkbox_2/button"
- template_node_child: true
-}
nodes {
position {
x: 100.0
@@ -92,29 +44,5 @@ nodes {
inherit_alpha: true
template: "/example/examples/basic/checkbox/checkbox.gui"
}
-nodes {
- type: TYPE_BOX
- id: "checkbox_3/root"
- parent: "checkbox_3"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_3/button"
- parent: "checkbox_3/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_3/icon"
- parent: "checkbox_3/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "checkbox_3/selected"
- parent: "checkbox_3/button"
- template_node_child: true
-}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/basic/checkbox_group/checkbox_group.lua b/example/examples/basic/checkbox_group/checkbox_group.lua
index cff045f..2ef54ce 100644
--- a/example/examples/basic/checkbox_group/checkbox_group.lua
+++ b/example/examples/basic/checkbox_group/checkbox_group.lua
@@ -1,4 +1,4 @@
-local event = require("druid.event")
+local event = require("event.event")
local component = require("druid.component")
-- Require checkbox component from checkbox example
diff --git a/example/examples/basic/drag/drag.gui b/example/examples/basic/drag/drag.gui
index 80572e3..c4ea468 100644
--- a/example/examples/basic/drag/drag.gui
+++ b/example/examples/basic/drag/drag.gui
@@ -1,241 +1,23 @@
-script: ""
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "drag"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_blue.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.631
- y: 0.843
- z: 0.961
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "drag/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "drag"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Drag Me"
- font: "text_bold"
- id: "drag/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "drag/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 8
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/drag/drag_to_node.gui b/example/examples/basic/drag/drag_to_node.gui
index ec8257a..1bc8e22 100644
--- a/example/examples/basic/drag/drag_to_node.gui
+++ b/example/examples/basic/drag/drag_to_node.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -23,20 +23,6 @@ nodes {
inherit_alpha: true
template: "/example/templates/button_text_blue.gui"
}
-nodes {
- type: TYPE_BOX
- id: "drag/root"
- parent: "drag"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "Drag Me"
- id: "drag/text"
- parent: "drag/root"
- overridden_fields: 8
- template_node_child: true
-}
nodes {
position {
y: 300.0
@@ -51,7 +37,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "zone"
parent: "root"
inherit_alpha: true
diff --git a/example/examples/basic/drag/drag_to_node.lua b/example/examples/basic/drag/drag_to_node.lua
index 34fec17..eb927f9 100644
--- a/example/examples/basic/drag/drag_to_node.lua
+++ b/example/examples/basic/drag/drag_to_node.lua
@@ -15,7 +15,7 @@ function M:init(template, nodes)
gui.set_text(self.text_counter, self.counter)
-- Init drag and move the drag node on drag callback
- self.drag = self.druid:new_drag("drag/root", self.on_drag_start)
+ self.drag = self.druid:new_drag("drag/root", self.on_drag)
self.drag.on_drag_end:subscribe(self.on_drag_end)
-- Save start position for animation
@@ -23,7 +23,7 @@ function M:init(template, nodes)
end
-function M:on_drag_start(dx, dy, x, y, touch)
+function M:on_drag(dx, dy, x, y, touch)
local position_x = gui.get(self.drag.node, "position.x")
local position_y = gui.get(self.drag.node, "position.y")
gui.set(self.drag.node, "position.x", position_x + dx)
diff --git a/example/examples/basic/grid/grid.gui b/example/examples/basic/grid/grid.gui
index c649b07..93a555a 100644
--- a/example/examples/basic/grid/grid.gui
+++ b/example/examples/basic/grid/grid.gui
@@ -1,117 +1,40 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 300.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 600.0
y: 600.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "grid"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,117 +42,32 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 100.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "grid"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 90.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -237,84 +75,39 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 50.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/grid/grid.lua b/example/examples/basic/grid/grid.lua
index b9928b5..db0bd16 100644
--- a/example/examples/basic/grid/grid.lua
+++ b/example/examples/basic/grid/grid.lua
@@ -1,7 +1,7 @@
local component = require("druid.component")
---@class grid: druid.base_component
----@field grid druid.static_grid
+---@field grid druid.grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("grid")
@@ -17,7 +17,7 @@ function M:init(template, nodes)
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
- self.grid = self.druid:new_static_grid("grid", "prefab", 3)
+ self.grid = self.druid:new_grid("grid", "prefab", 3)
for index = 1, 9 do
self:add_element()
diff --git a/example/examples/basic/hotkey/basic_hotkey.lua b/example/examples/basic/hotkey/basic_hotkey.lua
index d003699..fec96aa 100644
--- a/example/examples/basic/hotkey/basic_hotkey.lua
+++ b/example/examples/basic/hotkey/basic_hotkey.lua
@@ -1,5 +1,3 @@
-local hotkey = require("druid.extended.hotkey")
-
local component = require("druid.component")
---@class basic_hotkey: druid.base_component
@@ -15,7 +13,7 @@ function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
- self.hotkey = self.druid:new(hotkey, { "key_lshift", "key_x" }, self.on_hotkey)
+ self.hotkey = self.druid:new_hotkey({ "key_lshift", "key_x" }, self.on_hotkey)
end
diff --git a/example/examples/basic/hover/hover.gui b/example/examples/basic/hover/hover.gui
index 45adecd..30312c1 100644
--- a/example/examples/basic/hover/hover.gui
+++ b/example/examples/basic/hover/hover.gui
@@ -1,410 +1,36 @@
-script: ""
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button_mouse_hover"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button_mouse_hover/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button_mouse_hover"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Mouse Hover"
- font: "text_bold"
- id: "button_mouse_hover/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button_mouse_hover/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 8
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button_mobile_hover"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button_mobile_hover/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button_mobile_hover"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Mobile Hover"
- font: "text_bold"
- id: "button_mobile_hover/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button_mobile_hover/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 8
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/input/basic_input.gui b/example/examples/basic/input/basic_input.gui
index c4405a8..c13ede9 100644
--- a/example/examples/basic/input/basic_input.gui
+++ b/example/examples/basic/input/basic_input.gui
@@ -1,406 +1,29 @@
-script: ""
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
-}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "input"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/input.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "input/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "input"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -240.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 480.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap me to input"
- font: "text_bold"
- id: "input/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "input/root"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -150.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "input_2"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/input.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.463
- y: 0.475
- z: 0.49
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "input_2/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "input_2"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 480.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap me to input"
- font: "text_bold"
- id: "input_2/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "input_2/root"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 1
- overridden_fields: 14
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/input/basic_input.lua b/example/examples/basic/input/basic_input.lua
index 3648191..7be4813 100644
--- a/example/examples/basic/input/basic_input.lua
+++ b/example/examples/basic/input/basic_input.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local input = require("druid.extended.input")
---@class basic_input: druid.base_component
---@field druid druid_instance
@@ -12,9 +11,9 @@ local M = component.create("basic_input")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.input = self.druid:new(input, "input/root", "input/text")
+ self.input = self.druid:new_input("input/root", "input/text")
- self.input_2 = self.druid:new(input, "input_2/root", "input_2/text") --[[@as druid.input]]
+ self.input_2 = self.druid:new_input("input_2/root", "input_2/text") --[[@as druid.input]]
-- you can set custom style for input and their components
-- Check in the example, how long tap on bottom input will erase text
diff --git a/example/examples/basic/input/input_password.gui b/example/examples/basic/input/input_password.gui
index c93752a..03bdeef 100644
--- a/example/examples/basic/input/input_password.gui
+++ b/example/examples/basic/input/input_password.gui
@@ -15,19 +15,5 @@ nodes {
inherit_alpha: true
template: "/example/templates/input.gui"
}
-nodes {
- type: TYPE_BOX
- id: "input/root"
- parent: "input"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "input/text"
- parent: "input/root"
- overridden_fields: 1
- overridden_fields: 14
- template_node_child: true
-}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/basic/input/input_password.lua b/example/examples/basic/input/input_password.lua
index d56760a..014f1d7 100644
--- a/example/examples/basic/input/input_password.lua
+++ b/example/examples/basic/input/input_password.lua
@@ -1,7 +1,6 @@
local component = require("druid.component")
-local input = require("druid.extended.input")
----@class input_password: druid.component
+---@class input_password: druid.base_component
---@field druid druid_instance
---@field root node
local M = component.create("input_password")
@@ -13,7 +12,7 @@ function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
- self.input = self.druid:new(input, "input/root", "input/text", gui.KEYBOARD_TYPE_PASSWORD)
+ self.input = self.druid:new_input("input/root", "input/text", gui.KEYBOARD_TYPE_PASSWORD)
self.input:set_text("")
self.input.on_input_unselect:subscribe(function(_, text)
diff --git a/example/examples/basic/input/rich_input.gui b/example/examples/basic/input/rich_input.gui
index 108dc41..89e445d 100644
--- a/example/examples/basic/input/rich_input.gui
+++ b/example/examples/basic/input/rich_input.gui
@@ -1,918 +1,33 @@
-script: ""
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "rich_input"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/rich_input.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
- id: "rich_input/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "rich_input"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "rich_input/button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "rich_input/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -240.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 480.0
- y: 60.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Placeholder"
- font: "text_bold"
- id: "rich_input/placeholder_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 0.4
- y: 0.4
- z: 0.4
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "rich_input/button"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 1
- overridden_fields: 14
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -240.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 480.0
- y: 60.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "User input"
- font: "text_bold"
- id: "rich_input/input_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_W
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "rich_input/button"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 1
- overridden_fields: 14
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 16.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.631
- y: 0.843
- z: 0.961
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_16"
- id: "rich_input/cursor_node"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "rich_input/button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 8.0
- y: 8.0
- z: 8.0
- w: 8.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 0.5
- overridden_fields: 1
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 4.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.2
- y: 1.2
- z: 1.0
- w: 1.0
- }
- size {
- x: 20.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "|"
- font: "text_bold"
- id: "rich_input/cursor_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "rich_input/cursor_node"
- layer: ""
- inherit_alpha: false
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -150.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "rich_input_2"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/rich_input.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
- id: "rich_input_2/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "rich_input_2"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 500.0
- y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
- id: "rich_input_2/button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "rich_input_2/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 480.0
- y: 60.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Placeholder"
- font: "text_bold"
- id: "rich_input_2/placeholder_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.4
- y: 0.4
- z: 0.4
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "rich_input_2/button"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 480.0
- y: 60.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "User input"
- font: "text_bold"
- id: "rich_input_2/input_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "rich_input_2/button"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 16.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.631
- y: 0.843
- z: 0.961
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_16"
- id: "rich_input_2/cursor_node"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "rich_input_2/button"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 8.0
- y: 8.0
- z: 8.0
- w: 8.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 0.5
- overridden_fields: 1
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 4.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.2
- y: 1.2
- z: 1.0
- w: 1.0
- }
- size {
- x: 20.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "|"
- font: "text_bold"
- id: "rich_input_2/cursor_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "rich_input_2/cursor_node"
- layer: ""
- inherit_alpha: false
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/input/rich_input.lua b/example/examples/basic/input/rich_input.lua
index cef718c..a7e04ab 100644
--- a/example/examples/basic/input/rich_input.lua
+++ b/example/examples/basic/input/rich_input.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local rich_input = require("druid.custom.rich_input.rich_input")
---@class rich_input: druid.base_component
---@field druid druid_instance
@@ -11,10 +10,10 @@ local M = component.create("rich_input")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.rich_input = self.druid:new(rich_input, "rich_input") --[[@as druid.rich_input]]
+ self.rich_input = self.druid:new_rich_input("rich_input") --[[@as druid.rich_input]]
self.rich_input:set_placeholder("Enter text")
- self.rich_input_2 = self.druid:new(rich_input, "rich_input_2") --[[@as druid.rich_input]]
+ self.rich_input_2 = self.druid:new_rich_input("rich_input_2") --[[@as druid.rich_input]]
self.rich_input_2:set_placeholder("Enter text")
end
diff --git a/example/examples/basic/progress_bar/basic_progress_bar.gui b/example/examples/basic/progress_bar/basic_progress_bar.gui
index 975d78c..a46689f 100644
--- a/example/examples/basic/progress_bar/basic_progress_bar.gui
+++ b/example/examples/basic/progress_bar/basic_progress_bar.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -30,7 +30,7 @@ nodes {
z: 0.49
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "progress_bar_back"
pivot: PIVOT_W
parent: "root"
@@ -47,7 +47,7 @@ nodes {
z: 0.961
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "progress_bar_fill"
pivot: PIVOT_W
parent: "progress_bar_back"
diff --git a/example/examples/basic/progress_bar/basic_progress_bar.lua b/example/examples/basic/progress_bar/basic_progress_bar.lua
index 6681d01..fe85f93 100644
--- a/example/examples/basic/progress_bar/basic_progress_bar.lua
+++ b/example/examples/basic/progress_bar/basic_progress_bar.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local progress = require("druid.extended.progress")
---@class basic_progress_bar: druid.base_component
---@field druid druid_instance
@@ -12,7 +11,7 @@ local M = component.create("basic_progress_bar")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.progress = self.druid:new(progress, "progress_bar_fill", "x")
+ self.progress = self.druid:new_progress("progress_bar_fill", "x")
self.text_value = self:get_node("progress_value")
self:set_value(self.progress:get())
diff --git a/example/examples/basic/progress_bar/basic_progress_bar_slice9.gui b/example/examples/basic/progress_bar/basic_progress_bar_slice9.gui
index cfeff26..133f0c7 100644
--- a/example/examples/basic/progress_bar/basic_progress_bar_slice9.gui
+++ b/example/examples/basic/progress_bar/basic_progress_bar_slice9.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -30,7 +30,7 @@ nodes {
z: 0.49
}
type: TYPE_BOX
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "progress_bar_back"
pivot: PIVOT_W
parent: "root"
@@ -53,7 +53,7 @@ nodes {
z: 0.961
}
type: TYPE_BOX
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "progress_bar_fill"
pivot: PIVOT_W
parent: "progress_bar_back"
diff --git a/example/examples/basic/progress_bar/basic_progress_bar_slice9.lua b/example/examples/basic/progress_bar/basic_progress_bar_slice9.lua
index 9a73c0d..2640001 100644
--- a/example/examples/basic/progress_bar/basic_progress_bar_slice9.lua
+++ b/example/examples/basic/progress_bar/basic_progress_bar_slice9.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local progress = require("druid.extended.progress")
---@class basic_progress_bar_slice9: druid.base_component
---@field druid druid_instance
@@ -12,7 +11,7 @@ local M = component.create("basic_progress_bar_slice9")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.progress = self.druid:new(progress, "progress_bar_fill", "x")
+ self.progress = self.druid:new_progress("progress_bar_fill", "x")
self.text_value = self:get_node("progress_value")
self:set_value(self.progress:get())
diff --git a/example/examples/basic/radio_group/radio_group.gui b/example/examples/basic/radio_group/radio_group.gui
index f4b822a..a51e797 100644
--- a/example/examples/basic/radio_group/radio_group.gui
+++ b/example/examples/basic/radio_group/radio_group.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -27,55 +27,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/basic/checkbox/checkbox.gui"
}
-nodes {
- type: TYPE_BOX
- id: "checkbox_1/root"
- parent: "checkbox_1"
- template_node_child: true
-}
-nodes {
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- }
- type: TYPE_BOX
- texture: "druid/ui_circle_32"
- id: "checkbox_1/button"
- parent: "checkbox_1/root"
- slice9 {
- x: 8.0
- y: 8.0
- z: 8.0
- w: 8.0
- }
- overridden_fields: 5
- overridden_fields: 9
- overridden_fields: 22
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- texture: "druid/ui_circle_16"
- id: "checkbox_1/icon"
- parent: "checkbox_1/button"
- overridden_fields: 9
- template_node_child: true
-}
-nodes {
- position {
- y: -8.0
- }
- type: TYPE_BOX
- texture: "druid/ui_circle_16"
- id: "checkbox_1/selected"
- parent: "checkbox_1/button"
- overridden_fields: 1
- overridden_fields: 9
- overridden_fields: 38
- template_node_child: true
- size_mode: SIZE_MODE_AUTO
-}
nodes {
type: TYPE_TEMPLATE
id: "checkbox_2"
@@ -83,55 +34,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/basic/checkbox/checkbox.gui"
}
-nodes {
- type: TYPE_BOX
- id: "checkbox_2/root"
- parent: "checkbox_2"
- template_node_child: true
-}
-nodes {
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- }
- type: TYPE_BOX
- texture: "druid/ui_circle_32"
- id: "checkbox_2/button"
- parent: "checkbox_2/root"
- slice9 {
- x: 8.0
- y: 8.0
- z: 8.0
- w: 8.0
- }
- overridden_fields: 5
- overridden_fields: 9
- overridden_fields: 22
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- texture: "druid/ui_circle_16"
- id: "checkbox_2/icon"
- parent: "checkbox_2/button"
- overridden_fields: 9
- template_node_child: true
-}
-nodes {
- position {
- y: -8.0
- }
- type: TYPE_BOX
- texture: "druid/ui_circle_16"
- id: "checkbox_2/selected"
- parent: "checkbox_2/button"
- overridden_fields: 1
- overridden_fields: 9
- overridden_fields: 38
- template_node_child: true
- size_mode: SIZE_MODE_AUTO
-}
nodes {
position {
x: 100.0
@@ -142,54 +44,5 @@ nodes {
inherit_alpha: true
template: "/example/examples/basic/checkbox/checkbox.gui"
}
-nodes {
- type: TYPE_BOX
- id: "checkbox_3/root"
- parent: "checkbox_3"
- template_node_child: true
-}
-nodes {
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- }
- type: TYPE_BOX
- texture: "druid/ui_circle_32"
- id: "checkbox_3/button"
- parent: "checkbox_3/root"
- slice9 {
- x: 8.0
- y: 8.0
- z: 8.0
- w: 8.0
- }
- overridden_fields: 5
- overridden_fields: 9
- overridden_fields: 22
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- texture: "druid/ui_circle_16"
- id: "checkbox_3/icon"
- parent: "checkbox_3/button"
- overridden_fields: 9
- template_node_child: true
-}
-nodes {
- position {
- y: -8.0
- }
- type: TYPE_BOX
- texture: "druid/ui_circle_16"
- id: "checkbox_3/selected"
- parent: "checkbox_3/button"
- overridden_fields: 1
- overridden_fields: 9
- overridden_fields: 38
- template_node_child: true
- size_mode: SIZE_MODE_AUTO
-}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/basic/radio_group/radio_group.lua b/example/examples/basic/radio_group/radio_group.lua
index 1b74273..b1ac9bb 100644
--- a/example/examples/basic/radio_group/radio_group.lua
+++ b/example/examples/basic/radio_group/radio_group.lua
@@ -1,5 +1,5 @@
local component = require("druid.component")
-local event = require("druid.event")
+local event = require("event.event")
-- Require checkbox component from checkbox example
local checkbox = require("example.examples.basic.checkbox.checkbox")
diff --git a/example/examples/basic/rich_text/basic_rich_text.gui b/example/examples/basic/rich_text/basic_rich_text.gui
index 659924a..f51575b 100644
--- a/example/examples/basic/rich_text/basic_rich_text.gui
+++ b/example/examples/basic/rich_text/basic_rich_text.gui
@@ -7,8 +7,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
diff --git a/example/examples/basic/rich_text/basic_rich_text.lua b/example/examples/basic/rich_text/basic_rich_text.lua
index 3abb632..e61226b 100644
--- a/example/examples/basic/rich_text/basic_rich_text.lua
+++ b/example/examples/basic/rich_text/basic_rich_text.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local rich_text = require("druid.custom.rich_text.rich_text")
---@class basic_rich_text: druid.base_component
---@field druid druid_instance
@@ -11,7 +10,7 @@ local M = component.create("basic_rich_text")
---@param nodes table
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.druid:new(rich_text, "text", "Hello, I'm a Rich Text!")
+ self.druid:new_rich_text("text", "Hello, I'm a Rich Text!")
end
diff --git a/example/examples/basic/rich_text/rich_text_tags.gui b/example/examples/basic/rich_text/rich_text_tags.gui
index de6d63e..0105d87 100644
--- a/example/examples/basic/rich_text/rich_text_tags.gui
+++ b/example/examples/basic/rich_text/rich_text_tags.gui
@@ -7,8 +7,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
textures {
name: "druid_logo"
@@ -35,7 +35,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "background"
parent: "root"
inherit_alpha: true
diff --git a/example/examples/basic/rich_text/rich_text_tags.lua b/example/examples/basic/rich_text/rich_text_tags.lua
index 69f65cb..3e92a8f 100644
--- a/example/examples/basic/rich_text/rich_text_tags.lua
+++ b/example/examples/basic/rich_text/rich_text_tags.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local rich_text = require("druid.custom.rich_text.rich_text")
local helper = require("druid.helper")
---@class rich_text_tags: druid.base_component
@@ -13,20 +12,20 @@ local M = component.create("rich_text_tags")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.rich_text_color = self.druid:new(rich_text, "rich_text_color") --[[@as druid.rich_text]]
+ self.rich_text_color = self.druid:new_rich_text("rich_text_color") --[[@as druid.rich_text]]
self.rich_text_color:set_text("Hello, I'm a Rich Text and it's nested color tag")
- self.rich_text_font = self.druid:new(rich_text, "rich_text_font") --[[@as druid.rich_text]]
+ self.rich_text_font = self.druid:new_rich_text("rich_text_font") --[[@as druid.rich_text]]
self.rich_text_font:set_text("Hello, I'm a Rich Text and this is bold text")
- self.rich_text_size = self.druid:new(rich_text, "rich_text_size") --[[@as druid.rich_text]]
+ self.rich_text_size = self.druid:new_rich_text("rich_text_size") --[[@as druid.rich_text]]
self.rich_text_size:set_text("Hello, I'm have East Pivot and different text scale")
- self.rich_text_breaks = self.druid:new(rich_text, "rich_text_breaks") --[[@as druid.rich_text]]
+ self.rich_text_breaks = self.druid:new_rich_text("rich_text_breaks") --[[@as druid.rich_text]]
self.rich_text_breaks:set_text("Hello, I'm Rich Text With \"Line Breaks\"\nEnabled in GUI")
- self.rich_text_image = self.druid:new(rich_text, "rich_text_image") --[[@as druid.rich_text]]
- self.rich_text_image:set_text("Hello, I'mRich Text ")
+ self.rich_text_image = self.druid:new_rich_text("rich_text_image") --[[@as druid.rich_text]]
+ self.rich_text_image:set_text("Hello, I'mRich Text ")
self.position = {
[self.rich_text_color] = gui.get_position(self.rich_text_color.root),
diff --git a/example/examples/basic/rich_text/rich_text_tags_custom.gui b/example/examples/basic/rich_text/rich_text_tags_custom.gui
index 3c17183..28981a8 100644
--- a/example/examples/basic/rich_text/rich_text_tags_custom.gui
+++ b/example/examples/basic/rich_text/rich_text_tags_custom.gui
@@ -7,8 +7,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
diff --git a/example/examples/basic/rich_text/rich_text_tags_custom.lua b/example/examples/basic/rich_text/rich_text_tags_custom.lua
index 14d92e2..38adf14 100644
--- a/example/examples/basic/rich_text/rich_text_tags_custom.lua
+++ b/example/examples/basic/rich_text/rich_text_tags_custom.lua
@@ -1,7 +1,6 @@
local component = require("druid.component")
-local rich_text = require("druid.custom.rich_text.rich_text")
local helper = require("druid.helper")
-local event = require("druid.event")
+local event = require("event.event")
---@class rich_text_tags_custom: druid.base_component
---@field druid druid_instance
@@ -15,7 +14,7 @@ function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
do -- Init rich text with links example
- self.rich_text_link = self.druid:new(rich_text, "rich_text_link") --[[@as druid.rich_text]]
+ self.rich_text_link = self.druid:new_rich_text("rich_text_link") --[[@as druid.rich_text]]
self.rich_text_link:set_text("Hello, I'm a Custom Link")
local tagged = self.rich_text_link:tagged("custom_link")
@@ -27,10 +26,10 @@ function M:init(template, nodes)
end
end
- self.rich_text_characters = self.druid:new(rich_text, "rich_text_characters") --[[@as druid.rich_text]]
+ self.rich_text_characters = self.druid:new_rich_text("rich_text_characters") --[[@as druid.rich_text]]
self.rich_text_characters:set_text("Hello, I'm a have a splitted characters")
- self.rich_text_custom = self.druid:new(rich_text, "rich_text_custom") --[[@as druid.rich_text]]
+ self.rich_text_custom = self.druid:new_rich_text("rich_text_custom") --[[@as druid.rich_text]]
self.rich_text_custom:set_text("Hello, I'm have South Text Pivot to adjust different text scale")
self.position = {
diff --git a/example/examples/basic/scroll/scroll.gui b/example/examples/basic/scroll/scroll.gui
index 8931adf..fe6722b 100644
--- a/example/examples/basic/scroll/scroll.gui
+++ b/example/examples/basic/scroll/scroll.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -27,7 +27,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "scroll_view"
parent: "root"
inherit_alpha: true
@@ -53,7 +53,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_content"
pivot: PIVOT_N
parent: "scroll_view"
@@ -76,20 +76,6 @@ nodes {
inherit_alpha: true
template: "/example/templates/button_text_green.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_tutorial/root"
- parent: "button_tutorial"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "I do nothing!"
- id: "button_tutorial/text"
- parent: "button_tutorial/root"
- overridden_fields: 8
- template_node_child: true
-}
nodes {
position {
x: -185.0
@@ -302,32 +288,6 @@ nodes {
inherit_alpha: true
template: "/example/templates/button_text_green.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_stencil/root"
- parent: "button_stencil"
- template_node_child: true
-}
-nodes {
- scale {
- x: 0.8
- y: 0.8
- }
- size {
- x: 300.0
- y: 50.0
- }
- type: TYPE_TEXT
- text: "Click outside stencil node"
- id: "button_stencil/text"
- line_break: true
- parent: "button_stencil/root"
- overridden_fields: 3
- overridden_fields: 4
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
-}
nodes {
position {
x: -185.0
diff --git a/example/examples/basic/scroll_bind_grid/scroll_bind_grid.gui b/example/examples/basic/scroll_bind_grid/scroll_bind_grid.gui
index f713ea6..5fabe31 100644
--- a/example/examples/basic/scroll_bind_grid/scroll_bind_grid.gui
+++ b/example/examples/basic/scroll_bind_grid/scroll_bind_grid.gui
@@ -1,117 +1,40 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 400.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 400.0
y: 800.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -120,175 +43,48 @@ nodes {
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 800.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -400.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 300.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 300.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -296,84 +92,35 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 240.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Grid Item 1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/scroll_bind_grid/scroll_bind_grid.lua b/example/examples/basic/scroll_bind_grid/scroll_bind_grid.lua
index ba62a6e..f026f74 100644
--- a/example/examples/basic/scroll_bind_grid/scroll_bind_grid.lua
+++ b/example/examples/basic/scroll_bind_grid/scroll_bind_grid.lua
@@ -2,7 +2,7 @@ local component = require("druid.component")
---@class scroll_bind_grid: druid.base_component
---@field scroll druid.scroll
----@field grid druid.static_grid
+---@field grid druid.grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("scroll_bind_grid")
@@ -19,7 +19,7 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", "prefab", 1)
+ self.grid = self.druid:new_grid("content", "prefab", 1)
self.scroll:bind_grid(self.grid)
for index = 1, 20 do
diff --git a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.gui b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.gui
index 7165b82..18ad39c 100644
--- a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.gui
+++ b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.gui
@@ -1,117 +1,40 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: -450.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 900.0
y: 360.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -120,175 +43,48 @@ nodes {
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 900.0
y: 360.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: 450.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 270.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 190.0
y: 250.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -296,84 +92,36 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 150.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Grid Item 1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.lua b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.lua
index ce762f5..7e26681 100644
--- a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.lua
+++ b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.lua
@@ -2,7 +2,7 @@ local component = require("druid.component")
---@class scroll_bind_grid_horizontal: druid.base_component
---@field scroll druid.scroll
----@field grid druid.static_grid
+---@field grid druid.grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("scroll_bind_grid_horizontal")
@@ -19,7 +19,7 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", "prefab", 99999)
+ self.grid = self.druid:new_grid("content", "prefab", 99999)
self.scroll:bind_grid(self.grid)
for index = 1, 30 do
diff --git a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.gui b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.gui
index 165fbf2..a973517 100644
--- a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.gui
+++ b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -12,7 +12,7 @@ nodes {
y: 1000.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
inherit_alpha: true
visible: false
@@ -31,7 +31,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "view"
pivot: PIVOT_N
parent: "root"
@@ -50,7 +50,7 @@ nodes {
y: 800.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
pivot: PIVOT_N
parent: "view"
@@ -82,7 +82,7 @@ nodes {
z: 0.961
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
parent: "prefab"
inherit_alpha: true
diff --git a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.lua b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.lua
index d1d6ccc..91f185a 100644
--- a/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.lua
+++ b/example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.lua
@@ -2,7 +2,7 @@ local component = require("druid.component")
---@class scroll_bind_grid_points: druid.base_component
---@field scroll druid.scroll
----@field grid druid.static_grid
+---@field grid druid.grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("scroll_bind_grid_points")
@@ -19,7 +19,7 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", "prefab", 1)
+ self.grid = self.druid:new_grid("content", "prefab", 1)
self.scroll:bind_grid(self.grid)
for index = 1, 20 do
diff --git a/example/examples/basic/scroll_slider/scroll_slider.gui b/example/examples/basic/scroll_slider/scroll_slider.gui
index caf0a41..0766e91 100644
--- a/example/examples/basic/scroll_slider/scroll_slider.gui
+++ b/example/examples/basic/scroll_slider/scroll_slider.gui
@@ -1,117 +1,35 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 400.0
y: 1000.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "scroll_view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -120,57 +38,25 @@ nodes {
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: 500.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 400.0
y: 2600.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "scroll_content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "scroll_view"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -178,2340 +64,177 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button1"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button1/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button1"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 1"
- font: "text_bold"
- id: "button1/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button1/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -300.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button2"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button2/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button2"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 2"
- font: "text_bold"
- id: "button2/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button2/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -500.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button3"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button3/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button3"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 3"
- font: "text_bold"
- id: "button3/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button3/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -700.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button4"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button4/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button4"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 4"
- font: "text_bold"
- id: "button4/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button4/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -900.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button5"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button5/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button5"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 5"
- font: "text_bold"
- id: "button5/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button5/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -1100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button6"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button6/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button6"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 6"
- font: "text_bold"
- id: "button6/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button6/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -1300.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button7"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button7/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button7"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 7"
- font: "text_bold"
- id: "button7/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button7/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -1500.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button8"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button8/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button8"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 8"
- font: "text_bold"
- id: "button8/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button8/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -1700.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button9"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button9/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button9"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 9"
- font: "text_bold"
- id: "button9/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button9/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -1900.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button10"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button10/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button10"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 10"
- font: "text_bold"
- id: "button10/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button10/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -2100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button11"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button11/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button11"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 11"
- font: "text_bold"
- id: "button11/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button11/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -2300.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button12"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button12/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button12"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 12"
- font: "text_bold"
- id: "button12/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button12/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: -2500.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button13"
parent: "scroll_content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button13/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button13"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 0.9
- y: 0.9
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Tap to scroll 13"
- font: "text_bold"
- id: "button13/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: true
- parent: "button13/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 3
- overridden_fields: 8
- overridden_fields: 18
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 200.0
y: 500.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 16.0
y: 1000.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "slider_back"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_NE
- adjust_mode: ADJUST_MODE_FIT
parent: "scroll_view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -8.0
y: -24.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 16.0
y: 48.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "slider_pin"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "slider_back"
- layer: ""
inherit_alpha: true
slice9 {
x: 8.0
@@ -2519,17 +242,6 @@ nodes {
z: 8.0
w: 8.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/scroll_slider/scroll_slider.lua b/example/examples/basic/scroll_slider/scroll_slider.lua
index 79723ef..0627f82 100644
--- a/example/examples/basic/scroll_slider/scroll_slider.lua
+++ b/example/examples/basic/scroll_slider/scroll_slider.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local slider = require("druid.extended.slider")
---@class scroll_slider: druid.base_component
---@field root node
@@ -16,7 +15,7 @@ function M:init(template, nodes)
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
self.scroll.on_scroll:subscribe(self.on_scroll)
- self.slider = self.druid:new(slider, "slider_pin", vmath.vector3(-8, -976, 0), self.on_slider) --[[@as druid.slider]]
+ self.slider = self.druid:new_slider("slider_pin", vmath.vector3(-8, -976, 0), self.on_slider) --[[@as druid.slider]]
self.slider:set_input_node("slider_back")
self.druid:new_hover("slider_back", nil, self.on_slider_back_hover)
diff --git a/example/examples/basic/slider/basic_slider.gui b/example/examples/basic/slider/basic_slider.gui
index a8f132a..7c15e3e 100644
--- a/example/examples/basic/slider/basic_slider.gui
+++ b/example/examples/basic/slider/basic_slider.gui
@@ -1,58 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 32.0
@@ -60,303 +26,45 @@ nodes {
z: 32.0
w: 32.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "slider"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/slider.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 260.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.129
- y: 0.141
- z: 0.157
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "slider/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "slider"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 260.0
- y: 8.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.129
- y: 0.141
- z: 0.157
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
- id: "slider/slider_back"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "slider/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -118.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 24.0
- y: 24.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
- id: "slider/slider_pin"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "slider/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: 50.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 150.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "0 %"
font: "text_bold"
id: "slider_value"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/slider/basic_slider.lua b/example/examples/basic/slider/basic_slider.lua
index 05fcabc..73fe031 100644
--- a/example/examples/basic/slider/basic_slider.lua
+++ b/example/examples/basic/slider/basic_slider.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local slider = require("druid.extended.slider")
---@class basic_slider: druid.base_component
---@field druid druid_instance
@@ -13,7 +12,7 @@ local M = component.create("basic_slider")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.slider = self.druid:new(slider, "slider/slider_pin", vmath.vector3(118, 0, 0), self.on_slider_change) --[[@as druid.slider]]
+ self.slider = self.druid:new_slider("slider/slider_pin", vmath.vector3(118, 0, 0), self.on_slider_change) --[[@as druid.slider]]
-- To add input across all slider widget add a root node to acquire additional input
self.slider:set_input_node("slider/root")
diff --git a/example/examples/basic/slider/basic_slider_stepped.gui b/example/examples/basic/slider/basic_slider_stepped.gui
index a8f132a..7c15e3e 100644
--- a/example/examples/basic/slider/basic_slider_stepped.gui
+++ b/example/examples/basic/slider/basic_slider_stepped.gui
@@ -1,58 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 32.0
@@ -60,303 +26,45 @@ nodes {
z: 32.0
w: 32.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "slider"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/slider.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 260.0
- y: 40.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.129
- y: 0.141
- z: 0.157
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
- id: "slider/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "slider"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 260.0
- y: 8.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.129
- y: 0.141
- z: 0.157
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
- id: "slider/slider_back"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "slider/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: -118.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 24.0
- y: 24.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.722
- y: 0.741
- z: 0.761
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
- id: "slider/slider_pin"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "slider/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 4.0
- y: 4.0
- z: 4.0
- w: 4.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
y: 50.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 150.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "0 %"
font: "text_bold"
id: "slider_value"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/slider/basic_slider_stepped.lua b/example/examples/basic/slider/basic_slider_stepped.lua
index 02becaf..8a22642 100644
--- a/example/examples/basic/slider/basic_slider_stepped.lua
+++ b/example/examples/basic/slider/basic_slider_stepped.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local slider = require("druid.extended.slider")
---@class basic_slider_stepped: druid.base_component
---@field druid druid_instance
@@ -13,7 +12,7 @@ local M = component.create("basic_slider_stepped")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.slider = self.druid:new(slider, "slider/slider_pin", vmath.vector3(118, 0, 0), self.on_slider_change) --[[@as druid.slider]]
+ self.slider = self.druid:new_slider("slider/slider_pin", vmath.vector3(118, 0, 0), self.on_slider_change) --[[@as druid.slider]]
-- To add input across all slider widget add a root node to acquire additional input
self.slider:set_input_node("slider/root")
diff --git a/example/examples/basic/slider/basic_slider_vertical.gui b/example/examples/basic/slider/basic_slider_vertical.gui
index f039094..b59f960 100644
--- a/example/examples/basic/slider/basic_slider_vertical.gui
+++ b/example/examples/basic/slider/basic_slider_vertical.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -17,7 +17,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
@@ -34,38 +34,6 @@ nodes {
inherit_alpha: true
template: "/example/templates/slider.gui"
}
-nodes {
- size {
- x: 40.0
- y: 260.0
- }
- type: TYPE_BOX
- id: "slider/root"
- parent: "slider"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- size {
- x: 9.0
- y: 260.0
- }
- type: TYPE_BOX
- id: "slider/slider_back"
- parent: "slider/root"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- position {
- y: 118.0
- }
- type: TYPE_BOX
- id: "slider/slider_pin"
- parent: "slider/root"
- overridden_fields: 1
- template_node_child: true
-}
nodes {
position {
y: 170.0
diff --git a/example/examples/basic/slider/basic_slider_vertical.lua b/example/examples/basic/slider/basic_slider_vertical.lua
index ba3eff7..bbeb019 100644
--- a/example/examples/basic/slider/basic_slider_vertical.lua
+++ b/example/examples/basic/slider/basic_slider_vertical.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local slider = require("druid.extended.slider")
---@class basic_slider_vertical: druid.base_component
---@field druid druid_instance
@@ -13,7 +12,7 @@ local M = component.create("basic_slider_vertical")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.slider = self.druid:new(slider, "slider/slider_pin", vmath.vector3(0, -118, 0), self.on_slider_change) --[[@as druid.slider]]
+ self.slider = self.druid:new_slider("slider/slider_pin", vmath.vector3(0, -118, 0), self.on_slider_change) --[[@as druid.slider]]
-- To add input across all slider widget add a root node to acquire additional input
self.slider:set_input_node("slider/root")
diff --git a/example/examples/basic/swipe/basic_swipe.gui b/example/examples/basic/swipe/basic_swipe.gui
index 8faba60..5889073 100644
--- a/example/examples/basic/swipe/basic_swipe.gui
+++ b/example/examples/basic/swipe/basic_swipe.gui
@@ -1,58 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 1000.0
y: 1000.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 32.0
@@ -60,84 +26,35 @@ nodes {
z: 32.0
w: 32.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Swipe across area to action"
font: "text_bold"
id: "swipe_hint"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/swipe/basic_swipe.lua b/example/examples/basic/swipe/basic_swipe.lua
index e8d768a..ca56596 100644
--- a/example/examples/basic/swipe/basic_swipe.lua
+++ b/example/examples/basic/swipe/basic_swipe.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local swipe = require("druid.extended.swipe")
---@class basic_swipe: druid.base_component
---@field druid druid_instance
@@ -10,7 +9,7 @@ local M = component.create("basic_swipe")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.swipe = self.druid:new(swipe, "root", self.on_swipe) --[[@as druid.swipe]]
+ self.swipe = self.druid:new_swipe("root", self.on_swipe) --[[@as druid.swipe]]
self.text_hint = self:get_node("swipe_hint")
end
diff --git a/example/examples/basic/text/basic_text.gui b/example/examples/basic/text/basic_text.gui
index 185debb..0fb22eb 100644
--- a/example/examples/basic/text/basic_text.gui
+++ b/example/examples/basic/text/basic_text.gui
@@ -1,117 +1,36 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 100.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "text_area"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,84 +38,34 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 100.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Example text with default adjust"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "text_area"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/text/basic_text.lua b/example/examples/basic/text/basic_text.lua
index 63889c5..dca1682 100644
--- a/example/examples/basic/text/basic_text.lua
+++ b/example/examples/basic/text/basic_text.lua
@@ -1,7 +1,5 @@
local helper = require("druid.helper")
local component = require("druid.component")
-local container = require("example.components.container.container")
-local lang_text = require("druid.extended.lang_text")
---@class basic_text: druid.base_component
---@field druid druid_instance
@@ -16,7 +14,7 @@ function M:init(template, nodes)
self.text = self.druid:new_text("text")
-- This code is for adjustable text area with mouse
- self.container = self.druid:new(container, "text_area", nil, function(_, size)
+ self.container = self.druid:new_container("text_area", nil, function(_, size)
self.text:set_size(size)
self:refresh_text_position()
end) --[[@as druid.container]]
diff --git a/example/examples/basic/text/multiline_text.gui b/example/examples/basic/text/multiline_text.gui
index 3a66171..b4c491a 100644
--- a/example/examples/basic/text/multiline_text.gui
+++ b/example/examples/basic/text/multiline_text.gui
@@ -1,117 +1,36 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 100.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "text_area"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,84 +38,35 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 100.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Example multiline text with default adjust"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "text_area"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/basic/text/multiline_text.lua b/example/examples/basic/text/multiline_text.lua
index 56f78c8..d50de10 100644
--- a/example/examples/basic/text/multiline_text.lua
+++ b/example/examples/basic/text/multiline_text.lua
@@ -1,6 +1,5 @@
local helper = require("druid.helper")
local component = require("druid.component")
-local container = require("example.components.container.container")
---@class multiline_text: druid.base_component
---@field root node
@@ -16,7 +15,7 @@ function M:init(template, nodes)
self.text = self.druid:new_text("text")
-- This code is for adjustable text area with mouse
- self.container = self.druid:new(container, "text_area", nil, function(_, size)
+ self.container = self.druid:new_container("text_area", nil, function(_, size)
self.text:set_size(size)
self:refresh_text_position()
end) --[[@as druid.container]]
diff --git a/example/examples/basic/timer/basic_timer.lua b/example/examples/basic/timer/basic_timer.lua
index 72fcca4..1687628 100644
--- a/example/examples/basic/timer/basic_timer.lua
+++ b/example/examples/basic/timer/basic_timer.lua
@@ -1,9 +1,8 @@
-local event = require("druid.event")
-local timer = require("druid.extended.timer")
+local event = require("event.event")
local component = require("druid.component")
----@class basic_timer: druid.component
+---@class basic_timer: druid.base_component
---@field druid druid_instance
---@field root node
---@field text druid.text
@@ -16,7 +15,7 @@ function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
- self.timer = self.druid:new(timer, "text")
+ self.timer = self.druid:new_timer("text")
local time = 5
self.timer:set_interval(time, 0)
diff --git a/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.gui b/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.gui
index c45c867..3fad7ab 100644
--- a/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.gui
+++ b/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.gui
@@ -1,294 +1,81 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 350.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 350.0
y: 700.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 350.0
y: 700.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -400.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 300.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 300.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -296,84 +83,35 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 250.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.lua b/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.lua
index bdc6eca..b4ab3f6 100644
--- a/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.lua
+++ b/example/examples/data_list/add_remove_clear/data_list_add_remove_clear.lua
@@ -1,6 +1,5 @@
-local event = require("druid.event")
+local event = require("event.event")
local component = require("druid.component")
-local data_list = require("druid.extended.data_list")
---@class data_list_add_remove_clear: druid.base_component
---@field druid druid_instance
@@ -17,8 +16,8 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", self.prefab, 1)
- self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
+ self.grid = self.druid:new_grid("content", self.prefab, 1)
+ self.data_list = self.druid:new_data_list(self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
local data = {}
for index = 1, 20 do
@@ -26,7 +25,7 @@ function M:init(template, nodes)
end
self.data_list:set_data(data)
- self.on_item_click = event()
+ self.on_item_click = event.create()
end
diff --git a/example/examples/data_list/basic/data_list_basic.gui b/example/examples/data_list/basic/data_list_basic.gui
index c45c867..3fad7ab 100644
--- a/example/examples/data_list/basic/data_list_basic.gui
+++ b/example/examples/data_list/basic/data_list_basic.gui
@@ -1,294 +1,81 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 350.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 350.0
y: 700.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 350.0
y: 700.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -400.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 300.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 300.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -296,84 +83,35 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 250.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/data_list/basic/data_list_basic.lua b/example/examples/data_list/basic/data_list_basic.lua
index b3a3d81..f950b73 100644
--- a/example/examples/data_list/basic/data_list_basic.lua
+++ b/example/examples/data_list/basic/data_list_basic.lua
@@ -1,6 +1,5 @@
-local event = require("druid.event")
+local event = require("event.event")
local component = require("druid.component")
-local data_list = require("druid.extended.data_list")
---@class data_list_basic: druid.base_component
---@field druid druid_instance
@@ -16,8 +15,8 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", self.prefab, 1)
- self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
+ self.grid = self.druid:new_grid("content", self.prefab, 1)
+ self.data_list = self.druid:new_data_list(self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
local data = {}
for index = 1, 1000 do
@@ -25,7 +24,7 @@ function M:init(template, nodes)
end
self.data_list:set_data(data)
- self.on_item_click = event()
+ self.on_item_click = event.create()
end
diff --git a/example/examples/data_list/basic/data_list_horizontal_basic.gui b/example/examples/data_list/basic/data_list_horizontal_basic.gui
index 31f4823..e6e975b 100644
--- a/example/examples/data_list/basic/data_list_horizontal_basic.gui
+++ b/example/examples/data_list/basic/data_list_horizontal_basic.gui
@@ -1,294 +1,81 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: -450.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 900.0
y: 350.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 900.0
y: 350.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
x: 450.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 200.0
y: 270.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 190.0
y: 250.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -296,84 +83,36 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 150.0
y: 200.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/data_list/basic/data_list_horizontal_basic.lua b/example/examples/data_list/basic/data_list_horizontal_basic.lua
index 0f21fc7..262bea1 100644
--- a/example/examples/data_list/basic/data_list_horizontal_basic.lua
+++ b/example/examples/data_list/basic/data_list_horizontal_basic.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local data_list = require("druid.extended.data_list")
---@class data_list_horizontal_basic: druid.base_component
---@field druid druid_instance
@@ -15,8 +14,8 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", self.prefab, 1000)
- self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
+ self.grid = self.druid:new_grid("content", self.prefab, 1000)
+ self.data_list = self.druid:new_data_list(self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
local data = {}
for index = 1, 100 do
diff --git a/example/examples/data_list/cache_with_component/button_component.gui b/example/examples/data_list/cache_with_component/button_component.gui
index f3c8623..42d14cc 100644
--- a/example/examples/data_list/cache_with_component/button_component.gui
+++ b/example/examples/data_list/cache_with_component/button_component.gui
@@ -1,117 +1,35 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 300.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 300.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,84 +37,35 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 250.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/data_list/cache_with_component/cache_with_component.gui b/example/examples/data_list/cache_with_component/cache_with_component.gui
index f39b933..1be4909 100644
--- a/example/examples/data_list/cache_with_component/cache_with_component.gui
+++ b/example/examples/data_list/cache_with_component/cache_with_component.gui
@@ -1,421 +1,62 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 350.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 350.0
y: 700.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "view"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
clipping_mode: CLIPPING_MODE_STENCIL
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 350.0
y: 700.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "view"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: -300.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button_component"
parent: "content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/examples/data_list/cache_with_component/button_component.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 300.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
- id: "button_component/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button_component"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: false
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 300.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.631
- y: 0.843
- z: 0.961
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button_component/panel"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button_component/root"
- layer: ""
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 250.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Data Item 1"
- font: "text_bold"
- id: "button_component/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button_component/root"
- layer: ""
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/data_list/cache_with_component/cache_with_component.lua b/example/examples/data_list/cache_with_component/cache_with_component.lua
index ca308e2..1c2a0ac 100644
--- a/example/examples/data_list/cache_with_component/cache_with_component.lua
+++ b/example/examples/data_list/cache_with_component/cache_with_component.lua
@@ -1,6 +1,5 @@
-local event = require("druid.event")
+local event = require("event.event")
local component = require("druid.component")
-local data_list = require("druid.extended.data_list")
local button_component = require("example.examples.data_list.cache_with_component.button_component")
@@ -18,8 +17,8 @@ function M:init(template, nodes)
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
- self.grid = self.druid:new_static_grid("content", self.prefab, 1)
- self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
+ self.grid = self.druid:new_grid("content", self.prefab, 1)
+ self.data_list = self.druid:new_data_list(self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
self.data_list:set_use_cache(true)
self.data_list.on_element_add:subscribe(self.on_element_add)
self.data_list.on_element_remove:subscribe(self.on_element_remove)
@@ -30,7 +29,7 @@ function M:init(template, nodes)
end
self.data_list:set_data(data)
- self.on_item_click = event()
+ self.on_item_click = event.create()
end
@@ -52,7 +51,7 @@ end
---@param instance button_component
---@param data table
function M:on_element_add(index, node, instance, data)
- instance.text:set_to("Data Item " .. index)
+ instance.text:set_text("Data Item " .. index)
instance.button.on_click:subscribe(self.on_button_click, self)
instance:set_data(index)
end
diff --git a/example/examples/druid_examples.lua b/example/examples/druid_examples.lua
index 6303e80..62ec6d2 100644
--- a/example/examples/druid_examples.lua
+++ b/example/examples/druid_examples.lua
@@ -18,8 +18,9 @@ local M = {}
---@field root string
---@field template string|nil
---@field code_url string|nil @URL to the source code
----@field component_class druid.base_component
----@field on_create fun(instance: druid.base_component, output_list: output_list)|nil
+---@field component_class druid.base_component|nil
+---@field widget_class druid.widget|nil New way to create components
+---@field on_create fun(instance: druid.base_component|druid.widget, output_list: output_list)|nil
---@field get_debug_info (fun(instance: druid.base_component):string)|nil
---@field properties_control (fun(instance: druid.base_component, properties_panel: properties_panel))|nil
---@field information_text_id string|nil
diff --git a/example/examples/gamepad/gamepad_tester/gamepad_tester.gui b/example/examples/gamepad/gamepad_tester/gamepad_tester.gui
index a6904ed..4dbc25b 100644
--- a/example/examples/gamepad/gamepad_tester/gamepad_tester.gui
+++ b/example/examples/gamepad/gamepad_tester/gamepad_tester.gui
@@ -1,6 +1,6 @@
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -8,7 +8,7 @@ nodes {
y: 1000.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
inherit_alpha: true
visible: false
@@ -19,7 +19,7 @@ nodes {
y: 100.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "gamepad"
parent: "root"
inherit_alpha: true
@@ -36,66 +36,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui"
}
-nodes {
- type: TYPE_BOX
- id: "stick_left/root"
- parent: "stick_left"
- template_node_child: true
-}
-nodes {
- type: TYPE_PIE
- id: "stick_left/background_mask"
- parent: "stick_left/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/background"
- parent: "stick_left/background_mask"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/stick_root"
- parent: "stick_left/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/stick_shadow"
- parent: "stick_left/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/stick"
- parent: "stick_left/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/dot_1"
- parent: "stick_left/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/dot_2"
- parent: "stick_left/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/dot_3"
- parent: "stick_left/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_left/dot_4"
- parent: "stick_left/stick"
- template_node_child: true
-}
nodes {
position {
x: 200.0
@@ -107,66 +47,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui"
}
-nodes {
- type: TYPE_BOX
- id: "stick_right/root"
- parent: "stick_right"
- template_node_child: true
-}
-nodes {
- type: TYPE_PIE
- id: "stick_right/background_mask"
- parent: "stick_right/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/background"
- parent: "stick_right/background_mask"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/stick_root"
- parent: "stick_right/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/stick_shadow"
- parent: "stick_right/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/stick"
- parent: "stick_right/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/dot_1"
- parent: "stick_right/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/dot_2"
- parent: "stick_right/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/dot_3"
- parent: "stick_right/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "stick_right/dot_4"
- parent: "stick_right/stick"
- template_node_child: true
-}
nodes {
position {
x: -330.0
@@ -177,7 +57,7 @@ nodes {
y: 290.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "dpad"
parent: "gamepad"
inherit_alpha: true
@@ -193,32 +73,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_left/button"
- parent: "button_left"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button_left/text"
- parent: "button_left/button"
- overridden_fields: 45
- overridden_fields: 46
- template_node_child: true
- enabled: false
- visible: false
-}
-nodes {
- rotation {
- z: 180.0
- }
- type: TYPE_BOX
- id: "button_left/icon"
- parent: "button_left/button"
- overridden_fields: 2
- template_node_child: true
-}
nodes {
position {
y: 100.0
@@ -229,32 +83,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_up/button"
- parent: "button_up"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button_up/text"
- parent: "button_up/button"
- overridden_fields: 45
- overridden_fields: 46
- template_node_child: true
- enabled: false
- visible: false
-}
-nodes {
- rotation {
- z: 90.0
- }
- type: TYPE_BOX
- id: "button_up/icon"
- parent: "button_up/button"
- overridden_fields: 2
- template_node_child: true
-}
nodes {
position {
x: 100.0
@@ -265,28 +93,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_right/button"
- parent: "button_right"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button_right/text"
- parent: "button_right/button"
- overridden_fields: 45
- overridden_fields: 46
- template_node_child: true
- enabled: false
- visible: false
-}
-nodes {
- type: TYPE_BOX
- id: "button_right/icon"
- parent: "button_right/button"
- template_node_child: true
-}
nodes {
position {
y: -100.0
@@ -297,32 +103,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_down/button"
- parent: "button_down"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button_down/text"
- parent: "button_down/button"
- overridden_fields: 45
- overridden_fields: 46
- template_node_child: true
- enabled: false
- visible: false
-}
-nodes {
- rotation {
- z: -90.0
- }
- type: TYPE_BOX
- id: "button_down/icon"
- parent: "button_down/button"
- overridden_fields: 2
- template_node_child: true
-}
nodes {
position {
x: 330.0
@@ -333,7 +113,7 @@ nodes {
y: 290.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "buttons"
parent: "gamepad"
inherit_alpha: true
@@ -349,26 +129,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_x/button"
- parent: "button_x"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button_x/text"
- parent: "button_x/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_x/icon"
- parent: "button_x/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
y: 100.0
@@ -379,28 +139,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_y/button"
- parent: "button_y"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "Y"
- id: "button_y/text"
- parent: "button_y/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_y/icon"
- parent: "button_y/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
x: 100.0
@@ -411,28 +149,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_b/button"
- parent: "button_b"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "B"
- id: "button_b/text"
- parent: "button_b/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_b/icon"
- parent: "button_b/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
y: -100.0
@@ -443,28 +159,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_a/button"
- parent: "button_a"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "A"
- id: "button_a/text"
- parent: "button_a/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_a/icon"
- parent: "button_a/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
y: 160.0
@@ -474,7 +168,7 @@ nodes {
y: 290.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "buttons_system"
parent: "gamepad"
inherit_alpha: true
@@ -490,33 +184,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- size {
- x: 180.0
- y: 90.0
- }
- type: TYPE_BOX
- id: "button_back/button"
- parent: "button_back"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "Back"
- id: "button_back/text"
- parent: "button_back/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_back/icon"
- parent: "button_back/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
x: 110.0
@@ -527,33 +194,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- size {
- x: 180.0
- y: 90.0
- }
- type: TYPE_BOX
- id: "button_start/button"
- parent: "button_start"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "Start"
- id: "button_start/text"
- parent: "button_start/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_start/icon"
- parent: "button_start/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
x: -330.0
@@ -564,7 +204,7 @@ nodes {
y: 200.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "button_left_bump"
parent: "gamepad"
inherit_alpha: true
@@ -581,33 +221,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- size {
- x: 180.0
- y: 90.0
- }
- type: TYPE_BOX
- id: "button_l1/button"
- parent: "button_l1"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "L1"
- id: "button_l1/text"
- parent: "button_l1/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_l1/icon"
- parent: "button_l1/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
y: 60.0
@@ -618,26 +231,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_l2/button"
- parent: "button_l2"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_l2/fill"
- parent: "button_l2/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "L2"
- id: "button_l2/text"
- parent: "button_l2/button"
- overridden_fields: 8
- template_node_child: true
-}
nodes {
position {
x: 330.0
@@ -648,7 +241,7 @@ nodes {
y: 200.0
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "button_right_bump"
parent: "gamepad"
inherit_alpha: true
@@ -664,33 +257,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- size {
- x: 180.0
- y: 90.0
- }
- type: TYPE_BOX
- id: "button_r1/button"
- parent: "button_r1"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "R1"
- id: "button_r1/text"
- parent: "button_r1/button"
- overridden_fields: 8
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_r1/icon"
- parent: "button_r1/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
nodes {
position {
y: 60.0
@@ -701,25 +267,5 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_r2/button"
- parent: "button_r2"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_r2/fill"
- parent: "button_r2/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- text: "R2"
- id: "button_r2/text"
- parent: "button_r2/button"
- overridden_fields: 8
- template_node_child: true
-}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/gamepad/gamepad_tester/gamepad_tester.lua b/example/examples/gamepad/gamepad_tester/gamepad_tester.lua
index af59cab..4b807d4 100644
--- a/example/examples/gamepad/gamepad_tester/gamepad_tester.lua
+++ b/example/examples/gamepad/gamepad_tester/gamepad_tester.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local progress = require("druid.extended.progress")
---@class gamepad_tester: druid.base_component
---@field root node
@@ -38,8 +37,8 @@ function M:init(template, nodes)
self.button_start = self.druid:new_button("button_start/button"):set_key_trigger("gamepad_start")
self.button_back = self.druid:new_button("button_back/button"):set_key_trigger("gamepad_back")
- self.trigger_l2 = self.druid:new(progress, "button_l2/fill", "x", 0) --[[@as druid.progress]]
- self.trigger_r2 = self.druid:new(progress, "button_r2/fill", "x", 0) --[[@as druid.progress]]
+ self.trigger_l2 = self.druid:new_progress("button_l2/fill", "x", 0) --[[@as druid.progress]]
+ self.trigger_r2 = self.druid:new_progress("button_r2/fill", "x", 0) --[[@as druid.progress]]
self.stick_left = self:get_node("stick_left/stick_root")
self.stick_right = self:get_node("stick_right/stick_root")
diff --git a/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui b/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui
index a7f8b55..b666dda 100644
--- a/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui
+++ b/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui
@@ -1,58 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 90.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -60,143 +26,50 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 40.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "X"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_arrow"
+ texture: "druid_example/icon_arrow"
id: "icon"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui b/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui
index ffa86d2..215dc15 100644
--- a/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui
+++ b/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -17,7 +17,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
inherit_alpha: true
}
@@ -46,7 +46,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/pixel"
+ texture: "druid_example/pixel"
id: "background"
parent: "background_mask"
inherit_alpha: true
@@ -59,7 +59,7 @@ nodes {
}
nodes {
type: TYPE_BOX
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "stick_root"
parent: "root"
inherit_alpha: true
@@ -77,7 +77,7 @@ nodes {
z: 0.0
}
type: TYPE_BOX
- texture: "druid/ui_circle_64_blur_8"
+ texture: "druid_example/ui_circle_64_blur_8"
id: "stick_shadow"
parent: "stick_root"
inherit_alpha: true
@@ -95,7 +95,7 @@ nodes {
z: 0.49
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "stick"
parent: "stick_root"
inherit_alpha: true
@@ -121,7 +121,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "dot_1"
parent: "stick"
inherit_alpha: true
@@ -141,7 +141,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "dot_2"
parent: "stick"
inherit_alpha: true
@@ -161,7 +161,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "dot_3"
parent: "stick"
inherit_alpha: true
@@ -181,7 +181,7 @@ nodes {
z: 0.322
}
type: TYPE_BOX
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "dot_4"
parent: "stick"
inherit_alpha: true
diff --git a/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui b/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui
index ffe202d..3403f00 100644
--- a/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui
+++ b/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui
@@ -1,58 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 180.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -60,58 +26,25 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -90.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 180.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "fill"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
- adjust_mode: ADJUST_MODE_FIT
parent: "button"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,84 +52,38 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 40.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "X"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/gamepad/on_screen_control/on_screen_control.gui b/example/examples/gamepad/on_screen_control/on_screen_control.gui
index 63c4bf5..8fab1e3 100644
--- a/example/examples/gamepad/on_screen_control/on_screen_control.gui
+++ b/example/examples/gamepad/on_screen_control/on_screen_control.gui
@@ -1,6 +1,6 @@
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -13,7 +13,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
@@ -34,7 +34,7 @@ nodes {
z: 0.624
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "character"
parent: "root"
inherit_alpha: true
@@ -56,7 +56,7 @@ nodes {
z: 0.157
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "eye_left"
parent: "character"
inherit_alpha: true
@@ -72,7 +72,7 @@ nodes {
y: 0.984
}
type: TYPE_BOX
- texture: "druid/ui_circle_8"
+ texture: "druid_example/ui_circle_8"
id: "eye_left_blick"
parent: "eye_left"
inherit_alpha: true
@@ -89,7 +89,7 @@ nodes {
z: 0.157
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "eye_right"
parent: "character"
inherit_alpha: true
@@ -105,7 +105,7 @@ nodes {
y: 0.984
}
type: TYPE_BOX
- texture: "druid/ui_circle_8"
+ texture: "druid_example/ui_circle_8"
id: "eye_right_blick"
parent: "eye_right"
inherit_alpha: true
@@ -133,66 +133,6 @@ nodes {
parent: "on_screen_input/root"
template_node_child: true
}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/root"
- parent: "on_screen_input/on_screen_stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_PIE
- id: "on_screen_input/on_screen_stick/background_mask"
- parent: "on_screen_input/on_screen_stick/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/background"
- parent: "on_screen_input/on_screen_stick/background_mask"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/stick_root"
- parent: "on_screen_input/on_screen_stick/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/stick_shadow"
- parent: "on_screen_input/on_screen_stick/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/stick"
- parent: "on_screen_input/on_screen_stick/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/dot_1"
- parent: "on_screen_input/on_screen_stick/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/dot_2"
- parent: "on_screen_input/on_screen_stick/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/dot_3"
- parent: "on_screen_input/on_screen_stick/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/on_screen_stick/dot_4"
- parent: "on_screen_input/on_screen_stick/stick"
- template_node_child: true
-}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_button"
@@ -205,23 +145,5 @@ nodes {
parent: "on_screen_input/on_screen_button"
template_node_child: true
}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/button_action/button"
- parent: "on_screen_input/button_action"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "on_screen_input/button_action/text"
- parent: "on_screen_input/button_action/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_input/button_action/icon"
- parent: "on_screen_input/button_action/button"
- template_node_child: true
-}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/gamepad/on_screen_control/on_screen_input.gui b/example/examples/gamepad/on_screen_control/on_screen_input.gui
index b1d3488..5a6dc92 100644
--- a/example/examples/gamepad/on_screen_control/on_screen_input.gui
+++ b/example/examples/gamepad/on_screen_control/on_screen_input.gui
@@ -1,6 +1,6 @@
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -22,71 +22,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui"
}
-nodes {
- size {
- x: 400.0
- y: 400.0
- }
- type: TYPE_BOX
- id: "on_screen_stick/root"
- parent: "on_screen_stick"
- overridden_fields: 4
- template_node_child: true
-}
-nodes {
- type: TYPE_PIE
- id: "on_screen_stick/background_mask"
- parent: "on_screen_stick/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/background"
- parent: "on_screen_stick/background_mask"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/stick_root"
- parent: "on_screen_stick/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/stick_shadow"
- parent: "on_screen_stick/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/stick"
- parent: "on_screen_stick/stick_root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/dot_1"
- parent: "on_screen_stick/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/dot_2"
- parent: "on_screen_stick/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/dot_3"
- parent: "on_screen_stick/stick"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "on_screen_stick/dot_4"
- parent: "on_screen_stick/stick"
- template_node_child: true
-}
nodes {
position {
x: 300.0
@@ -108,25 +43,5 @@ nodes {
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
-nodes {
- type: TYPE_BOX
- id: "button_action/button"
- parent: "button_action"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "button_action/text"
- parent: "button_action/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "button_action/icon"
- parent: "button_action/button"
- overridden_fields: 45
- template_node_child: true
- enabled: false
-}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/gamepad/on_screen_control/on_screen_input.lua b/example/examples/gamepad/on_screen_control/on_screen_input.lua
index 41d1d21..bb927a0 100644
--- a/example/examples/gamepad/on_screen_control/on_screen_input.lua
+++ b/example/examples/gamepad/on_screen_control/on_screen_input.lua
@@ -1,13 +1,13 @@
local const = require("druid.const")
-local event = require("druid.event")
+local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
---@class on_screen_input: druid.base_component
---@field druid druid_instance
----@field on_action druid.event @()
----@field on_movement druid.event @(x: number, y: number, dt: number) X/Y values are in range -1..1
----@field on_movement_stop druid.event @()
+---@field on_action event @()
+---@field on_movement event @(x: number, y: number, dt: number) X/Y values are in range -1..1
+---@field on_movement_stop event @()
local M = component.create("on_screen_input")
local STICK_DISTANCE = 80
@@ -23,9 +23,9 @@ function M:init(template, nodes)
self.stick_root = self:get_node("on_screen_stick/stick_root")
self.stick_position = gui.get_position(self.stick_root)
- self.on_action = event()
- self.on_movement = event()
- self.on_movement_stop = event()
+ self.on_action = event.create()
+ self.on_movement = event.create()
+ self.on_movement_stop = event.create()
self.is_multitouch = helper.is_multitouch_supported()
end
diff --git a/example/examples/intro/examples_list.lua b/example/examples/intro/examples_list.lua
index 0366886..0618863 100644
--- a/example/examples/intro/examples_list.lua
+++ b/example/examples/intro/examples_list.lua
@@ -12,6 +12,14 @@ function M.get_examples()
code_url = "example/examples/intro/intro/intro.lua",
component_class = require("example.examples.intro.intro.intro"),
},
+ --{
+ -- name_id = "ui_example_how_to_use_example",
+ -- information_text_id = "ui_example_how_to_use_example_description",
+ -- template = "how_to_use_example",
+ -- root = "how_to_use_example/root",
+ -- code_url = "example/examples/intro/how_to_use_example/how_to_use_example.lua",
+ -- component_class = require("example.examples.intro.how_to_use_example.how_to_use_example"),
+ --}
}
end
diff --git a/example/examples/intro/how_to_use_example/how_to_use_example.gui b/example/examples/intro/how_to_use_example/how_to_use_example.gui
new file mode 100644
index 0000000..78283a9
--- /dev/null
+++ b/example/examples/intro/how_to_use_example/how_to_use_example.gui
@@ -0,0 +1,257 @@
+fonts {
+ name: "text_bold"
+ font: "/example/assets/fonts/text_bold.font"
+}
+fonts {
+ name: "text_regular"
+ font: "/example/assets/fonts/text_regular.font"
+}
+textures {
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
+}
+textures {
+ name: "druid_logo"
+ texture: "/example/assets/druid_logo.atlas"
+}
+nodes {
+ size {
+ x: 600.0
+ y: 1000.0
+ }
+ color {
+ x: 0.173
+ y: 0.184
+ z: 0.204
+ }
+ type: TYPE_BOX
+ texture: "druid_example/ui_circle_64"
+ id: "root"
+ inherit_alpha: true
+ slice9 {
+ x: 32.0
+ y: 32.0
+ z: 32.0
+ w: 32.0
+ }
+}
+nodes {
+ position {
+ x: -180.0
+ y: 375.0
+ }
+ type: TYPE_BOX
+ texture: "druid_logo/icon_druid"
+ id: "icon_druid_left"
+ parent: "root"
+ layer: "druid_logo"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ x: 180.0
+ y: 375.0
+ }
+ type: TYPE_BOX
+ texture: "druid_logo/icon_druid"
+ id: "icon_druid_right"
+ parent: "root"
+ layer: "druid_logo"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ y: 255.0
+ }
+ scale {
+ x: 2.0
+ y: 2.0
+ }
+ size {
+ x: 200.0
+ y: 40.0
+ }
+ color {
+ x: 0.941
+ y: 0.984
+ }
+ type: TYPE_TEXT
+ text: "Hello!"
+ font: "text_bold"
+ id: "text_hello"
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: -210.0
+ y: 191.0
+ }
+ scale {
+ x: 0.7
+ y: 0.7
+ }
+ size {
+ x: 600.0
+ y: 400.0
+ }
+ color {
+ x: 0.525
+ y: 0.525
+ z: 0.525
+ }
+ type: TYPE_TEXT
+ text: "Welcome to Druid Example Page\n"
+ "\n"
+ "Navigate over examples on the left\n"
+ "\n"
+ "Check example info on the right"
+ font: "text_bold"
+ id: "text_description"
+ pivot: PIVOT_NW
+ line_break: true
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: -210.0
+ y: -189.0
+ }
+ scale {
+ x: 0.7
+ y: 0.7
+ }
+ size {
+ x: 600.0
+ y: 300.0
+ }
+ color {
+ x: 0.525
+ y: 0.525
+ z: 0.525
+ }
+ type: TYPE_TEXT
+ text: "Your donation helps me stay engaged in creating valuable projects for Defold.\n"
+ "\n"
+ "If you appreciate what I\'m doing, please consider supporting me!"
+ font: "text_bold"
+ id: "text_support"
+ pivot: PIVOT_W
+ line_break: true
+ parent: "root"
+ inherit_alpha: true
+ outline_alpha: 0.0
+ shadow_alpha: 0.0
+}
+nodes {
+ position {
+ x: -170.0
+ y: -364.0
+ }
+ type: TYPE_BOX
+ texture: "druid_example/icon_heart"
+ id: "icon_heart1"
+ parent: "root"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ y: -364.0
+ }
+ type: TYPE_BOX
+ texture: "druid_example/icon_heart"
+ id: "icon_heart2"
+ parent: "root"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ x: 170.0
+ y: -364.0
+ }
+ type: TYPE_BOX
+ texture: "druid_example/icon_heart"
+ id: "icon_heart3"
+ parent: "root"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ y: -450.0
+ }
+ size {
+ x: 500.0
+ y: 80.0
+ }
+ type: TYPE_BOX
+ id: "sponsor"
+ parent: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ position {
+ x: -196.0
+ y: -3.0
+ }
+ type: TYPE_BOX
+ texture: "druid_logo/sponsor_github"
+ id: "sponsor_github"
+ parent: "sponsor"
+ layer: "druid_logo"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ x: 21.0
+ y: -3.0
+ }
+ type: TYPE_BOX
+ texture: "druid_logo/sponsor_coffee"
+ id: "sponsor_coffee"
+ parent: "sponsor"
+ layer: "druid_logo"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+nodes {
+ position {
+ x: 217.0
+ y: -3.0
+ }
+ type: TYPE_BOX
+ texture: "druid_logo/sponsor_kofi"
+ id: "sponsor_kofi"
+ parent: "sponsor"
+ layer: "druid_logo"
+ inherit_alpha: true
+ alpha: 0.75
+ size_mode: SIZE_MODE_AUTO
+}
+layers {
+ name: "druid_logo"
+}
+layers {
+ name: "text_regular"
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/intro/how_to_use_example/how_to_use_example.lua b/example/examples/intro/how_to_use_example/how_to_use_example.lua
new file mode 100644
index 0000000..b797f98
--- /dev/null
+++ b/example/examples/intro/how_to_use_example/how_to_use_example.lua
@@ -0,0 +1,33 @@
+local component = require("druid.component")
+local panthera = require("panthera.panthera")
+
+---@class how_to_use_example: druid.base_component
+---@field root node
+local M = component.create("how_to_use_example")
+
+---@param template string
+---@param nodes table
+function M:init(template, nodes)
+ self.druid = self:get_druid(template, nodes)
+ self.root = self:get_node("root")
+
+ self.druid:new_rich_text("text_hello", "Hello!")
+
+ self.druid:new_button("sponsor_github", self.open_link, "https://github.com/sponsors/insality")
+ self.druid:new_button("sponsor_coffee", self.open_link, "https://www.buymeacoffee.com/insality")
+ self.druid:new_button("sponsor_kofi", self.open_link, "https://ko-fi.com/insality")
+
+ self.druid:new_layout("sponsor")
+ :add("sponsor_github")
+ :add("sponsor_coffee")
+ :add("sponsor_kofi")
+ :set_margin(8, 0)
+end
+
+
+function M:open_link(link)
+ sys.open_url(link, { target = "_blank" })
+end
+
+
+return M
diff --git a/example/examples/intro/intro/intro.gui b/example/examples/intro/intro/intro.gui
index 834e285..78283a9 100644
--- a/example/examples/intro/intro/intro.gui
+++ b/example/examples/intro/intro/intro.gui
@@ -7,8 +7,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
textures {
name: "druid_logo"
@@ -25,7 +25,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
@@ -158,7 +158,7 @@ nodes {
y: -364.0
}
type: TYPE_BOX
- texture: "druid/icon_heart"
+ texture: "druid_example/icon_heart"
id: "icon_heart1"
parent: "root"
inherit_alpha: true
@@ -170,7 +170,7 @@ nodes {
y: -364.0
}
type: TYPE_BOX
- texture: "druid/icon_heart"
+ texture: "druid_example/icon_heart"
id: "icon_heart2"
parent: "root"
inherit_alpha: true
@@ -183,7 +183,7 @@ nodes {
y: -364.0
}
type: TYPE_BOX
- texture: "druid/icon_heart"
+ texture: "druid_example/icon_heart"
id: "icon_heart3"
parent: "root"
inherit_alpha: true
diff --git a/example/examples/intro/intro/intro.lua b/example/examples/intro/intro/intro.lua
index 4473ba1..10ea849 100644
--- a/example/examples/intro/intro/intro.lua
+++ b/example/examples/intro/intro/intro.lua
@@ -1,11 +1,8 @@
local component = require("druid.component")
-local rich_text = require("druid.custom.rich_text.rich_text")
-local layout = require("druid.extended.layout")
local panthera = require("panthera.panthera")
local intro_panthera = require("example.examples.intro.intro.intro_panthera")
---@class intro: druid.base_component
----@field druid druid_instance
---@field root node
local M = component.create("intro")
@@ -15,13 +12,13 @@ function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
- self.druid:new(rich_text, "text_hello", "Hello!")
+ self.druid:new_rich_text("text_hello", "Hello!")
self.druid:new_button("sponsor_github", self.open_link, "https://github.com/sponsors/insality")
self.druid:new_button("sponsor_coffee", self.open_link, "https://www.buymeacoffee.com/insality")
self.druid:new_button("sponsor_kofi", self.open_link, "https://ko-fi.com/insality")
- self.druid:new(layout, "sponsor")
+ self.druid:new_layout("sponsor")
:add("sponsor_github")
:add("sponsor_coffee")
:add("sponsor_kofi")
@@ -37,4 +34,9 @@ function M:open_link(link)
end
+function M:on_remove()
+ panthera.stop(self.animation)
+end
+
+
return M
diff --git a/example/examples/layout/basic/basic_layout.gui b/example/examples/layout/basic/basic_layout.gui
index 4bb12af..ed74c30 100644
--- a/example/examples/layout/basic/basic_layout.gui
+++ b/example/examples/layout/basic/basic_layout.gui
@@ -1,54 +1,20 @@
-script: ""
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 500.0
y: 500.0
- z: 0.0
- w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 32.0
@@ -56,117 +22,33 @@ nodes {
z: 32.0
w: 32.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 500.0
y: 500.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "layout"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 70.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "layout"
- layer: ""
inherit_alpha: true
slice9 {
x: 8.0
@@ -174,17 +56,6 @@ nodes {
z: 8.0
w: 8.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/panthera/animation_blend/animation_blend.gui b/example/examples/panthera/animation_blend/animation_blend.gui
index eb98b38..b6a0e2e 100644
--- a/example/examples/panthera/animation_blend/animation_blend.gui
+++ b/example/examples/panthera/animation_blend/animation_blend.gui
@@ -7,8 +7,8 @@ textures {
texture: "/example/examples/panthera/animation_blend/assets/animation_blend.atlas"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -21,7 +21,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
diff --git a/example/examples/panthera/animation_blend/animation_blend.lua b/example/examples/panthera/animation_blend/animation_blend.lua
index cbd5ea6..2192db2 100644
--- a/example/examples/panthera/animation_blend/animation_blend.lua
+++ b/example/examples/panthera/animation_blend/animation_blend.lua
@@ -1,9 +1,7 @@
local panthera = require("panthera.panthera")
local component = require("druid.component")
local helper = require("druid.helper")
-local event = require("druid.event")
-local lang_text = require("druid.extended.lang_text")
-local rich_text = require("druid.custom.rich_text.rich_text")
+local event = require("event.event")
local character_animation_blend = require("example.examples.panthera.animation_blend.character_animation_blend")
@@ -20,7 +18,7 @@ function M:init(template, nodes)
self.root = self:get_node("root")
self.root_size = gui.get_size(self.root)
- self.druid:new(lang_text, "text_hint", "ui_example_panthera_animation_blend_hint")
+ self.druid:new_lang_text("text_hint", "ui_example_panthera_animation_blend_hint")
self.animation_idle = panthera.create_gui(character_animation_blend, self:get_template(), nodes)
self.animation_vertical = panthera.create_gui(character_animation_blend, self:get_template(), nodes)
@@ -31,7 +29,7 @@ function M:init(template, nodes)
})
self:setup_rich_text()
- self.on_update = event()
+ self.on_update = event.create()
end
@@ -59,7 +57,7 @@ end
function M:setup_rich_text()
- self.rich_text = self.druid:new(rich_text, "rich_text_kenney", "Character assets by Kenney")
+ self.rich_text = self.druid:new_rich_text("rich_text_kenney", "Character assets by Kenney")
local tagged = self.rich_text:tagged("link")
for index = 1, #tagged do
diff --git a/example/examples/panthera/basic_animation/basic_animation.gui b/example/examples/panthera/basic_animation/basic_animation.gui
index fef1c91..4eb714a 100644
--- a/example/examples/panthera/basic_animation/basic_animation.gui
+++ b/example/examples/panthera/basic_animation/basic_animation.gui
@@ -1,241 +1,24 @@
-script: ""
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 200.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "button"
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_blue.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.631
- y: 0.843
- z: 0.961
- w: 1.0
- }
- type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
- id: "button/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- parent: "button"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
-}
-nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
- type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Hover Me!"
- font: "text_bold"
- id: "button/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
- parent: "button/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 8
- template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/widgets/examples_list.lua b/example/examples/widgets/examples_list.lua
index 6209cdd..d127fb0 100644
--- a/example/examples/widgets/examples_list.lua
+++ b/example/examples/widgets/examples_list.lua
@@ -11,6 +11,72 @@ function M.get_examples()
code_url = "example/examples/widgets/hover_hint/hover_hint_example.lua",
component_class = require("example.examples.widgets.hover_hint.hover_hint_example"),
},
+ {
+ name_id = "ui_example_widget_properties_panel",
+ information_text_id = "ui_example_widget_properties_panel_description",
+ template = "properties_panel",
+ root = "properties_panel/root",
+ code_url = "example/examples/widgets/properties_panel/properties_panel.lua",
+ widget_class = require("druid.widget.properties_panel.properties_panel"),
+ on_create = function(instance, output_list)
+ ---@cast instance widget.properties_panel
+
+ instance:add_button(function(button)
+ button:set_text_button("Button")
+ button.button.on_click:subscribe(function()
+ print("Button clicked")
+ end)
+ end)
+
+ instance:add_checkbox(function(checkbox)
+ --print("Checkbox clicked", value)
+ checkbox:set_text_property("Checkbox")
+ checkbox.on_change_value:subscribe(function(value)
+ print("Checkbox clicked", value)
+ end)
+ checkbox:set_value(false)
+ end)
+
+ instance:add_input(function(input)
+ input:set_text_property("Input")
+ input:set_text_value("Initial")
+ input:on_change(function(text)
+ print("Input changed", text)
+ end)
+ end)
+
+ instance:add_left_right_selector(function(selector)
+ selector:set_template("Arrows Number")
+ selector.on_change_value:subscribe(function(value)
+ print("Left Right Selector changed", value)
+ end)
+ selector:set_number_type(0, 42, true, 1)
+ selector:set_value(0)
+ end)
+
+ instance:add_left_right_selector(function(selector)
+ selector:set_template("Arrows Array")
+ selector.on_change_value:subscribe(function(value)
+ print("Left Right Array value", value)
+ end)
+ selector:set_array_type({"Zero", "One", "Two", "Three", "Four", "Five"}, false, 1)
+ selector:set_value("Zero")
+ end)
+
+ instance:add_slider(function(slider)
+ slider:set_text_property("Slider")
+ slider:set_value(0.5)
+ slider:on_change(function(value)
+ print("Slider changed", value)
+ end)
+ end)
+
+ instance:add_text(function(text)
+ text:set_text_property("Text")
+ text:set_text_value("Hello, World!")
+ end)
+ end,
+ },
{
name_id = "ui_example_widget_property_button",
information_text_id = "ui_example_widget_property_button_description",
@@ -25,6 +91,14 @@ function M.get_examples()
end)
end,
},
+ {
+ name_id = "ui_example_widget_property_input",
+ information_text_id = "ui_example_widget_property_input_description",
+ template = "property_input",
+ root = "property_input/root",
+ code_url = "druid/widget/properties_panel/properties/property_input.lua",
+ widget_class = require("druid.widget.properties_panel.properties.property_input"),
+ },
{
name_id = "ui_example_widget_property_slider",
information_text_id = "ui_example_widget_property_slider_description",
@@ -53,6 +127,57 @@ function M.get_examples()
end)
end,
},
+ {
+ name_id = "ui_example_widget_memory_panel",
+ information_text_id = "ui_example_widget_memory_panel_description",
+ template = "memory_panel",
+ root = "memory_panel/root",
+ code_url = "druid.widget.memory_panel.memory_panel.lua",
+ widget_class = require("druid.widget.memory_panel.memory_panel"),
+ on_create = function(instance, output_list)
+ ---@cast instance widget.memory_panel
+ print("Memory panel created")
+ end,
+ },
+ {
+ name_id = "ui_example_widget_fps_panel",
+ information_text_id = "ui_example_widget_fps_panel_description",
+ template = "fps_panel",
+ root = "fps_panel/root",
+ code_url = "druid.widget.fps_panel.fps_panel.lua",
+ widget_class = require("druid.widget.fps_panel.fps_panel"),
+ on_create = function(instance, output_list)
+ ---@cast instance widget.fps_panel
+ print("FPS panel created")
+ end,
+ },
+ {
+ name_id = "ui_example_widget_mini_graph",
+ information_text_id = "ui_example_widget_mini_graph_description",
+ template = "mini_graph",
+ root = "mini_graph/root",
+ code_url = "druid.widget.mini_graph.mini_graph.lua",
+ widget_class = require("druid.widget.mini_graph.mini_graph"),
+ on_create = function(instance, output_list)
+ ---@cast instance widget.mini_graph
+ instance:set_samples(50)
+ end,
+ properties_control = function(instance, properties_panel)
+ ---@cast instance widget.mini_graph
+ properties_panel:add_slider("value", 0.5, function(value)
+ -- Remap to -1, 2
+ value = value * 3 - 1
+ for index = 1, 50 do
+ -- Take value each 0.1 step, the higher value at argument value
+ local x = index * (1 / 50)
+ local distance = math.abs(x - value)
+ local line_v = 1 - distance^2
+
+ instance:set_line_value(index, line_v)
+ end
+ end)
+ end,
+ }
}
end
diff --git a/example/examples/widgets/fps_panel/example_fps_panel.gui b/example/examples/widgets/fps_panel/example_fps_panel.gui
new file mode 100644
index 0000000..4f01f77
--- /dev/null
+++ b/example/examples/widgets/fps_panel/example_fps_panel.gui
@@ -0,0 +1,104 @@
+nodes {
+ size {
+ x: 200.0
+ y: 100.0
+ }
+ type: TYPE_BOX
+ id: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "fps_panel"
+ parent: "root"
+ inherit_alpha: true
+ template: "/druid/widget/fps_panel/fps_panel.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/root"
+ parent: "fps_panel"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "fps_panel/mini_graph"
+ parent: "fps_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/root"
+ parent: "fps_panel/mini_graph"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/header"
+ parent: "fps_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "fps_panel/mini_graph/text_header"
+ parent: "fps_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/icon_drag"
+ parent: "fps_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/content"
+ parent: "fps_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/prefab_line"
+ parent: "fps_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/mini_graph/color_low"
+ parent: "fps_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/content"
+ parent: "fps_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "fps_panel/text_min_fps"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "fps_panel/text_fps"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/line_second_1"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "fps_panel/line_second_2"
+ parent: "fps_panel/content"
+ template_node_child: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/widgets/fps_panel/example_fps_panel.lua b/example/examples/widgets/fps_panel/example_fps_panel.lua
new file mode 100644
index 0000000..50de100
--- /dev/null
+++ b/example/examples/widgets/fps_panel/example_fps_panel.lua
@@ -0,0 +1,12 @@
+local fps_panel = require("druid.widget.fps_panel.fps_panel")
+
+---@class widget.example_fps_panel: druid.widget
+local M = {}
+
+
+function M:init()
+ self.fps_panel = self.druid:new_widget(fps_panel, "fps_panel")
+end
+
+
+return M
\ No newline at end of file
diff --git a/example/examples/widgets/hover_hint/hover_hint.gui b/example/examples/widgets/hover_hint/hover_hint.gui
index 9c8190c..f620a93 100644
--- a/example/examples/widgets/hover_hint/hover_hint.gui
+++ b/example/examples/widgets/hover_hint/hover_hint.gui
@@ -3,8 +3,8 @@ fonts {
font: "/example/assets/fonts/text_regular.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -27,7 +27,7 @@ nodes {
z: 0.157
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "panel_hint"
parent: "root"
inherit_alpha: true
diff --git a/example/examples/widgets/hover_hint/hover_hint.lua b/example/examples/widgets/hover_hint/hover_hint.lua
index 1578106..2cf4537 100644
--- a/example/examples/widgets/hover_hint/hover_hint.lua
+++ b/example/examples/widgets/hover_hint/hover_hint.lua
@@ -88,7 +88,7 @@ end
---@private
function M:refresh_content(node, hint_text, pivot_point, content_pivot)
- self.text_hint:set_to(hint_text)
+ self.text_hint:set_text(hint_text)
local text_width, text_height = self.text_hint:get_text_size()
local panel_width = math.max(text_width, MIN_PANEL_WIDTH) + PANEL_MARGIN
diff --git a/example/examples/widgets/hover_hint/hover_hint_example.gui b/example/examples/widgets/hover_hint/hover_hint_example.gui
index 8bb74a9..9c19b51 100644
--- a/example/examples/widgets/hover_hint/hover_hint_example.gui
+++ b/example/examples/widgets/hover_hint/hover_hint_example.gui
@@ -1,6 +1,6 @@
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
size {
@@ -13,7 +13,7 @@ nodes {
z: 0.204
}
type: TYPE_BOX
- texture: "druid/ui_circle_64"
+ texture: "druid_example/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
@@ -33,24 +33,6 @@ nodes {
inherit_alpha: true
template: "/example/examples/widgets/hover_hint/hover_hint.gui"
}
-nodes {
- type: TYPE_BOX
- id: "hover_hint/root"
- parent: "hover_hint"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "hover_hint/panel_hint"
- parent: "hover_hint/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "hover_hint/text_hint"
- parent: "hover_hint/panel_hint"
- template_node_child: true
-}
nodes {
position {
y: 100.0
@@ -65,7 +47,7 @@ nodes {
z: 0.624
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "node_yellow"
parent: "root"
inherit_alpha: true
@@ -90,7 +72,7 @@ nodes {
z: 0.608
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "node_red"
parent: "root"
inherit_alpha: true
@@ -115,7 +97,7 @@ nodes {
z: 0.961
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "node_blue"
parent: "root"
inherit_alpha: true
@@ -140,7 +122,7 @@ nodes {
z: 0.62
}
type: TYPE_BOX
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "node_green"
parent: "root"
inherit_alpha: true
diff --git a/example/examples/widgets/hover_hint/hover_hint_example.lua b/example/examples/widgets/hover_hint/hover_hint_example.lua
index 53633c1..28cf278 100644
--- a/example/examples/widgets/hover_hint/hover_hint_example.lua
+++ b/example/examples/widgets/hover_hint/hover_hint_example.lua
@@ -2,7 +2,7 @@ local hover_hint = require("example.examples.widgets.hover_hint.hover_hint")
local component = require("druid.component")
----@class hover_hint_example: druid.component
+---@class hover_hint_example: druid.base_component
---@field druid druid_instance
local M = component.create("hover_hint_example")
diff --git a/example/examples/widgets/memory_panel/example_memory_panel.gui b/example/examples/widgets/memory_panel/example_memory_panel.gui
new file mode 100644
index 0000000..44ee04a
--- /dev/null
+++ b/example/examples/widgets/memory_panel/example_memory_panel.gui
@@ -0,0 +1,110 @@
+nodes {
+ size {
+ x: 200.0
+ y: 100.0
+ }
+ type: TYPE_BOX
+ id: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "memory_panel"
+ parent: "root"
+ inherit_alpha: true
+ template: "/druid/widget/memory_panel/memory_panel.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/root"
+ parent: "memory_panel"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "memory_panel/mini_graph"
+ parent: "memory_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/root"
+ parent: "memory_panel/mini_graph"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/header"
+ parent: "memory_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/mini_graph/text_header"
+ parent: "memory_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/icon_drag"
+ parent: "memory_panel/mini_graph/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/content"
+ parent: "memory_panel/mini_graph/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/prefab_line"
+ parent: "memory_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/mini_graph/color_low"
+ parent: "memory_panel/mini_graph/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/content"
+ parent: "memory_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/text_max_value"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/text_per_second"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/line_second_1"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "memory_panel/line_second_2"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "memory_panel/text_memory"
+ parent: "memory_panel/content"
+ template_node_child: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/widgets/memory_panel/example_memory_panel.lua b/example/examples/widgets/memory_panel/example_memory_panel.lua
new file mode 100644
index 0000000..f42f0f6
--- /dev/null
+++ b/example/examples/widgets/memory_panel/example_memory_panel.lua
@@ -0,0 +1,12 @@
+local memory_panel = require("druid.widget.memory_panel.memory_panel")
+
+---@class widget.example_memory_panel: druid.widget
+local M = {}
+
+
+function M:init()
+ self.memory_panel = self.druid:new_widget(memory_panel, "memory_panel")
+end
+
+
+return M
\ No newline at end of file
diff --git a/example/examples/widgets/properties_panel/example_properties_panel.gui b/example/examples/widgets/properties_panel/example_properties_panel.gui
new file mode 100644
index 0000000..b1889c7
--- /dev/null
+++ b/example/examples/widgets/properties_panel/example_properties_panel.gui
@@ -0,0 +1,368 @@
+nodes {
+ size {
+ x: 200.0
+ y: 100.0
+ }
+ type: TYPE_BOX
+ id: "root"
+ inherit_alpha: true
+ size_mode: SIZE_MODE_AUTO
+ visible: false
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel"
+ parent: "root"
+ inherit_alpha: true
+ template: "/druid/widget/properties_panel/properties_panel.gui"
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/root"
+ parent: "properties_panel"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/header"
+ parent: "properties_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/text_header"
+ parent: "properties_panel/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/icon_drag"
+ parent: "properties_panel/header"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/content"
+ parent: "properties_panel/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/scroll_view"
+ parent: "properties_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/scroll_content"
+ parent: "properties_panel/scroll_view"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/propeties"
+ parent: "properties_panel/content"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_slider"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/root"
+ parent: "properties_panel/property_slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_slider/text_name"
+ parent: "properties_panel/property_slider/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/E_Anchor"
+ parent: "properties_panel/property_slider/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/slider"
+ parent: "properties_panel/property_slider/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/slider_back"
+ parent: "properties_panel/property_slider/slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/slider_pin"
+ parent: "properties_panel/property_slider/slider"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/button"
+ parent: "properties_panel/property_slider/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_slider/selected"
+ parent: "properties_panel/property_slider/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_slider/text_value"
+ parent: "properties_panel/property_slider/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_checkbox"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/root"
+ parent: "properties_panel/property_checkbox"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_checkbox/text_name"
+ parent: "properties_panel/property_checkbox/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/E_Anchor"
+ parent: "properties_panel/property_checkbox/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/button"
+ parent: "properties_panel/property_checkbox/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/icon"
+ parent: "properties_panel/property_checkbox/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_checkbox/selected"
+ parent: "properties_panel/property_checkbox/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_button"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/root"
+ parent: "properties_panel/property_button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_button/text_name"
+ parent: "properties_panel/property_button/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/E_Anchor"
+ parent: "properties_panel/property_button/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/button"
+ parent: "properties_panel/property_button/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_button/selected"
+ parent: "properties_panel/property_button/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_button/text_button"
+ parent: "properties_panel/property_button/button"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_input"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/root"
+ parent: "properties_panel/property_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/text_name"
+ parent: "properties_panel/property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/E_Anchor"
+ parent: "properties_panel/property_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_input/rich_input"
+ parent: "properties_panel/property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/rich_input/root"
+ parent: "properties_panel/property_input/rich_input"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/rich_input/button"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/rich_input/placeholder_text"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/rich_input/input_text"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/rich_input/cursor_node"
+ parent: "properties_panel/property_input/rich_input/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_input/rich_input/cursor_text"
+ parent: "properties_panel/property_input/rich_input/cursor_node"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_input/selected"
+ parent: "properties_panel/property_input/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_text"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_text/root"
+ parent: "properties_panel/property_text"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_text/text_name"
+ parent: "properties_panel/property_text/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_text/text_right"
+ parent: "properties_panel/property_text/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEMPLATE
+ id: "properties_panel/property_left_right_selector"
+ parent: "properties_panel/propeties"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/root"
+ parent: "properties_panel/property_left_right_selector"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_left_right_selector/text_name"
+ parent: "properties_panel/property_left_right_selector/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/E_Anchor"
+ parent: "properties_panel/property_left_right_selector/root"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/button_left"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/icon_left"
+ parent: "properties_panel/property_left_right_selector/button_left"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/button_right"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/icon_right"
+ parent: "properties_panel/property_left_right_selector/button_right"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_BOX
+ id: "properties_panel/property_left_right_selector/selected"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+nodes {
+ type: TYPE_TEXT
+ id: "properties_panel/property_left_right_selector/text_value"
+ parent: "properties_panel/property_left_right_selector/E_Anchor"
+ template_node_child: true
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/examples/widgets/properties_panel/example_properties_panel.lua b/example/examples/widgets/properties_panel/example_properties_panel.lua
new file mode 100644
index 0000000..887950d
--- /dev/null
+++ b/example/examples/widgets/properties_panel/example_properties_panel.lua
@@ -0,0 +1,67 @@
+local properties_panel = require("druid.widget.properties_panel.properties_panel")
+
+---@class widget.example_properties_panel: druid.widget
+local M = {}
+
+
+function M:init()
+ self.properties_panel = self.druid:new_widget(properties_panel, "properties_panel")
+
+ self.properties_panel:add_button(function(button)
+ button:set_text_button("Button")
+ button.button.on_click:subscribe(function()
+ print("Button clicked")
+ end)
+ end)
+
+ self.properties_panel:add_checkbox(function(checkbox)
+ --print("Checkbox clicked", value)
+ checkbox:set_text_property("Checkbox")
+ checkbox.on_change_value:subscribe(function(value)
+ print("Checkbox clicked", value)
+ end)
+ checkbox:set_value(false)
+ end)
+
+ self.properties_panel:add_input(function(input)
+ input:set_text_property("Input")
+ input:set_text_value("Initial")
+ input:on_change(function(text)
+ print("Input changed", text)
+ end)
+ end)
+
+ self.properties_panel:add_left_right_selector(function(selector)
+ selector:set_template("Arrows Number")
+ selector.on_change_value:subscribe(function(value)
+ print("Left Right Selector changed", value)
+ end)
+ selector:set_number_type(0, 42, true, 1)
+ selector:set_value(0)
+ end)
+
+ self.properties_panel:add_left_right_selector(function(selector)
+ selector:set_template("Arrows Array")
+ selector.on_change_value:subscribe(function(value)
+ print("Left Right Array value", value)
+ end)
+ selector:set_array_type({"Zero", "One", "Two", "Three", "Four", "Five"}, false, 1)
+ selector:set_value("Zero")
+ end)
+
+ self.properties_panel:add_slider(function(slider)
+ slider:set_text_property("Slider")
+ slider:set_value(0.5)
+ slider:on_change(function(value)
+ print("Slider changed", value)
+ end)
+ end)
+
+ self.properties_panel:add_text(function(text)
+ text:set_text_property("Text")
+ text:set_text_value("Hello, World!")
+ end)
+end
+
+
+return M
\ No newline at end of file
diff --git a/example/examples/windows/window_confirmation/window_confirmation.gui b/example/examples/windows/window_confirmation/window_confirmation.gui
index 27ed7fc..2c60a9e 100644
--- a/example/examples/windows/window_confirmation/window_confirmation.gui
+++ b/example/examples/windows/window_confirmation/window_confirmation.gui
@@ -4,55 +4,18 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 960.0
- y: 540.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 700.0
y: 500.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -60,58 +23,22 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 700.0
y: 500.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "window"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,58 +46,25 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: 250.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 700.0
y: 92.0
- z: 0.0
- w: 1.0
}
color {
x: 0.902
y: 0.875
z: 0.624
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_rounded_top_32"
+ texture: "druid_example/ui_rounded_top_32"
id: "panel_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "window"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -178,663 +72,166 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -46.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 300.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Confirmation"
font: "text_bold"
id: "text_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "panel_header"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 300.0
y: -46.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 100.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "button_close"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "panel_header"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_cross"
+ texture: "druid_example/icon_cross"
id: "icon_close"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button_close"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -45.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 700.0
y: 400.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 75.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 420.0
y: 140.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Do you agree with selected action?"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -160.0
y: -100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button_accept"
parent: "content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
id: "button_accept/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button_accept"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Confirm"
- font: "text_bold"
id: "button_accept/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button_accept/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 160.0
y: -100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button_decline"
parent: "content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_red.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.957
- y: 0.608
- z: 0.608
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
id: "button_decline/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button_decline"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Cancel"
- font: "text_bold"
id: "button_decline/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button_decline/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -844,4 +241,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/windows/window_confirmation/window_confirmation.lua b/example/examples/windows/window_confirmation/window_confirmation.lua
index a59bcd9..f91b7a5 100644
--- a/example/examples/windows/window_confirmation/window_confirmation.lua
+++ b/example/examples/windows/window_confirmation/window_confirmation.lua
@@ -1,5 +1,4 @@
local component = require("druid.component")
-local lang_text = require("druid.extended.lang_text")
local panthera = require("panthera.panthera")
local window_animation_panthera = require("example.examples.windows.window_animation_panthera")
@@ -19,10 +18,10 @@ local M = component.create("window_confirmation")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.text_header = self.druid:new(lang_text, "text_header", "ui_confirmation") --[[@as druid.lang_text]]
- self.text_button_accept = self.druid:new(lang_text, "button_accept/text", "ui_accept") --[[@as druid.lang_text]]
- self.text_button_decline = self.druid:new(lang_text, "button_decline/text", "ui_decline") --[[@as druid.lang_text]]
- self.text_description = self.druid:new(lang_text, "text") --[[@as druid.lang_text]]
+ self.text_header = self.druid:new_lang_text("text_header", "ui_confirmation") --[[@as druid.lang_text]]
+ self.text_button_accept = self.druid:new_lang_text("button_accept/text", "ui_accept") --[[@as druid.lang_text]]
+ self.text_button_decline = self.druid:new_lang_text("button_decline/text", "ui_decline") --[[@as druid.lang_text]]
+ self.text_description = self.druid:new_lang_text("text") --[[@as druid.lang_text]]
self.button_close = self.druid:new_button("button_close", self.on_button_close)
self.button_accept = self.druid:new_button("button_accept/root")
diff --git a/example/examples/windows/window_info/window_info.gui b/example/examples/windows/window_info/window_info.gui
index 1d45e4f..869dd30 100644
--- a/example/examples/windows/window_info/window_info.gui
+++ b/example/examples/windows/window_info/window_info.gui
@@ -4,55 +4,18 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 960.0
- y: 540.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 700.0
y: 500.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -60,58 +23,22 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 700.0
y: 500.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "window"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,58 +46,25 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: 250.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 700.0
y: 92.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_rounded_top_32"
+ texture: "druid_example/ui_rounded_top_32"
id: "panel_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "window"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -178,495 +72,142 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -46.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 300.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Information"
font: "text_bold"
id: "text_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "panel_header"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 300.0
y: -46.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 100.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "button_close"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "panel_header"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_cross"
+ texture: "druid_example/icon_cross"
id: "icon_close"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button_close"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -45.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 700.0
y: 400.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
position {
- x: 0.0
y: 75.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 420.0
y: 140.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "You are the best!"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -100.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_TEMPLATE
id: "button_accept"
parent: "content"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_green.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 280.0
- y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.557
- y: 0.835
- z: 0.62
- w: 1.0
- }
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
id: "button_accept/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button_accept"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 245.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "Confirm"
- font: "text_bold"
id: "button_accept/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button_accept/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -676,4 +217,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/windows/window_info/window_info.lua b/example/examples/windows/window_info/window_info.lua
index 26c36c1..3385176 100644
--- a/example/examples/windows/window_info/window_info.lua
+++ b/example/examples/windows/window_info/window_info.lua
@@ -1,6 +1,5 @@
local component = require("druid.component")
local panthera = require("panthera.panthera")
-local lang_text = require("druid.extended.lang_text")
local window_animation_panthera = require("example.examples.windows.window_animation_panthera")
@@ -18,9 +17,9 @@ local M = component.create("window_info")
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
- self.text_header = self.druid:new(lang_text, "text_header", "ui_information") --[[@as druid.lang_text]]
- self.text_button_accept = self.druid:new(lang_text, "button_accept/text", "ui_accept") --[[@as druid.lang_text]]
- self.text_description = self.druid:new(lang_text, "text") --[[@as druid.lang_text]]
+ self.text_header = self.druid:new_lang_text("text_header", "ui_information") --[[@as druid.lang_text]]
+ self.text_button_accept = self.druid:new_lang_text("button_accept/text", "ui_accept") --[[@as druid.lang_text]]
+ self.text_description = self.druid:new_lang_text("text") --[[@as druid.lang_text]]
self.button_close = self.druid:new_button("button_close", self.on_button_close)
self.button_accept = self.druid:new_button("button_accept/root")
diff --git a/example/examples/windows/window_language/window_language.gui b/example/examples/windows/window_language/window_language.gui
index 1076352..29c6763 100644
--- a/example/examples/windows/window_language/window_language.gui
+++ b/example/examples/windows/window_language/window_language.gui
@@ -4,55 +4,18 @@ fonts {
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 960.0
- y: 540.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 580.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -60,58 +23,22 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 600.0
y: 580.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "window"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -119,58 +46,25 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: 290.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 600.0
y: 92.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_rounded_top_32"
+ texture: "druid_example/ui_rounded_top_32"
id: "panel_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_N
- adjust_mode: ADJUST_MODE_FIT
parent: "window"
- layer: ""
inherit_alpha: true
slice9 {
x: 16.0
@@ -178,490 +72,119 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -46.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 1.5
y: 1.5
- z: 1.0
- w: 1.0
}
size {
x: 300.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Language"
font: "text_bold"
id: "text_header"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "panel_header"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 250.0
y: -46.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 100.0
y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "button_close"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "panel_header"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/icon_cross"
+ texture: "druid_example/icon_cross"
id: "icon_close"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button_close"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
size_mode: SIZE_MODE_AUTO
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: -45.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 600.0
y: 470.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "content"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 260.0
y: 90.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "button_prefab"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "content"
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 200.0
- y: 100.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
type: TYPE_TEMPLATE
id: "button"
parent: "button_prefab"
- layer: ""
inherit_alpha: true
- alpha: 1.0
template: "/example/templates/button_text_white.gui"
- template_node_child: false
- custom_type: 0
- enabled: true
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
- x: 240.0
- y: 70.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.941
- y: 0.984
- z: 1.0
- w: 1.0
+ x: 245.0
+ y: 75.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
id: "button/root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button"
- layer: "druid"
- inherit_alpha: true
- slice9 {
- x: 16.0
- y: 16.0
- z: 16.0
- w: 16.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
overridden_fields: 4
template_node_child: true
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- size {
- x: 220.0
- y: 50.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 0.31
- y: 0.318
- z: 0.322
- w: 1.0
- }
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
- text: "English"
- font: "text_bold"
id: "button/text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- shadow {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button/root"
- layer: "text_bold"
- inherit_alpha: true
- alpha: 1.0
- outline_alpha: 0.0
- shadow_alpha: 0.0
- overridden_fields: 4
- overridden_fields: 8
template_node_child: true
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -671,4 +194,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/examples/windows/window_language/window_language.lua b/example/examples/windows/window_language/window_language.lua
index f5f4120..25c9bf4 100644
--- a/example/examples/windows/window_language/window_language.lua
+++ b/example/examples/windows/window_language/window_language.lua
@@ -1,8 +1,7 @@
local lang = require("lang.lang")
local druid = require("druid.druid")
-local event = require("druid.event")
+local event = require("event.event")
local component = require("druid.component")
-local lang_text = require("druid.extended.lang_text")
local panthera = require("panthera.panthera")
local window_animation_panthera = require("example.examples.windows.window_animation_panthera")
@@ -12,8 +11,8 @@ local window_animation_panthera = require("example.examples.windows.window_anima
---@field button_close druid.button
---@field druid druid_instance
---@field lang_buttons table
----@field grid druid.static_grid
----@field on_language_change druid.event
+---@field grid druid.grid
+---@field on_language_change event
local M = component.create("window_language")
---Color: #F0FBFF
@@ -35,16 +34,16 @@ function M:init(template, nodes)
self.button_close = self.druid:new_button("button_close", self.on_button_close)
- self.druid:new(lang_text, "text_header", "ui_language")
- self.grid = self.druid:new_static_grid("content", self.prefab, 2)
+ self.druid:new_lang_text("text_header", "ui_language")
+ self.grid = self.druid:new_grid("content", self.prefab, 2)
self.grid.style.IS_DYNAMIC_NODE_POSES = true
- self.animation = panthera.create_gui(window_animation_panthera, self:get_template(), nodes)
+ self.animation = panthera.create_gui(window_animation_panthera, self:get_template(), self:get_nodes())
panthera.play(self.animation, "open")
self:load_langs()
- self.on_language_change = event()
+ self.on_language_change = event.create()
end
@@ -73,7 +72,7 @@ function M:load_langs()
local text = prefab_nodes[template .. "button/text"]
local button = self.druid:new_button(button_node, self.on_language_button, lang_id)
- self.druid:new(lang_text, text, "ui_language_" .. lang_id)
+ self.druid:new_lang_text(text, "ui_language_" .. lang_id)
gui.set_enabled(root, true)
self.grid:add(root)
diff --git a/example/locales/en.json b/example/locales/en.json
index c05a651..dcf64ea 100644
--- a/example/locales/en.json
+++ b/example/locales/en.json
@@ -177,6 +177,15 @@
"ui_example_widget_property_checkbox": "Property Checkbox",
"ui_example_widget_property_checkbox_description": "Here is a widget used in Properties panel",
+ "ui_example_widget_memory_panel": "Memory Panel",
+ "ui_example_widget_memory_panel_description": "Here is a example of memory panel usage",
+
+ "ui_example_widget_fps_panel": "FPS Panel",
+ "ui_example_widget_fps_panel_description": "Here is a example of FPS panel usage",
+
+ "ui_example_widget_properties_panel": "Properties Panel",
+ "ui_example_widget_properties_panel_description": "Here is a example of properties panel usage",
+
"ui_example_gamepad_tester": "Gamepad Tester",
"ui_example_gamepad_tester_description": "Test your gamepad here to bind buttons and axes",
diff --git a/example/templates/button_text_blue.gui b/example/templates/button_text_blue.gui
index ca44671..305913d 100644
--- a/example/templates/button_text_blue.gui
+++ b/example/templates/button_text_blue.gui
@@ -1,57 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 280.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
layer: "druid"
inherit_alpha: true
slice9 {
@@ -60,90 +27,42 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 245.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Info"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
-material: "/builtins/materials/gui.material"
-adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
layers {
name: "druid"
}
layers {
name: "text_bold"
}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/templates/button_text_green.gui b/example/templates/button_text_green.gui
index 41d3b0f..81921b6 100644
--- a/example/templates/button_text_green.gui
+++ b/example/templates/button_text_green.gui
@@ -1,57 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 280.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
layer: "druid"
inherit_alpha: true
slice9 {
@@ -60,83 +27,36 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 245.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Confirm"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -146,4 +66,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/templates/button_text_red.gui b/example/templates/button_text_red.gui
index 737878b..1d8efd6 100644
--- a/example/templates/button_text_red.gui
+++ b/example/templates/button_text_red.gui
@@ -1,57 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 280.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.957
y: 0.608
z: 0.608
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
layer: "druid"
inherit_alpha: true
slice9 {
@@ -60,83 +27,36 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 245.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Cancel"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -146,4 +66,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/templates/button_text_white.gui b/example/templates/button_text_white.gui
index 2935f42..6925cc8 100644
--- a/example/templates/button_text_white.gui
+++ b/example/templates/button_text_white.gui
@@ -1,57 +1,23 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 280.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.941
y: 0.984
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
layer: "druid"
inherit_alpha: true
slice9 {
@@ -60,83 +26,36 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 245.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Action"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
layers {
name: "druid"
@@ -146,4 +65,3 @@ layers {
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/templates/button_text_yellow.gui b/example/templates/button_text_yellow.gui
index 99593a5..2bd7677 100644
--- a/example/templates/button_text_yellow.gui
+++ b/example/templates/button_text_yellow.gui
@@ -1,57 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 280.0
y: 90.0
- z: 0.0
- w: 1.0
}
color {
x: 0.902
y: 0.875
z: 0.624
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_32"
+ texture: "druid_example/ui_circle_32"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
layer: "druid"
inherit_alpha: true
slice9 {
@@ -60,90 +27,42 @@ nodes {
z: 16.0
w: 16.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 245.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Warn"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
layer: "text_bold"
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
-material: "/builtins/materials/gui.material"
-adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
layers {
name: "druid"
}
layers {
name: "text_bold"
}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/example/templates/input.gui b/example/templates/input.gui
index 776bbbf..508eb27 100644
--- a/example/templates/input.gui
+++ b/example/templates/input.gui
@@ -1,58 +1,24 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 500.0
y: 80.0
- z: 0.0
- w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
+ texture: "druid_example/rect_round2_width1"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
slice9 {
x: 4.0
@@ -60,84 +26,39 @@ nodes {
z: 4.0
w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -240.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 480.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Tap me to input"
font: "text_bold"
id: "text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "root"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/templates/rich_input.gui b/example/templates/rich_input.gui
index 5467ee9..89023bd 100644
--- a/example/templates/rich_input.gui
+++ b/example/templates/rich_input.gui
@@ -1,117 +1,30 @@
-script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 500.0
y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: ""
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
visible: false
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 500.0
y: 80.0
- z: 0.0
- w: 1.0
- }
- color {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/rect_round2_width1"
+ texture: "druid_example/rect_round2_width1"
id: "button"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 4.0
@@ -119,192 +32,77 @@ nodes {
z: 4.0
w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 480.0
y: 60.0
- z: 0.0
- w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "Placeholder"
font: "text_bold"
id: "placeholder_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
outline {
x: 0.4
y: 0.4
z: 0.4
- w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 480.0
y: 60.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "User input"
font: "text_bold"
id: "input_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "button"
- layer: ""
inherit_alpha: true
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: 118.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 16.0
y: 50.0
- z: 0.0
- w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_16"
+ texture: "druid_example/ui_circle_16"
id: "cursor_node"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "button"
- layer: ""
inherit_alpha: true
slice9 {
x: 8.0
@@ -312,84 +110,37 @@ nodes {
z: 8.0
w: 8.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
alpha: 0.5
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
- x: 0.0
y: 4.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
}
scale {
x: 1.2
y: 1.2
- z: 1.0
- w: 1.0
}
size {
x: 20.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_TEXT
- blend_mode: BLEND_MODE_ALPHA
text: "|"
font: "text_bold"
id: "cursor_text"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- outline {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
shadow {
x: 1.0
y: 1.0
z: 1.0
- w: 1.0
}
- adjust_mode: ADJUST_MODE_FIT
- line_break: false
parent: "cursor_node"
- layer: ""
- inherit_alpha: false
- alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
- template_node_child: false
- text_leading: 1.0
- text_tracking: 0.0
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/example/templates/slider.gui b/example/templates/slider.gui
index ac7f71e..ce3cb31 100644
--- a/example/templates/slider.gui
+++ b/example/templates/slider.gui
@@ -1,113 +1,36 @@
-script: ""
textures {
- name: "druid"
- texture: "/example/assets/druid.atlas"
-}
-background_color {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
+ name: "druid_example"
+ texture: "/example/assets/druid_example.atlas"
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 260.0
y: 40.0
- z: 0.0
- w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/empty"
+ texture: "druid_example/empty"
id: "root"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
- layer: ""
inherit_alpha: true
- slice9 {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 0.0
- }
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
- position {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
size {
x: 260.0
y: 8.0
- z: 0.0
- w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
+ texture: "druid_example/ui_circle_8"
id: "slider_back"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 4.0
@@ -115,58 +38,24 @@ nodes {
z: 4.0
w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
nodes {
position {
x: -118.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- rotation {
- x: 0.0
- y: 0.0
- z: 0.0
- w: 1.0
- }
- scale {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
}
size {
x: 24.0
y: 24.0
- z: 0.0
- w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
- w: 1.0
}
type: TYPE_BOX
- blend_mode: BLEND_MODE_ALPHA
- texture: "druid/ui_circle_8"
+ texture: "druid_example/ui_circle_8"
id: "slider_pin"
- xanchor: XANCHOR_NONE
- yanchor: YANCHOR_NONE
- pivot: PIVOT_CENTER
- adjust_mode: ADJUST_MODE_FIT
parent: "root"
- layer: ""
inherit_alpha: true
slice9 {
x: 4.0
@@ -174,17 +63,6 @@ nodes {
z: 4.0
w: 4.0
}
- clipping_mode: CLIPPING_MODE_NONE
- clipping_visible: true
- clipping_inverted: false
- alpha: 1.0
- template_node_child: false
- size_mode: SIZE_MODE_MANUAL
- custom_type: 0
- enabled: true
- visible: true
- material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 512
diff --git a/game.project b/game.project
index a657a67..e233e1c 100644
--- a/game.project
+++ b/game.project
@@ -10,6 +10,7 @@ height = 1080
display_profiles = /builtins/render/default.display_profilesc
dynamic_orientation = 1
high_dpi = 1
+update_frequency = 60
[project]
title = druid
@@ -22,6 +23,8 @@ dependencies#1 = https://github.com/Insality/defold-saver/archive/refs/tags/1.zi
dependencies#2 = https://github.com/Insality/defold-tweener/archive/refs/tags/3.zip
dependencies#3 = https://github.com/Insality/panthera/archive/refs/tags/runtime.4.zip
dependencies#4 = https://github.com/Insality/defold-lang/archive/refs/tags/3.zip
+dependencies#5 = https://github.com/Insality/defold-event/archive/refs/tags/10.zip
+dependencies#6 = https://github.com/subsoap/defos/archive/refs/tags/v2.8.0.zip
[library]
include_dirs = druid
diff --git a/settings_deployer b/settings_deployer
index 448e40d..155dcc9 100644
--- a/settings_deployer
+++ b/settings_deployer
@@ -2,7 +2,7 @@
bob_folder=./
# You can point bob version for project in format "filename:sha"
-bob_sha="193:e4aaff11f49c941fde1dd93883cf69c6b8abebe4"
+bob_sha="196:11d2cd3a9be17b2fc5a2cb5cea59bbfb4af1ca96"
# Select Defold channel. Values: stable, beta, alpha
bob_channel="stable"
diff --git a/test/helper/test_helper.lua b/test/helper/test_helper.lua
index a728a0d..a451959 100644
--- a/test/helper/test_helper.lua
+++ b/test/helper/test_helper.lua
@@ -3,8 +3,9 @@ local mock = require("deftest.mock.mock")
local M = {}
-- Userdata type instead of script self
+---@return vector3|vector4
function M.get_context()
- return vmath.vector()
+ return vmath.vector({})
end
diff --git a/test/test.gui_script b/test/test.gui_script
index 54dcb74..59f6c21 100644
--- a/test/test.gui_script
+++ b/test/test.gui_script
@@ -17,6 +17,6 @@ function init(self)
deftest.add(tests[i])
end
- local is_report = (sys.get_config("test.report") == "1")
+ local is_report = (sys.get_config_int("test.report", 0) == 1)
deftest.run({ coverage = { enabled = is_report } })
end
diff --git a/test/tests/test_static_grid.lua b/test/tests/test_static_grid.lua
index 4e17ce7..0ffef0c 100644
--- a/test/tests/test_static_grid.lua
+++ b/test/tests/test_static_grid.lua
@@ -10,7 +10,7 @@ return function()
describe("Static Grid component", function()
local parent = nil
- ---@type druid.static_grid
+ ---@type druid.grid
local grid = nil
local prefab = nil
@@ -30,7 +30,7 @@ return function()
parent = mock_gui.add_box("parent", 0, 0, 50, 50)
prefab = mock_gui.add_box("prefab", 50, 50, 25, 25)
- grid = druid:new_static_grid(parent, prefab, 3)
+ grid = druid:new_grid(parent, prefab, 3)
end)
after(function()
diff --git a/update_docs.sh b/update_docs.sh
deleted file mode 100755
index e469afb..0000000
--- a/update_docs.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-## I am using Ldoc and my own Ldoc -> emmylua generator:
-## https://github.com/Insality/emmylua-from-ldoc-annotations
-
-emmylua_generator_path=~/code/lua/emmylua-from-ldoc-annotations
-
-echo "Update Ldoc"
-ldoc . --testing
-
-echo ""
-echo "Update EmmyLua annotations"
-original_path=$(pwd)
-bash $emmylua_generator_path/export.sh $original_path
-mv $emmylua_generator_path/annotations.lua $original_path/druid/annotations.lua
-cat ./utils/annotations_manual.lua >> $original_path/druid/annotations.lua
-cp $original_path/utils/ldoc_fixed.css $original_path/docs/ldoc_fixed.css
diff --git a/utils/annotations_manual.lua b/utils/annotations_manual.lua
deleted file mode 100644
index 46b8284..0000000
--- a/utils/annotations_manual.lua
+++ /dev/null
@@ -1,126 +0,0 @@
--- Manual Annotations --
-
----@class druid.component: druid.base_component
-
----@class druid.rich_text.metrics
----@field width number
----@field height number
----@field offset_x number|nil
----@field offset_y number|nil
----@field max_ascent number
----@field max_descent number
----@field node_size vector3|nil @For images only
-
----@class druid.rich_text.lines_metrics
----@field text_width number
----@field text_height number
----@field lines table
-
----@class druid.rich_text.word
----@field node node
----@field relative_scale number
----@field color vector4
----@field position vector3
----@field offset vector3
----@field scale vector3
----@field size vector3
----@field metrics druid.rich_text.metrics
----@field pivot userdata @ The gui.PIVOT_* constant
----@field text string
----@field shadow vector4
----@field outline vector4
----@field font string
----@field image druid.rich_text.image
----@field default_animation string
----@field anchor number
----@field br boolean
----@field nobr boolean
----@field source_text string
----@field image_color vector4
----@field text_color vector4
-
----@class druid.rich_text.image
----@field texture string
----@field anim string
----@field width number
----@field height number
-
----@class druid.rich_text.settings
----@field parent node
----@field size number
----@field fonts table
----@field scale vector3
----@field color vector4
----@field shadow vector4
----@field outline vector4
----@field position vector3
----@field image_pixel_grid_snap boolean
----@field combine_words boolean
----@field default_animation string
----@field text_prefab node
----@field adjust_scale number
----@field default_texture string
----@field is_multiline boolean
----@field text_leading number
----@field font hash
----@field width number
----@field height number
-
----@class GUITextMetrics
----@field width number
----@field height number
----@field max_ascent number
----@field max_descent number
-
----@class utf8
----@field len fun(s: string):number
----@field sub fun(s: string, start_index: number, length: number)
----@field reverse fun()
----@field char fun()
----@field unicode fun()
----@field gensub fun()
----@field byte fun()
----@field find fun()
----@field match fun(s: string, m: string)
----@field gmatch fun(s: string, m: string)
----@field gsub fun()
----@field dump fun()
----@field format fun()
----@field lower fun()
----@field upper fun()
----@field rep fun()
-
-
----Add generics to some functions.
-
----Create new component.
----@generic T: druid.base_component
----@param self druid_instance
----@param component T Component module
----@param ... any Other component params to pass it to component:init function
----@return T Component instance
-function druid_instance.new(self, component, ...) end
-
---- Set current component style table.
---- Invoke `on_style_change` on component, if exist. Component should handle their style changing and store all style params
----@generic T: druid.base_component
----@param self T @{BaseComponent}
----@param druid_style table|nil Druid style module
----@return T @{BaseComponent}
-function druid__base_component.set_style(self, druid_style) end
-
---- Set component template name.
---- Use on all your custom components with GUI layouts used as templates. It will check parent template name to build full template name in self:get_node()
----@generic T: druid.base_component
----@param self T @{BaseComponent}
----@param template string BaseComponent template name
----@return T @{BaseComponent}
-function druid__base_component.set_template(self, template) end
-
---- Set current component nodes.
---- Use if your component nodes was cloned with `gui.clone_tree` and you got the node tree.
----@generic T: druid.base_component
----@param self T @{BaseComponent}
----@param nodes table BaseComponent nodes table
----@return T @{BaseComponent}
-function druid__base_component.set_nodes(self, nodes) end
diff --git a/utils/ldoc_fixed.css b/utils/ldoc_fixed.css
deleted file mode 100644
index e63d191..0000000
--- a/utils/ldoc_fixed.css
+++ /dev/null
@@ -1,311 +0,0 @@
-/* BEGIN RESET
-
-Copyright (c) 2010, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.com/yui/license.html
-version: 2.8.2r1
-*/
-html {
- color: #000;
- background: #FFF;
-}
-body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
- margin: 0;
- padding: 0;
-}
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-fieldset,img {
- border: 0;
-}
-address,caption,cite,code,dfn,em,strong,th,var,optgroup {
- font-style: inherit;
- font-weight: inherit;
-}
-del,ins {
- text-decoration: none;
-}
-li {
- margin-left: 20px;
-}
-caption,th {
- text-align: left;
-}
-h1,h2,h3,h4,h5,h6 {
- font-size: 100%;
- font-weight: bold;
-}
-q:before,q:after {
- content: '';
-}
-abbr,acronym {
- border: 0;
- font-variant: normal;
-}
-sup {
- vertical-align: baseline;
-}
-sub {
- vertical-align: baseline;
-}
-legend {
- color: #000;
-}
-input,button,textarea,select,optgroup,option {
- font-family: inherit;
- font-size: inherit;
- font-style: inherit;
- font-weight: inherit;
-}
-input,button,textarea,select {*font-size:100%;
-}
-/* END RESET */
-
-body {
- margin-left: 1em;
- margin-right: 1em;
- font-family: arial, helvetica, geneva, sans-serif;
- background-color: #ffffff; margin: 0px;
-}
-
-code, tt { font-family: monospace; font-size: 1.1em; }
-span.parameter { font-family:monospace; }
-span.parameter:after { content:":"; }
-span.types:before { content:"("; }
-span.types:after { content:")"; }
-.type { font-weight: bold; font-style:italic }
-
-body, p, td, th { font-size: .95em; line-height: 1.2em;}
-
-p, ul { margin: 10px 0 0 0px;}
-
-strong { font-weight: bold;}
-
-em { font-style: italic;}
-
-h1 {
- font-size: 1.5em;
- margin: 0 0 20px 0;
-}
-h2, h3, h4 { margin: 15px 0 10px 0; }
-h2 { font-size: 1.25em; }
-h3 { font-size: 1.15em; }
-h4 { font-size: 1.06em; }
-
-a:link { font-weight: bold; color: #004080; text-decoration: none; }
-a:visited { font-weight: bold; color: #006699; text-decoration: none; }
-a:link:hover { text-decoration: underline; }
-
-hr {
- color:#cccccc;
- background: #00007f;
- height: 1px;
-}
-
-blockquote { margin-left: 3em; }
-
-ul { list-style-type: disc; }
-
-p.name {
- font-family: "Andale Mono", monospace;
- padding-top: 1em;
-}
-
-pre {
- background-color: rgb(245, 245, 245);
- border: 1px solid #C0C0C0; /* silver */
- padding: 10px;
- margin: 10px 0 10px 0;
- overflow: auto;
- font-family: "Andale Mono", monospace;
-}
-
-pre.example {
- font-size: .85em;
-}
-
-table.index { border: 1px #00007f; }
-table.index td { text-align: left; vertical-align: top; }
-
-#container {
- margin-left: 1em;
- margin-right: 1em;
- background-color: #ffffff;
-}
-
-#product {
- text-align: center;
- border-bottom: 1px solid #cccccc;
- background-color: #ffffff;
-}
-
-#product big {
- font-size: 2em;
-}
-
-#main {
- background-color:#FFFFFF; // #f0f0f0;
- border-left: 1px solid #cccccc;
-}
-
-#navigation {
- position: fixed;
- top: 0;
- left: 0;
- float: left;
- width: 14em;
- vertical-align: top;
- background-color:#FFFFFF; // #f0f0f0;
- border-right: 2px solid #cccccc;
- overflow: visible;
- overflow-y: scroll;
- height: 100%;
- padding-left: 1em;
-}
-
-#navigation h2 {
- background-color:#FFFFFF;//:#e7e7e7;
- font-size:1.1em;
- color:#000000;
- text-align: left;
- padding:0.2em;
- border-bottom:1px solid #dddddd;
-}
-
-#navigation ul
-{
- font-size:1em;
- list-style-type: none;
- margin: 1px 1px 10px 1px;
-}
-
-#navigation li {
- text-indent: -1em;
- display: block;
- margin: 3px 0px 0px 22px;
-}
-
-#navigation li li a {
- margin: 0px 3px 0px -1em;
-}
-
-#content {
- margin-left: 14em;
- padding: 1em;
- padding-left: 2em;
- width: 900px;
- border-left: 2px solid #cccccc;
- // border-right: 2px solid #cccccc;
- background-color: #ffffff;
-}
-
-#about {
- clear: both;
- padding-left: 1em;
- margin-left: 14em; // avoid the damn sidebar!
- border-top: 2px solid #cccccc;
- border-left: 2px solid #cccccc;
- background-color: #ffffff;
-}
-
-@media print {
- body {
- font: 12pt "Times New Roman", "TimeNR", Times, serif;
- }
- a { font-weight: bold; color: #004080; text-decoration: underline; }
-
- #main {
- background-color: #ffffff;
- border-left: 0px;
- }
-
- #container {
- margin-left: 2%;
- margin-right: 2%;
- background-color: #ffffff;
- }
-
- #content {
- padding: 1em;
- background-color: #ffffff;
- }
-
- #navigation {
- display: none;
- }
- pre.example {
- font-family: "Andale Mono", monospace;
- font-size: 10pt;
- page-break-inside: avoid;
- }
-}
-
-table.module_list {
- border-width: 1px;
- border-style: solid;
- border-color: #cccccc;
- border-collapse: collapse;
-}
-table.module_list td {
- border-width: 1px;
- padding: 3px;
- border-style: solid;
- border-color: #cccccc;
-}
-table.module_list td.name { background-color: #f0f0f0; ; min-width: 200px; }
-table.module_list td.summary { width: 100%; }
-
-table.function_list {
- border-width: 1px;
- border-style: solid;
- border-color: #cccccc;
- border-collapse: collapse;
-}
-table.function_list td {
- border-width: 1px;
- padding: 3px;
- border-style: solid;
- border-color: #cccccc;
-}
-table.function_list td.name { background-color: #f6f6ff; ; min-width: 200px; }
-table.function_list td.summary { width: 100%; }
-
-dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
-dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
-dl.table h3, dl.function h3 {font-size: .95em;}
-
-ul.nowrap {
- overflow:auto;
- whitespace:nowrap;
-}
-
-/* stop sublists from having initial vertical space */
-ul ul { margin-top: 0px; }
-ol ul { margin-top: 0px; }
-ol ol { margin-top: 0px; }
-ul ol { margin-top: 0px; }
-
-/* make the target distinct; helps when we're navigating to a function */
-a:target + * {
- background-color: #FF9;
-}
-
-
-/* styles for prettification of source */
-pre .comment { color: #558817; }
-pre .constant { color: #a8660d; }
-pre .escape { color: #844631; }
-pre .keyword { color: #aa5050; font-weight: bold; }
-pre .library { color: #0e7c6b; }
-pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
-pre .string { color: #8080ff; }
-pre .number { color: #f8660d; }
-pre .operator { color: #2239a8; font-weight: bold; }
-pre .preprocessor, pre .prepro { color: #a33243; }
-pre .global { color: #800080; }
-pre .user-keyword { color: #800080; }
-pre .prompt { color: #558817; }
-pre .url { color: #272fc2; text-decoration: underline; }
-