[comp.sys.mac.programmer] Highlight "OK" buttons

paco@homxc.UUCP (Herbert Throckmorton) (09/06/88)

Here's a riddle:

Default buttons in alerts get highlighted automatically.  IM vol.1
mentions in the "Dialog Manager" section that one can highlight the
default button in a dialog as well, but IM vol.1 doesn't mention how
to do that deed, as far as I can tell.  One way would be to define 
the default button as a user item and write a routine to highlight 
it, like in the example in that same IM section.  Is there a better
way, some flag or routine not mentioned in IM?

thanks -

	John Scoggins
	att!homxc!paco

blob@Apple.COM (Brian Bechtel) (09/07/88)

In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:

>IM vol.1 mentions in the "Dialog Manager" section that one can
>highlight the default button in a dialog as well, but IM vol.1 doesn't
>mention how to do that deed, as far as I can tell.

Page I-407 describes how to highlight a default button in the standard
way.
	PenSize(3,3);
	InsetRect(displayRect, -4, -4);
	FrameRoundRect(displayRect, 16, 16);

--Brian Bechtel		blob@apple.com

andrew@ems.Ems.MN.ORG (Andrew C. Esh) (09/07/88)

If you open a dialog with this:

      GetSelection := GetNewDialog(21, nil,  Pointer(-1) ); {Bring in dialog}

Then you can highlight the button with these lines:

	  {HighLight the OK button}
	GetDItem(GetSelection, I_OK, DType, DItem, tempRect); {Get button info}
	PenSize(3,3);
	InsetRect(tempRect,-4,-4);
	FrameRoundRect(tempRect,16,16);
	PenSize(1,1);

Check IM I-431 for a description of the arguments.  I_OK is defined as the item
number of the button.  21 is the resource number of the dialog.

					- Andrew
-- 
Andrew C. Esh        DOMAIN: andrew@ems.MN.ORG     APPLELINK: D0492
EMS/McGraw-Hill      UUCP: ihnp4!meccts!ems!andrew      AT&T: (612) 829-8200

spector@vx2.NYU.EDU (David HM Spector) (09/07/88)

Nope, you have to do it yourself.  The way I usually do it, is to make the
usual "default" button the one that gets "clicked on" by the dialog manager
when the user presses Return or Enter (i.e., make it the first button item),
and then do a FrameRoundRect of your button's bounds rect with set line
thickness ~3...  you call your doButtonHiLite routine before you
put up the dialog for the user to see (!!remember to SetPort to your
dialog first!!), and the call modladialog or whatever...

...hope that helps a little...

_DHMS
-------------------------------------------------------------------------------
David HM Spector				   New York University
Senior Systems Programmer			   Graduate School of Business
ARPAnet: SPECTOR@GBA.NYU.EDU			   Academic Computing Center
USEnet:...!{allegra,rocky,harvard}!cmcl2!spector   90 Trinity Place, Rm C-4
HamRadio: N2BCA      MCIMail: DSpector             New York, New York 10006
AppleLink: D1161     CompuServe: 71260,1410        (212) 285-6080
"What computer puts out work like this?"          "Hire us and we'll tell you."

ephraim@think.COM (ephraim vishniac) (09/08/88)

In article <16727@apple.Apple.COM> blob@apple.com.UUCP (Brian Bechtel) writes:
>In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:

>>IM vol.1 mentions in the "Dialog Manager" section that one can
>>highlight the default button in a dialog as well, but IM vol.1 doesn't
>>mention how to do that deed, as far as I can tell.

>Page I-407 describes how to highlight a default button in the standard
>way.
>	PenSize(3,3);
>	InsetRect(displayRect, -4, -4);
>	FrameRoundRect(displayRect, 16, 16);

That's how you *draw* the highlighting, which is only a partial answer
to the question of how you highlight a button.  The part that people
often get wrong is *when* you highlight the button.  They tend to
forget that the highlighting might need refreshment (refreshing?)
(redrawing?) when the dialog gets an update event.

It seems like a safe tactic would be to redraw the highlighting
whenever you get any update event for the dialog, but I'm sure
somebody will point out to me a reason that's a bad idea...


