Welcome, Guest. Please login or register.

Author Topic: C - Menus and multiple selections...  (Read 8125 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline desivTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2009
  • Posts: 1269
    • Show only replies by desiv
C - Menus and multiple selections...
« on: April 11, 2023, 12:14:55 AM »
I am confused (not a surprise) on multiple selections...
Long story short, I found some code I wrote 32 years ago and have been playing with it.  It's 1.3 code, using DICE on my Amiga.
Working great, but I remembered a bug/programming issue I had seen back then and never addressed.

Basically, I have an "Options" menu with four items that are CHECKIT|CHECKED|MENUTOGGLE entries.

My program uses IntuitMessage GetMsg to read the Class and Code.

I then do switches on the Class and then on the MENUPICK (Code) and have case entries for each.
For troubleshooting, I added a "puts ("Sound");" in one and a "puts("Extra");" in the other in my case statements so I could see on the shell when each registers.
And as long as I do a normal select (RMB, to the Options menu, hover over one of them and let go) it works fine.  Checkmark goes away, my variables get set, I see the puts proper result in my shell.
I can do the same thing when I RMB to select the item while using the RMB to get to the menu option.

What doesn't work is if I am holding the RMB and then use the LMB to select one AND THEN another one (while still holding the RMB).
When I let go, only the first item has my variables get set and shows results of the puts command.
BUT, both items lose their checkmarks (or gain them...)
i.e. the checkmark shows up or goes away with each LMB click, but only the first one registers any activity in the case statement.

I know I'm doing something wrong, but not sure what...

Pointers on places I can look for help?  I'm not yet finding what I think I need in the books/PDFs/text files (Amiga C Manual) I have been looking at...

Thanx,

Amiga 1200 w/ ACA1230/28 - 4G CF, MAS Player, ext floppy, and 1084S.
Amiga 500 w/ 2M CHIP and 8M FAST RAM, DCTV, AEHD floppy, and 1084S.
Amiga 1000 w/ 4M FAST RAM, DUAL CF hard drives, external floppy.
 

Offline Joloo

Re: C - Menus and multiple selections...
« Reply #1 on: April 11, 2023, 05:56:22 PM »
Hi,

you have to read the mask "NextSelect" after having processed the current item.
For menu items that mutually exclude each other and when you bypass Intuition, i.e. no mouse button involved, you'll have to set them manually.

Pseudo code for processing menu items:

Code: [Select]
struct Window *wdhnd /*, *intuiwin */;
struct Message *msg;
ULONG intuiclass, itemid;
UWORD intuicode;
void *intuiaddr;
struct Menu *menu;
struct MenuItem *item;

while ( (msg = GetMsg( wdhnd->UserPort )) )
{
  intuiclass = (ULONG) ((struct IntuiMessage *) msg)->Class;
  intuicode = ((struct IntuiMessage *) msg)->Code;
  intuiaddr = ((struct IntuiMessage *) msg)->IAddress;
  /* intuiwin = ((struct IntuiMessage *) msg)->IDCMPWindow; */

  switch (intuiclass)
  {
    case IDCMP_MENUPICK:
      /* The old Intuition (OS1.2, OS1.3)
         require Forbid-state while modifying
         this Intuition field */
      Forbid();
      wdhnd->Flags |= WFLG_RMBTRAP;
      Permit();

      /* Process _ALL_ menu actions... */
      while (1)
      {
        if (intuicode == MENUNULL || intuicode == 0)
          break;
        item = ItemAddress( menu, intuicode);
        if (item)
        {
          .... do your thing here ...

          /* Start processing next selected menu item but
             watch out if the window was closed; without
             any safety query, an Enforcer Hit isn't very far */
          /* Insert here a check if the window is still open */

          ... your check here ...

          /* Set intuicode to zero if your window was shut down,
             then break, otherwise continue with processing menu items: */

          intuicode = item->NextSelect;
        }
        else
        {
          intuicode = 0;
        }
      }

      Forbid();
      wdhnd->Flags &= ~WFLG_RMBTRAP;
      Permit();

      break;

    case IDCMP_DISKINSERTED:
    case IDCMP_DISKREMOVED:
      break;
  }
  ....
}

Kind regards
 

Offline desivTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2009
  • Posts: 1269
    • Show only replies by desiv
Re: C - Menus and multiple selections...
« Reply #2 on: April 12, 2023, 04:47:56 AM »
Thanx!
Still poking and cleaning things up (and trying to fully understand it), but it's working.
DICE is giving me an "int-ptr conversion" warning on this line:
struct MenuItem* item = ItemAddress(&my_menu, code);
(maybe I should have split them up, but I was being lazy)
But I think that makes sense, and ItemAddress is an int...

Gotta get back into C...
It's been quite a while... Lots to refresh and learn...
Amiga 1200 w/ ACA1230/28 - 4G CF, MAS Player, ext floppy, and 1084S.
Amiga 500 w/ 2M CHIP and 8M FAST RAM, DCTV, AEHD floppy, and 1084S.
Amiga 1000 w/ 4M FAST RAM, DUAL CF hard drives, external floppy.
 

Offline Thomas

Re: C - Menus and multiple selections...
« Reply #3 on: April 12, 2023, 08:04:20 AM »
DICE is giving me an "int-ptr conversion" warning on this line:
struct MenuItem* item = ItemAddress(&my_menu, code);

Probably because it is. You should #include <proto/intuition.h> to let dcc know about the return type of the ItemAddress function.

Also put -proto on the dcc command line to get an error for each undeclared function.


Offline desivTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2009
  • Posts: 1269
    • Show only replies by desiv
Re: C - Menus and multiple selections...
« Reply #4 on: April 12, 2023, 03:58:45 PM »
Probably because it is. You should #include <proto/intuition.h> to let dcc know about the return type of the ItemAddress function.
Thanx, I haven't looked into prototyping yet...  It's on my list...
Also put -proto on the dcc command line to get an error for each undeclared function.

Oh, that just sounds like something asking for trouble and more work...  ;-)
Amiga 1200 w/ ACA1230/28 - 4G CF, MAS Player, ext floppy, and 1084S.
Amiga 500 w/ 2M CHIP and 8M FAST RAM, DCTV, AEHD floppy, and 1084S.
Amiga 1000 w/ 4M FAST RAM, DUAL CF hard drives, external floppy.
 

