mirror of
https://github.com/Insality/druid
synced 2025-06-26 18:07:46 +02:00
Update
This commit is contained in:
parent
b053b5044b
commit
3f22e9c542
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -32,11 +32,10 @@
|
||||
"Lua.diagnostics.libraryFiles": "Disable",
|
||||
"Lua.runtime.version": "Lua 5.1",
|
||||
"Lua.workspace.library": [
|
||||
"~/Library/Application Support/Code/User/globalStorage/astronachos.defold",
|
||||
"~/Library/Application Support/Code/User/workspaceStorage/72e25b7e0fdc873ee6f7baa61edbd6b1/astronachos.defold",
|
||||
"~/Library/Application Support/Code/User/workspaceStorage/1446075a23c89451a63f0e82b2291def/astronachos.defold"
|
||||
"~/Library/Application Support/Cursor/User/globalStorage/astronachos.defold",
|
||||
"~/Library/Application Support/Cursor/User/workspaceStorage/1446075a23c89451a63f0e82b2291def/astronachos.defold"
|
||||
],
|
||||
"files.exclude": {
|
||||
"**/*.gui": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
druid/druid.script
Normal file
42
druid/druid.script
Normal file
@ -0,0 +1,42 @@
|
||||
-- Place this script nearby with the gui component to able make requests
|
||||
-- To the go namespace from GUI with events systems (cross context)
|
||||
|
||||
local defer = require("event.defer")
|
||||
|
||||
---Usage: defer.push("druid.get_atlas_path", {
|
||||
--- texture_name = gui.get_texture(self.node),
|
||||
--- sender = msg.url(),
|
||||
---}, callback, [context])
|
||||
---Pass texture name to get atlas info and sender url to check if the request is valid
|
||||
local MESSAGE_GET_ATLAS_PATH = "druid.get_atlas_path"
|
||||
|
||||
---@class druid.get_atlas_path_request
|
||||
---@field texture_name hash
|
||||
---@field sender hash
|
||||
|
||||
---@param request druid.get_atlas_path_request
|
||||
---@return string?
|
||||
local function get_atlas_path(self, request)
|
||||
local my_url = msg.url()
|
||||
my_url.fragment = nil
|
||||
|
||||
local copy_url = msg.url(request.sender)
|
||||
copy_url.fragment = nil
|
||||
|
||||
-- This check should works well
|
||||
if my_url ~= copy_url then
|
||||
return nil
|
||||
end
|
||||
|
||||
return go.get(request.sender, "textures", { key = request.texture_name })
|
||||
end
|
||||
|
||||
|
||||
function init(self)
|
||||
defer.subscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path, self)
|
||||
end
|
||||
|
||||
|
||||
function final(self)
|
||||
defer.unsubscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path, self)
|
||||
end
|
83
druid/materials/gui_tiling_node/gui_tiling_node.fp
Normal file
83
druid/materials/gui_tiling_node/gui_tiling_node.fp
Normal file
@ -0,0 +1,83 @@
|
||||
#version 140
|
||||
|
||||
uniform sampler2D texture_sampler;
|
||||
|
||||
in vec2 var_texcoord0;
|
||||
in vec4 var_color;
|
||||
in vec4 var_uv;
|
||||
in vec4 var_repeat; // [repeat_x, repeat_y, anchor_x, anchor_y]
|
||||
in vec4 var_params; // [margin_x, margin_y, offset_x, offset_y]
|
||||
in vec4 var_uv_rotated;
|
||||
|
||||
out vec4 color_out;
|
||||
|
||||
void main() {
|
||||
vec2 pivot = var_repeat.zw;
|
||||
// Margin is a value between 0 and 1 that means offset/padding from the one image to another
|
||||
vec2 margin = var_params.xy;
|
||||
vec2 offset = var_params.zw;
|
||||
vec2 repeat = var_repeat.xy;
|
||||
|
||||
// Atlas UV to local UV [0, 1]
|
||||
float u = (var_texcoord0.x - var_uv.x) / (var_uv.z - var_uv.x);
|
||||
float v = (var_texcoord0.y - var_uv.y) / (var_uv.w - var_uv.y);
|
||||
|
||||
// Adjust local UV by the pivot point. So 0:0 will be at the pivot point of node
|
||||
u = u - (0.5 + pivot.x);
|
||||
v = v - (0.5 - pivot.y);
|
||||
|
||||
// If rotated, swap UV
|
||||
if (var_uv_rotated.y < 0.5) {
|
||||
float temp = u;
|
||||
u = v;
|
||||
v = temp;
|
||||
}
|
||||
|
||||
// Adjust repeat by the margin
|
||||
repeat.x = repeat.x / (1.0 + margin.x);
|
||||
repeat.y = repeat.y / (1.0 + margin.y);
|
||||
|
||||
// Repeat is a value between 0 and 1 that represents the number of times the texture is repeated in the atlas.
|
||||
float tile_u = fract(u * repeat.x);
|
||||
float tile_v = fract(v * repeat.y);
|
||||
|
||||
float tile_width = 1.0 / repeat.x;
|
||||
float tile_height = 1.0 / repeat.y;
|
||||
|
||||
// Adjust tile UV by the pivot point.
|
||||
// Not center is left top corner, need to adjust it to pivot point
|
||||
tile_u = fract(tile_u + pivot.x + 0.5);
|
||||
tile_v = fract(tile_v - pivot.y + 0.5);
|
||||
|
||||
// Apply offset
|
||||
tile_u = fract(tile_u + offset.x);
|
||||
tile_v = fract(tile_v + offset.y);
|
||||
|
||||
// Extend margins
|
||||
margin = margin * 0.5;
|
||||
tile_u = mix(0.0 - margin.x, 1.0 + margin.x, tile_u);
|
||||
tile_v = mix(0.0 - margin.y, 1.0 + margin.y, tile_v);
|
||||
float alpha = 0.0;
|
||||
// If the tile is outside the margins, make it transparent, without IF
|
||||
alpha = step(0.0, tile_u) * step(tile_u, 1.0) * step(0.0, tile_v) * step(tile_v, 1.0);
|
||||
|
||||
tile_u = clamp(tile_u, 0.0, 1.0); // Keep borders in the range 0-1
|
||||
tile_v = clamp(tile_v, 0.0, 1.0); // Keep borders in the range 0-1
|
||||
|
||||
if (var_uv_rotated.y < 0.5) {
|
||||
float temp = tile_u;
|
||||
tile_u = tile_v;
|
||||
tile_v = temp;
|
||||
}
|
||||
|
||||
// Remap local UV to the atlas UV
|
||||
vec2 uv = vec2(
|
||||
mix(var_uv.x, var_uv.z, tile_u), // Get texture coordinate from the atlas
|
||||
mix(var_uv.y, var_uv.w, tile_v) // Get texture coordinate from the atlas
|
||||
//mix(var_uv.x, var_uv.z, tile_u * var_uv_rotated.x + tile_v * var_uv_rotated.z),
|
||||
//mix(var_uv.y, var_uv.w, 1.0 - (tile_u * var_uv_rotated.y + tile_v * var_uv_rotated.x))
|
||||
);
|
||||
|
||||
lowp vec4 tex = texture(texture_sampler, uv);
|
||||
color_out = tex * var_color;
|
||||
}
|
37
druid/materials/gui_tiling_node/gui_tiling_node.material
Normal file
37
druid/materials/gui_tiling_node/gui_tiling_node.material
Normal file
@ -0,0 +1,37 @@
|
||||
name: "repeat"
|
||||
tags: "gui"
|
||||
vertex_program: "/druid/materials/gui_tiling_node/gui_tiling_node.vp"
|
||||
fragment_program: "/druid/materials/gui_tiling_node/gui_tiling_node.fp"
|
||||
vertex_constants {
|
||||
name: "view_proj"
|
||||
type: CONSTANT_TYPE_VIEWPROJ
|
||||
}
|
||||
vertex_constants {
|
||||
name: "uv_coord"
|
||||
type: CONSTANT_TYPE_USER
|
||||
value {
|
||||
z: 1.0
|
||||
w: 1.0
|
||||
}
|
||||
}
|
||||
vertex_constants {
|
||||
name: "uv_repeat"
|
||||
type: CONSTANT_TYPE_USER
|
||||
value {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
}
|
||||
}
|
||||
vertex_constants {
|
||||
name: "params"
|
||||
type: CONSTANT_TYPE_USER
|
||||
value {
|
||||
}
|
||||
}
|
||||
vertex_constants {
|
||||
name: "uv_rotated"
|
||||
type: CONSTANT_TYPE_USER
|
||||
value {
|
||||
x: 1.0
|
||||
}
|
||||
}
|
40
druid/materials/gui_tiling_node/gui_tiling_node.vp
Normal file
40
druid/materials/gui_tiling_node/gui_tiling_node.vp
Normal file
@ -0,0 +1,40 @@
|
||||
#version 140
|
||||
|
||||
in mediump vec3 position;
|
||||
in mediump vec2 texcoord0;
|
||||
in lowp vec4 color;
|
||||
|
||||
uniform vertex_inputs
|
||||
{
|
||||
highp mat4 view_proj;
|
||||
highp vec4 uv_coord;
|
||||
highp vec4 uv_repeat; // [repeat_x, repeat_y, pivot_x, pivot_y]
|
||||
vec4 uv_rotated;
|
||||
vec4 params; // [margin_x, margin_y, offset_x, offset_y]
|
||||
};
|
||||
|
||||
out mediump vec2 var_texcoord0;
|
||||
out lowp vec4 var_color;
|
||||
out highp vec4 var_uv;
|
||||
out highp vec4 var_repeat;
|
||||
out vec4 var_params;
|
||||
out vec4 var_uv_rotated;
|
||||
|
||||
void main()
|
||||
{
|
||||
var_texcoord0 = texcoord0;
|
||||
var_color = vec4(color.rgb * color.a, color.a);
|
||||
var_uv = uv_coord;
|
||||
var_repeat = uv_repeat;
|
||||
var_params = params;
|
||||
var_uv_rotated = uv_rotated;
|
||||
|
||||
mat4 transform = mat4(
|
||||
1.0, 0, 0, 0.0,
|
||||
0, 1.0, 0, 0.0,
|
||||
0, 0, 1, 0,
|
||||
0.0, position.z, 0, 1.0
|
||||
);
|
||||
|
||||
gl_Position = view_proj * vec4(position.xyz, 1.0) * transform;
|
||||
}
|
168
druid/widget/tiling_node/tiling_node.lua
Normal file
168
druid/widget/tiling_node/tiling_node.lua
Normal file
@ -0,0 +1,168 @@
|
||||
local helper = require("druid.helper")
|
||||
local defer = require("event.defer")
|
||||
|
||||
---@class druid.tiling_node: druid.widget
|
||||
---@field animation table
|
||||
---@field node node
|
||||
---@field params vector4
|
||||
---@field time number
|
||||
local M = {}
|
||||
|
||||
M.PROP_SIZE_X = hash("size.x")
|
||||
M.PROP_SIZE_Y = hash("size.y")
|
||||
M.PROP_SCALE_X = hash("scale.x")
|
||||
M.PROP_SCALE_Y = hash("scale.y")
|
||||
|
||||
function M:init(node)
|
||||
self.node = self:get_node(node)
|
||||
self.animation = nil
|
||||
self.time = 0
|
||||
self.margin = 0
|
||||
|
||||
self.params = gui.get(self.node, "params") --[[@as vector4]]
|
||||
|
||||
defer.push("druid.get_atlas_path", {
|
||||
texture_name = gui.get_texture(self.node),
|
||||
sender = msg.url(),
|
||||
}, self.on_get_atlas_path, self)
|
||||
end
|
||||
|
||||
|
||||
function M:on_get_atlas_path(atlas_path)
|
||||
self.is_inited = self:init_tiling_animation(atlas_path)
|
||||
local repeat_x, repeat_y = self:get_repeat()
|
||||
self:refresh(repeat_x, repeat_y)
|
||||
end
|
||||
|
||||
|
||||
function M:on_node_property_changed(node, property)
|
||||
if not self.is_inited or node ~= self.node then
|
||||
return
|
||||
end
|
||||
|
||||
if property == "size" or property == "scale" then
|
||||
local repeat_x, repeat_y = self:get_repeat()
|
||||
self:set_repeat(repeat_x, repeat_y)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function M:get_repeat()
|
||||
if not self.is_inited then
|
||||
return 1, 1
|
||||
end
|
||||
local size_x = gui.get(self.node, M.PROP_SIZE_X)
|
||||
local size_y = gui.get(self.node, M.PROP_SIZE_Y)
|
||||
local scale_x = gui.get(self.node, M.PROP_SCALE_X)
|
||||
local scale_y = gui.get(self.node, M.PROP_SCALE_Y)
|
||||
|
||||
local repeat_x = (size_x / self.animation.width) / scale_x
|
||||
local repeat_y = (size_y / self.animation.height) / scale_y
|
||||
|
||||
return repeat_x, repeat_y
|
||||
end
|
||||
|
||||
|
||||
---@return boolean
|
||||
function M:init_tiling_animation(atlas_path)
|
||||
if not atlas_path then
|
||||
print("No atlas path found for node", gui.get_id(self.node), gui.get_texture(self.node))
|
||||
print("Probably you should add druid.script at window collection to access resources")
|
||||
return false
|
||||
end
|
||||
|
||||
self.animation = helper.get_animation_data_from_node(self.node, atlas_path)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Start our repeat shader work
|
||||
---@param repeat_x number X factor
|
||||
---@param repeat_y number Y factor
|
||||
function M:refresh(repeat_x, repeat_y)
|
||||
if not self.is_inited then
|
||||
return
|
||||
end
|
||||
|
||||
local node = self.node
|
||||
local animation = self.animation
|
||||
|
||||
local frame = animation.frames[1]
|
||||
gui.set(node, "uv_coord", frame.uv_coord)
|
||||
self:set_repeat(repeat_x, repeat_y)
|
||||
|
||||
if #animation.frames > 1 and animation.fps > 0 then
|
||||
animation.handle =
|
||||
timer.delay(1/animation.fps, true, function(self, handle, time_elapsed)
|
||||
local next_rame = animation.frames[animation.current_frame]
|
||||
gui.set(node, "uv_coord", next_rame.uv_coord)
|
||||
|
||||
animation.current_frame = animation.current_frame + 1
|
||||
if animation.current_frame > #animation.frames then
|
||||
animation.current_frame = 1
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function M:final()
|
||||
local animation = self.animation
|
||||
if animation.handle then
|
||||
timer.cancel(animation.handle)
|
||||
animation.handle = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---Update repeat factor values
|
||||
---@param repeat_x number? X factor
|
||||
---@param repeat_y number? Y factor
|
||||
function M:set_repeat(repeat_x, repeat_y)
|
||||
local animation = self.animation
|
||||
animation.v.x = repeat_x or animation.v.x
|
||||
animation.v.y = repeat_y or animation.v.y
|
||||
|
||||
local anchor = helper.get_pivot_offset(gui.get_pivot(self.node))
|
||||
animation.v.z = anchor.x
|
||||
animation.v.w = anchor.y
|
||||
|
||||
gui.set(self.node, "uv_repeat", animation.v)
|
||||
end
|
||||
|
||||
|
||||
function M:set_offset(offset_perc_x, offset_perc_y)
|
||||
self.params.z = offset_perc_x or self.params.z
|
||||
self.params.w = offset_perc_y or self.params.w
|
||||
gui.set(self.node, "params", self.params)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
function M:set_margin(margin_x, margin_y)
|
||||
self.params.x = margin_x or self.params.x
|
||||
self.params.y = margin_y or self.params.y
|
||||
gui.set(self.node, "params", self.params)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
---@param scale number
|
||||
function M:set_scale(scale)
|
||||
local current_scale_x = gui.get(self.node, M.PROP_SCALE_X)
|
||||
local current_scale_y = gui.get(self.node, M.PROP_SCALE_Y)
|
||||
local current_size_x = gui.get(self.node, M.PROP_SIZE_X)
|
||||
local current_size_y = gui.get(self.node, M.PROP_SIZE_Y)
|
||||
|
||||
local delta_scale_x = scale / current_scale_x
|
||||
local delta_scale_y = scale / current_scale_y
|
||||
gui.set(self.node, M.PROP_SCALE_X, scale)
|
||||
gui.set(self.node, M.PROP_SCALE_Y, scale)
|
||||
gui.set(self.node, M.PROP_SIZE_X, current_size_x / delta_scale_x)
|
||||
gui.set(self.node, M.PROP_SIZE_Y, current_size_y / delta_scale_y)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -110,7 +110,7 @@ end
|
||||
|
||||
|
||||
function M:update_components()
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
---@diagnostic disable-next-line, invisible
|
||||
local components = #self.druid.components_all
|
||||
|
||||
self.text_components_amount:set_text(tostring(components))
|
||||
|
@ -1,18 +1,12 @@
|
||||
local component = require("druid.component")
|
||||
|
||||
---@class property_button: druid.component
|
||||
---@class property_button: druid.widget
|
||||
---@field root node
|
||||
---@field text_name druid.lang_text
|
||||
---@field button druid.button
|
||||
---@field text_button druid.text
|
||||
---@field druid druid.instance
|
||||
local M = component.create("property_button")
|
||||
local M = {}
|
||||
|
||||
---@param template string
|
||||
---@param nodes table<hash, node>
|
||||
function M:init(template, nodes)
|
||||
self.druid = self:get_druid(template, nodes)
|
||||
|
||||
function M:init()
|
||||
self.root = self:get_node("root")
|
||||
self.text_name = self.druid:new_lang_text("text_name") --[[@as druid.lang_text]]
|
||||
self.selected = self:get_node("selected")
|
||||
|
@ -1,18 +1,12 @@
|
||||
local component = require("druid.component")
|
||||
|
||||
---@class property_checkbox: druid.component
|
||||
---@field druid druid.instance
|
||||
---@class property_checkbox: druid.widget
|
||||
---@field root druid.container
|
||||
---@field text_name druid.lang_text
|
||||
---@field button druid.button
|
||||
---@field selected node
|
||||
local M = component.create("property_checkbox")
|
||||
local M = {}
|
||||
|
||||
|
||||
---@param template string
|
||||
---@param nodes table<hash, node>
|
||||
function M:init(template, nodes)
|
||||
self.druid = self:get_druid(template, nodes)
|
||||
function M:init()
|
||||
self.root = self.druid:new_container("root") --[[@as druid.container]]
|
||||
|
||||
self.icon = self:get_node("icon")
|
||||
|
@ -1,19 +1,12 @@
|
||||
local component = require("druid.component")
|
||||
|
||||
---@class property_slider: druid.component
|
||||
---@field druid druid.instance
|
||||
---@class property_slider: druid.widget
|
||||
---@field root druid.container
|
||||
---@field text_name druid.lang_text
|
||||
---@field text_value druid.text
|
||||
---@field slider druid.slider
|
||||
local M = component.create("property_slider")
|
||||
local M = {}
|
||||
|
||||
|
||||
---@param template string
|
||||
---@param nodes table<hash, node>
|
||||
function M:init(template, nodes)
|
||||
self.druid = self:get_druid(template, nodes)
|
||||
|
||||
function M:init()
|
||||
self.root = self.druid:new_container("root") --[[@as druid.container]]
|
||||
self.selected = self:get_node("selected")
|
||||
gui.set_alpha(self.selected, 0)
|
||||
|
@ -87,7 +87,7 @@ end
|
||||
---@return property_slider
|
||||
function M:add_slider(text_id, initial_value, on_change_callback)
|
||||
local nodes = gui.clone_tree(self.property_slider_prefab)
|
||||
local instance = self.druid:new(property_slider, "property_slider", nodes) --[[@as property_slider]]
|
||||
local instance = self.druid:new_widget(property_slider, "property_slider", nodes) --[[@as property_slider]]
|
||||
instance.text_name:translate(text_id)
|
||||
instance:set_value(initial_value, true)
|
||||
|
||||
|
@ -6,5 +6,9 @@ embedded_instances {
|
||||
" id: \"druid\"\n"
|
||||
" component: \"/example/druid.gui\"\n"
|
||||
"}\n"
|
||||
"components {\n"
|
||||
" id: \"druid1\"\n"
|
||||
" component: \"/druid/druid.script\"\n"
|
||||
"}\n"
|
||||
""
|
||||
}
|
||||
|
@ -4785,6 +4785,25 @@ nodes {
|
||||
parent: "property_input/E_Anchor"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEMPLATE
|
||||
id: "example_tiling_node"
|
||||
parent: "widgets"
|
||||
inherit_alpha: true
|
||||
template: "/example/examples/widgets/tiling_node/example_tiling_node.gui"
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "example_tiling_node/root"
|
||||
parent: "example_tiling_node"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "example_tiling_node/tiling_node"
|
||||
parent: "example_tiling_node/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -20.0
|
||||
|
@ -3,7 +3,7 @@ local intro_panthera = require("example.examples.intro.intro.intro_panthera")
|
||||
|
||||
---@class examples.intro: druid.widget
|
||||
---@field root node
|
||||
---@field animation panthera.instance
|
||||
---@field animation panthera.animation
|
||||
local M = {}
|
||||
|
||||
|
||||
|
@ -7,9 +7,9 @@ local character_animation_blend = require("example.examples.panthera.animation_b
|
||||
---@class examples.animation_blend: druid.widget
|
||||
---@field root node
|
||||
---@field root_size vector3
|
||||
---@field animation_idle panthera.instance
|
||||
---@field animation_vertical panthera.instance
|
||||
---@field animation_horizontal panthera.instance
|
||||
---@field animation_idle panthera.animation
|
||||
---@field animation_vertical panthera.animation
|
||||
---@field animation_horizontal panthera.animation
|
||||
---@field rich_text druid.rich_text
|
||||
---@field on_update event
|
||||
local M = {}
|
||||
|
@ -3,7 +3,7 @@ local panthera = require("panthera.panthera")
|
||||
local basic_animation_panthera = require("example.examples.panthera.basic_animation.basic_animation_panthera")
|
||||
|
||||
---@class examples.basic_animation: druid.widget
|
||||
---@field animation panthera.instance
|
||||
---@field animation panthera.animation
|
||||
---@field button druid.button
|
||||
local M = {}
|
||||
|
||||
|
@ -177,6 +177,37 @@ function M.get_examples()
|
||||
end
|
||||
end)
|
||||
end,
|
||||
},
|
||||
{
|
||||
name_id = "ui_example_widget_tiling_node",
|
||||
information_text_id = "ui_example_widget_tiling_node_description",
|
||||
template = "example_tiling_node",
|
||||
root = "example_tiling_node/root",
|
||||
code_url = "example/examples/widgets/tiling_node/example_tiling_node.lua",
|
||||
widget_class = require("example.examples.widgets.tiling_node.example_tiling_node"),
|
||||
properties_control = function(instance, properties_panel)
|
||||
---@cast instance examples.example_tiling_node
|
||||
properties_panel:add_slider("Repeat X", 0, function(value)
|
||||
local repeat_x = math.floor(value * 10)
|
||||
instance.tiling_node:refresh(repeat_x, nil)
|
||||
end)
|
||||
properties_panel:add_slider("Repeat Y", 0, function(value)
|
||||
local repeat_y = math.floor(value * 10)
|
||||
instance.tiling_node:refresh(nil, repeat_y)
|
||||
end)
|
||||
properties_panel:add_slider("Offset X", 0, function(value)
|
||||
instance.tiling_node:set_offset(value, nil)
|
||||
end)
|
||||
properties_panel:add_slider("Offset Y", 0, function(value)
|
||||
instance.tiling_node:set_offset(nil, value)
|
||||
end)
|
||||
properties_panel:add_slider("Margin X", 0, function(value)
|
||||
instance.tiling_node:set_margin(value, nil)
|
||||
end)
|
||||
properties_panel:add_slider("Margin Y", 0, function(value)
|
||||
instance.tiling_node:set_margin(nil, value)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
33
example/examples/widgets/tiling_node/example_tiling_node.gui
Normal file
33
example/examples/widgets/tiling_node/example_tiling_node.gui
Normal file
@ -0,0 +1,33 @@
|
||||
textures {
|
||||
name: "tiling_texture"
|
||||
texture: "/example/examples/widgets/tiling_node/tiling_texture.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: 500.0
|
||||
y: 500.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "tiling_texture/pattern_0004"
|
||||
id: "tiling_node"
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
material: "gui_tiling_node"
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||
materials {
|
||||
name: "gui_tiling_node"
|
||||
material: "/druid/materials/gui_tiling_node/gui_tiling_node.material"
|
||||
}
|
12
example/examples/widgets/tiling_node/example_tiling_node.lua
Normal file
12
example/examples/widgets/tiling_node/example_tiling_node.lua
Normal file
@ -0,0 +1,12 @@
|
||||
local tiling_node = require("druid.widget.tiling_node.tiling_node")
|
||||
|
||||
---@class examples.example_tiling_node: druid.widget
|
||||
local M = {}
|
||||
|
||||
|
||||
function M:init()
|
||||
self.tiling_node = self.druid:new_widget(tiling_node, nil, nil, self:get_node("tiling_node"))
|
||||
end
|
||||
|
||||
|
||||
return M
|
BIN
example/examples/widgets/tiling_node/pattern_0004.png
Normal file
BIN
example/examples/widgets/tiling_node/pattern_0004.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
images {
|
||||
image: "/example/examples/widgets/tiling_node/pattern_0004.png"
|
||||
}
|
@ -10,7 +10,7 @@ local window_animation_panthera = require("example.examples.windows.window_anima
|
||||
---@field button_close druid.button
|
||||
---@field button_accept druid.button
|
||||
---@field button_decline druid.button
|
||||
---@field animation panthera.instance
|
||||
---@field animation panthera.animation
|
||||
local M = {}
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ local window_animation_panthera = require("example.examples.windows.window_anima
|
||||
---@field text_description druid.lang_text
|
||||
---@field button_close druid.button
|
||||
---@field button_accept druid.button
|
||||
---@field animation panthera.instance
|
||||
---@field animation panthera.animation
|
||||
local M = {}
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@ local window_animation_panthera = require("example.examples.windows.window_anima
|
||||
---@field lang_buttons table<string, druid.button>
|
||||
---@field grid druid.grid
|
||||
---@field on_language_change event
|
||||
---@field animation panthera.instance
|
||||
---@field animation panthera.animation
|
||||
local M = {}
|
||||
|
||||
|
||||
|
@ -58,7 +58,7 @@ cssfile = /builtins/manifests/web/dark_theme.css
|
||||
show_console_banner = 0
|
||||
|
||||
[native_extension]
|
||||
app_manifest =
|
||||
app_manifest =
|
||||
|
||||
[graphics]
|
||||
texture_profiles = /builtins/graphics/default.texture_profiles
|
||||
|
@ -3,7 +3,7 @@ local mock = require("deftest.mock.mock")
|
||||
local M = {}
|
||||
|
||||
-- Userdata type instead of script self
|
||||
---@return vector3|vector4
|
||||
---@return vector
|
||||
function M.get_context()
|
||||
return vmath.vector({})
|
||||
end
|
||||
|
@ -586,20 +586,19 @@ Hello! Druid 1.1 is here! It's brings a lot of new features and improvements. Le
|
||||
|
||||
**Changelog 1.1**
|
||||
- Remove external annotations, remove old HTML API page
|
||||
- Fully annotated code and new API readme page (hope more comfortable to use)
|
||||
- Fully annotated code and new API README page (hope more comfortable to use)
|
||||
- Widgets here!
|
||||
- A replacement for `custom_component`. Basically it's the same, but widgets contains no boilerplate code and more convinient to use.
|
||||
- A replacement for `custom_components`. Basically it's the same, but `widgets` contains no boilerplate code and more convinient to use.
|
||||
- Now I can include a kind of `widgets` with Druid and you can use it almost instantly in your project.
|
||||
- Removed `druid.register()`. Now all components are available by default and available with `self.druid:new_*` functions
|
||||
- This means the druid will be bigger in size, but it's much comfortable to use
|
||||
- This means the Druid will be bigger in size, but it's much comfortable to use
|
||||
- In case you want to delete components you not using, you can do it in fork in `druid.lua` file
|
||||
- Any additional widgets, color library will be not included until you use it
|
||||
- Remove `druid.event`, replaced with defold-event library. Now it required to double dependency to use Druid.
|
||||
- Remove `druid.event`, replaced with `defold-event` library. Now it required to double dependency to use Druid.
|
||||
- Add Druid UI kit, contains atlas so now you can use Druid GUI files in your projects.
|
||||
- Contains mostly basic shapes for my UI and can contains several icons. Atlas is a small, only `128x128` size and will be included in build only if you use it.
|
||||
- Contains mostly basic shapes for the UI and can contains several icons. Atlas is a small, only `128x128` size and will be included in build only if you use it.
|
||||
- [Text]: Add `trim_left` and `scale_then_trim_left` text adjust modes
|
||||
- [Text]: Add `set_text` function instead `set_to` (now it deprecated)
|
||||
- Add `druid.bindings` module to handle cross-context widgets
|
||||
- Add `druid.color` module to work with colors and palettes
|
||||
- Add `container` component to handle more complex adaptive layouts
|
||||
- [Shaders] Add repeat, hard image stencil and world gui materials
|
||||
|
Loading…
x
Reference in New Issue
Block a user