Ephraim Vishniac					  ephraim@think.com
Thinking Machines Corporation / 245 First Street / Cambridge, MA 02142-1214

     On two occasions I have been asked, "Pray, Mr. Babbage, if you put
     into the machine wrong figures, will the right answers come out?"

mikem@uhccux.uhcc.hawaii.edu (Mike Morton) (09/08/88)

In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:
>Default buttons in alerts get highlighted automatically.  IM vol.1
>mentions in the "Dialog Manager" section that one can highlight the
>default button in a dialog as well, but IM vol.1 doesn't mention how
>to do that deed, as far as I can tell.  One way would be to define 
>the default button as a user item and write a routine to highlight 
>it, like in the example in that same IM section.  Is there a better
>way, some flag or routine not mentioned in IM?

The code to draw the outline is on page I-407.  The simplest way to show
the outline is to draw it once when you first draw the dialog.  A user
item is more correct, in case the dialog needs to get redrawn (a sub-
dialog or FKEY can cover it).  But the Finder's alerts do it wrong, so
I've never felt compelled to do it right...

 -- Mike Morton // P.O. Box 11378, Honolulu, HI  96828, (808) 456-8455 HST
      Internet: msm@ceta.ics.hawaii.edu
    (anagrams): Mr. Machine Tool; Ethical Mormon; Chosen Immortal; etc.

sho@pur-phy (Sho Kuwamoto) (09/08/88)

In article <2352@uhccux.uhcc.hawaii.edu> mikem@uhccux.UUCP (Mike Morton) writes:
>In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:
>
>The code to draw the outline is on page I-407.  The simplest way to show
>the outline is to draw it once when you first draw the dialog.  A user
>item is more correct, in case the dialog needs to get redrawn (a sub-
>dialog or FKEY can cover it).  But the Finder's alerts do it wrong, so
>I've never felt compelled to do it right...
>
It's not *that* hard to use a userItem.  I do it.  But then again there are
a lot of other areas where I don't do exactly what Apple tells me...

-Sho

bradn@tekig4.TEK.COM (Bradford Needham) (09/08/88)

In article <27471@think.UUCP> ephraim@vidar.think.com.UUCP (ephraim vishniac) writes:
>...That's how you *draw* the highlighting, which is only a partial answer
>to the question of how you highlight a button....

I used to avoid highlighting default buttons because it seemed so complex.
Now I let the Dialog Manager handle button highlighting.  Here's how:

	In MacDraw, draw a thick-lined round-cornered rectangle.
	Select the rectangle and copy it to the clipboard.

	In ResEdit, paste your clipboard into a new PICT resource.
	Create a new PICT element in your dialog, giving your newly created
	PICT as the resource to show.
	Edit the rectangle of the new dialog element so it outlines
	your default button.
    
	Now when you display the dialog, the Dialog Manager will draw the
	PICT rectangle that outlines your default button.

Since this method relys solely on resource modification,
it needs no special handling at run-time.  You can even add default
highlighting to a dialog without recompiling your program.


Brad Needham
bradn@tekig4.TEK.COM

sho@pur-phy (Sho Kuwamoto) (09/08/88)

In article <3186@tekig4.TEK.COM> bradn@tekig4.TEK.COM (Bradford Needham) writes:
>I used to avoid highlighting default buttons because it seemed so complex.
>Now I let the Dialog Manager handle button highlighting.  Here's how:
>
>	In MacDraw, draw a thick-lined round-cornered rectangle.
>	Select the rectangle and copy it to the clipboard.
>
>	In ResEdit, paste your clipboard into a new PICT resource.
>	Create a new PICT element in your dialog, giving your newly created
>	PICT as the resource to show.
>	Edit the rectangle of the new dialog element so it outlines
>	your default button.
>    
>	Now when you display the dialog, the Dialog Manager will draw the
>	PICT rectangle that outlines your default button.
>
Here is what I do to hilight buttons.  It's not pretty, but it sort of
works.  Install it as a userItem which is big enough to cover all the
buttons you might want to hilight, and set oldItem=0 and whichItem to
whatever you want hilighted.  If you want to hilight a different
button, change whichItem and call an invalRect, or call the routine
directly if you want to avoid redreawing the buttons themselves.  The
reason I do this is because in maybe half of my dialogs, I ask the
user for input, and I want Cancel selected if there is no input in the
appropriate EditText items.  Cheers.

