home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / i / iv26_w_3.zip / EXAMPLES / DCLOCK / DFACE.C < prev    next >
C/C++ Source or Header  |  1992-03-03  |  8KB  |  291 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. /*
  24.  * digital clockface class
  25.  */
  26.  
  27. #include "dclock.h"
  28. #include "dface.h"
  29. #include "digit.h"
  30. #include "clocktime.h"
  31. #include <string.h>
  32.  
  33. static const int FadeDelay = 10000;
  34.  
  35. void DFace::DrawFace () {
  36.     output->ClearRect(canvas, 0, 0, xmax, ymax);
  37. }
  38.  
  39. void DFace::DrawColon () {
  40.     output->FillPolygon(canvas, colon[0].x, colon[0].y, colon[0].count);
  41.     output->FillPolygon(canvas, colon[1].x, colon[1].y, colon[1].count);
  42. }
  43.  
  44. void DFace::DrawAMPM (Painter *painter) {
  45.     if (AMPMmode != BLANK) {
  46.     if (AMPMmode == AM) {
  47.         painter->FillPolygon(canvas, A.x, A.y, A.count);
  48.     } else {
  49.         painter->FillPolygon(canvas, P.x, P.y, P.count);
  50.     }
  51.     painter->FillPolygon(canvas, M.x, M.y, M.count);
  52.     }
  53. }
  54.  
  55. void DFace::DrawDate () {
  56.     if (showDate && date.len != 0) {
  57.     Font* f = output->GetFont();
  58.     Coord dateYPos = ymax - f->Height();
  59.     Coord dateXPos = 2;
  60.  
  61.     int availWidth = xmax - dateXPos - 2;
  62.     int dayWidth = f->Width( date.text, 3 );
  63.     int dayDateWidth = f->Width( date.text, 10 );
  64.     int wholeWidth = f->Width( date.text, date.len );
  65.  
  66.     output->ClearRect(canvas, 0, ymax - f->Height(), xmax, ymax);
  67.     if (wholeWidth < availWidth) {
  68.         output->Text(canvas, date.text, date.len, dateXPos, dateYPos);
  69.     } else if (dayDateWidth < availWidth) {
  70.         output->Text(canvas, date.text, 10, dateXPos, dateYPos);
  71.     } else if (dayWidth < availWidth) {
  72.         output->Text(canvas, date.text, 3, dateXPos, dateYPos);
  73.     }
  74.     }
  75. }
  76.  
  77. void DFace::DrawBorder () {
  78.     if (showDate && showTime) {
  79.     int ypos = ymax - output->GetFont()->Height() - 2;
  80.     output->Line(canvas, 0, ypos, xmax, ypos);
  81.     }
  82. }
  83.  
  84. void DFace::Tick () {
  85.     int nextTick = clock->NextTick();
  86.     if (nextTick > 0) {
  87.     input->CatchTimer(nextTick + 1, 0); // this extra second makes sure the
  88.     } else {                    // timeout is after the next minute
  89.     int h, m, s;
  90.     char date[50];
  91.     clock->GetTime(date, h, m, s);
  92.     Set(date, h, m);
  93.     }
  94. }
  95.  
  96. void DFace::Set (char *today, int hours, int minutes) {
  97.     int h = hours;
  98.     if (mode==CIVIL) {
  99.     if (hours > 12) {
  100.         h -= 12;
  101.     } else if ( hours == 0 ) {
  102.         h = 12;                // midnight is 12:xx
  103.     }
  104.     }
  105.  
  106.     Event e;
  107.     Sensor* wait = new Sensor;
  108.     wait->CatchTimer(0,0);
  109.     Listen(wait);
  110.     unsigned long lasttime;
  111. //    unsigned long fade = FadeDelay * (1 << (min(4,max(0,FadeRate))) );
  112.     unsigned long fade = 1000;
  113.  
  114.     boolean done = false;
  115.     while (showTime && !done) {
  116.     Read(e);
  117.     lasttime = e.timestamp;
  118.     done = true;
  119.     if (mode == CIVIL && h < 10) {
  120.         done &= ht->Set(-1);        // blank digit
  121.     } else {
  122.         done &= ht->Set(h/10);
  123.     }
  124.     done &= hu->Set(h%10);
  125.     done &= mt->Set(minutes/10);
  126.     done &= mu->Set(minutes%10);
  127.  
  128.     wait->CatchTimer(0, 0);
  129.     Read(e);
  130.     wait->CatchTimer(0, int(lasttime+fade - e.timestamp));
  131.     }
  132.  
  133.     Listen(input);
  134.     Unref(wait);
  135.  
  136.     if (showTime && mode==CIVIL) {
  137.     AMPMMODE newAMPM = (hours >= 12) ? PM : AM;
  138.  
  139.     if (AMPMmode == BLANK) {
  140.         AMPMmode = newAMPM;
  141.         DrawAMPM(output);
  142.     } else if (AMPMmode != newAMPM) {
  143.         DrawAMPM(invertor);                // erase old
  144.         AMPMmode = newAMPM;
  145.         DrawAMPM(output);                // draw new
  146.     }
  147.     }
  148.     if (showDate && strcmp(date.text, today) != 0) {
  149.     strcpy(date.text, today);
  150.     date.len = strlen(today);
  151.     DrawDate();
  152.     if (showBorder) {
  153.         DrawBorder();
  154.     }
  155.     }
  156. }
  157.  
  158. DFace::DFace (
  159.     boolean showDate, boolean showBorder, boolean showTime,
  160.     TMode timeMode, int width, int height
  161. ) {
  162.     clock = new Clock();
  163.     mode = timeMode;
  164.     AMPMmode = BLANK;
  165.     A.count = AData.count;
  166.     P.count = PData.count;
  167.     M.count = MData.count;
  168.     colon[0].count = ColonData[0].count;
  169.     colon[1].count = ColonData[1].count;
  170.     this->showDate = showDate;
  171.     this->showBorder = showBorder;
  172.     this->showTime = showTime;
  173.     ht = new Digit(HTx, ALLy);
  174.     hu = new Digit(HUx, ALLy);
  175.     mt = new Digit(MTx, ALLy);
  176.     mu = new Digit(MUx, ALLy);
  177.     selected = false;
  178.     done = false;
  179.     date.len = 0;
  180.     shape->Rect(width, height);
  181.     shape->Rigid(hfil, hfil, vfil, vfil);
  182.     invertor = nil;
  183.     input = new Sensor;
  184.     input->CatchTimer(0, 0);
  185.     input->Catch(KeyEvent);
  186. }
  187.  
  188. void DFace::Reconfig () {
  189.     Unref(invertor);
  190.     invertor = new Painter(output);
  191.     invertor->Reference();
  192.     invertor->SetColors(invertor->GetBgColor(), invertor->GetFgColor());
  193.     ht->Reconfig(output);
  194.     hu->Reconfig(output);
  195.     mt->Reconfig(output);
  196.     mu->Reconfig(output);
  197. }
  198.  
  199. DFace::~DFace () {
  200.     delete clock;
  201.     delete ht;
  202.     delete hu;
  203.     delete mt;
  204.     delete mu;
  205.     Unref(invertor);
  206. }
  207.  
  208. void DFace::Resize () {
  209.     int i;
  210.  
  211.     int w = xmax;
  212.     int h = ymax;
  213.     if (showDate) {
  214.     // adjust vertical size for date
  215.     h -= output->GetFont()->Height();
  216.     }
  217.     // resize colon
  218.     for (i = 0; i < colon[0].count; i++) {
  219.     colon[0].x[i] = Coord(ColonData[0].x[i] * w );
  220.     colon[0].y[i] = Coord(ColonData[0].y[i] * h );
  221.     colon[1].x[i] = Coord(ColonData[1].x[i] * w );
  222.     colon[1].y[i] = Coord(ColonData[1].y[i] * h );
  223.     }
  224.     // resize AM/PM
  225.     for (i = 0; i < 12; i++) {
  226.     A.x[i] = Coord(AData.x[i] * w);
  227.     A.y[i] = Coord(AData.y[i] * h);
  228.     P.x[i] = Coord(PData.x[i] * w);
  229.     P.y[i] = Coord(PData.y[i] * h);
  230.     M.x[i] = Coord(MData.x[i] * w);
  231.     M.y[i] = Coord(MData.y[i] * h);
  232.     }
  233.     if (showTime) {
  234.     ht->Resize(canvas, h);
  235.     hu->Resize(canvas, h);
  236.     mt->Resize(canvas, h);
  237.     mu->Resize(canvas, h);
  238.     }
  239. }
  240.  
  241. void DFace::Redraw (Coord left, Coord bottom, Coord right, Coord top) {
  242.     output->Clip(canvas, left, bottom, right, top);
  243.     Draw();
  244.     output->NoClip();
  245. }
  246.  
  247. void DFace::RedrawList (int, Coord[], Coord[], Coord[], Coord[]) {
  248.     Redraw(0, 0, xmax, ymax);
  249. }
  250.  
  251. void DFace::Draw () {
  252.     DrawFace();
  253.     if (showDate) {
  254.     DrawDate();
  255.     }
  256.     if (showTime) {
  257.     DrawColon();
  258.     DrawAMPM(output);
  259.     ht->Redraw();
  260.     hu->Redraw();
  261.     mt->Redraw();
  262.     mu->Redraw();
  263.     }
  264.     if (showBorder) {
  265.     DrawBorder();
  266.     }
  267. }
  268.  
  269. void DFace::Handle (Event &event) {
  270.     switch (event.eventType) {
  271.     case KeyEvent:
  272.         if (event.len > 0 && event.keystring[0] == 'q') {
  273.         done = true;
  274.         }
  275.         break;
  276.     case TimerEvent:
  277.         Tick();
  278.         break;
  279.     }
  280. }
  281.  
  282. void DFace::Run () {
  283.     Event event;
  284.  
  285.     while (!done) {
  286.     Read(event);
  287.     Handle(event);
  288.     Tick();
  289.     }
  290. }
  291.