From 299f8501e8c60f7da203ce4be0b9f213d00c052d Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 18 Nov 2024 22:50:42 +0200 Subject: [PATCH] Widgets WIP --- druid/druid.atlas | 3 + druid/druid.lua | 9 + druid/event.lua | 8 +- druid/extended/container.lua | 20 +- druid/extended/layout.lua | 24 +++ druid/images/panels/rect_round2_width2.png | Bin 0 -> 183 bytes druid/styles/default/style.lua | 2 +- druid/system/druid_instance.lua | 2 +- druid/widget/debug_panel/debug_panel.gui | 16 -- .../properties/property_button.gui | 198 +----------------- .../properties/property_button.lua | 6 +- .../properties/property_checkbox.lua | 4 +- .../properties/property_slider.lua | 4 +- .../properties_panel/properties_panel.gui | 60 ++++-- .../properties_panel/properties_panel.lua | 90 +++++--- 15 files changed, 181 insertions(+), 265 deletions(-) create mode 100644 druid/images/panels/rect_round2_width2.png delete mode 100644 druid/widget/debug_panel/debug_panel.gui diff --git a/druid/druid.atlas b/druid/druid.atlas index ce36b4e..59904d2 100644 --- a/druid/druid.atlas +++ b/druid/druid.atlas @@ -19,4 +19,7 @@ images { images { image: "/druid/images/pixel.png" } +images { + image: "/druid/images/panels/rect_round2_width2.png" +} extrude_borders: 2 diff --git a/druid/druid.lua b/druid/druid.lua index 1172f34..6fb3d68 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -80,6 +80,15 @@ function M.set_sound_function(callback) end +---Subscribe Druid to the window listener. It will override your previous +---window listener, so if you have one, you should call M.on_window_callback manually. +function M.init_window_listener() + window.set_listener(function(_, window_event) + M.on_window_callback(window_event) + end) +end + + ---Set the window callback to enable Druid window events. ---@param event constant Event param from window listener function M.on_window_callback(event) diff --git a/druid/event.lua b/druid/event.lua index 9da6a6c..7bac8dc 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -13,7 +13,7 @@ local tinsert = table.insert local tremove = table.remove --- Return new event instance ----@param callback fun()|nil Subscribe the callback on new event, if callback exist +---@param callback function|nil Subscribe the callback on new event, if callback exist ---@param callback_context any|nil Additional context as first param to callback call ---@return druid.event ---@nodiscard @@ -30,7 +30,7 @@ end --- Check is event subscribed. ----@param callback fun() Callback itself +---@param callback function Callback itself ---@param callback_context any|nil Additional context as first param to callback call ---@return boolean, number|nil Is event subscribed, return index of callback in event as second param function M:is_subscribed(callback, callback_context) @@ -50,7 +50,7 @@ end ---Subscribe callback on event ----@param callback fun() Callback itself +---@param callback function Callback itself ---@param callback_context any|nil Additional context as first param to callback call, usually it's self ---@return boolean function M:subscribe(callback, callback_context) @@ -67,7 +67,7 @@ end ---Unsubscribe callback on event ----@param callback fun() Callback itself +---@param callback function Callback itself ---@param callback_context any|nil Additional context as first param to callback call ---@return boolean function M:unsubscribe(callback, callback_context) diff --git a/druid/extended/container.lua b/druid/extended/container.lua index 3223f5c..3a4a17f 100644 --- a/druid/extended/container.lua +++ b/druid/extended/container.lua @@ -134,8 +134,9 @@ end --- Set new size of layout node ---@param width number|nil ---@param height number|nil +---@param anchor_pivot constant|nil If set will keep the corner possition relative to the new size ---@return druid.container Container -function M:set_size(width, height) +function M:set_size(width, height, anchor_pivot) width = width or self.size.x height = height or self.size.y @@ -149,11 +150,23 @@ function M:set_size(width, height) if (width and width ~= self.size.x) or (height and height ~= self.size.y) then self.center_offset.x = -width * self.pivot_offset.x self.center_offset.y = -height * self.pivot_offset.y + local dx = self.size.x - width + local dy = self.size.y - height self.size.x = width self.size.y = height self.size.z = 0 gui.set_size(self.node, self.size) + if anchor_pivot then + local pivot = gui.get_pivot(self.node) + local pivot_offset = helper.get_pivot_offset(pivot) + local new_pivot_offset = helper.get_pivot_offset(anchor_pivot) + + local position_dx = dx * (pivot_offset.x - new_pivot_offset.x) + local position_dy = dy * (pivot_offset.y - new_pivot_offset.y) + self:set_position(self._position.x + position_dx, self._position.y - position_dy) + end + self:update_child_containers() self.on_size_changed:trigger(self:get_context(), self.size) end @@ -162,6 +175,11 @@ function M:set_size(width, height) end +function M:get_position() + return self._position +end + + ---@param pos_x number ---@param pos_y number function M:set_position(pos_x, pos_y) diff --git a/druid/extended/layout.lua b/druid/extended/layout.lua index 457c17c..e51931b 100644 --- a/druid/extended/layout.lua +++ b/druid/extended/layout.lua @@ -1,8 +1,12 @@ +local event = require("druid.event") local helper = require("druid.helper") local component = require("druid.component") ---@alias druid.layout.mode "horizontal"|"vertical"|"horizontal_wrap" +---@class druid.event.on_size_changed: druid.event +---@field subscribe fun(_, callback: fun(new_size: vector3), context: any|nil) + ---@class druid.layout.row_data ---@field width number ---@field height number @@ -25,6 +29,7 @@ local component = require("druid.component") ---@field is_resize_width boolean ---@field is_resize_height boolean ---@field is_justify boolean +---@field on_size_changed druid.event.on_size_changed local M = component.create("layout") ---Layout component constructor @@ -46,6 +51,8 @@ function M:init(node_or_node_id, layout_type) self.is_resize_width = false self.is_resize_height = false self.is_justify = false + + self.on_size_changed = event.create() end @@ -145,6 +152,21 @@ function M:add(node_or_node_id) end +function M:remove(node_or_node_id) + local node = type(node_or_node_id) == "table" and node_or_node_id.node or self:get_node(node_or_node_id) + + for index = #self.entities, 1, -1 do + if self.entities[index] == node then + table.remove(self.entities, index) + self.is_dirty = true + break + end + end + + return self +end + + ---@return druid.layout function M:refresh_layout() local layout_node = self.node @@ -273,6 +295,8 @@ function M:refresh_layout() size.y = rows_data.total_height + padding.y + padding.w end gui.set_size(layout_node, size) + + self.on_size_changed(size) end self.is_dirty = false diff --git a/druid/images/panels/rect_round2_width2.png b/druid/images/panels/rect_round2_width2.png new file mode 100644 index 0000000000000000000000000000000000000000..80841144f6c3e8b72ecf73de649a8c6596344de7 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4aTa()7Bet#3xhBt!>l*8o|0J>k`97X5jv*C{S0|q2Wl-c{J{z_{^@3yxpR5DB z+O!A9zostHm}n%gt{}OF>$-}iA2UP0ZK#r|WpY~2-*)dffvLM9{`1F${khS<%jtXv ZZ>K=q63&vR20(KeJYD@<);T3K0RS~vGspk{ literal 0 HcmV?d00001 diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index 0f74a66..7398c74 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -61,7 +61,7 @@ M["hover"] = { } M["drag"] = { - DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone + DRAG_DEADZONE = 4, -- Size in pixels of drag deadzone NO_USE_SCREEN_KOEF = false, } diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index db62255..87357ae 100755 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -690,7 +690,7 @@ end local layout = require("druid.extended.layout") ---Create Layout component ---@param node string|node The_node id or gui.get_node(node_id). ----@param mode string The layout mode +---@param mode string vertical|horizontal|horizontal_wrap ---@return druid.layout Layout component function M:new_layout(node, mode) return self:new(layout, node, mode) diff --git a/druid/widget/debug_panel/debug_panel.gui b/druid/widget/debug_panel/debug_panel.gui deleted file mode 100644 index e925213..0000000 --- a/druid/widget/debug_panel/debug_panel.gui +++ /dev/null @@ -1,16 +0,0 @@ -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 -} -material: "/builtins/materials/gui.material" -adjust_reference: ADJUST_REFERENCE_PARENT diff --git a/druid/widget/properties_panel/properties/property_button.gui b/druid/widget/properties_panel/properties/property_button.gui index d9ab2a3..b8a4bb0 100644 --- a/druid/widget/properties_panel/properties/property_button.gui +++ b/druid/widget/properties_panel/properties/property_button.gui @@ -1,4 +1,3 @@ -script: "" fonts { name: "text_bold" font: "/druid/fonts/text_bold.font" @@ -7,322 +6,135 @@ textures { name: "druid" texture: "/druid/druid.atlas" } -background_color { - x: 0.0 - y: 0.0 - z: 0.0 - w: 0.0 -} nodes { - position { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 - } - scale { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 - } size { x: 400.0 y: 40.0 - z: 0.0 - w: 1.0 - } - color { - x: 1.0 - y: 1.0 - z: 1.0 - w: 1.0 } type: TYPE_BOX - blend_mode: BLEND_MODE_ALPHA texture: "druid/empty" id: "root" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE pivot: PIVOT_NW adjust_mode: ADJUST_MODE_STRETCH - 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: -20.0 - z: 0.0 - w: 1.0 - } - rotation { - x: 0.0 - y: 0.0 - z: 0.0 - w: 1.0 } scale { x: 0.65 y: 0.65 - z: 1.0 - w: 1.0 } size { x: 200.0 y: 40.0 - z: 0.0 - w: 1.0 } color { x: 0.463 y: 0.475 z: 0.49 - w: 1.0 } type: TYPE_TEXT - blend_mode: BLEND_MODE_ALPHA text: "Button" font: "text_bold" id: "text_name" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE pivot: PIVOT_W outline { x: 1.0 y: 1.0 z: 1.0 - w: 1.0 } shadow { x: 1.0 y: 1.0 z: 1.0 - w: 1.0 } - adjust_mode: ADJUST_MODE_FIT - line_break: false parent: "root" - layer: "" inherit_alpha: true - alpha: 1.0 outline_alpha: 0.0 shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 - custom_type: 0 - enabled: true - visible: true - material: "" } nodes { position { x: 267.0 y: -20.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: 226.0 y: 40.0 - z: 0.0 - w: 1.0 } color { x: 0.463 y: 0.475 z: 0.49 - w: 1.0 } type: TYPE_BOX - blend_mode: BLEND_MODE_ALPHA - texture: "druid/rect_round2_width1" + 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 - y: 4.0 - z: 4.0 - w: 4.0 + x: 5.0 + y: 5.0 + z: 5.0 + w: 5.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: -20.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: 226.0 y: 4.0 - z: 0.0 - w: 1.0 } color { x: 0.894 y: 0.506 z: 0.333 - w: 1.0 } type: TYPE_BOX - blend_mode: BLEND_MODE_ALPHA texture: "druid/pixel" id: "selected" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE pivot: PIVOT_S adjust_mode: ADJUST_MODE_STRETCH parent: "button" - 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: 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: 0.65 y: 0.65 - z: 1.0 - w: 1.0 } size { x: 250.0 y: 30.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: "Button" font: "text_bold" id: "text_button" - xanchor: XANCHOR_NONE - yanchor: YANCHOR_NONE - pivot: PIVOT_CENTER outline { x: 1.0 y: 1.0 z: 1.0 - w: 1.0 } shadow { x: 1.0 y: 1.0 z: 1.0 - w: 1.0 } - adjust_mode: ADJUST_MODE_FIT - line_break: false parent: "button" - layer: "" inherit_alpha: true - alpha: 1.0 outline_alpha: 0.0 shadow_alpha: 0.0 - template_node_child: false - text_leading: 1.0 - text_tracking: 0.0 - custom_type: 0 - enabled: true - visible: true - material: "" } material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_PARENT -max_nodes: 512 diff --git a/druid/widget/properties_panel/properties/property_button.lua b/druid/widget/properties_panel/properties/property_button.lua index a691e61..0c7add5 100644 --- a/druid/widget/properties_panel/properties/property_button.lua +++ b/druid/widget/properties_panel/properties/property_button.lua @@ -1,6 +1,6 @@ ----@class property_button: druid.base_component +---@class property_button: druid.widget ---@field root node ----@field text_name druid.lang_text +---@field text_name druid.text ---@field button druid.button ---@field text_button druid.text ---@field druid druid_instance @@ -12,7 +12,7 @@ function M:init(template, nodes) self.druid = self:get_druid(template, nodes) self.root = self:get_node("root") - self.text_name = self.druid:new_lang_text("text_name") + self.text_name = self.druid:new_text("text_name") self.selected = self:get_node("selected") gui.set_alpha(self.selected, 0) diff --git a/druid/widget/properties_panel/properties/property_checkbox.lua b/druid/widget/properties_panel/properties/property_checkbox.lua index 8177957..6887283 100644 --- a/druid/widget/properties_panel/properties/property_checkbox.lua +++ b/druid/widget/properties_panel/properties/property_checkbox.lua @@ -1,6 +1,6 @@ ---@class property_checkbox: druid.widget +---@field root node ---@field druid druid_instance ----@field root druid.container ---@field text_name druid.lang_text ---@field button druid.button ---@field selected node @@ -11,7 +11,7 @@ local M = {} ---@param nodes table function M:init(template, nodes) self.druid = self:get_druid(template, nodes) - self.root = self.druid:new_container("root") + self.root = self:get_node("root") self.icon = self:get_node("icon") gui.set_enabled(self.icon, false) diff --git a/druid/widget/properties_panel/properties/property_slider.lua b/druid/widget/properties_panel/properties/property_slider.lua index 60d635a..92f7e3d 100644 --- a/druid/widget/properties_panel/properties/property_slider.lua +++ b/druid/widget/properties_panel/properties/property_slider.lua @@ -1,6 +1,6 @@ ---@class property_slider: druid.widget +---@field root node ---@field druid druid_instance ----@field root druid.container ---@field text_name druid.lang_text ---@field text_value druid.text ---@field slider druid.slider @@ -12,7 +12,7 @@ local M = {} function M:init(template, nodes) self.druid = self:get_druid(template, nodes) - self.root = self.druid:new_container("root") --[[@as druid.container]] + self.root = self:get_node("root") self.selected = self:get_node("selected") gui.set_alpha(self.selected, 0) self._value = 0 diff --git a/druid/widget/properties_panel/properties_panel.gui b/druid/widget/properties_panel/properties_panel.gui index bde0940..9bdcdd3 100644 --- a/druid/widget/properties_panel/properties_panel.gui +++ b/druid/widget/properties_panel/properties_panel.gui @@ -2,14 +2,18 @@ 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: 440.0 - y: 350.0 + x: 400.0 + y: 240.0 } color { x: 0.173 @@ -17,19 +21,24 @@ nodes { z: 0.204 } type: TYPE_BOX - texture: "druid/pixel" + texture: "druid/ui_circle_16" id: "root" - adjust_mode: ADJUST_MODE_STRETCH inherit_alpha: true + slice9 { + x: 8.0 + y: 8.0 + z: 8.0 + w: 8.0 + } } nodes { position { - x: -210.0 - y: 165.0 + x: -196.0 + y: 116.0 } scale { - x: 0.9 - y: 0.9 + x: 0.8 + y: 0.8 } size { x: 245.0 @@ -62,12 +71,12 @@ nodes { } nodes { position { - x: -200.0 - y: 115.0 + x: -196.0 + y: 70.0 } size { - x: 400.0 - y: 290.0 + x: 392.0 + y: 190.0 } type: TYPE_BOX texture: "druid/empty" @@ -81,16 +90,19 @@ nodes { } nodes { size { - x: 400.0 - y: 290.0 + x: 392.0 + y: 186.0 } type: TYPE_BOX - texture: "druid/empty" + texture: "druid/pixel" id: "scroll_content" pivot: PIVOT_NW adjust_mode: ADJUST_MODE_STRETCH parent: "scroll_view" inherit_alpha: true + slice9 { + w: 6.0 + } visible: false } nodes { @@ -280,5 +292,23 @@ nodes { parent: "property_button/button" template_node_child: true } +nodes { + position { + x: 192.0 + y: 112.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" + inherit_alpha: true + size_mode: SIZE_MODE_AUTO +} material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_PARENT diff --git a/druid/widget/properties_panel/properties_panel.lua b/druid/widget/properties_panel/properties_panel.lua index 557879e..d08e657 100644 --- a/druid/widget/properties_panel/properties_panel.lua +++ b/druid/widget/properties_panel/properties_panel.lua @@ -4,7 +4,7 @@ local property_button = require("druid.widget.properties_panel.properties.proper ---@class properties_panel: druid.widget ---@field root node ----@field text_no_properties druid.lang_text +---@field text_no_properties node ---@field scroll druid.scroll ---@field druid druid_instance local M = {} @@ -16,15 +16,18 @@ function M:init(template, nodes) --self.root = self.druid:new_container("root") self.root = self:get_node("root") + self.text_no_properties = self:get_node("text_no_properties") --self.root:add_container("text_header") self.properties = {} self.scroll = self.druid:new_scroll("scroll_view", "scroll_content") - --self.layout = self.druid:new_layout("scroll_content") + self.layout = self.druid:new_layout("scroll_content", "vertical") + :set_hug_content(false, true) - --self.grid = self.druid:new_grid("scroll_content", "item_size", 1) - --self.scroll:bind_grid(self.grid) + 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.property_checkbox_prefab = self:get_node("property_checkbox/root") gui.set_enabled(self.property_checkbox_prefab, false) @@ -34,6 +37,18 @@ 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") + local container_scroll_view = self.container:add_container("scroll_view") + container_scroll_view:add_container("scroll_content") +end + + +function M:on_drag_corner(dx, dy) + local position = self.container:get_position() + self.container:set_position(position.x + dx, position.y + dy) end @@ -42,14 +57,15 @@ function M:clear() self.druid:remove(self.properties[index]) end self.properties = {} + gui.set_enabled(self.text_no_properties, true) +end + - --local nodes = self.grid.nodes - --for index = 1, #nodes do - -- gui.delete_node(nodes[index]) - --end - --self.grid:clear() +function M:on_size_changed(new_size) + new_size.x = new_size.x + 8 + new_size.y = new_size.y + 50 + 8 - gui.set_enabled(self.text_no_properties.text.node, true) + self.container:set_size(new_size.x, new_size.y, gui.PIVOT_N) end @@ -59,17 +75,17 @@ end ---@return property_checkbox function M:add_checkbox(text_id, initial_value, on_change_callback) local nodes = gui.clone_tree(self.property_checkbox_prefab) - local instance = self.druid:new(property_checkbox, "property_checkbox", nodes) --[[@as property_checkbox]] - instance.text_name:translate(text_id) + local instance = self.druid:new_widget(property_checkbox, "property_checkbox", nodes) + instance.text_name:set_to(text_id) instance:set_value(initial_value, true) instance.button.on_click:subscribe(function() on_change_callback(instance:get_value()) end) - gui.set_enabled(instance.root.node, true) - --self.grid:add(instance.root.node) + gui.set_enabled(instance.root, true) + self.layout:add(instance.root) table.insert(self.properties, instance) - gui.set_enabled(self.text_no_properties.text.node, false) + gui.set_enabled(self.text_no_properties, false) return instance end @@ -81,14 +97,14 @@ end ---@return property_slider function M:add_slider(text_id, initial_value, on_change_callback) local nodes = gui.clone_tree(self.property_slider_prefab) - local instance = self.druid:new(property_slider, "property_slider", nodes) --[[@as property_slider]] - instance.text_name:translate(text_id) + local instance = self.druid:new_widget(property_slider, "property_slider", nodes) + instance.text_name:set_to(text_id) instance:set_value(initial_value, true) - gui.set_enabled(instance.root.node, true) - --self.grid:add(instance.root.node) + gui.set_enabled(instance.root, true) + self.layout:add(instance.root) table.insert(self.properties, instance) - gui.set_enabled(self.text_no_properties.text.node, false) + gui.set_enabled(self.text_no_properties, false) instance.slider.on_change_value:subscribe(function(_, value) on_change_callback(value) @@ -99,21 +115,41 @@ end ---@param text_id string ----@param on_click_callback function -function M:add_button(text_id, on_click_callback) +---@param on_click_callback function|nil +---@param callback_context any|nil +function M:add_button(text_id, on_click_callback, callback_context) local nodes = gui.clone_tree(self.property_button_prefab) - local instance = self.druid:new(property_button, "property_button", nodes) --[[@as property_button]] - instance.text_name:translate(text_id) + 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.grid:add(instance.root) + self.layout:add(instance.root) table.insert(self.properties, instance) - gui.set_enabled(self.text_no_properties.text.node, false) + gui.set_enabled(self.text_no_properties, false) - instance.button.on_click:subscribe(on_click_callback) + if on_click_callback then + instance.button.on_click:subscribe(on_click_callback, callback_context) + end return instance end +function M:remove(widget) + for index = 1, #self.properties do + if self.properties[index] == widget then + self.druid:remove(widget) + self.layout:remove(widget.root) + gui.delete_node(widget.root) + table.remove(self.properties, index) + break + end + end + + if #self.properties == 0 then + gui.set_enabled(self.text_no_properties, true) + end +end + + return M