|
|
1.1 ! root 1: /* APPPaint() - Parent window WM_PAINT processing routine. ! 2: * ! 3: * Created by Microsoft Corp., 1988 ! 4: * ! 5: * Purpose: ! 6: * Routine to graph biorythm cycles and tabulate dates. ! 7: * ! 8: * Arguments: ! 9: * hWnd - Handle of Window owning message ! 10: * message - Message itself ! 11: * mp1 - Extra message-dependent info ! 12: * mp2 - Extra message-dependent info ! 13: * ! 14: * Return Value: ! 15: * void ! 16: * ! 17: * Globals (modified): ! 18: * none ! 19: * ! 20: * Globals (static): ! 21: * Cycle[] - Array holding period for phy/emot/int: 23,28,33 ! 22: * cDayOfWeek[] - Array of chars holding first letter of days of week. ! 23: * Color[] - Set of colored pens used to identify cycles. ! 24: * ! 25: * Globals (referenced): ! 26: * Born - Bithdate in julian days. Read from WIN.INI. ! 27: * SelectDay - Current day being tracked, day is highlighted. Is ! 28: * in units of days from birth date. Date of present ! 29: * day initially used in WM_CREATE. ! 30: * Day - Day number from date born which is top line being ! 31: * displayed. Initially three days before SelectDay. ! 32: * bBorn - Boolean indicating whether valid birtdate entered or ! 33: * rectClient - Size of client area defined by WM_SIZE message ! 34: * LinesPerPage - Number of system font lines on client area, defined ! 35: * by WM_SIZE message handling ! 36: * tmFontInfo - Text Metric structure defined during WM_CREATE ! 37: * ! 38: * Description: ! 39: * Tabulates dates and graphs cycles. On color displays, weekends ! 40: * are written in red. The update rectangle is used to minimize ! 41: * repaint time of affected client area. ! 42: * ! 43: * Limits: ! 44: * N/A ! 45: */ ! 46: ! 47: #define INCL_WIN ! 48: #define INCL_GPI ! 49: #include <os2.h> ! 50: ! 51: #include "bio.h" ! 52: #include <math.h> ! 53: #include <stdio.h> ! 54: ! 55: /* Read-only global variables */ ! 56: extern double Born; ! 57: extern long Day, SelectDay; ! 58: extern BOOL bBorn; ! 59: extern FONTMETRICS tmFontInfo; ! 60: extern int LinesPerPage; ! 61: extern RECTL rectClient; ! 62: ! 63: /* Read-only static variables */ ! 64: static double Cycle[] = { 23.0, 28.0, 33.0 }; ! 65: static char cDayOfWeek[] = "MTWTFSS"; ! 66: extern LONG Color[]; ! 67: ! 68: VOID FAR PASCAL APPPaint( hWnd ) ! 69: HWND hWnd; ! 70: { ! 71: HPS hPS; ! 72: POINTL ptl; ! 73: int y, i; ! 74: int start, last; ! 75: char szDay[16]; ! 76: int Amplitude, offset; ! 77: int year, month; ! 78: double day; ! 79: RECTL rc, rcClip; ! 80: int DayOfWeek; ! 81: HRGN hrgnClip; ! 82: ! 83: hPS = WinBeginPaint( hWnd, NULL, &rcClip ); ! 84: ! 85: /* Erase client area */ ! 86: WinQueryWindowRect( hWnd, &rc ); ! 87: WinFillRect( hPS, &rc, CLR_WHITE ); ! 88: ! 89: /* Label parts of table and graph. */ ! 90: ptl.y = rectClient.yTop - tmFontInfo.lMaxBaselineExt + /* Top line */ ! 91: tmFontInfo.lMaxDescender; ! 92: ptl.x = 0; ! 93: GpiCharStringAt( hPS, &ptl, 6L, (PCH)" DATE" ); ! 94: ptl.x = 11 * tmFontInfo.lAveCharWidth; ! 95: GpiCharStringAt( hPS, &ptl, 3L, (PCH)"LOW" ); ! 96: ptl.x = rectClient.xRight - 5 * tmFontInfo.lAveCharWidth; ! 97: GpiCharStringAt( hPS, &ptl, 4L, (PCH)"HIGH" ); ! 98: ! 99: /* Underline labels from left to right across client area */ ! 100: ptl.y = rectClient.yTop - tmFontInfo.lMaxBaselineExt; ! 101: ptl.x = 0; ! 102: GpiMove( hPS, &ptl ); ! 103: ptl.x = rectClient.xRight; ! 104: GpiLine( hPS, &ptl ); ! 105: ! 106: /* Draw a vertical line separator between dates and cycles */ ! 107: ptl.y = rectClient.yTop; ! 108: ptl.x = 10 * tmFontInfo.lAveCharWidth; ! 109: GpiMove( hPS, &ptl ); ! 110: ptl.y = rectClient.yBottom; ! 111: GpiLine( hPS, &ptl ); ! 112: ! 113: /* Draw a dotted vertical center line to reference cycles */ ! 114: GpiSetLineType( hPS, LINETYPE_DOT ); ! 115: ptl.x = (10 * tmFontInfo.lAveCharWidth + rectClient.xRight) / 2; ! 116: GpiMove( hPS, &ptl ); ! 117: ptl.y = rectClient.yTop; ! 118: GpiLine( hPS, &ptl ); ! 119: /* (Should not have to restore line type after EndPaint) */ ! 120: GpiSetLineType( hPS, LINETYPE_DEFAULT ); ! 121: ! 122: /* Update only the range of lines which fall into update rectangle */ ! 123: start = (int)((rectClient.yTop - rcClip.yTop) / tmFontInfo.lMaxBaselineExt); ! 124: if (start<1) ! 125: start = 1; ! 126: last = (int)((rectClient.yTop - rcClip.yBottom) / tmFontInfo.lMaxBaselineExt); ! 127: if (last>(LinesPerPage-1)) ! 128: last = LinesPerPage-1; ! 129: ! 130: /* Set clip rectangle to completely draw entire rectangle representing ! 131: each date affected. Start drawing one day before and after ! 132: (outside clip rectangle) so that cycle lines will connect correctly ! 133: with unaffected lines. */ ! 134: rcClip.yTop = rectClient.yTop - start*tmFontInfo.lMaxBaselineExt; ! 135: start--; ! 136: last++; ! 137: rcClip.yBottom = rectClient.yTop - last*tmFontInfo.lMaxBaselineExt + 1; ! 138: hrgnClip = GpiCreateRegion( hPS, 1L, &rcClip ); ! 139: GpiSetClipRegion( hPS, hrgnClip ); ! 140: ! 141: /* List days and date */ ! 142: for (y=start; y<=last; y++) { ! 143: /* Get the calendar date from julian day */ ! 144: calendar( Born+Day+y-1, &year, &month, &day ); ! 145: /* Get offset into days of the week initials array */ ! 146: DayOfWeek = (int)((LONG)(Born+Day+y) % 7); ! 147: /* Assemble each of the parts in a buffer */ ! 148: sprintf(szDay, "%c %02d-%02d-%02d", cDayOfWeek[DayOfWeek], ! 149: month, (int)day, year - (trunc4((double)year / 100)*100) ); ! 150: /* If color available, draw weekends in red */ ! 151: if (DayOfWeek > 4) ! 152: GpiSetColor( hPS, CLR_RED ); ! 153: ptl.x = 0; ! 154: ptl.y = rectClient.yTop - ((y+1)*tmFontInfo.lMaxBaselineExt - ! 155: tmFontInfo.lMaxDescender); ! 156: GpiCharStringAt( hPS, &ptl, 10L, (PCH)szDay ); ! 157: GpiSetColor( hPS, CLR_BLACK ); ! 158: } ! 159: ! 160: /* Amplitude of sin wave is half client area minus space for dates */ ! 161: Amplitude = (int)((rectClient.xRight - 11 * tmFontInfo.lAveCharWidth) / 2); ! 162: /* Move to right, make room for column of dates */ ! 163: offset = (int)(Amplitude + 11 * tmFontInfo.lAveCharWidth - 4); ! 164: for (i=0; i<3 && bBorn; i++ ) { ! 165: GpiSetColor( hPS, Color[i] ); ! 166: for (y=start; y<=last; y++) { ! 167: ptl.x = (int)(sin( (y+Day-1)/Cycle[i]*2*3.14159 ) * Amplitude + offset); ! 168: ptl.y = rectClient.yTop - (y*tmFontInfo.lMaxBaselineExt + ! 169: tmFontInfo.lMaxBaselineExt/2); ! 170: if ((y+Day-1 > 0) && (y>start)) ! 171: GpiLine( hPS, &ptl ); ! 172: else ! 173: GpiMove( hPS, &ptl ); ! 174: } ! 175: } ! 176: ! 177: /* Draw highlight on selected day if visible. */ ! 178: if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage - 1)) { ! 179: rc.xRight = rectClient.xRight; ! 180: rc.xLeft = rectClient.xLeft; ! 181: rc.yTop = rectClient.yTop - (int)(SelectDay - Day + 1) * tmFontInfo.lMaxBaselineExt; ! 182: rc.yBottom = rc.yTop - tmFontInfo.lMaxBaselineExt + 1; ! 183: WinInvertRect( hPS, &rc ); ! 184: } ! 185: ! 186: WinEndPaint( hPS ); ! 187: ! 188: return; ! 189: } ! 190: ! 191: ! 192: /* julian() - Compute julian date from Gregorian calendar date. ! 193: * ! 194: * Purpose: ! 195: * Provide a standard time base. ! 196: * ! 197: * Arguments: ! 198: * year - Calendar year ! 199: * month - Calendar month ! 200: * day - Calendar day and fraction ! 201: * ! 202: * Return Value: ! 203: * double - Julian date converted ! 204: * ! 205: * Globals (modified): ! 206: * none ! 207: * ! 208: * Globals (referenced): ! 209: * none ! 210: * ! 211: * Description: ! 212: * Convert Gregorian dates to Julian Days. Refer to Alamanac for ! 213: * Computers (1978), p. B2, Naval Observatory Pub. ! 214: * ! 215: * Limits: ! 216: * Valid between ~1900 and 2099. ! 217: * ! 218: */ ! 219: ! 220: double PASCAL julian (year, month, day) ! 221: int year, month; ! 222: double day; ! 223: { ! 224: double dj; ! 225: double fracDay, intDay; ! 226: ! 227: fracDay = modf(day, &intDay); ! 228: dj = (long)367*year - 7*(year + (month+9) / 12) / 4 + 275*month / 9 + ! 229: intDay + 1721013.5 + fracDay; ! 230: return dj; ! 231: } ! 232: ! 233: ! 234: /* calendar() - Compute Gregorian calendar date from julian date. ! 235: * ! 236: * Purpose: ! 237: * Provide a standard time base. ! 238: * ! 239: * Arguments: ! 240: * juldate - Julian date to convert ! 241: * year - Calendar year result ! 242: * month - Calendar month result ! 243: * day - Calendar day and fraction result ! 244: * ! 245: * Return Value: ! 246: * void ! 247: * ! 248: * Globals (modified): ! 249: * none ! 250: * ! 251: * Globals (referenced): ! 252: * none ! 253: * ! 254: * Description: ! 255: * Convert Julian Days to Gregorian date. Refer to Astronomical ! 256: * Formulae for Calculators (1979), p. 23, by Jean Meeus. ! 257: * ! 258: * Limits: ! 259: * Valid for positive Julian Day values. ! 260: * ! 261: */ ! 262: ! 263: void PASCAL calendar (juldate, year, month, day) ! 264: double juldate; ! 265: int *year; ! 266: int *month; ! 267: double *day; ! 268: { ! 269: long b, c, d, e, z, alf; ! 270: ! 271: juldate = juldate + 0.5; ! 272: z = trunc4(juldate); ! 273: alf = trunc4((z - 1867216.25)/36524.25); ! 274: b = z + 1 + alf - alf / 4 + 1524; ! 275: c = trunc4((b - 122.1)/365.25); ! 276: d = 365*c + c / 4; ! 277: e = trunc4((b - d)/30.6001); ! 278: *day = b - d - trunc4(30.6001*e) + juldate - z; ! 279: if (e > 13) ! 280: *month = (int)e - 13; ! 281: else ! 282: *month = (int)e - 1; ! 283: if (*month > 2) ! 284: *year = (int)c - 4716; ! 285: else ! 286: *year = (int)c - 4715; ! 287: } ! 288: ! 289: long PASCAL trunc4( dflValue ) ! 290: double dflValue; ! 291: { ! 292: double intValue; ! 293: modf(dflValue, &intValue); ! 294: return (long)intValue; ! 295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.