From d1d54896fb4f7af853d16a43aa0ea2486c951d53 Mon Sep 17 00:00:00 2001 From: Insality Date: Wed, 16 Apr 2025 01:01:00 +0300 Subject: [PATCH] Update Docs --- druid/base/text.lua | 6 +- druid/custom/rich_input/rich_input.lua | 17 ++- .../gui_world/druid_gui_world_text_bold.font | 10 ++ .../druid_gui_world_text_regular.font | 8 ++ .../gui_world/gui-world-font-df.material | 8 ++ .../fonts/gui_world/gui-world-font-df.vp | 34 ++++++ example/examples/basic/input/rich_input.gui | 12 ++ .../go_widgets/go_bindings_panthera.lua | 107 +++++++++++++++++ .../widgets/go_widgets/go_widget.collection | 97 ++++++++++++++++ .../examples/widgets/go_widgets/go_widget.gui | 108 ++++++++++++++++++ .../examples/widgets/go_widgets/go_widget.lua | 35 ++++++ .../widgets/go_widgets/go_widget.script | 27 +++++ .../widgets/go_widgets/go_widget_panthera.lua | 66 +++++++++++ 13 files changed, 530 insertions(+), 5 deletions(-) create mode 100644 example/assets/fonts/gui_world/druid_gui_world_text_bold.font create mode 100644 example/assets/fonts/gui_world/druid_gui_world_text_regular.font create mode 100644 example/assets/fonts/gui_world/gui-world-font-df.material create mode 100644 example/assets/fonts/gui_world/gui-world-font-df.vp create mode 100644 example/examples/widgets/go_widgets/go_bindings_panthera.lua create mode 100644 example/examples/widgets/go_widgets/go_widget.collection create mode 100644 example/examples/widgets/go_widgets/go_widget.gui create mode 100644 example/examples/widgets/go_widgets/go_widget.lua create mode 100644 example/examples/widgets/go_widgets/go_widget.script create mode 100644 example/examples/widgets/go_widgets/go_widget_panthera.lua diff --git a/druid/base/text.lua b/druid/base/text.lua index f84423f..6b415de 100755 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -37,9 +37,9 @@ local utf8 = utf8 or utf8_lua --[[@as utf8]] ---@field on_update_text_scale event fun(self, scale, metrics) The event triggered when the text scale is updated ---@field on_set_pivot event fun(self, pivot) The event triggered when the text pivot is set ---@field style druid.text.style The style of the text ----@field private start_pivot userdata The start pivot of the text ----@field private start_scale vector3 The start scale of the text ----@field private scale vector3 The current scale of the text +---@field start_pivot userdata The start pivot of the text +---@field start_scale vector3 The start scale of the text +---@field scale vector3 The current scale of the text local M = component.create("text") diff --git a/druid/custom/rich_input/rich_input.lua b/druid/custom/rich_input/rich_input.lua index 8ee70b6..b6ada58 100644 --- a/druid/custom/rich_input/rich_input.lua +++ b/druid/custom/rich_input/rich_input.lua @@ -34,8 +34,21 @@ local function set_selection_width(self, selection_width) end +---@param self druid.rich_input local function update_text(self) - local left_text_part = utf8.sub(self.input:get_text(), 0, self.input.cursor_index) + local full_text = self.input:get_text() + local visible_text = self.input.text:get_text() + + local is_truncated = visible_text ~= full_text + local cursor_index = self.input.cursor_index + if is_truncated then + -- If text is truncated, we need to adjust the cursor index + -- to the last visible character + cursor_index = utf8.len(visible_text) + + end + + local left_text_part = utf8.sub(self.input:get_text(), 0, cursor_index) local selected_text_part = utf8.sub(self.input:get_text(), self.input.start_index + 1, self.input.end_index) local left_part_width = self.input.text:get_text_size(left_text_part) @@ -44,7 +57,7 @@ local function update_text(self) local pivot_text = gui.get_pivot(self.input.text.node) local pivot_offset = helper.get_pivot_offset(pivot_text) - self.cursor_position.x = self.text_position.x - self.input.total_width * (0.5 + pivot_offset.x) + left_part_width + self.cursor_position.x = self.text_position.x - self.input.text_width * (0.5 + pivot_offset.x) + left_part_width gui.set_position(self.cursor, self.cursor_position) gui.set_scale(self.cursor, self.input.text.scale) diff --git a/example/assets/fonts/gui_world/druid_gui_world_text_bold.font b/example/assets/fonts/gui_world/druid_gui_world_text_bold.font new file mode 100644 index 0000000..bac775b --- /dev/null +++ b/example/assets/fonts/gui_world/druid_gui_world_text_bold.font @@ -0,0 +1,10 @@ +font: "/druid/fonts/Roboto-Bold.ttf" +material: "/example/assets/fonts/gui_world/gui-world-font-df.material" +size: 40 +outline_alpha: 1.0 +outline_width: 2.0 +shadow_alpha: 1.0 +shadow_blur: 2 +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{|}" diff --git a/example/assets/fonts/gui_world/druid_gui_world_text_regular.font b/example/assets/fonts/gui_world/druid_gui_world_text_regular.font new file mode 100644 index 0000000..367a221 --- /dev/null +++ b/example/assets/fonts/gui_world/druid_gui_world_text_regular.font @@ -0,0 +1,8 @@ +font: "/druid/fonts/Roboto-Regular.ttf" +material: "/example/assets/fonts/gui_world/gui-world-font-df.material" +size: 40 +outline_alpha: 1.0 +outline_width: 2.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{|}" diff --git a/example/assets/fonts/gui_world/gui-world-font-df.material b/example/assets/fonts/gui_world/gui-world-font-df.material new file mode 100644 index 0000000..5996a3a --- /dev/null +++ b/example/assets/fonts/gui_world/gui-world-font-df.material @@ -0,0 +1,8 @@ +name: "font" +tags: "tile" +vertex_program: "/example/assets/fonts/gui_world/gui-world-font-df.vp" +fragment_program: "/builtins/fonts/font-df.fp" +vertex_constants { + name: "view_proj" + type: CONSTANT_TYPE_VIEWPROJ +} diff --git a/example/assets/fonts/gui_world/gui-world-font-df.vp b/example/assets/fonts/gui_world/gui-world-font-df.vp new file mode 100644 index 0000000..4cc0a99 --- /dev/null +++ b/example/assets/fonts/gui_world/gui-world-font-df.vp @@ -0,0 +1,34 @@ +#version 140 + +// positions are in world space +in highp vec4 position; +in mediump vec2 texcoord0; +in mediump vec4 sdf_params; +in mediump vec4 face_color; +in mediump vec4 outline_color; +in mediump vec4 shadow_color; +in mediump vec3 layer_mask; + +out mediump vec2 var_texcoord0; +out mediump vec4 var_face_color; +out mediump vec4 var_outline_color; +out mediump vec4 var_shadow_color; +out mediump vec4 var_sdf_params; +out mediump vec4 var_layer_mask; + +uniform vs_uniforms +{ + highp mat4 view_proj; +}; + +void main() +{ + var_texcoord0 = texcoord0; + var_face_color = vec4(face_color.xyz * face_color.w, face_color.w); + var_outline_color = vec4(outline_color.xyz * outline_color.w, outline_color.w); + var_shadow_color = vec4(shadow_color.xyz * shadow_color.w, shadow_color.w); + var_sdf_params = sdf_params; + var_layer_mask.rgb = layer_mask; + var_layer_mask.a = layer_mask.r * layer_mask.g * layer_mask.b; + gl_Position = view_proj * vec4(position.x, position.y, position.z, 1.0); +} diff --git a/example/examples/basic/input/rich_input.gui b/example/examples/basic/input/rich_input.gui index ffdf8df..02a00eb 100644 --- a/example/examples/basic/input/rich_input.gui +++ b/example/examples/basic/input/rich_input.gui @@ -78,15 +78,27 @@ nodes { template_node_child: true } nodes { + position { + x: -240.0 + } type: TYPE_TEXT id: "rich_input_2/placeholder_text" + pivot: PIVOT_W parent: "rich_input_2/button" + overridden_fields: 1 + overridden_fields: 14 template_node_child: true } nodes { + position { + x: -240.0 + } type: TYPE_TEXT id: "rich_input_2/input_text" + pivot: PIVOT_W parent: "rich_input_2/button" + overridden_fields: 1 + overridden_fields: 14 template_node_child: true } nodes { diff --git a/example/examples/widgets/go_widgets/go_bindings_panthera.lua b/example/examples/widgets/go_widgets/go_bindings_panthera.lua new file mode 100644 index 0000000..948de2e --- /dev/null +++ b/example/examples/widgets/go_widgets/go_bindings_panthera.lua @@ -0,0 +1,107 @@ +return { + data = { + animations = { + { + animation_id = "default", + animation_keys = { + { + duration = 1.305, + easing = "outsine", + end_value = 706, + key_type = "tween", + node_id = "go", + property_id = "position_x", + start_value = 960, + }, + { + duration = 3.03, + easing = "outsine", + end_value = 1.2, + key_type = "tween", + node_id = "go", + property_id = "scale_x", + start_value = 1, + }, + { + duration = 3.03, + easing = "outsine", + end_value = 1.2, + key_type = "tween", + node_id = "go", + property_id = "scale_y", + start_value = 1, + }, + { + duration = 1.689, + easing = "outsine", + end_value = 271, + key_type = "tween", + node_id = "go", + property_id = "position_y", + start_time = 1.305, + start_value = 540, + }, + { + duration = 1.665, + easing = "outsine", + end_value = 960, + key_type = "tween", + node_id = "go", + property_id = "position_x", + start_time = 2.995, + start_value = 706, + }, + { + duration = 2.97, + easing = "outsine", + end_value = 1, + key_type = "tween", + node_id = "go", + property_id = "scale_x", + start_time = 3.03, + start_value = 1.2, + }, + { + duration = 2.97, + easing = "outsine", + end_value = 1, + key_type = "tween", + node_id = "go", + property_id = "scale_y", + start_time = 3.03, + start_value = 1.2, + }, + { + duration = 1.353, + easing = "outsine", + end_value = 540, + key_type = "tween", + node_id = "go", + property_id = "position_y", + start_time = 4.647, + start_value = 271, + }, + }, + duration = 6, + }, + }, + metadata = { + fps = 60, + gizmo_steps = { + }, + gui_path = "/example/examples/widgets/go_widgets/go_widget.collection", + layers = { + }, + settings = { + font_size = 30, + }, + template_animation_paths = { + }, + }, + nodes = { + }, + }, + format = "json", + type = "animation_editor", + version = 1, +} \ No newline at end of file diff --git a/example/examples/widgets/go_widgets/go_widget.collection b/example/examples/widgets/go_widgets/go_widget.collection new file mode 100644 index 0000000..a0a9327 --- /dev/null +++ b/example/examples/widgets/go_widgets/go_widget.collection @@ -0,0 +1,97 @@ +name: "go_bindings" +scale_along_z: 0 +embedded_instances { + id: "go" + data: "components {\n" + " id: \"go_widget\"\n" + " component: \"/example/examples/widgets/go_widgets/go_widget.gui\"\n" + "}\n" + "components {\n" + " id: \"go_bindings\"\n" + " component: \"/example/examples/widgets/go_widgets/go_widget.script\"\n" + "}\n" + "components {\n" + " id: \"druid\"\n" + " component: \"/druid/druid.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"sprite\"\n" + " type: \"sprite\"\n" + " data: \"default_animation: \\\"ui_circle_64\\\"\\n" + "material: \\\"/panthera/materials/sprite.material\\\"\\n" + "attributes {\\n" + " name: \\\"color\\\"\\n" + " double_values {\\n" + " v: 0.839\\n" + " v: 0.808\\n" + " v: 0.533\\n" + " v: 1.0\\n" + " }\\n" + "}\\n" + "textures {\\n" + " sampler: \\\"texture_sampler\\\"\\n" + " texture: \\\"/druid/druid.atlas\\\"\\n" + "}\\n" + "\"\n" + " rotation {\n" + " z: 0.70710677\n" + " w: 0.70710677\n" + " }\n" + " scale {\n" + " x: 3.0\n" + " y: 3.0\n" + " }\n" + "}\n" + "embedded_components {\n" + " id: \"sprite_outline\"\n" + " type: \"sprite\"\n" + " data: \"default_animation: \\\"ui_circle_64\\\"\\n" + "material: \\\"/panthera/materials/sprite.material\\\"\\n" + "blend_mode: BLEND_MODE_MULT\\n" + "size {\\n" + " x: 64.0\\n" + " y: 64.0\\n" + "}\\n" + "attributes {\\n" + " name: \\\"color\\\"\\n" + " double_values {\\n" + " v: 0.839\\n" + " v: 0.808\\n" + " v: 0.533\\n" + " v: 1.0\\n" + " }\\n" + "}\\n" + "textures {\\n" + " sampler: \\\"texture_sampler\\\"\\n" + " texture: \\\"/druid/druid.atlas\\\"\\n" + "}\\n" + "\"\n" + " rotation {\n" + " z: 0.70710677\n" + " w: 0.70710677\n" + " }\n" + " scale {\n" + " x: 3.1\n" + " y: 3.1\n" + " }\n" + "}\n" + "" +} +embedded_instances { + id: "camera" + data: "embedded_components {\n" + " id: \"camera\"\n" + " type: \"camera\"\n" + " data: \"aspect_ratio: 1.0\\n" + "fov: 0.7854\\n" + "near_z: 0.1\\n" + "far_z: 1000.0\\n" + "orthographic_projection: 1\\n" + "orthographic_zoom: 0.4\\n" + "\"\n" + "}\n" + "" + position { + z: 10.0 + } +} diff --git a/example/examples/widgets/go_widgets/go_widget.gui b/example/examples/widgets/go_widgets/go_widget.gui new file mode 100644 index 0000000..984279e --- /dev/null +++ b/example/examples/widgets/go_widgets/go_widget.gui @@ -0,0 +1,108 @@ +script: "/druid/druid_widget.gui_script" +fonts { + name: "druid_text_bold" + font: "/example/assets/fonts/gui_world/druid_gui_world_text_bold.font" +} +textures { + name: "druid" + texture: "/druid/druid.atlas" +} +nodes { + type: TYPE_BOX + texture: "druid/empty" + id: "root" + inherit_alpha: true + size_mode: SIZE_MODE_AUTO +} +nodes { + position { + y: 150.0 + } + size { + x: 200.0 + y: 100.0 + } + type: TYPE_BOX + id: "group" + parent: "root" + inherit_alpha: true + size_mode: SIZE_MODE_AUTO + visible: false +} +nodes { + size { + x: 400.0 + y: 40.0 + } + color { + x: 0.886 + y: 0.518 + z: 0.518 + } + type: TYPE_BOX + texture: "druid/ui_circle_32" + id: "circle" + parent: "group" + inherit_alpha: true + slice9 { + x: 16.0 + y: 16.0 + z: 16.0 + w: 16.0 + } +} +nodes { + position { + x: -200.0 + } + size { + x: 400.0 + y: 40.0 + } + color { + x: 0.447 + y: 0.784 + z: 0.522 + } + type: TYPE_BOX + texture: "druid/ui_circle_32" + id: "green" + pivot: PIVOT_W + parent: "circle" + inherit_alpha: true + slice9 { + x: 16.0 + y: 16.0 + z: 16.0 + w: 16.0 + } +} +nodes { + size { + x: 400.0 + y: 40.0 + } + color { + x: 0.173 + y: 0.184 + z: 0.204 + } + type: TYPE_TEXT + text: "20" + font: "druid_text_bold" + id: "text" + parent: "group" + inherit_alpha: true + outline_alpha: 0.0 + shadow_alpha: 0.0 +} +material: "/druid/materials/gui_world/gui_world.material" +adjust_reference: ADJUST_REFERENCE_DISABLED +materials { + name: "gui_tiling_node" + material: "/druid/custom/tiling_node/gui_tiling_node.material" +} +materials { + name: "gui_stencil" + material: "/druid/materials/stencil/gui_stencil.material" +} diff --git a/example/examples/widgets/go_widgets/go_widget.lua b/example/examples/widgets/go_widgets/go_widget.lua new file mode 100644 index 0000000..3353142 --- /dev/null +++ b/example/examples/widgets/go_widgets/go_widget.lua @@ -0,0 +1,35 @@ +local panthera = require("panthera.panthera") + +local animation = require("example.examples.widgets.go_widgets.go_widget_panthera") + +---@class examples.widget.go_widget: druid.widget +local M = {} + + +function M:init() + self.root = self:get_node("root") + self.circle = self:get_node("circle") + self.animation = panthera.create_gui(animation) + self.counter = 0 + self.text_counter = self:get_node("text") + gui.set_text(self.text_counter, 0) +end + + +function M:play_animation() + panthera.play(self.animation, "default", { + is_loop = true, + callback = function() + self.counter = self.counter + 1 + gui.set_text(self.text_counter, self.counter) + end + }) +end + + +---@param position vector3 The position to set +function M:set_position(position) + gui.set_position(self.root, position) +end + +return M diff --git a/example/examples/widgets/go_widgets/go_widget.script b/example/examples/widgets/go_widgets/go_widget.script new file mode 100644 index 0000000..a65a4bd --- /dev/null +++ b/example/examples/widgets/go_widgets/go_widget.script @@ -0,0 +1,27 @@ +local panthera = require("panthera.panthera") + +local animation = require("example.examples.widgets.go_widgets.go_bindings_panthera") + +local druid = require("druid.druid") +local widget = require("example.examples.widgets.go_widgets.go_widget") + +function init(self) + local gui_url = msg.url(nil, nil, "go_widget") + self.go_widget = druid.get_widget(widget, gui_url) + self.go_widget:play_animation() + self.go_widget:set_position(go.get_position()) + + self.animation = panthera.create_go(animation) + panthera.play(self.animation, "default", { + is_loop = true, + speed = 2, + }) + + msg.post(".", "acquire_input_focus") +end + + +function update(self, dt) + self.go_widget:set_position(go.get_position()) +end + diff --git a/example/examples/widgets/go_widgets/go_widget_panthera.lua b/example/examples/widgets/go_widgets/go_widget_panthera.lua new file mode 100644 index 0000000..25ef78a --- /dev/null +++ b/example/examples/widgets/go_widgets/go_widget_panthera.lua @@ -0,0 +1,66 @@ +return { + data = { + animations = { + { + animation_id = "default", + animation_keys = { + { + duration = 0.9, + easing = "outsine", + end_value = -180, + key_type = "tween", + node_id = "text", + property_id = "position_x", + }, + { + duration = 0.95, + easing = "outsine", + end_value = 40, + key_type = "tween", + node_id = "green", + property_id = "size_x", + start_value = 400, + }, + { + duration = 0.37, + easing = "insine", + end_value = 400, + key_type = "tween", + node_id = "green", + property_id = "size_x", + start_time = 1.08, + start_value = 40, + }, + { + duration = 0.71, + easing = "outsine", + key_type = "tween", + node_id = "text", + property_id = "position_x", + start_time = 1.29, + start_value = -180, + }, + }, + duration = 2, + }, + }, + metadata = { + fps = 60, + gizmo_steps = { + }, + gui_path = "/example/examples/widgets/go_widgets/go_widget.gui", + layers = { + }, + settings = { + font_size = 30, + }, + template_animation_paths = { + }, + }, + nodes = { + }, + }, + format = "json", + type = "animation_editor", + version = 1, +} \ No newline at end of file