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

View File

@@ -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 <color=red>World</color>!")
```
### Parameters
- **node**: The node or node_id of the text node
## Rich Text Markup
The component uses HTML-like tags for formatting:
```l
<color=[#]HEX_VALUE>Colored text</color>
<color=COLOR_NAME>Colored text</color>
<shadow=[#]HEX_VALUE>Text with shadow</shadow>
<outline=[#]HEX_VALUE>Text with outline</outline>
<font=FONT_PATH>Text with custom font</font>
<size=NUMBER>Sized text</size>
<br/>Line break
<nobr>No line break zone</nobr>
<img=TEXTURE_ID[:ANIM_ID][,WIDTH][,HEIGHT]/>
```
## Methods
```lua
-- Set rich text content
rich_text:set_text("Hello <color=red>World</color>!")
-- 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 <color=red>rich</color> <color=green>text</color> <color=blue>component</color>.")
-- Create text with custom font and size
local title_text = self.druid:new_rich_text("title_node")
title_text:set_text("<font=fonts/title.font><size=2>GAME TITLE</size></font>")
-- Create text with shadow and outline effects
local effect_text = self.druid:new_rich_text("effect_node")
effect_text:set_text("<shadow=black><outline=white>Stylized Text</outline></shadow>")
-- Create text with embedded images
local info_text = self.druid:new_rich_text("info_text")
info_text:set_text("Your character: <img=hero_avatar,48,48/> Level <color=yellow>5</color><br/>HP: <color=red>75</color>/100<br/>MP: <color=blue>30</color>/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 <pulse=1.5>pulsing</pulse> 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("<color=aqua>Aqua</color> <color=red>Red</color> <color=lime>Lime</color>")
```
## 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