home *** CD-ROM | disk | FTP | other *** search
/ Dream 41 / Amiga_Dream_41.iso / Amiga / Programmation / gui / tri20b2dev.lha / Triton / Developer / DemoSource / customclass.c next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  10.1 KB  |  333 lines

  1. /*
  2.  *  Triton - The object oriented GUI creation system for the Amiga
  3.  *  Written by Stefan Zeiger in 1993-1996
  4.  *
  5.  *  (c) 1993-1996 by Stefan Zeiger
  6.  *  You are hereby allowed to use this source or parts
  7.  *  of it for creating programs for AmigaOS which use the
  8.  *  Triton GUI creation system. All other rights reserved.
  9.  *
  10.  *  CustomClass.c - A simple custom class
  11.  *
  12.  *  ****    ***   *   *  *  *****     ****    ***   *   *  ***   ***     *
  13.  *  *   *  *   *  **  *  *    *       *   *  *   *  **  *   *   *        *
  14.  *  *   *  *   *  * * *       *       ****   *****  * * *   *   *        *
  15.  *  *   *  *   *  *  **       *       *      *   *  *  **   *   *
  16.  *  ****    ***   *   *       *       *      *   *  *   *  ***   ***     *
  17.  *
  18.  *  It's easier than it looks!
  19.  *
  20.  */
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <math.h>
  27.  
  28. #include <libraries/triton.h>
  29. #include <graphics/gfx.h>
  30. #include <intuition/intuition.h>
  31.  
  32. #ifdef __GNUC__
  33. #ifndef __OPTIMIZE__
  34. #include <clib/triton_protos.h>
  35. #include <clib/graphics_protos.h>
  36. #include <clib/intuition_protos.h>
  37. #else
  38. #include <inline/triton.h>
  39. #include <inline/graphics.h>
  40. #include <inline/intuition.h>
  41. #endif /* __OPTIMIZE__ */
  42. #else
  43. #include <proto/triton.h>
  44. #include <proto/graphics.h>
  45. #include <proto/intuition.h>
  46. #endif /* __GNUC__ */
  47.  
  48.  
  49. /**** So it shall be written, so it shall be done: ****/
  50.  
  51. /****** class_Clock ******
  52. *
  53. *   NAME    
  54. *    class_Clock -- Display an analog clock.
  55. *
  56. *   SUPERCLASS
  57. *    class_DisplayObject
  58. *
  59. *   SYNOPSIS
  60. *    TROB_Clock
  61. *
  62. *   ATTRIBUTES
  63. *    <Default>        : <unused>
  64. *    TRAT_Clock_Hours : ULONG hours
  65. *                       (Default: 0)
  66. *                       [create, set, get]
  67. *    TRAT_Clock_Mins  : ULONG minutes
  68. *                       (Default: 0)
  69. *                       [create, set, get]
  70. *    TRAT_Clock_Secs  : ULONG seconds
  71. *                       (Default: 0)
  72. *                       [create, set, get]
  73. *    TRAT_Clock_DisplaySeconds : BOOL displayseconds
  74. *                       (Default: TRUE)
  75. *                       [create, set, get]
  76. *
  77. ******/
  78.  
  79. /**** The class tag ****/
  80. #define TROB_Clock                  TRTG_PRVCLS(1)
  81.  
  82. /**** The attribute tags ****/
  83. #define TRAT_Clock_Hours            TRTG_PRVOAT(1)
  84. #define TRAT_Clock_Mins             TRTG_PRVOAT(2)
  85. #define TRAT_Clock_Secs             TRTG_PRVOAT(3)
  86. #define TRAT_Clock_DisplaySeconds   TRTG_PRVOAT(4)
  87.  
  88. /**** The internal representation of instances of our class ****/
  89. struct TROD_Clock
  90. {
  91.   struct TROD_DisplayObject DO; /* Superclass object data */
  92.   ULONG Hours, Mins, Secs;      /* The currently displayed time */
  93.   BOOL DisplaySecs;             /* Display seconds? */
  94. };
  95.  
  96. TR_CONSTRUCTOR(Clock) /* This one's called for creating an instance */
  97. {
  98.   /* Initialize default values */
  99.   Self.DisplaySecs=TRUE;
  100.  
  101.   /* Let the superclass do its work (mainly argument parsing) */
  102.   if(!TR_SUPERMETHOD) return NULL;
  103.  
  104.   /* Set some DisplayObject fields */
  105.   Self.DO.XResize=TRUE;
  106.   Self.DO.YResize=TRUE;
  107.   Self.DO.MinHeight=50;
  108.   Self.DO.MinWidth=(Self.DO.MinHeight*Self.DO.O.Project->trp_AspectFixing)/16;
  109.  
  110.   /* We need to see some IDCMP messages */
  111.   Self.DO.O.Project->trp_IDCMPFlags|=IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE|IDCMP_INACTIVEWINDOW;
  112.  
  113.   /* You asked for it? Here you got it! */
  114.   return object;
  115. }
  116.  
  117. TR_SIMPLEMETHOD(Clock,INSTALL_REFRESH) /* 2 messages but only 1 method! */
  118. {
  119.   ULONG left,top,width,height;
  120.   struct TR_Project *project;
  121.   double r;
  122.   int d;
  123.  
  124.   TR_SUPERMETHOD; /* Call DisplayObject's INSTALL or REFRESH method */
  125.  
  126.   project = Self.DO.O.Project;
  127.   left    = Self.DO.Left;
  128.   top     = Self.DO.Top;
  129.   width   = Self.DO.Width;
  130.   height  = Self.DO.Height;
  131.  
  132.   /* Fill background */
  133.   TR_AreaFill(project,NULL,left,top,left+width-1,top+height-1,TRBF_NONE,NULL);
  134.  
  135.   /* Draw ticks */
  136.   SetAPen(project->trp_Window->RPort,TR_GetPen(project,TRPT_SYSTEMPEN,FILLPEN));
  137.   for(d=0;d<360;d+=5)
  138.     {
  139.       r=((double)d)*PI/180.0;
  140.       if(d%30==0)
  141.     {
  142.       SetAPen(project->trp_Window->RPort,TR_GetPen(project,TRPT_SYSTEMPEN,TEXTPEN));
  143.       Move(project->trp_Window->RPort,
  144.            (LONG)(left+width/2+(cos(r)*(width/2-1))),(LONG)(top+height/2+(sin(r)*(height/2-1))));
  145.       Draw(project->trp_Window->RPort,
  146.            (LONG)(left+width/2+(cos(r)*(width/2-1))*0.9),(LONG)(top+height/2+(sin(r)*(height/2-1))*0.9));
  147.       SetAPen(project->trp_Window->RPort,TR_GetPen(project,TRPT_SYSTEMPEN,FILLPEN));
  148.     }
  149.       else
  150.     {
  151.       Move(project->trp_Window->RPort,
  152.            (LONG)(left+width/2+(cos(r)*(width/2-1))),(LONG)(top+height/2+(sin(r)*(height/2-1))));
  153.       Draw(project->trp_Window->RPort,
  154.            (LONG)(left+width/2+(cos(r)*(width/2-1))*0.95),
  155.            (LONG)(top+height/2+(sin(r)*(height/2-1))*0.95));
  156.     }
  157.     }
  158.  
  159.   /* Draw Circle */
  160.   SetAPen(project->trp_Window->RPort,TR_GetPen(project,TRPT_SYSTEMPEN,TEXTPEN));
  161.   DrawEllipse(project->trp_Window->RPort,left+width/2,top+height/2,width/2-1,height/2-1);
  162.  
  163.   /* Draw second hand (even though this code is new and original :-) */
  164.   if(Self.DisplaySecs)
  165.     {
  166.       SetAPen(project->trp_Window->RPort,TR_GetPen(project,TRPT_SYSTEMPEN,FILLPEN));
  167.       d=270+(((double)(Self.Secs))*360.0/60.0);
  168.       r=((double)d)*PI/180.0;
  169.       Move(project->trp_Window->RPort,left+width/2,top+height/2);
  170.       Draw(project->trp_Window->RPort,
  171.        (LONG)(left+width/2+(cos(r)*(width/2-1))*0.85),(LONG)(top+height/2+(sin(r)*(height/2-1))*0.85));
  172.     }
  173.  
  174.   /* Draw minute hand */
  175.   SetAPen(project->trp_Window->RPort,TR_GetPen(project,TRPT_SYSTEMPEN,SHINEPEN));
  176.   d=270+(((double)(Self.Mins))*360.0/60.0);
  177.   r=((double)d)*PI/180.0;
  178.   Move(project->trp_Window->RPort,left+width/2,top+height/2);
  179.   Draw(project->trp_Window->RPort,
  180.        (LONG)(left+width/2+(cos(r)*(width/2-1))*0.75),(LONG)(top+height/2+(sin(r)*(height/2-1))*0.75));
  181.  
  182.   /* Draw hour hand */
  183.   d=270+(((double)(Self.Hours%12))*360.0/12.0+((double)(Self.Mins))*30.0/60.0);
  184.   r=((double)d)*PI/180.0;
  185.   Move(project->trp_Window->RPort,left+width/2,top+height/2);
  186.   Draw(project->trp_Window->RPort,
  187.        (LONG)(left+width/2+(cos(r)*(width/2-1))*0.60),(LONG)(top+height/2+(sin(r)*(height/2-1))*0.60));
  188.  
  189.   return 1; /* Everything OK */
  190. }
  191.  
  192. TR_METHOD(Clock,SETATTRIBUTE,SetAttributeData) /* Set an attribute (upon creation or later) */
  193. {
  194.   /* A good way to do this properly would be:
  195.      1) If a hand is changing erase the old hand with the background pen.
  196.      2) Modify the value.
  197.      3) If a hand was erased in step 1 redraw it.
  198.  
  199.      But since this is only an example program we'll do it the easy (and short) way:
  200.      1) Modify the value.
  201.      2) Refresh the display. */
  202.  
  203.   switch(data->attribute)
  204.   {
  205.     case TRAT_Clock_Hours:
  206.       Self.Hours=data->value;
  207.       goto dorefresh;
  208.     case TRAT_Clock_Mins:
  209.       Self.Mins=data->value;
  210.       goto dorefresh;
  211.     case TRAT_Clock_Secs:
  212.       Self.Secs=data->value;
  213.       goto dorefresh;
  214.     case TRAT_Clock_DisplaySeconds:
  215.       Self.DisplaySecs=data->value;
  216.       goto dorefresh;
  217.     default:
  218.       /* Pass messages for unknown attributes on to the superclass */
  219.       return TR_SUPERMETHOD;
  220.     }
  221.  
  222. dorefresh:
  223.   /* Attention! You can receive TROM_SETATTRIBUTE messages when the object
  224.      isn't currently installed. You have to make sure the object is indeed
  225.      installed before sending it a refresh message! */
  226.   if(Self.DO.Installed) return TR_DoMethod(&Self.DO.O,TROM_REFRESH,NULL);
  227.   else return 1;
  228. }
  229.  
  230. TR_SIMPLEMETHOD(Clock,GETATTRIBUTE) /* Return a requested attribute */
  231. {
  232.   switch((ULONG)data)
  233.   {
  234.     case TRAT_Clock_Hours:
  235.       return Self.Hours;
  236.     case TRAT_Clock_Mins:
  237.       return Self.Mins;
  238.     case TRAT_Clock_Secs:
  239.       return Self.Secs;
  240.     case TRAT_Clock_DisplaySeconds:
  241.       return (ULONG)(Self.DisplaySecs?TRUE:FALSE);
  242.     default:
  243.       /* Pass queries for unknown attributes on to the superclass */
  244.       return TR_SUPERMETHOD;
  245.   }
  246. }
  247.  
  248. TR_METHOD(Clock,EVENT,EventData) /* React on IDCMP messages */
  249. {
  250.   struct TR_Message *trmsg;
  251.  
  252.   if((data->imsg->Class==IDCMP_MOUSEBUTTONS)
  253.      &&(data->imsg->MouseX>=Self.DO.Left)
  254.      &&(data->imsg->MouseX<Self.DO.Left+Self.DO.Width)
  255.      &&(data->imsg->MouseY>=Self.DO.Top)
  256.      &&(data->imsg->MouseY<Self.DO.Top+Self.DO.Height)
  257.      &&(data->imsg->Code==SELECTDOWN))
  258.     {
  259.       DisplayBeep(NULL);
  260. /*       if(trmsg=TR_CreateMsg(Self.DO.O.Project->trp_App)) */
  261. /*     { */
  262. /*       trmsg->trm_ID=Self.DO.ID; */
  263. /*       trmsg->trm_Class=TRMS_ACTION; */
  264. /*       return TROM_EVENT_SWALLOWED; */
  265. /*     } */
  266.     }
  267.   return TROM_EVENT_CONTINUE;
  268. }
  269.  
  270.  
  271. /**** Let's see if our class works... ****/
  272.  
  273. int main(void)
  274. {
  275.   int retval=20;
  276.   BOOL close_me=FALSE;
  277.   struct TR_Message *trmsg;
  278.   struct TR_Project *project;
  279.  
  280.   if(TR_OpenTriton(TRITON20VERSION,TRCA_Name,"CustomClass",TRCA_Info,"Triton Custom Class Demo",TRCA_Version,"1.0",TAG_END))
  281.     {
  282.       if(TR_AddClassTags(Application, TROB_Clock, TROB_DisplayObject, NULL, sizeof(struct TROD_Clock),
  283.              TROM_NEW,          TRDP_Clock_NEW,
  284.              TROM_INSTALL,      TRDP_Clock_INSTALL_REFRESH,
  285.              TROM_REFRESH,      TRDP_Clock_INSTALL_REFRESH,
  286.              TROM_SETATTRIBUTE, TRDP_Clock_SETATTRIBUTE,
  287.              TROM_GETATTRIBUTE, TRDP_Clock_GETATTRIBUTE,
  288.              TROM_EVENT,        TRDP_Clock_EVENT,
  289.              TAG_END))
  290.     {
  291.       if(project=TR_OpenProjectTags(Application,
  292.                     WindowID(1), WindowPosition(TRWP_CENTERDISPLAY),
  293.                     WindowTitle("CustomClass (under construction!)"), WindowFlags(TRWF_NOMINTEXTWIDTH),
  294.                     QuickHelpOn(TRUE),
  295.                     HorizGroupA, Space, VertGroupA,
  296.                       Space,
  297.                       NamedFrameBox("Triton Clock"), ObjectBackfillB,
  298.                         HorizGroupA, Space, VertGroupA,
  299.                           Space,
  300.                           TROB_Clock, NULL, TRAT_Clock_Hours, 5, TRAT_Clock_Mins, 42,
  301.                             ID(1), QuickHelp("Use the mouse to drag the hands\n(NOT IMPLEMENTED YET!)"),
  302.                           Space,
  303.                                             EndGroup, Space, EndGroup,
  304.                       Space, EndGroup, Space, EndGroup, EndProject))
  305.         {
  306.           while(!close_me)
  307.         {
  308.           TR_Wait(Application,NULL);
  309.           while(trmsg=TR_GetMsg(Application))
  310.             {
  311.               if(trmsg->trm_Project==project) switch(trmsg->trm_Class)
  312.             {
  313.             case TRMS_CLOSEWINDOW:
  314.               close_me=TRUE;
  315.               break;
  316.  
  317.             case TRMS_ERROR:
  318.               puts(TR_GetErrorString(trmsg->trm_Data));
  319.               break;
  320.             }
  321.               TR_ReplyMsg(trmsg);
  322.             }
  323.         }
  324.           TR_CloseProject(project);
  325.         } else puts(TR_GetErrorString(trmsg->trm_Data));
  326.     } else puts("Can't initialize 'Clock' custom class.");
  327.       retval=0;
  328.       TR_CloseTriton();
  329.     } else puts("Can't open triton.library v6+.");
  330.  
  331.   return retval;
  332. }
  333.