This commit is contained in:
Insality
2025-03-06 01:50:31 +02:00
parent ea4ff7eafc
commit 3bb8705444
20 changed files with 2382 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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