pascal void OutlineButton(theWindow, itemNo)
WindowPtr theWindow;
short itemNo;
{
	pnState savePen;
	short	type;
	Handle	ignore;
	Rect	box;
	
	GetPenState(&savePen);
	PenSize(3,3);
/* don't need to erase the old one if it is the same, or if it doesn't exist */
	if(oldItem > 0 && oldItem != whichItem){
		PenPat(&white);
		GetDItem(theWindow, oldItem, &type, &ignore, &box);
		InsetRect(&box, -4, -4);
		FrameRoundRect(&box, 16, 16);
	}
/* need to draw the new one even if it is the same, because of update evts. */
	PenPat(&black);
	GetDItem(theWindow, whichItem, &type, &ignore, &box);
	InsetRect(&box, -4, -4);
	FrameRoundRect(&box, 16, 16);
	
	oldItem = whichItem;
	SetPenState(savePen);
}

drc@claris.UUCP (Dennis Cohen) (09/08/88)

In article <27471@think.UUCP> ephraim@vidar.think.com.UUCP (ephraim vishniac) writes:
...
>That's how you *draw* the highlighting, which is only a partial answer
>to the question of how you highlight a button.  The part that people
>often get wrong is *when* you highlight the button.  They tend to
>forget that the highlighting might need refreshment (refreshing?)
>(redrawing?) when the dialog gets an update event.
>
>It seems like a safe tactic would be to redraw the highlighting
>whenever you get any update event for the dialog, but I'm sure
>somebody will point out to me a reason that's a bad idea...
>

This is essentially the correct method (at least in my opinion).  The
method I use is to create a userItem that extends out from the default\
button by four pixels in all directions and attach a "draw me" proc to
it with SetDItem that does the FrameRoundRect.

Dennis Cohen
Claris Corp.
------------
Disclaimer: Any opinions expressed above are _MINE_!

leonardr@uxe.cso.uiuc.edu (09/08/88)

ephraim@think.COM(Ephraim Vishniac) in comp.sys.mac.programmer

>>In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:
>
>>>IM vol.1 mentions in the "Dialog Manager" section that one can
>>>highlight the default button in a dialog as well, but IM vol.1 doesn't
>>>mention how to do that deed, as far as I can tell.
>
>> [code, etc. was here before I removed it]
>
>That's how you *draw* the highlighting, which is only a partial answer
>to the question of how you highlight a button.  The part that people
>often get wrong is *when* you highlight the button.  They tend to
>forget that the highlighting might need refreshment (refreshing?)
>(redrawing?) when the dialog gets an update event.
>
>It seems like a safe tactic would be to redraw the highlighting
>whenever you get any update event for the dialog, but I'm sure
>somebody will point out to me a reason that's a bad idea...
>
	An even better idea is to use a UserItem, that was you are guarenteed that
the hiliting will be redrawn on update events (Dialog Manager call all User
Items on updates) and you don't need a filter proc!

	The code that I use for my UserItem is:

