[comp.sys.amiga] Gadgets.

val@wsccs.UUCP (Val Kartchner) (09/15/88)

     I'm having a problem with some gadgets on the Amiga.  Here are the
     structure declarations:

-----------------------------------------------------------------------------
/* Window and screen stuff */
#define SCREEN_WIDTH	640
#ifndef STDSCREENHEIGHT
#define STDSCREENHEIGHT 400
#endif

/* Colors */
#define BACKGROUND	0
#define NORMAL		1
#define	HIGHLIGHT	2
#define	GHOSTED		3
#define	BORDER		NORMAL
#define	TEXT		NORMAL

/* Text stuff */
#define TEXT_LEFT	5
#define	TEXT_HEIGHT	8
#define	TEXT_WIDTH	8

unsigned short larrow_bitmap[] =
 {
  0x0000,
  0x1000,
  0x3000,
  0x7e00,
  0xfe00,
  0x7e00,
  0x3000,
  0x1000
 };
unsigned short rarrow_bitmap[] =
 {
  0x0000,
  0x0800,
  0x0c00,
  0x7e00,
  0x7f00,
  0x7e00,
  0x0c00,
  0x0800
 };
struct Image larrow_image = { 0,0, 8,8,1, larrow_bitmap,0x2,0x0,NULL };
struct Image larrow_comp  = { 0,0, 8,8,1, larrow_bitmap,0x1,0x0,NULL };
struct Image rarrow_image = { 0,0, 8,8,1, rarrow_bitmap,0x2,0x0,NULL };
struct Image rarrow_comp  = { 0,0, 8,8,1, rarrow_bitmap,0x1,0x0,NULL };

struct PropInfo volpropinfo =
 {
  AUTOKNOB | FREEHORIZ, 1,1, 0xffff/10,0xffff/10,
  0,0,0,0,0,0		/* Intuition inits these */
 };

char GadgBName[11],GadgBVolume_I[4]="1";

struct Gadget GadgVolume_RA =
 {
  NULL,
  TEXT_LEFT+48*TEXT_WIDTH,15-TEXT_HEIGHT+1,TEXT_WIDTH*1,TEXT_HEIGHT,
  GADGIMAGE | GADGHIMAGE,GADGIMMEDIATE,BOOLGADGET,
  (APTR)&rarrow_image,(APTR)&rarrow_comp,NULL,NULL,
  NULL,
  NULL,NULL		/* User Info */
 };
struct Gadget GadgVolume_P =
 {
  &GadgVolume_RA,
  TEXT_LEFT+35*TEXT_WIDTH,15-TEXT_HEIGHT+1,100,TEXT_HEIGHT,
  GADGHNONE,RELVERIFY,PROPGADGET,
  NULL,NULL,NULL,NULL,
  (APTR)&volpropinfo,
  NULL,NULL
 };
struct Gadget GadgVolume_LA =
 {
  &GadgVolume_P,
  TEXT_LEFT+34*TEXT_WIDTH,15-TEXT_HEIGHT+1,TEXT_WIDTH*1,TEXT_HEIGHT,
  GADGIMAGE | GADGHIMAGE,GADGIMMEDIATE,BOOLGADGET,
  (APTR)&larrow_image,(APTR)&larrow_comp,NULL,NULL,
  NULL,
  NULL,NULL		/* User Info */
 };
-----------------------------------------------------------------------------

     I have other gadget declarations also.  When I compile this with
     Lattice (and link it), it crashes immediately.  If I remove
     GadgVolume_P from the list, all of the gadgets work correctly except
     GadgVolume_LA and GadgVolume_RA which don't complement.  I've tried
     GADGHCOMP and alternate images, and they still don't change, but I do
     recieve GADGETDOWN events.  When I do an AddGadget(w,&GadgVolume_P,-1)
     [Where w is a (Window *)], the machine immediately crashes with Address
     Error, Illegal Instruction, 1010 opcode, or 1111 opcode.

     When I compile it with the latest version of Manx Aztec C (and link
     it), *NONE* of the gadgets even show up.  (Fastmem was turned off.)
     Once it recieves a left mouse button event, even the menus stop
     working.

     I'm using midi.library, and all of the libraries have been opened
     successfully.   Would someone please help me with this?

			Thanks in advance,
				-=:[ VAL ]:=-
