mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 02:17:52 +02:00
Update
This commit is contained in:
parent
fb9c80b284
commit
e83e5a6c84
37
CONTRIBUTING.md
Normal file
37
CONTRIBUTING.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Contribution Guidelines
|
||||
|
||||
Hello, Defolder! Thanks for your interest in contributing to the **Druid** project. It's a massive project that has been around for a long time, and it's still growing. This project has a lot of places where you can help!
|
||||
|
||||
Finally, there are set of instructions that will help you to contribute to the project.
|
||||
|
||||
Thanks for your help!
|
||||
|
||||
## Update Documentation
|
||||
|
||||
If you see any mistakes in the documentation, you can update it by yourself.
|
||||
|
||||
You can push changes to the `master` branch directly. In case of small fixes, please also update the relative API `md` files. If there is a lot of changes, I will regenerate them manually.
|
||||
|
||||
## Issue Reporting
|
||||
|
||||
If you find any bugs, please report them to the [issue tracker](https://github.com/druid-js/druid/issues).
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Any pull requests are welcome!
|
||||
|
||||
Please, open PR against the `develop` branch. Very nice to have an issue, which this PR fixes.
|
||||
|
||||
You fix should contains only changes, which are related to the issue. Also please keep the code style the same!
|
||||
|
||||
Thanks <3
|
||||
|
||||
## Add or Update Examples
|
||||
|
||||
Examples contains a GUI scene, a Druid widget for this GUI. This GUI is included to the `examples.gui` and the information about examples are added in `examples_list.lua` file
|
||||
|
||||
You can add new examples or update existing ones.
|
||||
|
||||
To add new example, you need to create a new folder in the `examples` directory.
|
||||
|
||||
|
88
README.md
88
README.md
@ -7,7 +7,7 @@
|
||||
|
||||
[](https://github.com/sponsors/insality) [](https://ko-fi.com/insality) [](https://www.buymeacoffee.com/insality)
|
||||
|
||||
**Druid** - a powerful, flexible and easy to use **Defold** component UI framework. Contains a wide range of components and features to create stunning and customizable GUIs. Provides a powerful way to create, compose and manage your custom components and scenes.
|
||||
**Druid** - a powerful, flexible and easy to use **Defold** component UI framework. Contains a wide range of UI components that you can use to create a beautiful, responsive and customizable GUIs. Provides a powerful way to create, compose and manage your custom components and scenes.
|
||||
|
||||
## Druid Example
|
||||
|
||||
@ -15,6 +15,13 @@ Check the [**HTML5 version**](https://insality.github.io/druid/) of the **Druid*
|
||||
|
||||
In this example you can inspect a variety of **Druid** components and see how they work. Each example page provides a direct link to the corresponding example code, making it easier for you to understand how to use **Druid**.
|
||||
|
||||
## Features
|
||||
|
||||
- **Components** - Provides a extensive set of components, from basic buttons to infinity data lists and rich texts
|
||||
- **Customizable** - You can customize components appearance and behaviour
|
||||
- **Widgets** - Powerful way to create your own reusable components
|
||||
- **Input Handling** - Handles input in a stack-based manner and manage input priority
|
||||
- **Event Based** - Uses [Defold Event](https://github.com/Insality/defold-event) for components callbacks and communication between components
|
||||
|
||||
## Setup
|
||||
|
||||
@ -42,7 +49,7 @@ Here is a list of [all releases](https://github.com/Insality/druid/releases).
|
||||
|
||||
### Library Size
|
||||
|
||||
> **Note:** The library size is calculated based on the build report per platform.
|
||||
> **Note:** The library size is calculated based on the build report per platform. Full size contains all components, they can be stripped out in the build process if you don't need them.
|
||||
|
||||
| Platform | Full Size |
|
||||
| ---------------- | ------------- |
|
||||
@ -59,11 +66,41 @@ Here is a list of [all releases](https://github.com/Insality/druid/releases).
|
||||
|
||||
### Basic usage
|
||||
|
||||
To utilize **Druid**, begin by creating a **Druid** instance to instantiate components and include the main functions of **Druid**: *update*, *final*, *on_message*, and *on_input*.
|
||||
To use **Druid**, begin by creating a **Druid** instance to instantiate components and include the main functions of **Druid**: *update*, *final*, *on_message*, and *on_input*.
|
||||
|
||||
When using **Druid** components, provide a node name string as an argument. If you don't have the node name available in some cases, you can pass `gui.get_node()` instead.
|
||||
Create a new `*.gui_script` file and add the following code:
|
||||
|
||||
All **Druid** and component methods are invoked using the `:` operator, such as `self.druid:new_button()`.
|
||||
```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
|
||||
```
|
||||
|
||||
Now add this `*.gui_script` as a script to your GUI scene and now you can start creating Druid components.
|
||||
|
||||
Always, when you need to pass a node to a component, you can pass a node name string instead of `gui.get_node()` function.
|
||||
|
||||
All functions of **Druid** are invoked using the `:` operator, such as `self.druid:new_button()`.
|
||||
|
||||
Here is a basic example with a com
|
||||
|
||||
```lua
|
||||
local druid = require("druid.druid")
|
||||
@ -71,48 +108,13 @@ local druid = require("druid.druid")
|
||||
-- All component callbacks pass "self" as first argument
|
||||
-- This "self" is a context data passed in `druid.new(context)`
|
||||
local function on_button_callback(self)
|
||||
print("The button clicked!")
|
||||
self.text:set_text("The button clicked!")
|
||||
end
|
||||
|
||||
function init(self)
|
||||
self.druid = druid.new(self)
|
||||
self.button = self.druid:new_button("button_node_name", on_button_callback)
|
||||
end
|
||||
|
||||
-- "final" is a required function for the correct Druid workflow
|
||||
function final(self)
|
||||
self.druid:final()
|
||||
end
|
||||
|
||||
-- "update" is used in progress bar, scroll, and timer components
|
||||
function update(self, dt)
|
||||
self.druid:update(dt)
|
||||
end
|
||||
|
||||
-- "on_message" is used for specific Druid events, like language change or layout change
|
||||
function on_message(self, message_id, message, sender)
|
||||
self.druid:on_message(message_id, message, sender)
|
||||
end
|
||||
|
||||
-- "on_input" is used in almost all Druid components
|
||||
-- The return value from `druid:on_input` is required!
|
||||
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)
|
||||
self.button = self.druid:new_button("button_node_id", on_button_callback)
|
||||
self.text = self.druid:new_text("text_node_id", "Hello, Druid!")
|
||||
end
|
||||
|
||||
function final(self)
|
||||
|
@ -310,7 +310,6 @@ function M:set_web_user_interaction(is_web_mode)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---@param action_id hash The action id
|
||||
---@return boolean is_match True if the input matches the button
|
||||
function M:_is_input_match(action_id)
|
||||
|
@ -9,7 +9,7 @@ local COLOR_Z = hash("color.z")
|
||||
local M = {}
|
||||
|
||||
|
||||
---Get color color by id
|
||||
---Get color color by string (hex or from palette)
|
||||
---@param color_id string
|
||||
---@return vector4
|
||||
function M.get(color_id)
|
||||
|
@ -135,8 +135,9 @@ end
|
||||
---@param nodes table<hash, node>|nil
|
||||
---@return druid.instance
|
||||
function M:get_druid(template, nodes)
|
||||
local context = { _context = self }
|
||||
local druid_instance = setmetatable(context, { __index = self._meta.druid })
|
||||
local druid_instance = setmetatable({
|
||||
_context = self
|
||||
}, { __index = self._meta.druid })
|
||||
|
||||
if template then
|
||||
self:set_template(template)
|
||||
|
@ -112,12 +112,14 @@ end
|
||||
|
||||
|
||||
---Get a binded widget to the current game object.
|
||||
--- msg.url(nil, nil, "go_widget") -- current game object
|
||||
--- msg.url(nil, object_url, "go_widget") -- other game object
|
||||
---@generic T: druid.widget
|
||||
---@param widget_class T The class of the widget to return
|
||||
---@param gui_url_string string? GUI url, if nil current gui will be used
|
||||
---@param gui_url url GUI url
|
||||
---@return T
|
||||
function M.get_widget(widget_class, gui_url_string)
|
||||
local gui_url = msg.url(gui_url_string)
|
||||
function M.get_widget(widget_class, gui_url)
|
||||
gui_url = gui_url or msg.url()
|
||||
local guis = REGISTERED_GUI_WIDGETS[gui_url.socket]
|
||||
if not guis then
|
||||
return nil
|
||||
|
@ -34,6 +34,7 @@
|
||||
---@field upper fun()
|
||||
---@field rep fun()
|
||||
|
||||
-- This one should be a part of Defold annotations
|
||||
---@class action
|
||||
---@field value number The amount of input given by the user. This is usually 1 for buttons and 0-1 for analogue inputs. This is not present for mouse movement.
|
||||
---@field pressed boolean If the input was pressed this frame. This is not present for mouse movement.
|
||||
|
@ -8,31 +8,29 @@ local druid_component = require("druid.component")
|
||||
|
||||
---The Druid Factory used to create components
|
||||
---@class druid.instance
|
||||
---@field components_all druid.component[] All created components
|
||||
---@field components_interest table<string, druid.component[]> All components sorted by interest
|
||||
---@field private _context table Druid context, usually a self of gui script
|
||||
---@field private _style table Druid style table
|
||||
---@field private _is_late_remove_enabled boolean
|
||||
---@field private _late_remove druid.component[]
|
||||
---@field private _input_blacklist druid.component[]|nil
|
||||
---@field private _input_whitelist druid.component[]|nil
|
||||
---@field private input_inited boolean
|
||||
---@field private _late_init_timer_id number
|
||||
---@field private _input_components druid.component[]
|
||||
---@field package input_inited boolean Used to check if input is initialized
|
||||
---@field package components_all druid.component[] All created components
|
||||
---@field package components_interest table<string, druid.component[]> All components sorted by interest
|
||||
---@field package _context table Druid context, usually a self of gui script
|
||||
---@field package _style table Druid style table
|
||||
---@field package _late_init_timer_id number Timer id for late init
|
||||
---@field package _late_remove druid.component[] Components to be removed on late update
|
||||
---@field package _is_late_remove_enabled boolean Used to check if components should be removed on late update
|
||||
---@field package _input_blacklist druid.component[]|nil Components that should not receive input
|
||||
---@field package _input_whitelist druid.component[]|nil Components that should receive input
|
||||
local M = {}
|
||||
|
||||
local MSG_ADD_FOCUS = hash("acquire_input_focus")
|
||||
local MSG_REMOVE_FOCUS = hash("release_input_focus")
|
||||
local IS_NO_AUTO_INPUT = sys.get_config_int("druid.no_auto_input", 0) == 1
|
||||
local INTERESTS_CACHE = {} -- Cache interests per component class in runtime
|
||||
|
||||
|
||||
local function set_input_state(self, is_input_inited)
|
||||
if IS_NO_AUTO_INPUT or (self.input_inited == is_input_inited) then
|
||||
return
|
||||
end
|
||||
|
||||
self.input_inited = is_input_inited
|
||||
msg.post(".", is_input_inited and MSG_ADD_FOCUS or MSG_REMOVE_FOCUS)
|
||||
msg.post(".", is_input_inited and "acquire_input_focus" or "release_input_focus")
|
||||
end
|
||||
|
||||
|
||||
@ -98,7 +96,7 @@ local function register_interests(self, instance)
|
||||
end
|
||||
|
||||
|
||||
-- Create the Druid component instance
|
||||
---Create the Druid component instance
|
||||
---@param self druid.instance
|
||||
---@param instance_class druid.component
|
||||
---@return druid.component
|
||||
@ -148,8 +146,8 @@ end
|
||||
|
||||
|
||||
---Check whitelists and blacklists for input components
|
||||
---@param component druid.component
|
||||
---@return boolean
|
||||
---@param component druid.component The component to check
|
||||
---@return boolean is_can_use True if component can be processed on input step
|
||||
function M:_can_use_input_component(component)
|
||||
local can_by_whitelist = true
|
||||
local can_by_blacklist = true
|
||||
@ -181,7 +179,7 @@ end
|
||||
---Druid class constructor which used to create a Druid's components
|
||||
---@param context table Druid context. Usually it is self of gui script
|
||||
---@param style table? Druid style table
|
||||
---@return druid.instance
|
||||
---@return druid.instance instance The new Druid instance
|
||||
function M.create_druid_instance(context, style)
|
||||
local self = setmetatable({}, { __index = M })
|
||||
|
||||
@ -244,8 +242,8 @@ end
|
||||
|
||||
|
||||
---Remove created component from Druid instance.
|
||||
--
|
||||
-- Component `on_remove` function will be invoked, if exist.
|
||||
---
|
||||
---Component `on_remove` function will be invoked, if exist.
|
||||
---@generic T: druid.component
|
||||
---@param component T Component instance
|
||||
---@return boolean is_removed True if component was removed
|
||||
@ -422,8 +420,8 @@ 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
|
||||
---This one called by global druid.on_language_change, but can be
|
||||
---call manualy to update all translations
|
||||
---@private
|
||||
function M:on_language_change()
|
||||
local components = self.components_interest[const.ON_LANGUAGE_CHANGE]
|
||||
@ -540,7 +538,7 @@ end
|
||||
|
||||
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 callback function|event|nil The callback(self, custom_args) to call on back event
|
||||
---@param params any|nil Callback argument
|
||||
---@return druid.back_handler back_handler The new back handler component
|
||||
function M:new_back_handler(callback, params)
|
||||
@ -722,7 +720,7 @@ end
|
||||
|
||||
local rich_input = require("druid.custom.rich_input.rich_input")
|
||||
---Create RichInput component.
|
||||
-- As a template please check rich_input.gui layout.
|
||||
---As a template please check rich_input.gui layout.
|
||||
---@param template string The template string name
|
||||
---@param nodes table|nil Nodes table from gui.clone_tree
|
||||
---@return druid.rich_input rich_input The new rich input component
|
||||
|
@ -6,7 +6,8 @@ local druid = require("druid.druid")
|
||||
local widget = require("example.other.go_bindings.go_widget")
|
||||
|
||||
function init(self)
|
||||
self.go_widget = druid.get_widget(widget, "#go_widget")
|
||||
local gui_url = msg.url(nil, nil, "go_widget")
|
||||
self.go_widget = druid.get_widget(widget, gui_url)
|
||||
self.go_widget:play_animation()
|
||||
self.go_widget:set_position(go.get_position())
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user