conrod
conrod copied to clipboard
TextBox widget
The state stores cursor position and selected range.
The text is passed in as argument and the new text is passed back to the callback.
Behavior (edit comment to add more):
Insert new text
- [x] When selected range length is larger than zero and the widget receives a unicode character, the text within selected range should be removed and the unicode character inserted at the start of selected range, then selected range length should be set to
0
and cursor position set to start of selected range - [x] When selected range length is zero and the widget receives a unicode character, the unicode character should be inserted at cursor position, then increment cursor position and set selected range to
[cursor_pos, 0)
Keyboard events
- [x] When pressing Ctrl + A, the selected range should be set to
[0, len)
- [x] When pressing Ctrl + Left Arrow, the cursor position should be set to
0
and selected range should collapse to[cursor_pos, 0)
- [x] When pressing Ctrl + Right Arrow, the cursor position should be set to
len
and selected range should collapse to[cursor_pos, 0)
- [x] When pressing Backspace and selected range length is larger than zero, the text within selected range should be removed and selected range should collapse to
[cursor_pos, 0)
- [x] When pressing Backspace and selected range is zero and cursor position is larger than zero, the character at
(cursor_pos - 1)
should be removed, then decrementcursor_pos
and selected range should be set to[cursor_pos, 0)
- [x] When pressing Ctrl + E, jump to the end of the line
Select text with mouse
When not holding Shift:
- [x] When pressing with left mouse button anywhere in the range
[0, len)
, the cursor position should be set tomouse_pos
and selected range should collaps to[mouse_pos, 0)
- [x] When left mouse is pressed and mouse moved, the selected range should be set to
[cursor_pos, mouse_pos - cursor_pos)
. If length of selected range is negative, the values should be swapped.
When holding Shift:
- [x] When pressing with left mouse button anywhere in the range
[0, len)
, the selected range should be set to[cursor_pos, mouse_pos - cursor_pos)
. If length of selected range is negative, the values should be swapped. - [x] When left mouse is pressed and mouse moved, the selected range should be set to
[cursor_pos, mouse_pos - cursor_pos)
. If length of selected range is negative, the values should be swapped. - [x] When double-clicking mouse cursor on a non-space character the selected range should be set to the current word range.
- [x] When double-clicking mouse cursor on a space character the selected range should be set to the two words connected by the space character.
View
- [x] Keep the cursor inside view. This can be done by "navigating" the smallest possible amount from the current view to make the cursor visible.
Todo:
- [x] Define behavior for unicode event
- [x] Define behavior for keyboard events
- [x] Define behavior for selecting text with mouse cursor
- [ ] Define behavior for dragging text
Thanks for putting this together! I'm about to start having a go at this so I'll use it as a reference. I'm not sure I'll be able to get all features in right away, but hopefully can get something usable working in the next couple days.
What about Ctrl + E
for jump-to-end-of-line?
@porglezomp Thanks! Added to the list.
When the textbox is not captured there is no selection / cursor so the view can not be based on it. Therefore, I think it makes sense to set the view to whatever it was when the textbox was last captured, but what should happen if the text in the textbox is updated without being captured again first? Should the view reset to display whatever fits starting from the beginning of the text or slide left to the end of the new text or something else?
Currently, when the text is changed without interaction with the textbox and the textbox is captured the cursor / selection.end slides left if the text became shorter than the selection, otherwise it is unchanged.
It looks like input boxes in the browser reset and display from the start of the text when capture is lost, so unless anyone objects, I will go with this for now. This also means I don't need to keep track of what the view was before capture was lost, which is nice.
@dcampbell24 That's a good point! If this becomes annoying, then we'll change it.
If noone is working on the keyboard events I would like to take a shot at them.
@TheNeikos go for it. I can assign this to you if you want. I don't think I am going to be doing much with it any time soon.
So, interestingly UserInput
only stores keys since last input, and pressing both at the same tick is not very usable. Before I start adding that state to the textbox is that intended behaviour in the long term? Because an array of pressed keys right now seems to be much better to work with.
Trying to find the best place to ask this without opening a new issue. Is it possible to set the focus to a TextBox when it is first created? I'm creating a new one in a kind of pop up and would love it for to capture keyboard input straight away so the user can start typing without having to click on it with the mouse.