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