[comp.sys.mac.programmer] Editable TextItems in Dialogs - Help!

g099508030ea@deneb.ucdavis.edu (Jim Deline) (01/25/89)

I would like to be able to parse a string as it is being typed
into an editable textitem field of a dialog, and have all numbers
typed appear subscripted relative to the rest of the string.

For instance, if I were to type the string 'C6H6' I would like
the number six to be subscripted in all occurrences - as in
a molecular formula.  I would like to be able to do this 'on
the fly' - ie. as the string is being typed.

Does anyone know if this can be done?  If so, I would appreciate
some help as I am stumped.  PASCAL code fragments would be
most welcome, but I could probably get by with C code fragments
if I really had to (choke).

Jim Deline

shane@chablis.cc.umich.edu (Shane Looker) (01/26/89)

In article <3543@ucdavis.ucdavis.edu> jedeline@deneb.ucdavis.edu (Jim Deline) writes:
>
>I would like to be able to parse a string as it is being typed
>into an editable textitem field of a dialog, and have all numbers
>typed appear subscripted relative to the rest of the string.
>
>For instance, if I were to type the string 'C6H6' I would like
>the number six to be subscripted in all occurrences - as in
>a molecular formula.  I would like to be able to do this 'on
>the fly' - ie. as the string is being typed.
>
>Does anyone know if this can be done? 
>
>Jim Deline

An interesting idea.  I don't think you can do it with the normal EditText
item, since it uses TextEdit.  Probably your best bet is to create a UserItem
which is modified (the text in it) based on what field you are in, and what key is hit.  The way to do that is to create a filter proc which interecpts keydown
events, and modifies a global variable.  Then return a hit in the UserItem
from the filter proc, and re-draw the UserItem with the current string.  You
could use just a 1 character buffer to decide what to do with the key which
was just hit.

If you do this, remember to accept <return> and <enter> as button 1, and cmd-.
as button 2.  (Standard Mac interface.)


Shane Looker   |  Looker@um.cc.umich.edu | shane@chablis.cc.umich.edu

holland@m2.csc.ti.com (Fred Hollander) (01/27/89)

In article <887@mailrus.cc.umich.edu> shane@chablis.cc.umich.edu (Shane Looker) writes:
>In article <3543@ucdavis.ucdavis.edu> jedeline@deneb.ucdavis.edu (Jim Deline) writes:
>>
>>I would like to be able to parse a string as it is being typed
>>into an editable textitem field of a dialog, and have all numbers
>>typed appear subscripted relative to the rest of the string.
>
>An interesting idea.  I don't think you can do it with the normal EditText
>item, since it uses TextEdit.  Probably your best bet is to create a UserItem
>which is modified (the text in it) based on what field you are in, and what key is hit.  The way to do that is to create a filter proc which interecpts keydown
>events, and modifies a global variable.  Then return a hit in the UserItem

I'm not sure if this would work, but, why couldn't you use a filterProc even
with an editText field?  The filterProc could intercept keyDown events.  If
the character is invalid, it could modify itemHit and possibly theEvent.  Like
I said, I haven't tried this but it sounds like it should work.

Fred Hollander
Computer Science Center
Texas Instruments, Inc.
holland%ti-csl@csnet-rela

The above statements are my own and not representative of Texas Instruments.

alan@Apple.COM (Alan Mimms) (01/27/89)

In article <887@mailrus.cc.umich.edu> shane@chablis.cc.umich.edu (Shane Looker) writes:
>In article <3543@ucdavis.ucdavis.edu> jedeline@deneb.ucdavis.edu (Jim Deline) writes:
>>
>>I would like to be able to parse a string as it is being typed
>>into an editable textitem field of a dialog, and have all numbers
>>typed appear subscripted relative to the rest of the string.
>>
>>For instance, if I were to type the string 'C6H6' I would like
>>the number six to be subscripted in all occurrences - as in
>>a molecular formula.  I would like to be able to do this 'on
>>the fly' - ie. as the string is being typed.
>>
>>Does anyone know if this can be done? 
>>
>>Jim Deline
>
>An interesting idea.  I don't think you can do it with the normal EditText
>item, since it uses TextEdit.  Probably your best bet is to create a UserItem
>which is modified (the text in it) based on what field you are in, and what key is hit.  The way to do that is to create a filter proc which interecpts keydown
>events, and modifies a global variable.  Then return a hit in the UserItem
>from the filter proc, and re-draw the UserItem with the current string.  You
>could use just a 1 character buffer to decide what to do with the key which
>was just hit.
>
>If you do this, remember to accept <return> and <enter> as button 1, and cmd-.
>as button 2.  (Standard Mac interface.)
>
>
>Shane Looker   |  Looker@um.cc.umich.edu | shane@chablis.cc.umich.edu

Perhaps a simpler way is to employ a technique I have used 
for making password non-echo fields in dialogs.  Replace BOTH the
textProc and txMeas GrafProcs in your dialog GrafPort with
routines that do something like this:

QDProcs textProc:
    if (rectangle of text to be drawn intersects with the
	rectangle of the item you're doing magic in) {
	Draw the text in a "smart" way, changing fonts or
	whatever to make the numbers come out subscripted
	(Be sure to use the REAL StdText routine for all
	drawing, or you'll get recursed to death)
    } else {
	do the normal StdText routine
    }

The reason you have to make the textProc do the rectangle intersection
is that TextEdit can draw text EITHER in response to an update event
or in response to keystrokes, etc.  The "editItem" field of the
dialog is NOT correct in the former case (necessarily).

Also, the intersection test must be performed rather than a simple
PtInRect for the current pnLoc since TextEdit scrolls text by
shifting the origin it draws with and mucking with the clipRgn
during the text drawing.  Consequently, the pnLoc might very well
be outside of the display rectangle of the dialog item when
TextEdit is drawing the item's contents.

QDProcs txMeas:
    if (((DialogPeek) qd.thePort) -> editItem == yourMagicItem - 1) {
	Measure the (as above) in a magical way, taking into
	account the changes in font or whatever you'll be
	using for drawing
    } else {
	return the value from the REAL StdTxMeas routine
    }

Note that qd.thePort is really the DialogRecord for your dialog.
This helps out in this technique immeasurably.

For people making non-echo TextEdit fields in their dialogs,
please note: You can use this technique, setting the FONT of the
text being drawn or measured to a font in your application which
contains only a single glyph: the "blob" character (normally
option-8).  This makes ALL characters typed by the user appear as
blobs, but the text returned by GetIText is the string the
user typed.  This is the simplest of the four techniques I've
seen for doing this.

Hope this helps.
-- 
Alan Mimms			My opinions are generally
Communications Products Group	pretty worthless, but
Apple Computer			they *are* my own...
...it's so simple that only a child can do it!  -- Tom Lehrer, "New Math"