From f3fad8bd921c4c61d66688f3aead901ff5477cef Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 18 Nov 2024 21:48:08 +0200 Subject: [PATCH] Add test widget stubs --- README.md | 20 +- druid/widget/debug_panel/debug_panel.gui | 16 + .../properties/property_button.gui | 328 ++++++++++++++++++ .../properties/property_button.lua | 33 ++ .../properties/property_checkbox.gui | 120 +++++++ .../properties/property_checkbox.lua | 59 ++++ .../properties/property_slider.gui | 211 +++++++++++ .../properties/property_slider.lua | 75 ++++ .../properties_panel/properties_panel.gui | 295 ++++++++++++++++ .../properties_panel/properties_panel.lua | 126 +++++++ 10 files changed, 1282 insertions(+), 1 deletion(-) create mode 100644 druid/widget/debug_panel/debug_panel.gui create mode 100644 druid/widget/properties_panel/properties/property_button.gui create mode 100644 druid/widget/properties_panel/properties/property_button.lua create mode 100644 druid/widget/properties_panel/properties/property_checkbox.gui create mode 100644 druid/widget/properties_panel/properties/property_checkbox.lua create mode 100644 druid/widget/properties_panel/properties/property_slider.gui create mode 100644 druid/widget/properties_panel/properties/property_slider.lua create mode 100644 druid/widget/properties_panel/properties_panel.gui create mode 100644 druid/widget/properties_panel/properties_panel.lua diff --git a/README.md b/README.md index b72efc3..77a9bee 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ For all **Druid** instance functions, [see here](https://insality.github.io/drui ### Default GUI Script +Put the following code in your GUI script to start using **Druid**. + ```lua local druid = require("druid.druid") @@ -116,11 +118,27 @@ function on_message(self, message_id, message, sender) end function on_input(self, action_id, action) - self.druid:on_input(action_id, action) + return self.druid:on_input(action_id, action) end ``` +### Default Widget Template + +Create a new lua file to create a new widget class. This widget can be created with `self.druid:new_widget(widget_class, [template], [nodes])` + +```lua +local M = {} + +function M:init() + self.druid = self:get_druid() + self.root = self:get_node("root") +end + +return M +``` + + ### API Documentation **Druid** offers a wide range of components and functions. To facilitate usage, **Druid** provides comprehensive API documentation with examples and annotations. diff --git a/druid/widget/debug_panel/debug_panel.gui b/druid/widget/debug_panel/debug_panel.gui new file mode 100644 index 0000000..e925213 --- /dev/null +++ b/druid/widget/debug_panel/debug_panel.gui @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..d9ab2a3 --- /dev/null +++ b/druid/widget/properties_panel/properties/property_button.gui @@ -0,0 +1,328 @@ +script: "" +fonts { + name: "text_bold" + font: "/druid/fonts/text_bold.font" +} +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" + 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 + } + 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 new file mode 100644 index 0000000..9ffa273 --- /dev/null +++ b/druid/widget/properties_panel/properties/property_button.lua @@ -0,0 +1,33 @@ +local component = require("druid.component") +local lang_text = require("druid.extended.lang_text") + +---@class property_button: druid.base_component +---@field root node +---@field text_name druid.lang_text +---@field button druid.button +---@field text_button druid.text +---@field druid druid_instance +local M = component.create("property_button") + +---@param template string +---@param nodes table +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") --[[@as druid.lang_text]] + self.selected = self:get_node("selected") + gui.set_alpha(self.selected, 0) + + self.button = self.druid:new_button("button", self.on_click) + self.text_button = self.druid:new_text("text_button") +end + + +function M:on_click() + gui.set_alpha(self.selected, 1) + gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16) +end + + +return M diff --git a/druid/widget/properties_panel/properties/property_checkbox.gui b/druid/widget/properties_panel/properties/property_checkbox.gui new file mode 100644 index 0000000..777a6d3 --- /dev/null +++ b/druid/widget/properties_panel/properties/property_checkbox.gui @@ -0,0 +1,120 @@ +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" + pivot: PIVOT_NW + adjust_mode: ADJUST_MODE_STRETCH + inherit_alpha: true + visible: false +} +nodes { + position { + y: -20.0 + } + scale { + x: 0.65 + y: 0.65 + } + size { + x: 200.0 + y: 40.0 + } + color { + x: 0.463 + y: 0.475 + z: 0.49 + } + type: TYPE_TEXT + text: "Checkbox" + 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: 174.0 + y: -20.0 + } + size { + x: 40.0 + y: 40.0 + } + color { + x: 0.463 + y: 0.475 + z: 0.49 + } + type: TYPE_BOX + texture: "druid/rect_round2_width1" + id: "button" + parent: "root" + inherit_alpha: true + slice9 { + x: 4.0 + y: 4.0 + z: 4.0 + w: 4.0 + } +} +nodes { + color { + x: 0.722 + y: 0.741 + z: 0.761 + } + type: TYPE_BOX + texture: "druid/ui_circle_16" + id: "icon" + parent: "button" + inherit_alpha: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + y: -20.0 + } + size { + x: 40.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: "button" + inherit_alpha: true +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT diff --git a/druid/widget/properties_panel/properties/property_checkbox.lua b/druid/widget/properties_panel/properties/property_checkbox.lua new file mode 100644 index 0000000..fbe92c5 --- /dev/null +++ b/druid/widget/properties_panel/properties/property_checkbox.lua @@ -0,0 +1,59 @@ +local component = require("druid.component") +local container = require("example.components.container.container") +local lang_text = require("druid.extended.lang_text") + +---@class property_checkbox: druid.base_component +---@field druid druid_instance +---@field root druid.container +---@field text_name druid.lang_text +---@field button druid.button +---@field selected node +local M = component.create("property_checkbox") + + +---@param template string +---@param nodes table +function M:init(template, nodes) + self.druid = self:get_druid(template, nodes) + self.root = self.druid:new(container, "root") --[[@as druid.container]] + + self.icon = self:get_node("icon") + gui.set_enabled(self.icon, false) + + self.selected = self:get_node("selected") + gui.set_alpha(self.selected, 0) + + self.text_name = self.druid:new(lang_text, "text_name") --[[@as druid.lang_text]] + + self.button = self.druid:new_button("button", self.on_click) +end + + +---@param value boolean +function M:set_value(value, is_instant) + if self._value == value then + return + end + + self._value = value + gui.set_enabled(self.icon, value) + + if not is_instant then + gui.set_alpha(self.selected, 1) + gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16) + end +end + + +---@return boolean +function M:get_value() + return self._value +end + + +function M:on_click() + self:set_value(not self:get_value()) +end + + +return M diff --git a/druid/widget/properties_panel/properties/property_slider.gui b/druid/widget/properties_panel/properties/property_slider.gui new file mode 100644 index 0000000..bef97ac --- /dev/null +++ b/druid/widget/properties_panel/properties/property_slider.gui @@ -0,0 +1,211 @@ +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" + pivot: PIVOT_NW + adjust_mode: ADJUST_MODE_STRETCH + inherit_alpha: true + visible: false +} +nodes { + position { + y: -20.0 + } + scale { + x: 0.65 + y: 0.65 + } + size { + x: 200.0 + y: 40.0 + } + color { + x: 0.463 + y: 0.475 + z: 0.49 + } + type: TYPE_TEXT + text: "Slider" + 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: 234.0 + y: -20.0 + } + size { + x: 160.0 + y: 40.0 + } + color { + x: 0.129 + y: 0.141 + z: 0.157 + } + type: TYPE_BOX + texture: "druid/empty" + id: "slider" + parent: "root" + inherit_alpha: true +} +nodes { + size { + x: 160.0 + y: 8.0 + } + color { + x: 0.129 + y: 0.141 + z: 0.157 + } + type: TYPE_BOX + texture: "druid/ui_circle_8" + id: "slider_back" + parent: "slider" + inherit_alpha: true + slice9 { + x: 4.0 + y: 4.0 + z: 4.0 + w: 4.0 + } +} +nodes { + position { + x: -68.0 + } + size { + x: 24.0 + y: 24.0 + } + color { + x: 0.722 + y: 0.741 + z: 0.761 + } + type: TYPE_BOX + texture: "druid/ui_circle_8" + id: "slider_pin" + parent: "slider" + inherit_alpha: true + slice9 { + x: 4.0 + y: 4.0 + z: 4.0 + w: 4.0 + } +} +nodes { + position { + x: 380.0 + y: -20.0 + } + size { + x: 60.0 + y: 40.0 + } + color { + x: 0.463 + y: 0.475 + z: 0.49 + } + type: TYPE_BOX + texture: "druid/rect_round2_width1" + id: "button" + pivot: PIVOT_E + parent: "root" + inherit_alpha: true + slice9 { + x: 4.0 + y: 4.0 + z: 4.0 + w: 4.0 + } +} +nodes { + position { + y: -20.0 + } + size { + x: 60.0 + y: 4.0 + } + color { + x: 0.894 + y: 0.506 + z: 0.333 + } + type: TYPE_BOX + texture: "druid/pixel" + id: "selected" + pivot: PIVOT_SE + adjust_mode: ADJUST_MODE_STRETCH + parent: "button" + inherit_alpha: true +} +nodes { + position { + x: -30.0 + } + scale { + x: 0.55 + y: 0.55 + } + size { + x: 100.0 + y: 40.0 + } + color { + x: 0.722 + y: 0.741 + z: 0.761 + } + type: TYPE_TEXT + text: "25 %" + 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: "button" + inherit_alpha: true + outline_alpha: 0.0 + shadow_alpha: 0.0 +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT diff --git a/druid/widget/properties_panel/properties/property_slider.lua b/druid/widget/properties_panel/properties/property_slider.lua new file mode 100644 index 0000000..d5ada5f --- /dev/null +++ b/druid/widget/properties_panel/properties/property_slider.lua @@ -0,0 +1,75 @@ +local component = require("druid.component") +local container = require("example.components.container.container") +local lang_text = require("druid.extended.lang_text") +local slider = require("druid.extended.slider") + +---@class property_slider: druid.base_component +---@field druid druid_instance +---@field root druid.container +---@field text_name druid.lang_text +---@field text_value druid.text +---@field slider druid.slider +local M = component.create("property_slider") + + +---@param template string +---@param nodes table +function M:init(template, nodes) + self.druid = self:get_druid(template, nodes) + + self.root = self.druid:new(container, "root") --[[@as druid.container]] + 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_value = self.druid:new_text("text_value") + self.slider = self.druid:new(slider, "slider_pin", vmath.vector3(68, 0, 0), self._on_slider_change_by_user) --[[@as druid.slider]] + self.slider:set_input_node("slider") + + self:set_text_function(function(value) + return math.floor(value * 100) .. "%" + end) +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)) +end + + +---@param value number +function M:set_value(value, is_instant) + if self._value == value then + return + end + + self._value = value + self.slider:set(value, true) + self.text_value:set_to(self._text_function(value)) + + if not is_instant then + gui.set_alpha(self.selected, 1) + gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16) + end +end + + +---@return number +function M:get_value() + return self._value +end + + +function M:_on_slider_change_by_user(value) + self._value = value + self.text_value:set_to(self._text_function(value)) + + gui.set_alpha(self.selected, 1) + gui.animate(self.selected, "color.w", 0, gui.EASING_INSINE, 0.16) +end + + +return M diff --git a/druid/widget/properties_panel/properties_panel.gui b/druid/widget/properties_panel/properties_panel.gui new file mode 100644 index 0000000..da08017 --- /dev/null +++ b/druid/widget/properties_panel/properties_panel.gui @@ -0,0 +1,295 @@ +fonts { + name: "text_regular" + font: "/druid/fonts/text_regular.font" +} +textures { + name: "druid" + texture: "/druid/druid.atlas" +} +nodes { + size { + x: 440.0 + y: 350.0 + } + color { + x: 0.173 + y: 0.184 + z: 0.204 + } + type: TYPE_BOX + texture: "druid/pixel" + id: "root" + adjust_mode: ADJUST_MODE_STRETCH + layer: "druid" + inherit_alpha: true +} +nodes { + position { + x: -210.0 + y: 165.0 + } + scale { + x: 0.9 + y: 0.9 + } + size { + x: 245.0 + y: 50.0 + } + color { + x: 0.463 + y: 0.475 + z: 0.49 + } + type: TYPE_TEXT + text: "Properties" + font: "text_regular" + id: "text_header" + 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" + layer: "text_regular" + inherit_alpha: true + outline_alpha: 0.0 + shadow_alpha: 0.0 +} +nodes { + position { + x: -200.0 + y: 115.0 + } + size { + x: 400.0 + y: 290.0 + } + type: TYPE_BOX + texture: "druid/empty" + id: "scroll_view" + xanchor: XANCHOR_LEFT + pivot: PIVOT_NW + adjust_mode: ADJUST_MODE_STRETCH + parent: "root" + layer: "druid" + inherit_alpha: true + clipping_mode: CLIPPING_MODE_STENCIL +} +nodes { + size { + x: 400.0 + y: 290.0 + } + type: TYPE_BOX + texture: "druid/empty" + id: "scroll_content" + pivot: PIVOT_NW + adjust_mode: ADJUST_MODE_STRETCH + parent: "scroll_view" + layer: "druid" + inherit_alpha: true + visible: false +} +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" + layer: "text_regular" + inherit_alpha: true + outline_alpha: 0.0 + shadow_alpha: 0.0 + enabled: false +} +nodes { + position { + x: -200.0 + y: 100.0 + } + type: TYPE_BOX + texture: "druid/empty" + id: "propeties" + parent: "root" + inherit_alpha: true + size_mode: SIZE_MODE_AUTO + visible: false +} +nodes { + type: TYPE_TEMPLATE + id: "property_slider" + parent: "propeties" + inherit_alpha: true + template: "/druid/widget/properties_panel/properties/property_slider.gui" +} +nodes { + type: TYPE_BOX + id: "property_slider/root" + parent: "property_slider" + template_node_child: true +} +nodes { + type: TYPE_TEXT + id: "property_slider/text_name" + parent: "property_slider/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_slider/slider" + parent: "property_slider/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_slider/slider_back" + parent: "property_slider/slider" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_slider/slider_pin" + parent: "property_slider/slider" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_slider/button" + parent: "property_slider/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_slider/selected" + parent: "property_slider/button" + template_node_child: true +} +nodes { + type: TYPE_TEXT + id: "property_slider/text_value" + parent: "property_slider/button" + template_node_child: true +} +nodes { + position { + y: -50.0 + } + type: TYPE_TEMPLATE + id: "property_checkbox" + parent: "propeties" + inherit_alpha: true + template: "/druid/widget/properties_panel/properties/property_checkbox.gui" +} +nodes { + type: TYPE_BOX + id: "property_checkbox/root" + parent: "property_checkbox" + template_node_child: true +} +nodes { + type: TYPE_TEXT + id: "property_checkbox/text_name" + parent: "property_checkbox/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_checkbox/button" + parent: "property_checkbox/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_checkbox/icon" + parent: "property_checkbox/button" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_checkbox/selected" + parent: "property_checkbox/button" + template_node_child: true +} +nodes { + position { + y: -100.0 + } + type: TYPE_TEMPLATE + id: "property_button" + parent: "propeties" + inherit_alpha: true + template: "/druid/widget/properties_panel/properties/property_button.gui" +} +nodes { + type: TYPE_BOX + id: "property_button/root" + parent: "property_button" + template_node_child: true +} +nodes { + type: TYPE_TEXT + id: "property_button/text_name" + parent: "property_button/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_button/button" + parent: "property_button/root" + template_node_child: true +} +nodes { + type: TYPE_BOX + id: "property_button/selected" + parent: "property_button/button" + template_node_child: true +} +nodes { + type: TYPE_TEXT + id: "property_button/text_button" + parent: "property_button/button" + template_node_child: true +} +layers { + name: "druid" +} +layers { + name: "text_regular" +} +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 new file mode 100644 index 0000000..6a6496b --- /dev/null +++ b/druid/widget/properties_panel/properties_panel.lua @@ -0,0 +1,126 @@ +local container = require("example.components.container.container") +local lang_text = require("druid.extended.lang_text") + +local property_checkbox = require("example.components.properties_panel.properties.property_checkbox") +local property_slider = require("example.components.properties_panel.properties.property_slider") +local property_button = require("example.components.properties_panel.properties.property_button") + +---@class properties_panel: druid.widget +---@field root node +---@field text_no_properties druid.lang_text +---@field scroll druid.scroll +---@field druid druid_instance +local M = {} + +---@param template string +---@param nodes table +function M:init(template, nodes) + self.druid = self:get_druid(template, nodes) + + --self.root = self.druid:new(container, "root") --[[@as druid.container]] + --self.root:add_container("text_header") + --self.root:add_container("separator") + self.root = self:get_node("root") + + self.properties = {} + + self.druid:new(lang_text, "text_header", "ui_properties_panel") + self.text_no_properties = self.druid:new(lang_text, "text_no_properties", "ui_no_properties") --[[@as druid.lang_text]] + + self.scroll = self.druid:new_scroll("scroll_view", "scroll_content") + self.layout = self.druid:new_layout("scroll_content", "item_size") + + self.grid = self.druid:new_static_grid("scroll_content", "item_size", 1) + self.scroll:bind_grid(self.grid) + + self.property_checkbox_prefab = self:get_node("property_checkbox/root") + gui.set_enabled(self.property_checkbox_prefab, false) + + self.property_slider_prefab = self:get_node("property_slider/root") + gui.set_enabled(self.property_slider_prefab, false) + + self.property_button_prefab = self:get_node("property_button/root") + gui.set_enabled(self.property_button_prefab, false) +end + + +function M:clear() + for index = 1, #self.properties do + self.druid:remove(self.properties[index]) + end + self.properties = {} + + local nodes = self.grid.nodes + for index = 1, #nodes do + gui.delete_node(nodes[index]) + end + self.grid:clear() + + gui.set_enabled(self.text_no_properties.text.node, true) +end + + +---@param text_id string +---@param initial_value boolean +---@param on_change_callback function +---@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) + 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) + table.insert(self.properties, instance) + gui.set_enabled(self.text_no_properties.text.node, false) + + return instance +end + + +---@param text_id string +---@param initial_value number +---@param on_change_callback function +---@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) + instance:set_value(initial_value, true) + + gui.set_enabled(instance.root.node, true) + self.grid:add(instance.root.node) + table.insert(self.properties, instance) + gui.set_enabled(self.text_no_properties.text.node, false) + + instance.slider.on_change_value:subscribe(function(_, value) + on_change_callback(value) + end) + + return instance +end + + +---@param text_id string +---@param on_click_callback function +function M:add_button(text_id, on_click_callback) + 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) + + gui.set_enabled(instance.root, true) + self.grid:add(instance.root) + table.insert(self.properties, instance) + gui.set_enabled(self.text_no_properties.text.node, false) + + instance.button.on_click:subscribe(on_click_callback) + + return instance +end + + +return M