Update example with new brand one

This commit is contained in:
Insality
2024-10-17 01:24:15 +03:00
parent 2c762716bb
commit 91879509a0
197 changed files with 36779 additions and 7 deletions

View File

@@ -0,0 +1,50 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
size {
x: 700.0
y: 100.0
}
color {
x: 0.522
y: 0.522
z: 0.522
}
type: TYPE_TEXT
text: "Press \"back\" to trigger a callback"
font: "text_bold"
id: "text"
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,24 @@
local component = require("druid.component")
---@class basic_back_handler: druid.base_component
---@field druid druid_instance
local M = component.create("basic_back_handler")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.druid:new_back_handler(self.on_back)
end
function M:on_back()
local node = self:get_node("text")
gui.animate(node, gui.PROP_SCALE, vmath.vector3(1.2), gui.EASING_OUTELASTIC, 0.5, 0, function()
gui.animate(node, gui.PROP_SCALE, vmath.vector3(1), gui.EASING_OUTELASTIC, 0.5)
end)
end
return M

View File

@@ -0,0 +1,91 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
size {
x: 512.0
y: 512.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "blocker"
parent: "root"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
}
nodes {
type: TYPE_TEMPLATE
id: "button"
parent: "blocker"
inherit_alpha: true
template: "/example/templates/button_text_green.gui"
}
nodes {
type: TYPE_BOX
id: "button/root"
parent: "button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button/text"
parent: "button/root"
template_node_child: true
}
nodes {
position {
x: -246.0
y: 246.0
}
size {
x: 300.0
y: 50.0
}
type: TYPE_TEXT
text: "Blocker"
font: "text_bold"
id: "text"
pivot: PIVOT_NW
parent: "blocker"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,34 @@
local component = require("druid.component")
---@class basic_blocker: druid.component
---@field druid druid_instance
---@field root node
---@field blocker druid.blocker
local M = component.create("basic_blocker")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.button_root = self.druid:new_button(self.root, self.on_root_click)
-- This blocker forbid input to all previous nodes in node zone
self.blocker = self.druid:new_blocker("blocker")
self.button = self.druid:new_button("button/root", self.on_button_click)
end
function M:on_root_click()
print("Root click")
end
function M:on_button_click()
print("Button click")
end
return M

View File

@@ -0,0 +1,236 @@
script: ""
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_green.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Confirm"
font: "text_bold"
id: "button/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,19 @@
local component = require("druid.component")
---@class basic_button: druid.base_component
---@field druid druid_instance
---@field button druid.button
local M = component.create("basic_button")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.button = self.druid:new_button("button/root", function()
print("Button pressed")
end)
end
return M

View File

@@ -0,0 +1,236 @@
script: ""
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_green.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Confirm"
font: "text_bold"
id: "button/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,23 @@
local component = require("druid.component")
---@class basic_button_double_click: druid.base_component
---@field druid druid_instance
---@field button druid.button
local M = component.create("basic_button_double_click")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.button = self.druid:new_button("button/root", function()
print("Click")
end)
self.button.on_double_click:subscribe(function()
print("Double click")
end)
end
return M

View File

@@ -0,0 +1,107 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 200.0
y: 100.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
visible: false
}
nodes {
size {
x: 280.0
y: 90.0
}
color {
x: 0.902
y: 0.875
z: 0.624
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "button"
parent: "root"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
}
nodes {
size {
x: 400.0
y: 400.0
}
type: TYPE_PIE
id: "mask"
parent: "button"
inherit_alpha: true
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: false
size_mode: SIZE_MODE_AUTO
}
nodes {
size {
x: 280.0
y: 90.0
}
color {
x: 0.557
y: 0.835
z: 0.62
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "button_image"
parent: "mask"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
}
nodes {
size {
x: 245.0
y: 50.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_TEXT
text: "Confirm"
font: "text_bold"
id: "text"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "button"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,49 @@
local component = require("druid.component")
local panthera = require("panthera.panthera")
local animation = require("example.examples.basic.button.basic_button_hold_panthera")
---@class basic_button_hold: druid.base_component
---@field druid druid_instance
---@field button druid.button
local M = component.create("basic_button_hold")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.animation = panthera.create_gui(animation, self:get_template(), nodes)
self.button = self.druid:new_button("button", function()
print("Click")
end)
self.button:set_style({})
self.button.style.AUTOHOLD_TRIGGER = 2
self.button.style.LONGTAP_TIME = 0
self.button.on_hold_callback:subscribe(function(_, _, _, time)
local start_time = self.button.style.LONGTAP_TIME
local max_time = self.button.style.AUTOHOLD_TRIGGER
local progress = (time - start_time) / (max_time - start_time)
panthera.set_time(self.animation, "hold", progress)
end)
self.button.on_long_click:subscribe(function()
panthera.play(self.animation, "complete")
end)
self.button.hover.on_mouse_hover:subscribe(function(_, state)
if not state then
panthera.set_time(self.animation, "hold", 0)
end
end)
self.button.on_click_outside:subscribe(function()
panthera.set_time(self.animation, "hold", 0)
end)
end
return M

View File

@@ -0,0 +1,266 @@
return {
type = "animation_editor",
format = "json",
data = {
nodes = {
},
animations = {
{
animation_id = "default",
duration = 1,
animation_keys = {
},
},
{
animation_id = "hold",
duration = 1,
animation_keys = {
{
end_value = -90,
easing = "outsine",
property_id = "rotation_z",
node_id = "button_image",
key_type = "tween",
},
{
end_value = 90,
easing = "outsine",
property_id = "rotation_z",
node_id = "mask",
key_type = "tween",
},
{
end_value = 1.1,
easing = "outsine",
property_id = "scale_x",
duration = 0.15,
key_type = "tween",
node_id = "button",
start_value = 1,
},
{
end_value = 1.1,
easing = "outsine",
property_id = "scale_y",
duration = 0.15,
key_type = "tween",
node_id = "button",
start_value = 1,
},
{
end_value = 1.3,
easing = "outsine",
property_id = "scale_x",
duration = 0.15,
key_type = "tween",
node_id = "text",
start_value = 1,
},
{
end_value = 1.3,
easing = "outsine",
property_id = "scale_y",
duration = 0.15,
key_type = "tween",
node_id = "text",
start_value = 1,
},
{
start_value = 360,
easing = "outsine",
property_id = "fill_angle",
duration = 1,
node_id = "mask",
key_type = "tween",
},
{
end_value = 1,
easing = "incirc",
property_id = "scale_x",
duration = 0.85,
start_value = 1.1,
key_type = "tween",
node_id = "button",
start_time = 0.15,
},
{
end_value = 1,
easing = "incirc",
property_id = "scale_y",
duration = 0.85,
start_value = 1.1,
key_type = "tween",
node_id = "button",
start_time = 0.15,
},
{
end_value = 1,
easing = "outsine",
property_id = "scale_x",
duration = 0.51,
start_value = 1.3,
key_type = "tween",
node_id = "text",
start_time = 0.49,
},
{
end_value = 1,
easing = "outsine",
property_id = "scale_y",
duration = 0.51,
start_value = 1.3,
key_type = "tween",
node_id = "text",
start_time = 0.49,
},
},
},
{
animation_id = "complete",
duration = 0.4,
animation_keys = {
{
easing = "linear",
property_id = "inherit_alpha",
data = "false",
key_type = "trigger",
node_id = "text",
start_data = "true",
},
{
end_value = 0.624,
easing = "outsine",
property_id = "color_b",
key_type = "tween",
node_id = "button_image",
start_value = 0.62,
},
{
end_value = 0.875,
easing = "outsine",
property_id = "color_g",
key_type = "tween",
node_id = "button_image",
start_value = 0.835,
},
{
end_value = 0.902,
easing = "outsine",
property_id = "color_r",
key_type = "tween",
node_id = "button_image",
start_value = 0.557,
},
{
end_value = 1.1,
easing = "outsine",
property_id = "color_a",
duration = 0.17,
key_type = "tween",
node_id = "root",
start_value = 1,
},
{
end_value = 1.2,
easing = "outsine",
property_id = "scale_x",
duration = 0.17,
key_type = "tween",
node_id = "root",
start_value = 1,
},
{
end_value = 1.2,
easing = "outsine",
property_id = "scale_y",
duration = 0.17,
key_type = "tween",
node_id = "root",
start_value = 1,
},
{
end_value = 0.557,
easing = "outsine",
property_id = "color_r",
duration = 0.38,
start_value = 0.902,
key_type = "tween",
node_id = "button_image",
start_time = 0.02,
},
{
end_value = 0.62,
easing = "outsine",
property_id = "color_b",
duration = 0.38,
start_value = 0.624,
key_type = "tween",
node_id = "button_image",
start_time = 0.02,
},
{
end_value = 0.835,
easing = "outsine",
property_id = "color_g",
duration = 0.38,
start_value = 0.875,
key_type = "tween",
node_id = "button_image",
start_time = 0.02,
},
{
end_value = 1,
easing = "outsine",
property_id = "color_a",
duration = 0.22,
start_value = 1.1,
key_type = "tween",
node_id = "root",
start_time = 0.17,
},
{
end_value = 1,
easing = "outsine",
property_id = "scale_x",
duration = 0.22,
start_value = 1.2,
key_type = "tween",
node_id = "root",
start_time = 0.17,
},
{
end_value = 1,
easing = "outsine",
property_id = "scale_y",
duration = 0.22,
start_value = 1.2,
key_type = "tween",
node_id = "root",
start_time = 0.17,
},
{
easing = "linear",
property_id = "inherit_alpha",
start_data = "false",
data = "true",
key_type = "trigger",
node_id = "text",
start_time = 0.39,
},
},
},
},
metadata = {
layers = {
},
gui_path = "/example/examples/basic/button/basic_button_hold.gui",
gizmo_steps = {
},
settings = {
font_size = 40,
},
fps = 60,
},
},
version = 1,
}

View File

@@ -0,0 +1,77 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 200.0
y: 100.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
visible: false
}
nodes {
size {
x: 40.0
y: 40.0
}
color {
x: 0.463
y: 0.475
z: 0.49
}
type: TYPE_BOX
texture: "druid/rect_round2_width1"
id: "button"
parent: "root"
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
}
nodes {
color {
x: 0.722
y: 0.741
z: 0.761
}
type: TYPE_BOX
texture: "druid/icon_check"
id: "icon"
parent: "button"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -20.0
}
size {
x: 40.0
y: 4.0
}
color {
x: 0.894
y: 0.506
z: 0.333
}
type: TYPE_BOX
texture: "druid/pixel"
id: "selected"
pivot: PIVOT_S
adjust_mode: ADJUST_MODE_STRETCH
parent: "button"
inherit_alpha: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,41 @@
local component = require("druid.component")
---@class basic_checkbox: druid.base_component
---@field druid druid_instance
---@field button druid.button
local M = component.create("basic_checkbox")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.button = self.druid:new_button("button", self.on_checkbox_click) -- Button to handle checkbox
self.icon = self:get_node("icon") -- Checkbox icon to hide/show
self.selected = self:get_node("selected") -- Selected effect to show when checkbox is changed
gui.set_alpha(self.selected, 0)
self:set_state(false)
end
function M:on_checkbox_click()
self:set_state(not self.is_enabled)
end
function M:set_state(is_enabled)
if self.is_enabled == is_enabled then
return
end
self.is_enabled = is_enabled
gui.set_enabled(self.icon, self.is_enabled)
gui.set_alpha(self.selected, 1)
gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
end
return M

View File

@@ -0,0 +1,241 @@
script: ""
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "drag"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_blue.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "drag/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "drag"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Drag Me"
font: "text_bold"
id: "drag/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "drag/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 8
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,29 @@
local component = require("druid.component")
---@class drag: druid.base_component
---@field druid druid_instance
local M = component.create("drag")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
-- Init drag and move the drag node on drag callback
self.drag = self.druid:new_drag("drag/root", function(_, dx, dy)
local position_x = gui.get(self.drag.node, "position.x")
local position_y = gui.get(self.drag.node, "position.y")
gui.set(self.drag.node, "position.x", position_x + dx)
gui.set(self.drag.node, "position.y", position_y + dy)
end)
-- Save start position for animation
self.start_position = gui.get_position(self.drag.node)
self.drag.on_drag_end:subscribe(function()
gui.animate(self.drag.node, "position", self.start_position, gui.EASING_OUTBACK, 0.3)
end)
end
return M

View File

@@ -0,0 +1,124 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
type: TYPE_TEMPLATE
id: "drag"
parent: "root"
inherit_alpha: true
template: "/example/templates/button_text_blue.gui"
}
nodes {
type: TYPE_BOX
id: "drag/root"
parent: "drag"
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "Drag Me"
id: "drag/text"
parent: "drag/root"
overridden_fields: 8
template_node_child: true
}
nodes {
position {
y: 300.0
}
size {
x: 300.0
y: 300.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "zone"
parent: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
position {
y: 100.0
}
size {
x: 300.0
y: 100.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_TEXT
text: "Drop Item Here"
font: "text_bold"
id: "text_hint"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "zone"
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
scale {
x: 2.0
y: 2.0
}
size {
x: 100.0
y: 100.0
}
type: TYPE_TEXT
text: "0"
font: "text_bold"
id: "text_counter"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "zone"
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,62 @@
local component = require("druid.component")
---@class drag_to_node: druid.base_component
---@field druid druid_instance
local M = component.create("drag_to_node")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.zone = self:get_node("zone")
self.counter = 0
self.text_counter = self:get_node("text_counter")
gui.set_text(self.text_counter, self.counter)
-- Init drag and move the drag node on drag callback
self.drag = self.druid:new_drag("drag/root", self.on_drag_start)
self.drag.on_drag_end:subscribe(self.on_drag_end)
-- Save start position for animation
self.start_position = gui.get_position(self.drag.node)
end
function M:on_drag_start(dx, dy, x, y, touch)
local position_x = gui.get(self.drag.node, "position.x")
local position_y = gui.get(self.drag.node, "position.y")
gui.set(self.drag.node, "position.x", position_x + dx)
gui.set(self.drag.node, "position.y", position_y + dy)
local is_pick_zone = gui.pick_node(self.zone, touch.x, touch.y)
self:on_hover_pick_zone(is_pick_zone)
end
function M:on_drag_end(x, y, touch)
gui.animate(self.drag.node, "position", self.start_position, gui.EASING_OUTBACK, 0.3)
local is_pick_zone = gui.pick_node(self.zone, touch.x, touch.y)
if is_pick_zone then
self.counter = self.counter + 1
gui.set_text(self.text_counter, self.counter)
self:on_drop_to_zone()
end
self:on_hover_pick_zone(false)
end
function M:on_hover_pick_zone(is_pick_zone)
local target_alpha = is_pick_zone and 1.5 or 1
gui.animate(self.zone, "color.w", target_alpha, gui.EASING_OUTSINE, 0.3)
end
function M:on_drop_to_zone()
gui.set_scale(self.zone, vmath.vector3(1.2))
gui.animate(self.zone, "scale", vmath.vector3(1), gui.EASING_OUTBACK, 0.3)
end
return M

View File

@@ -0,0 +1,721 @@
local const = require("druid.const")
local helper = require("druid.helper")
local M = {}
function M.get_examples()
---@type druid.example.data[]
return {
{
name_id = "ui_example_basic_button",
information_text_id = "ui_example_basic_button_description",
template = "basic_button",
root = "basic_button/root",
code_url = "example/examples/basic/button/basic_button.lua",
component_class = require("example.examples.basic.button.basic_button"),
properties_control = function(instance, properties_panel)
---@cast instance basic_button
local checkbox = properties_panel:add_checkbox("ui_enabled", false, function(value)
instance.button:set_enabled(value)
end)
checkbox:set_value(true)
end,
on_create = function(instance, output_log)
---@cast instance basic_button
instance.button.on_click:subscribe(function()
output_log:add_log_text("Button Clicked")
end)
end,
},
{
name_id = "ui_example_basic_button_double_click",
information_text_id = "ui_example_basic_button_double_click_description",
template = "basic_button_double_click",
root = "basic_button_double_click/root",
code_url = "example/examples/basic/button/basic_button_double_click.lua",
component_class = require("example.examples.basic.button.basic_button_double_click"),
on_create = function(instance, output_log)
---@cast instance basic_button_double_click
instance.button.on_click:subscribe(function()
output_log:add_log_text("Clicked")
end)
instance.button.on_double_click:subscribe(function()
output_log:add_log_text("Double Clicked")
end)
end,
},
{
name_id = "ui_example_basic_button_hold",
information_text_id = "ui_example_basic_button_hold_description",
template = "basic_button_hold",
root = "basic_button_hold/root",
code_url = "example/examples/basic/button/basic_button_hold.lua",
component_class = require("example.examples.basic.button.basic_button_hold"),
on_create = function(instance, output_log)
---@cast instance basic_button_hold
instance.button.on_click:subscribe(function()
output_log:add_log_text("Clicked")
end)
instance.button.on_long_click:subscribe(function()
output_log:add_log_text("On long click")
end)
end,
},
{
name_id = "ui_example_basic_text",
information_text_id = "ui_example_basic_text_description",
template = "basic_text",
root = "basic_text/root",
code_url = "example/examples/basic/text/basic_text.lua",
component_class = require("example.examples.basic.text.basic_text"),
properties_control = function(instance, properties_panel)
---@cast instance basic_text
local adjust_index = 1
local adjust_types = {
const.TEXT_ADJUST.DOWNSCALE,
const.TEXT_ADJUST.DOWNSCALE_LIMITED,
--const.TEXT_ADJUST.SCALE_THEN_SCROLL, -- works bad with container for some reason
--const.TEXT_ADJUST.SCROLL, -- works bad with container for some reason
const.TEXT_ADJUST.TRIM,
}
properties_panel:add_button("ui_adjust_next", function()
adjust_index = adjust_index + 1
if adjust_index > #adjust_types then
adjust_index = 1
end
instance.text:set_text_adjust(adjust_types[adjust_index], 0.5)
end)
local pivot_index = 1
local pivot_list = {
gui.PIVOT_CENTER,
gui.PIVOT_W,
gui.PIVOT_SW,
gui.PIVOT_S,
gui.PIVOT_SE,
gui.PIVOT_E,
gui.PIVOT_NE,
gui.PIVOT_N,
gui.PIVOT_NW,
}
---@cast instance rich_text_tags
properties_panel:add_button("ui_pivot_next", function()
pivot_index = pivot_index + 1
if pivot_index > #pivot_list then
pivot_index = 1
end
instance:set_pivot(pivot_list[pivot_index])
end)
end,
get_debug_info = function(instance)
---@cast instance multiline_text
local info = ""
info = info .. "Text Adjust: " .. instance.text.adjust_type .. "\n"
info = info .. "Pivot: " .. gui.get_pivot(instance.text.node) .. "\n"
return info
end
},
{
name_id = "ui_example_basic_multiline_text",
information_text_id = "ui_example_basic_multiline_text_description",
template = "multiline_text",
root = "multiline_text/root",
code_url = "example/examples/basic/text/multiline_text.lua",
component_class = require("example.examples.basic.text.multiline_text"),
properties_control = function(instance, properties_panel)
---@cast instance multiline_text
local adjust_index = 1
local adjust_types = {
const.TEXT_ADJUST.DOWNSCALE,
const.TEXT_ADJUST.DOWNSCALE_LIMITED,
--const.TEXT_ADJUST.SCALE_THEN_SCROLL, -- works bad with container for some reason
--const.TEXT_ADJUST.SCROLL, -- works bad with container for some reason
const.TEXT_ADJUST.TRIM,
}
properties_panel:add_button("ui_adjust_next", function()
adjust_index = adjust_index + 1
if adjust_index > #adjust_types then
adjust_index = 1
end
instance.text:set_text_adjust(adjust_types[adjust_index], 0.8)
end)
end,
get_debug_info = function(instance)
---@cast instance multiline_text
local info = ""
info = info .. "Text Adjust: " .. instance.text.adjust_type .. "\n"
info = info .. "Pivot: " .. gui.get_pivot(instance.text.node) .. "\n"
return info
end
},
{
name_id = "ui_example_basic_hover",
information_text_id = "ui_example_basic_hover_description",
template = "hover",
root = "hover/root",
code_url = "example/examples/basic/hover/hover.lua",
component_class = require("example.examples.basic.hover.hover"),
},
{
name_id = "ui_example_basic_drag",
information_text_id = "ui_example_basic_drag_description",
template = "drag",
root = "drag/root",
code_url = "example/examples/basic/drag/drag.lua",
component_class = require("example.examples.basic.drag.drag"),
},
{
name_id = "ui_example_basic_drag_to_node",
information_text_id = "ui_example_basic_drag_to_node_description",
template = "drag_to_node",
root = "drag_to_node/root",
code_url = "example/examples/basic/drag/drag_to_node.lua",
component_class = require("example.examples.basic.drag.drag_to_node"),
},
{
name_id = "ui_example_basic_slider",
information_text_id = "ui_example_basic_slider_description",
template = "basic_slider",
root = "basic_slider/root",
code_url = "example/examples/basic/slider/basic_slider.lua",
component_class = require("example.examples.basic.slider.basic_slider"),
on_create = function(instance, output_log)
---@cast instance basic_slider
instance.slider.on_change_value:subscribe(function(_, value)
local value = helper.round(value, 2)
output_log:add_log_text("Slider Value: " .. value)
end)
end,
},
{
name_id = "ui_example_basic_slider_vertical",
information_text_id = "ui_example_basic_slider_vertical_description",
template = "basic_slider_vertical",
root = "basic_slider_vertical/root",
code_url = "example/examples/basic/slider/basic_slider_vertical.lua",
component_class = require("example.examples.basic.slider.basic_slider_vertical"),
on_create = function(instance, output_log)
---@cast instance basic_slider_vertical
instance.slider.on_change_value:subscribe(function(_, value)
local value = helper.round(value, 2)
output_log:add_log_text("Slider Value: " .. value)
end)
end,
},
{
name_id = "ui_example_basic_slider_stepped",
information_text_id = "ui_example_basic_slider_stepped_description",
template = "basic_slider_stepped",
root = "basic_slider_stepped/root",
code_url = "example/examples/basic/slider/basic_slider_stepped.lua",
component_class = require("example.examples.basic.slider.basic_slider_stepped"),
on_create = function(instance, output_log)
---@cast instance basic_slider
instance.slider.on_change_value:subscribe(function(_, value)
local value = helper.round(value, 2)
output_log:add_log_text("Slider Value: " .. value)
end)
end,
},
{
name_id = "ui_example_basic_progress_bar",
information_text_id = "ui_example_basic_progress_bar_description",
template = "basic_progress_bar",
root = "basic_progress_bar/root",
code_url = "example/examples/basic/progress_bar/basic_progress_bar.lua",
component_class = require("example.examples.basic.progress_bar.basic_progress_bar"),
properties_control = function(instance, properties_panel)
---@cast instance basic_progress_bar
properties_panel:add_slider("ui_value", 1, function(value)
instance:set_value(value)
end)
end,
},
{
name_id = "ui_example_basic_progress_bar_slice9",
information_text_id = "ui_example_basic_progress_bar_slice9_description",
template = "basic_progress_bar_slice9",
root = "basic_progress_bar_slice9/root",
code_url = "example/examples/basic/progress_bar/basic_progress_bar_slice9.lua",
component_class = require("example.examples.basic.progress_bar.basic_progress_bar_slice9"),
properties_control = function(instance, properties_panel)
---@cast instance basic_progress_bar_slice9
properties_panel:add_slider("ui_value", 1, function(value)
instance:set_value(value)
end)
end,
},
{
name_id = "ui_example_basic_blocker",
information_text_id = "ui_example_basic_blocker_description",
template = "basic_blocker",
root = "basic_blocker/root",
code_url = "example/examples/basic/blocker/basic_blocker.lua",
component_class = require("example.examples.basic.blocker.basic_blocker"),
on_create = function(instance, output_log)
---@cast instance basic_blocker
instance.button_root.on_click:subscribe(function()
output_log:add_log_text("Root Clicked")
end)
instance.button.on_click:subscribe(function()
output_log:add_log_text("Button Clicked")
end)
end,
},
{
name_id = "ui_example_basic_back_handler",
information_text_id = "ui_example_basic_back_handler_description",
template = "basic_back_handler",
root = "basic_back_handler/root",
code_url = "example/examples/basic/back_handler/basic_back_handler.lua",
component_class = require("example.examples.basic.back_handler.basic_back_handler"),
},
{
name_id = "ui_example_basic_timer",
information_text_id = "ui_example_basic_timer_description",
template = "basic_timer",
root = "basic_timer/root",
code_url = "example/examples/basic/timer/basic_timer.lua",
component_class = require("example.examples.basic.timer.basic_timer"),
on_create = function(instance, output_log)
---@cast instance basic_timer
instance.on_cycle_end:subscribe(function()
output_log:add_log_text("Timer Cycle End")
end)
end,
},
{
name_id = "ui_example_basic_hotkey",
information_text_id = "ui_example_basic_hotkey_description",
template = "basic_hotkey",
root = "basic_hotkey/root",
code_url = "example/examples/basic/hotkey/basic_hotkey.lua",
component_class = require("example.examples.basic.hotkey.basic_hotkey"),
on_create = function(instance, output_log)
---@cast instance basic_hotkey
instance.hotkey.on_hotkey_released:subscribe(function()
output_log:add_log_text("Hotkey Released")
end)
end,
},
{
name_id = "ui_example_basic_scroll",
information_text_id = "ui_example_basic_scroll_description",
template = "scroll",
root = "scroll/root",
code_url = "example/examples/basic/scroll/scroll.lua",
component_class = require("example.examples.basic.scroll.scroll"),
on_create = function(instance, output_log)
---@cast instance scroll
instance.button_tutorial.on_click:subscribe(function()
output_log:add_log_text("Button Tutorial Clicked")
end)
instance.button_stencil.on_click:subscribe(function()
output_log:add_log_text("Button Stencil Clicked")
end)
end,
properties_control = function(instance, properties_panel)
---@cast instance scroll
local is_stretch = instance.scroll.style.EXTRA_STRETCH_SIZE > 0
properties_panel:add_checkbox("ui_elastic_scroll", is_stretch, function(value)
instance.scroll:set_extra_stretch_size(value and 100 or 0)
end)
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
end,
get_debug_info = function(instance)
---@cast instance scroll
local info = ""
local s = instance.scroll
info = info .. "View Size Y: " .. gui.get(s.view_node, "size.y") .. "\n"
info = info .. "Content Size Y: " .. gui.get(s.content_node, "size.y") .. "\n"
info = info .. "Content position Y: " .. math.ceil(s.position.y) .. "\n"
info = info .. "Content Range Y: " .. s.available_pos.y .. " - " .. s.available_pos.w .. "\n"
return info
end
},
{
name_id = "ui_example_basic_scroll_slider",
information_text_id = "ui_example_basic_scroll_slider_description",
template = "scroll_slider",
root = "scroll_slider/root",
code_url = "example/examples/basic/scroll_slider/scroll_slider.lua",
component_class = require("example.examples.basic.scroll_slider.scroll_slider"),
get_debug_info = function(instance)
---@cast instance scroll_slider
local info = ""
local s = instance.scroll
info = info .. "View Size Y: " .. gui.get(s.view_node, "size.y") .. "\n"
info = info .. "Content Size Y: " .. gui.get(s.content_node, "size.y") .. "\n"
info = info .. "Content position Y: " .. math.ceil(s.position.y) .. "\n"
info = info .. "Content Range Y: " .. s.available_pos.y .. " - " .. s.available_pos.w .. "\n"
return info
end
},
{
name_id = "ui_example_basic_grid",
information_text_id = "ui_example_basic_grid_description",
template = "grid",
root = "grid/root",
code_url = "example/examples/basic/grid/grid.lua",
component_class = require("example.examples.basic.grid.grid"),
properties_control = function(instance, properties_panel)
---@cast instance grid
local slider = properties_panel:add_slider("ui_grid_in_row", 0.3, function(value)
local in_row_amount = math.ceil(value * 10)
in_row_amount = math.max(1, in_row_amount)
instance.grid:set_in_row(in_row_amount)
end)
slider:set_text_function(function(value)
return tostring(math.ceil(value * 10))
end)
properties_panel:add_button("ui_add_element", function()
if #instance.created_nodes >= 36 then
return
end
instance:add_element()
end)
properties_panel:add_button("ui_remove_element", function()
instance:remove_element()
end)
properties_panel:add_button("ui_clear_elements", function()
instance:clear()
end)
end,
},
{
name_id = "ui_example_basic_scroll_bind_grid",
information_text_id = "ui_example_basic_scroll_bind_grid_description",
template = "scroll_bind_grid",
root = "scroll_bind_grid/root",
code_url = "example/examples/basic/scroll_bind_grid/scroll_bind_grid.lua",
component_class = require("example.examples.basic.scroll_bind_grid.scroll_bind_grid"),
properties_control = function(instance, properties_panel)
---@cast instance scroll_bind_grid
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
properties_panel:add_button("ui_add_element", function()
if #instance.created_nodes >= 100 then
return
end
instance:add_element()
end)
properties_panel:add_button("ui_remove_element", function()
instance:remove_element()
end)
properties_panel:add_button("ui_clear_elements", function()
instance:clear()
end)
end,
get_debug_info = function(instance)
---@cast instance scroll_bind_grid
local info = ""
local s = instance.scroll
local view_node_size = gui.get(s.view_node, "size.y")
local scroll_position = -s.position
local scroll_bottom_position = vmath.vector3(scroll_position.x, scroll_position.y - view_node_size, scroll_position.z)
info = info .. "View Size Y: " .. gui.get(s.view_node, "size.y") .. "\n"
info = info .. "Content Size Y: " .. gui.get(s.content_node, "size.y") .. "\n"
info = info .. "Content position Y: " .. math.ceil(s.position.y) .. "\n"
info = info .. "Content Range Y: " .. s.available_pos.y .. " - " .. s.available_pos.w .. "\n"
info = info .. "Grid Items: " .. #instance.grid.nodes .. "\n"
info = info .. "Grid Item Size: " .. instance.grid.node_size.x .. " x " .. instance.grid.node_size.y .. "\n"
info = info .. "Top Scroll Pos Grid Index: " .. instance.grid:get_index(scroll_position) .. "\n"
info = info .. "Bottm Scroll Pos Grid Index: " .. instance.grid:get_index(scroll_bottom_position) .. "\n"
return info
end
},
{
name_id = "ui_example_basic_scroll_bind_grid_horizontal",
information_text_id = "ui_example_basic_scroll_bind_grid_horizontal_description",
template = "scroll_bind_grid_horizontal",
root = "scroll_bind_grid_horizontal/root",
code_url = "example/examples/basic/scroll_bind_grid/scroll_bind_grid_horizontal.lua",
component_class = require("example.examples.basic.scroll_bind_grid.scroll_bind_grid_horizontal"),
properties_control = function(instance, properties_panel)
---@cast instance scroll_bind_grid_horizontal
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
properties_panel:add_button("ui_add_element", function()
if #instance.created_nodes >= 100 then
return
end
instance:add_element()
end)
properties_panel:add_button("ui_remove_element", function()
instance:remove_element()
end)
properties_panel:add_button("ui_clear_elements", function()
instance:clear()
end)
end,
get_debug_info = function(instance)
---@cast instance scroll_bind_grid_horizontal
local info = ""
local s = instance.scroll
local view_node_size = gui.get(s.view_node, "size.x")
local scroll_position = -s.position
local scroll_bottom_position = vmath.vector3(scroll_position.x + view_node_size, scroll_position.y, scroll_position.z)
info = info .. "View Size X: " .. gui.get(s.view_node, "size.x") .. "\n"
info = info .. "Content Size X: " .. gui.get(s.content_node, "size.x") .. "\n"
info = info .. "Content position X: " .. math.ceil(s.position.x) .. "\n"
info = info .. "Content Range X: " .. s.available_pos.x .. " - " .. s.available_pos.z .. "\n"
info = info .. "Grid Items: " .. #instance.grid.nodes .. "\n"
info = info .. "Grid Item Size: " .. instance.grid.node_size.x .. " x " .. instance.grid.node_size.y .. "\n"
info = info .. "Left Scroll Pos Grid Index: " .. instance.grid:get_index(scroll_position) .. "\n"
info = info .. "Right Scroll Pos Grid Index: " .. instance.grid:get_index(scroll_bottom_position) .. "\n"
return info
end
},
{
name_id = "ui_example_basic_scroll_bind_grid_points",
information_text_id = "ui_example_basic_scroll_bind_grid_points_description",
template = "scroll_bind_grid_points",
root = "scroll_bind_grid_points/root",
code_url = "example/examples/basic/scroll_bind_grid/scroll_bind_grid_points.lua",
component_class = require("example.examples.basic.scroll_bind_grid.scroll_bind_grid_points"),
properties_control = function(instance, properties_panel)
---@cast instance scroll_bind_grid_points
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
properties_panel:add_button("ui_add_element", function()
if #instance.created_nodes >= 100 then
return
end
instance:add_element()
end)
properties_panel:add_button("ui_remove_element", function()
instance:remove_element()
end)
properties_panel:add_button("ui_clear_elements", function()
instance:clear()
end)
end,
get_debug_info = function(instance)
---@cast instance scroll_bind_grid_points
local info = ""
local s = instance.scroll
local view_node_size = gui.get(s.view_node, "size.y")
local scroll_position = -s.position
local scroll_bottom_position = vmath.vector3(scroll_position.x, scroll_position.y - view_node_size, scroll_position.z)
info = info .. "View Size Y: " .. gui.get(s.view_node, "size.y") .. "\n"
info = info .. "Content Size Y: " .. gui.get(s.content_node, "size.y") .. "\n"
info = info .. "Content position Y: " .. math.ceil(s.position.y) .. "\n"
info = info .. "Content Range Y: " .. s.available_pos.y .. " - " .. s.available_pos.w .. "\n"
info = info .. "Grid Items: " .. #instance.grid.nodes .. "\n"
info = info .. "Grid Item Size: " .. instance.grid.node_size.x .. " x " .. instance.grid.node_size.y .. "\n"
info = info .. "Top Scroll Pos Grid Index: " .. instance.grid:get_index(scroll_position) .. "\n"
info = info .. "Bottm Scroll Pos Grid Index: " .. instance.grid:get_index(scroll_bottom_position) .. "\n"
return info
end
},
{
name_id = "ui_example_basic_input",
information_text_id = "ui_example_basic_input_description",
template = "basic_input",
root = "basic_input/root",
code_url = "example/examples/basic/input/basic_input.lua",
component_class = require("example.examples.basic.input.basic_input"),
on_create = function(instance, output_log)
---@cast instance basic_input
instance.input.on_input_unselect:subscribe(function(_, text)
output_log:add_log_text("Input: " .. text)
end)
instance.input_2.on_input_unselect:subscribe(function(_, text)
output_log:add_log_text("Input 2: " .. text)
end)
end,
},
{
name_id = "ui_example_input_password",
information_text_id = "ui_example_input_password_description",
template = "input_password",
root = "input_password/root",
code_url = "example/examples/basic/input/input_password.lua",
component_class = require("example.examples.basic.input.input_password"),
on_create = function(instance, output_log)
---@cast instance input_password
instance.input.on_input_unselect:subscribe(function(_, text)
output_log:add_log_text("Input: " .. text)
end)
end,
},
{
name_id = "ui_example_basic_rich_input",
information_text_id = "ui_example_basic_rich_input_description",
template = "basic_rich_input",
root = "basic_rich_input/root",
code_url = "example/examples/basic/input/rich_input.lua",
component_class = require("example.examples.basic.input.rich_input"),
on_create = function(instance, output_log)
---@cast instance rich_input
instance.rich_input.input.on_input_unselect:subscribe(function(_, text)
output_log:add_log_text("Input: " .. text)
end)
instance.rich_input_2.input.on_input_unselect:subscribe(function(_, text)
output_log:add_log_text("Input 2: " .. text)
end)
end,
},
{
name_id = "ui_example_basic_rich_text",
information_text_id = "ui_example_basic_rich_text_description",
template = "basic_rich_text",
root = "basic_rich_text/root",
code_url = "example/examples/basic/rich_text/basic_rich_text.lua",
component_class = require("example.examples.basic.rich_text.basic_rich_text"),
},
{
name_id = "ui_example_rich_text_tags",
information_text_id = "ui_example_rich_text_tags_description",
template = "rich_text_tags",
root = "rich_text_tags/root",
code_url = "example/examples/basic/rich_text/rich_text_tags.lua",
component_class = require("example.examples.basic.rich_text.rich_text_tags"),
properties_control = function(instance, properties_panel)
local pivot_index = 1
local pivot_list = {
gui.PIVOT_CENTER,
gui.PIVOT_W,
gui.PIVOT_SW,
gui.PIVOT_S,
gui.PIVOT_SE,
gui.PIVOT_E,
gui.PIVOT_NE,
gui.PIVOT_N,
gui.PIVOT_NW,
}
---@cast instance rich_text_tags
properties_panel:add_button("ui_pivot_next", function()
pivot_index = pivot_index + 1
if pivot_index > #pivot_list then
pivot_index = 1
end
instance:set_pivot(pivot_list[pivot_index])
end)
end
},
--{
-- name_id = "ui_example_rich_text_tags_custom",
-- information_text_id = "ui_example_rich_text_tags_custom_description",
-- template = "rich_text_tags_custom",
-- root = "rich_text_tags_custom/root",
-- code_url = "example/examples/basic/rich_text/rich_text_tags_custom.lua",
-- component_class = require("example.examples.basic.rich_text.rich_text_tags_custom"),
-- properties_control = function(instance, properties_panel)
-- local pivot_index = 1
-- local pivot_list = {
-- gui.PIVOT_CENTER,
-- gui.PIVOT_W,
-- gui.PIVOT_SW,
-- gui.PIVOT_S,
-- gui.PIVOT_SE,
-- gui.PIVOT_E,
-- gui.PIVOT_NE,
-- gui.PIVOT_N,
-- gui.PIVOT_NW,
-- }
-- ---@cast instance rich_text_tags_custom
-- properties_panel:add_button("ui_pivot_next", function()
-- pivot_index = pivot_index + 1
-- if pivot_index > #pivot_list then
-- pivot_index = 1
-- end
-- instance:set_pivot(pivot_list[pivot_index])
-- end)
-- end,
-- on_create = function(instance, output_log)
-- ---@cast instance rich_text_tags_custom
-- instance.on_link_click:subscribe(function(text)
-- output_log:add_log_text("Custom Link: " .. text)
-- end)
-- end
--},
{
name_id = "ui_example_basic_swipe",
information_text_id = "ui_example_basic_swipe_description",
template = "basic_swipe",
root = "basic_swipe/root",
code_url = "example/examples/basic/swipe/basic_swipe.lua",
component_class = require("example.examples.basic.swipe.basic_swipe"),
on_create = function(instance, output_log)
---@cast instance basic_swipe
instance.swipe.on_swipe:subscribe(function(_, side, dist, delta_time)
output_log:add_log_text("Swipe Side: " .. side)
end)
end,
},
{
name_id = "ui_example_basic_checkbox",
information_text_id = "ui_example_basic_checkbox_description",
template = "basic_checkbox",
root = "basic_checkbox/root",
code_url = "example/examples/basic/checkbox/basic_checkbox.lua",
component_class = require("example.examples.basic.checkbox.basic_checkbox"),
on_create = function(instance, output_log)
---@cast instance basic_checkbox
instance.button.on_click:subscribe(function()
output_log:add_log_text("Checkbox Clicked: " .. tostring(instance.is_enabled))
end)
end,
},
}
end
return M

View File

@@ -0,0 +1,320 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 300.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 600.0
y: 600.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "grid"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 100.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "grid"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 90.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.5
y: 1.5
z: 1.0
w: 1.0
}
size {
x: 50.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "prefab"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,66 @@
local component = require("druid.component")
---@class grid: druid.base_component
---@field grid druid.static_grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("grid")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.created_nodes = {}
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.grid = self.druid:new_static_grid("grid", "prefab", 3)
for index = 1, 9 do
self:add_element()
end
end
function M:on_remove()
self:clear()
end
function M:add_element()
local prefab_nodes = gui.clone_tree(self.prefab)
local root = prefab_nodes[self:get_template() .. "/prefab"]
local text = prefab_nodes[self:get_template() .. "/text"]
table.insert(self.created_nodes, root)
gui.set_text(text, #self.created_nodes)
gui.set_enabled(root, true)
self.grid:add(root)
end
function M:remove_element()
local last_node = table.remove(self.created_nodes)
if last_node == nil then
return
end
gui.delete_node(last_node)
local grid_index = self.grid:get_index_by_node(last_node)
self.grid:remove(grid_index)
end
function M:clear()
for _, node in ipairs(self.created_nodes) do
gui.delete_node(node)
end
self.created_nodes = {}
self.grid:clear()
end
return M

View File

@@ -0,0 +1,36 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
nodes {
size {
x: 200.0
y: 100.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
visible: false
}
nodes {
size {
x: 700.0
y: 100.0
}
color {
x: 0.522
y: 0.522
z: 0.522
}
type: TYPE_TEXT
text: "Press \"SHIFT\" + \"X\" to trigger hotkey"
font: "text_bold"
id: "text"
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,29 @@
local hotkey = require("druid.extended.hotkey")
local component = require("druid.component")
---@class basic_hotkey: druid.base_component
---@field druid druid_instance
---@field root node
---@field text druid.text
local M = component.create("basic_hotkey")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.hotkey = self.druid:new(hotkey, { "key_lshift", "key_x" }, self.on_hotkey)
end
function M:on_hotkey()
gui.animate(self.root, gui.PROP_SCALE, vmath.vector3(1.2), gui.EASING_OUTELASTIC, 0.5, 0, function()
gui.animate(self.root, gui.PROP_SCALE, vmath.vector3(1), gui.EASING_OUTELASTIC, 0.5)
end)
end
return M

View File

@@ -0,0 +1,410 @@
script: ""
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 100.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button_mouse_hover"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_green.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button_mouse_hover/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button_mouse_hover"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Mouse Hover"
font: "text_bold"
id: "button_mouse_hover/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button_mouse_hover/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 8
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: -100.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button_mobile_hover"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_green.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button_mobile_hover/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button_mobile_hover"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Mobile Hover"
font: "text_bold"
id: "button_mobile_hover/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button_mobile_hover/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 8
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,34 @@
local component = require("druid.component")
---@class hover: druid.base_component
---@field druid druid_instance
---@field hover druid.hover
---@field hover_pressed druid.hover
local M = component.create("hover")
---Color: #E6DF9F
local HOVERED_COLOR = vmath.vector4(230/255, 223/255, 159/255, 1.0)
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
-- Default hover callback is `on_hover`, designed for mobile devices
-- It's only hover if touch action is above the node
self.hover_default = self.druid:new_hover("button_mobile_hover/root", self.on_hover)
-- If you wan't to use mouse hover, you can use `on_mouse_hover` callback
-- It's checks the `action_id` == nil (mouse events)
self.hover = self.druid:new_hover("button_mouse_hover/root", nil, self.on_hover)
self.default_color = gui.get_color(self.hover.node)
end
function M:on_hover(is_hover, hover_instance)
gui.animate(hover_instance.node, "color", is_hover and HOVERED_COLOR or self.default_color, gui.EASING_LINEAR, 0.2)
end
return M

View File

@@ -0,0 +1,406 @@
script: ""
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "input"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/input.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 80.0
z: 0.0
w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/rect_round2_width1"
id: "input/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "input"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -240.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 480.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Tap me to input"
font: "text_bold"
id: "input/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "input/root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: -150.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "input_2"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/input.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 80.0
z: 0.0
w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/rect_round2_width1"
id: "input_2/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "input_2"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 480.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Tap me to input"
font: "text_bold"
id: "input_2/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "input_2/root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 1
overridden_fields: 14
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,26 @@
local component = require("druid.component")
local input = require("druid.extended.input")
---@class basic_input: druid.base_component
---@field druid druid_instance
---@field input druid.input
local M = component.create("basic_input")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.input = self.druid:new(input, "input/root", "input/text")
self.input_2 = self.druid:new(input, "input_2/root", "input_2/text") --[[@as druid.input]]
-- you can set custom style for input and their components
-- Check in the example, how long tap on bottom input will erase text
self.input_2.style.IS_LONGTAP_ERASE = true
self.input_2.button.style.AUTOHOLD_TRIGGER = 1.5
end
return M

View File

@@ -0,0 +1,33 @@
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
type: TYPE_TEMPLATE
id: "input"
parent: "root"
inherit_alpha: true
template: "/example/templates/input.gui"
}
nodes {
type: TYPE_BOX
id: "input/root"
parent: "input"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "input/text"
parent: "input/root"
overridden_fields: 1
overridden_fields: 14
template_node_child: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,25 @@
local component = require("druid.component")
local input = require("druid.extended.input")
---@class input_password: druid.component
---@field druid druid_instance
---@field root node
local M = component.create("input_password")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.input = self.druid:new(input, "input/root", "input/text", gui.KEYBOARD_TYPE_PASSWORD)
self.input:set_text("")
self.input.on_input_unselect:subscribe(function(_, text)
print(text)
end)
end
return M

View File

@@ -0,0 +1,918 @@
script: ""
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "rich_input"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/rich_input.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 80.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "rich_input/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_input"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 80.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/rect_round2_width1"
id: "rich_input/button"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_input/root"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -240.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 480.0
y: 60.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Placeholder"
font: "text_bold"
id: "rich_input/placeholder_text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 0.4
y: 0.4
z: 0.4
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "rich_input/button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 1
overridden_fields: 14
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -240.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 480.0
y: 60.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "User input"
font: "text_bold"
id: "rich_input/input_text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
outline {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "rich_input/button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 1
overridden_fields: 14
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 16.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_16"
id: "rich_input/cursor_node"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_input/button"
layer: ""
inherit_alpha: true
slice9 {
x: 8.0
y: 8.0
z: 8.0
w: 8.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 0.5
overridden_fields: 1
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 4.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.2
y: 1.2
z: 1.0
w: 1.0
}
size {
x: 20.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "|"
font: "text_bold"
id: "rich_input/cursor_text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "rich_input/cursor_node"
layer: ""
inherit_alpha: false
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: -150.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "rich_input_2"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/rich_input.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 80.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "rich_input_2/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_input_2"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 80.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/rect_round2_width1"
id: "rich_input_2/button"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_input_2/root"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 480.0
y: 60.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Placeholder"
font: "text_bold"
id: "rich_input_2/placeholder_text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 0.4
y: 0.4
z: 0.4
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "rich_input_2/button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 480.0
y: 60.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "User input"
font: "text_bold"
id: "rich_input_2/input_text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "rich_input_2/button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 16.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_16"
id: "rich_input_2/cursor_node"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "rich_input_2/button"
layer: ""
inherit_alpha: true
slice9 {
x: 8.0
y: 8.0
z: 8.0
w: 8.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 0.5
overridden_fields: 1
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 4.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.2
y: 1.2
z: 1.0
w: 1.0
}
size {
x: 20.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "|"
font: "text_bold"
id: "rich_input_2/cursor_text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "rich_input_2/cursor_node"
layer: ""
inherit_alpha: false
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,22 @@
local component = require("druid.component")
local rich_input = require("druid.custom.rich_input.rich_input")
---@class rich_input: druid.base_component
---@field druid druid_instance
---@field rich_input druid.rich_input
local M = component.create("rich_input")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.rich_input = self.druid:new(rich_input, "rich_input") --[[@as druid.rich_input]]
self.rich_input:set_placeholder("Enter text")
self.rich_input_2 = self.druid:new(rich_input, "rich_input_2") --[[@as druid.rich_input]]
self.rich_input_2:set_placeholder("Enter text")
end
return M

View File

@@ -0,0 +1,89 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -150.0
}
size {
x: 300.0
y: 32.0
}
color {
x: 0.463
y: 0.475
z: 0.49
}
type: TYPE_BOX
texture: "druid/pixel"
id: "progress_bar_back"
pivot: PIVOT_W
parent: "root"
inherit_alpha: true
}
nodes {
size {
x: 300.0
y: 32.0
}
color {
x: 0.631
y: 0.843
z: 0.961
}
type: TYPE_BOX
texture: "druid/pixel"
id: "progress_bar_fill"
pivot: PIVOT_W
parent: "progress_bar_back"
inherit_alpha: true
}
nodes {
position {
y: 50.0
}
size {
x: 150.0
y: 50.0
}
color {
x: 0.722
y: 0.741
z: 0.761
}
type: TYPE_TEXT
text: "0 %"
font: "text_bold"
id: "progress_value"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,28 @@
local component = require("druid.component")
local progress = require("druid.extended.progress")
---@class basic_progress_bar: druid.base_component
---@field druid druid_instance
---@field progress druid.progress
local M = component.create("basic_progress_bar")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.progress = self.druid:new(progress, "progress_bar_fill", "x")
self.text_value = self:get_node("progress_value")
self:set_value(self.progress:get())
end
function M:set_value(value)
gui.set_text(self.text_value, math.ceil(value * 100) .. "%")
self.progress:set_to(value)
end
return M

View File

@@ -0,0 +1,101 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -150.0
}
size {
x: 300.0
y: 32.0
}
color {
x: 0.463
y: 0.475
z: 0.49
}
type: TYPE_BOX
texture: "druid/ui_circle_16"
id: "progress_bar_back"
pivot: PIVOT_W
parent: "root"
inherit_alpha: true
slice9 {
x: 8.0
y: 8.0
z: 8.0
w: 8.0
}
}
nodes {
size {
x: 300.0
y: 32.0
}
color {
x: 0.631
y: 0.843
z: 0.961
}
type: TYPE_BOX
texture: "druid/ui_circle_16"
id: "progress_bar_fill"
pivot: PIVOT_W
parent: "progress_bar_back"
inherit_alpha: true
slice9 {
x: 8.0
y: 8.0
z: 8.0
w: 8.0
}
}
nodes {
position {
y: 50.0
}
size {
x: 150.0
y: 50.0
}
color {
x: 0.722
y: 0.741
z: 0.761
}
type: TYPE_TEXT
text: "0 %"
font: "text_bold"
id: "progress_value"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,28 @@
local component = require("druid.component")
local progress = require("druid.extended.progress")
---@class basic_progress_bar_slice9: druid.base_component
---@field druid druid_instance
---@field progress druid.progress
local M = component.create("basic_progress_bar_slice9")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.progress = self.druid:new(progress, "progress_bar_fill", "x")
self.text_value = self:get_node("progress_value")
self:set_value(self.progress:get())
end
function M:set_value(value)
gui.set_text(self.text_value, math.ceil(value * 100) .. "%")
self.progress:set_to(value)
end
return M

View File

@@ -0,0 +1,46 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Hello I\'m a Rich Text!"
font: "text_regular"
id: "text"
pivot: PIVOT_W
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,18 @@
local component = require("druid.component")
local rich_text = require("druid.custom.rich_text.rich_text")
---@class basic_rich_text: druid.base_component
---@field druid druid_instance
---@field rich_text druid.rich_text
local M = component.create("basic_rich_text")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.druid:new(rich_text, "text", "Hello, I'm a <font=text_bold><color=E48155>Rich Text</font></color>!")
end
return M

View File

@@ -0,0 +1,167 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
textures {
name: "druid_logo"
texture: "/example/assets/druid_logo.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
size {
x: 400.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "background"
parent: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
position {
x: -200.0
y: 400.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_color"
pivot: PIVOT_W
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -200.0
y: 200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_breaks"
pivot: PIVOT_W
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: 200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_size"
pivot: PIVOT_SE
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -200.0
y: -200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_font"
pivot: PIVOT_W
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -200.0
y: -400.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_image"
pivot: PIVOT_W
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,76 @@
local component = require("druid.component")
local rich_text = require("druid.custom.rich_text.rich_text")
local helper = require("druid.helper")
---@class rich_text_tags: druid.base_component
---@field druid druid_instance
---@field rich_text druid.rich_text
local M = component.create("rich_text_tags")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.rich_text_color = self.druid:new(rich_text, "rich_text_color") --[[@as druid.rich_text]]
self.rich_text_color:set_text("Hello, I'm a <color=E48155>Rich Text</color> and it's <color=8ED59E>nested <color=A1D7F5>color</color> tag</color>")
self.rich_text_font = self.druid:new(rich_text, "rich_text_font") --[[@as druid.rich_text]]
self.rich_text_font:set_text("Hello, I'm a <font=text_bold>Rich Text</font> and this is <font=text_bold><color=8ED59E>bold text</color></font>")
self.rich_text_size = self.druid:new(rich_text, "rich_text_size") --[[@as druid.rich_text]]
self.rich_text_size:set_text("Hello, I'm have <size=1.15><font=text_bold>East Pivot</font></size> and <size=0.85><font=text_bold>different text scale</font></size>")
self.rich_text_breaks = self.druid:new(rich_text, "rich_text_breaks") --[[@as druid.rich_text]]
self.rich_text_breaks:set_text("Hello, I'm Rich Text<br/>With \"<color=E6DF9F>Line Breaks</color>\"\nEnabled in GUI")
self.rich_text_image = self.druid:new(rich_text, "rich_text_image") --[[@as druid.rich_text]]
self.rich_text_image:set_text("Hello, I'm<img=druid:icon_cross,32/>Rich Text <img=druid_logo:icon_druid,48/> <color=8ED59E><img=druid_logo:icon_druid,48/></color> <color=F49B9B><img=druid_logo:icon_druid,48/></color>")
self.position = {
[self.rich_text_color] = gui.get_position(self.rich_text_color.root),
[self.rich_text_font] = gui.get_position(self.rich_text_font.root),
[self.rich_text_size] = gui.get_position(self.rich_text_size.root),
[self.rich_text_breaks] = gui.get_position(self.rich_text_breaks.root),
[self.rich_text_image] = gui.get_position(self.rich_text_image.root),
}
-- Adjust positions with pivots
for rich_text, pos in pairs(self.position) do
local size_x = gui.get(rich_text.root, "size.x")
local size_y = gui.get(rich_text.root, "size.y")
local parent_pivot = gui.get_pivot(rich_text.root)
local pivot_offset = helper.get_pivot_offset(parent_pivot)
local offset_x = size_x * pivot_offset.x
local offset_y = size_y * pivot_offset.y
pos.x = pos.x - offset_x
pos.y = pos.y - offset_y
end
end
function M:set_pivot(pivot)
local rich_texts = {
self.rich_text_color,
self.rich_text_font,
self.rich_text_size,
self.rich_text_breaks,
self.rich_text_image,
}
for _, rich_text in ipairs(rich_texts) do
gui.set_pivot(rich_text.root, pivot)
local pos = self.position[rich_text]
local size_x = gui.get(rich_text.root, "size.x")
local size_y = gui.get(rich_text.root, "size.y")
local parent_pivot = gui.get_pivot(rich_text.root)
local pivot_offset = helper.get_pivot_offset(parent_pivot)
local offset_x = size_x * pivot_offset.x
local offset_y = size_y * pivot_offset.y
gui.set_position(rich_text.root, vmath.vector3(pos.x + offset_x, pos.y + offset_y, pos.z))
rich_text:set_text(rich_text:get_text())
end
end
return M

View File

@@ -0,0 +1,92 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
y: 200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_link"
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_characters"
pivot: PIVOT_W
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -200.0
y: -200.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_regular"
id: "rich_text_custom"
pivot: PIVOT_W
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,67 @@
local component = require("druid.component")
local rich_text = require("druid.custom.rich_text.rich_text")
local helper = require("druid.helper")
local event = require("druid.event")
---@class rich_text_tags_custom: druid.base_component
---@field druid druid_instance
---@field rich_text druid.rich_text
local M = component.create("rich_text_tags_custom")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
do -- Init rich text with links example
self.rich_text_link = self.druid:new(rich_text, "rich_text_link") --[[@as druid.rich_text]]
self.rich_text_link:set_text("Hello, I'm a <custom_link><color=A1D7F5>Custom Link</color></custom_link>")
local tagged = self.rich_text_link:tagged("custom_link")
for index = 1, #tagged do
local word = tagged[index]
self.druid:new_button(word.node, function()
self.on_link_click:trigger(word.text)
end)
end
end
self.rich_text_characters = self.druid:new(rich_text, "rich_text_characters") --[[@as druid.rich_text]]
self.rich_text_characters:set_text("Hello, I'm a have a splitted characters")
self.rich_text_custom = self.druid:new(rich_text, "rich_text_custom") --[[@as druid.rich_text]]
self.rich_text_custom:set_text("Hello, I'm have <size=1.25><font=text_bold>South Text Pivot</font></size> to adjust <size=0.75><font=text_bold>different text scale</font></size>")
self.position = {
[self.rich_text_link] = gui.get_position(self.rich_text_link.root),
[self.rich_text_characters] = gui.get_position(self.rich_text_characters.root),
[self.rich_text_custom] = gui.get_position(self.rich_text_custom.root),
}
self.on_link_click = event.create()
end
function M:set_pivot(pivot)
local pivot_offset = helper.get_pivot_offset(pivot)
local rich_texts = {
self.rich_text_link,
self.rich_text_characters,
self.rich_text_custom,
}
for _, rich_text in ipairs(rich_texts) do
gui.set_pivot(rich_text.root, pivot)
local pos = self.position[rich_text]
local size_x = gui.get(rich_text.root, "size.x")
local size_y = gui.get(rich_text.root, "size.y")
local offset_x = size_x * pivot_offset.x
local offset_y = size_y * pivot_offset.y
gui.set_position(rich_text.root, vmath.vector3(pos.x + offset_x, pos.y + offset_y, pos.z))
rich_text:set_text(rich_text:get_text())
end
end
return M

View File

@@ -0,0 +1,876 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 400.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "scroll_view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 500.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 400.0
y: 1700.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "scroll_content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "scroll_view"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: -946.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button_tutorial"
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_green.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button_tutorial/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button_tutorial"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "I do nothing!"
font: "text_bold"
id: "button_tutorial/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button_tutorial/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 8
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -185.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 900.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "To setup scroll in your scene\n"
"\n"
"- Place \"View\" box node\n"
"\n"
"- Put \"Content\" node inside \"Scroll View\"\n"
"\n"
"- Init scroll with `druid:new_scroll(\"view\", \"content\")"
font: "text_bold"
id: "ui_scroll_text_1"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -185.0
y: -482.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 400.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Now your content node can be scrollable in View node borders. In this example the content node contains this tutorial text"
font: "text_bold"
id: "ui_scroll_text_2"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -185.0
y: -713.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 400.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "All other components are placed as usual.\n"
"\n"
"For example, button:"
font: "text_bold"
id: "ui_scroll_text_3"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -185.0
y: -1042.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 400.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "You probably wish to add \"stencil\" to your view node to clip all content what outside scroll"
font: "text_bold"
id: "ui_scroll_text_4"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -185.0
y: -1257.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 0.75
y: 0.75
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 400.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Druid automatically checks the stencil nodes to add a \"click zone\" for input elements like buttons to prevent the input if they are outside of stencil nodes"
font: "text_bold"
id: "ui_scroll_text_5"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: -1605.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button_stencil"
parent: "scroll_content"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/button_text_green.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 280.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.557
y: 0.835
z: 0.62
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button_stencil/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button_stencil"
layer: "druid"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 245.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Try click me outside"
font: "text_bold"
id: "button_stencil/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "button_stencil/root"
layer: "text_bold"
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
overridden_fields: 8
overridden_fields: 18
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,21 @@
local component = require("druid.component")
---@class scroll: druid.base_component
---@field root node
---@field scroll druid.scroll
---@field druid druid_instance
local M = component.create("scroll")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
self.button_tutorial = self.druid:new_button("button_tutorial/root")
self.button_stencil = self.druid:new_button("button_stencil/root")
end
return M

View File

@@ -0,0 +1,379 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 400.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 400.0
y: 800.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 400.0
y: 800.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "view"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: -400.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "content"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 240.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Grid Item 1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "prefab"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,69 @@
local component = require("druid.component")
---@class scroll_bind_grid: druid.base_component
---@field scroll druid.scroll
---@field grid druid.static_grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("scroll_bind_grid")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.created_nodes = {}
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", "prefab", 1)
self.scroll:bind_grid(self.grid)
for index = 1, 20 do
self:add_element()
end
end
function M:on_remove()
self:clear()
end
function M:add_element()
local prefab_nodes = gui.clone_tree(self.prefab)
local root = prefab_nodes[self:get_template() .. "/prefab"]
local text = prefab_nodes[self:get_template() .. "/text"]
table.insert(self.created_nodes, root)
gui.set_text(text, "Grid Item " .. #self.created_nodes)
gui.set_enabled(root, true)
self.grid:add(root)
end
function M:remove_element()
local last_node = table.remove(self.created_nodes)
if last_node == nil then
return
end
gui.delete_node(last_node)
local grid_index = self.grid:get_index_by_node(last_node)
self.grid:remove(grid_index)
end
function M:clear()
for _, node in ipairs(self.created_nodes) do
gui.delete_node(node)
end
self.created_nodes = {}
self.grid:clear()
end
return M

View File

@@ -0,0 +1,379 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: -450.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 900.0
y: 360.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 900.0
y: 360.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_FIT
parent: "view"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 450.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 270.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "content"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 190.0
y: 250.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 150.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Grid Item 1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "prefab"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,69 @@
local component = require("druid.component")
---@class scroll_bind_grid_horizontal: druid.base_component
---@field scroll druid.scroll
---@field grid druid.static_grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("scroll_bind_grid_horizontal")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.created_nodes = {}
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", "prefab", 99999)
self.scroll:bind_grid(self.grid)
for index = 1, 30 do
self:add_element()
end
end
function M:on_remove()
self:clear()
end
function M:add_element()
local prefab_nodes = gui.clone_tree(self.prefab)
local root = prefab_nodes[self:get_template() .. "/prefab"]
local text = prefab_nodes[self:get_template() .. "/text"]
table.insert(self.created_nodes, root)
gui.set_text(text, "Grid Item " .. #self.created_nodes)
gui.set_enabled(root, true)
self.grid:add(root)
end
function M:remove_element()
local last_node = table.remove(self.created_nodes)
if last_node == nil then
return
end
gui.delete_node(last_node)
local grid_index = self.grid:get_index_by_node(last_node)
self.grid:remove(grid_index)
end
function M:clear()
for _, node in ipairs(self.created_nodes) do
gui.delete_node(node)
end
self.created_nodes = {}
self.grid:clear()
end
return M

View File

@@ -0,0 +1,126 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
y: 400.0
}
size {
x: 400.0
y: 800.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "view"
pivot: PIVOT_N
parent: "root"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_STENCIL
}
nodes {
size {
x: 400.0
y: 800.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "content"
pivot: PIVOT_N
parent: "view"
inherit_alpha: true
visible: false
}
nodes {
position {
y: -400.0
}
size {
x: 300.0
y: 400.0
}
type: TYPE_BOX
id: "prefab"
parent: "content"
inherit_alpha: true
visible: false
}
nodes {
size {
x: 300.0
y: 90.0
}
color {
x: 0.631
y: 0.843
z: 0.961
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "panel"
parent: "prefab"
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
}
nodes {
size {
x: 240.0
y: 50.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_TEXT
text: "Grid Item 1"
font: "text_bold"
id: "text"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "prefab"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,75 @@
local component = require("druid.component")
---@class scroll_bind_grid_points: druid.base_component
---@field scroll druid.scroll
---@field grid druid.static_grid
---@field text druid.text
---@field druid druid_instance
local M = component.create("scroll_bind_grid_points")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.created_nodes = {}
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", "prefab", 1)
self.scroll:bind_grid(self.grid)
for index = 1, 20 do
self:add_element()
end
local points = self.grid:get_all_pos()
for _, point in ipairs(points) do
point.y = point.y + self.scroll.view_size.y/2
end
self.scroll:set_points(points)
end
function M:on_remove()
self:clear()
end
function M:add_element()
local prefab_nodes = gui.clone_tree(self.prefab)
local root = prefab_nodes[self:get_template() .. "/prefab"]
local text = prefab_nodes[self:get_template() .. "/text"]
table.insert(self.created_nodes, root)
gui.set_text(text, "Grid Item " .. #self.created_nodes)
gui.set_enabled(root, true)
self.grid:add(root)
end
function M:remove_element()
local last_node = table.remove(self.created_nodes)
if last_node == nil then
return
end
gui.delete_node(last_node)
local grid_index = self.grid:get_index_by_node(last_node)
self.grid:remove(grid_index)
end
function M:clear()
for _, node in ipairs(self.created_nodes) do
gui.delete_node(node)
end
self.created_nodes = {}
self.grid:clear()
end
return M

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
local component = require("druid.component")
local slider = require("druid.extended.slider")
---@class scroll_slider: druid.base_component
---@field root node
---@field scroll druid.scroll
---@field slider druid.slider
---@field druid druid_instance
local M = component.create("scroll_slider")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
self.scroll.on_scroll:subscribe(self.on_scroll)
self.slider = self.druid:new(slider, "slider_pin", vmath.vector3(-8, -976, 0), self.on_slider) --[[@as druid.slider]]
self.slider:set_input_node("slider_back")
self.druid:new_hover("slider_back", nil, self.on_slider_back_hover)
for index = 1, 13 do
self.druid:new_button("button" .. index .. "/root", self.on_button_click)
end
end
function M:on_scroll()
local scroll_percent = self.scroll:get_percent()
self.slider:set(1 - scroll_percent.y, true)
end
function M:on_slider(value)
self.scroll:scroll_to_percent(vmath.vector3(0, 1 - value, 0), true)
end
---@param button druid.button
function M:on_button_click(_, button)
local node = button.node
self.scroll:scroll_to(gui.get_position(node))
end
function M:on_slider_back_hover(is_hover)
local node = self:get_node("slider_pin")
gui.animate(node, "color.w", is_hover and 1.5 or 1, gui.EASING_OUTSINE, 0.2)
end
return M

View File

@@ -0,0 +1,362 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_64"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "slider"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/slider.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 260.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "slider/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "slider"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 260.0
y: 8.0
z: 0.0
w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_8"
id: "slider/slider_back"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "slider/root"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -118.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 24.0
y: 24.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_8"
id: "slider/slider_pin"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "slider/root"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 50.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 150.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "0 %"
font: "text_bold"
id: "slider_value"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,30 @@
local component = require("druid.component")
local slider = require("druid.extended.slider")
---@class basic_slider: druid.base_component
---@field druid druid_instance
---@field root node
---@field slider druid.slider
local M = component.create("basic_slider")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.slider = self.druid:new(slider, "slider/slider_pin", vmath.vector3(118, 0, 0), self.on_slider_change) --[[@as druid.slider]]
-- To add input across all slider widget add a root node to acquire additional input
self.slider:set_input_node("slider/root")
self.text_value = self:get_node("slider_value")
end
function M:on_slider_change(value)
gui.set_text(self.text_value, math.ceil(value * 100) .. "%")
end
return M

View File

@@ -0,0 +1,362 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_64"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "slider"
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/templates/slider.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 260.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "slider/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "slider"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 260.0
y: 8.0
z: 0.0
w: 1.0
}
color {
x: 0.129
y: 0.141
z: 0.157
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_8"
id: "slider/slider_back"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "slider/root"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -118.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 24.0
y: 24.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_8"
id: "slider/slider_pin"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "slider/root"
layer: ""
inherit_alpha: true
slice9 {
x: 4.0
y: 4.0
z: 4.0
w: 4.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 50.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 150.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "0 %"
font: "text_bold"
id: "slider_value"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,32 @@
local component = require("druid.component")
local slider = require("druid.extended.slider")
---@class basic_slider_stepped: druid.base_component
---@field druid druid_instance
---@field root node
---@field slider druid.slider
local M = component.create("basic_slider_stepped")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.slider = self.druid:new(slider, "slider/slider_pin", vmath.vector3(118, 0, 0), self.on_slider_change) --[[@as druid.slider]]
-- To add input across all slider widget add a root node to acquire additional input
self.slider:set_input_node("slider/root")
self.slider:set_steps({0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1})
self.text_value = self:get_node("slider_value")
end
function M:on_slider_change(value)
gui.set_text(self.text_value, math.ceil(value * 100) .. "%")
end
return M

View File

@@ -0,0 +1,102 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
type: TYPE_TEMPLATE
id: "slider"
parent: "root"
inherit_alpha: true
template: "/example/templates/slider.gui"
}
nodes {
size {
x: 40.0
y: 260.0
}
type: TYPE_BOX
id: "slider/root"
parent: "slider"
overridden_fields: 4
template_node_child: true
}
nodes {
size {
x: 9.0
y: 260.0
}
type: TYPE_BOX
id: "slider/slider_back"
parent: "slider/root"
overridden_fields: 4
template_node_child: true
}
nodes {
position {
y: 118.0
}
type: TYPE_BOX
id: "slider/slider_pin"
parent: "slider/root"
overridden_fields: 1
template_node_child: true
}
nodes {
position {
y: 160.0
}
size {
x: 150.0
y: 50.0
}
color {
x: 0.722
y: 0.741
z: 0.761
}
type: TYPE_TEXT
text: "0 %"
font: "text_bold"
id: "slider_value"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,30 @@
local component = require("druid.component")
local slider = require("druid.extended.slider")
---@class basic_slider_vertical: druid.base_component
---@field druid druid_instance
---@field root node
---@field slider druid.slider
local M = component.create("basic_slider_vertical")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.slider = self.druid:new(slider, "slider/slider_pin", vmath.vector3(0, -118, 0), self.on_slider_change) --[[@as druid.slider]]
-- To add input across all slider widget add a root node to acquire additional input
self.slider:set_input_node("slider/root")
self.text_value = self:get_node("slider_value")
end
function M:on_slider_change(value)
gui.set_text(self.text_value, math.ceil(value * 100) .. "%")
end
return M

View File

@@ -0,0 +1,143 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1000.0
y: 1000.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_64"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 600.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.722
y: 0.741
z: 0.761
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Swipe across area to action"
font: "text_bold"
id: "swipe_hint"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,34 @@
local component = require("druid.component")
local swipe = require("druid.extended.swipe")
---@class basic_swipe: druid.base_component
---@field druid druid_instance
local M = component.create("basic_swipe")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.swipe = self.druid:new(swipe, "root", self.on_swipe) --[[@as druid.swipe]]
self.text_hint = self:get_node("swipe_hint")
end
function M:on_swipe(swipe_side, dist, delta_time)
print("Swipe side:", swipe_side, "Distance:", dist, "Time:", delta_time)
if swipe_side == "up" then
gui.animate(self.text_hint, gui.PROP_POSITION, vmath.vector3(0, 200, 0), gui.EASING_OUTBACK, 0.4)
elseif swipe_side == "down" then
gui.animate(self.text_hint, gui.PROP_POSITION, vmath.vector3(0, -200, 0), gui.EASING_OUTBACK, 0.4)
elseif swipe_side == "left" then
gui.animate(self.text_hint, gui.PROP_POSITION, vmath.vector3(-200, 0, 0), gui.EASING_OUTBACK, 0.4)
elseif swipe_side == "right" then
gui.animate(self.text_hint, gui.PROP_POSITION, vmath.vector3(200, 0, 0), gui.EASING_OUTBACK, 0.4)
end
end
return M

View File

@@ -0,0 +1,202 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 600.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "text_area"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 600.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.941
y: 0.984
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Example text with default adjust"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "text_area"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,42 @@
local helper = require("druid.helper")
local component = require("druid.component")
local container = require("example.components.container.container")
local lang_text = require("druid.extended.lang_text")
---@class basic_text: druid.base_component
---@field druid druid_instance
---@field text druid.text
local M = component.create("basic_text")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.text = self.druid:new_text("text")
-- This code is for adjustable text area with mouse
self.container = self.druid:new(container, "text_area", nil, function(_, size)
self.text:set_size(size)
self:refresh_text_position()
end) --[[@as druid.container]]
self.container:create_draggable_corners()
end
function M:set_pivot(pivot)
self.text:set_pivot(pivot)
self:refresh_text_position()
end
function M:refresh_text_position()
-- Need to update text position with different pivot
local pivot = gui.get_pivot(self.text.node)
local pivot_offset = helper.get_pivot_offset(pivot)
gui.set_position(self.text.node, vmath.vector3(pivot_offset.x * self.text.start_size.x, pivot_offset.y * self.text.start_size.y, 0))
end
return M

View File

@@ -0,0 +1,202 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 600.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.463
y: 0.475
z: 0.49
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "text_area"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 600.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.941
y: 0.984
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Example multiline text with default adjust"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "text_area"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,26 @@
local component = require("druid.component")
local container = require("example.components.container.container")
---@class multiline_text: druid.base_component
---@field root node
---@field druid druid_instance
local M = component.create("multiline_text")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.text = self.druid:new_text("text")
-- This code is for adjustable text area with mouse
self.container = self.druid:new(container, "text_area", nil, function(_, size)
self.text:set_size(size)
end) --[[@as druid.container]]
self.container:create_draggable_corners()
end
return M

View File

@@ -0,0 +1,35 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
nodes {
size {
x: 200.0
y: 100.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
visible: false
}
nodes {
scale {
x: 2.0
y: 2.0
}
size {
x: 200.0
y: 100.0
}
type: TYPE_TEXT
text: "5:09"
font: "text_bold"
id: "text"
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,33 @@
local event = require("druid.event")
local timer = require("druid.extended.timer")
local component = require("druid.component")
---@class basic_timer: druid.component
---@field druid druid_instance
---@field root node
---@field text druid.text
local M = component.create("basic_timer")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.timer = self.druid:new(timer, "text")
local time = 5
self.timer:set_interval(time, 0)
self.timer.on_timer_end:subscribe(function()
time = time + 5
self.timer:set_interval(time, 0)
self.on_cycle_end:trigger()
end)
self.on_cycle_end = event.create()
end
return M

View File

@@ -0,0 +1,379 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 350.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 350.0
y: 700.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/pixel"
id: "view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 350.0
y: 700.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "view"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: -400.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "content"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 250.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "prefab"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,70 @@
local event = require("druid.event")
local component = require("druid.component")
local data_list = require("druid.extended.data_list")
---@class data_list_add_remove_clear: druid.base_component
---@field druid druid_instance
---@field data_list druid.data_list
local M = component.create("data_list_add_remove_clear")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", self.prefab, 1)
self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
local data = {}
for index = 1, 20 do
table.insert(data, {})
end
self.data_list:set_data(data)
self.on_item_click = event()
end
---@param item_data table
---@param index number
---@return node, druid.base_component
function M:create_item_callback(item_data, index)
local nodes = gui.clone_tree(self.prefab)
local root = nodes[self:get_template() .. "/prefab"]
local text = nodes[self:get_template() .. "/text"]
gui.set_enabled(root, true)
gui.set_text(text, "Data Item " .. index)
local button = self.druid:new_button(root, self.on_button_click, index)
return root, button
end
function M:on_button_click(index)
self.on_item_click:trigger(index)
end
function M:add_item(index)
self.data_list:add({}, index)
end
function M:remove_item(index)
print("Want to remove item", index)
self.data_list:remove(index)
end
function M:clear()
self.data_list:clear()
end
return M

View File

@@ -0,0 +1,379 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 350.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 350.0
y: 700.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/pixel"
id: "view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 350.0
y: 700.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "view"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: -400.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "content"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 250.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "prefab"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,53 @@
local event = require("druid.event")
local component = require("druid.component")
local data_list = require("druid.extended.data_list")
---@class data_list_basic: druid.base_component
---@field druid druid_instance
local M = component.create("data_list_basic")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", self.prefab, 1)
self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
local data = {}
for index = 1, 1000 do
table.insert(data, {})
end
self.data_list:set_data(data)
self.on_item_click = event()
end
---@param item_data table
---@param index number
---@return node, druid.base_component
function M:create_item_callback(item_data, index)
local nodes = gui.clone_tree(self.prefab)
local root = nodes[self:get_template() .. "/prefab"]
local text = nodes[self:get_template() .. "/text"]
gui.set_enabled(root, true)
gui.set_text(text, "Data Item " .. index)
local button = self.druid:new_button(root, self.on_button_click, index)
return root, button
end
function M:on_button_click(index)
self.on_item_click:trigger(index)
end
return M

View File

@@ -0,0 +1,379 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: -450.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 900.0
y: 350.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/pixel"
id: "view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 900.0
y: 350.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_FIT
parent: "view"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 450.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 270.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "content"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 190.0
y: 250.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "prefab"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 150.0
y: 200.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: true
parent: "prefab"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,46 @@
local component = require("druid.component")
local data_list = require("druid.extended.data_list")
---@class data_list_horizontal_basic: druid.base_component
---@field druid druid_instance
local M = component.create("data_list_horizontal_basic")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", self.prefab, 1000)
self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
local data = {}
for index = 1, 100 do
table.insert(data, {})
end
self.data_list:set_data(data)
end
function M:create_item_callback(item_data, index)
local nodes = gui.clone_tree(self.prefab)
local root = nodes[self:get_template() .. "/prefab"]
local text = nodes[self:get_template() .. "/text"]
gui.set_enabled(root, true)
gui.set_text(text, "Data Item " .. index)
local button = self.druid:new_button(root, self.on_button_click, index)
return root, button
end
function M:on_button_click(index)
print("Button clicked", index)
end
return M

View File

@@ -0,0 +1,202 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 250.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,35 @@
local component = require("druid.component")
---@class button_component: druid.base_component
---@field root node
---@field druid druid_instance
---@field text druid.text
---@field data any
local M = component.create("button_component")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.button = self.druid:new_button(self.root)
self.text = self.druid:new_text("text")
self.data = nil
end
---@param data any
function M:set_data(data)
self.data = data
end
function M:get_data()
return self.data
end
return M

View File

@@ -0,0 +1,421 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 350.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 350.0
y: 700.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/pixel"
id: "view"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 350.0
y: 700.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "content"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_N
adjust_mode: ADJUST_MODE_FIT
parent: "view"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: -300.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEMPLATE
id: "button_component"
parent: "content"
layer: ""
inherit_alpha: true
alpha: 1.0
template: "/example/examples/data_list/cache_with_component/button_component.gui"
template_node_child: false
custom_type: 0
enabled: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "button_component/root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button_component"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 300.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button_component/panel"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button_component/root"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: true
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 250.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "Data Item 1"
font: "text_bold"
id: "button_component/text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button_component/root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: true
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,73 @@
local event = require("druid.event")
local component = require("druid.component")
local data_list = require("druid.extended.data_list")
local button_component = require("example.examples.data_list.cache_with_component.button_component")
---@class data_list_cache_with_component: druid.base_component
---@field druid druid_instance
local M = component.create("data_list_cache_with_component")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.prefab = self:get_node("button_component/root")
gui.set_enabled(self.prefab, false)
self.scroll = self.druid:new_scroll("view", "content")
self.grid = self.druid:new_static_grid("content", self.prefab, 1)
self.data_list = self.druid:new(data_list, self.scroll, self.grid, self.create_item_callback) --[[@as druid.data_list]]
self.data_list:set_use_cache(true)
self.data_list.on_element_add:subscribe(self.on_element_add)
self.data_list.on_element_remove:subscribe(self.on_element_remove)
local data = {}
for index = 1, 1000 do
table.insert(data, {})
end
self.data_list:set_data(data)
self.on_item_click = event()
end
---@param item_data table
---@param index number
---@return node, druid.base_component
function M:create_item_callback(item_data, index)
local nodes = gui.clone_tree(self.prefab)
local instance = self.druid:new(button_component, "button_component", nodes)
gui.set_enabled(instance.root, true)
return instance.root, instance
end
---@param index number
---@param node node
---@param instance button_component
---@param data table
function M:on_element_add(index, node, instance, data)
instance.text:set_to("Data Item " .. index)
instance.button.on_click:subscribe(self.on_button_click, self)
instance:set_data(index)
end
function M:on_element_remove(index, node, instance, data)
instance.button.on_click:unsubscribe(self.on_button_click, self)
end
---@param instance button_component
function M:on_button_click(instance)
local data = instance:get_data()
self.on_item_click:trigger(data)
end
return M

View File

@@ -0,0 +1,203 @@
local M = {}
function M.get_examples()
---@type druid.example.data[]
return {
{
name_id = "ui_example_data_list_basic",
information_text_id = "ui_example_data_list_basic_description",
template = "data_list_basic",
root = "data_list_basic/root",
code_url = "example/examples/data_list/basic/data_list_basic.lua",
component_class = require("example.examples.data_list.basic.data_list_basic"),
on_create = function(instance, output_list)
---@cast instance data_list_basic
instance.on_item_click:subscribe(function(index)
output_list:add_log_text("Item clicked: " .. index)
end)
end,
properties_control = function(instance, properties_panel)
---@cast instance data_list_basic
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
properties_panel:add_slider("ui_scroll", 0, function(value)
instance.scroll:scroll_to_percent(vmath.vector3(0, 1 - value, 0), true)
end)
end,
get_debug_info = function(instance)
---@cast instance data_list_basic
local data_list = instance.data_list
local data = data_list:get_data()
local info = ""
info = info .. "Data length: " .. #data .. "\n"
info = info .. "First Visual Index: " .. data_list.top_index .. "\n"
info = info .. "Last Visual Index: " .. data_list.last_index .. "\n"
local s = instance.scroll
info = info .. "\n"
info = info .. "View Size Y: " .. gui.get(s.view_node, "size.y") .. "\n"
info = info .. "Content Size Y: " .. gui.get(s.content_node, "size.y") .. "\n"
info = info .. "Content position Y: " .. math.ceil(s.position.y) .. "\n"
info = info .. "Content Range Y: " .. s.available_pos.y .. " - " .. s.available_pos.w .. "\n"
return info
end
},
{
name_id = "ui_example_data_list_horizontal_basic",
information_text_id = "ui_example_data_list_horizontal_basic_description",
template = "data_list_horizontal_basic",
root = "data_list_horizontal_basic/root",
code_url = "example/examples/data_list/basic/data_list_horizontal_basic.lua",
component_class = require("example.examples.data_list.basic.data_list_horizontal_basic"),
properties_control = function(instance, properties_panel)
---@cast instance data_list_horizontal_basic
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
end,
get_debug_info = function(instance)
---@cast instance data_list_horizontal_basic
local data_list = instance.data_list
local data = data_list:get_data()
local info = ""
info = info .. "Data length: " .. #data .. "\n"
info = info .. "First Visual Index: " .. data_list.top_index .. "\n"
info = info .. "Last Visual Index: " .. data_list.last_index .. "\n"
local s = instance.scroll
info = info .. "\n"
info = info .. "View Size X: " .. gui.get(s.view_node, "size.x") .. "\n"
info = info .. "Content Size X: " .. gui.get(s.content_node, "size.x") .. "\n"
info = info .. "Content position X: " .. math.ceil(s.position.x) .. "\n"
info = info .. "Content Range X: " .. s.available_pos.x .. " - " .. s.available_pos.z .. "\n"
return info
end
},
{
name_id = "ui_example_data_list_add_remove_clear",
information_text_id = "ui_example_data_list_add_remove_clear_description",
template = "data_list_add_remove_clear",
root = "data_list_add_remove_clear/root",
code_url = "example/examples/data_list/add_remove_clear/data_list_add_remove_clear.lua",
component_class = require("example.examples.data_list.add_remove_clear.data_list_add_remove_clear"),
on_create = function(instance, output_list)
---@cast instance data_list_add_remove_clear
instance.on_item_click:subscribe(function(index)
instance:remove_item(index)
output_list:add_log_text("Item removed: " .. index)
end)
end,
properties_control = function(instance, properties_panel)
---@cast instance data_list_add_remove_clear
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
properties_panel:add_slider("ui_scroll", 0, function(value)
instance.scroll:scroll_to_percent(vmath.vector3(0, 1 - value, 0), true)
end)
properties_panel:add_button("ui_add_item", function()
instance:add_item()
end)
properties_panel:add_button("ui_remove_item", function()
instance:remove_item()
end)
properties_panel:add_button("ui_clear_items", function()
instance.data_list:clear()
end)
end,
get_debug_info = function(instance)
---@cast instance data_list_add_remove_clear
local data_list = instance.data_list
local data = data_list:get_data()
local info = ""
info = info .. "Data length: " .. #data .. "\n"
info = info .. "First Visual Index: " .. data_list.top_index .. "\n"
info = info .. "Last Visual Index: " .. data_list.last_index .. "\n"
local s = instance.scroll
info = info .. "\n"
info = info .. "View Size X: " .. gui.get(s.view_node, "size.x") .. "\n"
info = info .. "Content Size X: " .. gui.get(s.content_node, "size.x") .. "\n"
info = info .. "Content position X: " .. math.ceil(s.position.x) .. "\n"
info = info .. "Content Range X: " .. s.available_pos.x .. " - " .. s.available_pos.z .. "\n"
return info
end
},
{
name_id = "ui_example_data_list_cache_with_component",
information_text_id = "ui_example_data_list_cache_with_component_description",
template = "data_list_cache_with_component",
root = "data_list_cache_with_component/root",
code_url = "example/examples/data_list/cache_with_component/cache_with_component.lua",
component_class = require("example.examples.data_list.cache_with_component.cache_with_component"),
on_create = function(instance, output_list)
---@cast instance data_list_cache_with_component
instance.on_item_click:subscribe(function(index)
output_list:add_log_text("Item clicked: " .. index)
end)
end,
properties_control = function(instance, properties_panel)
---@cast instance data_list_cache_with_component
local view_node = instance.scroll.view_node
local is_stencil = gui.get_clipping_mode(view_node) == gui.CLIPPING_MODE_STENCIL
properties_panel:add_checkbox("ui_clipping", is_stencil, function(value)
gui.set_clipping_mode(view_node, value and gui.CLIPPING_MODE_STENCIL or gui.CLIPPING_MODE_NONE)
end)
properties_panel:add_slider("ui_scroll", 0, function(value)
instance.scroll:scroll_to_percent(vmath.vector3(0, 1 - value, 0), true)
end)
end,
get_debug_info = function(instance)
---@cast instance data_list_cache_with_component
local data_list = instance.data_list
local data = data_list:get_data()
local info = ""
info = info .. "Data length: " .. #data .. "\n"
info = info .. "First Visual Index: " .. data_list.top_index .. "\n"
info = info .. "Last Visual Index: " .. data_list.last_index .. "\n"
local s = instance.scroll
info = info .. "\n"
info = info .. "View Size Y: " .. gui.get(s.view_node, "size.y") .. "\n"
info = info .. "Content Size Y: " .. gui.get(s.content_node, "size.y") .. "\n"
info = info .. "Content position Y: " .. math.ceil(s.position.y) .. "\n"
info = info .. "Content Range Y: " .. s.available_pos.y .. " - " .. s.available_pos.w .. "\n"
return info
end
},
}
end
return M

View File

@@ -0,0 +1,49 @@
local intro_examples = require("example.examples.intro.examples_list")
local basic_examples = require("example.examples.basic.examples_list")
local data_list_examples = require("example.examples.data_list.examples_list")
local layout_examples = require("example.examples.layout.examples_list")
local gamepad_examples = require("example.examples.gamepad.examples_list")
local window_examples = require("example.examples.windows.examples_list")
local panthera_examples = require("example.examples.panthera.examples_list")
local M = {}
---@class druid.examples
---@field example_name_id string
---@field examples_list druid.example.data[]
---@class druid.example.data
---@field name_id string
---@field root string
---@field template string|nil
---@field code_url string|nil @URL to the source code
---@field component_class druid.base_component
---@field on_create fun(instance: druid.base_component, output_list: output_list)|nil
---@field get_debug_info (fun(instance: druid.base_component):string)|nil
---@field properties_control (fun(instance: druid.base_component, properties_panel: properties_panel))|nil
---@field information_text_id string|nil
local function add_examples(examples, example_name_id, examples_list)
table.insert(examples, {
example_name_id = example_name_id,
examples_list = examples_list
})
end
---@return druid.examples[]
function M.get_examples()
local examples = {}
add_examples(examples, "ui_examples_intro", intro_examples.get_examples())
add_examples(examples, "ui_examples_basic", basic_examples.get_examples())
add_examples(examples, "ui_examples_data_list", data_list_examples.get_examples())
add_examples(examples, "ui_examples_layout", layout_examples.get_examples())
add_examples(examples, "ui_examples_gamepad", gamepad_examples.get_examples())
add_examples(examples, "ui_examples_window", window_examples.get_examples())
add_examples(examples, "ui_examples_panthera", panthera_examples.get_examples())
return examples
end
return M

View File

@@ -0,0 +1,72 @@
local M = {}
---@return druid.example.data[]
function M.get_examples()
---@type druid.example.data[]
return {
{
name_id = "ui_example_gamepad_tester",
information_text_id = "ui_example_gamepad_tester_description",
template = "gamepad_tester",
root = "gamepad_tester/root",
code_url = "example/examples/gamepad/gamepad_tester/gamepad_tester.lua",
component_class = require("example.examples.gamepad.gamepad_tester.gamepad_tester"),
on_create = function(instance, output_list)
---@cast instance gamepad_tester
instance.button_left.on_click:subscribe(function()
output_list:add_log_text("Button Left Clicked")
end)
instance.button_right.on_click:subscribe(function()
output_list:add_log_text("Button Right Clicked")
end)
instance.button_up.on_click:subscribe(function()
output_list:add_log_text("Button Up Clicked")
end)
instance.button_down.on_click:subscribe(function()
output_list:add_log_text("Button Down Clicked")
end)
instance.button_a.on_click:subscribe(function()
output_list:add_log_text("Button A Clicked")
end)
instance.button_b.on_click:subscribe(function()
output_list:add_log_text("Button B Clicked")
end)
instance.button_x.on_click:subscribe(function()
output_list:add_log_text("Button X Clicked")
end)
instance.button_y.on_click:subscribe(function()
output_list:add_log_text("Button Y Clicked")
end)
instance.button_back.on_click:subscribe(function()
output_list:add_log_text("Button Back Clicked")
end)
instance.button_start.on_click:subscribe(function()
output_list:add_log_text("Button Start Clicked")
end)
instance.button_l1.on_click:subscribe(function()
output_list:add_log_text("Button L1 Clicked")
end)
instance.button_r1.on_click:subscribe(function()
output_list:add_log_text("Button R1 Clicked")
end)
instance.button_stick_left.on_click:subscribe(function()
output_list:add_log_text("Button Stick Left Clicked")
end)
instance.button_stick_right.on_click:subscribe(function()
output_list:add_log_text("Button Stick Right Clicked")
end)
end,
},
{
name_id = "ui_example_on_screen_control",
information_text_id = "ui_example_on_screen_control_description",
template = "on_screen_control",
root = "on_screen_control/root",
code_url = "example/examples/gamepad/on_screen_control/on_screen_control.lua",
component_class = require("example.examples.gamepad.on_screen_control.on_screen_control"),
}
}
end
return M

View File

@@ -0,0 +1,725 @@
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "root"
inherit_alpha: true
visible: false
}
nodes {
size {
x: 200.0
y: 100.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "gamepad"
parent: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -200.0
y: -300.0
}
type: TYPE_TEMPLATE
id: "stick_left"
parent: "gamepad"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui"
}
nodes {
type: TYPE_BOX
id: "stick_left/root"
parent: "stick_left"
template_node_child: true
}
nodes {
type: TYPE_PIE
id: "stick_left/background_mask"
parent: "stick_left/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/background"
parent: "stick_left/background_mask"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/stick_root"
parent: "stick_left/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/stick_shadow"
parent: "stick_left/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/stick"
parent: "stick_left/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/dot_1"
parent: "stick_left/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/dot_2"
parent: "stick_left/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/dot_3"
parent: "stick_left/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_left/dot_4"
parent: "stick_left/stick"
template_node_child: true
}
nodes {
position {
x: 200.0
y: -300.0
}
type: TYPE_TEMPLATE
id: "stick_right"
parent: "gamepad"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui"
}
nodes {
type: TYPE_BOX
id: "stick_right/root"
parent: "stick_right"
template_node_child: true
}
nodes {
type: TYPE_PIE
id: "stick_right/background_mask"
parent: "stick_right/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/background"
parent: "stick_right/background_mask"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/stick_root"
parent: "stick_right/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/stick_shadow"
parent: "stick_right/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/stick"
parent: "stick_right/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/dot_1"
parent: "stick_right/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/dot_2"
parent: "stick_right/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/dot_3"
parent: "stick_right/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "stick_right/dot_4"
parent: "stick_right/stick"
template_node_child: true
}
nodes {
position {
x: -330.0
y: 24.0
}
size {
x: 290.0
y: 290.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "dpad"
parent: "gamepad"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -100.0
}
type: TYPE_TEMPLATE
id: "button_left"
parent: "dpad"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_left/button"
parent: "button_left"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button_left/text"
parent: "button_left/button"
overridden_fields: 45
overridden_fields: 46
template_node_child: true
enabled: false
visible: false
}
nodes {
rotation {
z: 180.0
}
type: TYPE_BOX
id: "button_left/icon"
parent: "button_left/button"
overridden_fields: 2
template_node_child: true
}
nodes {
position {
y: 100.0
}
type: TYPE_TEMPLATE
id: "button_up"
parent: "dpad"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_up/button"
parent: "button_up"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button_up/text"
parent: "button_up/button"
overridden_fields: 45
overridden_fields: 46
template_node_child: true
enabled: false
visible: false
}
nodes {
rotation {
z: 90.0
}
type: TYPE_BOX
id: "button_up/icon"
parent: "button_up/button"
overridden_fields: 2
template_node_child: true
}
nodes {
position {
x: 100.0
}
type: TYPE_TEMPLATE
id: "button_right"
parent: "dpad"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_right/button"
parent: "button_right"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button_right/text"
parent: "button_right/button"
overridden_fields: 45
overridden_fields: 46
template_node_child: true
enabled: false
visible: false
}
nodes {
type: TYPE_BOX
id: "button_right/icon"
parent: "button_right/button"
template_node_child: true
}
nodes {
position {
y: -100.0
}
type: TYPE_TEMPLATE
id: "button_down"
parent: "dpad"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_down/button"
parent: "button_down"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button_down/text"
parent: "button_down/button"
overridden_fields: 45
overridden_fields: 46
template_node_child: true
enabled: false
visible: false
}
nodes {
rotation {
z: -90.0
}
type: TYPE_BOX
id: "button_down/icon"
parent: "button_down/button"
overridden_fields: 2
template_node_child: true
}
nodes {
position {
x: 330.0
y: 24.0
}
size {
x: 290.0
y: 290.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "buttons"
parent: "gamepad"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -100.0
}
type: TYPE_TEMPLATE
id: "button_x"
parent: "buttons"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_x/button"
parent: "button_x"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button_x/text"
parent: "button_x/button"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_x/icon"
parent: "button_x/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
y: 100.0
}
type: TYPE_TEMPLATE
id: "button_y"
parent: "buttons"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_y/button"
parent: "button_y"
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "Y"
id: "button_y/text"
parent: "button_y/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_y/icon"
parent: "button_y/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
x: 100.0
}
type: TYPE_TEMPLATE
id: "button_b"
parent: "buttons"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_b/button"
parent: "button_b"
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "B"
id: "button_b/text"
parent: "button_b/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_b/icon"
parent: "button_b/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
y: -100.0
}
type: TYPE_TEMPLATE
id: "button_a"
parent: "buttons"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_a/button"
parent: "button_a"
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "A"
id: "button_a/text"
parent: "button_a/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_a/icon"
parent: "button_a/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
y: 160.0
}
size {
x: 290.0
y: 290.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "buttons_system"
parent: "gamepad"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -110.0
}
type: TYPE_TEMPLATE
id: "button_back"
parent: "buttons_system"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
size {
x: 180.0
y: 90.0
}
type: TYPE_BOX
id: "button_back/button"
parent: "button_back"
overridden_fields: 4
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "Back"
id: "button_back/text"
parent: "button_back/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_back/icon"
parent: "button_back/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
x: 110.0
}
type: TYPE_TEMPLATE
id: "button_start"
parent: "buttons_system"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
size {
x: 180.0
y: 90.0
}
type: TYPE_BOX
id: "button_start/button"
parent: "button_start"
overridden_fields: 4
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "Start"
id: "button_start/text"
parent: "button_start/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_start/icon"
parent: "button_start/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
x: -330.0
y: 360.0
}
size {
x: 200.0
y: 200.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "button_left_bump"
parent: "gamepad"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -3.0
y: -57.0
}
type: TYPE_TEMPLATE
id: "button_l1"
parent: "button_left_bump"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
size {
x: 180.0
y: 90.0
}
type: TYPE_BOX
id: "button_l1/button"
parent: "button_l1"
overridden_fields: 4
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "L1"
id: "button_l1/text"
parent: "button_l1/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_l1/icon"
parent: "button_l1/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
y: 60.0
}
type: TYPE_TEMPLATE
id: "button_l2"
parent: "button_left_bump"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui"
}
nodes {
type: TYPE_BOX
id: "button_l2/button"
parent: "button_l2"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_l2/fill"
parent: "button_l2/button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "L2"
id: "button_l2/text"
parent: "button_l2/button"
overridden_fields: 8
template_node_child: true
}
nodes {
position {
x: 330.0
y: 360.0
}
size {
x: 200.0
y: 200.0
}
type: TYPE_BOX
texture: "druid/empty"
id: "button_right_bump"
parent: "gamepad"
inherit_alpha: true
visible: false
}
nodes {
position {
y: -60.0
}
type: TYPE_TEMPLATE
id: "button_r1"
parent: "button_right_bump"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
size {
x: 180.0
y: 90.0
}
type: TYPE_BOX
id: "button_r1/button"
parent: "button_r1"
overridden_fields: 4
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "R1"
id: "button_r1/text"
parent: "button_r1/button"
overridden_fields: 8
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_r1/icon"
parent: "button_r1/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
nodes {
position {
y: 60.0
}
type: TYPE_TEMPLATE
id: "button_r2"
parent: "button_right_bump"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_trigger.gui"
}
nodes {
type: TYPE_BOX
id: "button_r2/button"
parent: "button_r2"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_r2/fill"
parent: "button_r2/button"
template_node_child: true
}
nodes {
type: TYPE_TEXT
text: "R2"
id: "button_r2/text"
parent: "button_r2/button"
overridden_fields: 8
template_node_child: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,87 @@
local component = require("druid.component")
local progress = require("druid.extended.progress")
---@class gamepad_tester: druid.base_component
---@field root node
---@field buttons druid.button
---@field buttons_system druid.button
---@field button_left_bump druid.button
---@field button_right_bump druid.button
---@field druid druid_instance
local M = component.create("gamepad_tester")
local STICK_DISTANCE = 50
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.button_left = self.druid:new_button("button_left/button"):set_key_trigger("gamepad_lpad_left")
self.button_right = self.druid:new_button("button_right/button"):set_key_trigger("gamepad_lpad_right")
self.button_up = self.druid:new_button("button_up/button"):set_key_trigger("gamepad_lpad_up")
self.button_down = self.druid:new_button("button_down/button"):set_key_trigger("gamepad_lpad_down")
self.button_x = self.druid:new_button("button_x/button"):set_key_trigger("gamepad_rpad_left")
self.button_b = self.druid:new_button("button_b/button"):set_key_trigger("gamepad_rpad_right")
self.button_y = self.druid:new_button("button_y/button"):set_key_trigger("gamepad_rpad_up")
self.button_a = self.druid:new_button("button_a/button"):set_key_trigger("gamepad_rpad_down")
self.button_l1 = self.druid:new_button("button_l1/button"):set_key_trigger("gamepad_lshoulder")
self.button_r1 = self.druid:new_button("button_r1/button"):set_key_trigger("gamepad_rshoulder")
self.button_stick_left = self.druid:new_button("stick_left/root"):set_key_trigger("gamepad_lstick_click")
self.button_stick_right = self.druid:new_button("stick_right/root"):set_key_trigger("gamepad_rstick_click")
self.button_start = self.druid:new_button("button_start/button"):set_key_trigger("gamepad_start")
self.button_back = self.druid:new_button("button_back/button"):set_key_trigger("gamepad_back")
self.trigger_l2 = self.druid:new(progress, "button_l2/fill", "x", 0) --[[@as druid.progress]]
self.trigger_r2 = self.druid:new(progress, "button_r2/fill", "x", 0) --[[@as druid.progress]]
self.stick_left = self:get_node("stick_left/stick_root")
self.stick_right = self:get_node("stick_right/stick_root")
end
function M:on_input(action_id, action)
if action_id == hash("gamepad_ltrigger") then
self.trigger_l2:set_to(action.value)
end
if action_id == hash("gamepad_rtrigger") then
self.trigger_r2:set_to(action.value)
end
-- Left Stick
if action_id == hash("gamepad_lstick_left") then
gui.set(self.stick_left, "position.x", -action.value * STICK_DISTANCE)
end
if action_id == hash("gamepad_lstick_right") then
gui.set(self.stick_left, "position.x", action.value * STICK_DISTANCE)
end
if action_id == hash("gamepad_lstick_up") then
gui.set(self.stick_left, "position.y", action.value * STICK_DISTANCE)
end
if action_id == hash("gamepad_lstick_down") then
gui.set(self.stick_left, "position.y", -action.value * STICK_DISTANCE)
end
-- Right Stick
if action_id == hash("gamepad_rstick_left") then
gui.set(self.stick_right, "position.x", -action.value * STICK_DISTANCE)
end
if action_id == hash("gamepad_rstick_right") then
gui.set(self.stick_right, "position.x", action.value * STICK_DISTANCE)
end
if action_id == hash("gamepad_rstick_up") then
gui.set(self.stick_right, "position.y", action.value * STICK_DISTANCE)
end
if action_id == hash("gamepad_rstick_down") then
gui.set(self.stick_right, "position.y", -action.value * STICK_DISTANCE)
end
end
return M

View File

@@ -0,0 +1,202 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 90.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.5
y: 1.5
z: 1.0
w: 1.0
}
size {
x: 40.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.941
y: 0.984
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "X"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.941
y: 0.984
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/icon_arrow"
id: "icon"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "button"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,191 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 12.0
y: 12.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/empty"
id: "root"
inherit_alpha: true
}
nodes {
size {
x: 256.0
y: 256.0
}
type: TYPE_PIE
id: "background_mask"
parent: "root"
inherit_alpha: true
perimeterVertices: 64
clipping_mode: CLIPPING_MODE_STENCIL
clipping_visible: false
size_mode: SIZE_MODE_AUTO
}
nodes {
size {
x: 256.0
y: 256.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/pixel"
id: "background"
parent: "background_mask"
inherit_alpha: true
slice9 {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
}
nodes {
type: TYPE_BOX
texture: "druid/empty"
id: "stick_root"
parent: "root"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
visible: false
}
nodes {
scale {
x: 2.0
y: 2.0
}
color {
x: 0.0
y: 0.0
z: 0.0
}
type: TYPE_BOX
texture: "druid/ui_circle_64_blur_8"
id: "stick_shadow"
parent: "stick_root"
inherit_alpha: true
alpha: 0.25
size_mode: SIZE_MODE_AUTO
}
nodes {
scale {
x: 2.0
y: 2.0
}
color {
x: 0.463
y: 0.475
z: 0.49
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "stick"
parent: "stick_root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: -22.0
}
scale {
x: 0.5
y: 0.5
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/ui_circle_16"
id: "dot_1"
parent: "stick"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: 22.0
}
scale {
x: 0.5
y: 0.5
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/ui_circle_16"
id: "dot_2"
parent: "stick"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 22.0
}
scale {
x: 0.5
y: 0.5
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/ui_circle_16"
id: "dot_3"
parent: "stick"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -22.0
}
scale {
x: 0.5
y: 0.5
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_BOX
texture: "druid/ui_circle_16"
id: "dot_4"
parent: "stick"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,202 @@
script: ""
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 180.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.31
y: 0.318
z: 0.322
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "button"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: -90.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 180.0
y: 90.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_32"
id: "fill"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_W
adjust_mode: ADJUST_MODE_FIT
parent: "button"
layer: ""
inherit_alpha: true
slice9 {
x: 16.0
y: 16.0
z: 16.0
w: 16.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.5
y: 1.5
z: 1.0
w: 1.0
}
size {
x: 40.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.941
y: 0.984
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "X"
font: "text_bold"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 0.0
shadow_alpha: 0.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,227 @@
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
size {
x: 128.0
y: 128.0
}
color {
x: 0.902
y: 0.875
z: 0.624
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "character"
parent: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
position {
x: -25.0
y: 21.0
}
color {
x: 0.129
y: 0.141
z: 0.157
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "eye_left"
parent: "character"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: -8.0
y: 8.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_BOX
texture: "druid/ui_circle_8"
id: "eye_left_blick"
parent: "eye_left"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 25.0
y: 21.0
}
color {
x: 0.129
y: 0.141
z: 0.157
}
type: TYPE_BOX
texture: "druid/ui_circle_32"
id: "eye_right"
parent: "character"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: -8.0
y: 8.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_BOX
texture: "druid/ui_circle_8"
id: "eye_right_blick"
parent: "eye_right"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -300.0
}
type: TYPE_TEMPLATE
id: "on_screen_input"
parent: "root"
inherit_alpha: true
template: "/example/examples/gamepad/on_screen_control/on_screen_input.gui"
}
nodes {
type: TYPE_BOX
id: "on_screen_input/root"
parent: "on_screen_input"
template_node_child: true
}
nodes {
type: TYPE_TEMPLATE
id: "on_screen_input/on_screen_stick"
parent: "on_screen_input/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/root"
parent: "on_screen_input/on_screen_stick"
template_node_child: true
}
nodes {
type: TYPE_PIE
id: "on_screen_input/on_screen_stick/background_mask"
parent: "on_screen_input/on_screen_stick/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/background"
parent: "on_screen_input/on_screen_stick/background_mask"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/stick_root"
parent: "on_screen_input/on_screen_stick/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/stick_shadow"
parent: "on_screen_input/on_screen_stick/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/stick"
parent: "on_screen_input/on_screen_stick/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/dot_1"
parent: "on_screen_input/on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/dot_2"
parent: "on_screen_input/on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/dot_3"
parent: "on_screen_input/on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_stick/dot_4"
parent: "on_screen_input/on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/on_screen_button"
parent: "on_screen_input/root"
template_node_child: true
}
nodes {
type: TYPE_TEMPLATE
id: "on_screen_input/button_action"
parent: "on_screen_input/on_screen_button"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/button_action/button"
parent: "on_screen_input/button_action"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "on_screen_input/button_action/text"
parent: "on_screen_input/button_action/button"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_input/button_action/icon"
parent: "on_screen_input/button_action/button"
template_node_child: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,59 @@
local component = require("druid.component")
local on_screen_input = require("example.examples.gamepad.on_screen_control.on_screen_input")
---@class on_screen_control: druid.base_component
---@field druid druid_instance
---@field on_screen_input on_screen_input
local M = component.create("on_screen_control")
local CHARACTER_SPEED = 700
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.character = self:get_node("character")
self.character_position = gui.get_position(self.character)
self.character_eye_left = self:get_node("eye_left")
self.character_eye_right = self:get_node("eye_right")
self.on_screen_input = self.druid:new(on_screen_input, "on_screen_input") --[[@as on_screen_input]]
self.on_screen_input.on_action:subscribe(self.on_action_button, self)
self.on_screen_input.on_movement:subscribe(self.on_movement, self)
self.on_screen_input.on_movement_stop:subscribe(self.on_movement_stop, self)
end
function M:on_action_button()
gui.set_scale(self.character, vmath.vector3(1.5))
gui.animate(self.character, gui.PROP_SCALE, vmath.vector3(1), gui.EASING_INSINE, 0.2)
end
function M:on_movement(x, y, dt)
self.character_position.x = self.character_position.x + x * CHARACTER_SPEED * dt
self.character_position.y = self.character_position.y + y * CHARACTER_SPEED * dt
-- Clamp to -436, 436, area of the screen
self.character_position.x = math.min(436, math.max(-436, self.character_position.x))
self.character_position.y = math.min(436, math.max(-436, self.character_position.y))
gui.set_position(self.character, self.character_position)
-- Adjust angle of the eyes
local angle = math.deg(math.atan2(y, x)) - 135
gui.set(self.character_eye_left, "euler.z", angle)
gui.set(self.character_eye_right, "euler.z", angle)
end
function M:on_movement_stop()
gui.set(self.character_eye_left, "euler.z", 0)
gui.set(self.character_eye_right, "euler.z", 0)
end
return M

View File

@@ -0,0 +1,132 @@
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 400.0
}
type: TYPE_BOX
id: "root"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -300.0
}
type: TYPE_TEMPLATE
id: "on_screen_stick"
parent: "root"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_stick.gui"
}
nodes {
size {
x: 400.0
y: 400.0
}
type: TYPE_BOX
id: "on_screen_stick/root"
parent: "on_screen_stick"
overridden_fields: 4
template_node_child: true
}
nodes {
type: TYPE_PIE
id: "on_screen_stick/background_mask"
parent: "on_screen_stick/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/background"
parent: "on_screen_stick/background_mask"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/stick_root"
parent: "on_screen_stick/root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/stick_shadow"
parent: "on_screen_stick/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/stick"
parent: "on_screen_stick/stick_root"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/dot_1"
parent: "on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/dot_2"
parent: "on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/dot_3"
parent: "on_screen_stick/stick"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "on_screen_stick/dot_4"
parent: "on_screen_stick/stick"
template_node_child: true
}
nodes {
position {
x: 300.0
}
size {
x: 400.0
y: 400.0
}
type: TYPE_BOX
id: "on_screen_button"
parent: "root"
inherit_alpha: true
visible: false
}
nodes {
type: TYPE_TEMPLATE
id: "button_action"
parent: "on_screen_button"
inherit_alpha: true
template: "/example/examples/gamepad/gamepad_tester/templates/gamepad_button.gui"
}
nodes {
type: TYPE_BOX
id: "button_action/button"
parent: "button_action"
template_node_child: true
}
nodes {
type: TYPE_TEXT
id: "button_action/text"
parent: "button_action/button"
template_node_child: true
}
nodes {
type: TYPE_BOX
id: "button_action/icon"
parent: "button_action/button"
overridden_fields: 45
template_node_child: true
enabled: false
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,107 @@
local const = require("druid.const")
local event = require("druid.event")
local helper = require("druid.helper")
local component = require("druid.component")
---@class on_screen_input: druid.base_component
---@field druid druid_instance
---@field on_action druid.event @()
---@field on_movement druid.event @(x: number, y: number, dt: number) X/Y values are in range -1..1
---@field on_movement_stop druid.event @()
local M = component.create("on_screen_input")
local STICK_DISTANCE = 80
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.button_action = self:get_node("on_screen_button")
self.on_screen_control = self:get_node("on_screen_stick/root")
self.stick_root = self:get_node("on_screen_stick/stick_root")
self.stick_position = gui.get_position(self.stick_root)
self.on_action = event()
self.on_movement = event()
self.on_movement_stop = event()
self.is_multitouch = helper.is_multitouch_supported()
end
---@param action_id hash
---@param action action
function M:on_input(action_id, action)
if self.is_multitouch then
if action_id == const.ACTION_MULTITOUCH then
for _, touch in ipairs(action.touch) do
self:process_touch(touch)
end
end
else
if action_id == const.ACTION_TOUCH then
self:process_touch(action)
end
end
return false
end
---@param action action|touch
function M:process_touch(action)
if action.pressed and gui.pick_node(self.button_action, action.x, action.y) then
self.on_action:trigger()
gui.animate(self.button_action, gui.PROP_SCALE, vmath.vector3(1.2), gui.EASING_OUTSINE, 0.1, 0, function()
gui.animate(self.button_action, gui.PROP_SCALE, vmath.vector3(1), gui.EASING_INSINE, 0.2, 0.05)
end)
end
if gui.pick_node(self.on_screen_control, action.x, action.y) then
self._is_stick_drag = action.id or true
end
local is_the_same_touch_id = not action.id or action.id == self._is_stick_drag
if self._is_stick_drag and is_the_same_touch_id then
-- action.dx and action.dy are broken inside touches for some reason, manual calculations seems fine
local dx = action.x - (self._prev_x or action.x)
local dy = action.y - (self._prev_y or action.y)
self._prev_x = action.x
self._prev_y = action.y
self.stick_position.x = self.stick_position.x + dx
self.stick_position.y = self.stick_position.y + dy
-- Limit to STICK_DISTANCE
local length = vmath.length(self.stick_position)
if length > STICK_DISTANCE then
self.stick_position.x = self.stick_position.x / length * STICK_DISTANCE
self.stick_position.y = self.stick_position.y / length * STICK_DISTANCE
end
gui.set_position(self.stick_root, self.stick_position)
end
if action.released and is_the_same_touch_id then
self._is_stick_drag = false
self.stick_position.x = 0
self.stick_position.y = 0
self._prev_x = nil
self._prev_y = nil
gui.animate(self.stick_root, gui.PROP_POSITION, self.stick_position, gui.EASING_OUTBACK, 0.3)
self.on_movement_stop:trigger()
end
end
function M:update(dt)
if self.stick_position.x ~= 0 or self.stick_position.y ~= 0 then
self.on_movement:trigger(self.stick_position.x / STICK_DISTANCE, self.stick_position.y / STICK_DISTANCE, dt)
end
end
return M

View File

@@ -0,0 +1,18 @@
local helper = require "druid.helper"
local M = {}
function M.get_examples()
---@type druid.example.data[]
return {
{
name_id = "ui_example_intro",
information_text_id = "ui_example_intro_description",
template = "intro",
root = "intro/root",
code_url = "example/examples/intro/intro/intro.lua",
component_class = require("example.examples.intro.intro.intro"),
},
}
end
return M

View File

@@ -0,0 +1,257 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
fonts {
name: "text_regular"
font: "/example/assets/fonts/text_regular.font"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
textures {
name: "druid_logo"
texture: "/example/assets/druid_logo.atlas"
}
nodes {
size {
x: 600.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
position {
x: -180.0
y: 375.0
}
type: TYPE_BOX
texture: "druid_logo/icon_druid"
id: "icon_druid_left"
parent: "root"
layer: "druid_logo"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 180.0
y: 375.0
}
type: TYPE_BOX
texture: "druid_logo/icon_druid"
id: "icon_druid_right"
parent: "root"
layer: "druid_logo"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: 255.0
}
scale {
x: 2.0
y: 2.0
}
size {
x: 200.0
y: 40.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Hello!"
font: "text_bold"
id: "text_hello"
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -210.0
y: 191.0
}
scale {
x: 0.7
y: 0.7
}
size {
x: 600.0
y: 400.0
}
color {
x: 0.525
y: 0.525
z: 0.525
}
type: TYPE_TEXT
text: "Welcome to Druid Example Page\n"
"\n"
"Navigate over examples on the left\n"
"\n"
"Check example info on the right"
font: "text_bold"
id: "text_description"
pivot: PIVOT_NW
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -210.0
y: -189.0
}
scale {
x: 0.7
y: 0.7
}
size {
x: 600.0
y: 300.0
}
color {
x: 0.525
y: 0.525
z: 0.525
}
type: TYPE_TEXT
text: "Your donation helps me stay engaged in creating valuable projects for Defold.\n"
"\n"
"If you appreciate what I\'m doing, please consider supporting me!"
font: "text_bold"
id: "text_support"
pivot: PIVOT_W
line_break: true
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -170.0
y: -364.0
}
type: TYPE_BOX
texture: "druid/icon_heart"
id: "icon_heart1"
parent: "root"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -364.0
}
type: TYPE_BOX
texture: "druid/icon_heart"
id: "icon_heart2"
parent: "root"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 170.0
y: -364.0
}
type: TYPE_BOX
texture: "druid/icon_heart"
id: "icon_heart3"
parent: "root"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -450.0
}
size {
x: 500.0
y: 80.0
}
type: TYPE_BOX
id: "sponsor"
parent: "root"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
visible: false
}
nodes {
position {
x: -196.0
y: -3.0
}
type: TYPE_BOX
texture: "druid_logo/sponsor_github"
id: "sponsor_github"
parent: "sponsor"
layer: "druid_logo"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 21.0
y: -3.0
}
type: TYPE_BOX
texture: "druid_logo/sponsor_coffee"
id: "sponsor_coffee"
parent: "sponsor"
layer: "druid_logo"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 217.0
y: -3.0
}
type: TYPE_BOX
texture: "druid_logo/sponsor_kofi"
id: "sponsor_kofi"
parent: "sponsor"
layer: "druid_logo"
inherit_alpha: true
alpha: 0.75
size_mode: SIZE_MODE_AUTO
}
layers {
name: "druid_logo"
}
layers {
name: "text_regular"
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,40 @@
local component = require("druid.component")
local rich_text = require("druid.custom.rich_text.rich_text")
local layout = require("druid.extended.layout")
local panthera = require("panthera.panthera")
local intro_panthera = require("example.examples.intro.intro.intro_panthera")
---@class intro: druid.base_component
---@field druid druid_instance
---@field root node
local M = component.create("intro")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.druid:new(rich_text, "text_hello", "He<color=#E48155>ll</color>o!")
self.druid:new_button("sponsor_github", self.open_link, "https://github.com/sponsors/insality")
self.druid:new_button("sponsor_coffee", self.open_link, "https://www.buymeacoffee.com/insality")
self.druid:new_button("sponsor_kofi", self.open_link, "https://ko-fi.com/insality")
self.druid:new(layout, "sponsor")
:add("sponsor_github")
:add("sponsor_coffee")
:add("sponsor_kofi")
:set_margin(8, 0)
self.animation = panthera.create_gui(intro_panthera, self:get_template(), nodes)
panthera.play(self.animation, "idle", { is_loop = true })
end
function M:open_link(link)
sys.open_url(link, { target = "_blank" })
end
return M

View File

@@ -0,0 +1,560 @@
return {
version = 1,
format = "json",
type = "animation_editor",
data = {
metadata = {
fps = 60,
layers = {
{
name = "druid_logo",
color = "73E84C",
},
{
name = "text_regular",
color = "90D2F6",
},
},
gui_path = "/example/examples/intro/intro/intro.gui",
settings = {
font_size = 40,
},
gizmo_steps = {
},
},
nodes = {
},
animations = {
{
animation_id = "default",
duration = 1,
animation_keys = {
},
},
{
animation_id = "idle",
duration = 10,
animation_keys = {
{
node_id = "icon_druid_left",
property_id = "position_y",
duration = 2,
easing = "outsine",
start_value = 375,
key_type = "tween",
end_value = 370,
},
{
node_id = "icon_druid_right",
property_id = "position_y",
duration = 2,
easing = "outsine",
start_value = 375,
key_type = "tween",
end_value = 370,
},
{
end_value = 0.737,
node_id = "icon_heart1",
property_id = "color_b",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 0.38,
node_id = "icon_heart1",
property_id = "color_g",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 0.941,
node_id = "icon_heart1",
property_id = "color_r",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 1,
node_id = "icon_heart1",
property_id = "color_a",
duration = 0.7,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 1.1,
node_id = "icon_heart1",
property_id = "scale_x",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 1.1,
node_id = "icon_heart1",
property_id = "scale_y",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 1.2,
node_id = "sponsor_github",
property_id = "color_a",
start_value = 0.75,
easing = "outsine",
duration = 0.7,
key_type = "tween",
start_time = 0.7,
},
{
end_value = 0.75,
node_id = "icon_heart1",
property_id = "color_a",
duration = 1,
easing = "insine",
start_value = 1,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 1,
node_id = "icon_heart1",
property_id = "color_b",
duration = 1,
easing = "insine",
start_value = 0.737,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 1,
node_id = "icon_heart1",
property_id = "color_g",
duration = 1,
easing = "insine",
start_value = 0.38,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 1,
node_id = "icon_heart1",
property_id = "color_r",
duration = 1,
easing = "insine",
start_value = 0.941,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 1,
node_id = "icon_heart1",
property_id = "scale_x",
duration = 1,
easing = "insine",
start_value = 1.1,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 1,
node_id = "icon_heart1",
property_id = "scale_y",
duration = 1,
easing = "insine",
start_value = 1.1,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 1,
node_id = "sponsor_github",
property_id = "color_a",
start_value = 1.2,
easing = "insine",
duration = 1,
key_type = "tween",
start_time = 1.4,
},
{
end_value = 380,
node_id = "icon_druid_left",
property_id = "position_y",
duration = 2.5,
easing = "outsine",
start_value = 370,
key_type = "tween",
start_time = 2,
},
{
end_value = 380,
node_id = "icon_druid_right",
property_id = "position_y",
duration = 2.5,
easing = "outsine",
start_value = 370,
key_type = "tween",
start_time = 2,
},
{
end_value = 0.353,
node_id = "icon_heart2",
property_id = "color_b",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "color_g",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "color_r",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "color_a",
duration = 0.7,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1.1,
node_id = "icon_heart2",
property_id = "scale_x",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1.1,
node_id = "icon_heart2",
property_id = "scale_y",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1.2,
node_id = "sponsor_coffee",
property_id = "color_a",
duration = 0.7,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 3.7,
},
{
end_value = 1.2,
node_id = "icon_druid_left",
property_id = "color_a",
duration = 0.35,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 4.15,
},
{
end_value = 1.2,
node_id = "icon_druid_right",
property_id = "color_a",
duration = 0.35,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 4.15,
},
{
end_value = 0.75,
node_id = "icon_heart2",
property_id = "color_a",
duration = 1,
easing = "insine",
start_value = 1,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "color_b",
duration = 1,
easing = "insine",
start_value = 0.353,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "color_g",
duration = 1,
easing = "insine",
start_value = 1,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "color_r",
duration = 1,
easing = "insine",
start_value = 1,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "scale_x",
duration = 1,
easing = "insine",
start_value = 1.1,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 1,
node_id = "icon_heart2",
property_id = "scale_y",
duration = 1,
easing = "insine",
start_value = 1.1,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 1,
node_id = "sponsor_coffee",
property_id = "color_a",
duration = 1,
easing = "insine",
start_value = 1.2,
key_type = "tween",
start_time = 4.4,
},
{
end_value = 0.75,
node_id = "icon_druid_left",
property_id = "color_a",
duration = 1.15,
easing = "outsine",
start_value = 1.2,
key_type = "tween",
start_time = 4.5,
},
{
end_value = 0.75,
node_id = "icon_druid_right",
property_id = "color_a",
duration = 1.15,
easing = "outsine",
start_value = 1.2,
key_type = "tween",
start_time = 4.5,
},
{
end_value = 375,
node_id = "icon_druid_left",
property_id = "position_y",
duration = 5.5,
easing = "insine",
start_value = 380,
key_type = "tween",
start_time = 4.5,
},
{
end_value = 375,
node_id = "icon_druid_right",
property_id = "position_y",
duration = 5.5,
easing = "insine",
start_value = 380,
key_type = "tween",
start_time = 4.5,
},
{
end_value = 0.478,
node_id = "icon_heart3",
property_id = "color_b",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 0.494,
node_id = "icon_heart3",
property_id = "color_g",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "color_r",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "color_a",
duration = 0.7,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 1.1,
node_id = "icon_heart3",
property_id = "scale_x",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 1.1,
node_id = "icon_heart3",
property_id = "scale_y",
duration = 0.7,
easing = "outsine",
start_value = 1,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 1.2,
node_id = "sponsor_kofi",
property_id = "color_a",
duration = 0.7,
easing = "outsine",
start_value = 0.75,
key_type = "tween",
start_time = 6.7,
},
{
end_value = 0.75,
node_id = "icon_heart3",
property_id = "color_a",
duration = 1,
easing = "insine",
start_value = 1,
key_type = "tween",
start_time = 7.4,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "color_b",
duration = 1,
easing = "insine",
start_value = 0.478,
key_type = "tween",
start_time = 7.4,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "color_g",
duration = 1,
easing = "insine",
start_value = 0.494,
key_type = "tween",
start_time = 7.4,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "color_r",
duration = 1,
easing = "insine",
start_value = 1,
key_type = "tween",
start_time = 7.4,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "scale_x",
duration = 1,
easing = "insine",
start_value = 1.1,
key_type = "tween",
start_time = 7.4,
},
{
end_value = 1,
node_id = "icon_heart3",
property_id = "scale_y",
duration = 1,
easing = "insine",
start_value = 1.1,
key_type = "tween",
start_time = 7.4,
},
{
end_value = 1,
node_id = "sponsor_kofi",
property_id = "color_a",
duration = 1,
easing = "insine",
start_value = 1.2,
key_type = "tween",
start_time = 7.4,
},
},
},
},
},
}

View File

@@ -0,0 +1,190 @@
script: ""
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 500.0
z: 0.0
w: 1.0
}
color {
x: 0.173
y: 0.184
z: 0.204
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_64"
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 500.0
y: 500.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/empty"
id: "layout"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: false
material: ""
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 70.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 0.631
y: 0.843
z: 0.961
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: "druid/ui_circle_16"
id: "prefab"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "layout"
layer: ""
inherit_alpha: true
slice9 {
x: 8.0
y: 8.0
z: 8.0
w: 8.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
material: ""
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@@ -0,0 +1,76 @@
local helper = require("druid.helper")
local component = require("druid.component")
local layout = require("druid.extended.layout")
---@class basic_layout: druid.base_component
---@field druid druid_instance
---@field root node
local M = component.create("basic_layout")
local PIVOTS = {
gui.PIVOT_CENTER,
gui.PIVOT_N,
gui.PIVOT_NE,
gui.PIVOT_E,
gui.PIVOT_SE,
gui.PIVOT_S,
gui.PIVOT_SW,
gui.PIVOT_W,
gui.PIVOT_NW,
}
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.layout = self.druid:new(layout, "layout", "horizontal_wrap")
self.prefab = self:get_node("prefab")
gui.set_enabled(self.prefab, false)
local default_size = gui.get_size(self.prefab)
self.nodes = {}
for _ = 1, 12 do
local node = gui.clone(self.prefab)
-- Set different size for some nodes
if math.random() > 0.5 then
local size = vmath.vector3(default_size.x * 2, default_size.y, 0)
gui.set_size(node, size)
end
-- Set random pivot point for each node
local pivot = PIVOTS[math.random(1, #PIVOTS)]
gui.set_pivot(node, pivot)
gui.set_enabled(node, true)
self.layout:add(node)
table.insert(self.nodes, node)
end
end
function M:set_pivot(pivot)
local offset = helper.get_pivot_offset(pivot)
local size = gui.get_size(self.root)
local pos = vmath.vector3(size.x * offset.x, size.y * offset.y, 0)
gui.set_position(self.layout.node, pos)
gui.set_pivot(self.layout.node, pivot)
self.layout:refresh_layout()
end
function M:on_remove()
self.layout:clear_layout()
for _, node in ipairs(self.nodes) do
gui.delete_node(node)
end
end
return M

View File

@@ -0,0 +1,91 @@
local M = {}
---@return druid.example.data[]
function M.get_examples()
---@type druid.example.data[]
return {
{
name_id = "ui_example_layout_basic",
information_text_id = "ui_example_layout_basic_description",
template = "basic_layout",
root = "basic_layout/root",
code_url = "example/examples/layout/basic/basic_layout.lua",
component_class = require("example.examples.layout.basic.basic_layout"),
properties_control = function(instance, properties_panel)
---@cast instance basic_layout
properties_panel:add_slider("ui_padding", 0, function(value)
local padding = math.floor((value * 64) * 100) / 100
instance.layout:set_padding(vmath.vector4(padding))
end)
properties_panel:add_slider("ui_margin_x", 0, function(value)
local margin = math.floor((value * 64) * 100) / 100
instance.layout:set_margin(margin, nil)
end)
properties_panel:add_slider("ui_margin_y", 0, function(value)
local margin = math.floor((value * 64) * 100) / 100
instance.layout:set_margin(nil, margin)
end)
properties_panel:add_checkbox("ui_justify", false, function(value)
instance.layout:set_justify(value)
end)
local pivot_index = 1
local pivot_list = {
gui.PIVOT_CENTER,
gui.PIVOT_W,
gui.PIVOT_SW,
gui.PIVOT_S,
gui.PIVOT_SE,
gui.PIVOT_E,
gui.PIVOT_NE,
gui.PIVOT_N,
gui.PIVOT_NW,
}
properties_panel:add_button("ui_pivot_next", function()
pivot_index = pivot_index + 1
if pivot_index > #pivot_list then
pivot_index = 1
end
instance:set_pivot(pivot_list[pivot_index])
end)
local type_index = 1
local type_list = {
"horizontal_wrap",
"horizontal",
"vertical",
}
properties_panel:add_button("ui_type_next", function()
type_index = type_index + 1
if type_index > #type_list then
type_index = 1
end
instance.layout:set_type(type_list[type_index])
end)
end,
get_debug_info = function(instance)
---@cast instance basic_layout
local layout = instance.layout
local p = layout.padding
local info = ""
info = info .. "Layout: " .. layout.type .. "\n"
info = info .. "Padding: " .. math.floor(p.x) .. " " .. math.floor(p.y) .. " " .. math.floor(p.z) .. " " .. math.floor(p.w) .. "\n"
info = info .. "Margin: " .. layout.margin.x .. " " .. layout.margin.y .. "\n"
info = info .. "Justify: " .. tostring(layout.is_justify) .. "\n"
info = info .. "Pivot: " .. tostring(gui.get_pivot(layout.node)) .. "\n"
return info
end
}
}
end
return M

View File

@@ -0,0 +1,218 @@
fonts {
name: "text_bold"
font: "/example/assets/fonts/text_bold.font"
}
textures {
name: "animation_blend"
texture: "/example/examples/panthera/animation_blend/assets/animation_blend.atlas"
}
textures {
name: "druid"
texture: "/example/assets/druid.atlas"
}
nodes {
size {
x: 1000.0
y: 1000.0
}
color {
x: 0.173
y: 0.184
z: 0.204
}
type: TYPE_BOX
texture: "druid/ui_circle_64"
id: "root"
inherit_alpha: true
slice9 {
x: 32.0
y: 32.0
z: 32.0
w: 32.0
}
}
nodes {
size {
x: 100.0
y: 100.0
}
type: TYPE_BOX
id: "character"
parent: "root"
inherit_alpha: true
visible: false
}
nodes {
type: TYPE_BOX
texture: "animation_blend/pink_body_squircle"
id: "body"
parent: "character"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: 2.0
}
size {
x: 100.0
y: 40.0
}
type: TYPE_BOX
id: "eyes"
parent: "body"
inherit_alpha: true
visible: false
}
nodes {
position {
x: -32.0
}
type: TYPE_BOX
texture: "animation_blend/facial_part_eye_open"
id: "eye_left"
parent: "eyes"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: 34.0
}
rotation {
z: 5.0
}
type: TYPE_BOX
texture: "animation_blend/facial_part_eyebrow_b"
id: "brow_left"
parent: "eye_left"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 32.0
}
type: TYPE_BOX
texture: "animation_blend/facial_part_eye_open"
id: "eye_right"
parent: "eyes"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: 34.0
}
rotation {
z: -5.0
}
scale {
x: -1.0
}
type: TYPE_BOX
texture: "animation_blend/facial_part_eyebrow_b"
id: "brow_right"
parent: "eye_right"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -35.0
}
type: TYPE_BOX
texture: "animation_blend/facial_part_mouth_happy"
id: "mouth"
parent: "body"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: 130.0
}
rotation {
z: -10.0
}
type: TYPE_BOX
texture: "animation_blend/pink_hand_open"
id: "hand_left"
parent: "body"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
x: -130.0
}
rotation {
z: 10.0
}
scale {
x: -1.0
}
type: TYPE_BOX
texture: "animation_blend/pink_hand_open"
id: "hand_right"
parent: "body"
inherit_alpha: true
size_mode: SIZE_MODE_AUTO
}
nodes {
position {
y: -445.0
}
size {
x: 600.0
y: 100.0
}
color {
x: 0.31
y: 0.318
z: 0.322
}
type: TYPE_TEXT
text: "Hover mouse over this area"
font: "text_bold"
id: "text_hint"
outline {
x: 1.0
y: 1.0
z: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
}
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
nodes {
position {
x: -200.0
y: 430.0
}
size {
x: 400.0
y: 100.0
}
color {
x: 0.941
y: 0.984
}
type: TYPE_TEXT
text: "Rich text"
font: "text_bold"
id: "rich_text_kenney"
pivot: PIVOT_W
parent: "root"
inherit_alpha: true
outline_alpha: 0.0
shadow_alpha: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@@ -0,0 +1,75 @@
local panthera = require("panthera.panthera")
local component = require("druid.component")
local helper = require("druid.helper")
local event = require("druid.event")
local lang_text = require("druid.extended.lang_text")
local rich_text = require("druid.custom.rich_text.rich_text")
local character_animation_blend = require("example.examples.panthera.animation_blend.character_animation_blend")
---@class animation_blend: druid.base_component
---@field root node
---@field druid druid_instance
local M = component.create("animation_blend")
---@param template string
---@param nodes table<hash, node>
function M:init(template, nodes)
self.druid = self:get_druid(template, nodes)
self.root = self:get_node("root")
self.root_size = gui.get_size(self.root)
self.druid:new(lang_text, "text_hint", "ui_example_panthera_animation_blend_hint")
self.animation_idle = panthera.create_gui(character_animation_blend, self:get_template(), nodes)
self.animation_vertical = panthera.create_gui(character_animation_blend, self:get_template(), nodes)
self.animation_horizontal = panthera.create_gui(character_animation_blend, self:get_template(), nodes)
panthera.play(self.animation_idle, "idle", {
is_loop = true,
})
self:setup_rich_text()
self.on_update = event()
end
---@param action_id hash
---@param action action
function M:on_input(action_id, action)
if action_id == nil and gui.pick_node(self.root, action.x, action.y) then
local root_screen_pos = gui.get_screen_position(self.root)
local gui_scale = helper.get_gui_scale()
local dx = (action.screen_x - root_screen_pos.x) / gui_scale -- -root_size.x / 2 .. root_size.x / 2
local animation_progress_x = (dx + self.root_size.x / 2) / self.root_size.x -- 0 .. 1
panthera.set_time(self.animation_horizontal, "horizontal", animation_progress_x)
local dy = (action.screen_y - root_screen_pos.y) / gui_scale -- -root_size.y / 2 .. root_size.y / 2
local animation_progress_y = (dy + self.root_size.y / 2) / self.root_size.y -- 0 .. 1
panthera.set_time(self.animation_vertical, "vertical", animation_progress_y)
end
end
function M:update()
self.on_update:trigger()
end
function M:setup_rich_text()
self.rich_text = self.druid:new(rich_text, "rich_text_kenney", "Character assets by <color=865BD9><link>Kenney</link></color>")
local tagged = self.rich_text:tagged("link")
for index = 1, #tagged do
---@type druid.rich_text.word
local word = tagged[index]
self.druid:new_button(word.node, function()
sys.open_url("https://kenney.nl/")
end)
end
end
return M

View File

@@ -0,0 +1,46 @@
images {
image: "/example/examples/panthera/animation_blend/assets/facial_part_eye_open.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/facial_part_eyebrow_b.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/facial_part_mouth_happy.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/facial_part_mouth_smirk.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/pink_body_squircle.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/pink_hand_closed.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/pink_hand_open.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/pink_hand_point.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/shadow.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
images {
image: "/example/examples/panthera/animation_blend/assets/facial_part_eye_half_top.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
margin: 0
extrude_borders: 2
inner_padding: 0
max_page_width: 0
max_page_height: 0
rename_patterns: ""

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

Some files were not shown because too many files have changed in this diff Show More