diff --git a/druid/druid.script b/druid/druid.script deleted file mode 100644 index 209ba74..0000000 --- a/druid/druid.script +++ /dev/null @@ -1,37 +0,0 @@ --- Place this script nearby with the gui component to able make requests --- To the go namespace from GUI with events systems (cross context) - -local event_queue = require("druid.event_queue") - ----Usage: event_queue.request("druid.get_atlas_path", callback, gui.get_texture(self.node), msg.url()) ----Pass texture name to get atlas info and sender url to check if the request is valid -local MESSAGE_GET_ATLAS_PATH = "druid.get_atlas_path" - - ----@param texture_name hash The name from gui.get_texture(node) ----@param sender hash Just msg.url from the caller -local function get_atlas_path(texture_name, sender) - local my_url = msg.url() - my_url.fragment = nil - - local copy_url = msg.url(sender) - copy_url.fragment = nil - - -- This check should works well - local is_my_url = my_url == copy_url - if not is_my_url then - return nil - end - - return go.get(sender, "textures", { key = texture_name }) -end - - -function init(self) - event_queue.subscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path) -end - - -function final(self) - event_queue.unsubscribe(MESSAGE_GET_ATLAS_PATH, get_atlas_path) -end \ No newline at end of file diff --git a/druid/event_queue.lua b/druid/event_queue.lua deleted file mode 100644 index cdeb7c2..0000000 --- a/druid/event_queue.lua +++ /dev/null @@ -1,84 +0,0 @@ -local event = require("event.event") - ----@class event.queue -local M = {} - -local event_handlers = {} -local pending_callbacks = {} - - ----Request to handle a specified event and processes the queue of callbacks associated with it. ----If event has already been triggered, the callback will be executed immediately. ----If event not triggered yet, callback will be executed when event will be triggered. ----It triggered only once and then removed from the queue. ----@param event_name string The name of the event to trigger. ----@param callback fun() The callback function to execute upon triggering. ----@param ... any Additional arguments for the callback. -function M.request(event_name, callback, ...) - pending_callbacks[event_name] = pending_callbacks[event_name] or {} - table.insert(pending_callbacks[event_name], { event.create(callback), ... }) - - M.process_pending_callbacks(event_name) -end - - ----Subscribes to a specified event and executes a callback when the event is triggered. --- If the event has already been triggered, the callback will be executed immediately. ----@param event_name string The name of the event to subscribe to. ----@param callback fun() The function to call when the event is triggered. -function M.subscribe(event_name, callback) - event_handlers[event_name] = event_handlers[event_name] or event.create() - - if event_handlers[event_name] then - event_handlers[event_name]:subscribe(callback) - end - - M.process_pending_callbacks(event_name) -end - - ----Unsubscribes a callback function from a specified event. ----@param event_name string The name of the event to unsubscribe from. ----@param callback fun() The function to remove from the event's subscription list. -function M.unsubscribe(event_name, callback) - if event_handlers[event_name] then - event_handlers[event_name]:unsubscribe(callback) - end -end - - ----Processes the queue for a given event name, executing callbacks and handling results. ----Processed callbacks are removed from the queue. ----@param event_name string The name of the event for which to process the queue. -function M.process_pending_callbacks(event_name) - local callbacks_to_process = pending_callbacks[event_name] - local event_handler = event_handlers[event_name] - - if not callbacks_to_process or not event_handler then - return - end - - -- Loop through the queue in reverse to prevent index errors during removal - for i = #callbacks_to_process, 1, -1 do - local callback_entry = callbacks_to_process[i] - -- Better to figure out how to make it without 2 unpacks, but ok for all our cases now - local args = { unpack(callback_entry, 2) } - - -- Safely call the event handler and handle errors - local success, result = pcall(event_handler.trigger, event_handler, unpack(args)) - - if success and result then - local callback_function = callback_entry[1] - pcall(callback_function, result) -- Safely invoke the callback, catching any errors - table.remove(callbacks_to_process, i) -- Remove the processed callback from the queue - end - end - - -- Clean up if the callback queue is empty - if #callbacks_to_process == 0 then - pending_callbacks[event_name] = nil - end -end - - -return M diff --git a/druid/materials/gui_repeat/gui_repeat.fp b/druid/materials/gui_repeat/gui_repeat.fp deleted file mode 100644 index fb355aa..0000000 --- a/druid/materials/gui_repeat/gui_repeat.fp +++ /dev/null @@ -1,84 +0,0 @@ -#version 140 - -uniform sampler2D texture_sampler; - -in vec2 var_texcoord0; -in vec4 var_color; -in vec4 var_uv; -in vec4 var_repeat; // [repeat_x, repeat_y, anchor_x, anchor_y] -in vec4 var_params; // [margin_x, margin_y, offset_x, offset_y] -in vec4 var_perspective; -in vec4 var_uv_rotated; - -out vec4 color_out; - -void main() { - vec2 pivot = var_repeat.zw; - // Margin is a value between 0 and 1 that means offset/padding from the one image to another - vec2 margin = var_params.xy; - vec2 offset = var_params.zw; - vec2 repeat = var_repeat.xy; - - // Atlas UV to local UV [0, 1] - float u = (var_texcoord0.x - var_uv.x) / (var_uv.z - var_uv.x); - float v = (var_texcoord0.y - var_uv.y) / (var_uv.w - var_uv.y); - - // Adjust local UV by the pivot point. So 0:0 will be at the pivot point of node - u = u - (0.5 + pivot.x); - v = v - (0.5 - pivot.y); - - // If rotated, swap UV - if (var_uv_rotated.y < 0.5) { - float temp = u; - u = v; - v = temp; - } - - // Adjust repeat by the margin - repeat.x = repeat.x / (1.0 + margin.x); - repeat.y = repeat.y / (1.0 + margin.y); - - // Repeat is a value between 0 and 1 that represents the number of times the texture is repeated in the atlas. - float tile_u = fract(u * repeat.x); - float tile_v = fract(v * repeat.y); - - float tile_width = 1.0 / repeat.x; - float tile_height = 1.0 / repeat.y; - - // Adjust tile UV by the pivot point. - // Not center is left top corner, need to adjust it to pivot point - tile_u = fract(tile_u + pivot.x + 0.5); - tile_v = fract(tile_v - pivot.y + 0.5); - - // Apply offset - tile_u = fract(tile_u + offset.x); - tile_v = fract(tile_v + offset.y); - - // Extend margins - margin = margin * 0.5; - tile_u = mix(0.0 - margin.x, 1.0 + margin.x, tile_u); - tile_v = mix(0.0 - margin.y, 1.0 + margin.y, tile_v); - float alpha = 0.0; - // If the tile is outside the margins, make it transparent, without IF - alpha = step(0.0, tile_u) * step(tile_u, 1.0) * step(0.0, tile_v) * step(tile_v, 1.0); - - tile_u = clamp(tile_u, 0.0, 1.0); // Keep borders in the range 0-1 - tile_v = clamp(tile_v, 0.0, 1.0); // Keep borders in the range 0-1 - - if (var_uv_rotated.y < 0.5) { - float temp = tile_u; - tile_u = tile_v; - tile_v = temp; - } - - // Remap local UV to the atlas UV - vec2 uv = vec2( - mix(var_uv.x, var_uv.z, tile_u), // Get texture coordinate from the atlas - mix(var_uv.y, var_uv.w, tile_v) // Get texture coordinate from the atlas - //mix(var_uv.x, var_uv.z, tile_u * var_uv_rotated.x + tile_v * var_uv_rotated.z), - //mix(var_uv.y, var_uv.w, 1.0 - (tile_u * var_uv_rotated.y + tile_v * var_uv_rotated.x)) - ); - - lowp vec4 tex = texture(texture_sampler, uv); - color_out = tex * var_color; -} \ No newline at end of file diff --git a/druid/materials/gui_repeat/gui_repeat.material b/druid/materials/gui_repeat/gui_repeat.material deleted file mode 100644 index 213467e..0000000 --- a/druid/materials/gui_repeat/gui_repeat.material +++ /dev/null @@ -1,43 +0,0 @@ -name: "repeat" -tags: "gui" -vertex_program: "/druid/materials/gui_repeat/gui_repeat.vp" -fragment_program: "/druid/materials/gui_repeat/gui_repeat.fp" -vertex_constants { - name: "view_proj" - type: CONSTANT_TYPE_VIEWPROJ -} -vertex_constants { - name: "uv_coord" - type: CONSTANT_TYPE_USER - value { - z: 1.0 - w: 1.0 - } -} -vertex_constants { - name: "uv_repeat" - type: CONSTANT_TYPE_USER - value { - x: 1.0 - y: 1.0 - } -} -vertex_constants { - name: "params" - type: CONSTANT_TYPE_USER - value { - } -} -vertex_constants { - name: "perspective" - type: CONSTANT_TYPE_USER - value { - } -} -vertex_constants { - name: "uv_rotated" - type: CONSTANT_TYPE_USER - value { - x: 1.0 - } -} diff --git a/druid/materials/gui_repeat/gui_repeat.vp b/druid/materials/gui_repeat/gui_repeat.vp deleted file mode 100644 index 12c1460..0000000 --- a/druid/materials/gui_repeat/gui_repeat.vp +++ /dev/null @@ -1,50 +0,0 @@ -#version 140 - -in mediump vec3 position; -in mediump vec2 texcoord0; -in lowp vec4 color; - -uniform vertex_inputs -{ - highp mat4 view_proj; - highp vec4 uv_coord; - highp vec4 uv_repeat; // [repeat_x, repeat_y, pivot_x, pivot_y] - vec4 uv_rotated; - vec4 params; // [margin_x, margin_y, offset_x, offset_y] - vec4 perspective; // [perspective_x, perspective_y, zoom, offset_y] -}; - -out mediump vec2 var_texcoord0; -out lowp vec4 var_color; -out highp vec4 var_uv; -out highp vec4 var_repeat; -out vec4 var_params; -out vec4 var_perspective; -out vec4 var_uv_rotated; - -void main() -{ - var_texcoord0 = texcoord0; - var_color = vec4(color.rgb * color.a, color.a); - var_uv = uv_coord; - var_repeat = uv_repeat; - var_params = params; - var_perspective = perspective; - var_uv_rotated = uv_rotated; - - mat4 transform = mat4( - 1.0, 0, 0, 0.0, - 0, 1.0, 0, 0.0, - 0, 0, 1, 0, - 0.0, position.z, 0, 1.0 - ); - - // Matrix Info = mat4( - // scale_x, skew_x, 0, offset_x, - // skew_y, scale_y, 0, offset_y, - // 0, 0, scale_z, offset_z, - // perspective_x, perspective_y, perspective_z, zoom - //) - - gl_Position = view_proj * vec4(position.xyz, 1.0) * transform; -} diff --git a/druid/materials/gui_world/gui_world.fp b/druid/materials/gui_world/gui_world.fp deleted file mode 100644 index e0ac809..0000000 --- a/druid/materials/gui_world/gui_world.fp +++ /dev/null @@ -1,13 +0,0 @@ -#version 140 - -in mediump vec2 var_texcoord0; -in mediump vec4 var_color; - -out vec4 out_fragColor; - -uniform mediump sampler2D texture_sampler; - -void main() -{ - out_fragColor = texture(texture_sampler, var_texcoord0.xy) * var_color; -} diff --git a/druid/materials/gui_world/gui_world.material b/druid/materials/gui_world/gui_world.material index f609d2e..62671ac 100644 --- a/druid/materials/gui_world/gui_world.material +++ b/druid/materials/gui_world/gui_world.material @@ -1,7 +1,7 @@ name: "gui_world" tags: "tile" -vertex_program: "/druid/materials/gui_world/gui_world.vp" -fragment_program: "/druid/materials/gui_world/gui_world.fp" +vertex_program: "/builtins/materials/gui.vp" +fragment_program: "/builtins/materials/gui.fp" vertex_constants { name: "view_proj" type: CONSTANT_TYPE_VIEWPROJ diff --git a/druid/materials/gui_world/gui_world.vp b/druid/materials/gui_world/gui_world.vp deleted file mode 100644 index 9e2b190..0000000 --- a/druid/materials/gui_world/gui_world.vp +++ /dev/null @@ -1,20 +0,0 @@ -#version 140 - -in mediump vec3 position; -in mediump vec2 texcoord0; -in mediump vec4 color; - -out mediump vec2 var_texcoord0; -out mediump vec4 var_color; - -uniform vs_uniforms -{ - mediump mat4 view_proj; -}; - -void main() -{ - var_texcoord0 = texcoord0; - var_color = vec4(color.rgb * color.a, color.a); - gl_Position = view_proj * vec4(position.xyz, 1.0); -} diff --git a/druid/materials/skew/gui_skew.fp b/druid/materials/skew/gui_skew.fp deleted file mode 100644 index c3d593d..0000000 --- a/druid/materials/skew/gui_skew.fp +++ /dev/null @@ -1,18 +0,0 @@ -#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; -} \ No newline at end of file diff --git a/druid/materials/skew/gui_skew.material b/druid/materials/skew/gui_skew.material deleted file mode 100644 index 5575ae1..0000000 --- a/druid/materials/skew/gui_skew.material +++ /dev/null @@ -1,8 +0,0 @@ -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 -} diff --git a/druid/materials/skew/gui_skew.vp b/druid/materials/skew/gui_skew.vp deleted file mode 100644 index 382c88b..0000000 --- a/druid/materials/skew/gui_skew.vp +++ /dev/null @@ -1,20 +0,0 @@ -#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); -} diff --git a/druid/materials/stencil/gui_stencil.fp b/druid/materials/stencil/gui_stencil.fp index c3d593d..cc58610 100644 --- a/druid/materials/stencil/gui_stencil.fp +++ b/druid/materials/stencil/gui_stencil.fp @@ -9,10 +9,10 @@ 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; -} \ No newline at end of file +} diff --git a/druid/materials/stencil/gui_stencil.material b/druid/materials/stencil/gui_stencil.material index 5575ae1..e994c21 100644 --- a/druid/materials/stencil/gui_stencil.material +++ b/druid/materials/stencil/gui_stencil.material @@ -1,6 +1,6 @@ name: "repeat" tags: "gui" -vertex_program: "/druid/materials/stencil/gui_stencil.vp" +vertex_program: "/builtins/materials/gui.vp" fragment_program: "/druid/materials/stencil/gui_stencil.fp" vertex_constants { name: "view_proj" diff --git a/druid/materials/stencil/gui_stencil.vp b/druid/materials/stencil/gui_stencil.vp deleted file mode 100644 index 382c88b..0000000 --- a/druid/materials/stencil/gui_stencil.vp +++ /dev/null @@ -1,20 +0,0 @@ -#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); -} diff --git a/druid/widget/node_repeat/node_repeat.lua b/druid/widget/node_repeat/node_repeat.lua deleted file mode 100644 index 74044b7..0000000 --- a/druid/widget/node_repeat/node_repeat.lua +++ /dev/null @@ -1,194 +0,0 @@ -local helper = require("druid.helper") -local event_queue = require("druid.event_queue") - ----@class druid.node_repeat: druid.widget ----@field animation table ----@field node node ----@field params vector4 ----@field time number -local M = {} - -M.PROP_SIZE_X = hash("size.x") -M.PROP_SIZE_Y = hash("size.y") -M.PROP_SCALE_X = hash("scale.x") -M.PROP_SCALE_Y = hash("scale.y") - -function M:init(node) - self.node = self:get_node(node) - self.animation = nil - gui.set_material(self.node, hash("gui_repeat")) - self.time = 0 - self.margin = 0 - - self.params = gui.get(self.node, "params") --[[@as vector4]] - self:get_atlas_path(function(atlas_path) - self.is_inited = self:init_tiling_animation(atlas_path) - local repeat_x, repeat_y = self:get_repeat() - self:animate(repeat_x, repeat_y) - end) - - --self.druid.events.on_node_property_changed:subscribe(self.on_node_property_changed, self) -end - - -function M:on_node_property_changed(node, property) - if not self.is_inited or node ~= self.node then - return - end - - if property == "size" or property == "scale" then - local repeat_x, repeat_y = self:get_repeat() - self:set_repeat(repeat_x, repeat_y) - end -end - - -function M:get_repeat() - if not self.is_inited then - return 1, 1 - end - local size_x = gui.get(self.node, M.PROP_SIZE_X) - local size_y = gui.get(self.node, M.PROP_SIZE_Y) - local scale_x = gui.get(self.node, M.PROP_SCALE_X) - local scale_y = gui.get(self.node, M.PROP_SCALE_Y) - - local repeat_x = (size_x / self.animation.width) / scale_x - local repeat_y = (size_y / self.animation.height) / scale_y - - return repeat_x, repeat_y -end - - -function M:get_atlas_path(callback) - event_queue.request("druid.get_atlas_path", callback, gui.get_texture(self.node), msg.url()) -end - - ----@return boolean -function M:init_tiling_animation(atlas_path) - if not atlas_path then - print("No atlas path found for node", gui.get_id(self.node), gui.get_texture(self.node)) - print("Probably you should add druid.script at window collection to access resources") - return false - end - - self.animation = helper.get_animation_data_from_node(self.node, atlas_path) - return true -end - --- Start our repeat shader work ----@param repeat_x number X factor ----@param repeat_y number Y factor -function M:animate(repeat_x, repeat_y) - if not self.is_inited then - return - end - - local node = self.node - local animation = self.animation - - local frame = animation.frames[1] - gui.set(node, "uv_coord", frame.uv_coord) - self:set_repeat(repeat_x, repeat_y) - - if #animation.frames > 1 and animation.fps > 0 then - animation.handle = - timer.delay(1/animation.fps, true, function(self, handle, time_elapsed) - local next_rame = animation.frames[animation.current_frame] - gui.set(node, "uv_coord", next_rame.uv_coord) - - animation.current_frame = animation.current_frame + 1 - if animation.current_frame > #animation.frames then - animation.current_frame = 1 - end - end) - end -end - - -function M:final() - local animation = self.animation - if animation.handle then - timer.cancel(animation.handle) - animation.handle = nil - end -end - - ----Update repeat factor values ----@param repeat_x number X factor ----@param repeat_y number Y factor -function M:set_repeat(repeat_x, repeat_y) - local animation = self.animation - animation.v.x = repeat_x or animation.v.x - animation.v.y = repeat_y or animation.v.y - - local anchor = helper.get_pivot_offset(gui.get_pivot(self.node)) - animation.v.z = anchor.x - animation.v.w = anchor.y - - gui.set(self.node, "uv_repeat", animation.v) -end - - -function M:set_perpective(perspective_x, perspective_y) - if perspective_x then - gui.set(self.node, "perspective.x", perspective_x) - end - - if perspective_y then - gui.set(self.node, "perspective.y", perspective_y) - end - - return self -end - - -function M:set_perpective_offset(offset_x, offset_y) - if offset_x then - gui.set(self.node, "perspective.z", offset_x) - end - - if offset_y then - gui.set(self.node, "perspective.w", offset_y) - end - - return self -end - - -function M:set_offset(offset_perc_x, offset_perc_y) - self.params.z = offset_perc_x or self.params.z - self.params.w = offset_perc_y or self.params.w - gui.set(self.node, "params", self.params) - return self -end - - -function M:set_margin(margin_x, margin_y) - self.params.x = margin_x or self.params.x - self.params.y = margin_y or self.params.y - gui.set(self.node, "params", self.params) - return self -end - - ----@param scale number -function M:set_scale(scale) - local current_scale_x = gui.get(self.node, M.PROP_SCALE_X) - local current_scale_y = gui.get(self.node, M.PROP_SCALE_Y) - local current_size_x = gui.get(self.node, M.PROP_SIZE_X) - local current_size_y = gui.get(self.node, M.PROP_SIZE_Y) - - local delta_scale_x = scale / current_scale_x - local delta_scale_y = scale / current_scale_y - gui.set(self.node, M.PROP_SCALE_X, scale) - gui.set(self.node, M.PROP_SCALE_Y, scale) - gui.set(self.node, M.PROP_SIZE_X, current_size_x / delta_scale_x) - gui.set(self.node, M.PROP_SIZE_Y, current_size_y / delta_scale_y) - - return self -end - - -return M diff --git a/example/druid.gui b/example/druid.gui index 1538aa4..48394a3 100644 --- a/example/druid.gui +++ b/example/druid.gui @@ -4713,9 +4713,6 @@ nodes { template_node_child: true } nodes { - position { - x: -200.0 - } type: TYPE_TEMPLATE id: "property_input" parent: "widgets" diff --git a/example/locales/en.json b/example/locales/en.json index dcf64ea..c5ecbd5 100644 --- a/example/locales/en.json +++ b/example/locales/en.json @@ -23,6 +23,7 @@ "ui_type_next": "Next Type", "ui_adjust_next": "Next Adjust", "ui_enabled": "Enabled", + "ui_item_size": "Item Size", "ui_examples_basic": "Basic", "ui_examples_data_list": "Data List", @@ -183,9 +184,15 @@ "ui_example_widget_fps_panel": "FPS Panel", "ui_example_widget_fps_panel_description": "Here is a example of FPS panel usage", + "ui_example_widget_mini_graph": "Mini Graph", + "ui_example_widget_mini_graph_description": "Here is a example of mini graph usage", + "ui_example_widget_properties_panel": "Properties Panel", "ui_example_widget_properties_panel_description": "Here is a example of properties panel usage", + "ui_example_widget_property_input": "Property Input", + "ui_example_widget_property_input_description": "Here is a example of property input usage", + "ui_example_gamepad_tester": "Gamepad Tester", "ui_example_gamepad_tester_description": "Test your gamepad here to bind buttons and axes", @@ -215,4 +222,4 @@ "ui_language_it": "Italiano", "ui_language_kr": "한국어", "ui_language_zh": "中文" -} \ No newline at end of file +}