Move bindings to druid, update widgets

This commit is contained in:
Insality 2025-02-18 21:12:56 +02:00
parent 5eaa50552a
commit dd5f619345
10 changed files with 103 additions and 95 deletions

View File

@ -1,48 +0,0 @@
local event = require("event.event")
local M = {}
local WRAPPED_WIDGETS = {}
---Set a widget to the current game object. The game object can acquire the widget by calling `bindings.get_widget`
---It wraps with events only top level functions cross-context, so no access to nested widgets functions
---@param widget druid.widget
function M.set_widget(widget)
local object = msg.url()
object.fragment = nil
-- Make a copy of the widget with all functions wrapped in events
-- It makes available to call gui functions from game objects
local wrapped_widget = setmetatable({}, { __index = widget })
local parent_table = getmetatable(widget).__index
-- Go through all functions and wrap them in events
for key, value in pairs(parent_table) do
if type(value) == "function" then
wrapped_widget[key] = event.create(function(_, ...)
return value(widget, ...)
end)
end
end
WRAPPED_WIDGETS[object.socket] = WRAPPED_WIDGETS[object.socket] or {}
WRAPPED_WIDGETS[object.socket][object.path] = wrapped_widget
end
---@param object_url string|userdata|url @root object
---@return druid.widget|nil
function M.get_widget(object_url)
assert(object_url, "You must provide an object_url")
object_url = msg.url(object_url --[[@as string]])
local socket_widgets = WRAPPED_WIDGETS[object_url.socket]
if not socket_widgets then
return nil
end
return socket_widgets[object_url.path]
end
return M

View File

@ -86,32 +86,20 @@ function M.lerp(t, color1, color2)
return vmath.vector4(r, g, b, a) return vmath.vector4(r, g, b, a)
end end
---@param hex string ---@param hex string
---@param alpha number|nil ---@return number, number, number
---@return number, number, number, number function M.hex2rgb(hex)
function M.hex2rgb(hex, alpha) if not hex or #hex < 3 then
alpha = alpha or 1 return 0, 0, 0
if alpha > 1 then
alpha = alpha / 100
end end
-- Remove leading # hex = hex:gsub("^#", "")
if string.sub(hex, 1, 1) == "#" then
hex = string.sub(hex, 2)
end
-- Expand 3-digit hex codes to 6 digits
if #hex == 3 then if #hex == 3 then
hex = string.rep(string.sub(hex, 1, 1), 2) .. hex = hex:gsub("(.)", "%1%1")
string.rep(string.sub(hex, 2, 2), 2) ..
string.rep(string.sub(hex, 3, 3), 2)
end end
return tonumber("0x" .. hex:sub(1,2)) / 255,
local r = tonumber("0x" .. string.sub(hex, 1, 2)) / 255 tonumber("0x" .. hex:sub(3,4)) / 255,
local g = tonumber("0x" .. string.sub(hex, 3, 4)) / 255 tonumber("0x" .. hex:sub(5,6)) / 255
local b = tonumber("0x" .. string.sub(hex, 5, 6)) / 255
return r, g, b, alpha
end end
@ -119,8 +107,8 @@ end
---@param alpha number|nil ---@param alpha number|nil
---@return vector4 ---@return vector4
function M.hex2vector4(hex, alpha) function M.hex2vector4(hex, alpha)
local r, g, b, a = M.hex2rgb(hex, alpha) local r, g, b = M.hex2rgb(hex)
return vmath.vector4(r, g, b, a) return vmath.vector4(r, g, b, alpha or 1)
end end
@ -226,4 +214,4 @@ end
M.load_palette() M.load_palette()
return M return M

View File

@ -1,3 +1,4 @@
local event = require("event.event")
local events = require("event.events") local events = require("event.events")
local settings = require("druid.system.settings") local settings = require("druid.system.settings")
local druid_instance = require("druid.system.druid_instance") local druid_instance = require("druid.system.druid_instance")
@ -83,4 +84,49 @@ function M.on_language_change()
end end
local WRAPPED_WIDGETS = {}
---Set a widget to the current game object. The game object can acquire the widget by calling `bindings.get_widget`
---It wraps with events only top level functions cross-context, so no access to nested widgets functions
---@param widget druid.widget
function M.set_widget(widget)
local object = msg.url()
object.fragment = nil
-- Make a copy of the widget with all functions wrapped in events
-- It makes available to call gui functions from game objects
local wrapped_widget = setmetatable({}, { __index = widget })
local parent_table = getmetatable(widget).__index
-- Go through all functions and wrap them in events
for key, value in pairs(parent_table) do
if type(value) == "function" then
wrapped_widget[key] = event.create(function(_, ...)
return value(widget, ...)
end)
end
end
WRAPPED_WIDGETS[object.socket] = WRAPPED_WIDGETS[object.socket] or {}
WRAPPED_WIDGETS[object.socket][object.path] = wrapped_widget
end
---@param object_url string|userdata|url|nil Root object, if nil current object will be used
---@return druid.widget|nil
function M.get_widget(object_url)
object_url = object_url or msg.url()
if object_url then
object_url = msg.url(object_url --[[@as string]])
end
local socket_widgets = WRAPPED_WIDGETS[object_url.socket]
if not socket_widgets then
return nil
end
return socket_widgets[object_url.path]
end
return M return M