-- 
----  /\  ----------------------------------------------------------------
     /\/\  .    /\     |  Val Kartchner  {UT@WSC}  |  'vi' must go, this
    /    \/ \/\/  \    |  #include <disclaimer.h>  |  is non-negotiable.
===/ U i n T e c h \===!ihnp4!utah-cs!utah-gr!uplherc!sp7040!obie!val=====  

sie@fulcrum.bt.co.uk (Simon Raybould) (12/20/89)

I am trying to make two boolean gadgets mutually exclusive of each other
The code below works ish. When the first gadget is selected, it is highlighted.
When the second gadget is selected, it is highlighted and the first should
be un-highlighted as a toggle where one or the other is highlighted, but
not both. 

At the moment, the second click on a gadget cause it to change its colours.
Any help on this would be apreciated.

I believe that to do this, the gadgets have to be removed, altered and then
re-added to the window, is this true?

The code below is taken from a program and is from the code for handling
the GADGETUP message. PURCHASE and REPAY are both gadget structures.

			} else if(Message->IAddress == (APTR)&REPAY) {
				PR = PR_REPAY;
				ip = RemoveGadget(AddWindow, &PURCHASE);
				ir = RemoveGadget(AddWindow, &REPAY);
				REPAY.Flags |= SELECTED;
				PURCHASE.Flags &= ~SELECTED;
				AddGadget(AddWindow, &PURCHASE, ip);
				AddGadget(AddWindow, &REPAY, ir);
				RefreshGadgets(&REPAY, AddWindow, NULL);
			} else if(Message->IAddress == (APTR)&PURCHASE) {
				PR = PR_PURCHASE;
				ir = RemoveGadget(AddWindow, &REPAY);
				ip = RemoveGadget(AddWindow, &PURCHASE);
				PURCHASE.Flags |= SELECTED;
				REPAY.Flags &= ~SELECTED;
				AddGadget(AddWindow, &REPAY, ir);
				AddGadget(AddWindow, &PURCHASE, ip);
				RefreshGadgets(&REPAY, AddWindow, NULL);
			}

many thanks.

S.J.R

+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+-=-=-=-=-=-=-=-+-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|   Simon Raybould                |  BT Fulcrum   | Are all your pets called  |
|   path : sie@fulcrum.bt.co.uk   |  Birmingham   |      Eric ??? - Python    |
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+-=-=-=-=-=-=-=-+-=-=-=-=-=-=-=-=-=-=-=-=-=-+

cmcmanis@stpeter.Sun.COM (Chuck McManis) (12/23/89)

In article <1989Dec20.100023.6376@cat.fulcrum.bt.co.uk> (Simon Raybould) writes:
> I am trying to make two boolean gadgets mutually exclusive of each
> other The code below works ish. When the first gadget is selected, it
> is highlighted.  When the second gadget is selected, it is highlighted
> and the first should be un-highlighted as a toggle where one or the
> other is highlighted, but not both.

OK there are a few things that will help you out considerably. The first
is to set up your gadgets correctly. The flags you will need are, 
GADGIMMEDIATE, and GADGHCOMP. The gadget *must* be of type Image or
not have any IntuiText in it. The reason for the restrictions are that
Intuition has a tough time figuring out how to render multiple graphic
items such as a gadget with Text and a border(s) structure. The other
thing you need to do is stop using the RefreshGadgets()/AddGadgets() calls
and use RefreshGList/AddGList ones in 1.2. The latest ROM Kernel Manual
AutoDocs and Includes has the documentation for them in them. 

>I believe that to do this, the gadgets have to be removed, altered and then
>re-added to the window, is this true?

Not necessarily, but you can if you choose to.

>The code below is taken from a program and is from the code for handling
>the GADGETUP message. PURCHASE and REPAY are both gadget structures.

Ok and now a step by step analysis :

