From 3bb8705444ec15db722a568c68f47c5ed88255de Mon Sep 17 00:00:00 2001 From: Insality Date: Thu, 6 Mar 2025 01:50:31 +0200 Subject: [PATCH] Update --- .../components/base/back_handler_manual.md | 47 +++++ docs_md/components/base/blocker_manual.md | 50 +++++ docs_md/components/base/button_manual.md | 89 ++++++++ docs_md/components/base/drag_manual.md | 79 +++++++ docs_md/components/base/hover_manual.md | 84 ++++++++ docs_md/components/base/scroll_manual.md | 106 ++++++++++ docs_md/components/base/static_grid_manual.md | 119 +++++++++++ docs_md/components/base/text_manual.md | 141 +++++++++++++ .../components/custom/rich_input_manual.md | 197 ++++++++++++++++++ docs_md/components/custom/rich_text_manual.md | 129 ++++++++++++ .../components/extended/container_manual.md | 165 +++++++++++++++ .../components/extended/data_list_manual.md | 148 +++++++++++++ docs_md/components/extended/hotkey_manual.md | 132 ++++++++++++ docs_md/components/extended/input_manual.md | 185 ++++++++++++++++ .../components/extended/lang_text_manual.md | 127 +++++++++++ docs_md/components/extended/layout_manual.md | 98 +++++++++ .../components/extended/progress_manual.md | 111 ++++++++++ docs_md/components/extended/slider_manual.md | 114 ++++++++++ docs_md/components/extended/swipe_manual.md | 136 ++++++++++++ docs_md/components/extended/timer_manual.md | 125 +++++++++++ 20 files changed, 2382 insertions(+) diff --git a/docs_md/components/base/back_handler_manual.md b/docs_md/components/base/back_handler_manual.md index e69de29..9d2f264 100644 --- a/docs_md/components/base/back_handler_manual.md +++ b/docs_md/components/base/back_handler_manual.md @@ -0,0 +1,47 @@ +# Druid Back Handler Component + +## Description + +The Back Handler component is designed to handle back button actions, including the Android back button and the Backspace key. It provides a simple way to implement back navigation or other actions when the user presses the back button. + +## Features + +- Handles Android back button and Backspace key presses +- Customizable callback function +- Optional parameters to pass to the callback +- Event-based architecture + +## Basic Usage + +```lua +local callback = function(self, params) + -- Handle back action here + print("Back button pressed!") +end + +local params = { custom_data = "value" } +local back_handler = self.druid:new_back_handler(callback, params) +``` + +### Parameters + +- **callback**: (optional) Function to call when back button is pressed +- **params**: (optional) Custom data to pass to the callback + +## Events + +The Back Handler component provides an event you can subscribe to: + +```lua +-- Subscribe to back event +back_handler.on_back:subscribe(function(self, params) + print("Back button was pressed!") +end) +``` + +## Notes + +- The Back Handler component requires proper key triggers setup in your `input.binding` file for correct operation +- Back Handler is recommended to be placed in every game window to handle closing or in the main screen to call settings windows +- Multiple Back Handlers can be active at the same time, but only the first one that processes the input will trigger its callback +- Back Handler reacts on release action of ACTION_BACK or ACTION_BACKSPACE diff --git a/docs_md/components/base/blocker_manual.md b/docs_md/components/base/blocker_manual.md index e69de29..1d4dbe0 100644 --- a/docs_md/components/base/blocker_manual.md +++ b/docs_md/components/base/blocker_manual.md @@ -0,0 +1,50 @@ +# Druid Blocker Component + +## Description + +The Blocker component is designed to consume input in a specific zone defined by a GUI node. It's useful for creating unclickable zones within buttons or for creating panels of buttons on top of another button. + +## Features + +- Blocks input in a specific zone +- Can be enabled or disabled programmatically +- Useful for creating safe zones in UI + +## Basic Usage + +```lua +local blocker = self.druid:new_blocker("blocker_node") +``` + +### Parameters + +- **node**: The node or node_id of the blocker node + +## Methods + +```lua +-- Enable or disable the blocker +blocker:set_enabled(true) -- Enable +blocker:set_enabled(false) -- Disable + +-- Check if blocker is enabled +local is_enabled = blocker:is_enabled() +``` + +## Notes + +- The Blocker component consumes input if `gui.pick_node` works on it +- The Blocker node should be enabled to capture input +- The initial enabled state is determined by `gui.is_enabled(node, true)` +- Blocker is useful for creating "safe zones" in your UI, where you have large buttons with specific clickable areas +- A common use case is to place a blocker with window content behind a close button, so clicking outside the close button (but still on the window) doesn't trigger actions from elements behind the window + +### Example Use Case + +![Blocker Scheme](../../../media/blocker_scheme.png) + +In this example: +- Blue zone is a **button** with close_window callback +- Yellow zone is a blocker with window content + +This setup creates a safe zone where the user can interact with the window content without accidentally triggering actions from elements behind the window. diff --git a/docs_md/components/base/button_manual.md b/docs_md/components/base/button_manual.md index e69de29..5fc243a 100644 --- a/docs_md/components/base/button_manual.md +++ b/docs_md/components/base/button_manual.md @@ -0,0 +1,89 @@ +# Druid Button Component + +## Description + +Button component is a basic component that can be used to create a clickable button. It provides various interaction callbacks such as click, long click, double click, and more. The component makes any GUI node clickable and allows you to define different behaviors for various user interactions. + +## Features + +- Regular click handling +- Long click detection +- Double click detection +- Repeated click handling (while holding) +- Hold state callbacks +- Click outside detection +- Keyboard key triggering +- Custom animation node support +- Enabled/disabled states +- Customizable click zones +- HTML5 interaction support + +## Basic Usage + +```lua +local button = self.druid:new_button(node, [callback], [params], [anim_node]) +``` + +### Parameters + +- **node**: The node or node_id to make clickable +- **callback**: (optional) Function to call when button is clicked +- **params**: (optional) Custom arguments to pass to the callback +- **anim_node**: (optional) Node to animate instead of the trigger node + +### Example + +```lua +-- Simple button with callback +local button = self.druid:new_button("button_node", function(self, params, button_instance) + print("Button clicked!") +end) + +-- Button with custom parameters +local custom_args = "Any data to pass to callback" +local button = self.druid:new_button("button_node", on_button_click, custom_args) + +-- Button with separate animation node +local button = self.druid:new_button("big_panel", callback, nil, "small_icon") +``` + +## HTML5 Interaction + +The Button component supports HTML5 interaction mode, which allows you to define different behaviors for various user interactions. Use this mode when you need to use special interactions like copy/paste, keyboard, etc. + +```lua +button:set_web_user_interaction(true) +``` + +## Events + +The Button component provides several events you can subscribe to: + +- **on_click**: Triggered when button is clicked +- **on_pressed**: Triggered when button is pressed down +- **on_repeated_click**: Triggered repeatedly while holding the button +- **on_long_click**: Triggered when button is held for a certain time +- **on_double_click**: Triggered when button is clicked twice in quick succession +- **on_hold_callback**: Triggered while holding the button, before long_click +- **on_click_outside**: Triggered when click is released outside the button + +### Example + +```lua +-- Subscribe to double click event +button.on_double_click:subscribe(function(self, params, button_instance, click_amount) + print("Double clicked! Click amount: " .. click_amount) +end) + +-- Subscribe to long click event +button.on_long_click:subscribe(function(self, params, button_instance, hold_time) + print("Long press detected! Hold time: " .. hold_time) +end) +``` + +## Notes + +- The click callback will not trigger if the cursor moves outside the node's area between pressed and released states +- If a button has a double click event and it is triggered, the regular click callback will not be invoked +- If you have a stencil on buttons and don't want to trigger them outside the stencil node, use `button:set_click_zone` +- Animation node can be used to animate a small icon on a big panel (trigger zone is the big panel, animation node is the small icon) diff --git a/docs_md/components/base/drag_manual.md b/docs_md/components/base/drag_manual.md index e69de29..3d7661c 100644 --- a/docs_md/components/base/drag_manual.md +++ b/docs_md/components/base/drag_manual.md @@ -0,0 +1,79 @@ +# Druid Drag Component + +## Description + +The Drag component handles drag actions on a node, allowing users to move UI elements by dragging them. It provides proper handling for multitouch and swap touches while dragging. + +## Features + +- Handles drag actions on nodes +- Supports multitouch and touch swapping +- Provides drag start, drag, and drag end events +- Customizable drag deadzone +- Optional click zone restriction + +## Basic Usage + +```lua +local drag = self.druid:new_drag("drag_node", function(self, dx, dy, x, y, touch) + -- Handle drag action + local position = gui.get_position(drag.node) + gui.set_position(drag.node, vmath.vector3(position.x + dx, position.y + dy, position.z)) +end) +``` + +### Parameters + +- **node**: The node or node_id of the draggable node +- **on_drag_callback**: (optional) Function to call during drag with parameters (self, dx, dy, total_x, total_y, touch) + +## Events + +The Drag component provides several events you can subscribe to: + +```lua +-- Subscribe to drag start event +drag.on_drag_start:subscribe(function(self, touch) + print("Drag started") +end) + +-- Subscribe to drag end event +drag.on_drag_end:subscribe(function(self, x, y, touch) + print("Drag ended, total movement: " .. x .. ", " .. y) +end) + +-- Subscribe to touch start/end events +drag.on_touch_start:subscribe(function(self, touch) + print("Touch started") +end) + +drag.on_touch_end:subscribe(function(self, touch) + print("Touch ended") +end) +``` + +## Methods + +```lua +-- Set a click zone to restrict drag area +drag:set_click_zone("stencil_node") + +-- Enable or disable drag +drag:set_enabled(true) -- Enable +drag:set_enabled(false) -- Disable + +-- Check if drag is enabled +local is_enabled = drag:is_enabled() + +-- Set drag cursor appearance (requires defos) +drag:set_drag_cursors(true) -- Enable custom cursors +drag:set_drag_cursors(false) -- Disable custom cursors +``` + +## Notes + +- Drag will be processed even if the cursor is outside of the node, as long as the drag has already started +- The component has a configurable deadzone (default: 10 pixels) before drag is triggered +- You can restrict the drag area by setting a click zone, which is useful for stencil nodes +- The drag component automatically detects the closest stencil node and sets it as the click zone if none is specified +- The drag component can be configured to use screen aspect ratio for drag values diff --git a/docs_md/components/base/hover_manual.md b/docs_md/components/base/hover_manual.md index e69de29..d6dba94 100644 --- a/docs_md/components/base/hover_manual.md +++ b/docs_md/components/base/hover_manual.md @@ -0,0 +1,84 @@ +# Druid Hover Component + +## Description + +The Hover component handles hover interactions with nodes, providing callbacks for both touch hover and mouse hover states. It's useful for creating interactive UI elements that respond to user hover actions. + +## Features + +- Handles touch hover (with pressed action) +- Handles mouse hover (without pressing) +- Provides hover state tracking +- Customizable cursor styles (with defos) +- Optional click zone restriction + +## Basic Usage + +```lua +-- Basic hover with touch hover callback +local hover = self.druid:new_hover("node", function(self, is_hover) + -- Handle hover state change + local color = is_hover and vmath.vector4(1, 0.8, 0.8, 1) or vmath.vector4(1, 1, 1, 1) + gui.animate(hover.node, "color", color, gui.EASING_LINEAR, 0.2) +end) + +-- Hover with both touch and mouse hover callbacks +local hover = self.druid:new_hover("node", + function(self, is_hover) + -- Handle touch hover + end, + function(self, is_hover) + -- Handle mouse hover + end +) +``` + +### Parameters + +- **node**: The node or node_id of the hover node +- **on_hover_callback**: (optional) Function to call on touch hover state change +- **on_mouse_hover_callback**: (optional) Function to call on mouse hover state change + +## Events + +The Hover component provides two events you can subscribe to: + +```lua +-- Subscribe to touch hover event +hover.on_hover:subscribe(function(self, is_hover) + print("Touch hover state: " .. tostring(is_hover)) +end) + +-- Subscribe to mouse hover event +hover.on_mouse_hover:subscribe(function(self, is_hover) + print("Mouse hover state: " .. tostring(is_hover)) +end) +``` + +## Methods + +```lua +-- Set hover state manually +hover:set_hover(true) +hover:set_hover(false) + +-- Set mouse hover state manually +hover:set_mouse_hover(true) +hover:set_mouse_hover(false) + +-- Check current hover states +local is_hovered = hover:is_hovered() +local is_mouse_hovered = hover:is_mouse_hovered() + +-- Set a click zone to restrict hover area +hover:set_click_zone("stencil_node") +``` + +## Notes + +- By default, hover handles the "hover event" with pressed touch action_id, meaning the mouse or touch has to be pressed +- On desktop platforms, there is an "on_mouse_hover" event that triggers on mouse hover without any action id +- By default, the component assumes the node is in a non-hovered state (both hover and mouse_hover) +- The hover component automatically detects the closest stencil node and sets it as the click zone if none is specified +- You can customize cursor styles for hover states if you're using the defos extension +- Hover state is automatically reset when input is interrupted or the node is disabled diff --git a/docs_md/components/base/scroll_manual.md b/docs_md/components/base/scroll_manual.md index e69de29..252920e 100644 --- a/docs_md/components/base/scroll_manual.md +++ b/docs_md/components/base/scroll_manual.md @@ -0,0 +1,106 @@ +# Druid Scroll Component + +## Description + +The Scroll component handles scrollable content in your UI. It consists of two main parts: a static view node that captures user input, and a dynamic content node that moves in response to user interaction. + +## Features + +- Horizontal and vertical scrolling +- Inertial scrolling with customizable friction +- Points of interest for snap-to-position scrolling +- Scroll-to-position and scroll-to-percent functions +- Mouse wheel support +- Stretch effect for overscrolling +- Grid binding for automatic content size adjustment + +## Basic Usage + +```lua +local scroll = self.druid:new_scroll("view_node", "content_node") +``` + +### Parameters + +- **view_node**: The node or node_id of the static view part (captures input) +- **content_node**: The node or node_id of the dynamic content part (moves when scrolling) + +## Setup + +The typical setup involves placing a view_node and adding a content_node as its child: + +![Scroll Scheme](../../../media/scroll_scheme.png) + +The view_node captures user input and defines the visible area, while the content_node contains all the scrollable content and moves in response to user interaction. + +## Methods + +```lua +-- Scroll to a specific position +scroll:scroll_to(vmath.vector3(100, 200, 0), false) -- Animated scroll +scroll:scroll_to(vmath.vector3(100, 200, 0), true) -- Instant scroll + +-- Scroll to a percentage of the content +scroll:scroll_to_percent(vmath.vector3(0.5, 0.5, 0), false) -- Scroll to middle + +-- Get current scroll percentage +local percent = scroll:get_percent() + +-- Set content size +scroll:set_size(vmath.vector3(500, 1000, 0)) + +-- Update view size if it changes +scroll:update_view_size() + +-- Enable/disable inertial scrolling +scroll:set_inert(true) +scroll:set_inert(false) + +-- Set points of interest for snap-to-position scrolling +scroll:set_points({ + vmath.vector3(0, 0, 0), + vmath.vector3(0, 200, 0), + vmath.vector3(0, 400, 0) +}) + +-- Scroll to a specific point of interest +scroll:scroll_to_index(2) + +-- Enable/disable horizontal or vertical scrolling +scroll:set_horizontal_scroll(true) +scroll:set_vertical_scroll(true) + +-- Check if a node is visible in the scroll view +local is_visible = scroll:is_node_in_view(node) + +-- Bind a grid to automatically adjust scroll size +scroll:bind_grid(grid) +``` + +## Events + +```lua +-- Subscribe to scroll movement +scroll.on_scroll:subscribe(function(self, position) + print("Scroll position: " .. position.x .. ", " .. position.y) +end) + +-- Subscribe to scroll_to events +scroll.on_scroll_to:subscribe(function(self, target, is_instant) + print("Scrolling to: " .. target.x .. ", " .. target.y) +end) + +-- Subscribe to point scroll events +scroll.on_point_scroll:subscribe(function(self, index, point) + print("Scrolled to point: " .. index) +end) +``` + +## Notes + +- The scroll component has customizable style parameters for friction, inertia, and stretch effects +- By default, scroll has inertia and a stretching effect, which can be adjusted via style settings +- You can set up "points of interest" to make the scroll always center on the closest point +- When using a stencil node with the scroll, buttons inside the scroll may be clickable outside the stencil bounds. Use `button:set_click_zone(scroll.view_node)` to restrict button clicks to the visible area +- The scroll component automatically detects the closest stencil node and sets it as the click zone if none is specified +- Mouse wheel scrolling is supported and can be customized or disabled via style settings diff --git a/docs_md/components/base/static_grid_manual.md b/docs_md/components/base/static_grid_manual.md index e69de29..e157944 100644 --- a/docs_md/components/base/static_grid_manual.md +++ b/docs_md/components/base/static_grid_manual.md @@ -0,0 +1,119 @@ +# Druid Static Grid Component + +## Description + +The Static Grid component handles the positioning of UI elements in a grid layout with rows and columns. It provides a way to organize nodes in a structured grid with consistent spacing. + +## Features + +- Automatic positioning of nodes in rows and columns +- Customizable number of elements per row +- Dynamic addition and removal of nodes +- Node sorting capabilities +- Events for grid changes +- Automatic size calculation + +## Basic Usage + +```lua +local grid = self.druid:new_grid("parent_node", "item_prefab", 3) + +-- Add nodes to the grid +local node1 = gui.clone(prefab) +local node2 = gui.clone(prefab) +grid:add(node1) +grid:add(node2) +``` + +### Parameters + +- **parent_node**: The node or node_id of the parent container where grid items will be placed +- **item_prefab**: The node or node_id of the item prefab (used to determine item size) +- **in_row**: (optional) Number of items per row (default: 1) + +## Methods + +```lua +-- Add a node to the grid +local node = gui.clone(prefab) +grid:add(node) + +-- Add multiple nodes +grid:add_many({node1, node2, node3}) + +-- Remove a node from the grid +grid:remove(node) + +-- Clear all nodes from the grid +grid:clear() + +-- Get node position by index +local position = grid:get_pos(5) + +-- Get grid size for a specific number of elements +local size = grid:get_size_for(10) + +-- Get current grid borders +local borders = grid:get_borders() + +-- Get all node positions +local positions = grid:get_all_pos() + +-- Set custom position function +grid:set_position_function(function(node, pos) + -- Custom positioning logic + gui.set_position(node, pos) +end) + +-- Change items per row +grid:set_in_row(4) + +-- Set item size +grid:set_item_size(100, 50) + +-- Sort grid nodes +grid:sort_nodes(function(a, b) + -- Custom sorting logic + return gui.get_id(a) < gui.get_id(b) +end) +``` + +## Events + +```lua +-- Subscribe to node addition +grid.on_add_item:subscribe(function(self, node) + print("Node added to grid") +end) + +-- Subscribe to node removal +grid.on_remove_item:subscribe(function(self, node) + print("Node removed from grid") +end) + +-- Subscribe to grid changes +grid.on_change_items:subscribe(function(self) + print("Grid items changed") +end) + +-- Subscribe to grid clear +grid.on_clear:subscribe(function(self) + print("Grid cleared") +end) + +-- Subscribe to position updates +grid.on_update_positions:subscribe(function(self) + print("Grid positions updated") +end) +``` + +## Notes + +- The grid component calculates positions based on the size of the item prefab +- The grid's pivot point affects how items are positioned within the grid +- You can customize the grid's behavior with style settings: + - `IS_DYNAMIC_NODE_POSES`: If true, always centers grid content based on the grid's pivot + - `IS_ALIGN_LAST_ROW`: If true, always aligns the last row of the grid based on the grid's pivot +- The grid component does not automatically delete GUI nodes when cleared or when nodes are removed +- The grid can be used with the Scroll component to create scrollable lists +- When used with DataList, the grid can efficiently handle large collections of data diff --git a/docs_md/components/base/text_manual.md b/docs_md/components/base/text_manual.md index e69de29..7708eb4 100644 --- a/docs_md/components/base/text_manual.md +++ b/docs_md/components/base/text_manual.md @@ -0,0 +1,141 @@ +# Druid Text Component + +## Description + +Text component is a basic component that provides various adjustment modes for text nodes. It allows text to be scaled down to fit within the size of the text node, trimmed, scrolled, or a combination of these adjustments. The component makes it easy to handle text display in different scenarios. + +## Features + +- Automatic text size adjustment +- Multiple text adjustment modes (downscale, trim, scroll, etc.) +- Text pivot control +- Text color and alpha management +- Text size and scale control +- Text metrics calculation +- Event-based architecture for text changes + +## Basic Usage + +```lua +local text = self.druid:new_text(node, [initial_value], [adjust_type]) +``` + +### Parameters + +- **node**: The node or node_id of the text node +- **initial_value**: (optional) Initial text value. Default is the text from the GUI node +- **adjust_type**: (optional) Adjustment type for text. Default is "DOWNSCALE". See adjustment types below + +### Example + +```lua +-- Simple text component +local text = self.druid:new_text("text_node") + +-- Text with initial value +local text = self.druid:new_text("text_node", "Hello, World!") + +-- Text with specific adjustment type +local text = self.druid:new_text("text_node", "Hello, World!", const.TEXT_ADJUST.TRIM) +``` + +## Text Adjustment Types + +The Text component supports several adjustment types to handle different text display scenarios: + +- **DOWNSCALE**: Scales down the text to fit within the text node's size +- **NO_ADJUST**: No adjustment, text displays as is +- **TRIM**: Trims the text with an ellipsis (...) if it doesn't fit +- **TRIM_LEFT**: Trims the text from the left with an ellipsis if it doesn't fit +- **DOWNSCALE_LIMITED**: Scales down the text but not below a minimum scale +- **SCROLL**: Shifts the text anchor when it doesn't fit +- **SCALE_THEN_SCROLL**: First scales down the text, then scrolls if needed +- **SCALE_THEN_TRIM**: First scales down the text, then trims if needed +- **SCALE_THEN_TRIM_LEFT**: First scales down the text, then trims from the left if needed + +### Example + +```lua +-- Import constants +local const = require("druid.const") + +-- Create text with TRIM adjustment +local text = self.druid:new_text("text_node", "Long text that might not fit", const.TEXT_ADJUST.TRIM) + +-- Change adjustment type later +text:set_text_adjust(const.TEXT_ADJUST.SCALE_THEN_TRIM) +``` + +## Events + +The Text component provides several events you can subscribe to: + +- **on_set_text**: Triggered when text is set or changed +- **on_update_text_scale**: Triggered when text scale is updated +- **on_set_pivot**: Triggered when text pivot is changed + +### Example + +```lua +-- Subscribe to text change event +text.on_set_text:subscribe(function(self, text_value) + print("Text changed to: " .. text_value) +end) + +-- Subscribe to scale update event +text.on_update_text_scale:subscribe(function(self, scale, metrics) + print("Text scale updated to: " .. scale.x) +end) +``` + +## Methods + +```lua +-- Set text content +text:set_text("New text content") + +-- Get current text content +local current_text = text:get_text() + +-- Set text area size +text:set_size(vmath.vector3(200, 100, 0)) + +-- Set text color +text:set_color(vmath.vector4(1, 0, 0, 1)) -- Red color + +-- Set text alpha +text:set_alpha(0.5) -- 50% opacity + +-- Set text scale +text:set_scale(vmath.vector3(1.5, 1.5, 1)) -- 150% scale + +-- Set text pivot +text:set_pivot(gui.PIVOT_CENTER) + +-- Check if text is multiline +local is_multiline = text:is_multiline() + +-- Set text adjustment type +text:set_text_adjust(const.TEXT_ADJUST.TRIM) + +-- Set minimal scale for limited adjustment types +text:set_minimal_scale(0.5) -- 50% minimum scale + +-- Get current text adjustment type +local adjust_type = text:get_text_adjust() + +-- Get text size (width and height) +local width, height = text:get_text_size() + +-- Get text index by width (useful for cursor positioning) +local char_index = text:get_text_index_by_width(100) +``` + +## Notes + +- Text component by default has auto-adjust text sizing. Text will never be bigger than the text node size, which you can set up in the GUI scene. +- Auto-adjustment can be disabled by setting the adjustment type to `NO_ADJUST`. +- Text pivot can be changed with `text:set_pivot()`, and the text will maintain its position inside the text size box. +- For multiline text, the component will try to fit the text within both width and height constraints. +- The trim postfix (default: "...") can be customized in the style settings. +- When using `DOWNSCALE_LIMITED` or `SCALE_THEN_SCROLL`, you can set a minimal scale to prevent text from becoming too small. diff --git a/docs_md/components/custom/rich_input_manual.md b/docs_md/components/custom/rich_input_manual.md index e69de29..f2ebfe8 100644 --- a/docs_md/components/custom/rich_input_manual.md +++ b/docs_md/components/custom/rich_input_manual.md @@ -0,0 +1,197 @@ +# Druid Rich Input Component + +## Description + +The Rich Input component provides an enhanced text input field with advanced features like text selection, cursor positioning, and placeholder text. It extends the basic Input component to offer a more sophisticated text entry experience. + +## Features + +- Text input with cursor support +- Text selection capabilities +- Customizable placeholder text +- Maximum length restriction +- Input validation and filtering +- Events for text changes and interactions +- Support for multiline input +- Customizable visual feedback + +## Basic Usage + +```lua +-- Create a basic rich input +local rich_input = self.druid:new_rich_input("input_node", "input_text_node") + +-- Set initial text +rich_input:set_text("Initial text") + +-- Set placeholder text +rich_input:set_placeholder("Enter text here...") +``` + +### Parameters + +- **node**: The node or node_id of the input background +- **text_node**: The node or node_id of the text component +- **keyboard_type**: (optional) The type of keyboard to show on mobile devices + +## Methods + +```lua +-- Set input text +rich_input:set_text("New text") + +-- Get current text +local text = rich_input:get_text() + +-- Clear input +rich_input:clear() + +-- Set maximum text length +rich_input:set_max_length(50) + +-- Set input validation pattern +rich_input:set_allowed_characters("[%w%s]") -- Only alphanumeric and spaces + +-- Set placeholder text +rich_input:set_placeholder("Enter text here...") + +-- Set placeholder color +rich_input:set_placeholder_color(vmath.vector4(0.5, 0.5, 0.5, 1)) + +-- Enable/disable multiline input +rich_input:set_multiline(true) +rich_input:set_multiline(false) + +-- Enable/disable the input +rich_input:set_enabled(true) +rich_input:set_enabled(false) + +-- Check if input is enabled +local is_enabled = rich_input:is_enabled() + +-- Set input focus +rich_input:set_focus() + +-- Remove input focus +rich_input:remove_focus() + +-- Check if input has focus +local has_focus = rich_input:is_focused() + +-- Select all text +rich_input:select_all() + +-- Set cursor position +rich_input:set_cursor_position(5) + +-- Set selection range +rich_input:set_selection(2, 5) -- Select characters from index 2 to 5 + +-- Get current selection +local selection_start, selection_end = rich_input:get_selection() +``` + +## Events + +```lua +-- Subscribe to text change event +rich_input.on_input_text:subscribe(function(self, text) + print("Text changed to: " .. text) +end) + +-- Subscribe to focus events +rich_input.on_focus:subscribe(function(self) + print("Input gained focus") +end) + +rich_input.on_focus_lost:subscribe(function(self) + print("Input lost focus") +end) + +-- Subscribe to input submit event (Enter key) +rich_input.on_submit:subscribe(function(self) + print("Input submitted with text: " .. self:get_text()) +end) + +-- Subscribe to input canceled event (Escape key) +rich_input.on_cancel:subscribe(function(self) + print("Input canceled") +end) + +-- Subscribe to selection change event +rich_input.on_selection_change:subscribe(function(self, start, end_pos) + print("Selection changed: " .. start .. " to " .. end_pos) +end) + +-- Subscribe to cursor position change event +rich_input.on_cursor_change:subscribe(function(self, position) + print("Cursor position: " .. position) +end) +``` + +## Examples + +```lua +-- Create a username input with validation +local username_input = self.druid:new_rich_input("username_bg", "username_text") +username_input:set_placeholder("Username") +username_input:set_allowed_characters("[%w_]") -- Only alphanumeric and underscore +username_input:set_max_length(20) + +-- Create a password input +local password_input = self.druid:new_rich_input("password_bg", "password_text") +password_input:set_placeholder("Password") +password_input:set_password(true) +password_input:set_password_char("•") + +-- Create a multiline text area +local text_area = self.druid:new_rich_input("textarea_bg", "textarea_text") +text_area:set_multiline(true) +text_area:set_placeholder("Enter your message here...") + +-- Create a search input with clear button +local search_input = self.druid:new_rich_input("search_bg", "search_text") +search_input:set_placeholder("Search...") + +local clear_button = self.druid:new_button("clear_button", function() + search_input:clear() + search_input:set_focus() +end) + +-- Create an input with selection handling +local editor_input = self.druid:new_rich_input("editor_bg", "editor_text") +editor_input.on_selection_change:subscribe(function(self, start, end_pos) + if start ~= end_pos then + -- Text is selected + show_formatting_toolbar() + else + -- No selection + hide_formatting_toolbar() + end +end) + +-- Format selected text +function format_bold() + local start, end_pos = editor_input:get_selection() + if start ~= end_pos then + local text = editor_input:get_text() + local selected_text = text:sub(start, end_pos) + local new_text = text:sub(1, start-1) .. "**" .. selected_text .. "**" .. text:sub(end_pos+1) + editor_input:set_text(new_text) + editor_input:set_selection(start, end_pos + 4) -- Adjust selection to include formatting + end +end +``` + +## Notes + +- The Rich Input component extends the basic Input component with enhanced selection and cursor capabilities +- The placeholder text is shown when the input is empty and doesn't have focus +- Text selection can be done via mouse/touch drag or programmatically +- The component handles cursor positioning and blinking +- Input validation can be used to restrict what characters users can enter +- For multiline input, the component supports line breaks and scrolling +- The component provides events for all major input interactions, allowing you to create responsive forms +- Selection and cursor position are reported in character indices, not pixel positions +- The component handles clipboard operations (copy, cut, paste) on supported platforms +- For best user experience, consider providing visual feedback for selection and cursor position diff --git a/docs_md/components/custom/rich_text_manual.md b/docs_md/components/custom/rich_text_manual.md index e69de29..15bd458 100644 --- a/docs_md/components/custom/rich_text_manual.md +++ b/docs_md/components/custom/rich_text_manual.md @@ -0,0 +1,129 @@ +# Druid Rich Text Component + +## Description + +The Rich Text component extends the basic Text component to provide advanced text formatting capabilities. It allows you to display text with different styles, colors, and formatting within the same text node, using HTML-like markup tags. + +## Features + +- Inline text styling and formatting +- Support for different colors within text +- Font size variations within text +- Shadow and outline text effects +- Image insertion within text +- Line break control +- Custom tag support for advanced formatting + +## Basic Usage + +```lua +-- Create a basic rich text component +local rich_text = self.druid:new_rich_text("text_node") + +-- Set text with formatting +rich_text:set_text("Hello World!") +``` + +### Parameters + +- **node**: The node or node_id of the text node + +## Rich Text Markup + +The component uses HTML-like tags for formatting: + +```l +Colored text +Colored text +Text with shadow +Text with outline +Text with custom font +Sized text +
Line break +No line break zone + +``` + +## Methods + +```lua +-- Set rich text content +rich_text:set_text("Hello World!") + +-- Get current text (with markup) +local text = rich_text:get_text() + +-- Get text without markup +local plain_text = rich_text:get_plain_text() + +-- Set default text color +rich_text:set_default_color(vmath.vector4(1, 1, 1, 1)) + +-- Register a custom tag handler +rich_text:register_tag("shake", function(params, settings, style) + -- Custom tag implementation + -- Modify settings table based on params +end) + +-- Clear all text +rich_text:clear() +``` + +## Events + +```lua +-- Subscribe to text change event +rich_text.on_text_change:subscribe(function(self, text) + print("Rich text changed to: " .. text) +end) +``` + +## Examples + +```lua +-- Create a rich text with multiple formatting styles +local rich_text = self.druid:new_rich_text("text_node") +rich_text:set_text("Welcome to Druid! This is a rich text component.") + +-- Create text with custom font and size +local title_text = self.druid:new_rich_text("title_node") +title_text:set_text("GAME TITLE") + +-- Create text with shadow and outline effects +local effect_text = self.druid:new_rich_text("effect_node") +effect_text:set_text("Stylized Text") + +-- Create text with embedded images +local info_text = self.druid:new_rich_text("info_text") +info_text:set_text("Your character: Level 5
HP: 75/100
MP: 30/50") + +-- Create text with custom tag +local custom_text = self.druid:new_rich_text("custom_text") +custom_text:register_tag("pulse", function(params, settings, style) + -- Implementation of pulsing effect + settings.pulse = true + settings.pulse_speed = tonumber(params) or 1 +end) +custom_text:set_text("This is a pulsing text!") +``` + +## Color Names + +The component supports predefined color names that can be used instead of hex values: + +```lua +-- Example of using named colors +rich_text:set_text("Aqua Red Lime") +``` + +## Notes + +- The Rich Text component is based on Britzl's defold-richtext library (version 5.19.0) with modifications +- The markup tags are processed at render time and converted to appropriate visual representations +- For complex formatting needs, you can register custom tags with specialized rendering logic +- When using images within text, you can specify width and height parameters +- The component supports nested tags for combined formatting effects +- For performance reasons, avoid extremely complex formatting in text that changes frequently +- The component handles tag escaping, so you can display tag-like syntax by escaping the brackets +- Rich text parsing may have a small performance impact compared to regular text rendering +- You can define custom colors in the style settings to use them by name in your markup diff --git a/docs_md/components/extended/container_manual.md b/docs_md/components/extended/container_manual.md index e69de29..355a43d 100644 --- a/docs_md/components/extended/container_manual.md +++ b/docs_md/components/extended/container_manual.md @@ -0,0 +1,165 @@ +# Druid Container Component + +## Description + +The Container component provides a way to group and manage multiple UI elements as a single entity. It allows you to show, hide, enable, or disable a collection of nodes together, and provides events for container state changes. + +## Features + +- Group multiple nodes under a single container +- Show/hide all container nodes together +- Enable/disable all container nodes together +- Animation support for transitions +- Events for container state changes +- Optional animation callbacks + +## Basic Usage + +```lua +-- Create a container with a single node +local container = self.druid:new_container("container_node") + +-- Create a container with multiple nodes +local container = self.druid:new_container({"node1", "node2", "node3"}) +``` + +### Parameters + +- **nodes**: A node, node_id, or array of nodes/node_ids to include in the container + +## Methods + +```lua +-- Add nodes to the container +container:add("new_node") +container:add({"node4", "node5"}) + +-- Remove nodes from the container +container:remove("node1") +container:remove({"node2", "node3"}) + +-- Show the container (all nodes) +container:show() + +-- Hide the container (all nodes) +container:hide() + +-- Show with animation +container:show(function(self) + -- Animation complete callback + print("Container shown") +end) + +-- Hide with animation +container:hide(function(self) + -- Animation complete callback + print("Container hidden") +end) + +-- Enable the container (all nodes) +container:set_enabled(true) + +-- Disable the container (all nodes) +container:set_enabled(false) + +-- Check if container is visible +local is_visible = container:is_visible() + +-- Check if container is enabled +local is_enabled = container:is_enabled() +``` + +## Events + +```lua +-- Subscribe to visibility change event +container.on_visibility_changed:subscribe(function(self, is_visible) + print("Container visibility changed to: " .. tostring(is_visible)) +end) + +-- Subscribe to enabled state change event +container.on_enabled_changed:subscribe(function(self, is_enabled) + print("Container enabled state changed to: " .. tostring(is_enabled)) +end) +``` + +## Animation + +The container component supports custom animations for show and hide operations: + +```lua +-- Set custom show animation +container:set_show_animation(function(self, callback) + -- Animate container nodes + for _, node in ipairs(self.nodes) do + gui.animate(node, "color.w", 1, gui.EASING_OUTSINE, 0.5, 0, callback) + end +end) + +-- Set custom hide animation +container:set_hide_animation(function(self, callback) + -- Animate container nodes + for _, node in ipairs(self.nodes) do + gui.animate(node, "color.w", 0, gui.EASING_OUTSINE, 0.5, 0, callback) + end +end) +``` + +## Examples + +```lua +-- Create a panel container with multiple elements +local panel = self.druid:new_container({ + "panel_bg", + "panel_title", + "panel_content", + "close_button" +}) + +-- Set custom show animation +panel:set_show_animation(function(self, callback) + local bg = gui.get_node("panel_bg") + local content = gui.get_node("panel_content") + + -- Animate background + gui.set_scale(bg, vmath.vector3(0.8, 0.8, 1)) + gui.animate(bg, "scale", vmath.vector3(1, 1, 1), gui.EASING_OUTBACK, 0.4) + + -- Animate content + gui.set_alpha(content, 0) + gui.animate(content, "color.w", 1, gui.EASING_OUTSINE, 0.3, 0.1, callback) +end) + +-- Show the panel with animation +panel:show(function() + print("Panel animation completed") +end) + +-- Create a tab system with multiple containers +local tab1 = self.druid:new_container("tab1_content") +local tab2 = self.druid:new_container("tab2_content") +local tab3 = self.druid:new_container("tab3_content") + +local function switch_to_tab(tab_index) + tab1:hide() + tab2:hide() + tab3:hide() + + if tab_index == 1 then tab1:show() end + if tab_index == 2 then tab2:show() end + if tab_index == 3 then tab3:show() end +end + +-- Switch to tab 1 +switch_to_tab(1) +``` + +## Notes + +- The container component does not create or delete nodes, it only manages their visibility and enabled state +- When a container is hidden, all its nodes are disabled by default to prevent input +- You can customize the show and hide animations to create smooth transitions +- Containers are useful for organizing UI elements into logical groups like panels, windows, or tabs +- The container component respects the node's initial state when it's added to the container +- You can nest containers to create complex UI hierarchies +- The container component is often used with other components like buttons, texts, and layouts to create complete UI panels diff --git a/docs_md/components/extended/data_list_manual.md b/docs_md/components/extended/data_list_manual.md index e69de29..5f76714 100644 --- a/docs_md/components/extended/data_list_manual.md +++ b/docs_md/components/extended/data_list_manual.md @@ -0,0 +1,148 @@ +# Druid Data List Component + +## Description + +The Data List component provides an efficient way to display and manage large collections of data in a scrollable list. It creates and reuses a limited number of visual items to represent potentially unlimited data, optimizing performance for large datasets. + +## Features + +- Efficient display of large data collections +- Item recycling for optimal performance +- Integration with Grid and Scroll components +- Support for different item visual representations +- Dynamic data updates +- Customizable item creation and binding + +## Basic Usage + +```lua +-- Create a data list with a grid +local grid = self.druid:new_grid("grid_node", "item_prefab", 1) +local scroll = self.druid:new_scroll("view_node", "content_node") +scroll:bind_grid(grid) + +-- Create a data list with the grid +local data_list = self.druid:new_data_list(grid, function(self, data, index, node) + -- Bind data to visual item + local text_node = gui.get_node(node .. "/text") + gui.set_text(text_node, data.text) +end) + +-- Set data to the list +local data = { + { text = "Item 1" }, + { text = "Item 2" }, + { text = "Item 3" }, + -- ... more items +} +data_list:set_data(data) +``` + +### Parameters + +- **grid**: The grid component to use for item layout +- **bind_function**: Function to bind data to visual items with parameters (self, data, index, node) + +## Methods + +```lua +-- Set data to the list +data_list:set_data(data_array) + +-- Get current data +local data = data_list:get_data() + +-- Update specific data item +data_list:update_item(5, { text = "Updated Item 5" }) + +-- Add new items to the list +data_list:add(new_data_array) + +-- Remove items from the list +data_list:remove(5) -- Remove item at index 5 +data_list:remove(5, 3) -- Remove 3 items starting from index 5 + +-- Clear all data +data_list:clear() + +-- Get visual item node by data index +local node = data_list:get_node_by_index(10) + +-- Get data index by visual item node +local index = data_list:get_index_by_node(node) + +-- Set in-flight items (number of items created beyond visible area) +data_list:set_in_flight(2) +``` + +## Events + +```lua +-- Subscribe to data changes +data_list.on_data_changed:subscribe(function(self) + print("Data list data changed") +end) + +-- Subscribe to item creation +data_list.on_create_item:subscribe(function(self, node, index, data) + print("Created item at index: " .. index) +end) + +-- Subscribe to item removal +data_list.on_remove_item:subscribe(function(self, node, index) + print("Removed item at index: " .. index) +end) + +-- Subscribe to item binding +data_list.on_bind_item:subscribe(function(self, node, index, data) + print("Bound data to item at index: " .. index) +end) +``` + +## Examples + +```lua +-- Create a data list with custom item creation +local grid = self.druid:new_grid("grid_node", "item_prefab", 1) +local scroll = self.druid:new_scroll("view_node", "content_node") +scroll:bind_grid(grid) + +local data_list = self.druid:new_data_list(grid, function(self, data, index, node) + -- Bind data to visual item + local text_node = gui.get_node(node .. "/text") + local icon_node = gui.get_node(node .. "/icon") + + gui.set_text(text_node, data.title) + gui.set_texture(icon_node, data.icon_texture) + + -- Set up item interaction + local button = self.druid:new_button(node, function() + print("Clicked on item: " .. data.title) + end) +end) + +-- Set data with different item types +local data = { + { title = "Item 1", icon_texture = "icon1" }, + { title = "Item 2", icon_texture = "icon2" }, + { title = "Item 3", icon_texture = "icon3" }, +} +data_list:set_data(data) + +-- Add new items dynamically +function add_new_item() + data_list:add({ { title = "New Item", icon_texture = "new_icon" } }) +end +``` + +## Notes + +- The Data List component requires a Grid component for layout and typically a Scroll component for scrolling +- It creates only enough visual items to fill the visible area plus a few extra for smooth scrolling +- As the user scrolls, the component reuses existing items and rebinds them with new data +- This approach is much more efficient than creating one visual item per data entry +- The bind function is called whenever an item needs to be updated with data +- You can customize the appearance and behavior of each item in the bind function +- The component supports dynamic data updates, allowing you to add, remove, or modify items at runtime +- For best performance, keep your bind function efficient and avoid expensive operations +- The in-flight parameter controls how many extra items are created beyond the visible area diff --git a/docs_md/components/extended/hotkey_manual.md b/docs_md/components/extended/hotkey_manual.md index e69de29..ea0019b 100644 --- a/docs_md/components/extended/hotkey_manual.md +++ b/docs_md/components/extended/hotkey_manual.md @@ -0,0 +1,132 @@ +# Druid Hotkey Component + +## Description + +The Hotkey component provides a way to handle keyboard shortcuts in your UI. It allows you to define specific key combinations that trigger actions, making your UI more accessible and efficient for keyboard users. + +## Features + +- Support for single key and key combination shortcuts +- Customizable callback functions +- Optional key modifiers (shift, ctrl, alt) +- Ability to enable/disable hotkeys +- Events for hotkey triggers + +## Basic Usage + +```lua +-- Create a hotkey for the 'Enter' key +local hotkey = self.druid:new_hotkey("key_enter", function(self) + -- Handle Enter key press + print("Enter key pressed!") +end) + +-- Create a hotkey with modifiers (Ctrl+S) +local save_hotkey = self.druid:new_hotkey({ + key = "key_s", + modifier = "key_ctrl" +}, function(self) + -- Handle Ctrl+S key combination + print("Ctrl+S pressed - saving...") +end) +``` + +### Parameters + +- **key_trigger**: The key or key combination to trigger the hotkey + - Can be a string for a single key (e.g., "key_enter") + - Can be a table for key combinations (e.g., {key = "key_s", modifier = "key_ctrl"}) +- **callback**: (optional) Function to call when the hotkey is triggered + +## Methods + +```lua +-- Enable the hotkey +hotkey:set_enabled(true) + +-- Disable the hotkey +hotkey:set_enabled(false) + +-- Check if hotkey is enabled +local is_enabled = hotkey:is_enabled() + +-- Trigger the hotkey programmatically +hotkey:trigger() +``` + +## Events + +```lua +-- Subscribe to hotkey trigger event +hotkey.on_pressed:subscribe(function(self) + print("Hotkey was triggered") +end) +``` + +## Key Combinations + +The component supports various key combinations: + +```lua +-- Single key +local hotkey1 = self.druid:new_hotkey("key_space", callback) + +-- Key with modifier +local hotkey2 = self.druid:new_hotkey({ + key = "key_s", + modifier = "key_ctrl" +}, callback) + +-- Key with multiple modifiers +local hotkey3 = self.druid:new_hotkey({ + key = "key_s", + modifier = {"key_ctrl", "key_shift"} +}, callback) +``` + +## Examples + +```lua +-- Create navigation hotkeys +local next_hotkey = self.druid:new_hotkey("key_right", function() + navigate_to_next_page() +end) + +local prev_hotkey = self.druid:new_hotkey("key_left", function() + navigate_to_previous_page() +end) + +-- Create application shortcuts +local save_hotkey = self.druid:new_hotkey({ + key = "key_s", + modifier = "key_ctrl" +}, function() + save_document() +end) + +local undo_hotkey = self.druid:new_hotkey({ + key = "key_z", + modifier = "key_ctrl" +}, function() + undo_last_action() +end) + +-- Create a help dialog hotkey +local help_hotkey = self.druid:new_hotkey("key_f1", function() + show_help_dialog() +end) +``` + +## Notes + +- The Hotkey component requires proper key triggers setup in your `input.binding` file +- Hotkeys are global by default and will trigger regardless of UI focus +- You can enable/disable hotkeys based on context (e.g., disable certain hotkeys when a dialog is open) +- Key names should match the action IDs defined in your input bindings +- Common key names include: + - Navigation: "key_up", "key_down", "key_left", "key_right" + - Modifiers: "key_ctrl", "key_shift", "key_alt" + - Function keys: "key_f1", "key_f2", etc. + - Special keys: "key_enter", "key_space", "key_escape", "key_backspace" +- The component handles both key press and key release events +- Hotkeys are a great way to improve accessibility and user experience for keyboard users diff --git a/docs_md/components/extended/input_manual.md b/docs_md/components/extended/input_manual.md index e69de29..19d730a 100644 --- a/docs_md/components/extended/input_manual.md +++ b/docs_md/components/extended/input_manual.md @@ -0,0 +1,185 @@ +# Druid Input Component + +## Description + +The Input component provides a way to handle text input in your UI. It allows users to enter and edit text, with support for various input features like text selection, cursor positioning, and input validation. + +## Features + +- Text input handling with cursor support +- Text selection capabilities +- Input validation and filtering +- Maximum length restriction +- Password mode with character masking +- Events for text changes and interactions +- Support for multiline input +- Customizable visual feedback + +## Basic Usage + +```lua +-- Create a basic text input +local input = self.druid:new_input("input_node", "input_text_node") + +-- Set initial text +input:set_text("Initial text") +``` + +### Parameters + +- **node**: The node or node_id of the input background +- **text_node**: The node or node_id of the text component +- **keyboard_type**: (optional) The type of keyboard to show on mobile devices + +## Methods + +```lua +-- Set input text +input:set_text("New text") + +-- Get current text +local text = input:get_text() + +-- Clear input +input:clear() + +-- Set maximum text length +input:set_max_length(50) + +-- Set input validation pattern +input:set_allowed_characters("[%w%s]") -- Only alphanumeric and spaces + +-- Enable/disable password mode +input:set_password(true) -- Enable password mode +input:set_password(false) -- Disable password mode + +-- Set password character +input:set_password_char("*") + +-- Set placeholder text (shown when input is empty) +input:set_placeholder("Enter text here...") + +-- Set placeholder color +input:set_placeholder_color(vmath.vector4(0.5, 0.5, 0.5, 1)) + +-- Enable/disable multiline input +input:set_multiline(true) +input:set_multiline(false) + +-- Enable/disable the input +input:set_enabled(true) +input:set_enabled(false) + +-- Check if input is enabled +local is_enabled = input:is_enabled() + +-- Set input focus +input:set_focus() + +-- Remove input focus +input:remove_focus() + +-- Check if input has focus +local has_focus = input:is_focused() + +-- Select all text +input:select_all() + +-- Set cursor position +input:set_cursor_position(5) +``` + +## Events + +```lua +-- Subscribe to text change event +input.on_input_text:subscribe(function(self, text) + print("Text changed to: " .. text) +end) + +-- Subscribe to focus events +input.on_focus:subscribe(function(self) + print("Input gained focus") +end) + +input.on_focus_lost:subscribe(function(self) + print("Input lost focus") +end) + +-- Subscribe to input submit event (Enter key) +input.on_submit:subscribe(function(self) + print("Input submitted with text: " .. self:get_text()) +end) + +-- Subscribe to input canceled event (Escape key) +input.on_cancel:subscribe(function(self) + print("Input canceled") +end) +``` + +## Examples + +```lua +-- Create a username input with validation +local username_input = self.druid:new_input("username_bg", "username_text") +username_input:set_placeholder("Username") +username_input:set_allowed_characters("[%w_]") -- Only alphanumeric and underscore +username_input:set_max_length(20) + +-- Create a password input +local password_input = self.druid:new_input("password_bg", "password_text") +password_input:set_placeholder("Password") +password_input:set_password(true) +password_input:set_password_char("•") + +-- Create a multiline text area +local text_area = self.druid:new_input("textarea_bg", "textarea_text") +text_area:set_multiline(true) +text_area:set_placeholder("Enter your message here...") + +-- Create a numeric input for age +local age_input = self.druid:new_input("age_bg", "age_text") +age_input:set_allowed_characters("%d") -- Only digits +age_input:set_max_length(3) +age_input:set_keyboard_type(gui.KEYBOARD_TYPE_NUMBER_PAD) + +-- Create a form with multiple inputs and validation +local email_input = self.druid:new_input("email_bg", "email_text") +email_input:set_placeholder("Email") + +local function validate_form() + local email = email_input:get_text() + local password = password_input:get_text() + + -- Simple email validation + if not email:match("^[%w%.]+@[%w%.]+%.%w+$") then + print("Invalid email format") + return false + end + + if #password < 8 then + print("Password must be at least 8 characters") + return false + end + + return true +end + +local submit_button = self.druid:new_button("submit_button", function() + if validate_form() then + print("Form submitted successfully") + end +end) +``` + +## Notes + +- The Input component requires proper key triggers setup in your `input.binding` file +- On mobile platforms, the component will show the appropriate keyboard based on the keyboard_type parameter +- The component handles text selection, cursor positioning, and clipboard operations +- You can customize the visual appearance of the input, including text color, selection color, and cursor +- Input validation can be used to restrict what characters users can enter +- The placeholder text is shown when the input is empty and doesn't have focus +- For multiline input, the component supports line breaks and scrolling +- The component provides events for all major input interactions, allowing you to create responsive forms +- Password mode masks the entered text with the specified character for security diff --git a/docs_md/components/extended/lang_text_manual.md b/docs_md/components/extended/lang_text_manual.md index e69de29..474ad11 100644 --- a/docs_md/components/extended/lang_text_manual.md +++ b/docs_md/components/extended/lang_text_manual.md @@ -0,0 +1,127 @@ +# Druid Lang Text Component + +## Description + +The Lang Text component extends the basic Text component to provide localization support. It automatically updates the text when the game language changes, making it easy to create multilingual UIs. + +## Features + +- Automatic text localization +- Support for text parameters and formatting +- Updates automatically when language changes +- Inherits all Text component features +- Support for fallback languages + +## Basic Usage + +```lua +-- Create a basic localized text +local lang_text = self.druid:new_lang_text("text_node", "ui.welcome_message") +``` + +### Parameters + +- **node**: The node or node_id of the text node +- **locale_id**: The localization key to use for this text +- **params**: (optional) Parameters to format into the localized string + +## Methods + +```lua +-- Set the localization key +lang_text:set_locale_id("ui.new_message") + +-- Set parameters for text formatting +lang_text:set_params({name = "Player", score = 100}) + +-- Update the text with current locale and parameters +lang_text:update_text() + +-- Get the current locale ID +local locale_id = lang_text:get_locale_id() + +-- Get the current parameters +local params = lang_text:get_params() + +-- Set a specific language for this text (overrides global language) +lang_text:set_language("en") + +-- Reset to use the global language +lang_text:reset_language() +``` + +## Inheritance from Text Component + +The Lang Text component inherits all methods and properties from the basic Text component, including: + +```lua +-- Set text color +lang_text:set_color(vmath.vector4(1, 0, 0, 1)) + +-- Set text scale +lang_text:set_scale(1.5) + +-- Set text pivot +lang_text:set_pivot(gui.PIVOT_CENTER) + +-- Set text adjustment +lang_text:set_text_adjust(druid.const.TEXT_ADJUST.DOWNSCALE) +``` + +## Examples + +```lua +-- Create a welcome message with player name +local welcome_text = self.druid:new_lang_text("welcome_text", "ui.welcome", {name = "Player"}) + +-- Update player name +function update_player_name(new_name) + welcome_text:set_params({name = new_name}) +end + +-- Create a score display with formatting +local score_text = self.druid:new_lang_text("score_text", "ui.score", {score = 0}) + +-- Update score +function update_score(new_score) + score_text:set_params({score = new_score}) +end + +-- Create a text with language override +local hint_text = self.druid:new_lang_text("hint_text", "ui.hint") +hint_text:set_language("en") -- Always show hint in English regardless of game language +``` + +## Localization Format + +The Lang Text component works with the localization system to retrieve strings based on locale IDs. The localization format typically looks like: + +```lua +-- In your localization files +local localization = { + en = { + ui = { + welcome = "Welcome, {name}!", + score = "Score: {score}", + hint = "Press Space to continue" + } + }, + fr = { + ui = { + welcome = "Bienvenue, {name}!", + score = "Score: {score}", + hint = "Appuyez sur Espace pour continuer" + } + } +} +``` + +## Notes + +- The Lang Text component requires a properly set up localization system +- The component automatically updates when the game language changes +- You can use parameters in your localized strings with {param_name} syntax +- The component inherits all features from the basic Text component +- You can override the language for specific texts, which is useful for debugging or for text that should always appear in a specific language +- The component works with the Druid localization system, which supports fallback languages +- For complex formatting, you can use custom format functions in your localization system diff --git a/docs_md/components/extended/layout_manual.md b/docs_md/components/extended/layout_manual.md index e69de29..a3899ec 100644 --- a/docs_md/components/extended/layout_manual.md +++ b/docs_md/components/extended/layout_manual.md @@ -0,0 +1,98 @@ +# Druid Layout Component + +## Description + +The Layout component provides automatic positioning and sizing of UI elements based on predefined layout rules. It helps create responsive UIs that adapt to different screen sizes and orientations. + +## Features + +- Automatic positioning of nodes based on layout rules +- Support for different layout types (static, dynamic, fixed) +- Anchoring nodes to different parts of the screen +- Automatic adjustment when screen size changes +- Pivot-based positioning +- Margin and padding support + +## Basic Usage + +```lua +local layout = self.druid:new_layout("layout_node") +``` + +### Parameters + +- **node**: The node or node_id of the layout container + +## Layout Types + +The Layout component supports several layout types: + +- **Static Layout**: Fixed position relative to parent +- **Dynamic Layout**: Position based on parent size and node anchor +- **Fixed Layout**: Position based on screen size and node anchor + +## Methods + +```lua +-- Set layout type +layout:set_static_layout() -- Fixed position relative to parent +layout:set_dynamic_layout() -- Position based on parent size +layout:set_fixed_layout() -- Position based on screen size + +-- Update layout size +layout:set_size(width, height) + +-- Set node anchor (position relative to parent) +layout:set_anchor(anchor_type) +-- Available anchor types: ANCHOR.CENTER, ANCHOR.TOP, ANCHOR.BOTTOM, etc. + +-- Set node pivot (position relative to node itself) +layout:set_pivot(pivot_type) +-- Available pivot types: PIVOT.CENTER, PIVOT.N, PIVOT.S, etc. + +-- Set margins (distance from anchor point) +layout:set_margin(left, top, right, bottom) + +-- Set padding (internal spacing) +layout:set_padding(left, top, right, bottom) + +-- Manually update layout +layout:update() + +-- Reset to initial state +layout:reset() +``` + +## Events + +```lua +-- Subscribe to layout changes +layout.on_layout_change:subscribe(function(self) + print("Layout changed") +end) +``` + +## Example + +```lua +-- Create a layout that anchors to the top right of the screen +local layout = self.druid:new_layout("panel") +layout:set_fixed_layout() +layout:set_anchor(druid.const.ANCHOR.TOP_RIGHT) +layout:set_pivot(druid.const.PIVOT.NE) +layout:set_margin(0, 50, 50, 0) -- 50px from top, 50px from right + +-- Create a dynamic layout that centers in its parent +local layout = self.druid:new_layout("content") +layout:set_dynamic_layout() +layout:set_anchor(druid.const.ANCHOR.CENTER) +layout:set_pivot(druid.const.PIVOT.CENTER) +``` + +## Notes + +- The layout component automatically adjusts when the screen size changes +- You can nest layouts to create complex UI structures +- The layout component works well with other components like Grid and Scroll +- For responsive UIs, use fixed layouts for screen-anchored elements and dynamic layouts for elements that should adapt to their parent's size +- The layout component respects the node's initial position as an offset from the calculated position diff --git a/docs_md/components/extended/progress_manual.md b/docs_md/components/extended/progress_manual.md index e69de29..7d403d1 100644 --- a/docs_md/components/extended/progress_manual.md +++ b/docs_md/components/extended/progress_manual.md @@ -0,0 +1,111 @@ +# Druid Progress Component + +## Description + +The Progress component provides a way to visualize progress or completion status through various visual representations. It can be used to create progress bars, loading indicators, or any UI element that needs to display a value within a range. + +## Features + +- Visual representation of progress values +- Support for different visual styles (bar, radial, etc.) +- Customizable value range +- Smooth value transitions with animations +- Events for progress changes +- Support for fill nodes, size nodes, and slice nodes + +## Basic Usage + +```lua +-- Basic progress bar with a fill node +local progress = self.druid:new_progress("progress_node", druid.const.PROGRESS.FILL) + +-- Set progress value (0 to 1) +progress:set_value(0.5) -- 50% progress +``` + +### Parameters + +- **node**: The node or node_id of the progress container +- **mode**: (optional) The progress visualization mode (default: FILL) + - `druid.const.PROGRESS.FILL`: Changes the fill of the node + - `druid.const.PROGRESS.SIZE`: Changes the size of the node + - `druid.const.PROGRESS.SLICE`: Changes the slice of a pie node + +## Methods + +```lua +-- Set progress value (0 to 1) +progress:set_value(0.75) -- 75% progress + +-- Set progress value with animation +progress:set_to(0.75, 0.5) -- Animate to 75% over 0.5 seconds + +-- Get current progress value +local value = progress:get_value() + +-- Set custom value range +progress:set_range(0, 100) +progress:set_value(50) -- 50% progress (value 50 in range 0-100) + +-- Set key points for non-linear progress +progress:set_key_points({ + { value = 0, percent = 0 }, + { value = 50, percent = 0.25 }, -- 50 is 25% of visual progress + { value = 100, percent = 1 } +}) + +-- Set fill target node (for FILL mode) +progress:set_fill_node("fill_node") + +-- Set size target node (for SIZE mode) +progress:set_size_node("size_node") + +-- Set slice target node (for SLICE mode) +progress:set_slice_node("slice_node") + +-- Reset to initial state +progress:reset() +``` + +## Events + +```lua +-- Subscribe to progress value changes +progress.on_change:subscribe(function(self, value) + print("Progress changed to: " .. value) +end) + +-- Subscribe to progress completion +progress.on_complete:subscribe(function(self) + print("Progress completed!") +end) +``` + +## Examples + +```lua +-- Create a horizontal progress bar +local progress = self.druid:new_progress("bar_node", druid.const.PROGRESS.SIZE) +progress:set_size_node("fill_node") +progress:set_value(0.5) + +-- Create a radial progress indicator +local progress = self.druid:new_progress("pie_node", druid.const.PROGRESS.SLICE) +progress:set_slice_node("slice_node") +progress:set_value(0.75) + +-- Create a progress bar with custom range +local progress = self.druid:new_progress("health_bar", druid.const.PROGRESS.FILL) +progress:set_range(0, 100) +progress:set_value(75) -- 75/100 = 75% progress +``` + +## Notes + +- The progress component can be used with different visual representations based on the mode +- For FILL mode, the component changes the x or y fill of the target node +- For SIZE mode, the component changes the size of the target node +- For SLICE mode, the component changes the inner or outer bounds of a pie node +- You can create non-linear progress visualization using key points +- The progress component supports smooth animations between values +- The default value range is 0 to 1, but you can customize it for your specific needs diff --git a/docs_md/components/extended/slider_manual.md b/docs_md/components/extended/slider_manual.md index e69de29..5140bcd 100644 --- a/docs_md/components/extended/slider_manual.md +++ b/docs_md/components/extended/slider_manual.md @@ -0,0 +1,114 @@ +# Druid Slider Component + +## Description + +The Slider component provides an interactive way for users to select a value from a range by dragging a handle along a track. It's commonly used for settings like volume control, brightness adjustment, or any scenario where users need to select a value within a continuous range. + +## Features + +- Interactive value selection through dragging +- Customizable value range +- Support for horizontal and vertical orientations +- Smooth handle movement with animations +- Events for value changes and interactions +- Optional steps for discrete value selection +- Visual feedback through progress component integration + +## Basic Usage + +```lua +-- Basic horizontal slider +local slider = self.druid:new_slider("slider_node", "pin_node", vmath.vector3(1, 0, 0)) + +-- Set initial value (0 to 1) +slider:set_value(0.5) -- 50% of the slider range +``` + +### Parameters + +- **node**: The node or node_id of the slider background/track +- **pin_node**: The node or node_id of the draggable handle/pin +- **axis**: The axis vector for the slider direction (e.g., vmath.vector3(1, 0, 0) for horizontal) + +## Methods + +```lua +-- Set slider value (0 to 1) +slider:set_value(0.75) -- 75% of the slider range + +-- Set slider value with animation +slider:set_to(0.75, 0.5) -- Animate to 75% over 0.5 seconds + +-- Get current slider value +local value = slider:get_value() + +-- Set custom value range +slider:set_range(0, 100) +slider:set_value(50) -- 50% of the slider range (value 50 in range 0-100) + +-- Set steps for discrete values +slider:set_steps(5) -- 5 steps: 0, 0.25, 0.5, 0.75, 1 + +-- Enable/disable the slider +slider:set_enabled(true) +slider:set_enabled(false) + +-- Check if slider is enabled +local is_enabled = slider:is_enabled() + +-- Set a progress component to visualize the slider value +local progress = self.druid:new_progress("progress_node") +slider:set_progress(progress) + +-- Reset to initial state +slider:reset() +``` + +## Events + +```lua +-- Subscribe to value changes +slider.on_change:subscribe(function(self, value) + print("Slider value changed to: " .. value) +end) + +-- Subscribe to drag start event +slider.on_drag_start:subscribe(function(self) + print("Started dragging slider") +end) + +-- Subscribe to drag end event +slider.on_drag_end:subscribe(function(self) + print("Stopped dragging slider") +end) +``` + +## Examples + +```lua +-- Create a horizontal slider with steps +local slider = self.druid:new_slider("slider_bg", "slider_pin", vmath.vector3(1, 0, 0)) +slider:set_steps(10) -- 10 discrete steps +slider:set_value(0.3) + +-- Create a vertical slider with custom range +local slider = self.druid:new_slider("volume_bg", "volume_pin", vmath.vector3(0, 1, 0)) +slider:set_range(0, 100) +slider:set_value(75) -- 75/100 = 75% of the slider + +-- Create a slider with visual progress feedback +local slider = self.druid:new_slider("slider_bg", "slider_pin", vmath.vector3(1, 0, 0)) +local progress = self.druid:new_progress("progress_fill") +slider:set_progress(progress) +slider:set_value(0.5) +``` + +## Notes + +- The slider component calculates the handle position based on the background node size and the specified axis +- For horizontal sliders, use axis vector (1, 0, 0); for vertical sliders, use (0, 1, 0) +- The slider component automatically adjusts the handle position when the value changes +- When using steps, the slider will snap to the nearest step value +- You can integrate a progress component to provide visual feedback of the current value +- The slider's drag behavior respects the bounds of the background node +- The default value range is 0 to 1, but you can customize it for your specific needs diff --git a/docs_md/components/extended/swipe_manual.md b/docs_md/components/extended/swipe_manual.md index e69de29..633c25b 100644 --- a/docs_md/components/extended/swipe_manual.md +++ b/docs_md/components/extended/swipe_manual.md @@ -0,0 +1,136 @@ +# Druid Swipe Component + +## Description + +The Swipe component detects swipe gestures on a specified node or across the entire screen. It provides information about swipe direction, speed, and distance, allowing you to implement gesture-based interactions in your UI. + +## Features + +- Detection of swipe gestures in 8 directions +- Customizable swipe sensitivity and threshold +- Information about swipe speed and distance +- Support for both touch and mouse input +- Optional click zone restriction +- Events for swipe detection + +## Basic Usage + +```lua +-- Basic swipe detection across the entire screen +local swipe = self.druid:new_swipe(function(self, swipe_info) + -- Handle swipe action + print("Swipe detected in direction: " .. swipe_info.direction) +end) + +-- Swipe detection on a specific node +local swipe = self.druid:new_swipe(function(self, swipe_info) + -- Handle swipe action + print("Swipe detected in direction: " .. swipe_info.direction) +end, "swipe_area_node") +``` + +### Parameters + +- **callback**: (optional) Function to call when a swipe is detected +- **node**: (optional) The node or node_id to detect swipes on (default: entire screen) + +## Swipe Info + +The swipe callback provides a `swipe_info` table with the following information: + +```lua +{ + direction = druid.const.SWIPE.RIGHT, -- Direction constant + distance = 150, -- Distance in pixels + time = 0.2, -- Time taken for the swipe in seconds + speed = 750, -- Speed in pixels per second + x = 150, -- X distance + y = 0, -- Y distance + touch = hash("touch") -- Touch that triggered the swipe +} +``` + +## Methods + +```lua +-- Set minimum swipe distance threshold +swipe:set_minimum_distance(50) + +-- Set maximum swipe time threshold +swipe:set_maximum_time(0.5) + +-- Set a click zone to restrict swipe area +swipe:set_click_zone("stencil_node") + +-- Enable or disable swipe detection +swipe:set_enabled(true) +swipe:set_enabled(false) + +-- Check if swipe detection is enabled +local is_enabled = swipe:is_enabled() +``` + +## Events + +```lua +-- Subscribe to swipe event +swipe.on_swipe:subscribe(function(self, swipe_info) + print("Swipe detected in direction: " .. swipe_info.direction) + print("Swipe distance: " .. swipe_info.distance) + print("Swipe speed: " .. swipe_info.speed) +end) +``` + +## Swipe Directions + +The component provides constants for swipe directions: + +```lua +druid.const.SWIPE = { + UP = "up", + DOWN = "down", + LEFT = "left", + RIGHT = "right", + UP_LEFT = "up_left", + UP_RIGHT = "up_right", + DOWN_LEFT = "down_left", + DOWN_RIGHT = "down_right" +} +``` + +## Examples + +```lua +-- Create a swipe detector with custom thresholds +local swipe = self.druid:new_swipe(function(self, swipe_info) + if swipe_info.direction == druid.const.SWIPE.LEFT then + -- Handle left swipe + print("Left swipe detected") + elseif swipe_info.direction == druid.const.SWIPE.RIGHT then + -- Handle right swipe + print("Right swipe detected") + end +end) +swipe:set_minimum_distance(100) -- Require at least 100px of movement +swipe:set_maximum_time(0.3) -- Must complete within 0.3 seconds + +-- Create a swipe detector for a specific area +local swipe = self.druid:new_swipe(nil, "swipe_area") +swipe.on_swipe:subscribe(function(self, swipe_info) + if swipe_info.speed > 1000 then + print("Fast swipe detected!") + else + print("Slow swipe detected") + end +end) +``` + +## Notes + +- The swipe component detects gestures based on both distance and time thresholds +- By default, a swipe must be at least 50 pixels in distance and completed within 0.4 seconds +- The component determines the direction based on the angle of the swipe +- You can restrict the swipe detection area by setting a click zone, which is useful for stencil nodes +- The swipe component automatically detects the closest stencil node and sets it as the click zone if none is specified +- Swipe detection works with both touch and mouse input +- The component provides detailed information about each swipe, allowing you to implement velocity-based interactions diff --git a/docs_md/components/extended/timer_manual.md b/docs_md/components/extended/timer_manual.md index e69de29..27a73a6 100644 --- a/docs_md/components/extended/timer_manual.md +++ b/docs_md/components/extended/timer_manual.md @@ -0,0 +1,125 @@ +# Druid Timer Component + +## Description + +The Timer component provides a way to create and manage countdown or countup timers in your UI. It can be used for game timers, cooldowns, or any feature that requires time tracking with visual feedback. + +## Features + +- Countdown and countup timer modes +- Customizable time format display +- Pause, resume, and reset functionality +- Events for timer updates and completion +- Optional text component integration for visual display +- Support for different time units (seconds, minutes, hours) + +## Basic Usage + +```lua +-- Basic countdown timer (10 seconds) +local timer = self.druid:new_timer(10, true) + +-- Start the timer +timer:start() +``` + +### Parameters + +- **time**: The initial time value in seconds +- **is_countdown**: (optional) Boolean indicating if this is a countdown timer (default: false) + +## Methods + +```lua +-- Start the timer +timer:start() + +-- Pause the timer +timer:pause() + +-- Resume a paused timer +timer:resume() + +-- Reset the timer to its initial value +timer:reset() + +-- Set a new time value +timer:set_time(30) -- Set to 30 seconds + +-- Get current time value +local current_time = timer:get_time() + +-- Check if timer is running +local is_running = timer:is_running() + +-- Set a text component to display the timer +local text = self.druid:new_text("timer_text") +timer:set_text(text) + +-- Set custom time format +timer:set_format(function(self, time) + local minutes = math.floor(time / 60) + local seconds = math.floor(time % 60) + return string.format("%02d:%02d", minutes, seconds) +end) +``` + +## Events + +```lua +-- Subscribe to timer tick event (called every frame while timer is running) +timer.on_tick:subscribe(function(self, value) + print("Timer value: " .. value) +end) + +-- Subscribe to timer completion event +timer.on_complete:subscribe(function(self) + print("Timer completed!") +end) +``` + +## Examples + +```lua +-- Create a 5-minute countdown timer with text display +local timer = self.druid:new_timer(300, true) -- 300 seconds = 5 minutes +local text = self.druid:new_text("timer_text") +timer:set_text(text) +timer:set_format(function(self, time) + local minutes = math.floor(time / 60) + local seconds = math.floor(time % 60) + return string.format("%02d:%02d", minutes, seconds) +end) +timer:start() + +-- Create a stopwatch (countup timer) +local stopwatch = self.druid:new_timer(0, false) +local text = self.druid:new_text("stopwatch_text") +stopwatch:set_text(text) +stopwatch:start() + +-- Create a game round timer with events +local round_timer = self.druid:new_timer(60, true) -- 60 second round +round_timer.on_tick:subscribe(function(self, value) + if value <= 10 then + -- Last 10 seconds, show warning + print("Time is running out!") + end +end) +round_timer.on_complete:subscribe(function(self) + -- Round is over + print("Round completed!") +end) +round_timer:start() +``` + +## Notes + +- The timer component updates every frame while running +- For countdown timers, the timer completes when it reaches 0 +- For countup timers, you need to manually check for completion or set a target time +- The default time format is seconds with one decimal place (e.g., "10.0") +- You can customize the time format to display hours, minutes, seconds, or any other format +- The timer component can be paused, resumed, and reset at any time +- When using with a text component, the timer automatically updates the text display +- The timer value is in seconds, but you can convert it to other units in your format function