[comp.sys.amiga.programmer] Prop gadgets and FOLLOWMOUSE

johnhlee@fulla.cs.cornell.edu (John H. Lee) (02/09/91)

I've been having a problem with prop gadgets and FOLLOWMOUSE.  It seems
that the MOUSEMOVE IDCMP messages I get have the IAddress set to the
window containing the gadget rather than the gadget itself.  The GADGETDOWN
and GADGETUP IDCMP messages have the IAddress set properly, however.
I don't have REPORTMOUSE set for the window, so I'm not getting MOUSEMOVEs
for the window itself.

This wouldn't be a problem except when trying to use multiple prop gadgets
with active tracking (i.e., update an on-screen value as a prop gadget is
"thumbed".)  Currently, I set a variable when I receive a GADGETDOWN on a
prop gadget, use the variable instead of the IAddress field for MOUSEMOVES,
and reset the variable on a GADGETUP for the prop gadget.  It works, but
not as elegant.

Am I doing something wrong, or is this an old bug?

-------------------------------------------------------------------------------
The DiskDoctor threatens the crew!  Next time on AmigaDos: The Next Generation.
	John Lee		Internet: johnhlee@cs.cornell.edu
The above opinions of those of the user, and not of this machine.

hoffmann@acl.kodak.com (marty hoffmann) (02/09/91)

John Lee asked about using FOLLOWMOUSE to track a proportional gadget.
The fact that the messages related to FOLLOWMOUSE point to the window
and not the gadget is probably not a bug.

If I want to update screen information (like a counter) while the user
slides a proportional gadget, I create the gadget with GADGIMMEDIATE 
and RELVERIFY.  When I get a GADGETDOWN message for the gadget, I 
enter a tight loop, reading the pot values directly from the PropInfo
structure and updating the screen accordingly.  The exit condition for
the loop is receiving the corresponding GADGETUP.  When I exit the
loop, I read the pot values and update the screen one last time.

I never use FOLLOWMOUSE in this respect.

The above idea works even if the user clicks on the gadget without 
dragging it.

						Marty Hoffmann 

forgeas@swinjm.UUCP (Jean-Michel Forgeas) (02/11/91)

In article <51792@cornell.UUCP>, John H. Lee writes:

> I've been having a problem with prop gadgets and FOLLOWMOUSE.  It seems
> that the MOUSEMOVE IDCMP messages I get have the IAddress set to the
> window containing the gadget rather than the gadget itself.

Yes this is  problem for me too.
You could test your list of props looking for the SELECTED flag:

if (FlagIsSet( Prop1->Flags, SELECTED )) ...;
else if (FlagIsSet( Prop2->Flags, SELECTED )) ...;
...
This works for me.

    Jean-Michel
--
                                     \___/
Jean-Michel Forgeas                   \-/
cbmvax!cbmehq!cbmfra!swinjm!forgeas    |    The Software Winery
                                      -^-
                           And, where is the universe ?

peter@cbmvax.commodore.com (Peter Cherna) (02/12/91)

In article <51792@cornell.UUCP> johnhlee@cs.cornell.edu (John H. Lee) writes:
>
>I've been having a problem with prop gadgets and FOLLOWMOUSE.  It seems
>that the MOUSEMOVE IDCMP messages I get have the IAddress set to the
>window containing the gadget rather than the gadget itself.

This is true, and it's doubtful we could ever change this.  However,
it's easy to know which gadget is in use.  If you get a GADGETDOWN
for your prop. gadget, then all MOUSEMOVEs are from this gadget until
you hear the corresponding GADGETUP.  The Rom Kernel Manual discusses
this.

>	John Lee		Internet: johnhlee@cs.cornell.edu

     Peter
--
     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.commodore.com
My opinions do not necessarily represent the opinions of my employer.
"Oh, PIN-compatible!  I thought you wanted me to make it IN-compatible!"

peter@cbmvax.commodore.com (Peter Cherna) (02/12/91)

In article <1991Feb8.213305.15745@ssd.kodak.com> hoffmann@acl.kodak.com (marty hoffmann) writes:
>If I want to update screen information (like a counter) while the user
>slides a proportional gadget, I create the gadget with GADGIMMEDIATE 
>and RELVERIFY.  When I get a GADGETDOWN message for the gadget, I 
>enter a tight loop, reading the pot values directly from the PropInfo
>structure and updating the screen accordingly.

Aaaak.  Why do you use a tight loop?  That's equivalent to busy
waiting, which is bad in a multitasking environment.  You should
use FOLLOWMOUSE and wait for MOUSEMOVE events.  Only update your
view of the world when you get MOUSEMOVEs.  Some people refresh
every INTUITICK instead of using MOUSEMOVE, but I recommend
MOUSEMOVE.

Here's an additional tip:  if your prop gadget represents a number
(say) from 1 to 10, then you'll get several MOUSEMOVEs for each
level.  Make sure the level actually changes before refreshing
whatever changes (eg. a list moves).

>						Marty Hoffmann 

     Peter
--
     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.commodore.com
My opinions do not necessarily represent the opinions of my employer.
"Oh, PIN-compatible!  I thought you wanted me to make it IN-compatible!"

hoffmann@acl.kodak.com (marty hoffmann) (02/12/91)

Bless me father, for I have sinned.   My last confession was...

Yes, I am guilty of reading the pot values in a tight loop.  I was
so excited the first time I got this to work that I never even 
thought about the fact that I was stealing CPU cycles 
(like Homer steals cable).

For my pennance, I'm going to go home and re-read the Intuition manual.

