From 8d409b80629529bd2abcbbe557e587e3bbdd6a56 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 19 Oct 2024 10:58:51 +0300 Subject: [PATCH] Update docs --- .vscode/settings.json | 8 +- README.md | 28 +++--- docs_md/01-components.md | 61 ++----------- docs_md/02-creating_custom_components.md | 58 ++++++++---- docs_md/changelog.md | 107 ++++++++++++++++++----- 5 files changed, 153 insertions(+), 109 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 44850ee8..28a4386c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -33,6 +33,10 @@ "Lua.runtime.version": "Lua 5.1", "Lua.workspace.library": [ "~/Library/Application Support/Code/User/globalStorage/astronachos.defold", - "~/Library/Application Support/Code/User/workspaceStorage/72e25b7e0fdc873ee6f7baa61edbd6b1/astronachos.defold" - ] + "~/Library/Application Support/Code/User/workspaceStorage/72e25b7e0fdc873ee6f7baa61edbd6b1/astronachos.defold", + "~/Library/Application Support/Code/User/workspaceStorage/1446075a23c89451a63f0e82b2291def/astronachos.defold" + ], + "files.exclude": { + "**/*.gui": true + } } \ No newline at end of file diff --git a/README.md b/README.md index 760392e6..987ac8a2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,11 @@ **Druid** - powerful **Defold** component UI framework that empowers developers to create stunning and customizable GUIs by leveraging a wide range of embedded components or effortlessly designing their own game-specific components. -Try the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Druid** example app. +## Druid Example + +Check the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Druid** example app. + +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**. ## Setup @@ -17,9 +21,9 @@ Try the [**HTML5 version**](https://insality.github.io/druid/druid/) of the **Dr To integrate the **Druid** extension into your own project, add this project as a [dependency](https://www.defold.com/manuals/libraries/) in your **Defold** game. Open your `game.project` file and add the following line to the dependencies field under the project section: -**Druid v0.12.0** +**Druid v1.0** -> [https://github.com/Insality/druid/archive/refs/tags/0.12.0.zip](https://github.com/Insality/druid/archive/refs/tags/0.12.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). @@ -30,7 +34,7 @@ Here is a list of [all releases](https://github.com/Insality/druid/releases). | Platform | Library Size | | ---------------- | ------------- | -| HTML5 | **38.96 KB** | +| HTML5 | **38.00 KB** | | Desktop / Mobile | **65.97 KB** | @@ -118,10 +122,10 @@ Here is full **Druid** components list. | **[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. | ❌ | | -| **[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 | ❌ | | +| **[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](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) | | @@ -137,18 +141,16 @@ druid.register("data_list", data_list) | Name | Description | Example |
Preview
| |------|-------------|---------|---------| -| **[Checkbox](https://insality.github.io/druid/modules/Checkbox.html)** | Switch node state on click event. | [Checkbox Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | | -| **[Checkbox group](https://insality.github.io/druid/modules/CheckboxGroup.html)** | Group of checkbox components. | [Checkbox group Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | | -| **[Radio group](https://insality.github.io/druid/modules/RadioGroup.html)** | Like checkbox group but with single choise only. | [Radio Group Example](https://insality.github.io/druid/druid/?example=general_checkboxes) | | -| **[Dynamic Grid](https://insality.github.io/druid/modules/DynamicGrid.html)** | Logic over GUI Node. Component to manage node positions with all different node sizes. Only one direction: horizontal or vertical. | [Dynamic Grid Example](https://insality.github.io/druid/druid/?example=general_grid) | | | **[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](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](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) | | For a complete overview, see: **_[components.md](docs_md/01-components.md)_**. diff --git a/docs_md/01-components.md b/docs_md/01-components.md index 16c30b3e..6aa07353 100644 --- a/docs_md/01-components.md +++ b/docs_md/01-components.md @@ -192,49 +192,6 @@ Create input component with druid: `input = druid:new_input(button_node_name, te - To make work different keyboard type, make sure value in game.project Android:InputMethod set to HidderInputField (https://defold.com/manuals/project-settings/#input-method) -## Checkbox -[Checkbox API here](https://insality.github.io/druid/modules/Checkbox.html) - -### Overview -Basic Druid checkbox component. - -### Setup -Create checkbox component with druid: `checkbox = druid:new_checkbox(node, callback)` - -### Notes -- Checkbox uses button to handle click -- You can setup another node to handle input with click_node arg in component init: `druid:new_checkbox(node, callback, [click_node])` - - -## Checkbox group -[Checkbox group API here](https://insality.github.io/druid/modules/CheckboxGroup.html) - -### Overview -Several checkboxes in one group - -### Setup -Create checkbox_group component with druid: `group = druid:new_checkbox_group(nodes[], callback)` - -### Notes -- Callback arguments: `function(self, checkbox_index)`. Index is equals in _nodes[]_ array in component constructor -- You can get/set checkbox_group state with `group:set_state()` and `group:get_state()` - - -## Radio group -[Radio group API here](https://insality.github.io/druid/modules/RadioGroup.html) - -### Overview -Several checkboxes in one group with single choice - -### Setup -Create radio_group component with druid: `group = druid:new_radio_group(nodes[], callback)` - -### Notes -- Callback arguments: `function(self, checkbox_index)`. Index is equals in _nodes[]_ array in component constructor -- You can get/set radio_group state with `group:set_state()` and `group:get_state()` -- Only different from checkbox_group: on click another checkboxes in this group will be unchecked - - ## Timer [Timer API here](https://insality.github.io/druid/modules/Timer.html) @@ -419,7 +376,7 @@ Create hotkey component with druid: `hotkey = druid:new_hotkey(keys_array, callb [Layout API here](https://insality.github.io/druid/modules/Layout.html) ### Overview -Component to handle node size depends on layout mode. Unlike from Defold Adjust modes, you able to select node stretch by one size or zoom by minimum or maximum side +Component to arrange nodes inside layout node with margin/paddings settings. Works with different node sizes and pivots. Works in the same way as Figma AutoLayout ### Setup This is extended component. Before use it, you should register it: @@ -428,17 +385,15 @@ local druid = require("druid.druid") local layout = require("druid.extended.layout") druid.register("layout", layout) ``` -Create layout component with druid: `layout = druid:new_layout(node, layout_mode, on_size_change_callback)` +Create layout component with druid: `layout = druid:new_layout(node, layout_mode)` ### Notes - Layout mode can be next: - - `const.LAYOUT_MODE.STRETCH_X` - Stretch node only by X - - `const.LAYOUT_MODE.STRETCH_Y` - Stretch node only by Y - - `const.LAYOUT_MODE.ZOOM_MIN` - Zoom node by minimal stretch multiplier - - `const.LAYOUT_MODE.ZOOM_MAX` - Zoom node by maximum stretch multiplier - - `const.LAYOUT_MODE.FIT` - Usual Defold Fit mode - - `const.LAYOUT_MODE.STRETCH` - Usual Defold Stretch Mode -- The Layout component will change the node size property. So it's able to increase size of 9patch nodes without scaling issue -- The Layout works even inside parent node with Fit adjust mode + - `horizontal` - arrange nodes in horizontal line + - `vertical` - arrange nodes in vertical line + - `horizontal_wrap` - arrange nodes in horizontal line with wrap to next line +- You can setup margin and padding for layout nodes +- You can set "justify" alignment to place nodes with the same margin between layout node borders +- You can set "hug" by content. This option will set layout node size by content size. Can be setup separately for width and height diff --git a/docs_md/02-creating_custom_components.md b/docs_md/02-creating_custom_components.md index cf9c32cc..45e5a6b1 100644 --- a/docs_md/02-creating_custom_components.md +++ b/docs_md/02-creating_custom_components.md @@ -15,18 +15,38 @@ A basic custom component template looks like this (you can copy it from `/druid/ local component = require("druid.component") ---@class component_name: druid.base_component -local Component = component.create("component_name") +local M = component.create("component_name") -function Component:init(template, nodes) +function M: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) end -function Component:on_remove() end +function M:hello() + print("Hello from custom component") +end + +return M +``` + +Then you can create your custom component with Druid: +```lua +local druid = require("druid.druid") + +local my_component = require("my.amazing.component") + +function init(self) + self.druid = druid.new(self) + + -- We pass a GUI template "template_name" and skip nodes due it already on the scene + self.my_component = self.druid:new(my_component, "template_name") + self.my_component:hello() -- Hello from custom component + + +end -return Component ``` ### Full Component Template @@ -37,36 +57,36 @@ A full custom component template looks like this (you can copy it from `/druid/t local component = require("druid.component") ---@class component_name: druid.base_component -local Component = component.create("component_name") +local M = component.create("component_name") -function Component:init(template, nodes) +function M:init(template, nodes) self.druid = self:get_druid(template, nodes) self.root = self:get_node("root") end -function Component:update(dt) end +function M:update(dt) end -function Component:on_input(action_id, action) return false end +function M:on_input(action_id, action) return false end -function Component:on_style_change(style) end +function M:on_style_change(style) end -function Component:on_message(message_id, message, sender) end +function M:on_message(message_id, message, sender) end -function Component:on_language_change() end +function M:on_language_change() end -function Component:on_layout_change() end +function M:on_layout_change() end -function Component:on_window_resized() end +function M:on_window_resized() end -function Component:on_input_interrupt() end +function M:on_input_interrupt() end -function Component:on_focus_lost() end +function M:on_focus_lost() end -function Component:on_focus_gained() end +function M:on_focus_gained() end -function Component:on_remove() end +function M:on_remove() end -return Component +return M ``` ### Spawning a Custom Component @@ -117,7 +137,7 @@ Druid provides an editor script to assist you in creating Lua files for your GUI The script analyzes the current GUI scene and generates a Lua file with stubs for all Druid components found. The output file is named after the current GUI scene and placed in the same directory. Note that the script does not override any existing *.lua files. If you want to regenerate a file, delete the previous version first. -The script requires `python3` with `deftree` installed. If `deftree` is not installed, the instructions will be displayed in the console. +The script requires `python` with `deftree` installed. If `deftree` is not installed, the instructions will be displayed in the console. ### Auto-Layout Components diff --git a/docs_md/changelog.md b/docs_md/changelog.md index f04f2843..aa478ae9 100644 --- a/docs_md/changelog.md +++ b/docs_md/changelog.md @@ -503,25 +503,88 @@ Please support me if you like this project! It will help me keep engaged to upda -### Druid 0.12.0 - -**Changelog 0.12.0** -- New Logo! -- [Example] New Example Page with 40+ examples -- [Data List] Rework Data List. Now only works with Static Grid only. Now the Data List more stable with extended API. - - Add Cached Data List option. This used less memory (it's really much optimized) but requires uses the `on_add_element` and `on_remove_element` events to setup your nodes. All components should be the same class. -- [Rich Text] The Rich Text now applied to the text node instead of Rich Text Template (contained 3 nodes before - root, text and image prefabs) -- [Rich Input] Updated Rich Input. Now it goes with selection and cursor navigation. Added new input keys for setup in Druid (arrows keys, ctrl, shift) -- [System] Updated and fixed annotations -- [System] Removed `middleclass.lua` -- [System] Add `self:get_druid(template, nodes)` to escape the `self:set_template(template)` and `self:set_nodes(nodes)` calls in custom components -- [Input] Now user can tap from one text input area to another with one click. Before first tap is closed the focus on selected input. -- [Layout] Removed Layout component. Add new Layout component what do a some different things. It's like Dynamic Grid but with more control and settings. -- [Dynamic Grid] Deprecated Dynamic Grid. Layout will be instead of it. -- [Drag] Add touch param to Drag callbacks, it's much easier to add custom logic with knowledge of input action data. -- [Scroll] Add `scroll.view_size`, `scroll:set_view_size(size)` and `scroll:update_view_size()` functions to manage with current scroll input area and scroll visible part -- [Static Grid] Add `grid:set_item_size(size)`, `grid:sort_nodes(comparator)` functions -- [Text] Seems adjust by height for multiline text is workings good now -- [Rich Input] Extended Rich Input API -- [Progress Bar] More accurate scaling for progress bars fow images with slice9 params -- [Slider] Fix several slider issues in slider setup +### Druid 1.0 + +**Description** + +Hello! The long-awaited update for Druid is finally here! + +I'm releasing this version as 1.0, since Druid is pretty stable and packed with features. + +This update brings a lot of improvements, so let's dive in: + +**New Example Page** +I’ve updated Druid's main examples page. Since Druid has become quite popular, I wanted to ensure the examples meet high standards of quality and aesthetics. The examples are now clearer and provide more information. I’ve also added many new examples. Check them out! + +**Component Reworking** +Several components have been reworked. While I generally avoid introducing breaking changes, sometimes they are necessary for progress. + +- Rich Text is now applied directly to the text node, rather than using a Rich Text Template. This makes setup and usage much easier! I’m still working on figuring out how to apply this approach to Rich Input. + +- The Layout component has been completely replaced. It now functions similarly to Dynamic Grid but is responsible for adjusting nodes in the GUI. It’s easier to use and offers more configuration options. + +- Dynamic Grid will be deprecated in the future, with the new Layout component serving as its replacement. + +- Data List now works exclusively with Static Grid, making it more stable and optimized. Additionally, a new "cached" version is available, which optimizes node reuse. However, the cached version requires using `on_add_element` and `on_remove_element` events to properly set up nodes. + +**Code Cleanup** +I’ve finally removed "middleclass" from Druid. If you were using it for some reason, you’ll need to copy the "middleclass" code into your project. + +**Annotations** +Druid’s annotations were originally created when there were no Lua language servers. These annotations are of the older LDoc type and not EmmyLua. In the future, I aim to eliminate annotations altogether and rely on annotated code, which is easier to read, maintain, and feature-rich. The Defold will support the LLS (Lua Language Server) as well as VSCode with amazing Defold-Kit extension. + +--- + +**Milestone**: https://github.com/Insality/druid/milestone/12 + +**Changelog 1.0.0** + +- New Druid logo! +- **[Example]** New Example Page with 40+ examples. +- **[Data List]** Reworked Data List to work only with **Static Grid**. It’s now more stable and has an extended API. + - Added a **Cached Data List** option, which uses less memory (highly optimized) but requires `on_add_element` and `on_remove_element` events for node setup. All components must be of the same class in this case. +- **[Rich Text]** Now applied directly to the text node instead of using a Rich Text Template (which previously contained three nodes: root, text, and image prefabs). This simplifies usage in the GUI. +- **[Rich Input]** Updated with new features such as selection and cursor navigation. New input keys can be configured in Druid (arrows, ctrl, shift). +- **[Input]** Users can now switch between text input areas with a single click, instead of needing to tap twice (once to close the focus and once to open the new input). +- **[Layout]** Reworked the Layout component. The new version allows arranging nodes in various modes (vertical, horizontal, horizontal wrap) and includes more settings (margins, padding, justification, pivots, and content hugging options). This will replace Dynamic Grid in the future. +- **[Dynamic Grid]** Deprecated in favor of the new Layout component. +- **[Drag]** Added a touch parameter to Drag callbacks, making it easier to add custom logic with input action data. +- **[Scroll]** Added `scroll.view_size`, `scroll:set_view_size(size)`, and `scroll:update_view_size()` functions for better management of the scroll input area and visible part. +- **[Static Grid]** Added `grid:set_item_size(size)` and `grid:sort_nodes(comparator)` functions. +- **[Text]** Adjustments for multiline text height seem to be working correctly now. +- **[Progress Bar]** Improved accuracy when scaling progress bars for images with slice9 parameters. +- **[Slider]** Fixed several slider setup issues. +- **[System]** Updated and fixed annotations. +- **[System]** Removed `middleclass.lua`. +- **[System]** Removed: `checkbox`, `checkbox_group`, and `radio_button` components. These components can be easily created using the Button component. Check the examples for implementation. +- **[System]** Removed: `pin_knob` custom component. It mostly was created as an example and now is not needed. +- **[System]** Added `self:get_druid(template, nodes)` to replace `self:set_template(template)` and `self:set_nodes(nodes)` calls in custom components. +- Various improvements and fixes. + + +A big thanks to the my Github supporters: +- [Defold Foundation](https://defold.com) +- [Ragetto](https://forum.defold.com/u/ragetto) +- [Pawel](https://forum.defold.com/u/pawel/summary) + +And all my other supporters! Very appreciated! + +❤️ Support ❤️ + +Please support me if you like this project! It will help me keep engaged to update **Druid** and make it even better! + +[![Github-sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/insality) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/insality) [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/insality) + + +--- + +**Postmortem** + +Thoughts, wrong decisions, future plans, and how to update correctly: + +- No styles should exist. +- Annotations should be updated or removed. +- Non-explicit event parameters can cause confusion, particularly with `self` parameters. +- There is room for performance optimization. Memory usage is not optimized, though it can still handle heavy-load GUIs like Panthera. +- Creating custom components could be made easier. +- There can be a much less code bindings between elements. Like bind_grid, update_size after some changes etc. \ No newline at end of file