Remove uncompleted stuff

This commit is contained in:
Insality 2025-03-26 23:30:29 +02:00
parent 91f2d593d2
commit dee77ab313
17 changed files with 13 additions and 600 deletions

View File

@ -1,37 +0,0 @@
-- Place this script nearby with the gui component to able make requests
-- To the go namespace from GUI with events systems (cross context)
local event_queue = require("druid.event_queue")
---Usage: event_queue.request("druid.get_atlas_path", callback, gui.get_texture(self.node), msg.url())
---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"
---@param texture_name hash The name from gui.get_texture(node)
---@param sender hash Just msg.url from the caller
local function get_atlas_path(texture_name, sender)
local my_url = msg.url()
my_url.fragment = nil
local copy_url = msg.url(sender)
copy_url.fragment = nil
-- This check should works well
local is_my_url = my_url == copy_url
if not is_my_url then
return nil
end
return go.get(sender, "textures", { key = texture_name })
end
function init(self)
event_queue.subscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path)
end
function final(self)
event_queue.unsubscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path)
end

View File

@ -1,84 +0,0 @@
local event = require("event.event")
---@class event.queue
local M = {}
local event_handlers = {}
local pending_callbacks = {}
---Request to handle a specified event and processes the queue of callbacks associated with it.
---If event has already been triggered, the callback will be executed immediately.
---If event not triggered yet, callback will be executed when event will be triggered.
---It triggered only once and then removed from the queue.
---@param event_name string The name of the event to trigger.
---@param callback fun() The callback function to execute upon triggering.
---@param ... any Additional arguments for the callback.
function M.request(event_name, callback, ...)
pending_callbacks[event_name] = pending_callbacks[event_name] or {}
table.insert(pending_callbacks[event_name], { event.create(callback), ... })
M.process_pending_callbacks(event_name)
end
---Subscribes to a specified event and executes a callback when the event is triggered.
-- If the event has already been triggered, the callback will be executed immediately.
---@param event_name string The name of the event to subscribe to.
---@param callback fun() The function to call when the event is triggered.
function M.subscribe(event_name, callback)
event_handlers[event_name] = event_handlers[event_name] or event.create()
if event_handlers[event_name] then
event_handlers[event_name]:subscribe(callback)
end
M.process_pending_callbacks(event_name)
end
---Unsubscribes a callback function from a specified event.
---@param event_name string The name of the event to unsubscribe from.
---@param callback fun() The function to remove from the event's subscription list.
function M.unsubscribe(event_name, callback)
if event_handlers[event_name] then
event_handlers[event_name]:unsubscribe(callback)
end
end
---Processes the queue for a given event name, executing callbacks and handling results.
---Processed callbacks are removed from the queue.
---@param event_name string The name of the event for which to process the queue.
function M.process_pending_callbacks(event_name)
local callbacks_to_process = pending_callbacks[event_name]
local event_handler = event_handlers[event_name]
if not callbacks_to_process or not event_handler then
return
end
-- Loop through the queue in reverse to prevent index errors during removal
for i = #callbacks_to_process, 1, -1 do
local callback_entry = callbacks_to_process[i]
-- Better to figure out how to make it without 2 unpacks, but ok for all our cases now
local args = { unpack(callback_entry, 2) }
-- Safely call the event handler and handle errors
local success, result = pcall(event_handler.trigger, event_handler, unpack(args))
if success and result then
local callback_function = callback_entry[1]
pcall(callback_function, result) -- Safely invoke the callback, catching any errors
table.remove(callbacks_to_process, i) -- Remove the processed callback from the queue
end
end
-- Clean up if the callback queue is empty
if #callbacks_to_process == 0 then
pending_callbacks[event_name] = nil
end
end
return M

View File

@ -1,84 +0,0 @@
#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_perspective;
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;
}

View File

@ -1,43 +0,0 @@
name: "repeat"
tags: "gui"
vertex_program: "/druid/materials/gui_repeat/gui_repeat.vp"
fragment_program: "/druid/materials/gui_repeat/gui_repeat.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: "perspective"
type: CONSTANT_TYPE_USER
value {
}
}
vertex_constants {
name: "uv_rotated"
type: CONSTANT_TYPE_USER
value {
x: 1.0
}
}

