Home   Archive   Permalink



capturing keys within a field

Is there a way to capture keys within a field as they get typed along?
    
With feel and engage, I can get keys as they are typed, at the cost of writing key handling.
    
Is there a way to copy the field face object and modify its behavior?
    
Can I access the string containing the characters showing on the screen?
    
Also How to use a face created with make face inside a VID layout?
    
R ebol[]
    
view-block: [
    txt: field
    entry: field feel [
    
     engage: func [face action event] [        
        switch/default event/key reduce [
             bs [remove back tail face/text]
             cr [unview]
             escape [unview]
             'left [
                system/view/caret: back face/text
                ; not working
                ]    
             ] [
                append face/text event/key
                txt/text: face/text
             ]
                    
        show face
        show txt
        event
     ]
    ]
]
    
view/new center-face layout view-block
focus entry
do-events

posted by:   OneArb     22-Feb-2017/23:16:15-8:00



This is a little closer to traditional behaviour:
    
     switch/default event/key reduce [
         bs [system/view/caret: remove back system/view/caret]
         cr [unview]
         escape [unview]
         'left [
             system/view/caret: back system/view/caret
             ; not working
         ]
     ][
         system/view/caret: insert system/view/caret event/key
         txt/text: face/text
     ]
    
Q. Is there a way to copy the field face object and modify its behavior?
    
What would you do with the copy of the field face? You can just do -- make face [...some changes...] -- within the ENGAGE functions to make a clone. A face is just an object after all.
    
Q. Can I access the string containing the characters showing on the screen?
    
FACE/TEXT is the self same string.
    
Q. Also How to use a face created with make face inside a VID layout?
    
You need to place it inside another face's pane. SOME-FACE/PANE can be a face or a block of faces. Note that View kicks in when you place faces within SYSTEM/VIEW/SCREEN-FACE/PANE (try SOURCE VIEW).

posted by:   Chris     23-Feb-2017/0:30:31-8:00



Does this help toward your end goal?
    
R E B O L []
view/new w: layout [
    f: field
    field
    key #"^[" [quit]
    key #"^H" [system/view/caret: remove back system/view/caret show w]
] forever [
    old: copy f/text
    if not viewed? w [quit] wait .1
    if old <> x: copy f/text [print x]
]

posted by:   Nick     23-Feb-2017/12:53:30-8:00



Q. Is there a way to copy the field face object and modify its behavior?
        
What would you do with the copy of the field face?
    
Capture keystrokes before they get to FACE/TEXT
    


posted by:   OneArb     25-Feb-2017/9:16:34-8:00



The first solution works great, the additional code is minimal.
    
Why do I need to change txt/text: face/text
into txt/text: copy face/text
    
when I use a text field instead of field?
    
view-block: [
    txt: text white blue bold 200
    entry: field feel [
    
     engage: func [face action event] [        
; -- contributed code
     switch/default event/key reduce [
        bs [system/view/caret: remove back system/view/caret]
        cr [unview]
        escape [unview]
        'left [
         system/view/caret: back system/view/caret
        ]
        'right [
         system/view/caret: next system/view/caret
        ]
        'end [
         system/view/caret: tail system/view/caret
        ]
        'home [
         system/view/caret: head system/view/caret
        ]                
     ][
         system/view/caret: insert system/view/caret event/key
         txt/text: copy face/text
     ]
; --- contributed code
        show face
        show txt
     ]
    ]
]
    
view/new center-face layout view-block
focus entry
do-events

posted by:   OneArb     25-Feb-2017/9:23:21-8:00



Without the 'copy', txt/text permanently refers to the text in face/text (if you change txt/text, you're changing that face/text too). By copying face/text, you're referring to the text that's in face/text as that moment.

posted by:   Nick     25-Feb-2017/9:36:23-8:00



That's the intended behavior.
    
With txt field
txt/text: face/text
; does update txt
    
With txt text
txt/text: face/text
; show txt displays nothing
    
txt/text: copy face/text
; does update txt

posted by:   OneArb     26-Feb-2017/17:51:30-8:00



I tried the first version:
    
         'left [
             system/view/caret: back system/view/caret
         ]
    
It requires to redefine the behavior of every single key, including highlight insert / over ...
    
The second proposed solution can be made to use the native field editing. dirty? allows to find out about each new keystroke:
    
    
R EBOL []
print ""
view/new center-face w: layout [
     f: field
     target: field
     key #"^[" [quit]
]
focus f
    
forever [
    if not viewed? w [break]
    wait .01
    
    if f/dirty? [
    
     either (length? f/text) > (length? target/text) [
        action-type: "add char - "
     ] [
        action-type: "modify string - "
     ]
    
     newchar: exclude f/text target/text
        ; needs fixing
     print join action-type (newchar)
        
     target/text: copy f/text
     show target
     f/dirty?: false
    ]
]
    
    
I am not 100% sure how
    
    if not viewed? w [break]
    
works.

posted by:   OneArb     27-Feb-2017/20:41:30-8:00



If the Window is closed, the forever loop continues to evaluate and you'll have an invisible Rebol process running, so I put the 'viewed? w' condition to close the process properly.

posted by:   Nick     28-Feb-2017/4:04:34-8:00



Without viewed? w field editing locks up.
    
I figured viewed? would become false when closing w.
    
I am yet to comprehend the lockup.

posted by:   OneArb     28-Feb-2017/16:39:51-8:00