How embarrassing :^(

							Marty Hoffmann

peter@cbmvax.commodore.com (Peter Cherna) (02/12/91)

In article <18a9ae90.ARN0d71@swinjm.UUCP> forgeas@swinjm.UUCP (Jean-Michel Forgeas) writes:
>In article <51792@cornell.UUCP>, John H. Lee writes:
>
>> I've been having a problem with prop gadgets and FOLLOWMOUSE.  It seems
>> that the MOUSEMOVE IDCMP messages I get have the IAddress set to the
>> window containing the gadget rather than the gadget itself.

This is a bug that many people reported, (including myself, right
when I arrived at Commodore).  There are two reasons why it won't
change:

1.  Risk of breaking some software that expects to find the window-pointer
    there.
2.  Because it's easy to get around the problem, which you MUST do to
    run under 1.x and 2.0x.
>
>Yes this is  problem for me too.
>You could test your list of props looking for the SELECTED flag:

It's more efficient to remember the pointer to the last gadget you
saw a GADGETDOWN for.

>This works for me.
>
>    Jean-Michel

     Peter
--
     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.commodore.com
My opinions do not necessarily represent the opinions of my employer.
"Oh, PIN-compatible!  I thought you wanted me to make it IN-compatible!"

dgg@ksr.com (David Grubbs) (02/13/91)

Why all the text descriptions?  If you have an efficient algorithm, then
include it.  An English description of a C program is useful only to a CompSci
teacher, not the students.
--
David G. Grubbs				Kendall Square Research Corp.
{harvard,uunet,world}!ksr!dgg		dgg@ksr.com

johnhlee@viola.cs.cornell.edu (John H. Lee) (02/15/91)

In article <DGG.91Feb12135350@kaos.ksr.com> dgg@ksr.com (David Grubbs) writes:
>Why all the text descriptions?  If you have an efficient algorithm, then
>include it.  An English description of a C program is useful only to a CompSci
>teacher, not the students.

Uh oh!  I hope that English isn't your second language, with <insert favorite
programming language here> as your first!  :-)

I thought the concept was rather simple, but I have enclosed some excerpts
from my test program that demonstrate the work-around I came up with.
(BTW, the idea behind the program was to demonstrate the ability to design
and create prop gadgets that work like the sliders in DECwindows or the
VAXstation VWS windowing system.  The numerical value of the slider is
displayed directly above the knob and is updated and moved with the knob
as the user drags the knob.)


[...]
#define	G_PROP1		1
#define	G_PROP2		2

#define	GADGET(g)	((struct Gadget *)(g))

[...]

static struct Gadget
		prop2 = {
	NULL,
	10, 25, 200, 12,
	GADGHNONE | GADGIMAGE,
	GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY,
	PROPGADGET,
	(APTR)&thumb2_img,
	NULL,
	NULL,
	0L,
	(APTR)&prop2_info,
	G_PROP2,
	(APTR)&pv2_info
},
		prop1 = {
	&prop2,
	10, 55, 200, 12,
	GADGHNONE | GADGIMAGE,
	GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY,
	PROPGADGET,
	(APTR)&thumb1_img,
	NULL,
	NULL,
	0L,
	(APTR)&prop1_info,
	G_PROP1,
	(APTR)&pv1_info
};


static struct NewWindow	windowdata = {
	10, 10,
	300, 70,
	-1, -1,
	CLOSEWINDOW | GADGETUP | GADGETDOWN | MOUSEMOVE,
	WINDOWCLOSE | WINDOWDRAG | SMART_REFRESH | ACTIVATE,
	&prop1,
	NULL,
	"Prop Gadget Test",
	NULL,
	NULL,
	0, 0, 0, 0,
	WBENCHSCREEN
};



static struct Window	*window = NULL;



void	CloseAll(void),
	FatalError(char *),
	UpdateProp(struct Gadget *, struct Window *);




main()
{
BOOL	notDone = TRUE;
ULONG	sigm_ctlc = SIGBREAKF_CTRL_C,
	sigm_window,
	sigs;
struct IntuiMessage	*msg;
ULONG	class;
APTR	iaddr;
struct Gadget	*g_iaddr = NULL;


	if ((IntuitionBase = (struct IntuitionBase *)
		OpenLibrary("intuition.library", 0L)) == NULL)
		FatalError("Unable to open intuition.library");

	if ((window = OpenWindow(&windowdata)) == NULL)
		FatalError("Unable to open window");
	sigm_window = 1L << window->UserPort->mp_SigBit;

	UpdateProp(&prop1, window);
	UpdateProp(&prop2, window);

	while (notDone) {
	    sigs = Wait(sigm_ctlc | sigm_window);

	    if (sigs & sigm_ctlc) notDone = FALSE;

	    else {
		while (msg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
		    class = msg->Class;
		    iaddr = msg->IAddress;
		    ReplyMsg((struct Message *)msg);

		    switch (class) {
		      case CLOSEWINDOW:
			notDone = FALSE;
			break;
		      case GADGETDOWN:
			if (GADGET(iaddr)->GadgetType == PROPGADGET)
				g_iaddr = GADGET(iaddr);
			break;
		      case GADGETUP:
			if ((g_iaddr != NULL) && (g_iaddr == GADGET(iaddr))) {
				UpdateProp(g_iaddr, window);
				g_iaddr = NULL;
			} /* if */
			break;
		      case MOUSEMOVE:
			if (g_iaddr != NULL) UpdateProp(g_iaddr, window);
			break;
		      default:
			break;
		    } /* case */
		} /* while */
	    } /* else */
	} /* while */

	CloseAll();

	exit(0);
} /* main */

[...]

-------------------------------------------------------------------------------
The DiskDoctor threatens the crew!  Next time on AmigaDos: The Next Generation.
	John Lee		Internet: johnhlee@cs.cornell.edu
The above opinions of those of the user, and not of this machine.