PROCEDURE OutlineButton(aDialog: DialogPtr; itemNo: Integer);
  VAR
    iType: integer;
    iHandle: Handle;
    iBox: Rect;
  BEGIN
    GetDItem(aDialog, 1, iType, iHandle, iBox); {I assume that OK is #1}
    InsetRect(iBox, - 4, - 4);
    PenSize(3, 3);
    FrameRoundRect(iBox, 16, 16);
    PenNormal;
  END;

	All you need to do to use this is to create a userItem (I just create it as
the last item in my Dialog and I give it a rect of 0,0,0,0 since it doesn't
matter) and then set this routine to it using SetDItem.


+---------------------------------+-----------------------------------+
+                                 +  Any thing I say may be taken as  +
+   Leonard Rosenthol             +  fact, then again you might decide+
+   President, LazerWare, inc.    +  that it really isn't, so you     +
+                                 +  never know, do you??             +
+   leonardr@uxe.cso.uiuc.edu     +                                   +
+   GEnie:  MACgician             +  MacNET: MACgician                +
+   Delphi: MACgician             +                                   +
+                                 +                                   +
+---------------------------------+-----------------------------------+

shane@chianti.cc.umich.edu (Shane Looker) (09/09/88)

[Geez.  You don't check news for a few days and everybody goes crazy...]


In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:
>  [ Basically, how do I highlite the default button? ]
>
>	John Scoggins
>	att!homxc!paco


Here is the code I throw into my applications/whatevers which need to have
a dialog button highlighted...

----------------------------------------------------

Set_Hilite(dlog, itemNo)
DialogPtr	dlog;		/* The DialogPtr to work with */
short		itemNo;		/* Which item is the UserItem */
{
	Rect	Box;
	pascal void Hilite_Default();
	
	GetDItem(dlog, itemNo, NIL, NIL, &Box);  /* Grab the item rectangle */
			/* Now setup the procedure for it */
	SetDItem(dlog, itemNo, userItem, (Handle) Hilite_Default, &Box);
}


pascal void Hilite_Default(theWindow, itemNo)
WindowPtr	theWindow;
short		itemNo;
{
	Rect	Box;
	
		/* NOTE!: #define OK 1
                   for most dialog boxes.  */
	GetDItem(theWindow, OK, NIL, NIL, &Box);  /* Grab the display rect */
	InsetRect(&Box, -4, -4);		  /* Move out a bit */
	PenSize(3,3);				  /* Set the pen */
	FrameRoundRect(&Box, 16, 16);		/* Frame it */
	PenSize(1,1);				/* Fix the Pen */
	
}


-----------------------------------------------------


Now do :

   dlog = GetNewDialog(xxx, NIL, (WindowPtr) -1);
   Set_Hilite(dlog, USER_ITEM_NUMBER);


Nothing mystical here.  NIL is #defined to be 0L.

Shane Looker
Looker@um.cc.umich.edu

nopuklic@ndsuvax.UUCP (Blayne Puklich) (09/10/88)

In article <3316@homxc.UUCP> paco@homxc.UUCP (Herbert Throckmorton) writes:
>Here's a riddle:
>
>Default buttons in alerts get highlighted automatically.  IM vol.1
>mentions in the "Dialog Manager" section that one can highlight the
>default button in a dialog as well, but IM vol.1 doesn't mention how
>to do that deed, as far as I can tell.  One way would be to define
>the default button as a user item and write a routine to highlight
>it, like in the example in that same IM section.  Is there a better
>way, some flag or routine not mentioned in IM?
>
>thanks -
>
>        John Scoggins
>        att!homxc!paco

John:
	There really is no other way to do this except for what IM I-407
says near the top of the page.
	Another way to do this is get the Box for the dialog item
number 1 in the dialog's list, do the three calls as shown, and let it
fly.  Remember, though, that if you draw something over the RoundRect
around the button, you'll need to redraw the RoundRect.  The best way
to do this would be to have a filter for the whole process of drawing the
RoundRect around item 1.  The filter would only act upon update events
passed to it by ModalDialog for theDialog.  This probably sounds like
too much work, but try it out and it should work.
	Oh, before I forget, if you do use a filter for theDialog, you
have to intercept keyboard hits for Enter and Return if you want ModalDialog
to return to the caller when they are pressed.  That's more like what the
user guidelines say you should do.

||+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++||
||	Blayne Puklich			nopuklic@plains.NoDak.edu	   ||
||	NDSU Student ACM     		NU087763@NDSUVM1.bitnet		   ||
||	Chairperson		  North Dakota State University, Fargo, ND ||
||									   ||
||		"Everyone should have a Corvette, I think."		   ||
||	NOTE: If nopuklic@plains.NoDak.edu bounces, revert to		   ||
||		nopuklic@ndsuvax.EDU.					   ||
||-------------------------------------------------------------------------||