home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / dev / gui / mui / developer / c / examples / class3.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  8KB  |  299 lines

  1. #include "demo.h"
  2.  
  3.  
  4. /***************************************************************************/
  5. /* Here is the beginning of our simple new class...                        */
  6. /***************************************************************************/
  7.  
  8. /*
  9. ** This is an example for the simplest possible MUI class. It's just some
  10. ** kind of custom image and supports only two methods:
  11. ** MUIM_AskMinMax and MUIM_Draw.
  12. */
  13.  
  14. /*
  15. ** This is the instance data for our custom class.
  16. ** Since it's a very simple class, it contains just a dummy entry.
  17. */
  18.  
  19. struct Data
  20. {
  21.     int x,y,sx,sy;
  22. };
  23.  
  24.  
  25. /*
  26. ** AskMinMax method will be called before the window is opened
  27. ** and before layout takes place. We need to tell MUI the
  28. ** minimum, maximum and default size of our object.
  29. */
  30.  
  31. SAVEDS ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg)
  32. {
  33.     /*
  34.     ** let our superclass first fill in what it thinks about sizes.
  35.     ** this will e.g. add the size of frame and inner spacing.
  36.     */
  37.  
  38.     DoSuperMethodA(cl,obj,msg);
  39.  
  40.     /*
  41.     ** now add the values specific to our object. note that we
  42.     ** indeed need to *add* these values, not just set them!
  43.     */
  44.  
  45.     msg->MinMaxInfo->MinWidth  += 100;
  46.     msg->MinMaxInfo->DefWidth  += 120;
  47.     msg->MinMaxInfo->MaxWidth  += 500;
  48.  
  49.     msg->MinMaxInfo->MinHeight += 40;
  50.     msg->MinMaxInfo->DefHeight += 90;
  51.     msg->MinMaxInfo->MaxHeight += 300;
  52.  
  53.     return(0);
  54. }
  55.  
  56.  
  57. /*
  58. ** Draw method is called whenever MUI feels we should render
  59. ** our object. This usually happens after layout is finished
  60. ** or when we need to refresh in a simplerefresh window.
  61. ** Note: You may only render within the rectangle
  62. **       _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj).
  63. */
  64.  
  65. SAVEDS ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
  66. {
  67.     struct Data *data = INST_DATA(cl,obj);
  68.  
  69.     /*
  70.     ** let our superclass draw itself first, area class would
  71.     ** e.g. draw the frame and clear the whole region. What
  72.     ** it does exactly depends on msg->flags.
  73.     **
  74.     ** Note: You *must* call the super method prior to do
  75.     ** anything else, otherwise msg->flags will not be set
  76.     ** properly !!!
  77.     */
  78.  
  79.     DoSuperMethodA(cl,obj,msg);
  80.  
  81.     /*
  82.     ** if MADF_DRAWOBJECT isn't set, we shouldn't draw anything.
  83.     ** MUI just wanted to update the frame or something like that.
  84.     */
  85.  
  86.     if (msg->flags & MADF_DRAWUPDATE) /* called from our input method */
  87.     {
  88.         if (data->sx || data->sy)
  89.         {
  90.             SetBPen(_rp(obj),_dri(obj)->dri_Pens[SHINEPEN]);
  91.             ScrollRaster(_rp(obj),data->sx,data->sy,_mleft(obj),_mtop(obj),_mright(obj),_mbottom(obj));
  92.             SetBPen(_rp(obj),0);
  93.             data->sx = 0;
  94.             data->sy = 0;
  95.         }
  96.         else
  97.         {
  98.             SetAPen(_rp(obj),_dri(obj)->dri_Pens[SHADOWPEN]);
  99.             WritePixel(_rp(obj),data->x,data->y);
  100.         }
  101.     }
  102.     else if (msg->flags & MADF_DRAWOBJECT)
  103.     {
  104.         SetAPen(_rp(obj),_dri(obj)->dri_Pens[SHINEPEN]);
  105.         RectFill(_rp(obj),_mleft(obj),_mtop(obj),_mright(obj),_mbottom(obj));
  106.     }
  107.  
  108.     return(0);
  109. }
  110.  
  111.  
  112. SAVEDS ULONG mSetup(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  113. {
  114.     if (!(DoSuperMethodA(cl,obj,msg)))
  115.         return(FALSE);
  116.  
  117.     MUI_RequestIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  118.  
  119.     return(TRUE);
  120. }
  121.  
  122.  
  123. SAVEDS ULONG mCleanup(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  124. {
  125.     MUI_RejectIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  126.     return(DoSuperMethodA(cl,obj,msg));
  127. }
  128.  
  129.  
  130. SAVEDS ULONG mHandleInput(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  131. {
  132.     #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
  133.     #define _isinobject(x,y) (_between(_mleft(obj),(x),_mright(obj)) && _between(_mtop(obj),(y),_mbottom(obj)))
  134.  
  135.     struct Data *data = INST_DATA(cl,obj);
  136.  
  137.     if (msg->muikey)
  138.     {
  139.         switch (msg->muikey)
  140.         {
  141.             case MUIKEY_LEFT : data->sx=-1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  142.             case MUIKEY_RIGHT: data->sx= 1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  143.             case MUIKEY_UP   : data->sy=-1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  144.             case MUIKEY_DOWN : data->sy= 1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  145.         }
  146.     }
  147.  
  148.     if (msg->imsg)
  149.     {
  150.         switch (msg->imsg->Class)
  151.         {
  152.             case IDCMP_MOUSEBUTTONS:
  153.             {
  154.                 if (msg->imsg->Code==SELECTDOWN)
  155.                 {
  156.                     if (_isinobject(msg->imsg->MouseX,msg->imsg->MouseY))
  157.                     {
  158.                         data->x = msg->imsg->MouseX;
  159.                         data->y = msg->imsg->MouseY;
  160.                         MUI_Redraw(obj,MADF_DRAWUPDATE);
  161.                         MUI_RequestIDCMP(obj,IDCMP_MOUSEMOVE);
  162.                     }
  163.                 }
  164.                 else
  165.                     MUI_RejectIDCMP(obj,IDCMP_MOUSEMOVE);
  166.             }
  167.             break;
  168.  
  169.             case IDCMP_MOUSEMOVE:
  170.             {
  171.                 if (_isinobject(msg->imsg->MouseX,msg->imsg->MouseY))
  172.                 {
  173.                     data->x = msg->imsg->MouseX;
  174.                     data->y = msg->imsg->MouseY;
  175.                     MUI_Redraw(obj,MADF_DRAWUPDATE);
  176.                 }
  177.             }
  178.             break;
  179.         }
  180.     }
  181.  
  182.     return(0);
  183. }
  184.  
  185.  
  186. /*
  187. ** Here comes the dispatcher for our custom class. We only need to
  188. ** care about MUIM_AskMinMax and MUIM_Draw in this simple case.
  189. ** Unknown/unused methods are passed to the superclass immediately.
  190. */
  191.  
  192. SAVEDS ASM ULONG MyDispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  193. {
  194.     switch (msg->MethodID)
  195.     {
  196.         case MUIM_AskMinMax  : return(mAskMinMax  (cl,obj,(APTR)msg));
  197.         case MUIM_Draw       : return(mDraw       (cl,obj,(APTR)msg));
  198.         case MUIM_HandleInput: return(mHandleInput(cl,obj,(APTR)msg));
  199.         case MUIM_Setup      : return(mSetup      (cl,obj,(APTR)msg));
  200.         case MUIM_Cleanup    : return(mCleanup    (cl,obj,(APTR)msg));
  201.     }
  202.  
  203.     return(DoSuperMethodA(cl,obj,msg));
  204. }
  205.  
  206.  
  207.  
  208. /***************************************************************************/
  209. /* Thats all there is about it. Now lets see how things are used...        */
  210. /***************************************************************************/
  211.  
  212. int main(int argc,char *argv[])
  213. {
  214.     APTR app,window,MyObj;
  215.     struct MUI_CustomClass *mcc;
  216.     ULONG signals;
  217.     BOOL running = TRUE;
  218.  
  219.     init();
  220.  
  221.     /* Create the new custom class with a call to MUI_CreateCustomClass(). */
  222.     /* Caution: This function returns not a struct IClass, but a           */
  223.     /* struct MUI_CustomClass which contains a struct IClass to be         */
  224.     /* used with NewObject() calls.                                        */
  225.     /* Note well: MUI creates the dispatcher hook for you, you may         */
  226.     /* *not* use its h_Data field! If you need custom data, use the        */
  227.     /* cl_UserData of the IClass structure!                                */
  228.  
  229.     if (!(mcc = MUI_CreateCustomClass(NULL,MUIC_Area,NULL,sizeof(struct Data),MyDispatcher)))
  230.         fail(NULL,"Could not create custom class.");
  231.  
  232.     app = ApplicationObject,
  233.         MUIA_Application_Title      , "Class3",
  234.         MUIA_Application_Version    , "$VER: Class3 1.0 (01.12.93)",
  235.         MUIA_Application_Copyright  , "©1993, Stefan Stuntz",
  236.         MUIA_Application_Author     , "Stefan Stuntz",
  237.         MUIA_Application_Description, "Demonstrate the use of custom classes.",
  238.         MUIA_Application_Base       , "CLASS3",
  239.  
  240.         SubWindow, window = WindowObject,
  241.             MUIA_Window_Title, "A rather complex custom class",
  242.             MUIA_Window_ID   , MAKE_ID('C','L','S','3'),
  243.             WindowContents, VGroup,
  244.  
  245.                 Child, TextObject,
  246.                     TextFrame,
  247.                     MUIA_Background, MUII_TextBack,
  248.                     MUIA_Text_Contents, "\33cPaint with mouse,\nscroll with cursor keys.",
  249.                     End,
  250.  
  251.                 Child, MyObj = NewObject(mcc->mcc_Class,NULL,
  252.                     TextFrame,
  253.                     TAG_DONE),
  254.  
  255.                 End,
  256.  
  257.             End,
  258.         End;
  259.  
  260.     if (!app)
  261.         fail(app,"Failed to create Application.");
  262.  
  263.     set(window,MUIA_Window_DefaultObject, MyObj);
  264.  
  265.     DoMethod(window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  266.         app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  267.  
  268.  
  269.  
  270. /*
  271. ** Input loop...
  272. */
  273.  
  274.     set(window,MUIA_Window_Open,TRUE);
  275.  
  276.     while (running)
  277.     {
  278.         switch (DoMethod(app,MUIM_Application_Input,&signals))
  279.         {
  280.             case MUIV_Application_ReturnID_Quit:
  281.                 running = FALSE;
  282.                 break;
  283.         }
  284.  
  285.         if (running && signals) Wait(signals);
  286.     }
  287.  
  288.     set(window,MUIA_Window_Open,FALSE);
  289.  
  290.  
  291. /*
  292. ** Shut down...
  293. */
  294.  
  295.     MUI_DisposeObject(app);     /* dispose all objects. */
  296.     MUI_DeleteCustomClass(mcc); /* delete the custom class. */
  297.     fail(NULL,NULL);            /* exit, app is already disposed. */
  298. }
  299.