[comp.sys.amiga.tech] Beginner questions - on Gadgets and Menus

cmcmanis@stpeter.Eng.Sun.COM (Chuck McManis) (06/13/90)

In article <2232.26757d10@csc.anu.oz> myb100@csc.anu.oz writes:
>Question (1a): I have a window with two gadgets (TOGGLESELECT), each containing
>some text. When I select one of the gadgets, I'd like to change the text
>contained in this gadget. 

Ok, this is a pretty reasonable thing to want to do, but you will run
into an Intuition bug when you try it. This is that TOGGLESELECT gadgets
do not work like you would really like them too (ie they are rendered
incorrectly). Because of this, you have to do a little more work for
nice gadgets, but it isn't too tough. 

>What am I doing wrong ????? 
>        BeginRefresh(my_window);
>        RefreshGadgets(gadg1,my_window,NULL); 
>        EndRefresh(my_window);

This is what you are doing wrong. BeginRefresh/EndRefresh are _only_
called when you are sent a REFRESH message. So first off you can
eliminate those (and EndRefresh takes two parameters). Then
instead of using the old 1.1 function RefreshGadgets you will really
want to use the 1.2 function RefreshGList() which will refresh 
just the one gadget for you, and finally you will want to put an &
in front of gadg1 because you have declared a real gadget structure
and Refresh wants a pointer to a gadget structure. One of the nice
things about function prototypes are that they will catch these common
errors. 

>(1b) According to the C-manual, RefreshGadgets() starts at the specified
>     gadget, and works its way down the list. In my program, gadg1 is followed 
>     by NULL and gadg2 is followed by &gadg1. When I replace gadg1 by gadg2 in 
>     the above RefreshGadgets(), I get a guru #3, regardless of anything else 
>     I had before it....how come ?

Instead of RefreshGadgets use RefreshGList, its parameters are :
	RefreshGList(Gadgets, Window, Requester, NumGad);

So you would type RefreshGList(win, &gadg1, NULL, 1);

Consider the following program :
/* These define the gadget with three choices */

struct IntuiText options[3] = {
	{1, 0, JAM1, 0, 0, NULL, "Start", NULL},
	{1, 0, JAM1, 0, 0, NULL, "Stop", NULL},
	{2, 0, JAM1, 0, 0, NULL, "Pause", NULL}};

SHORT	box[] = {0,0, 0,0, 0,0, 0,0, 0,0}; /* Filled in later */

struct Border 	regular = {
	0, 0, 1, 0, JAM1, 5, &box[0], NULL},
		highlight = {
	0, 0, 2, 0, JAM1, 5, &box[0], NULL};

/* Notice are gadget is RELVERIFY meaning we only check it on GADGETUP
 * messages.
 */
struct Gadget choice = {
	NULL, 10, 10, 0, 0, GADGHIMAGE, GADGIMMEDIATE+RELVERIFY, 
	BOOLGADGET, (APTR) &regular, (APTR) &highlight, &options[0],
	NULL, 0x2344, NULL};

/* Clears the area defined by a gadget select box to the current
 * window background color 
 */
void
ClearGad(win, gad) 
	struct Window *win;	
	struct Gadget *gad;
{
	int	pen;

	pen = win->RPort->FgPen;
	SetAPen(win->RPort->BgPen);
	RectFill(win->RPort, gad->LeftEdge, gad->TopEdge,
	gad->LeftEdge+gad->Width-1, gad->TopEdge+gad->Height-1);
	SetAPen(win->RPort, pen);
}


