mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 02:17:52 +02:00
More widgets stuff, cleaning code
This commit is contained in:
parent
37190684c4
commit
c35dfc7066
@ -212,7 +212,9 @@ end
|
||||
---@param node_or_node_id node|string
|
||||
---@param on_drag_callback function
|
||||
function M:init(node_or_node_id, on_drag_callback)
|
||||
self.druid = self:get_druid()
|
||||
self.node = self:get_node(node_or_node_id)
|
||||
self.hover = self.druid:new_hover(self.node)
|
||||
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
@ -239,6 +241,20 @@ function M:init(node_or_node_id, on_drag_callback)
|
||||
self.on_drag_end = Event()
|
||||
|
||||
self:on_window_resized()
|
||||
self:set_drag_cursors(true)
|
||||
end
|
||||
|
||||
|
||||
---Set Drag component enabled state.
|
||||
---@param is_enabled boolean
|
||||
function M:set_drag_cursors(is_enabled)
|
||||
if defos and is_enabled then
|
||||
self.hover.style.ON_HOVER_CURSOR = defos.CURSOR_CROSSHAIR
|
||||
self.hover.style.ON_MOUSE_HOVER_CURSOR = defos.CURSOR_HAND
|
||||
else
|
||||
self.hover.style.ON_HOVER_CURSOR = nil
|
||||
self.hover.style.ON_MOUSE_HOVER_CURSOR = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -796,6 +796,8 @@ function M:_update_size()
|
||||
self:_set_scroll_position(self.position.x, self.position.y)
|
||||
self.target_position.x = self.position.x
|
||||
self.target_position.y = self.position.y
|
||||
|
||||
self.drag:set_drag_cursors(self.drag.can_x or self.drag.can_y)
|
||||
end
|
||||
|
||||
|
||||
|
@ -391,10 +391,11 @@ end
|
||||
|
||||
|
||||
--- Set text to text field
|
||||
---@deprecated
|
||||
---@param set_to string Text for node
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_to(set_to)
|
||||
set_to = set_to or ""
|
||||
set_to = tostring(set_to or "")
|
||||
|
||||
self.last_value = set_to
|
||||
gui.set_text(self.node, set_to)
|
||||
@ -407,9 +408,20 @@ function M:set_to(set_to)
|
||||
end
|
||||
|
||||
|
||||
function M:set_text(new_text)
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
return self:set_to(new_text)
|
||||
end
|
||||
|
||||
|
||||
function M:get_text()
|
||||
return self.last_value
|
||||
end
|
||||
|
||||
|
||||
--- Set text area size
|
||||
---@param size vector3 The new text area size
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_size(size)
|
||||
self.start_size = size
|
||||
self.text_area = vmath.vector3(size)
|
||||
@ -421,7 +433,7 @@ end
|
||||
|
||||
--- Set color
|
||||
---@param color vector4 Color for node
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_color(color)
|
||||
self.color = color
|
||||
gui.set_color(self.node, color)
|
||||
@ -432,7 +444,7 @@ end
|
||||
|
||||
--- Set alpha
|
||||
---@param alpha number Alpha for node
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_alpha(alpha)
|
||||
self.color.w = alpha
|
||||
gui.set_color(self.node, self.color)
|
||||
@ -443,7 +455,7 @@ end
|
||||
|
||||
--- Set scale
|
||||
---@param scale vector3 Scale for node
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_scale(scale)
|
||||
self.last_scale = scale
|
||||
gui.set_scale(self.node, scale)
|
||||
@ -454,7 +466,7 @@ end
|
||||
|
||||
--- Set text pivot. Text will re-anchor inside text area
|
||||
---@param pivot number The gui.PIVOT_* constant
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_pivot(pivot)
|
||||
local prev_pivot = gui.get_pivot(self.node)
|
||||
local prev_offset = const.PIVOTS[prev_pivot]
|
||||
@ -487,7 +499,7 @@ end
|
||||
--- Set text adjust, refresh the current text visuals, if needed
|
||||
---@param adjust_type string|nil See const.TEXT_ADJUST. If pass nil - use current adjust type
|
||||
---@param minimal_scale number|nil If pass nil - not use minimal scale
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_text_adjust(adjust_type, minimal_scale)
|
||||
self.adjust_type = adjust_type
|
||||
self._minimal_scale = minimal_scale
|
||||
@ -499,7 +511,7 @@ end
|
||||
|
||||
--- Set minimal scale for DOWNSCALE_LIMITED or SCALE_THEN_SCROLL adjust types
|
||||
---@param minimal_scale number If pass nil - not use minimal scale
|
||||
---@return Text Current text instance
|
||||
---@return druid.text Current text instance
|
||||
function M:set_minimal_scale(minimal_scale)
|
||||
self._minimal_scale = minimal_scale
|
||||
|
||||
|
48
druid/bindings.lua
Normal file
48
druid/bindings.lua
Normal file
@ -0,0 +1,48 @@
|
||||
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 only top level functions, so no access to nested widgets
|
||||
---@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
|
@ -13,6 +13,13 @@ local M = {}
|
||||
---@param color_id string
|
||||
---@return vector4
|
||||
function M.get(color_id)
|
||||
-- Check is it hex: starts with "#" or contains only 3 or 6 hex symbols
|
||||
if type(color_id) == "string" then
|
||||
if string.sub(color_id, 1, 1) == "#" or string.match(color_id, "^[0-9a-fA-F]+$") then
|
||||
return M.hex2vector4(color_id)
|
||||
end
|
||||
end
|
||||
|
||||
return PALETTE_DATA[CURRENT_PALETTE] and PALETTE_DATA[CURRENT_PALETTE][color_id] or DEFAULT_COLOR
|
||||
end
|
||||
|
||||
|
@ -1,117 +1,35 @@
|
||||
script: ""
|
||||
fonts {
|
||||
name: "text_bold"
|
||||
font: "/example/assets/fonts/text_bold.font"
|
||||
font: "/druid/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
|
||||
texture: "/druid/druid.atlas"
|
||||
}
|
||||
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
|
||||
x: 200.0
|
||||
y: 40.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: 500.0
|
||||
y: 80.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
x: 200.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
w: 1.0
|
||||
x: 0.31
|
||||
y: 0.318
|
||||
z: 0.322
|
||||
}
|
||||
type: TYPE_BOX
|
||||
blend_mode: BLEND_MODE_ALPHA
|
||||
texture: "druid/rect_round2_width1"
|
||||
texture: "druid/rect_round2_width2"
|
||||
id: "button"
|
||||
xanchor: XANCHOR_NONE
|
||||
yanchor: YANCHOR_NONE
|
||||
pivot: PIVOT_CENTER
|
||||
adjust_mode: ADJUST_MODE_FIT
|
||||
parent: "root"
|
||||
layer: ""
|
||||
inherit_alpha: true
|
||||
slice9 {
|
||||
x: 4.0
|
||||
@ -119,192 +37,89 @@ nodes {
|
||||
z: 4.0
|
||||
w: 4.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
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 480.0
|
||||
y: 60.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
x: 380.0
|
||||
y: 50.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: "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: "button"
|
||||
layer: ""
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
alpha: 1.0
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
template_node_child: false
|
||||
text_leading: 1.0
|
||||
text_tracking: 0.0
|
||||
custom_type: 0
|
||||
enabled: true
|
||||
visible: true
|
||||
material: ""
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 0.0
|
||||
y: 0.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
}
|
||||
rotation {
|
||||
x: 0.0
|
||||
y: 0.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
}
|
||||
scale {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
w: 1.0
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 480.0
|
||||
y: 60.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
x: 380.0
|
||||
y: 50.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: "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: "button"
|
||||
layer: ""
|
||||
parent: "root"
|
||||
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: 118.0
|
||||
y: 0.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
}
|
||||
rotation {
|
||||
x: 0.0
|
||||
y: 0.0
|
||||
z: 0.0
|
||||
w: 1.0
|
||||
x: 61.0
|
||||
}
|
||||
scale {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
w: 1.0
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
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: "cursor_node"
|
||||
xanchor: XANCHOR_NONE
|
||||
yanchor: YANCHOR_NONE
|
||||
pivot: PIVOT_CENTER
|
||||
adjust_mode: ADJUST_MODE_FIT
|
||||
parent: "button"
|
||||
layer: ""
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
slice9 {
|
||||
x: 8.0
|
||||
@ -312,84 +127,34 @@ nodes {
|
||||
z: 8.0
|
||||
w: 8.0
|
||||
}
|
||||
clipping_mode: CLIPPING_MODE_NONE
|
||||
clipping_visible: true
|
||||
clipping_inverted: false
|
||||
alpha: 0.5
|
||||
template_node_child: false
|
||||
size_mode: SIZE_MODE_MANUAL
|
||||
custom_type: 0
|
||||
enabled: true
|
||||
visible: true
|
||||
material: ""
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 0.0
|
||||
x: -1.4
|
||||
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: "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: "cursor_node"
|
||||
layer: ""
|
||||
inherit_alpha: false
|
||||
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
|
||||
|
@ -22,4 +22,10 @@ images {
|
||||
images {
|
||||
image: "/druid/images/panels/rect_round2_width2.png"
|
||||
}
|
||||
images {
|
||||
image: "/druid/images/icons/icon_drag.png"
|
||||
}
|
||||
images {
|
||||
image: "/druid/images/icons/icon_arrow.png"
|
||||
}
|
||||
extrude_borders: 2
|
||||
|
15
druid/editor_scripts/widget.lua_template
Normal file
15
druid/editor_scripts/widget.lua_template
Normal file
@ -0,0 +1,15 @@
|
||||
---@class widget.TEMPLATE: druid.widget
|
||||
local M = {}
|
||||
|
||||
function M:init()
|
||||
self.root = self:get_node("root")
|
||||
self.button = self.druid:new_button("button"), self.on_button, self)
|
||||
end
|
||||
|
||||
|
||||
function M:on_button()
|
||||
print("Root node", self.root)
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -196,7 +196,7 @@ end
|
||||
---Get current size of layout node
|
||||
---@return vector3 size
|
||||
function M:get_size()
|
||||
return self.size
|
||||
return vmath.vector3(self.size)
|
||||
end
|
||||
|
||||
|
||||
|
@ -88,8 +88,8 @@ end
|
||||
function M:set_padding(padding_x, padding_y, padding_z, padding_w)
|
||||
self.padding.x = padding_x or self.padding.x
|
||||
self.padding.y = padding_y or self.padding.y
|
||||
self.padding.z = padding_z or padding_x or self.padding.z
|
||||
self.padding.w = padding_w or padding_y or self.padding.w
|
||||
self.padding.z = padding_z or self.padding.z
|
||||
self.padding.w = padding_w or self.padding.w
|
||||
self.is_dirty = true
|
||||
|
||||
return self
|
||||
@ -153,7 +153,6 @@ function M:add(node_or_node_id)
|
||||
---@cast node node
|
||||
table.insert(self.entities, node)
|
||||
gui.set_parent(node, self.node)
|
||||
|
||||
self.is_dirty = true
|
||||
|
||||
return self
|
||||
@ -229,7 +228,7 @@ function M:refresh_layout()
|
||||
local node_height = rows_data.nodes_height[node]
|
||||
local pivot_offset = helper.get_pivot_offset(gui.get_pivot(node))
|
||||
|
||||
if node_width > 0 and node_height > 0 then
|
||||
if node_width > 0 or node_height > 0 then
|
||||
-- Calculate position for current node
|
||||
local position_x, position_y
|
||||
|
||||
@ -396,7 +395,7 @@ function M:calculate_rows_data()
|
||||
rows_data.nodes_height[node] = node_height
|
||||
end
|
||||
|
||||
if node_width > 0 and node_height > 0 then
|
||||
if node_width > 0 or node_height > 0 then
|
||||
if type == "horizontal" then
|
||||
current_row.width = current_row.width + node_width + margin.x
|
||||
current_row.height = math.max(current_row.height, node_height)
|
||||
|
BIN
druid/images/icons/icon_arrow.png
Normal file
BIN
druid/images/icons/icon_arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 B |
BIN
druid/images/icons/icon_drag.png
Normal file
BIN
druid/images/icons/icon_drag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 200 B |
18
druid/materials/stencil/gui_stencil.fp
Normal file
18
druid/materials/stencil/gui_stencil.fp
Normal file
@ -0,0 +1,18 @@
|
||||
#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;
|
||||
}
|
8
druid/materials/stencil/gui_stencil.material
Normal file
8
druid/materials/stencil/gui_stencil.material
Normal file
@ -0,0 +1,8 @@
|
||||
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
|
||||
}
|
20
druid/materials/stencil/gui_stencil.vp
Normal file
20
druid/materials/stencil/gui_stencil.vp
Normal file
@ -0,0 +1,20 @@
|
||||
#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);
|
||||
}
|
@ -61,7 +61,7 @@ M["hover"] = {
|
||||
}
|
||||
|
||||
M["drag"] = {
|
||||
DRAG_DEADZONE = 4, -- Size in pixels of drag deadzone
|
||||
DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone
|
||||
NO_USE_SCREEN_KOEF = false,
|
||||
}
|
||||
|
||||
|
2
druid/system/druid_annotations.lua
Normal file
2
druid/system/druid_annotations.lua
Normal file
@ -0,0 +1,2 @@
|
||||
---@class druid.widget: druid.base_component
|
||||
---@field druid druid_instance
|
@ -733,7 +733,7 @@ local rich_input = require("druid.custom.rich_input.rich_input")
|
||||
---Create RichInput component.
|
||||
-- As a template please check rich_input.gui layout.
|
||||
---@param template string The template string name
|
||||
---@param nodes table Nodes table from gui.clone_tree
|
||||
---@param nodes table|nil Nodes table from gui.clone_tree
|
||||
---@return druid.rich_input RichInput component
|
||||
function M:new_rich_input(template, nodes)
|
||||
return self:new(rich_input, template, nodes)
|
||||
|
222
druid/widget/fps_panel/fps_panel.gui
Normal file
222
druid/widget/fps_panel/fps_panel.gui
Normal file
@ -0,0 +1,222 @@
|
||||
fonts {
|
||||
name: "text_regular"
|
||||
font: "/druid/fonts/text_regular.font"
|
||||
}
|
||||
fonts {
|
||||
name: "text_bold"
|
||||
font: "/druid/fonts/text_bold.font"
|
||||
}
|
||||
textures {
|
||||
name: "druid"
|
||||
texture: "/druid/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 {
|
||||
type: TYPE_TEMPLATE
|
||||
id: "mini_graph"
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
template: "/druid/widget/mini_graph/mini_graph.gui"
|
||||
}
|
||||
nodes {
|
||||
color {
|
||||
x: 0.173
|
||||
y: 0.184
|
||||
z: 0.204
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/root"
|
||||
parent: "mini_graph"
|
||||
overridden_fields: 5
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/header"
|
||||
parent: "mini_graph/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
text: "FPS"
|
||||
id: "mini_graph/text_header"
|
||||
parent: "mini_graph/header"
|
||||
overridden_fields: 8
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/icon_drag"
|
||||
parent: "mini_graph/header"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/content"
|
||||
parent: "mini_graph/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
color {
|
||||
x: 0.525
|
||||
y: 0.525
|
||||
z: 0.525
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/prefab_line"
|
||||
parent: "mini_graph/content"
|
||||
overridden_fields: 5
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
color {
|
||||
x: 0.957
|
||||
y: 0.608
|
||||
z: 0.608
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/color_low"
|
||||
parent: "mini_graph/content"
|
||||
overridden_fields: 5
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
x: 200.0
|
||||
y: 100.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "content"
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -96.0
|
||||
y: 12.0
|
||||
}
|
||||
scale {
|
||||
x: 0.3
|
||||
y: 0.3
|
||||
}
|
||||
size {
|
||||
x: 260.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "12 FPS"
|
||||
font: "text_regular"
|
||||
id: "text_min_fps"
|
||||
pivot: PIVOT_W
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: 12.0
|
||||
}
|
||||
scale {
|
||||
x: 0.3
|
||||
y: 0.3
|
||||
}
|
||||
size {
|
||||
x: 260.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "60 FPS"
|
||||
font: "text_bold"
|
||||
id: "text_fps"
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -33.4
|
||||
y: 30.0
|
||||
}
|
||||
size {
|
||||
x: 3.0
|
||||
y: 8.0
|
||||
}
|
||||
color {
|
||||
x: 0.173
|
||||
y: 0.184
|
||||
z: 0.204
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/pixel"
|
||||
id: "line_second_1"
|
||||
pivot: PIVOT_N
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 33.2
|
||||
y: 30.0
|
||||
}
|
||||
size {
|
||||
x: 3.0
|
||||
y: 8.0
|
||||
}
|
||||
color {
|
||||
x: 0.173
|
||||
y: 0.184
|
||||
z: 0.204
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/pixel"
|
||||
id: "line_second_2"
|
||||
pivot: PIVOT_N
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
84
druid/widget/fps_panel/fps_panel.lua
Normal file
84
druid/widget/fps_panel/fps_panel.lua
Normal file
@ -0,0 +1,84 @@
|
||||
local mini_graph = require("druid.widget.mini_graph.mini_graph")
|
||||
|
||||
---@class widget.fps_panel: druid.widget
|
||||
---@field root node
|
||||
local M = {}
|
||||
|
||||
local TARGET_FPS = sys.get_config_int("display.update_frequency", 60)
|
||||
if TARGET_FPS == 0 then
|
||||
TARGET_FPS = 60
|
||||
end
|
||||
|
||||
function M:init()
|
||||
self.delta_time = 0.1 -- in seconds
|
||||
self.collect_time = 3 -- in seconds
|
||||
self.collect_time_counter = 0
|
||||
self.graph_samples = self.collect_time / self.delta_time
|
||||
|
||||
-- Store frame time in seconds last collect_time seconds
|
||||
self.fps_samples = {}
|
||||
|
||||
self.mini_graph = self.druid:new_widget(mini_graph, "mini_graph")
|
||||
self.mini_graph:set_samples(self.graph_samples) -- show last 30 seconds
|
||||
self.mini_graph:set_max_value(TARGET_FPS)
|
||||
|
||||
gui.set_parent(self:get_node("content"), self.mini_graph.content, true)
|
||||
|
||||
self.text_min_fps = self.druid:new_text("text_min_fps")
|
||||
self.text_fps = self.druid:new_text("text_fps")
|
||||
|
||||
self.timer_id = timer.delay(self.delta_time, true, function()
|
||||
self:push_fps_value()
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function M:update(dt)
|
||||
if not self.previous_time then
|
||||
self.previous_time = socket.gettime()
|
||||
return
|
||||
end
|
||||
|
||||
local current_time = socket.gettime()
|
||||
local delta_time = current_time - self.previous_time
|
||||
self.previous_time = current_time
|
||||
self.collect_time_counter = self.collect_time_counter + delta_time
|
||||
|
||||
table.insert(self.fps_samples, 1, delta_time)
|
||||
|
||||
while self.collect_time_counter > self.collect_time do
|
||||
-- Remove last
|
||||
local removed_value = table.remove(self.fps_samples)
|
||||
self.collect_time_counter = self.collect_time_counter - removed_value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function M:push_fps_value()
|
||||
if #self.fps_samples == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local max_frame_time = 0
|
||||
local average_frame_time = 0
|
||||
local average_samples_count = self.delta_time
|
||||
local average_collected = 0
|
||||
for index = 1, #self.fps_samples do
|
||||
if average_frame_time < average_samples_count then
|
||||
average_frame_time = average_frame_time + self.fps_samples[index]
|
||||
average_collected = average_collected + 1
|
||||
end
|
||||
max_frame_time = math.max(max_frame_time, self.fps_samples[index])
|
||||
end
|
||||
|
||||
average_frame_time = average_frame_time / average_collected
|
||||
|
||||
self.mini_graph:push_line_value(1 / average_frame_time)
|
||||
|
||||
self.text_fps:set_to(tostring(math.ceil(1 / average_frame_time) .. " FPS"))
|
||||
local lowest_value = math.ceil(self.mini_graph:get_lowest_value())
|
||||
self.text_min_fps:set_to(lowest_value .. " lowest")
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -1,3 +1,15 @@
|
||||
fonts {
|
||||
name: "text_regular"
|
||||
font: "/druid/fonts/text_regular.font"
|
||||
}
|
||||
fonts {
|
||||
name: "text_bold"
|
||||
font: "/druid/fonts/text_bold.font"
|
||||
}
|
||||
textures {
|
||||
name: "druid"
|
||||
texture: "/druid/druid.atlas"
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
x: 200.0
|
||||
@ -23,36 +35,208 @@ nodes {
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
text: "Memory Panel"
|
||||
id: "mini_graph/text_header"
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/header"
|
||||
parent: "mini_graph/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
text: "Memory"
|
||||
id: "mini_graph/text_header"
|
||||
parent: "mini_graph/header"
|
||||
overridden_fields: 8
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/icon_drag"
|
||||
parent: "mini_graph/root"
|
||||
parent: "mini_graph/header"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/panel_diagram"
|
||||
id: "mini_graph/content"
|
||||
parent: "mini_graph/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/prefab_line"
|
||||
parent: "mini_graph/panel_diagram"
|
||||
parent: "mini_graph/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "mini_graph/text_value"
|
||||
parent: "mini_graph/root"
|
||||
type: TYPE_BOX
|
||||
id: "mini_graph/color_low"
|
||||
parent: "mini_graph/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
x: 200.0
|
||||
y: 100.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "content"
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -96.0
|
||||
y: 12.0
|
||||
}
|
||||
scale {
|
||||
x: 0.3
|
||||
y: 0.3
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "120.23 KB"
|
||||
font: "text_regular"
|
||||
id: "text_max_value"
|
||||
pivot: PIVOT_W
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 96.0
|
||||
y: 12.0
|
||||
}
|
||||
scale {
|
||||
x: 0.3
|
||||
y: 0.3
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "120 KB/s"
|
||||
font: "text_regular"
|
||||
id: "text_per_second"
|
||||
pivot: PIVOT_E
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -33.4
|
||||
y: 30.0
|
||||
}
|
||||
size {
|
||||
x: 3.0
|
||||
y: 8.0
|
||||
}
|
||||
color {
|
||||
x: 0.173
|
||||
y: 0.184
|
||||
z: 0.204
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/pixel"
|
||||
id: "line_second_1"
|
||||
pivot: PIVOT_N
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 33.2
|
||||
y: 30.0
|
||||
}
|
||||
size {
|
||||
x: 3.0
|
||||
y: 8.0
|
||||
}
|
||||
color {
|
||||
x: 0.173
|
||||
y: 0.184
|
||||
z: 0.204
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/pixel"
|
||||
id: "line_second_2"
|
||||
pivot: PIVOT_N
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: 12.0
|
||||
}
|
||||
scale {
|
||||
x: 0.3
|
||||
y: 0.3
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "120 KB"
|
||||
font: "text_bold"
|
||||
id: "text_memory"
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||
|
@ -4,19 +4,73 @@ local mini_graph = require("druid.widget.mini_graph.mini_graph")
|
||||
---@field root node
|
||||
local M = {}
|
||||
|
||||
|
||||
function M:init()
|
||||
self.druid = self:get_druid()
|
||||
self.delta_time = 0.1
|
||||
self.samples_count = 30
|
||||
self.memory_limit = 100
|
||||
|
||||
self.mini_graph = self.druid:new_widget(mini_graph, "mini_graph")
|
||||
self.mini_graph:set_samples(self.samples_count)
|
||||
gui.set_parent(self:get_node("content"), self.mini_graph.content, true)
|
||||
|
||||
--for index = 1, 32 do
|
||||
-- self.mini_graph:set_line_value(index, 0)
|
||||
--end
|
||||
self.max_value = self.druid:new_text("text_max_value")
|
||||
self.text_per_second = self.druid:new_text("text_per_second")
|
||||
self.text_memory = self.druid:new_text("text_memory")
|
||||
|
||||
timer.delay(0.1, true, function()
|
||||
self.mini_graph:push_line_value(math.random())
|
||||
self.memory = collectgarbage("count")
|
||||
self.memory_samples = {}
|
||||
|
||||
self:update_text_memory()
|
||||
|
||||
self.timer_id = timer.delay(self.delta_time, true, function()
|
||||
self:push_next_value()
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function M:set_low_memory_limit(limit)
|
||||
self.memory_limit = limit
|
||||
end
|
||||
|
||||
|
||||
function M:push_next_value()
|
||||
local memory = collectgarbage("count")
|
||||
local diff = math.max(0, memory - self.memory)
|
||||
self.memory = memory
|
||||
self:update_text_memory()
|
||||
|
||||
table.insert(self.memory_samples, diff)
|
||||
if #self.memory_samples > self.samples_count then
|
||||
table.remove(self.memory_samples, 1)
|
||||
end
|
||||
|
||||
self.mini_graph:push_line_value(diff)
|
||||
|
||||
local max_value = math.max(unpack(self.memory_samples))
|
||||
max_value = math.max(max_value, self.memory_limit) -- low limit to display
|
||||
self.mini_graph:set_max_value(max_value)
|
||||
|
||||
local max_memory = math.ceil(self.mini_graph:get_highest_value())
|
||||
self.max_value:set_to(max_memory .. " KB")
|
||||
|
||||
local last_second = 0
|
||||
local last_second_samples = math.ceil(1 / self.delta_time)
|
||||
for index = #self.memory_samples - last_second_samples + 1, #self.memory_samples do
|
||||
last_second = last_second + (self.memory_samples[index] or 0)
|
||||
end
|
||||
self.text_per_second:set_to(math.ceil(last_second) .. " KB/s")
|
||||
end
|
||||
|
||||
|
||||
function M:update_text_memory()
|
||||
local memory = math.ceil(collectgarbage("count")) -- in KB
|
||||
if memory > 1024 then
|
||||
memory = memory / 1024
|
||||
self.text_memory:set_to(string.format("%.2f", memory) .. " MB")
|
||||
else
|
||||
self.text_memory:set_to(memory .. " KB")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -31,10 +31,26 @@ nodes {
|
||||
w: 8.0
|
||||
}
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: 70.0
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
y: 40.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "header"
|
||||
pivot: PIVOT_N
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -92.0
|
||||
y: 63.0
|
||||
y: -8.0
|
||||
}
|
||||
scale {
|
||||
x: 0.5
|
||||
@ -64,26 +80,26 @@ nodes {
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "root"
|
||||
parent: "header"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 92.0
|
||||
y: 67.0
|
||||
x: 96.0
|
||||
y: -4.0
|
||||
}
|
||||
color {
|
||||
x: 0.129
|
||||
y: 0.141
|
||||
z: 0.157
|
||||
x: 0.306
|
||||
y: 0.31
|
||||
z: 0.314
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/ui_circle_32"
|
||||
texture: "druid/icon_drag"
|
||||
id: "icon_drag"
|
||||
pivot: PIVOT_NE
|
||||
parent: "root"
|
||||
parent: "header"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
}
|
||||
@ -102,7 +118,7 @@ nodes {
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/ui_circle_16"
|
||||
id: "panel_diagram"
|
||||
id: "content"
|
||||
pivot: PIVOT_S
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
@ -113,6 +129,7 @@ nodes {
|
||||
w: 8.0
|
||||
}
|
||||
clipping_mode: CLIPPING_MODE_STENCIL
|
||||
material: "gui_stencil"
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
@ -128,44 +145,32 @@ nodes {
|
||||
texture: "druid/pixel"
|
||||
id: "prefab_line"
|
||||
pivot: PIVOT_S
|
||||
parent: "panel_diagram"
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: 12.0
|
||||
}
|
||||
scale {
|
||||
x: 0.7
|
||||
y: 0.7
|
||||
x: -10.0
|
||||
y: 4.0
|
||||
}
|
||||
size {
|
||||
x: 260.0
|
||||
y: 40.0
|
||||
x: 8.0
|
||||
y: 8.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
x: 0.557
|
||||
y: 0.835
|
||||
z: 0.62
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "120.23 KB"
|
||||
font: "text_bold"
|
||||
id: "text_value"
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "root"
|
||||
type: TYPE_BOX
|
||||
texture: "druid/pixel"
|
||||
id: "color_low"
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||
materials {
|
||||
name: "gui_stencil"
|
||||
material: "/druid/materials/stencil/gui_stencil.material"
|
||||
}
|
||||
|
@ -7,25 +7,46 @@ local SIZE_Y = hash("size.y")
|
||||
|
||||
|
||||
function M:init()
|
||||
self.druid = self:get_druid()
|
||||
self.root = self:get_node("root")
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.text_header = self.druid:new_text("text_header")
|
||||
self.text_value = self.druid:new_text("text_value")
|
||||
self.drag_corner = self.druid:new_drag("icon_drag", self.on_drag_corner)
|
||||
self.layout = self.druid:new_layout("panel_diagram", "horizontal")
|
||||
|
||||
self.druid:new_drag("header", self.on_drag_widget)
|
||||
self.druid:new_button("icon_drag", self.toggle_hide)
|
||||
:set_style(nil)
|
||||
|
||||
self.content = self:get_node("content")
|
||||
self.layout = self.druid:new_layout(self.content, "horizontal")
|
||||
:set_margin(0, 0)
|
||||
:set_padding(0, 0, 0, 0)
|
||||
|
||||
self.prefab_line = self:get_node("prefab_line")
|
||||
gui.set_enabled(self.prefab_line, false)
|
||||
|
||||
self.color_zero = color.hex2vector4("#8ED59E")
|
||||
self.color_one = color.hex2vector4("#F49B9B")
|
||||
local node_color_low = self:get_node("color_low")
|
||||
self.color_zero = gui.get_color(node_color_low)
|
||||
self.color_one = gui.get_color(self.prefab_line)
|
||||
gui.set_enabled(node_color_low, false)
|
||||
|
||||
self.is_hidden = false
|
||||
self.max_value = 1 -- in this value line will be at max height
|
||||
self.lines = {}
|
||||
self.values = {}
|
||||
self.samples = 64
|
||||
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.container:add_container("header")
|
||||
self.default_size = self.container:get_size()
|
||||
end
|
||||
|
||||
|
||||
function M:set_samples(samples)
|
||||
self.samples = samples
|
||||
self.layout:clear_layout()
|
||||
for index = 1, #self.lines do
|
||||
gui.delete_node(self.lines[index])
|
||||
end
|
||||
self.lines = {}
|
||||
|
||||
local line_width = self.layout:get_size().x / self.samples
|
||||
for index = 1, self.samples do
|
||||
local line = gui.clone(self.prefab_line)
|
||||
@ -34,11 +55,6 @@ function M:init()
|
||||
self.layout:add(line)
|
||||
table.insert(self.lines, line)
|
||||
end
|
||||
|
||||
for index = 1, self.samples do
|
||||
local outsine = index/self.samples
|
||||
self:set_line_value(index, outsine)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -50,39 +66,78 @@ function M:set_line_value(index, value)
|
||||
return
|
||||
end
|
||||
|
||||
local target_color = color.lerp(value * value, self.color_zero, self.color_one)
|
||||
gui.set(line, SIZE_Y, value * 70)
|
||||
gui.set_color(line, target_color)
|
||||
|
||||
self.values[index] = value
|
||||
|
||||
local normalized = vmath.clamp(value/self.max_value, 0, 1)
|
||||
local target_color = color.lerp(normalized, self.color_zero, self.color_one)
|
||||
gui.set_color(line, target_color)
|
||||
self:set_line_height(index)
|
||||
|
||||
end
|
||||
|
||||
|
||||
---@return number
|
||||
function M:get_line_value(index)
|
||||
return self.values[index]
|
||||
return self.values[index] or 0
|
||||
end
|
||||
|
||||
|
||||
function M:push_line_value(value)
|
||||
for index = 1, self.samples - 1 do
|
||||
self:set_line_value(index, self:get_line_value(index + 1), true)
|
||||
self:set_line_value(index, self:get_line_value(index + 1))
|
||||
end
|
||||
|
||||
self:set_line_value(self.samples, value, true)
|
||||
self:set_line_value(self.samples, value)
|
||||
end
|
||||
|
||||
|
||||
---@param text string
|
||||
function M:set_text(text)
|
||||
self.text_value:set_to(text)
|
||||
function M:set_max_value(max_value)
|
||||
if self.max_value == max_value then
|
||||
return
|
||||
end
|
||||
|
||||
self.max_value = max_value
|
||||
for index = 1, self.samples do
|
||||
self:set_line_height(index)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function M:on_drag_corner(dx, dy)
|
||||
function M:set_line_height(index)
|
||||
local value = self.values[index] or 0
|
||||
local normalized = vmath.clamp(value / self.max_value, 0, 1)
|
||||
local size_y = normalized * 70
|
||||
gui.set(self.lines[index], SIZE_Y, size_y)
|
||||
end
|
||||
|
||||
|
||||
function M:get_lowest_value()
|
||||
return math.min(unpack(self.values))
|
||||
end
|
||||
|
||||
|
||||
function M:get_highest_value()
|
||||
return math.max(unpack(self.values))
|
||||
end
|
||||
|
||||
|
||||
function M:on_drag_widget(dx, dy)
|
||||
local position = self.container:get_position()
|
||||
self.container:set_position(position.x + dx, position.y + dy)
|
||||
end
|
||||
|
||||
|
||||
function M:toggle_hide()
|
||||
self.is_hidden = not self.is_hidden
|
||||
local hidden_size = gui.get_size(self:get_node("header"))
|
||||
|
||||
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)
|
||||
|
||||
gui.set_enabled(self.content, not self.is_hidden)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -23,11 +23,11 @@ nodes {
|
||||
x: -200.0
|
||||
}
|
||||
scale {
|
||||
x: 0.65
|
||||
y: 0.65
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
x: 350.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
@ -50,6 +50,7 @@ nodes {
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
adjust_mode: ADJUST_MODE_STRETCH
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
@ -119,12 +120,12 @@ nodes {
|
||||
}
|
||||
nodes {
|
||||
scale {
|
||||
x: 0.65
|
||||
y: 0.65
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 250.0
|
||||
y: 30.0
|
||||
x: 380.0
|
||||
y: 50.0
|
||||
}
|
||||
color {
|
||||
x: 0.722
|
||||
|
@ -1,3 +1,5 @@
|
||||
local color = require("druid.color")
|
||||
|
||||
---@class property_button: druid.widget
|
||||
---@field root node
|
||||
---@field container druid.container
|
||||
@ -7,11 +9,7 @@
|
||||
---@field druid druid_instance
|
||||
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_text("text_name")
|
||||
self.selected = self:get_node("selected")
|
||||
@ -21,7 +19,9 @@ function M:init(template, nodes)
|
||||
self.text_button = self.druid:new_text("text_button")
|
||||
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.container:add_container("text_name")
|
||||
self.container:add_container("text_name", nil, function(_, size)
|
||||
self.text_button:set_size(size)
|
||||
end)
|
||||
self.container:add_container("E_Anchor")
|
||||
end
|
||||
|
||||
@ -32,4 +32,17 @@ function M:on_click()
|
||||
end
|
||||
|
||||
|
||||
---@param text string
|
||||
---@return property_button
|
||||
function M:set_text_button(text)
|
||||
self.text_button:set_text(text)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
function M:set_color(color_value)
|
||||
color.set_color(self:get_node("button"), color_value)
|
||||
end
|
||||
|
||||
|
||||
return M
|
||||
|
@ -23,11 +23,11 @@ nodes {
|
||||
x: -200.0
|
||||
}
|
||||
scale {
|
||||
x: 0.65
|
||||
y: 0.65
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
x: 360.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
|
@ -1,16 +1,13 @@
|
||||
---@class property_checkbox: druid.widget
|
||||
---@field root node
|
||||
---@field druid druid_instance
|
||||
---@field text_name druid.lang_text
|
||||
---@field text_name druid.text
|
||||
---@field button druid.button
|
||||
---@field selected node
|
||||
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.icon = self:get_node("icon")
|
||||
@ -19,7 +16,7 @@ function M:init(template, nodes)
|
||||
self.selected = self:get_node("selected")
|
||||
gui.set_alpha(self.selected, 0)
|
||||
|
||||
self.text_name = self.druid:new_lang_text("text_name")
|
||||
self.text_name = self.druid:new_text("text_name")
|
||||
|
||||
self.button = self.druid:new_button("button", self.on_click)
|
||||
|
||||
|
143
druid/widget/properties_panel/properties/property_input.gui
Normal file
143
druid/widget/properties_panel/properties/property_input.gui
Normal file
@ -0,0 +1,143 @@
|
||||
fonts {
|
||||
name: "text_bold"
|
||||
font: "/druid/fonts/text_bold.font"
|
||||
}
|
||||
textures {
|
||||
name: "druid"
|
||||
texture: "/druid/druid.atlas"
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
x: 400.0
|
||||
y: 40.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/empty"
|
||||
id: "root"
|
||||
adjust_mode: ADJUST_MODE_STRETCH
|
||||
inherit_alpha: true
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -200.0
|
||||
}
|
||||
scale {
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 350.0
|
||||
y: 50.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "Button"
|
||||
font: "text_bold"
|
||||
id: "text_name"
|
||||
pivot: PIVOT_W
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 200.0
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
y: 40.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "E_Anchor"
|
||||
pivot: PIVOT_E
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -100.0
|
||||
}
|
||||
type: TYPE_TEMPLATE
|
||||
id: "rich_input"
|
||||
parent: "E_Anchor"
|
||||
inherit_alpha: true
|
||||
template: "/druid/custom/rich_input/rich_input.gui"
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "rich_input/root"
|
||||
parent: "rich_input"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "rich_input/button"
|
||||
parent: "rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "rich_input/placeholder_text"
|
||||
parent: "rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "rich_input/input_text"
|
||||
parent: "rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "rich_input/cursor_node"
|
||||
parent: "rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "rich_input/cursor_text"
|
||||
parent: "rich_input/cursor_node"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -100.0
|
||||
y: -20.0
|
||||
}
|
||||
size {
|
||||
x: 200.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: "E_Anchor"
|
||||
inherit_alpha: true
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
38
druid/widget/properties_panel/properties/property_input.lua
Normal file
38
druid/widget/properties_panel/properties/property_input.lua
Normal file
@ -0,0 +1,38 @@
|
||||
---@class property_input: druid.widget
|
||||
---@field root node
|
||||
---@field container druid.container
|
||||
---@field text_name druid.text
|
||||
---@field button druid.button
|
||||
---@field text_button druid.text
|
||||
---@field druid druid_instance
|
||||
local M = {}
|
||||
|
||||
function M:init()
|
||||
self.root = self:get_node("root")
|
||||
self.text_name = self.druid:new_text("text_name")
|
||||
self.selected = self:get_node("selected")
|
||||
gui.set_alpha(self.selected, 0)
|
||||
|
||||
self.rich_input = self.druid:new_rich_input("rich_input")
|
||||
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.container:add_container("text_name")
|
||||
self.container:add_container("E_Anchor")
|
||||
end
|
||||
|
||||
|
||||
function M:on_click()
|
||||
gui.set_alpha(self.selected, 1)
|
||||
gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16)
|
||||
end
|
||||
|
||||
|
||||
---@param text string
|
||||
---@return property_input
|
||||
function M:set_text_button(text)
|
||||
self.text_button:set_text(text)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -23,11 +23,11 @@ nodes {
|
||||
x: -200.0
|
||||
}
|
||||
scale {
|
||||
x: 0.65
|
||||
y: 0.65
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 200.0
|
||||
x: 380.0
|
||||
y: 40.0
|
||||
}
|
||||
color {
|
||||
|
@ -2,23 +2,19 @@
|
||||
---@field root node
|
||||
---@field container druid.container
|
||||
---@field druid druid_instance
|
||||
---@field text_name druid.lang_text
|
||||
---@field text_name druid.text
|
||||
---@field text_value druid.text
|
||||
---@field slider druid.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:get_node("root")
|
||||
self.selected = self:get_node("selected")
|
||||
gui.set_alpha(self.selected, 0)
|
||||
self._value = 0
|
||||
|
||||
self.text_name = self.druid:new_lang_text("text_name") --[[@as druid.lang_text]]
|
||||
self.text_name = self.druid:new_text("text_name")
|
||||
self.text_value = self.druid:new_text("text_value")
|
||||
self.slider = self.druid:new_slider("slider_pin", vmath.vector3(55, 0, 0), self._on_slider_change_by_user) --[[@as druid.slider]]
|
||||
self.slider:set_input_node("slider")
|
||||
@ -36,7 +32,7 @@ end
|
||||
---@param callback fun(value:number):string
|
||||
function M:set_text_function(callback)
|
||||
self._text_function = callback
|
||||
self.text_value:set_to(self._text_function(self._value))
|
||||
self.text_value:set_text(self._text_function(self._value))
|
||||
end
|
||||
|
||||
|
||||
|
96
druid/widget/properties_panel/properties/property_text.gui
Normal file
96
druid/widget/properties_panel/properties/property_text.gui
Normal file
@ -0,0 +1,96 @@
|
||||
fonts {
|
||||
name: "text_bold"
|
||||
font: "/druid/fonts/text_bold.font"
|
||||
}
|
||||
textures {
|
||||
name: "druid"
|
||||
texture: "/druid/druid.atlas"
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
x: 400.0
|
||||
y: 40.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/empty"
|
||||
id: "root"
|
||||
adjust_mode: ADJUST_MODE_STRETCH
|
||||
inherit_alpha: true
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -200.0
|
||||
}
|
||||
scale {
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 400.0
|
||||
y: 50.0
|
||||
}
|
||||
color {
|
||||
x: 0.463
|
||||
y: 0.475
|
||||
z: 0.49
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "Text"
|
||||
font: "text_bold"
|
||||
id: "text_name"
|
||||
pivot: PIVOT_W
|
||||
outline {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
shadow {
|
||||
x: 1.0
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 200.0
|
||||
}
|
||||
scale {
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 350.0
|
||||
y: 50.0
|
||||
}
|
||||
color {
|
||||
x: 0.722
|
||||
y: 0.741
|
||||
z: 0.761
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "Text"
|
||||
font: "text_bold"
|
||||
id: "text_right"
|
||||
pivot: PIVOT_E
|
||||
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
|
39
druid/widget/properties_panel/properties/property_text.lua
Normal file
39
druid/widget/properties_panel/properties/property_text.lua
Normal file
@ -0,0 +1,39 @@
|
||||
---@class property_text: druid.widget
|
||||
---@field root node
|
||||
---@field container druid.container
|
||||
---@field text_name druid.text
|
||||
---@field text_right druid.text
|
||||
local M = {}
|
||||
|
||||
function M:init()
|
||||
self.root = self:get_node("root")
|
||||
self.text_name = self.druid:new_text("text_name")
|
||||
self.text_right = self.druid:new_text("text_right", "")
|
||||
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.container:add_container("text_name", nil, function(_, size)
|
||||
self.text_name:set_size(size)
|
||||
end)
|
||||
self.container:add_container("text_right", nil, function(_, size)
|
||||
self.text_right:set_size(size)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
---@param text string
|
||||
---@return property_text
|
||||
function M:set_text(text)
|
||||
self.text_name:set_text(text)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
---@param text string
|
||||
---@return property_text
|
||||
function M:set_right_text(text)
|
||||
self.text_right:set_text(text or "")
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -33,15 +33,31 @@ nodes {
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -192.0
|
||||
y: 116.0
|
||||
}
|
||||
scale {
|
||||
x: 0.8
|
||||
y: 0.8
|
||||
y: 120.0
|
||||
}
|
||||
size {
|
||||
x: 245.0
|
||||
x: 400.0
|
||||
y: 40.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "header"
|
||||
pivot: PIVOT_N
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -192.0
|
||||
y: -8.0
|
||||
}
|
||||
scale {
|
||||
x: 0.5
|
||||
y: 0.5
|
||||
}
|
||||
size {
|
||||
x: 500.0
|
||||
y: 50.0
|
||||
}
|
||||
color {
|
||||
@ -64,15 +80,49 @@ nodes {
|
||||
y: 1.0
|
||||
z: 1.0
|
||||
}
|
||||
parent: "root"
|
||||
parent: "header"
|
||||
inherit_alpha: true
|
||||
outline_alpha: 0.0
|
||||
shadow_alpha: 0.0
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 192.0
|
||||
y: -4.0
|
||||
}
|
||||
color {
|
||||
x: 0.306
|
||||
y: 0.31
|
||||
z: 0.314
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/icon_drag"
|
||||
id: "icon_drag"
|
||||
pivot: PIVOT_NE
|
||||
parent: "header"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: -120.0
|
||||
}
|
||||
size {
|
||||
x: 400.0
|
||||
y: 190.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "content"
|
||||
pivot: PIVOT_S
|
||||
parent: "root"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -200.0
|
||||
y: 70.0
|
||||
y: 190.0
|
||||
}
|
||||
size {
|
||||
x: 400.0
|
||||
@ -84,7 +134,7 @@ nodes {
|
||||
xanchor: XANCHOR_LEFT
|
||||
pivot: PIVOT_NW
|
||||
adjust_mode: ADJUST_MODE_STRETCH
|
||||
parent: "root"
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
clipping_mode: CLIPPING_MODE_STENCIL
|
||||
}
|
||||
@ -109,51 +159,12 @@ nodes {
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -200.0
|
||||
y: 115.0
|
||||
}
|
||||
scale {
|
||||
x: 0.7
|
||||
y: 0.7
|
||||
}
|
||||
size {
|
||||
x: 570.0
|
||||
y: 50.0
|
||||
}
|
||||
color {
|
||||
x: 0.31
|
||||
y: 0.318
|
||||
z: 0.322
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "No properties for this example"
|
||||
font: "text_regular"
|
||||
id: "text_no_properties"
|
||||
pivot: PIVOT_NW
|
||||
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
|
||||
enabled: false
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: 50.0
|
||||
y: 170.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/empty"
|
||||
id: "propeties"
|
||||
parent: "root"
|
||||
parent: "content"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
visible: false
|
||||
@ -313,21 +324,107 @@ nodes {
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 192.0
|
||||
y: 112.0
|
||||
y: -150.0
|
||||
}
|
||||
color {
|
||||
x: 0.129
|
||||
y: 0.141
|
||||
z: 0.157
|
||||
}
|
||||
type: TYPE_BOX
|
||||
texture: "druid/ui_circle_32"
|
||||
id: "icon_drag"
|
||||
pivot: PIVOT_NE
|
||||
parent: "root"
|
||||
type: TYPE_TEMPLATE
|
||||
id: "property_input"
|
||||
parent: "propeties"
|
||||
inherit_alpha: true
|
||||
size_mode: SIZE_MODE_AUTO
|
||||
template: "/druid/widget/properties_panel/properties/property_input.gui"
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_input/root"
|
||||
parent: "property_input"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "property_input/text_name"
|
||||
parent: "property_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_input/E_Anchor"
|
||||
parent: "property_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEMPLATE
|
||||
id: "property_input/rich_input"
|
||||
parent: "property_input/E_Anchor"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_input/rich_input/root"
|
||||
parent: "property_input/rich_input"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_input/rich_input/button"
|
||||
parent: "property_input/rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "property_input/rich_input/placeholder_text"
|
||||
parent: "property_input/rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "property_input/rich_input/input_text"
|
||||
parent: "property_input/rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_input/rich_input/cursor_node"
|
||||
parent: "property_input/rich_input/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "property_input/rich_input/cursor_text"
|
||||
parent: "property_input/rich_input/cursor_node"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_input/selected"
|
||||
parent: "property_input/E_Anchor"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: -200.0
|
||||
}
|
||||
type: TYPE_TEMPLATE
|
||||
id: "property_text"
|
||||
parent: "propeties"
|
||||
inherit_alpha: true
|
||||
template: "/druid/widget/properties_panel/properties/property_text.gui"
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "property_text/root"
|
||||
parent: "property_text"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "property_text/text_name"
|
||||
parent: "property_text/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "property_text/text_right"
|
||||
parent: "property_text/root"
|
||||
template_node_child: true
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||
|
@ -1,32 +1,41 @@
|
||||
local property_checkbox = require("druid.widget.properties_panel.properties.property_checkbox")
|
||||
local property_slider = require("druid.widget.properties_panel.properties.property_slider")
|
||||
local property_button = require("druid.widget.properties_panel.properties.property_button")
|
||||
local property_input = require("druid.widget.properties_panel.properties.property_input")
|
||||
local property_text = require("druid.widget.properties_panel.properties.property_text")
|
||||
|
||||
---@class properties_panel: druid.widget
|
||||
---@field root node
|
||||
---@field text_no_properties node
|
||||
---@field scroll druid.scroll
|
||||
---@field druid druid_instance
|
||||
local M = {}
|
||||
|
||||
---@param template string
|
||||
---@param nodes table<hash, node>
|
||||
function M:init(template, nodes)
|
||||
self.druid = self:get_druid(template, nodes)
|
||||
|
||||
--self.root = self.druid:new_container("root")
|
||||
function M:init()
|
||||
self.root = self:get_node("root")
|
||||
self.text_no_properties = self:get_node("text_no_properties")
|
||||
self.content = self:get_node("content")
|
||||
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.container:add_container("header")
|
||||
self.container_content = self.container:add_container("content")
|
||||
self.container_scroll_view = self.container_content:add_container("scroll_view")
|
||||
self.contaienr_scroll_content = self.container_scroll_view:add_container("scroll_content")
|
||||
|
||||
self.default_size = self.container:get_size()
|
||||
|
||||
self.properties = {}
|
||||
|
||||
self.text_header = self.druid:new_text("text_header")
|
||||
self.scroll = self.druid:new_scroll("scroll_view", "scroll_content")
|
||||
self.layout = self.druid:new_layout("scroll_content", "vertical")
|
||||
:set_hug_content(false, true)
|
||||
:set_padding(nil, 0)
|
||||
|
||||
self.layout.on_size_changed:subscribe(self.on_size_changed, self)
|
||||
|
||||
self.drag_corner = self.druid:new_drag("icon_drag", self.on_drag_corner)
|
||||
self.druid:new_drag("header", self.on_drag_widget)
|
||||
self.druid:new_button("icon_drag", self.toggle_hide)
|
||||
:set_style(nil)
|
||||
|
||||
self.property_checkbox_prefab = self:get_node("property_checkbox/root")
|
||||
gui.set_enabled(self.property_checkbox_prefab, false)
|
||||
@ -37,17 +46,15 @@ function M:init(template, nodes)
|
||||
self.property_button_prefab = self:get_node("property_button/root")
|
||||
gui.set_enabled(self.property_button_prefab, false)
|
||||
|
||||
self.container = self.druid:new_container(self.root)
|
||||
self.container:add_container("text_header")
|
||||
self.container:add_container("icon_drag")
|
||||
--self.container:create_draggable_corners()
|
||||
self.property_input_prefab = self:get_node("property_input/root")
|
||||
gui.set_enabled(self.property_input_prefab, false)
|
||||
|
||||
self.container_scroll_view = self.container:add_container("scroll_view")
|
||||
self.contaienr_scroll_content = self.container_scroll_view:add_container("scroll_content")
|
||||
self.property_text_prefab = self:get_node("property_text/root")
|
||||
gui.set_enabled(self.property_text_prefab, false)
|
||||
end
|
||||
|
||||
|
||||
function M:on_drag_corner(dx, dy)
|
||||
function M:on_drag_widget(dx, dy)
|
||||
local position = self.container:get_position()
|
||||
self.container:set_position(position.x + dx, position.y + dy)
|
||||
end
|
||||
@ -55,15 +62,21 @@ end
|
||||
|
||||
function M:clear()
|
||||
for index = 1, #self.properties do
|
||||
gui.delete_node(self.properties[index].root)
|
||||
self.druid:remove(self.properties[index])
|
||||
end
|
||||
self.layout:clear_layout()
|
||||
self.properties = {}
|
||||
gui.set_enabled(self.text_no_properties, true)
|
||||
end
|
||||
|
||||
|
||||
function M:on_size_changed(new_size)
|
||||
self.container:set_size(new_size.x, new_size.y + 50, 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)
|
||||
if not self.is_hidden then
|
||||
self.container:set_size(self.default_size.x, self.default_size.y, gui.PIVOT_N)
|
||||
end
|
||||
|
||||
local width = self.layout:get_size().x - self.layout.padding.x - self.layout.padding.z
|
||||
for index = 1, #self.properties do
|
||||
@ -72,51 +85,39 @@ function M:on_size_changed(new_size)
|
||||
end
|
||||
|
||||
|
||||
---@param text_id string
|
||||
---@param text string
|
||||
---@param initial_value boolean
|
||||
---@param on_change_callback function
|
||||
---@return property_checkbox
|
||||
function M:add_checkbox(text_id, initial_value, on_change_callback)
|
||||
function M:add_checkbox(text, initial_value, on_change_callback)
|
||||
text = tostring(text)
|
||||
|
||||
local nodes = gui.clone_tree(self.property_checkbox_prefab)
|
||||
local instance = self.druid:new_widget(property_checkbox, "property_checkbox", nodes)
|
||||
instance.text_name:set_to(text_id)
|
||||
self:add_property(instance)
|
||||
|
||||
instance.text_name:set_to(text)
|
||||
instance:set_value(initial_value, true)
|
||||
instance.button.on_click:subscribe(function()
|
||||
on_change_callback(instance:get_value())
|
||||
end)
|
||||
|
||||
gui.set_enabled(instance.root, true)
|
||||
self.layout:add(instance.root)
|
||||
table.insert(self.properties, instance)
|
||||
|
||||
local width = self.layout:get_size().x - self.layout.padding.x - self.layout.padding.z
|
||||
instance.container:set_size(width)
|
||||
|
||||
gui.set_enabled(self.text_no_properties, false)
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
|
||||
---@param text_id string
|
||||
---@param text string
|
||||
---@param initial_value number
|
||||
---@param on_change_callback function
|
||||
---@return property_slider
|
||||
function M:add_slider(text_id, initial_value, on_change_callback)
|
||||
function M:add_slider(text, initial_value, on_change_callback)
|
||||
text = tostring(text)
|
||||
local nodes = gui.clone_tree(self.property_slider_prefab)
|
||||
local instance = self.druid:new_widget(property_slider, "property_slider", nodes)
|
||||
instance.text_name:set_to(text_id)
|
||||
self:add_property(instance)
|
||||
|
||||
instance.text_name:set_text(text)
|
||||
instance:set_value(initial_value, true)
|
||||
|
||||
gui.set_enabled(instance.root, true)
|
||||
self.layout:add(instance.root)
|
||||
table.insert(self.properties, instance)
|
||||
|
||||
local width = self.layout:get_size().x - self.layout.padding.x - self.layout.padding.z
|
||||
instance.container:set_size(width)
|
||||
|
||||
gui.set_enabled(self.text_no_properties, false)
|
||||
|
||||
instance.slider.on_change_value:subscribe(function(_, value)
|
||||
on_change_callback(value)
|
||||
end)
|
||||
@ -125,23 +126,15 @@ function M:add_slider(text_id, initial_value, on_change_callback)
|
||||
end
|
||||
|
||||
|
||||
---@param text_id string
|
||||
---@param text string
|
||||
---@param on_click_callback function|nil
|
||||
---@param callback_context any|nil
|
||||
function M:add_button(text_id, on_click_callback, callback_context)
|
||||
function M:add_button(text, on_click_callback, callback_context)
|
||||
local nodes = gui.clone_tree(self.property_button_prefab)
|
||||
local instance = self.druid:new_widget(property_button, "property_button", nodes)
|
||||
instance.text_name:set_to(text_id)
|
||||
|
||||
gui.set_enabled(instance.root, true)
|
||||
self.layout:add(instance.root)
|
||||
table.insert(self.properties, instance)
|
||||
|
||||
local width = self.layout:get_size().x - self.layout.padding.x - self.layout.padding.z
|
||||
instance.container:set_size(width)
|
||||
|
||||
gui.set_enabled(self.text_no_properties, false)
|
||||
self:add_property(instance)
|
||||
|
||||
instance.text_name:set_text(text)
|
||||
if on_click_callback then
|
||||
instance.button.on_click:subscribe(on_click_callback, callback_context)
|
||||
end
|
||||
@ -150,6 +143,48 @@ function M:add_button(text_id, on_click_callback, callback_context)
|
||||
end
|
||||
|
||||
|
||||
function M:add_input(text, initial_value, on_change_callback)
|
||||
text = tostring(text)
|
||||
local nodes = gui.clone_tree(self.property_input_prefab)
|
||||
local instance = self.druid:new_widget(property_input, "property_input", nodes)
|
||||
self:add_property(instance)
|
||||
|
||||
instance.text_name:set_text(text)
|
||||
instance.rich_input:set_text(initial_value)
|
||||
instance.rich_input:set_placeholder("")
|
||||
instance.rich_input.input.on_input_unselect:subscribe(function(_, value)
|
||||
on_change_callback(value)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
---@param text string
|
||||
---@param right_text string|nil
|
||||
---@return property_text
|
||||
function M:add_text(text, right_text)
|
||||
text = tostring(text)
|
||||
local nodes = gui.clone_tree(self.property_text_prefab)
|
||||
local instance = self.druid:new_widget(property_text, "property_text", nodes)
|
||||
self:add_property(instance)
|
||||
|
||||
instance:set_text(text)
|
||||
instance:set_right_text(right_text)
|
||||
return instance
|
||||
end
|
||||
|
||||
|
||||
---@private
|
||||
function M:add_property(widget)
|
||||
gui.set_enabled(widget.root, true)
|
||||
self.layout:add(widget.root)
|
||||
table.insert(self.properties, widget)
|
||||
local width = self.layout:get_size().x - self.layout.padding.x - self.layout.padding.z
|
||||
widget.container:set_size(width)
|
||||
|
||||
return widget
|
||||
end
|
||||
|
||||
|
||||
function M:remove(widget)
|
||||
for index = 1, #self.properties do
|
||||
if self.properties[index] == widget then
|
||||
@ -160,10 +195,19 @@ function M:remove(widget)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #self.properties == 0 then
|
||||
gui.set_enabled(self.text_no_properties, true)
|
||||
end
|
||||
|
||||
function M:toggle_hide()
|
||||
self.is_hidden = not self.is_hidden
|
||||
local hidden_size = gui.get_size(self:get_node("header"))
|
||||
|
||||
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)
|
||||
|
||||
gui.set_enabled(self.content, not self.is_hidden)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user