[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[MacPerl] Clock, re-Styled, for discussion



I have a few suggestions to make about style, and Kevin has provided
us with a nifty starting point, so here is my version of his Clock
script.  My changes should provoke at least SOME discussion (:-).

Essentially, I:

  *  lined up lines of code to neaten and clarify parallelism
  *  shortened the $mdh calculation a bit
  *  added a header block
  *  added a few parentheses, spaces, and leading zeroes
  *  pulled the subroutine definitions away from the main code

The following line is far too "cute" (read, mysterious) for my taste:

    if ($t != ($tt = time) and $t = $tt) {

So I replaced it with:

    $tt = time();
    if ($t != $tt) {
      $t = $tt;

-r

=====

#!perl -w

# Clock - display an analog/digital clock window on the Mac's screen
#
# Written by Kevin Reid <kpreid@ibm.net>, 9810?? (???)
# Modified by Rich Morin <rdm@ptf.com>,   981029 (public domain)

use Mac::Events;
use Mac::Windows;
use Mac::QuickDraw;
use Mac::Menus;
use Time::Local;

@divs = (0.4, 0.75, 0.90);
$showtext  = 1;
$showtitle = 1;
$pi  = 3.14159;
$pi2 = $pi * 2;
$wrect = new Rect (100, 100, 300, 250);

$lgray = new RGBColor ((50000) x 3);
$dgray = new RGBColor ((10000) x 3);
$black = new RGBColor (    (0) x 3);
$white = new RGBColor ((65535) x 3);

InitWin($wrect, $showtitle);

$m = new MacHierMenu 2000, '', (
  ['Text Time' => sub {
    $showtext = !$showtext;
    $win->layout;
    SetItemMark $m->{menu}, 1, $showtext  ? "\cR" : '';
  }],
  ['Title Bar' => sub {
    $showtitle = !$showtitle;
    InitWin($win->window->contRgn->rgnBBox, $showtitle);
    SetItemMark $m->{menu}, 2, $showtitle ? "\cR" : '';
  }],
);

SetItemMark $m->{menu}, 1, $showtext  ? "\cR" : '';
SetItemMark $m->{menu}, 2, $showtitle ? "\cR" : '';

$t = $tt = 0;
while ($win->window) {
  $tt = time();
  if ($t != $tt) {
    $t = $tt;
    SetPort($win->window);
    foreach (@hands) {
      InvalRect new Rect (@{$_->{begin}},
                map($_+1, @{$_->{end}}));
    }
#   ($sec, $min, $hr) = localtime;
#   $hands[0]{ang} = $hr % 12 / 12 * $pi2;
#   $hands[1]{ang} = $min     / 60 * $pi2;
#   $hands[2]{ang} = $sec     / 60 * $pi2;

    $tstr = scalar localtime;
    $secs_today = timegm(localtime) % 86400;
    $hands[0]{ang} = $secs_today / -21600 * $pi2;
    $hands[1]{ang} = $secs_today /   3600 * $pi2;
    $hands[2]{ang} = $secs_today /     60 * $pi2;

    calc_hands();
    foreach (@hands) {
      InvalRect new Rect (@{$_->{begin}},
                map($_+1, @{$_->{end}}));
    }
    InvalRect new Rect ($midh - StringWidth($tstr) / 2, $tpos - 10,
                        $midh + StringWidth($tstr) / 2, $tpos + 10)
      if $showtext;
  }
  WaitNextEvent();
}

END {$win->dispose}


sub InitWin {        # Initialize Window
# InitWin($rect,     # bounding rectangle
#         $title);   # show title if true

  my ($rect, $title) = @_;

  $win->dispose if($win);
  $win = new MacColorWindow (
    $rect,
    'Clock',
    1,
    $title ? documentProc : plainDBox,
    1,                  # Anybody know how to write a round WDEF?
  );

  $win->sethook(layout => sub {
    my $wRect = $win->window->contRgn->rgnBBox;
    SetPort($win->window);
    my $sPt = GlobalToLocal(new Point ($wRect->right, $wRect->bottom));

    $midh = $sPt->h * 0.50;
    $midv = ($sPt->v - ($showtext ? 20 : 0)) * 0.50;
    $mdv  = $midv - 10;
    $mdh  = $mdv;
    $mdt  = $sPt->h / 2 - 10;
    $mdv  = $mdh = $mdt if ($mdh > $mdt);
    $tpos = $sPt->v - 10;

    for (0..2) {
      $hands[$_]{len}[0] = $mdh * $divs[$_];
      $hands[$_]{len}[1] = $mdv * $divs[$_];
      $hands[$_]{ang}    = rand() * $pi;
      $hands[$_]{begin}  = [0, 0];
      $hands[$_]{end}    = [0, 0];
    }
    # Indices are $hands[ which hand ]{ len, tip }[ x or y coord ].

    calc_hands();
    InvalRect new Rect (0, 0, $sPt->h, $sPt->v);
  });
  $win->layout;
  $win->sethook(drawgrowicon => sub {});

  RGBBackColor($lgray);
  $win->sethook(redraw => sub {
    RGBForeColor($white);
    FrameOval(new Rect($midh - $mdh + 1, $midv - $mdv + 1,
                       $midh + $mdh + 1, $midv + $mdv + 1));
    RGBForeColor($dgray);
    FrameOval(new Rect($midh - $mdh,     $midv - $mdv,
                       $midh + $mdh,     $midv + $mdv));
    RGBForeColor($black);
    foreach (@hands) {
      MoveTo($midh, $midv);
      LineTo(@{$_->{tip}});
    }
    if ($showtext) {
      MoveTo($midh - StringWidth($tstr) / 2, $tpos);
      DrawString $tstr;
    }
  });

  $win->sethook(click => sub {
  if ($Mac::Events::CurrentEvent->modifiers & controlKey) {
      my ($mw, $pt) = @_;
      $m->insert;
      my $mp = LocalToGlobal(GetMouse);
      PopUpMenuSelect $m->{menu}, $mp->v, $mp->h, 1;
      $m->delete;
    } else {
      DragWindow($win->window, $Mac::Events::CurrentEvent->where);
    }
  });
}


sub calc_hands {            # Calculate hand images
#  calc_hands();

  foreach (@hands) {
    $_->{tip}[0] =  sin($_->{ang}) * $_->{len}[0] + $midh;
    $_->{tip}[1] = -cos($_->{ang}) * $_->{len}[1] + $midv;
    @box = map {($$_[0] < $$_[1]) ? $_ : [$$_[1], $$_[0]]}
      ([$_->{tip}[0], $midh], [$_->{tip}[1], $midv]);
    $_->{begin} = [$box[0][0], $box[1][0]];
    $_->{end}   = [$box[0][1], $box[1][1]];
  }
}

__END__

Rich Morin:          rdm@cfcl.com, +1 650-873-7841, http://www.ptf.com/~rdm
Prime Time Freeware: info@ptf.com, +1 408-433-9662, http://www.ptf.com
MacPerl: http://www.ptf.com/macperl,   http://www.ptf.com/ptf/products/MPPE
MkLinux: http://www.mklinux.apple.com, http://www.ptf.com/ptf/products/MKLP



***** Want to unsubscribe from this list?
***** Send mail with body "unsubscribe" to mac-perl-request@iis.ee.ethz.ch