Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: field focus event

From: brett:codeconscious at: 20-Sep-2003 0:13

Mike Yaunish wrote:
> I am trying to find where I can drop some code into a view field the > instant that the field becomes active.
Hi Mike, I don't think there is any focus event as such that does this. However, there are two functions that manage focus for VID fields: Focus and Unfocus. These functions are quite small so the idea is to replace them with your own version that generates your own events. I'll have a stab below. The other way you could look at this (depending on what you are doing) is instead of a function being called when focus changes you could have another face poll (using a rate) system/view/focal-face to see if it is the face you are interested in and do something while that is true. This might be useful for some sort of interactive display. For the rest of the email, I'll go the first route, to generate a focus events. There is a little information on the Focus function here: http://www.rebol.com/how-to/fields.html#sect3.5. The trick with modifying the Focus function is to rebind it to the context it was created within, which is ctx-text. How do I know that? A bit of searching some time ago. So the plan. (1) Modify Focus to check the face it is given for two new facets - one for pre-focus, one for post-focus. If they are not there carry on as normal. If they are present then they would normally contain functions, but you could have a simple value true/false. If the pre-focus facet evaluates to False or None then exit the Focus function early, thereby cancelling it. Might be handy for something! (2) Modify Unfocus similarly. Pre-unfocus could be useful for validation - see next point. (3) Looking at the code for Unfocus I guess that no VID code expects a return value from it, however it is useful for us. If Pre-unfocus is set to none, the user might want to prevent the field from being unfocussed - so if I pass that back as a return from Unfocus, the Focus routine can be cancelled. Could be handy for validation. If I pass a value back - all is well. I figure here I may as well pass the face back that was unfocussed or if the window is just opened a True. I've added a local variable tmp-value to handle Unset! in both functions. Now all this looks to be to be pretty good but I haven't tested/investigated it thoroughly to see if it breaks other VID assumptions. Use at your own risk! :^) There is one other issue. When you close the window Unfocus is not called so you will not get my Unfocus events generated when the user closes the window. If you need this you will probably need an event function (insert-event-func) to trap the close and call Unfocus. Code below. Regards, Brett. ; ------------------------------------------------------- focus: func [ "Focuses key events on a specific face." face /no-show /local tmp-face tmp-value ] bind [ ; My pre-focus addition if in face 'pre-focus [ ; Call the pre-focus function, Cancel the focus if false/none. if all [ not unset? set/any 'tmp-value face/pre-focus face not tmp-value ] [exit] ] ; Another change, if unfocus was cancelled, cancel the focus. if not unfocus [exit] if not face [exit] view*/focal-face: face if not string? face/text [ face/text: either face/text [form face/text] [copy ""] ] if none? face/line-list [ if face/para [face/para/scroll: 0x0] view*/caret: tail face/text ] if flag-face? face field [hilight-all face] ; My post-focus addition if in face 'post-focus [face/post-focus face] if not no-show [show face] ] in ctx-text 'view* unfocus: func [ "Removes the current key event focus." /local tmp-face tmp-value ] bind [ tmp-face: view*/focal-face ; My addition if all [tmp-face in tmp-face 'pre-unfocus] [ ; Call the pre-unfocus function, Cancel the focus if false/none. if all [ not unset? set/any 'tmp-value tmp-face/pre-unfocus tmp-face not tmp-value ] [ ; This will mean that unfocus is cancelled. return none ] ] view*/focal-face: none view*/caret: none unlight-text ; My post-unfocus addition if all [tmp-face in tmp-face 'post-unfocus] [ tmp-face/post-unfocus tmp-face ] if tmp-face [show tmp-face] ; Another addition. Send back a true if we did unfocus. any [tmp-face true] ] in ctx-text 'view* ; ------------------------------------------------------- ; Test program stylize/master [ log-field: field with [ pre-focus: func [face] [ print ["pre-focus" mold face/text] ] post-focus: func [face] [ print ["post-focus" mold face/text] ] pre-unfocus: func [face] [ print ["pre-unfocus" mold face/text] ] post-unfocus: func [face] [ print ["post-unfocus" mold face/text] ] ] ] view layout [ logfld: log-field "Log field 1" logfld: log-field "Log field 2" field "I change the colour of the box." with [ post-focus: does [ box1/color: green show box1 ] post-unfocus: does [ box1/color: gray show box1 ] ] box1: box 10x10 orange field "You cannot focus me!" with [pre-focus: none] field "Black hole" with [pre-unfocus: none] ]