One of the things that irks with REBOL 2 is you can't display anti-aliased fonts in text input fields, like the VID field. So I have come up with a workaround that uses DRAW to dynamically render the text as you type. It's a bit of a hack, since it only works reliably with monospaced fonts, but it does work, and it supports basic text entry and backspacing. I eventually plan to add support for copy / paste and other key combinations, but for now I thought I'd share what I have so far in case anyone is trying to achieve something similar.
Just make sure you download and install the 'Inconsolata Bold' font before tetsing it (or adjust the width/padding settings, as described in my comments below).
https://fonts.google.com/specimen/Inconsolata
R E B O L []
; the width of each character in your font
charWidth: 9
; the top / bottom padding used to vertically
; center the text in your input field
charPadding: 7
; the font for your input field
; Note: This works best with a monospaced font because all characters have the same width.
; If you use a variable width font then the cursor will slowly drift away as you type.
; If you change the font or size below then the width and padding above needs to be adjusted to match.
aaFont: make face/font [
name: 'Inconsolata Bold'
size: 18
]
; the blinking cursor
textCursor: make face [
offset: as-pair 7 charPadding
size: 15x40
color: none
edge: none
; hiding the textCursor face stops the timer, and so we
; have to draw the cursor in a pane and hide it instead
pane: make face [
; indent the cursor away from the last character
offset: 3x0
size: 15x40
color: none
edge: none
effect: [ draw [
pen 0.0.0
font aaFont
text anti-aliased '|'
] ]
]
; blink two times a second
rate: 2
feel: make feel [
engage: func [face action event] [
if action = 'time [
either face/pane/show? [hide face/pane] [show face/pane]
]
]
]
]
; the typed text
textString: make face [
offset: as-pair 7 charPadding
size: 800x40
color: none
edge: none
font: none
; required for focus to work
flags: none
data: make object! [
text: ''
]
feel: make feel [
engage: func [face action event] [
if action = 'key [
if not word? event/key [
; TODO: expand this to handle copy / paste
; and other special keys and combinations
either event/key = #'^H'
; remove the last character when the backspace key is pressed
[remove back tail textString/data/text]
; otherwise append / display all other keys
[append textString/data/text event/key]
effect: [ draw [
pen 0.0.0
font aaFont
text anti-aliased textString/data/text
] ]
; move the cursor ahead (or back) by 1 character
textCursor/offset: as-pair ((length? textString/data/text) * charWidth) charPadding
show textCursor
show face
]
]
]
]
]
inputField: make face [
offset: 50x55
size: 800x40
color: 255.255.255
edge: make edge [size: 1x1 color: 0.0.0 effect: 'bevel]
pane: [textString textCursor]
]
window: make face [
size: 900x150
color: 236.236.236
edge: none
pane: [inputField]
]
center-face window
view/new window
; allow the textString face to receive keyboard events
; it must have a 'flags' property for this to work
focus textString
do-events