From 08e93c7423d7dac6118f732881ce32421f9ce937 Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 17 Apr 2020 23:27:18 +0300 Subject: [PATCH] Start implementation of input component --- druid/base/input.lua | 144 ++++++++++++++++++++++- example/gui/main/main.gui | 238 +++++++++++++++++++++++++++++++++++++- example/page/main.lua | 7 ++ 3 files changed, 384 insertions(+), 5 deletions(-) diff --git a/druid/base/input.lua b/druid/base/input.lua index 603eb71..f0395dc 100644 --- a/druid/base/input.lua +++ b/druid/base/input.lua @@ -1,16 +1,152 @@ --- Druid input text component. -- Carry on user text input --- UNIMPLEMENTED +-- @author Part of code from Britzl gooey input component -- @module druid.input +local const = require("druid.const") local component = require("druid.component") +local utf8 = require("druid.system.utf8") -local M = component.create("input") +local M = component.create("input", { const.ON_INPUT }) -function M.init(self, node, callback, click_node) - self.style = self:get_style() +local function select(self) + gui.reset_keyboard() + if not self.selected then + print("selected") + self.selected = true + gui.show_keyboard(gui.KEYBOARD_TYPE_DEFAULT, false) + end end +local function unselect(self) + gui.reset_keyboard() + if self.selected then + self.selected = false + print("unselected") + gui.hide_keyboard() + end +end + + +function M.init(self, click_node, text_node) + self.druid = self:get_druid(self) + self.text = self.druid:new_text(text_node) + + self.selected = false + self.value = "" + self.marked_value = "" + self.current_value = "" + self.is_empty = true + + self.text_width = 0 + self.market_text_width = 0 + self.total_width = 0 + + self.max_width = 10 + + self.keyboard_type = gui.KEYBOARD_TYPE_DEFAULT + + self.button = self.druid:new_button(click_node, select) + self.button.on_click_outside:subscribe(unselect) +end + + +function M.on_input(self, action_id, action) + if self.selected then + local input_text = nil + if action_id == const.ACTION_TEXT then + print("usual", action.text) + -- ignore return key + if action.text == "\n" or action.text == "\r" then + return true + end + + local hex = string.gsub(action.text,"(.)", function (c) + return string.format("%02X%s",string.byte(c), "") + end) + + -- ignore arrow keys + if not string.match(hex, "EF9C8[0-3]") then + -- if not config or not config.allowed_characters or action.text:match(config.allowed_characters) then + input_text = self.value .. action.text + if self.max_length then + input_text = utf8.sub(self.value, 1, self.max_length) + end + self.marked_value = "" + end + end + + if action_id == const.ACTION_MARKED_TEXT then + print("marked") + self.marked_value = action.text or "" + if self.max_length then + input_text = utf8.sub(self.marked_value, 1, self.max_length) + end + end + + if action_id == const.ACTION_BACKSPACE and (action.pressed or action.repeated) then + input_text = utf8.sub(self.value, 1, -2) + end + + if action_id == const.ACTION_ENTER and action.released then + unselect(self) + return true + end + + if action_id == const.ACTION_BACK and action.released then + unselect(self) + return true + end + + if input_text then + print("set input_text", input_text) + self:set_text(input_text) + return true + end + end + + return self.selected +end + + +function M.set_text(self, input_text) + self.value = input_text + + -- only update the text if it has changed + local current_value = self.value .. self.marked_value + + print(self.value) + if current_value ~= self.current_value then + self.current_value = current_value + + -- mask text if password field + local masked_value, masked_marked_value + if self.keyboard_type == gui.KEYBOARD_TYPE_PASSWORD then + masked_value = M.mask_text(self.text, "*") + masked_marked_value = M.mask_text(self.marked_text, "*") + end + + -- text + marked text + local value = masked_value or self.value + local marked_value = masked_marked_value or self.marked_value + self.is_empty = #value == 0 and #marked_value == 0 + + -- measure it + self.text_width = self.text:get_text_width(value) + self.marked_text_width = self.text:get_text_width(marked_value) + self.total_width = self.text_width + self.marked_text_width + + self.text:set_to(value .. marked_value) + end +end + + +function M.get_text(self) + return self.value .. self.marked_value +end + + + return M diff --git a/example/gui/main/main.gui b/example/gui/main/main.gui index 5f58f85..5c98da4 100644 --- a/example/gui/main/main.gui +++ b/example/gui/main/main.gui @@ -2882,7 +2882,7 @@ nodes { nodes { position { x: 0.0 - y: -800.0 + y: -890.0 z: 0.0 w: 1.0 } @@ -2989,6 +2989,242 @@ nodes { template_node_child: false size_mode: SIZE_MODE_MANUAL } +nodes { + position { + x: 0.0 + y: -800.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: 1.0 + y: 1.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: "kenney/empty" + id: "section_input" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "scroll_content" + layer: "image" + 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_AUTO +} +nodes { + position { + x: -250.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.7 + y: 0.7 + z: 1.0 + w: 1.0 + } + size { + x: 300.0 + y: 60.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Input:" + font: "game" + id: "text_input" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_W + outline { + x: 0.0 + y: 0.0 + z: 0.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: "section_input" + layer: "text" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} +nodes { + position { + x: 130.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: 190.0 + y: 45.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: "kenney/progress_back" + id: "input_box" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + adjust_mode: ADJUST_MODE_FIT + parent: "section_input" + layer: "image" + 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_AUTO +} +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.4 + y: 0.4 + z: 1.0 + w: 1.0 + } + size { + x: 450.0 + y: 80.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "Input text will be here" + font: "game" + id: "input_text" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_CENTER + outline { + x: 0.0 + y: 0.0 + z: 0.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: "input_box" + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 0.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} nodes { position { x: 600.0 diff --git a/example/page/main.lua b/example/page/main.lua index 2da7d7f..a56eab1 100644 --- a/example/page/main.lua +++ b/example/page/main.lua @@ -106,6 +106,12 @@ local function setup_back_handler(self) end +local function setup_input(self) + local input = self.druid:new_input("input_box", "input_text") + input:set_text("hello!") +end + + function M.setup_page(self) setup_texts(self) @@ -117,6 +123,7 @@ function M.setup_page(self) setup_scroll(self) setup_slider(self) setup_back_handler(self) + setup_input(self) end