Composite BOOPSI gadget input handling

7 posts / 0 new
Last post
trixie
trixie's picture
Offline
Last seen: 7 months 3 weeks ago
Joined: 2011-02-03 13:58
Composite BOOPSI gadget input handling

I'm experimenting with what the Amiga RKRM / Dev Wiki refer to as "composite gadgets", i.e. gadget classes composed of other BOOPSI gadgets. My experimental gadget is actually a layout consisting of a few button.gadget objects; basically it's a kind of a toolbar for input selection.

As far as I understand it, I'll need to implement a GM_HANDLEINPUT routine, in which I'll process the input and identify the actual button pressed. After that, I need to inform Intuition about the button choice, preferably returning a code that the programmer will be able to retrieve in his WM_HANDLEINPUT event loop.

How would I go about accomplishing that? Does the following bit of RKRM documentation (Intuition / BOOPSI Gadgets chapter) provide the key?

For both GM_GOACTIVE and GM_HANDLEINPUT, the gadget can bitwise-OR any of these "go inactive" return values with GMR_VERIFY. The GMR_VERIFY flag tells Intuition to send a GADGETUP IntuiMessage to the gadget's window. If the gadget uses GMR_VERIFY, it has to supply a value for the IntuiMessage.Code field. It does this by passing a value in the gpInput.gpi_Termination field.

General advice as well as code examples will be greatly appreciated.

thomas
thomas's picture
Offline
Last seen: 1 week 5 days ago
Joined: 2011-05-16 14:23
Re: Composite BOOPSI gadget input handling

Actually you don't need to care. You just forward the GM_HANDLEINPUT message to the active member and return to Intuition what the member returned to you. The button class takes care of gpi_Termination and GMR_VERIFY. Just make sure that you set GA_RelVerify for each button.

During GM_HITTEST you determine the active member. GM_GOACTIVE and GM_GOINACTIVE are forwarded to the active member just like GM_HANDLEINPUT.

In each message you forward to one of your members, you have to adjust the mouse coordinates so that they are relative to the member and not relative to the group.

If I am not mistaken you have access to the Enhancer source code (I haven't). There should be a time.gadget which consists of a group (timegclass) with two members (timestrgclass and arrowgclass). It's a special kind of group as it always contains exactly two members and has a fixed layout (the arrows are always as wide as they are high, the string gadget takes the rest). But it demonstrates the message forwarding.

TSK
TSK's picture
Offline
Last seen: 1 year 2 months ago
Joined: 2011-06-28 02:06
Re: Composite BOOPSI gadget input handling

@Trixie, @thomas

Could you two make an example code to public of how to do it ?

thomas
thomas's picture
Offline
Last seen: 1 week 5 days ago
Joined: 2011-05-16 14:23
Re: Composite BOOPSI gadget input handling

Here is a more generic example: http://thomas-rapp.homepage.t-online.de/examples/groupgad.c

trixie
trixie's picture
Offline
Last seen: 7 months 3 weeks ago
Joined: 2011-02-03 13:58
Re: Composite BOOPSI gadget input handling

@Thomas

Thank you very much - helpful as usual! I do have access to the Enhancer Software repository, and I'll have a look at the time.gadget as well as your generic example.

AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2

thomas
thomas's picture
Offline
Last seen: 1 week 5 days ago
Joined: 2011-05-16 14:23
Re: Composite BOOPSI gadget input handling

Small update to the source code. It now compiles without warnings with GCC/OS4 and I added a small space around the toolbar to make it look a bit nicer.

broadblues
broadblues's picture
Offline
Last seen: 4 years 10 months ago
Joined: 2012-05-02 21:48
Re: Composite BOOPSI gadget input handling

My calandar gadget in AOrganiser works exactly like this.

http://www.broad.ology.org.uk/docs/amiga/aorganiser/#mainwindow

It's "simply" a grid of button.gadgets objects. As Thomas said you just direct Handle input to the active button.

The whole code is abit long to share here but here is a couple of relavent snippets

  1. case GM_GOACTIVE:
  2. case GM_GOINACTIVE:
  3. case GM_HANDLEINPUT:
  4.  
  5. if(cd->cd_ActiveMember) retval = (APTR)doHandleInput(o,cd->cd_ActiveMember,msg);
  6. else retval= (APTR)GMR_NOREUSE;
  7. break;
  8.  
  9. case GM_HITTEST:
  10. case GM_HELPTEST:
  11. MouseX = ((struct gpHitTest *)msg)->gpht_Mouse.X;
  12. MouseY = ((struct gpHitTest *)msg)->gpht_Mouse.Y;
  13.  
  14. retval = (APTR)doGroupHitTest(cl,o,msg);
  15. break;
  1. ULONG GHIT =0;
  2. ULONG GIDHIT = 0;
  3.  
  4. ULONG
  5. doGroupHitTest(Class *cl, Object * o, Msg msg){
  6.  
  7. int i;
  8. ULONG result = 0;
  9. WORD x,y;
  10.  
  11. struct CalData *cd = (struct CalData *)INST_DATA(cl,o);
  12.  
  13. /* get absolute mouse coords */
  14.  
  15. x = ((struct gpHitTest *)msg)->gpht_Mouse.X + ((struct Gadget *)o)->LeftEdge;
  16. y = ((struct gpHitTest *)msg)->gpht_Mouse.Y + ((struct Gadget *)o)->TopEdge;
  17.  
  18. /* for each active button adjust the hittest and pass on the message */
  19. struct gpHitTest myMsg;
  20.  
  21. myMsg.MethodID = msg->MethodID;
  22. myMsg.gpht_GInfo = ((struct gpHitTest *)msg)->gpht_GInfo;
  23.  
  24. for(i = 0; i < 31; i ++){
  25. if(cd->cd_Buttons[i].b_Active){
  26.  
  27. WORD Left,Top,Width,Height;
  28. WORD X,Y;
  29. Left = ((struct Gadget *)cd->cd_Buttons[i].b_Button)->LeftEdge;
  30. Top = ((struct Gadget *)cd->cd_Buttons[i].b_Button)->TopEdge;
  31. Width = ((struct Gadget *)cd->cd_Buttons[i].b_Button)->Width;
  32. Height = ((struct Gadget *)cd->cd_Buttons[i].b_Button)->Height;
  33. X = x - Left;
  34. Y = y - Top;
  35. if( (X >= 0) && (X<=Width) && (Y>=0) && (Y<=Height)) {
  36.  
  37. myMsg.gpht_Mouse.X = X;
  38. myMsg.gpht_Mouse.Y = Y;
  39.  
  40. result = DoMethodA(cd->cd_Buttons[i].b_Button,(Msg )&myMsg);
  41. if (result == GMR_GADGETHIT){
  42. cd->cd_ActiveMember = cd->cd_Buttons[i].b_Button;
  43. GHIT = result;
  44. GIDHIT =((struct Gadget*) cd->cd_Buttons[i].b_Button)->GadgetID;
  45. cd->cd_Date = GIDHIT;
  46. return(result);
  47. }
  48. }
  49. }
  50. }
  51. // cd->cd_ActiveMember = NULL;
  52. GHIT = 0;
  53. GIDHIT = 0;
  54. return (0);
  55. }

I'm a strong advocate of building complex gadgets from less complex ones , rather than inventing the whole car from scratch, you can at least use the wheels and gears already in existance....

I also use the concept for SketchBlock Pro's new "wrapping toolbar"

Log in or register to post comments