View File

@ -42,6 +42,9 @@ function M:init()
self.container = self.druid:new_container(self.root) self.container = self.druid:new_container(self.root)
self.container:add_container(self.mini_graph.container) self.container:add_container(self.mini_graph.container)
local container_content = self.container:add_container("content")
container_content:add_container("text_min_fps")
container_content:add_container("text_fps")
end end
@ -98,4 +101,4 @@ function M:push_fps_value()
end end
return M return M

View File

@ -117,6 +117,7 @@ nodes {
y: 1.0 y: 1.0
z: 1.0 z: 1.0
} }
adjust_mode: ADJUST_MODE_STRETCH
parent: "content" parent: "content"
inherit_alpha: true inherit_alpha: true
outline_alpha: 0.0 outline_alpha: 0.0
@ -155,6 +156,7 @@ nodes {
y: 1.0 y: 1.0
z: 1.0 z: 1.0
} }
adjust_mode: ADJUST_MODE_STRETCH
parent: "content" parent: "content"
inherit_alpha: true inherit_alpha: true
outline_alpha: 0.0 outline_alpha: 0.0

View File

@ -40,6 +40,9 @@ function M:init()
self.container = self.druid:new_container(self.root) self.container = self.druid:new_container(self.root)
self.container:add_container(self.mini_graph.container) self.container:add_container(self.mini_graph.container)
local container_content = self.container:add_container("content")
container_content:add_container("text_max_value")
container_content:add_container("text_per_second")
end end
@ -93,4 +96,4 @@ function M:update_text_memory()
end end
return M return M

View File