Offline Thomas

Re: C - Menus and multiple selections...
« Reply #5 on: April 12, 2023, 07:30:21 PM »
Thanx, I haven't looked into prototyping yet...

There is not much to look into. A prototype is just a repetition of the function declaration.

For example if this is your main program:

Code: [Select]
#include <stdio.h>

int main (int argc,char **argv)
{
printf ("Hello World\n");
return (0);
}

Then this is its prototype:

Code: [Select]
int main (int argc,char **argv);

You can make it shorter if you omit the argument names because for a prototype the compiler only needs the types, not the names.

Code: [Select]
int main (int,char **);

But it is much more readable with the names included, especially if there are multiple arguments of the same type.

And no, it does not ask for trouble, it helps you to avoid trouble.
« Last Edit: April 12, 2023, 07:34:07 PM by Thomas »
 

Offline desivTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2009
  • Posts: 1269
    • Show only replies by desiv
Re: C - Menus and multiple selections...
« Reply #6 on: April 12, 2023, 08:51:34 PM »
And no, it does not ask for trouble, it helps you to avoid trouble.
You are making it tough for me to justify being lazy. ;-)
And you are right. 
This question came up as I found a printout (just paper) from a solitaire game I wrote using DICE in 92 or so.  OCRd it and went about fixing the code, to get it to compile.
Finally got there, but one of the OCR errors that took me a bit to find, I would have found much quicker if I had prototyped that function, if I understand it correctly.

OCR just dropped an entry it couldn't read, so there was one fewer item than it really needed...

I'll make sure to add prototyping as a move forward... 
Thanx!
Amiga 1200 w/ ACA1230/28 - 4G CF, MAS Player, ext floppy, and 1084S.
Amiga 500 w/ 2M CHIP and 8M FAST RAM, DCTV, AEHD floppy, and 1084S.
Amiga 1000 w/ 4M FAST RAM, DUAL CF hard drives, external floppy.
 

Offline desivTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2009
  • Posts: 1269
    • Show only replies by desiv
Re: C - Menus and multiple selections...
« Reply #7 on: April 14, 2023, 05:04:26 AM »
I knew it was going to be trouble.. ;-)

I added:
#include <proto/intuition.h>