View File

@ -1,50 +0,0 @@
#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]
vec4 perspective; // [perspective_x, perspective_y, zoom, 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_perspective;
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_perspective = perspective;
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
);
// Matrix Info = mat4(
// scale_x, skew_x, 0, offset_x,
// skew_y, scale_y, 0, offset_y,
// 0, 0, scale_z, offset_z,
// perspective_x, perspective_y, perspective_z, zoom
//)
gl_Position = view_proj * vec4(position.xyz, 1.0) * transform;
}

View File

@ -1,13 +0,0 @@
#version 140
in mediump vec2 var_texcoord0;
in mediump vec4 var_color;
out vec4 out_fragColor;
uniform mediump sampler2D texture_sampler;
void main()
{
out_fragColor = texture(texture_sampler, var_texcoord0.xy) * var_color;
}

View File

@ -1,7 +1,7 @@
name: "gui_world" name: "gui_world"
tags: "tile" tags: "tile"
vertex_program: "/druid/materials/gui_world/gui_world.vp" vertex_program: "/builtins/materials/gui.vp"
fragment_program: "/druid/materials/gui_world/gui_world.fp" fragment_program: "/builtins/materials/gui.fp"
vertex_constants { vertex_constants {
name: "view_proj" name: "view_proj"
type: CONSTANT_TYPE_VIEWPROJ type: CONSTANT_TYPE_VIEWPROJ

View File

@ -1,20 +0,0 @@
#version 140
in mediump vec3 position;
in mediump vec2 texcoord0;
in mediump vec4 color;
out mediump vec2 var_texcoord0;
out mediump vec4 var_color;
uniform vs_uniforms
{
mediump mat4 view_proj;
};
void main()
{
var_texcoord0 = texcoord0;
var_color = vec4(color.rgb * color.a, color.a);
gl_Position = view_proj * vec4(position.xyz, 1.0);
}

View File

@ -1,18 +0,0 @@
#version 140
uniform sampler2D texture_sampler;
in vec2 var_texcoord0;
in vec4 var_color;
out vec4 color_out;
void main() {
lowp vec4 tex = texture(texture_sampler, var_texcoord0.xy);
if (tex.a < 0.5) {
discard;
}
// Final color of stencil texture
color_out = tex * var_color;
}

View File

@ -1,8 +0,0 @@
name: "repeat"
tags: "gui"
vertex_program: "/druid/materials/stencil/gui_stencil.vp"
fragment_program: "/druid/materials/stencil/gui_stencil.fp"
vertex_constants {
name: "view_proj"
type: CONSTANT_TYPE_VIEWPROJ
}

View File

@ -1,20 +0,0 @@
#version 140
uniform vertex_inputs {
highp mat4 view_proj;
};
// positions are in world space
in mediump vec3 position;
in mediump vec2 texcoord0;
in lowp vec4 color;
out mediump vec2 var_texcoord0;
out lowp vec4 var_color;
void main()
{
var_texcoord0 = texcoord0;
var_color = vec4(color.rgb * color.a, color.a);
gl_Position = view_proj * vec4(position.xyz, 1.0);
}

View File

@ -9,10 +9,10 @@ out vec4 color_out;
void main() { void main() {
lowp vec4 tex = texture(texture_sampler, var_texcoord0.xy); lowp vec4 tex = texture(texture_sampler, var_texcoord0.xy);
if (tex.a < 0.5) { if (tex.a < 0.5) {
discard; discard;
} }
// Final color of stencil texture
color_out = tex * var_color; color_out = tex * var_color;
} }

View File

@ -1,6 +1,6 @@
name: "repeat" name: "repeat"
tags: "gui" tags: "gui"
vertex_program: "/druid/materials/stencil/gui_stencil.vp" vertex_program: "/builtins/materials/gui.vp"
fragment_program: "/druid/materials/stencil/gui_stencil.fp" fragment_program: "/druid/materials/stencil/gui_stencil.fp"
vertex_constants { vertex_constants {
name: "view_proj" name: "view_proj"

View File

@ -1,20 +0,0 @@
#version 140
uniform vertex_inputs {
highp mat4 view_proj;
};
// positions are in world space
in mediump vec3 position;
in mediump vec2 texcoord0;
in lowp vec4 color;
out mediump vec2 var_texcoord0;
out lowp vec4 var_color;
void main()
{
var_texcoord0 = texcoord0;
var_color = vec4(color.rgb * color.a, color.a);
gl_Position = view_proj * vec4(position.xyz, 1.0);
}

View File

@ -1,194 +0,0 @@
local helper = require("druid.helper")
local event_queue = require("druid.event_queue")
---@class druid.node_repeat: 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
gui.set_material(self.node, hash("gui_repeat"))
self.time = 0
self.margin = 0
self.params = gui.get(self.node, "params") --[[@as vector4]]
self:get_atlas_path(function(atlas_path)
self.is_inited = self:init_tiling_animation(atlas_path)
local repeat_x, repeat_y = self:get_repeat()
self:animate(repeat_x, repeat_y)
end)
--self.druid.events.on_node_property_changed:subscribe(self.on_node_property_changed, self)
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
function M:get_atlas_path(callback)
event_queue.request("druid.get_atlas_path", callback, gui.get_texture(self.node), msg.url())
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:animate(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_perpective(perspective_x, perspective_y)
if perspective_x then
gui.set(self.node, "perspective.x", perspective_x)
end
if perspective_y then
gui.set(self.node, "perspective.y", perspective_y)
end
return self
end
function M:set_perpective_offset(offset_x, offset_y)
if offset_x then
gui.set(self.node, "perspective.z", offset_x)
end
if offset_y then
gui.set(self.node, "perspective.w", offset_y)
end
return self
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

View File

@ -4713,9 +4713,6 @@ nodes {
template_node_child: true template_node_child: true
} }
nodes { nodes {
position {
x: -200.0
}
type: TYPE_TEMPLATE type: TYPE_TEMPLATE
id: "property_input" id: "property_input"
parent: "widgets" parent: "widgets"

View File

@ -23,6 +23,7 @@
"ui_type_next": "Next Type", "ui_type_next": "Next Type",
"ui_adjust_next": "Next Adjust", "ui_adjust_next": "Next Adjust",
"ui_enabled": "Enabled", "ui_enabled": "Enabled",
"ui_item_size": "Item Size",
"ui_examples_basic": "Basic", "ui_examples_basic": "Basic",
"ui_examples_data_list": "Data List", "ui_examples_data_list": "Data List",
@ -183,9 +184,15 @@
"ui_example_widget_fps_panel": "FPS Panel", "ui_example_widget_fps_panel": "FPS Panel",
"ui_example_widget_fps_panel_description": "Here is a example of FPS panel usage", "ui_example_widget_fps_panel_description": "Here is a example of FPS panel usage",
"ui_example_widget_mini_graph": "Mini Graph",
"ui_example_widget_mini_graph_description": "Here is a example of mini graph usage",
"ui_example_widget_properties_panel": "Properties Panel", "ui_example_widget_properties_panel": "Properties Panel",
"ui_example_widget_properties_panel_description": "Here is a example of properties panel usage", "ui_example_widget_properties_panel_description": "Here is a example of properties panel usage",
"ui_example_widget_property_input": "Property Input",
"ui_example_widget_property_input_description": "Here is a example of property input usage",
"ui_example_gamepad_tester": "Gamepad Tester", "ui_example_gamepad_tester": "Gamepad Tester",
"ui_example_gamepad_tester_description": "Test your gamepad here to bind buttons and axes", "ui_example_gamepad_tester_description": "Test your gamepad here to bind buttons and axes",
@ -215,4 +222,4 @@
"ui_language_it": "Italiano", "ui_language_it": "Italiano",
"ui_language_kr": "한국어", "ui_language_kr": "한국어",
"ui_language_zh": "中文" "ui_language_zh": "中文"
} }