@ -23,6 +23,7 @@ nodes {
type: TYPE_BOX type: TYPE_BOX
texture: "druid/ui_circle_16" texture: "druid/ui_circle_16"
id: "root" id: "root"
adjust_mode: ADJUST_MODE_STRETCH
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {
x: 8.0 x: 8.0
@ -120,6 +121,7 @@ nodes {
texture: "druid/ui_circle_16" texture: "druid/ui_circle_16"
id: "content" id: "content"
pivot: PIVOT_S pivot: PIVOT_S
adjust_mode: ADJUST_MODE_STRETCH
parent: "root" parent: "root"
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {

View File

@ -11,6 +11,7 @@ function M:init()
self.root = self:get_node("root") self.root = self:get_node("root")
self.text_header = self.druid:new_text("text_header") self.text_header = self.druid:new_text("text_header")
self.icon_drag = self:get_node("icon_drag")
self.druid:new_drag("header", self.on_drag_widget) self.druid:new_drag("header", self.on_drag_widget)
self.druid:new_button("icon_drag", self.toggle_hide) self.druid:new_button("icon_drag", self.toggle_hide)
:set_style(nil) :set_style(nil)
@ -34,7 +35,11 @@ function M:init()
self.values = {} self.values = {}
self.container = self.druid:new_container(self.root) self.container = self.druid:new_container(self.root)
self.container:add_container("header") local container_header = self.container:add_container("header", "stretch_x")
container_header:add_container("text_header")
container_header:add_container("icon_drag")
self.container:add_container("content", "stretch_x")
self.default_size = self.container:get_size() self.default_size = self.container:get_size()
end end
@ -141,6 +146,10 @@ end
function M:on_drag_widget(dx, dy) function M:on_drag_widget(dx, dy)
if not gui.is_enabled(self.icon_drag) then
return
end
local position = self.container:get_position() local position = self.container:get_position()
self.container:set_position(position.x + dx, position.y + dy) self.container:set_position(position.x + dx, position.y + dy)
end end
@ -159,4 +168,4 @@ function M:toggle_hide()
end end
return M return M

View File

@ -13,7 +13,7 @@ textures {
nodes { nodes {
size { size {
x: 400.0 x: 400.0
y: 240.0 y: 400.0
} }
color { color {
x: 0.173 x: 0.173
@ -23,6 +23,7 @@ nodes {
type: TYPE_BOX type: TYPE_BOX
texture: "druid/ui_circle_16" texture: "druid/ui_circle_16"
id: "root" id: "root"
pivot: PIVOT_N
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {
x: 8.0 x: 8.0
@ -32,9 +33,6 @@ nodes {
} }
} }
nodes { nodes {
position {
y: 120.0
}
size { size {
x: 400.0 x: 400.0
y: 40.0 y: 40.0
@ -105,15 +103,15 @@ nodes {
} }
nodes { nodes {
position { position {
y: -120.0 y: -50.0
} }
size { size {
x: 400.0 x: 400.0
y: 190.0 y: 350.0
} }
type: TYPE_BOX type: TYPE_BOX
id: "content" id: "content"
pivot: PIVOT_S pivot: PIVOT_N
parent: "root" parent: "root"
inherit_alpha: true inherit_alpha: true
size_mode: SIZE_MODE_AUTO size_mode: SIZE_MODE_AUTO
@ -122,11 +120,10 @@ nodes {
nodes { nodes {
position { position {
x: -200.0 x: -200.0
y: 190.0
} }
size { size {
x: 400.0 x: 400.0
y: 190.0 y: 350.0
} }
type: TYPE_BOX type: TYPE_BOX
texture: "druid/empty" texture: "druid/empty"
@ -141,7 +138,7 @@ nodes {
nodes { nodes {
size { size {
x: 400.0 x: 400.0
y: 190.0 y: 350.0
} }
type: TYPE_BOX type: TYPE_BOX
texture: "druid/pixel" texture: "druid/pixel"
@ -159,7 +156,7 @@ nodes {
} }
nodes { nodes {
position { position {
y: 170.0 y: -10.0
} }
type: TYPE_BOX type: TYPE_BOX
texture: "druid/empty" texture: "druid/empty"

View File

@ -14,6 +14,7 @@ local property_vector3 = require("druid.widget.properties_panel.properties.prope
---@field container_content druid.container ---@field container_content druid.container
---@field container_scroll_view druid.container ---@field container_scroll_view druid.container
---@field contaienr_scroll_content druid.container ---@field contaienr_scroll_content druid.container
---@field button_hidden druid.button
---@field text_header druid.text ---@field text_header druid.text
---@field paginator widget.property_left_right_selector ---@field paginator widget.property_left_right_selector
---@field properties druid.widget[] List of created properties ---@field properties druid.widget[] List of created properties
@ -47,8 +48,9 @@ function M:init()
self.layout.on_size_changed:subscribe(self.on_size_changed, self) self.layout.on_size_changed:subscribe(self.on_size_changed, self)
self.druid:new_drag("header", self.on_drag_widget) self.druid:new_drag("header", self.on_drag_widget)
self.druid:new_button("icon_drag", self.toggle_hide) self.button_hidden = self.druid:new_button("icon_drag", function()
:set_style(nil) self:set_hidden(not self._is_hidden)
end):set_style(nil)
self.property_checkbox_prefab = self:get_node("property_checkbox/root") self.property_checkbox_prefab = self:get_node("property_checkbox/root")
gui.set_enabled(self.property_checkbox_prefab, false) gui.set_enabled(self.property_checkbox_prefab, false)
@ -130,7 +132,7 @@ function M:on_size_changed(new_size)
self.container_content:set_size(new_size.x, new_size.y, gui.PIVOT_N) self.container_content:set_size(new_size.x, new_size.y, gui.PIVOT_N)
self.default_size = vmath.vector3(new_size.x, new_size.y + 50, 0) self.default_size = vmath.vector3(new_size.x, new_size.y + 50, 0)
if not self.is_hidden then if not self._is_hidden then
self.container:set_size(self.default_size.x, self.default_size.y, gui.PIVOT_N) self.container:set_size(self.default_size.x, self.default_size.y, gui.PIVOT_N)
end end
@ -292,15 +294,19 @@ function M:remove(widget)
end end
function M:toggle_hide() function M:set_hidden(is_hidden)
self.is_hidden = not self.is_hidden self._is_hidden = is_hidden
local hidden_size = gui.get_size(self:get_node("header")) local hidden_size = gui.get_size(self:get_node("header"))
local new_size = self.is_hidden and hidden_size or self.default_size local new_size = self._is_hidden and hidden_size or self.default_size
self.container:set_size(new_size.x, new_size.y, gui.PIVOT_N) self.container:set_size(new_size.x, new_size.y, gui.PIVOT_N)
gui.set_enabled(self.content, not self.is_hidden) gui.set_enabled(self.content, not self._is_hidden)
return self end
function M:is_hidden()
return self._is_hidden
end end