I originally posted this in a reply to BCD Clock built using only binary logic.
It was inspired by jryan and LED Clock
Version 1.0 I wrote this to give a graphical rpresentation of the original post.
Version 2.0 I wrote to teach my self Tk Canvas programming and auto resize.
I am sure there is a better way to the the auto resize than the clunky way I am doing it now.
If anyone has suggestions on how to imporove the resize code or any other aspect please post them.
Thanks,
Three
#--------------------------------------------------------------
# Perl BCD Clock v2.0
#
# By Three
#
# Inspired by
# Think Geek - LED Binary Clock at http://www.thinkgeek.com/cub
+egoodies/lights/59e0/
# PerlMonks jryan at http://www.perlmonks.com/index.pl?node_id=
+104914
#
# Origionaly posted at http://www.perlmonks.com/index.pl?node_id=22
+3195
#
# Updates
# Replaced radio buttons with direct canvas drawing.
# Auto resizes according to window size.
# Replaced clunky set_column sub
#
#--------------------------------------------------------------
#Emulate think geek binary clock in perl tk
use strict;
use warnings;
#Get package in PPM by install Tk
use Tk;
#Size varables
my $diamater;
my $column_size;
my $row_size;
my $column_mid_point;
my $row_mid_point;
#Setup the screen
my $main=MainWindow->new();
$main->MoveToplevelWindow(1,1);
$main->title("BCD Clock");
#Setup Image at default heights
my $canvas = $main->Canvas(-width => 150, -height => 100)->pack(-fill=
+>"both",-expand =>"true");
#Setup screen update timer
my $status_timer = Tk::After->new($main,'1000','repeat',\&process_loop
+);
#Loop for visuals
MainLoop();
#--------------------------------------------------------------
# Main process loop
#--------------------------------------------------------------
sub process_loop {
#Main loop of program
#Clear the canvas
$canvas->delete('all');
#Get local time
my @lt = localtime;
#Handle single digit problem by left fill 0
if(length($lt[2]) == 1) { $lt[2] = '0' . $lt[2]; }
if(length($lt[1]) == 1) { $lt[1] = '0' . $lt[1]; }
if(length($lt[0]) == 1) { $lt[0] = '0' . $lt[0]; }
#Calculate positons
$column_size = $canvas->Width / 6;
$row_size = $canvas->Height / 4;
#Compare column size to get the diamater
if($column_size > $row_size) {
#If column bigger than row then force row diamater
$diamater = $row_size;
} else {
#If column less than row then force column diamater
$diamater = $column_size;
}
#Reduce the diamater to 6/8 of diamater
$diamater = ($diamater / 8) * 6;
#Calculete the midpoints
$column_mid_point = ($column_size - $diamater) / 2;
$row_mid_point = ($row_size - $diamater) / 2;
#Set the radio buttons based on value and position
set_column(substr($lt[2],0,1), $column_mid_point);
set_column(substr($lt[2],1,1), $column_size + $column_mid_point )
+;
set_column(substr($lt[1],0,1), $column_size * 2 + $column_mid_poi
+nt);
set_column(substr($lt[1],1,1), $column_size * 3 + $column_mid_poi
+nt);
set_column(substr($lt[0],0,1), $column_size * 4 + $column_mid_poi
+nt);
set_column(substr($lt[0],1,1), $column_size * 5 + $column_mid_poi
+nt);
}
#--------------------------------------------------------------
# Makes the led's based on value and column location
#--------------------------------------------------------------
sub set_column {
#Ugly cludge to set the radio buttons
my ($value, $column) = @_;
#Get ths bits of the value
my @bits = substr(unpack("B*",$value),-4) =~ /\w/g;
#Check digit 8 for skip conditons of Hours digit 1, Minute digit 1
+, Seconds digit 1
if($column != $column_mid_point and $column != $column_size * 2 +
+ $column_mid_point and $column != $column_size * 4 + $column_mid_poi
+nt) {
#Draw digit 8 based on $bits[0]
$canvas->createOval($column, $row_mid_point,$column + $diamate
+r, $row_mid_point + $diamater, -fill => $bits[0]?"RED":"BLACK");
}
#Check digit 4 for skip conditons of Hours digit 2
if($column != $column_mid_point) {
#Draw digit 4 based on $bits[1]
$canvas->createOval($column, $row_size + $row_mid_point,$colum
+n + $diamater,$row_size + $diamater + $row_mid_point, -fill => $bits[
+1]?"RED":"BLACK");
}
#Draw digit 8 based on $bits[2]
$canvas->createOval($column, $row_size * 2 + $row_mid_point,$colum
+n + $diamater,$row_size * 2 + $diamater + $row_mid_point, -fill => $b
+its[2]?"RED":"BLACK");
#Draw digit 8 based on $bits[3]
$canvas->createOval($column, $row_size * 3 + $row_mid_point,$colum
+n + $diamater,$row_size * 3 + $diamater + $row_mid_point, -fill => $b
+its[3]?"RED":"BLACK");
}