And now I get an error on compile, on my OpenScreen command?
DC1: "klondike1.11.c" L:233 Fatal:104 Pragma argument count conflict with prototype: OpenScreen

And that line just looks like this:
my_screen= (struct Screen *) OpenScreen( &my_new_screen );

As far as I can tell, there should only be one argument (not sure yet what a "pragma argument" is) for OpenScreen and it should be a pointer to a screen structure., I think.

Maybe the 1.3 includes don't like the proto/intuition.h that came with DICE (I looked at that .h file and it was pretty empty mostly pointing to other files, and as I don't fully understand prototyping and pragmas... ;-)   (obviously)
The DICE setup info had me copy over the NDK amiga13 includes, but that was into the amiga13 directory, and that didn't have any proto directory, so it's using the one that came with DICE.  Not sure if that matters.

But that's OK.  Just means I have more C to learn about... ;-)
Amiga 1200 w/ ACA1230/28 - 4G CF, MAS Player, ext floppy, and 1084S.
Amiga 500 w/ 2M CHIP and 8M FAST RAM, DCTV, AEHD floppy, and 1084S.
Amiga 1000 w/ 4M FAST RAM, DUAL CF hard drives, external floppy.
 

Offline Thomas

Re: C - Menus and multiple selections...
« Reply #8 on: April 14, 2023, 02:57:37 PM »
Maybe the 1.3 includes don't like the proto/intuition.h that came with DICE

Yes, you have to use a consistent set of include files. Have a look at https://eab.abime.net/showthread.php?t=68332, it instructs how to install Dice C correctly with the OS 3.9 NDK.

You can use the 3.9 NDK to write programs for 1.3 without issues. Just don't use functions which don't exist in OS 1.3.


Quote
(I looked at that .h file and it was pretty empty mostly pointing to other files, and as I don't fully understand prototyping and pragmas... ;-)   (obviously)

The proto/*.h files don't contain prototypes. They are (more or less) compiler-independent covers which include the necessary files to tell the compiler how to call OS functions in an efficient way.

The actual prototypes are in clib/*_protos.h

Pragmas tell the compiler how to populate registers with arguments. You might have heard that the OS expects arguments in registers while the C compiler usually puts them on the stack. The pragma instructions tell the compiler to use registers instead. But the #pragma syntax is compiler-specific, so it is not a good idea to include pragma/*.h files in your code. Rather use the proto/*.h file which should know which pragma files to use for each compiler.

It is rather safe to include clib/*.h instead of proto/*.h. It just creates a little overhead in each function call, because it first calls a C stub function which takes arguments from the stack and puts them in registers before it calls the actual OS function.

With the Dice C compiler you might run into situaitions when it tells you "subroutine is too complex to generate code for". In this case the simple solution is to use clib/ include instead of proto/.



Offline desivTopic starter

  • Hero Member
  • *****
  • Join Date: Oct 2009
  • Posts: 1269
    • Show only replies by desiv
Re: C - Menus and multiple selections...
« Reply #9 on: December 05, 2023, 11:40:27 PM »
I know, talking to myself... ;-)
I just figured that I should update this as I forgot to post on my status...
I got the multiple menu selections fully working, but I basically re-wrote the way it tried to do it...
I was doing switches on which menu tree to be in and then checked within each menu match as to which menu item was selected.  (Or something like that...  Don't have all the code in front of me...)
That wasn't working for me if you selected (LMB) multiple menu items during the same RMB action...

I took out the switches and changed it to IF statements that check for MENUNUM && MENUITEM and that fixed it.
I don't have that many menus and items, so the lack of efficiency shouldn't be a problem.  ;-)

If you want to see the (not great, but working) code, I put it (source and program) on Aminet, called Klondike92...  (92 being the year I stopped working on it)

Also, if you want to read a bit about my thought process while I was working on it (I don't recommend it; I'm not a blogger), I did keep a mini journal thing...
https://retrofiend.blogspot.com/2023/04/rescuing-my-old-commodore-amiga.html
Amiga 1200 w/ ACA1230/28 - 4G CF, MAS Player, ext floppy, and 1084S.
Amiga 500 w/ 2M CHIP and 8M FAST RAM, DCTV, AEHD floppy, and 1084S.
Amiga 1000 w/ 4M FAST RAM, DUAL CF hard drives, external floppy.