-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
selection and cursor pos #258
Changes from all commits
987fb34
65ac7a4
6f4bce2
7ceae08
e67b9b4
2e31d10
84471c7
68396e1
f904763
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,8 +19,9 @@ | |
-- @tfield druid.text placeholder @{Text} | ||
|
||
--- | ||
|
||
local const = require("druid.const") | ||
local component = require("druid.component") | ||
local utf8 = require("druid.system.utf8") | ||
|
||
local RichInput = component.create("druid.rich_input") | ||
|
||
|
@@ -30,37 +31,103 @@ local SCHEME = { | |
PLACEHOLDER = "placeholder_text", | ||
INPUT = "input_text", | ||
CURSOR = "cursor_node", | ||
HIGHLIGHT = "highlight_node", | ||
} | ||
|
||
|
||
local function set_cursor(self) | ||
if self.touch_pos_x then | ||
local text = self.input:get_text() | ||
local node_pos = gui.get_screen_position(self.highlight) | ||
local touch_delta_x = self.touch_pos_x - node_pos.x | ||
local letters_count = utf8.len(self.input:get_text()) | ||
local cursor_delta = 0 | ||
local gap = self.input.total_width/2 * -1 | ||
|
||
for i = 1, letters_count do | ||
cursor_delta = gap + self.text:get_text_size(utf8.sub(text, 1, i)) - self.half_cursor_width | ||
if cursor_delta <= touch_delta_x then | ||
gui.set_position(self.cursor, vmath.vector3(cursor_delta + self.half_cursor_width/2, 0, 0)) | ||
self.input.cursor_letter_index = i | ||
end | ||
end | ||
|
||
self.touch_pos_x = nil | ||
else | ||
local text = self.input:get_text() | ||
local gap = self.input.total_width/2 * -1 | ||
local cursor_delta = gap + self.text:get_text_size(utf8.sub(text, 1, self.input.cursor_letter_index)) - self.half_cursor_width | ||
gui.set_position(self.cursor, vmath.vector3(cursor_delta + self.half_cursor_width/2, 0, 0)) | ||
end | ||
end | ||
|
||
|
||
local function animate_cursor(self) | ||
gui.cancel_animation(self.cursor, gui.PROP_COLOR) | ||
gui.set_color(self.cursor, vmath.vector4(1)) | ||
gui.animate(self.cursor, gui.PROP_COLOR, vmath.vector4(1,1,1,0), gui.EASING_INSINE, 0.8, 0, nil, gui.PLAYBACK_LOOP_PINGPONG) | ||
end | ||
|
||
|
||
local function update_text(self, text) | ||
local function update_text(self) | ||
local text_width = self.input.total_width | ||
animate_cursor(self) | ||
gui.set_position(self.cursor, vmath.vector3(text_width/2, 0, 0)) | ||
local text_height = self.input.text_height | ||
gui.set_scale(self.cursor, self.input.text.scale) | ||
gui.set_size(self.highlight, vmath.vector3(text_width, text_height, 0)) | ||
set_cursor(self) | ||
end | ||
|
||
|
||
local function clear_text(self, replace_with_symbol) | ||
local spacer = replace_with_symbol or "" | ||
self.input:set_text(spacer) | ||
update_text(self) | ||
|
||
if replace_with_symbol then | ||
gui.set_position(self.cursor, vmath.vector3(self.input.total_width/2, 0, 0)) | ||
self.input.cursor_letter_index = 1 | ||
else | ||
gui.set_position(self.cursor, vmath.vector3(0, 0, 0)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can create a |
||
self.input.cursor_letter_index = 1 | ||
end | ||
|
||
gui.set_enabled(self.highlight, false) | ||
gui.set_enabled(self.cursor, true) | ||
end | ||
|
||
|
||
local function on_select(self) | ||
self.input.cursor_letter_index = utf8.len(self.input:get_text()) or 0 | ||
gui.set_enabled(self.cursor, true) | ||
gui.set_enabled(self.highlight, false) | ||
gui.set_enabled(self.placeholder.node, false) | ||
animate_cursor(self) | ||
end | ||
|
||
|
||
local function on_unselect(self) | ||
gui.set_enabled(self.cursor, false) | ||
gui.set_enabled(self.highlight, false) | ||
gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0) | ||
end | ||
|
||
|
||
local function on_button_click(self) | ||
self.touch_pos_x = self.action_pos_x | ||
gui.set_enabled(self.highlight, false) | ||
gui.set_enabled(self.cursor, true) | ||
self.text:set_to(self.input:get_text()) | ||
set_cursor(self) | ||
end | ||
|
||
|
||
local function on_button_double_click(self) | ||
if #self.input:get_text() > 0 then | ||
gui.set_enabled(self.highlight, true) | ||
gui.set_enabled(self.cursor, false) | ||
end | ||
end | ||
|
||
--- Component init function | ||
-- @tparam RichInput self @{RichInput} | ||
-- @tparam string template The template string name | ||
|
@@ -71,15 +138,27 @@ function RichInput.init(self, template, nodes) | |
self.druid = self:get_druid() | ||
self.input = self.druid:new_input(self:get_node(SCHEME.BUTTON), self:get_node(SCHEME.INPUT)) | ||
self.cursor = self:get_node(SCHEME.CURSOR) | ||
|
||
self.input:set_text("") | ||
self.highlight = self:get_node(SCHEME.HIGHLIGHT) | ||
|
||
self.placeholder = self.druid:new_text(self:get_node(SCHEME.PLACEHOLDER)) | ||
self.text = self.druid:new_text(self:get_node(SCHEME.INPUT)) | ||
|
||
self.input.on_input_text:subscribe(update_text) | ||
self.input.on_input_select:subscribe(on_select) | ||
self.input.on_input_unselect:subscribe(on_unselect) | ||
|
||
self.input.button.on_click:subscribe(on_button_click, self) | ||
self.input.button.on_double_click:subscribe(on_button_double_click, self) | ||
self.input.style.NO_CONSUME_INPUT_WHILE_SELECTED = true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the rich input should not change these style settings (and for skip input keys same) |
||
self.input.style.SKIP_INPUT_KEYS = true | ||
self.input.style.IS_LONGTAP_ERASE = false | ||
|
||
self.input.cursor_letter_index = 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already inited in input component |
||
self.action_pos_x = nil | ||
self.half_cursor_width = self.text:get_text_size("|")/2 | ||
|
||
clear_text(self) | ||
on_unselect(self) | ||
update_text(self, "") | ||
end | ||
|
||
|
||
|
@@ -92,4 +171,53 @@ function RichInput.set_placeholder(self, placeholder_text) | |
end | ||
|
||
|
||
function RichInput.on_input(self, action_id, action) | ||
self.action_pos_x = action.screen_x | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The values |
||
|
||
if gui.is_enabled(self.highlight) then | ||
if action_id == const.ACTION_BACKSPACE or action_id == const.ACTION_DEL then | ||
clear_text(self) | ||
on_select(self) | ||
elseif action_id == const.ACTION_TEXT then | ||
clear_text(self, action.text) | ||
end | ||
else | ||
if action_id == const.ACTION_DEL and action.pressed then | ||
local text = self.input:get_text() | ||
local new_text = utf8.sub(text, 1, self.input.cursor_letter_index) .. utf8.sub(text, self.input.cursor_letter_index +2 ) | ||
self.input:set_text(new_text) | ||
end | ||
|
||
if action_id == const.ACTION_BACKSPACE then | ||
if self.input.cursor_letter_index > 0 and gui.is_enabled(self.cursor) and action.pressed then | ||
local text = self.input:get_text() | ||
local new_text = utf8.sub(text, 1, self.input.cursor_letter_index-1) .. utf8.sub(text, self.input.cursor_letter_index +1 ) | ||
self.input.cursor_letter_index = self.input.cursor_letter_index -1 | ||
self.input:set_text(new_text) | ||
end | ||
return true | ||
end | ||
|
||
if action_id == const.ACTION_LEFT and action.pressed then | ||
--print("left") | ||
if self.input.cursor_letter_index > 1 then | ||
self.input.cursor_letter_index = self.input.cursor_letter_index -1 | ||
end | ||
elseif action_id == const.ACTION_RIGHT and action.pressed then | ||
--print("right") | ||
if self.input.cursor_letter_index < utf8.len(self.input:get_text()) then | ||
self.input.cursor_letter_index = self.input.cursor_letter_index + 1 | ||
end | ||
end | ||
|
||
update_text(self) | ||
self.touch_pos_x = nil | ||
|
||
if utf8.len(self.input:get_text()) <=0 then | ||
self.input.cursor_letter_index = 0 | ||
end | ||
end | ||
return false | ||
end | ||
|
||
return RichInput |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the touch_pos_x should be as arg of function, wdyt?