>			} else if(Message->IAddress == (APTR)&REPAY) {
	This is not the optimal way to identify gadgets, using their 
	GadgetID is much better. When you create the gadget, set the
	ID to something useful like g->GadgetID = REPAY_GADGET; Then 
	in your code you can use something like :
	case GADGETUP :
		thisgad = (struct Gadget *)(Message->IAddress);
		switch (thisgad->GadgetID) {
			case REPAY_GADGET : 
				... etc ...

>				PR = PR_REPAY;
>				ip = RemoveGadget(AddWindow, &PURCHASE);
>				ir = RemoveGadget(AddWindow, &REPAY);

	This will work, but add the following code :
		PURCHASE.NextGadget = &REPAY;
		REPAY.NextGadget = NULL;

>				REPAY.Flags |= SELECTED;
>				PURCHASE.Flags &= ~SELECTED;

		This is fine.
>				AddGadget(AddWindow, &PURCHASE, ip);
>				AddGadget(AddWindow, &REPAY, ir);
		Now instead of this, use the code :
			AddGlist(AddWindow, &PURCHASE, -1, 2, NULL);
		This will add your two gadgets back in one call.

>				RefreshGadgets(&REPAY, AddWindow, NULL);

		Now instead of the RefreshGadgets call use this instead :
			RefreshGList(&PURCHASE, AddWindow, NULL, 2);

>			} else if(Message->IAddress == (APTR)&PURCHASE) {
>				PR = PR_PURCHASE;
>				ir = RemoveGadget(AddWindow, &REPAY);
>				ip = RemoveGadget(AddWindow, &PURCHASE);
>				PURCHASE.Flags |= SELECTED;
>				REPAY.Flags &= ~SELECTED;
>				AddGadget(AddWindow, &REPAY, ir);
>				AddGadget(AddWindow, &PURCHASE, ip);
>				RefreshGadgets(&REPAY, AddWindow, NULL);
>			}

Clearly the same comments apply here as well. 

Now another way for this to work is to maintain a pointer to the currently
selected gadget, of a mutually excluded gadget list. A pointer to this pointer
is stored in the UserData field of the gadgets that are excluded. So lets
say you had three gadgets {Foo, Bar, and Bletch} that were all mutually
exluded. Declare a pointer "FBBPointer" or something and set it up to
Point at the initially selected gadget. Now when ever you see a gadget
select you can process it as follows :
	case GADGETUP :
		g = (struct Gadget *)(Message->IAddress);
		if (g->Flags & MUTUALEXCLUDE) {
			/* Find the currently selected gadget of the group */
			g1 = *((struct Gadget **)(g->UserData));
			if (g != g1) { /* Simple optimization */
				/* Deselect the current one */
				g1->Flags &= ~SELECTED;
				/* Select the one the user clicked on */
				g->Flags |= SELECTED;
				RefreshGlist(g, AddWindow, NULL, 1);
				RefreshGlist(g1, AddWindow, NULL, 1);
				*((struct Gadget **)(g->UserData)) = g;
			}
		}
		break;

This method has a couple of advantages. One, this same code can handle
lots of different groups of excluded gadgets, and two the variable
you use to keep the selected gadget pointer can be used by your
program as a state variable. And finally, there isn't any reason why
you have to limit yourself to a a pointer to a gadget. Let's say you
were designing a backup program and had two gadgets "DF0:" and "DF1:"
You could create a structure that looked like this :
	struct activedrive {
		struct Gadget *ActiveGadget;
		char	      *DriveName;
	} *FooBarBletch;

Now you use the above code, which would keep FooBarBletch pointing at
the correct gadget, and when it came time to open the disk that was
selected you could use something like :
	Lock(FooBarBletch->DriveName, ACCESS_WRITE);
Because the FooBarBletch pointer would already have the pointer to the
appropriate gadget in it.

Just some ideas ....

--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@Eng.Sun.COM
These opinions are my own and no one elses, but you knew that didn't you.
"If it didn't have bones in it, it wouldn't be crunchy now would it?!"

jlabelle@lynx.northeastern.edu (09/06/90)

While reading about creating a sprite data structure, I have become confused
by exactly making one with hex code. i.e. 0x1600,0x200. How the heck am I 
suppose to know what hex code creates what color pixel. I am not
familiar with Hex at all. How can I translate this? Is there a program that 
takes sprite objects and creates a data structure that can be used for C?
By the way what does 0x1600,0x2200 create. How can I translate this stuff,
for future needs?? Or do I? 

BTW, CATS: When do you guys plan to have 2.0 ROM Kernal reference manual out
for sale. I hate not knowing that there is a feature which should be utilized.
And, is 2.0 officially out?? If it is, will I get an upgrade on chip?
Can I get a specific book that teaches me 68030 Assembly language with the 
Amiga 3000 in the near future??

Please send any comments or donations to jlabelle@lynx.northeastern.edu.

-----

Spontaneous Gratification -- That's all I ask for!
Disclaimer: Why won't this work?