home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v6.zip / MMPM2TK / TK / CLOCK / CLOCKDRW.C < prev    next >
C/C++ Source or Header  |  1993-01-29  |  22KB  |  555 lines

  1. /*static char *SCCSID = "@(#)clockdrw.c    13.6 92/04/16";*/
  2. /*************************************************************************
  3.  * Name        : Clockdrw.c
  4.  *
  5.  * Description : This file contains the C source code required for the
  6.  *               graphics processing in the clock sample program.
  7.  *
  8.  * MMPM/2 API's: None
  9.  *************************************************************************/
  10. #define  INCL_OS2MM                      /* Required for MCI & MMIO headers   */
  11. #define  INCL_WIN                        /* Required to use Win APIs.         */
  12. #define  INCL_PM                         /* Required to use PM APIs.          */
  13. #define  INCL_GPIPRIMATIVES              /* Required to use GPI OS/2 APIs.    */
  14. #define  INCL_WINHELP                    /* Required to use IPF.              */
  15.  
  16. #include <os2.h>
  17. #include <os2me.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20.  
  21. #include "clock.h"
  22. /************************* Procedure/Function Prototypes **********************/
  23.  
  24. VOID             PlaceTheTimeMarkers( HPS     hps,
  25.                                       PPOINTL pptlMarkerPosition,
  26.                                       USHORT  usClockNumeral );
  27. VOID             DrawClockCircles( HPS     hps,
  28.                                    PPOINTL pptlMarkerPosition,
  29.                                    LONG    lCircleColor,
  30.                                    USHORT  usCircleSize );
  31. /****************************** Local Variables. ******************************/
  32.  
  33. POINTL  aptlMarkerPosition[ NUMBER_OF_MINUTE_MARKERS ] =
  34.    {
  35.       {   0,  131 }, {   13,  130 }, {   27,  128 }, {   40,  124 },
  36.       {  53,  119 }, {   65,  113 }, {   76,  105 }, {   87,  97  },
  37.       {  97,   87 }, {  105,   76 }, {  113,   65 }, {  119,  53  },
  38.       { 124,   40 }, {  128,   27 }, {  130,   13 }, {  131,   0  },
  39.       { 130,  -13 }, {  128,  -27 }, {  124,  -40 }, {  119, -53  },
  40.       { 113,  -65 }, {  105,  -76 }, {   97,  -87 }, {   87, -97  },
  41.       {  76, -105 }, {   65, -113 }, {   53, -119 }, {   40, -124 },
  42.       {  27, -128 }, {   13, -130 }, {    0, -131 }, {  -13, -130 },
  43.       { -27, -128 }, {  -40, -124 }, {  -53, -119 }, {  -65, -113 },
  44.       { -76,  105 }, {  -87,  -97 }, {  -97,  -87 }, { -105,  -76 },
  45.       {-113,  -65 }, { -119,  -53 }, { -124,  -40 }, { -128,  -27 },
  46.       {-130,  -13 }, { -130,    0 }, { -130,   13 }, { -128,   27 },
  47.       {-124,   40 }, { -119,   53 }, { -113,   65 }, {  105,   76 },
  48.       { -97,   87 }, {  -87,   97 }, {  -76,  105 }, {  -65,  113 },
  49.       { -53,  119 }, {  -40,  124 }, {  -27,  128 }, {  -13,  129 },
  50.    };
  51.  
  52. POINTL aptlHandsPosition[ NUMBER_OF_MINUTE_MARKERS ] =
  53.    {
  54.        {  0,  111 }, {   11,  110 }, {   23,  108 }, {   34,  105 },
  55.        { 45  ,101 }, {   55,   96 }, {   65,   90 }, {   74,   82 },
  56.        { 82,   74 }, {   90,   65 }, {   96,   55 }, {  101,   45 },
  57.        { 105,  34 }, {  108,   23 }, {  110,   11 }, {  111,    0 },
  58.        { 110, -11 }, {  108,  -23 }, {  105,  -34 }, {  101,  -45 },
  59.        { 96,  -55 }, {   90,  -65 }, {   82,  -74 }, {   74,  -82 },
  60.        { 65,  -90 }, {   55,  -96 }, {   45, -101 }, {   34, -105 },
  61.        { 23, -108 }, {   11, -110 }, {    0, -111 }, {  -11, -110 },
  62.        { -23,-108 }, {  -34, -105 }, {  -45, -101 }, {  -55,  -96 },
  63.        { -65, -90 }, {  -74,  -82 }, {  -82,  -74 }, {  -90,  -65 },
  64.        { -96, -55 }, { -101,  -45 }, { -105,  -34 }, { -108,  -23 },
  65.        { -110,-11 }, { -111,    0 }, { -110,   11 }, { -108,   23 },
  66.        { -105, 34 }, { -101,   45 }, {  -96,   55 }, {  -90,   65 },
  67.        { -82,  74 }, {  -74,   82 }, {  -65,   90 }, {  -55,   96 },
  68.        { -45, 101 }, {  -34,  105 }, {  -23,  108 }, {  -11  ,110 }
  69.    };
  70.  
  71. /*************************************************************************
  72.  * Name        : DrawTheClockFace
  73.  *
  74.  * Description : This procedure will draw the clock face. Instead of
  75.  *               numerals on the clock face, it will have lines in the place
  76.  *               of numerals (called  time markers or sticks).
  77.  *                  Set up the required values to draw a circle.
  78.  *                  Move to the center of the dialog window.
  79.  *                  Then place the sticks.
  80.   *
  81.  *               STICKS - Hour and Minute positions.
  82.  *
  83.  * Concepts    : None.
  84.  *
  85.  * MMPM/2 API's: None.
  86.  *
  87.  * Parameters  : hps                - The presentation space in which
  88.  *                                    to draw.
  89.  *               pptlCircleCenter   - The coordinates of the window center.
  90.  *
  91.  * Return      : None.
  92.  *
  93.  *************************************************************************/
  94. VOID  DrawTheClockFace( HPS     hps,
  95.                         PPOINTL pptlCircleCenter )
  96. {
  97.    ARCPARAMS apsArcParameters;       /* Parameters used to form circle.       */
  98.    POINTL    ptrMarkerPosition;      /* Marker position.                      */
  99.    USHORT    usClockNumeral;         /* Clock face numeral.                   */
  100.  
  101.    /*
  102.     * Set the arc parameters so that a circle will be drawn when the
  103.     * GpiFullArc API is called.
  104.     * p - scales in the X direction.
  105.     * q - scales in the Y direction.
  106.     * r - sheared ellipse or arc.
  107.     * s - sheared ellipse or arc.
  108.     */
  109.  
  110.    apsArcParameters.lP = (LONG) 1;
  111.    apsArcParameters.lQ = (LONG) 1;
  112.    apsArcParameters.lR = (LONG) 0;
  113.    apsArcParameters.lS = (LONG) 0;
  114.  
  115.    GpiSetArcParams( hps,                   /* Presentation Space.             */
  116.                     &apsArcParameters );   /* Arc parameters.                 */
  117.  
  118.    /*
  119.     * Move to the center of the window so that the Clock Circle can be
  120.     * drawn.
  121.     */
  122.    GpiMove( hps,                  /* Presentation Space.                      */
  123.             pptlCircleCenter );   /* Center point in the window.              */
  124.  
  125.    /*
  126.     * Place the time markers on the clock face.
  127.     */
  128.    for(usClockNumeral=1; usClockNumeral<13; usClockNumeral++)
  129.    {
  130.       ptrMarkerPosition.x = pptlCircleCenter->x;
  131.       ptrMarkerPosition.y = pptlCircleCenter->y;
  132.  
  133.       PlaceTheTimeMarkers(
  134.          hps,                       /* Presentation Space.                    */
  135.          &ptrMarkerPosition,        /* Structure that will hold the position. */
  136.          usClockNumeral );          /* Which numeral we are dealing with.     */
  137.  
  138.    }  /* End of Clock Numeral For Loop. */
  139.  
  140. } /* End of DrawTheClockFace */
  141.  
  142.  
  143. /*************************************************************************
  144.  * Name        : DrawTheHourHand
  145.  *
  146.  * Description : This procedure takes the given presentation space and
  147.  *               draws the hour hand on the face of the clock.  In drawing
  148.  *               the new hour's hand on the clock face the old hour hand
  149.  *               has to be erased first.  After the old hour hand is erased
  150.  *               the new hour hand position can be drawn.
  151.  *
  152.  * Concepts    : None.
  153.  *
  154.  * MMPM/2 API's: None.
  155.  *
  156.  * Parameters  : hps              - The presentation space to in which
  157.  *                                  to draw.
  158.  *               pptlCircleCenter - The coordinates of the window center.
  159.  *               usHour           - The hour to use to show the correct hand.
  160.  *               usMinute         - The minute to use to place the hour hand.
  161.  *
  162.  * Return      : None.
  163.  *
  164.  *************************************************************************/
  165. MRESULT EXPENTRY DrawTheHourHand( HPS     hps,
  166.                       PPOINTL pptlCircleCenter,
  167.                       USHORT  usHour,
  168.                       USHORT  usMinute)
  169. {
  170.    POINTL ptlHandPosition;       /* Hour hand position.                       */
  171.    USHORT usTempHour;            /* Temporary value for the hour.             */
  172.  
  173.    extern USHORT usLastHour;
  174.  
  175.    /*
  176.     * Place the 'real' hour into a temporary variable that can be
  177.     * changed as desired.
  178.     */
  179.    usTempHour = usHour % (USHORT) 12;
  180.  
  181.    /*
  182.     * Move to the Center of the Clock Face.
  183.     */
  184.    GpiMove(
  185.       hps,                 /* Presentation Space.                             */
  186.       pptlCircleCenter );  /* Center point of the circle.                     */
  187.  
  188.    /*
  189.     * Take the center of the circle as a starting point and initalize the
  190.     * variable that is used to draw the hour hand.
  191.     */
  192.    ptlHandPosition.x = pptlCircleCenter->x;
  193.    ptlHandPosition.y = pptlCircleCenter->y;
  194.  
  195.    /*
  196.     * Check to make sure that the hour value that was passed into the
  197.     * procedure is within bounds.  If it is not, the hour hand will NOT
  198.     * be updated.
  199.     */
  200.    if ( usTempHour > -1 && usTempHour < 13 )
  201.    {
  202.       /*
  203.        * See if the usHour is at the top of the hour.  If it is, make
  204.        * the variable look at the first cell in the array, i.e., the zero
  205.        * cell.
  206.        */
  207.       if ( usTempHour == 12 )
  208.       {
  209.          usTempHour = 0;
  210.       }
  211.  
  212.       /*
  213.        * Erase the OLD hour.
  214.        * - Set the draw color to the background color.
  215.        * - Set the position for the minute hand.
  216.        * - Draw the hour hand to erase the old hour.
  217.        * BUT don't erase the hour hand if it has not been drawn before, i.e.,
  218.        * this is the first time into this routine after startup.
  219.        */
  220.       if ( usLastHour == 99 )
  221.       {
  222.          GpiSetColor(
  223.             hps,                    /* Presentation Space.                    */
  224.             SYSCLR_FIELDBACKGROUND);/* Background color to erase the old hour.*/
  225.  
  226.          ptlHandPosition.x +=
  227.             (aptlHandsPosition[
  228.                (usLastHour * HOUR_HAND_INDEX) + (usMinute / 12) ].x / 2 );
  229.          ptlHandPosition.y +=
  230.             (aptlHandsPosition[
  231.                (usLastHour * HOUR_HAND_INDEX) + (usMinute / 12) ].y / 2  );
  232.  
  233.          GpiLine(
  234.             hps,                    /* Presentation Space.                    */
  235.             &ptlHandPosition );     /* Center point of the circle.            */
  236.  
  237.          DrawClockCircles(
  238.             hps,                    /* Handle to the Presentation space.      */
  239.             &ptlHandPosition,       /* Position to place the Marker.          */
  240.             SYSCLR_FIELDBACKGROUND, /* Color to make the end dot.             */
  241.             (USHORT) HAND_DOT );    /* Size of the time marker circle.        */
  242.     }
  243.  
  244.       /*
  245.        * Draw the NEW hour hand.
  246.        * - Reset the center values into the position points.
  247.        * - Calculate the new hour hand position.
  248.        * - Reset the color.
  249.        * - Move to the center of the clock.
  250.        * - Draw the new hour hand.
  251.        */
  252.       ptlHandPosition.x = pptlCircleCenter->x;
  253.       ptlHandPosition.y = pptlCircleCenter->y;
  254.  
  255.       ptlHandPosition.x +=
  256.          (aptlHandsPosition[
  257.             (usTempHour * HOUR_HAND_INDEX) + (usMinute / 12) ].x / 2 );
  258.       ptlHandPosition.y +=
  259.          (aptlHandsPosition[
  260.             (usTempHour * HOUR_HAND_INDEX) + (usMinute / 12) ].y / 2 );
  261.  
  262.      GpiSetColor(
  263.         hps,                 /* Presentation Space.                          */
  264.         CLOCK_HAND_COLOR  ); /* Color to use for the clock.                  */
  265.  
  266.      GpiMove(
  267.         hps,                 /* Presentation Space.                          */
  268.         pptlCircleCenter );  /* Center point of the circle.                  */
  269.  
  270.      GpiLine(
  271.         hps,                 /* Presentation Space.                          */
  272.         &ptlHandPosition );  /* End of the clock hand.                       */
  273.  
  274.      DrawClockCircles(
  275.         hps,                 /* Handle to the Presentation space.            */
  276.         &ptlHandPosition,    /* Position to place the Marker.                */
  277.         CLR_BLUE,            /* Color to make the end dot.                   */
  278.         (USHORT) HAND_DOT ); /* Size of the time marker circle.              */
  279.  
  280.      /*
  281.       * Since the hour value passed into the routine has been used, make
  282.       * this hour the Last Hour that was updated.  This allows the last
  283.       * hour to be removed from the clock face before the new hour is
  284.       * placed on the clock.
  285.       */
  286.      usLastHour = usHour;
  287.  
  288.   }  /* End of IF minute is within bounds. */
  289.  
  290. } /* End of DrawTheHourHand */
  291.  
  292.  
  293. /*************************************************************************
  294.  * Name        : DrawTheMinuteHand
  295.  *
  296.  * Description : This procedure will take the given presentation space
  297.  *               and window rectangle and draw the minute hand.  The
  298.  *               routine first erases the old minute hand and then draws
  299.  *               the new minute hand.
  300.  *
  301.  * Concepts    : None.
  302.  *
  303.  * MMPM/2 API's: None.
  304.  *
  305.  * Parameters  : hps                - The presentation space to in which
  306.  *                                    to draw.
  307.  *               pptlCircleCenter   - The coordinates of the window center.
  308.  *               usMinute           - The minute hand to display.
  309.  *
  310.  * Return      : None.
  311.  *
  312.  *************************************************************************/
  313. MRESULT EXPENTRY DrawTheMinuteHand( HPS hps,
  314.                         PPOINTL pptlCircleCenter,
  315.                         USHORT  usMinute)
  316. {
  317.    POINTL ptlHandPosition;       /* Minute hand position.                     */
  318.    USHORT usTempMinute;          /* Temporary value for the minute.           */
  319.  
  320.    extern USHORT usLastMinute;
  321.  
  322.    /*
  323.     * Place the 'real' Minute into a temporary variable that can be
  324.     * changed as desired.
  325.     */
  326.    usTempMinute = usMinute;
  327.  
  328.    /*
  329.     * Move to the Center of the Clock Face.
  330.     */
  331.    GpiMove(
  332.       hps,                 /* Presentation Space.                             */
  333.       pptlCircleCenter );  /* Center point of the circle.                     */
  334.  
  335.    /*
  336.     * Take the center of the circle as a starting point and initalize the
  337.     * variable that is used to draw the hour hand.
  338.     */
  339.    ptlHandPosition.x = pptlCircleCenter->x;
  340.    ptlHandPosition.y = pptlCircleCenter->y;
  341.  
  342.    /*
  343.     * Check to make sure that the minute value that was passed into the
  344.     * procedure is within bounds.  If it is not, the minute hand will NOT
  345.     * be updated.
  346.     */
  347.    if ( usTempMinute > -1 && usTempMinute < 61 )
  348.    {
  349.       /*
  350.        * See if the usMinute is at the top of the hour.  If it is, make
  351.        * the variable look at the first cell in the array, i.e., the zero
  352.        * cell.
  353.        */
  354.       if ( usTempMinute == 60 )
  355.       {
  356.          usTempMinute = 0;
  357.       }
  358.  
  359.       /*
  360.        * Erase the OLD minute.
  361.        * - Set the draw color to the background color.
  362.        * - Set the position for the minute hand.
  363.        * - Draw the minute to erase the old minute.
  364.        */
  365.       GpiSetColor(
  366.          hps,                    /* Presentation Space.                       */
  367.          SYSCLR_FIELDBACKGROUND);/* Background color to erase the old hour.   */
  368.  
  369.       ptlHandPosition.x +=
  370.          (aptlHandsPosition[ usLastMinute ].x );
  371.       ptlHandPosition.y +=
  372.          (aptlHandsPosition[ usLastMinute ].y );
  373.  
  374.      GpiLine(
  375.         hps,                     /* Presentation Space.                       */
  376.         &ptlHandPosition );      /* Center point of the circle.               */
  377.  
  378.      DrawClockCircles(
  379.         hps,                     /* Handle to the Presentation space.         */
  380.         &ptlHandPosition,        /* Position to place the Marker.             */
  381.         SYSCLR_FIELDBACKGROUND,  /* Color to make the end dot.                */
  382.         (USHORT) HAND_DOT );     /* Size of the time marker circle.           */
  383.  
  384.      /*
  385.       * Draw the NEW minute.
  386.       * - Reset the center values into the position points.
  387.       * - Calculate the new minute hand position.
  388.       * - Reset the color.
  389.       * - Move to the center of the clock.
  390.       * - Draw the new minute hand.
  391.       */
  392.       ptlHandPosition.x = pptlCircleCenter->x;
  393.       ptlHandPosition.y = pptlCircleCenter->y;
  394.  
  395.       ptlHandPosition.x +=
  396.          (aptlHandsPosition[ usTempMinute ].x );
  397.       ptlHandPosition.y +=
  398.          (aptlHandsPosition[ usTempMinute ].y );
  399.  
  400.      GpiSetColor(
  401.         hps,                 /* Presentation Space.                           */
  402.         CLOCK_HAND_COLOR );  /* Color to use for the clock, Black             */
  403.  
  404.      GpiMove(
  405.         hps,                 /* Presentation Space.                           */
  406.         pptlCircleCenter );  /* Center point of the circle.                   */
  407.  
  408.      GpiLine(
  409.         hps,                 /* Presentation Space.                           */
  410.         &ptlHandPosition );  /* End of the clock hand.                        */
  411.  
  412.      DrawClockCircles(
  413.         hps,                 /* Handle to the Presentation space.             */
  414.         &ptlHandPosition,    /* Position to place the Marker.                 */
  415.         CLR_BLUE,            /* Color to make the end dot.                    */
  416.         (USHORT) HAND_DOT ); /* Size of the time marker circle.               */
  417.  
  418.      /*
  419.       * Since the minute value passed into the routine has been used, make
  420.       * this minute is the Last Minute that was updated.  This allows the last
  421.       * minute to be removed from the clock face before the new minute is
  422.       * placed on the clock.
  423.       */
  424.      usLastMinute = usMinute;
  425.  
  426.   }  /* End of IF minute is within bounds. */
  427.  
  428. } /* End of DrawTheMinuteHand */
  429.  
  430.  
  431. /*************************************************************************
  432.  * Name        : PlaceTheTimeMarkers
  433.  *
  434.  * Description : This procedure will take the given parameters and
  435.  *               figure out where to place the given clock markers on the
  436.  *               face of the clock, i.e., where a 1, 2, 3,.. would be
  437.  *               placed on a real clock face.
  438.  *
  439.  * Concepts    : None.
  440.  *
  441.  * MMPM/2 API's: None.
  442.  *
  443.  * Parameters  : hps                - Handle to the presentation space.
  444.  *               pptlMarkerPosition - Will hold the point to place a numeral.
  445.  *               usClockNumeral     - The current time marker.
  446.  *
  447.  * Return      : pptlMarkerPosition - Holds the coordinates for the numeral.
  448.  *
  449.  *************************************************************************/
  450. VOID PlaceTheTimeMarkers( HPS     hps,
  451.                           PPOINTL pptlMarkerPosition,
  452.                           USHORT  usClockNumeral )
  453. {
  454.    /*
  455.     * See if the time marker is for the 12 o' clock position, if so, make
  456.     * the value 0 so that the index into the position array will work
  457.     * correctly.
  458.     */
  459.    if ( usClockNumeral == 12 )
  460.    {
  461.       usClockNumeral = 0;
  462.    }
  463.  
  464.    /*
  465.     * If the clock value is in range draw the marker on the clock face.
  466.     * - Get the position for the marker based on the given clock value.
  467.     * - See if the clock value requires a BIG marker or a SMALL marker.
  468.     * - Draw the appropriate marker.
  469.     */
  470.    if ( usClockNumeral > -1 && usClockNumeral < 12 )
  471.    {
  472.  
  473.       pptlMarkerPosition->x +=
  474.          (aptlMarkerPosition[ usClockNumeral * HOUR_HAND_INDEX ].x );
  475.       pptlMarkerPosition->y +=
  476.          (aptlMarkerPosition[ usClockNumeral * HOUR_HAND_INDEX ].y );
  477.  
  478.       /*
  479.        * If the clock numeral is 3, 6, 9, or 0(12) then place a big circle
  480.        * on the clock face, otherwise place a little circle.
  481.        */
  482.       if ( usClockNumeral == 3 || usClockNumeral == 6 ||
  483.            usClockNumeral == 9 || usClockNumeral == 0   )
  484.       {
  485.          DrawClockCircles(
  486.             hps,                 /* Handle to the Presentation space.         */
  487.             pptlMarkerPosition,  /* Position to place the Marker.             */
  488.             CLR_BLUE,            /* Color to make the end dot.                */
  489.             (USHORT) 4 );        /* Size of the time marker circle.  Bigger.  */
  490.       }
  491.       else
  492.       {
  493.          DrawClockCircles(
  494.             hps,                 /* Handle to the Presentation space.         */
  495.             pptlMarkerPosition,  /* Position to place the Marker.             */
  496.             CLR_BLUE,            /* Color to make the end dot.                */
  497.             (USHORT) 2 );        /* Size of the time marker circle.  Smaller .*/
  498.       }  /* End of IF which marker to draw. */
  499.  
  500.    }  /* End of checking for valid value. */
  501.  
  502. } /* End of PlaceTheTimeMarkers */
  503.  
  504.  
  505.  
  506. /*************************************************************************
  507.  * Name        : DrawClockCircles
  508.  *
  509.  * Description : This procedure will take the given parameters and place
  510.  *               a circle at some point in the Presentation Space.  The
  511.  *               circle size, color, and position is given by the calling
  512.  *               routine.
  513.  *
  514.  * Concepts    : None.
  515.  *
  516.  * MMPM/2 API's: None.
  517.  *
  518.  * Parameters  : hps - The handle to the Presentation space.  This will
  519.  *                     allow the procedure to draw the bitmaps onto the
  520.  *                     screen.
  521.  *               pptlMarkerPosition - The point to place the marker.
  522.  *               lCircleColor       - The color to make the marker.
  523.  *               usCircleSize       - How big to make the marker.
  524.  *
  525.  * Return      : None.
  526.  *
  527.  *************************************************************************/
  528. VOID DrawClockCircles( HPS     hps,
  529.                        PPOINTL pptlMarkerPosition,
  530.                        LONG    lCircleColor,
  531.                        USHORT  usCircleSize )
  532. {
  533.    /*
  534.     * Set the color of the Time markers.
  535.     */
  536.    GpiSetColor(
  537.       hps,              /* Presentation Space.                                */
  538.       lCircleColor );   /* Color to use for the clock, Black                  */
  539.  
  540.    /*
  541.     * Move to the starting position of the marker.
  542.     */
  543.    GpiMove(
  544.       hps,
  545.       pptlMarkerPosition );
  546.  
  547.    GpiFullArc(
  548.       hps,                       /* Presentation Space.                       */
  549.       DRO_OUTLINEFILL,           /* Fills the interior of the circle.         */
  550.       (usCircleSize * 65536) );  /* How big is the circle.                    */
  551.  
  552. }  /* End of DrawClockCircles */
  553.  
  554.  
  555.