main()
{
	int	curchoice = 0;
	...
	win = OpenWindow(&yourwindowstuff);
	if (!win) 
		cleanup();

	/* Fix up the "box" structure and gadget structure */
	choice.Width = TextWidth(win->RPort, "Pause", 5);
	choice.Height = win->RPort->TextHeight;
	box[4] = box[6] = choice.Width; 
	box[7] = box[9] = choice.Height;
	AddGList(win, &choice, -1, 1, NULL);
	/* May be optional, I can't remember if Add refreshes. */
	RefreshGList(choice, win, 0, 1);
	...
		case GADGETUP : 
		   if (gad->GadetID == 0x1244) {
			/* Remove the gadget */
			RemoveGList(win, &choice, 1);
			ClearGad(win, &choice);
			curchoice = (curchoice + 1) % 3;
			choice.IText = &options[curchoice];
			/* Force non selection */
			choice.Flags &= ~SELECTED;
			AddGList(win, &choice, -1, 1, NULL);
			RefreshGList(choice, win, 0, 1);
			break;
		   }
	...

What this example does :
	First off the gadget is defined and it uses IntuiText structures
	for its labels and a border to identify the outlines of the gadget.

	The flags GADGHIMAGE will cause the "highlight" border to be used
	when the gadget is about to be selected. Since both border structures
	share the same set of coordinates the border won't change shape but
	it will change color. The GADGIMMEDIATE+RELVERIFY flags will let us
	know when the gadget is selected and the mouse button released.
	(ie it's time to do something.)

	The initial part of the main program fixes up the border and gadget
	structure to take into account the Font that was associated with
	this window when it opened. This makes sure your gadgets will look
	nice even when the font changes. Of course other parts of your
	application may want to check too, this is just an example. Once
	"adjusted" the gadget is added to the window's list of gadgets.

	Finally, when a message is received that this gadget was selected,
	the gadget is removed from the window's list, modified with the 
	new text value and then re-added and refreshed. There is a small
	routine to clear the window to the background color when this 
	happens. 
	
	Voila' you now have a gadget that every time you click on it, it
	changes its label.

>(2) I've seen a neat sub-menu used in some programs, like VLT, where the 
>    sub-menu items were in a 4x3 grid, i.e. 12 items, 3 to each of 4 lines.
>    Does anyone have some example code they could show me as to how this is 
>    done ? 

In the Menu chapter of the ROM Kernel Manual you will notice that MenuItem
structures have a TopEdge and a LeftEdge. Ever wonder what would happen
if two MenuItems had the same TopEdge value but different LeftEdge values?
Can you guess?


--
--Chuck McManis						    Sun Microsystems
uucp: {anywhere}!sun!cmcmanis   BIX: <none>   Internet: cmcmanis@Eng.Sun.COM
These opinions are my own and no one elses, but you knew that didn't you.
"I tell you this parrot is bleeding deceased!"

myb100@csc.anu.oz (06/13/90)

G'day y'all !

After being such a great help with my last question, I thought I'd push
my luck and ask two (3?) this time. :-) Both are about C, the first is probably
simple :-) ? , the second probably a bit trickier.

Question (1a): I have a window with two gadgets (TOGGLESELECT), each containing
some text. When I select one of the gadgets, I'd like to change the text
contained in this gadget. Below is an excerpt. This almost makes sense, but...
I realise that I've probably crossed my &s with my .s and ->s, but I'm now 
going nuts. 

What am I doing wrong ????? 

[...]
UBYTE gad1str[]="G1";
struct IntuiText text1 {...}
struct Gadget gadg1 {...}

[ Gadget 1 has been selected..]

        {
        printf("Reporting: 1 down\n");    /* No problem here */

        strcpy(gad1str,"1g");       /* what I'd like to have in the gadget.*/
        text1.IText=&gad1str[0];    /* Is this the right                   */
        gadg1.GadgetText=&text1;    /* incantation ? It looks right...but  */
                                    /* who am I to say :-) ?               */

        BeginRefresh(my_window);
        RefreshGadgets(gadg1,my_window,NULL); 
        EndRefresh(my_window);
        }

(1b) According to the C-manual, RefreshGadgets() starts at the specified
     gadget, and works its way down the list. In my program, gadg1 is followed 
     by NULL and gadg2 is followed by &gadg1. When I replace gadg1 by gadg2 in 
     the above RefreshGadgets(), I get a guru #3, regardless of anything else 
     I had before it....how come ?


(2) I've seen a neat sub-menu used in some programs, like VLT, where the 
    sub-menu items were in a 4x3 grid, i.e. 12 items, 3 to each of 4 lines.
    Does anyone have some example code they could show me as to how this is 
    done ? 

Any help on either item will be *greatly* appreciated. [E-mail or Post..] 
I support any calls for more example code in the Public Domain ! Us beginners
with Intuition from C would appreciate it ! 

ANTICI..(tanx heeps)..PATION... :-)

===============================================================================
 Markus Buchhorn                                           ///  | This space
 Mt Stromlo and Siding Spring Observatories, Canberra     ///   | 
 PMB Weston Ck. P.O. A.C.T. 2611, Australia           \\\///    | intentionally
 markus@mso.anu.edu.au  -or- nssdca::psi%mssso::markus \XX/     | left blank
-------------------------------------------------------------------------------
 Phone donations: AUS-6-249-0280 Flames: alt.dev.null  Disclaimer: standard
===============================================================================