mirror of
https://github.com/Insality/druid
synced 2025-06-26 18:07:46 +02:00
Update docs, add Editor script: Create Druid GUI Script, add simple using widgets example
This commit is contained in:
parent
749666a4a5
commit
6795934a1f
@ -223,7 +223,7 @@ Special thanks to all the contributors who have helped make **Druid** better!
|
||||
<img src="https://contributors-img.web.app/image?repo=insality/druid"/>
|
||||
</a>
|
||||
|
||||
Read the [CONTRIBUTING](CONTRIBUTING) file for more information.
|
||||
Read the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
|
||||
|
||||
|
||||
## ❤️ Support project ❤️
|
||||
|
144
druid/editor_scripts/create_druid_gui_script.lua
Normal file
144
druid/editor_scripts/create_druid_gui_script.lua
Normal file
@ -0,0 +1,144 @@
|
||||
local M = {}
|
||||
|
||||
local function to_camel_case(snake_str)
|
||||
local components = {}
|
||||
for component in snake_str:gmatch("[^_]+") do
|
||||
table.insert(components, component:sub(1, 1):upper() .. component:sub(2))
|
||||
end
|
||||
return table.concat(components, "")
|
||||
end
|
||||
|
||||
|
||||
function M.create_druid_gui_script(selection)
|
||||
local gui_filepath = editor.get(selection, "path")
|
||||
local filename = gui_filepath:match("([^/]+)%.gui$")
|
||||
print("Create Druid GUI Script for", gui_filepath)
|
||||
|
||||
local absolute_project_path = editor.external_file_attributes(".").path
|
||||
local widget_resource_path = gui_filepath:gsub("%.gui$", ".gui_script")
|
||||
local new_widget_absolute_path = absolute_project_path .. widget_resource_path
|
||||
|
||||
local widget_name = to_camel_case(filename)
|
||||
local widget_type = filename
|
||||
|
||||
-- Check if file already exists
|
||||
local f = io.open(new_widget_absolute_path, "r")
|
||||
if f then
|
||||
f:close()
|
||||
print("Widget file already exists at " .. new_widget_absolute_path)
|
||||
print("Creation aborted to prevent overwriting")
|
||||
return
|
||||
end
|
||||
|
||||
-- Get template path from preferences
|
||||
local template_path = editor.prefs.get("druid.gui_script_template_path")
|
||||
|
||||
-- Get template content using the path from preferences
|
||||
local template_content = editor.get(template_path, "text")
|
||||
if not template_content then
|
||||
print("Error: Could not load template from", template_path)
|
||||
print("Check the template path in [Druid] Settings")
|
||||
return
|
||||
end
|
||||
|
||||
-- Replace template variables
|
||||
template_content = template_content:gsub("{COMPONENT_NAME}", widget_name)
|
||||
template_content = template_content:gsub("{COMPONENT_TYPE}", widget_type)
|
||||
|
||||
-- Write file
|
||||
local file, err = io.open(new_widget_absolute_path, "w")
|
||||
if not file then
|
||||
print("Error creating widget file:", err)
|
||||
return
|
||||
end
|
||||
file:write(template_content)
|
||||
file:close()
|
||||
|
||||
print("Widget created at " .. widget_resource_path)
|
||||
|
||||
M.link_gui_script(selection, widget_resource_path)
|
||||
end
|
||||
|
||||
|
||||
---Links a GUI script to a GUI file by updating the script property
|
||||
---@param selection string The GUI resource to modify
|
||||
---@param widget_resource_path string The path to the GUI script to link
|
||||
function M.link_gui_script(selection, widget_resource_path)
|
||||
local defold_parser = require("druid.editor_scripts.defold_parser.defold_parser")
|
||||
local system = require("druid.editor_scripts.defold_parser.system.system")
|
||||
|
||||
local gui_filepath = editor.get(selection, "path")
|
||||
print("Linking GUI script to", gui_filepath)
|
||||
|
||||
-- Get the absolute path to the file
|
||||
local absolute_project_path = editor.external_file_attributes(".").path
|
||||
if not absolute_project_path:match("[\\/]$") then
|
||||
absolute_project_path = absolute_project_path .. "/"
|
||||
end
|
||||
local clean_gui_path = gui_filepath
|
||||
if clean_gui_path:sub(1, 1) == "/" then
|
||||
clean_gui_path = clean_gui_path:sub(2)
|
||||
end
|
||||
local gui_absolute_path = absolute_project_path .. clean_gui_path
|
||||
|
||||
-- Create a backup
|
||||
local backup_path = gui_absolute_path .. ".backup"
|
||||
print("Creating backup at:", backup_path)
|
||||
|
||||
-- Read and write backup
|
||||
local content, err_read = system.read_file(gui_absolute_path)
|
||||
if not content then
|
||||
print("Error reading original file for backup:", err_read)
|
||||
return
|
||||
end
|
||||
|
||||
local success, err_write = system.write_file(backup_path, content)
|
||||
if not success then
|
||||
print("Error creating backup file:", err_write)
|
||||
return
|
||||
end
|
||||
|
||||
-- Parse the GUI file
|
||||
print("Parsing GUI file...")
|
||||
local gui_data = defold_parser.load_from_file(gui_absolute_path)
|
||||
if not gui_data then
|
||||
print("Error: Failed to parse GUI file")
|
||||
return
|
||||
end
|
||||
|
||||
-- Update the script property
|
||||
print("Setting script property to:", widget_resource_path)
|
||||
gui_data.script = widget_resource_path
|
||||
|
||||
-- Write the updated GUI file
|
||||
print("Writing updated GUI file...")
|
||||
local save_success = defold_parser.save_to_file(gui_absolute_path, gui_data)
|
||||
|
||||
if not save_success then
|
||||
print("Error: Failed to save GUI file")
|
||||
print("Attempting to restore from backup...")
|
||||
|
||||
-- Restore from backup on failure
|
||||
local backup_content, backup_err_read = system.read_file(backup_path)
|
||||
if not backup_content then
|
||||
print("Error reading backup file:", backup_err_read)
|
||||
return
|
||||
end
|
||||
|
||||
local restore_success, restore_err_write = system.write_file(gui_absolute_path, backup_content)
|
||||
if not restore_success then
|
||||
print("Critical: Failed to restore from backup:", restore_err_write)
|
||||
return
|
||||
end
|
||||
|
||||
print("Restored successfully from backup")
|
||||
return
|
||||
end
|
||||
|
||||
-- Remove backup on success
|
||||
os.remove(backup_path)
|
||||
print("Successfully linked GUI script to:", gui_filepath)
|
||||
end
|
||||
|
||||
|
||||
return M
|
@ -1,11 +1,12 @@
|
||||
local assign_layers = require("druid.editor_scripts.assign_layers")
|
||||
local create_druid_widget = require("druid.editor_scripts.create_druid_widget")
|
||||
local create_druid_gui_script = require("druid.editor_scripts.create_druid_gui_script")
|
||||
local druid_settings = require("druid.editor_scripts.druid_settings")
|
||||
|
||||
local M = {}
|
||||
|
||||
local DEFAULT_WIDGET_TEMPLATE_PATH = "/druid/templates/widget_full.lua.template"
|
||||
|
||||
local DEFAULT_GUI_SCRIPT_TEMPLATE_PATH = "/druid/templates/druid.gui_script.template"
|
||||
|
||||
---Define preferences schema
|
||||
function M.get_prefs_schema()
|
||||
@ -13,6 +14,10 @@ function M.get_prefs_schema()
|
||||
["druid.widget_template_path"] = editor.prefs.schema.string({
|
||||
default = DEFAULT_WIDGET_TEMPLATE_PATH,
|
||||
scope = editor.prefs.SCOPE.PROJECT
|
||||
}),
|
||||
["druid.gui_script_template_path"] = editor.prefs.schema.string({
|
||||
default = DEFAULT_GUI_SCRIPT_TEMPLATE_PATH,
|
||||
scope = editor.prefs.SCOPE.PROJECT
|
||||
})
|
||||
}
|
||||
end
|
||||
@ -47,6 +52,19 @@ function M.get_commands()
|
||||
end
|
||||
},
|
||||
|
||||
{
|
||||
label = "[Druid] Create Druid GUI Script",
|
||||
locations = { "Edit", "Assets" },
|
||||
query = { selection = {type = "resource", cardinality = "one"} },
|
||||
active = function(opts)
|
||||
local path = editor.get(opts.selection, "path")
|
||||
return path:match("%.gui$") ~= nil
|
||||
end,
|
||||
run = function(opts)
|
||||
return create_druid_gui_script.create_druid_gui_script(opts.selection)
|
||||
end
|
||||
},
|
||||
|
||||
{
|
||||
label = "[Druid] Settings",
|
||||
locations = { "Edit" },
|
||||
|
@ -6,8 +6,6 @@ function M.open_settings()
|
||||
|
||||
local dialog_component = editor.ui.component(function(props)
|
||||
local template_path, set_template_path = editor.ui.use_state(editor.prefs.get("druid.widget_template_path"))
|
||||
|
||||
-- Check if the template path is valid
|
||||
local path_valid = editor.ui.use_memo(function(path)
|
||||
-- Use resource_exists to check if the resource exists
|
||||
local exists = false
|
||||
@ -19,6 +17,16 @@ function M.open_settings()
|
||||
return exists
|
||||
end, template_path)
|
||||
|
||||
local gui_script_template_path, set_gui_script_template_path = editor.ui.use_state(editor.prefs.get("druid.gui_script_template_path"))
|
||||
local gui_script_template_path_valid = editor.ui.use_memo(function(path)
|
||||
local exists = false
|
||||
pcall(function()
|
||||
local content = editor.get(path, "text")
|
||||
exists = content ~= nil
|
||||
end)
|
||||
return exists
|
||||
end, gui_script_template_path)
|
||||
|
||||
return editor.ui.dialog({
|
||||
title = "Druid Settings",
|
||||
content = editor.ui.vertical({
|
||||
@ -39,6 +47,20 @@ function M.open_settings()
|
||||
color = editor.ui.COLOR.WARNING
|
||||
}) or nil,
|
||||
|
||||
editor.ui.label({
|
||||
text = "GUI Script Template Path:"
|
||||
}),
|
||||
editor.ui.resource_field({
|
||||
value = gui_script_template_path,
|
||||
on_value_changed = set_gui_script_template_path,
|
||||
extensions = {"lua", "template"},
|
||||
padding = editor.ui.PADDING.SMALL
|
||||
}),
|
||||
not gui_script_template_path_valid and editor.ui.label({
|
||||
text = "Warning: Path not found!",
|
||||
color = editor.ui.COLOR.WARNING
|
||||
}) or nil,
|
||||
|
||||
-- Links section title
|
||||
editor.ui.label({
|
||||
text = "Documentation:",
|
||||
|
@ -3,8 +3,7 @@ material: "/builtins/fonts/font-df.material"
|
||||
size: 40
|
||||
outline_alpha: 1.0
|
||||
outline_width: 2.0
|
||||
shadow_alpha: 1.0
|
||||
shadow_blur: 2
|
||||
shadow_blur: 0
|
||||
output_format: TYPE_DISTANCE_FIELD
|
||||
render_mode: MODE_MULTI_LAYER
|
||||
characters: "\302\241\302\253\302\273\302\277\303\200\303\202\303\206\303\207\303\210\303\211\303\212\303\213\303\216\303\217\303\224\303\231\303\233\303\234\303\237\303\240\303\241\303\242\303\243\303\244\303\246\303\247\303\250\303\251\303\252\303\253\303\255\303\256\303\257\303\261\303\262\303\263\303\264\303\265\303\266\303\271\303\273\303\274\303\277\305\222\305\223\305\270\320\201\320\220\320\221\320\222\320\223\320\224\320\225\320\226\320\227\320\230\320\231\320\232\320\233\320\234\320\235\320\236\320\237\320\240\320\241\320\242\320\243\320\244\320\245\320\246\320\247\320\250\320\251\320\252\320\253\320\254\320\255\320\256\320\257\320\260\320\261\320\262\320\263\320\264\320\265\320\266\320\267\320\270\320\271\320\272\320\273\320\274\320\275\320\276\320\277\321\200\321\201\321\202\321\203\321\204\321\205\321\206\321\207\321\210\321\211\321\212\321\213\321\214\321\215\321\216\321\217\321\221\342\200\224\343\200\201\343\200\202\343\200\214\343\200\215\357\274\201\357\274\214\357\274\237 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}"
|
||||
|
21
druid/templates/druid.gui_script.template
Normal file
21
druid/templates/druid.gui_script.template
Normal file
@ -0,0 +1,21 @@
|
||||
local druid = require("druid.druid")
|
||||
|
||||
function init(self)
|
||||
self.druid = druid.new(self)
|
||||
end
|
||||
|
||||
function final(self)
|
||||
self.druid:final()
|
||||
end
|
||||
|
||||
function update(self, dt)
|
||||
self.druid:update(dt)
|
||||
end
|
||||
|
||||
function on_message(self, message_id, message, sender)
|
||||
self.druid:on_message(message_id, message, sender)
|
||||
end
|
||||
|
||||
function on_input(self, action_id, action)
|
||||
return self.druid:on_input(action_id, action)
|
||||
end
|
@ -52,29 +52,8 @@ function M:init()
|
||||
self:set_hidden(not self._is_hidden)
|
||||
end):set_style(nil)
|
||||
|
||||
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)
|
||||
|
||||
self.property_input_prefab = self:get_node("property_input/root")
|
||||
gui.set_enabled(self.property_input_prefab, false)
|
||||
|
||||
self.property_text_prefab = self:get_node("property_text/root")
|
||||
gui.set_enabled(self.property_text_prefab, false)
|
||||
|
||||
self.property_left_right_selector_prefab = self:get_node("property_left_right_selector/root")
|
||||
gui.set_enabled(self.property_left_right_selector_prefab, false)
|
||||
|
||||
self.property_vector3_prefab = self:get_node("property_vector3/root")
|
||||
gui.set_enabled(self.property_vector3_prefab, false)
|
||||
|
||||
-- We not using as a part of properties, since it handled in a way to be paginable
|
||||
self.paginator = self.druid:new_widget(property_left_right_selector, "property_left_right_selector", self.property_left_right_selector_prefab)
|
||||
self.paginator = self.druid:new_widget(property_left_right_selector, "property_left_right_selector", "root")
|
||||
self.paginator:set_text("Page")
|
||||
self.paginator:set_number_type(1, 1, true)
|
||||
self.paginator:set_value(self.current_page)
|
||||
@ -85,6 +64,14 @@ function M:init()
|
||||
self.paginator.container:set_size(width)
|
||||
|
||||
gui.set_enabled(self.paginator.root, false)
|
||||
|
||||
gui.set_enabled(self:get_node("property_checkbox/root"), false)
|
||||
gui.set_enabled(self:get_node("property_slider/root"), false)
|
||||
gui.set_enabled(self:get_node("property_button/root"), false)
|
||||
gui.set_enabled(self:get_node("property_input/root"), false)
|
||||
gui.set_enabled(self:get_node("property_text/root"), false)
|
||||
gui.set_enabled(self:get_node("property_left_right_selector/root"), false)
|
||||
gui.set_enabled(self:get_node("property_vector3/root"), false)
|
||||
end
|
||||
|
||||
|
||||
@ -179,53 +166,53 @@ end
|
||||
---@param on_create fun(checkbox: druid.widget.property_checkbox)|nil
|
||||
---@return druid.widget.properties_panel
|
||||
function M:add_checkbox(on_create)
|
||||
return self:add_inner_widget(property_checkbox, "property_checkbox", self.property_checkbox_prefab, on_create)
|
||||
return self:add_inner_widget(property_checkbox, "property_checkbox", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@param on_create fun(slider: druid.widget.property_slider)|nil
|
||||
---@return druid.widget.properties_panel
|
||||
function M:add_slider(on_create)
|
||||
return self:add_inner_widget(property_slider, "property_slider", self.property_slider_prefab, on_create)
|
||||
return self:add_inner_widget(property_slider, "property_slider", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@param on_create fun(button: druid.widget.property_button)|nil
|
||||
---@return druid.widget.properties_panel
|
||||
function M:add_button(on_create)
|
||||
return self:add_inner_widget(property_button, "property_button", self.property_button_prefab, on_create)
|
||||
return self:add_inner_widget(property_button, "property_button", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@param on_create fun(input: druid.widget.property_input)|nil
|
||||
---@return druid.widget.properties_panel
|
||||
function M:add_input(on_create)
|
||||
return self:add_inner_widget(property_input, "property_input", self.property_input_prefab, on_create)
|
||||
return self:add_inner_widget(property_input, "property_input", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@param on_create fun(text: druid.widget.property_text)|nil
|
||||
function M:add_text(on_create)
|
||||
return self:add_inner_widget(property_text, "property_text", self.property_text_prefab, on_create)
|
||||
return self:add_inner_widget(property_text, "property_text", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@param on_create fun(selector: druid.widget.property_left_right_selector)|nil
|
||||
function M:add_left_right_selector(on_create)
|
||||
return self:add_inner_widget(property_left_right_selector, "property_left_right_selector", self.property_left_right_selector_prefab, on_create)
|
||||
return self:add_inner_widget(property_left_right_selector, "property_left_right_selector", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@param on_create fun(vector3: druid.widget.property_vector3)|nil
|
||||
function M:add_vector3(on_create)
|
||||
return self:add_inner_widget(property_vector3, "property_vector3", self.property_vector3_prefab, on_create)
|
||||
return self:add_inner_widget(property_vector3, "property_vector3", "root", on_create)
|
||||
end
|
||||
|
||||
|
||||
---@generic T: druid.widget
|
||||
---@param widget_class T
|
||||
---@param template string|nil
|
||||
---@param nodes table<hash, node>|node|nil
|
||||
---@param nodes table<hash, node>|string|node|nil
|
||||
---@param on_create fun(widget: T)|nil
|
||||
---@return druid.widget.properties_panel
|
||||
function M:add_inner_widget(widget_class, template, nodes, on_create)
|
||||
|
@ -4998,6 +4998,13 @@ nodes {
|
||||
parent: "container_resize/panel_content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEMPLATE
|
||||
id: "use_widgets"
|
||||
parent: "container"
|
||||
inherit_alpha: true
|
||||
template: "/example/examples/container/use_widgets/use_widgets.gui"
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: -20.0
|
||||
|
@ -151,7 +151,9 @@ local function setup_components(self)
|
||||
self.container_output:add_container(self.output_list.root)
|
||||
|
||||
self.next_example = self.druid:new_hotkey("key_down", on_next_example, self)
|
||||
:add_hotkey("key_s")
|
||||
self.previous_example = self.druid:new_hotkey("key_up", on_previous_example, self)
|
||||
:add_hotkey("key_w")
|
||||
|
||||
do -- Component bindings
|
||||
self.examples_list_view.on_debug_info:subscribe(function(info)
|
||||
|
@ -57,7 +57,7 @@ nodes {
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
y: 118.0
|
||||
y: -118.0
|
||||
}
|
||||
type: TYPE_BOX
|
||||
id: "slider/slider_pin"
|
||||
|
@ -6,7 +6,7 @@ local helper = require("druid.helper")
|
||||
local M = {}
|
||||
|
||||
function M:init()
|
||||
self.slider = self.druid:new_slider("slider/slider_pin", vmath.vector3(0, -118, 0), self.on_slider_change) --[[@as druid.slider]]
|
||||
self.slider = self.druid:new_slider("slider/slider_pin", vmath.vector3(0, 118, 0), self.on_slider_change) --[[@as druid.slider]]
|
||||
|
||||
-- To add input across all slider widget add a root node to acquire additional input
|
||||
self.slider:set_input_node("slider/root")
|
||||
|
@ -40,7 +40,7 @@ nodes {
|
||||
y: 100.0
|
||||
}
|
||||
type: TYPE_TEXT
|
||||
text: "Can be used as relative anchors"
|
||||
text: "Can be resized with different rules"
|
||||
font: "text_bold"
|
||||
id: "text"
|
||||
parent: "root"
|
||||
@ -204,6 +204,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -230,6 +231,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -257,6 +259,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
size {
|
||||
@ -279,6 +282,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -305,6 +309,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -331,6 +336,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -358,6 +364,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -384,6 +391,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
@ -411,6 +419,7 @@ nodes {
|
||||
z: 16.0
|
||||
w: 16.0
|
||||
}
|
||||
alpha: 0.25
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||
|
@ -18,7 +18,7 @@ function M.get_examples()
|
||||
root = "container_resize/root",
|
||||
code_url = "example/examples/container/container_resize/container_resize.lua",
|
||||
widget_class = require("example.examples.container.container_resize.container_resize"),
|
||||
},
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
10
example/examples/using_widgets/using_widgets.collection
Normal file
10
example/examples/using_widgets/using_widgets.collection
Normal file
@ -0,0 +1,10 @@
|
||||
name: "using_widgets"
|
||||
scale_along_z: 0
|
||||
embedded_instances {
|
||||
id: "go"
|
||||
data: "components {\n"
|
||||
" id: \"using_widgets\"\n"
|
||||
" component: \"/example/examples/using_widgets/using_widgets.gui\"\n"
|
||||
"}\n"
|
||||
""
|
||||
}
|
119
example/examples/using_widgets/using_widgets.gui
Normal file
119
example/examples/using_widgets/using_widgets.gui
Normal file
@ -0,0 +1,119 @@
|
||||
script: "/example/examples/using_widgets/using_widgets.gui_script"
|
||||
fonts {
|
||||
name: "text_bold"
|
||||
font: "/example/assets/fonts/text_bold.font"
|
||||
}
|
||||
fonts {
|
||||
name: "text_regular"
|
||||
font: "/example/assets/fonts/text_regular.font"
|
||||
}
|
||||
textures {
|
||||
name: "druid_example"
|
||||
texture: "/example/assets/druid_example.atlas"
|
||||
}
|
||||
nodes {
|
||||
position {
|
||||
x: 861.0
|
||||
y: 545.0
|
||||
}
|
||||
scale {
|
||||
x: 3.0
|
||||
y: 3.0
|
||||
}
|
||||
type: TYPE_TEMPLATE
|
||||
id: "memory_panel"
|
||||
inherit_alpha: true
|
||||
template: "/druid/widget/memory_panel/memory_panel.gui"
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/root"
|
||||
parent: "memory_panel"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEMPLATE
|
||||
id: "memory_panel/mini_graph"
|
||||
parent: "memory_panel/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/mini_graph/root"
|
||||
parent: "memory_panel/mini_graph"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/mini_graph/header"
|
||||
parent: "memory_panel/mini_graph/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "memory_panel/mini_graph/text_header"
|
||||
parent: "memory_panel/mini_graph/header"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/mini_graph/icon_drag"
|
||||
parent: "memory_panel/mini_graph/header"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/mini_graph/content"
|
||||
parent: "memory_panel/mini_graph/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/mini_graph/prefab_line"
|
||||
parent: "memory_panel/mini_graph/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/mini_graph/color_low"
|
||||
parent: "memory_panel/mini_graph/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/content"
|
||||
parent: "memory_panel/root"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "memory_panel/text_max_value"
|
||||
parent: "memory_panel/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "memory_panel/text_per_second"
|
||||
parent: "memory_panel/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/line_second_1"
|
||||
parent: "memory_panel/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_BOX
|
||||
id: "memory_panel/line_second_2"
|
||||
parent: "memory_panel/content"
|
||||
template_node_child: true
|
||||
}
|
||||
nodes {
|
||||
type: TYPE_TEXT
|
||||
id: "memory_panel/text_memory"
|
||||
parent: "memory_panel/content"
|
||||
template_node_child: true
|
||||
}
|
||||
material: "/builtins/materials/gui.material"
|
||||
adjust_reference: ADJUST_REFERENCE_PARENT
|
25
example/examples/using_widgets/using_widgets.gui_script
Normal file
25
example/examples/using_widgets/using_widgets.gui_script
Normal file
@ -0,0 +1,25 @@
|
||||
local druid = require("druid.druid")
|
||||
|
||||
local memory_panel = require("druid.widget.memory_panel.memory_panel")
|
||||
|
||||
function init(self)
|
||||
self.druid = druid.new(self)
|
||||
|
||||
self.memory_panel = self.druid:new_widget(memory_panel, "memory_panel")
|
||||
end
|
||||
|
||||
function final(self)
|
||||
self.druid:final()
|
||||
end
|
||||
|
||||
function update(self, dt)
|
||||
self.druid:update(dt)
|
||||
end
|
||||
|
||||
function on_message(self, message_id, message, sender)
|
||||
self.druid:on_message(message_id, message, sender)
|
||||
end
|
||||
|
||||
function on_input(self, action_id, action)
|
||||
return self.druid:on_input(action_id, action)
|
||||
end
|
@ -212,6 +212,12 @@
|
||||
"ui_example_panthera_animation_blend_description": "Here is a example of Panthera Animation Blend.",
|
||||
"ui_example_panthera_animation_blend_hint": "Hover mouse over this area",
|
||||
|
||||
"ui_example_container_anchors": "Container: Anchors",
|
||||
"ui_example_container_anchors_description": "Here is a example of container anchors.",
|
||||
|
||||
"ui_example_container_resize": "Container: Resize",
|
||||
"ui_example_container_resize_description": "Here is a example of container resize.",
|
||||
|
||||
"ui_animation_vertical": "Vertical",
|
||||
"ui_animation_horizontal": "Horizontal",
|
||||
|
||||
|
@ -583,96 +583,116 @@ Hello there, Druid users!
|
||||
|
||||
The wait is over - **Druid 1.1** has arrived! This update brings substantial improvements and exciting new features that make building UI in Defold easier and more powerful than ever.
|
||||
|
||||
By the way, the PR number of this release is #300. Sounds veeery huge and long journey for me!
|
||||
By the way, the PR number of this release is #300. It's sounds ve-eery huge and the long journey for me!
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Widgets** are here! This is the evolution of custom components, but with no boilerplate code and far more convenient usage. All Druid examples have been migrated to use widgets. Widgets are now a default way to create a new custom components (basically any of your GUI element on the screen).
|
||||
- **Widgets** are here! This is the evolution of custom components, but Widgets with totally no boilerplate code and far more convenient usage. All Druid examples have been migrated to use widgets. Widgets are now a default way to create a new user custom components.
|
||||
|
||||
The widget code is simple as:
|
||||
```lua
|
||||
---@class my_widget: druid.widget
|
||||
local M = {}
|
||||
|
||||
function M:init()
|
||||
-- Druid is available now
|
||||
self.button = self.druid:new_button("button")
|
||||
end
|
||||
|
||||
return M
|
||||
```
|
||||
|
||||
To instantiate a widget, you need to call
|
||||
```lua
|
||||
local my_widget = require("widgets.my_widget.my_widget")
|
||||
self.widget = self.druid:new_widget(my_widget, "widget_template_id")
|
||||
```
|
||||
|
||||
To create a widget with a even more fast way, now you always can right click on GUI file and select `Create Druid Widget` to create a widget file for current GUI file nearby.
|
||||
|
||||
- **No more calling `druid.register()`!** All Druid components are now available by default with `self.druid:new_*` functions, making getting started simpler than ever.
|
||||
|
||||
- **Druid UI Kit** brings fonts, atlas, and ready-to-use GUI templates right out of the box - a long-requested feature that lets you use Druid UI elements instantly in your projects. I think now it's a possible to create a external dependencies with a set of GUI templates and Druid's widgets to make a ready to use UI kit for projects! The flow to init widgets always now from two steps:
|
||||
- **Druid UI Kit** brings fonts, atlas, and ready-to-use GUI templates right out of the box - a long-requested feature that lets you use Druid UI elements instantly in your projects. I think now it's a possible to create even a external dependencies with a set of GUI templates and Druid's widgets to make a ready to use UI kit for projects! The flow to init widgets always now from two steps:
|
||||
- Add GUI template to your GUI scene
|
||||
- Call `self.widget = self.druid:new_widget(widget_file, "template_id")` to init widget
|
||||
- Call `self.widget = self.druid:new_widget(widget_file, "template_id", "tempalate_id/root")` to clone root node from template and init widget from it
|
||||
- or Call `self.widget = self.druid:new_widget(widget_file, "template_id", "tempalate_id/root")` to clone root node from template and init widget from it
|
||||
|
||||
|
||||
- **Completely reworked documentation** with full code annotations. Start with the [Quick API Reference](/api/quick_api_reference.md) to get familiar with **Druid**. Any documentation are generated from the code annotations, so in case to update documentation, you need to update annotations in the code.
|
||||
- **Completely reworked documentation** with full code annotations. Let's check the new brand [Quick API Reference](/api/quick_api_reference.md) to get familiar with **Druid**. Any documentation are generated from the code annotations, so in case to update documentation, you need to update annotations in the code directly.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- `druid.event` has been replaced with the [defold-event](https://github.com/Insality/defold-event) library, requiring a small migration in your code if you were using events directly. Double dependencies are now required to use Druid.
|
||||
|
||||
## Improved Workflow
|
||||
|
||||
The editor scripts have been updated too. Now they use pure **Lua** instead of **Python**, meaning there's no additional setup required to start using them! This is a "Create Druid Widget" and "Assign Layers" editor scripts at the moment.
|
||||
- `druid.event` has been replaced with the [defold-event](https://github.com/Insality/defold-event) library, requiring a small migration in your code if you were using Druid events directly before. Double dependencies: `defold-event` and `druid` are now required to use **Druid**.
|
||||
|
||||
---
|
||||
|
||||
This release represents a major step forward in making Druid more maintainable, readable, and powerful. Check out the full changelog for all the details! The [contributing guide](/CONTRIBUTING) is created for people who want to contribute to the Druid.
|
||||
This release represents a major step forward in making Druid more maintainable, readable, and powerful. Check out the full changelog for all the details!
|
||||
|
||||
The [contributing guide](CONTRIBUTING.md) is created for people who want to contribute to the Druid.
|
||||
|
||||
Thank you for using Druid and please share your feedback!
|
||||
|
||||
|
||||
---
|
||||
|
||||
**Milestone**:
|
||||
|
||||
**Changelog 1.1.0**
|
||||
- [Docs] Reworked all documentation pages
|
||||
- **[Docs]** Reworked all documentation pages
|
||||
- The code now is fully annotated
|
||||
- The old API website is removed
|
||||
- The API now placed as a markdown files in the `api` folder
|
||||
- The API now placed as a markdown files in the `api` folder of the repository
|
||||
- Start with [Quick API Reference](/api/quick_api_reference.md) to learn how to use Druid
|
||||
- [BREAKING] Remove `druid.event`, replaced with `defold-event` library. Now it required to two dependencies to use Druid.
|
||||
- **[BREAKING]** Remove `druid.event`, replaced with `defold-event` library. Now it required to two dependencies to use Druid.
|
||||
- This allow to make more flexible features, like shaders and sync init functions between script and gui_script in various cases.
|
||||
- You need to migrate from `require("druid.event")` to `require("event.event")` if you are using it in your project
|
||||
- If you are used `event.is_exist()` now, you should use `#event > 0` or `not event:is_empty()` instead
|
||||
- Use 11+ version of `defold-event` library: `https://github.com/Insality/defold-event/archive/refs/tags/11.zip`
|
||||
- Read [defold-event](https://github.com/Insality/defold-event) to learn more about the library
|
||||
- [UI Kit] Add Druid UI Kit, contains `druid.atlas`, `druid_text_bold.font`, `druid_text_regular.font` so now you can use Druid GUI files in your projects.
|
||||
- **[UI Kit]** Add Druid UI Kit, contains `druid.atlas`, `druid_text_bold.font`, `druid_text_regular.font` so now you can use Druid GUI files in your projects.
|
||||
- Contains mostly basic shapes for the UI and can contains several icons. Atlas is a small, only `128x128` size and will be included in build only if you use it. Probably will grow a little bit in future.
|
||||
- A long waited feature which allows try or just use some **Druid** GUI features almost instantly.
|
||||
- No more "rich_input" template is not working! Should be good for now.
|
||||
- Now GUI files from **Druid** can be added inside your project.
|
||||
- This allow to include `Default Widgets` - ready to use GUI templates
|
||||
- [Widgets] Widgets here!
|
||||
- Two fonts will keep in the UI Kit: `druid_text_bold.font` and `druid_text_regular.font`. They each of them `~100KB`, already contains extended characters set, with font size of `40`.
|
||||
- **[Widgets]** **Widgets here!**
|
||||
- A replacement for Druid's `custom_components`. Basically it's the same, but `widgets` contains no boilerplate code and more convinient to use.
|
||||
- Now I can include a kind of `widgets` with Druid and you can use it almost instantly in your project.
|
||||
- All Druid Examples was migrated to use Widgets instead of Custom Components.
|
||||
- [Widgets] Widgets can be used in GO `script` files. It's a kind of experimental feature, but looks fun to check.
|
||||
- **[Widgets]** Widgets can be used in GO `script` files.
|
||||
- It's a kind of experimental feature, but looks fun to check.
|
||||
- Added the `druid_widget.gui_script` which can register a Druid instance for this GUI scene.
|
||||
- You can use `druid.get_widget(class, url)` to get a Druid instance in GO context.
|
||||
- All top level functions from widget are available in GO context.
|
||||
- It uses an `defold-event` library, so wrapping have a costs.
|
||||
- [System] 🎉 No need for the `druid.register()`! Now all Druid's components are available by default and available with `self.druid:new_*` functions
|
||||
- **[System]** 🎉 No need for the `druid.register()`! Now all Druid's components are available by default and available with `self.druid:new_*` functions
|
||||
- This means the Druid will be bigger in size, but it's much comfortable to use
|
||||
- In case you want to delete components you are not using, you can do it in fork in `druid.lua` file
|
||||
- Read [optimize_druid_size.md](optimize_druid_size.md) to learn how to reduce the size of the Druid library if you need
|
||||
- Read [optimize_druid_size.md](optimize_druid_size.md) to learn how to reduce the size of the Druid library if you interested
|
||||
- Any additional new widgets, utilities files will be not included until you use it
|
||||
- You still can register your custom components to make a aliases for them. Widgets are not supported here.
|
||||
- [BREAKING] Removed old `druid.no_stencil_check` and `druid.no_auto_template` flags. Now it's always disabled
|
||||
- [System]: Huge code refactoring and improvements. The goal is to raise maintainability and readability of the code to help people to contribute to the Druid.
|
||||
- Add [CONTRIBUTING](/CONTRIBUTING) file with various information to help people to contribute to the Druid.
|
||||
- [Editor Scripts]: Updated editor scripts
|
||||
- Add "[Druid] Create Druid Widget" instead of "Create Custom Component"
|
||||
- The "[Druid] Assign Layers" now works purely in lua (before it was a python)
|
||||
- Add the "[Druid] Settings" with a widget template settings and links to documentation
|
||||
- [Text]: Add `trim_left` and `scale_then_trim_left` text adjust modes
|
||||
- [Text]: Add `set_text` function instead `set_to` (the `set_to` now deprecated)
|
||||
- [Widget] Add widget `mini_graph`
|
||||
- [Widget] Add widget `memory_panel` (works over `mini_graph` widget)
|
||||
- [Widget] Add widget `fps_panel` (works over `mini_graph` widget)
|
||||
- [Widget] Add widget `properties_panel`
|
||||
- [Unit Tests] Updated Unit tests
|
||||
- **[BREAKING]** Removed old `druid.no_stencil_check` and `druid.no_auto_template` flags. Now it's always disabled
|
||||
- **[System]** Huge code refactoring and improvements. The goal is to raise maintainability and readability of the code to help people to contribute.
|
||||
- **[Docs]** Add [CONTRIBUTING.md](/CONTRIBUTING.md) file with various information to help people to contribute to the Druid.
|
||||
- **[Editor Scripts]** Updated editor scripts
|
||||
- **[Editor Scripts]** Add "[Druid] Create Druid Widget" instead of "Create Custom Component"
|
||||
- **[Editor Scripts]** Add "[Druid] Settings" editor dialog
|
||||
- Contains different documentation links
|
||||
- You can adjust the widget template path to use your own templates in "Create Druid Widget" editor script
|
||||
- **[Text]** Add `trim_left` and `scale_then_trim_left` text adjust modes
|
||||
- **[Text]** Add `set_text` function instead `set_to` (the `set_to` now deprecated)
|
||||
- **[Widget]** Add widget `mini_graph`
|
||||
- **[Widget]** Add widget `memory_panel` (works over `mini_graph` widget)
|
||||
- **[Widget]** Add widget `fps_panel` (works over `mini_graph` widget)
|
||||
- **[Widget]** Add widget `properties_panel`
|
||||
- **[Unit Tests]** Updated Unit tests
|
||||
- Now it's cover more cases and more code, which is great!
|
||||
|
||||
|
||||
A big thanks to the my Github supporters:
|
||||
- [Defold Foundation](https://defold.com)
|
||||
- [Pawel](https://forum.defold.com/u/pawel/summary)
|
||||
- [Pawel](https://forum.defold.com/u/pawel)
|
||||
- [Ragetto](https://forum.defold.com/u/ragetto)
|
||||
- [Ekharkunov](https://forum.defold.com/u/ekharkunov/summary)
|
||||
- [Ekharkunov](https://forum.defold.com/u/ekharkunov)
|
||||
|
||||
And all my other supporters! Very appreciated!
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user