Tk::LCD Investigations
I recently made a UTC clock script using Tk::LCD. It simulates the look of a 7-segment LCD display. The elements/digits are designed around a 22x36 pixel block(large) and an 11x18 pixel block(small). In using this package, I determined that the digits were too small and that leading zeros weren't displayed. I implemented an option for displaying leading zeros and another for scaling the elements to an arbitrary multiple(where 1 equals the original large size). I plan a separate post to discuss these changes further.
This post concerns a test script for adding support for special characters in this case the : (colon). Currently Tk::LCD only supports numbers, minus, and space. This script draws a : within a 22x36 pixel block and provides for scaling to an arbitrary multiple.
The challenge of this script was in returning lists from a callback. While I came across the solution(call by reference and the $_[0] construct) fairly quickly the implementation was not obvious to me. The result is shown below.
I plan to integrate this code into my version of Tk::LCD to allow display of an HH:MM format. Other specical characters could be implemented in a similar way.
Update1: colon2.pl listed below includes changes based on comments to colon1.pl. Thanks to all who provided comments.
#! /usr/bin/perl # colon2.pl - Draw a scalable : (colon) on a canvas # Test script for a planned addition to Tk::LCD.pm # Tk::LCD defines elements within a 22 x 36 pixel re +ctangle # The colon is drawn as two circles within this rect +angle # # @Base shapes are scaled and moved into @scaled sha +pes for display # Clicking the Next or Previous button rescales # and redraws the screen # # James M. Lynes, Jr. - KE4MIQ # Created: March 14, 2023 # Last Modified: 03/14/2023 - Initial Version # 03/15/2023 - First working version # 03/17/2023 - Updated with PerlMonks comments # # Environment: Ubuntu 22.04LTS # # Notes: Install Perl Tk and non-core modules # sudo apt update # sudo apt install perl-tk use strict; use warnings; use Tk; my @baseBox = (0, 0, 22, 0, 22, 36, 0, 36); # Base Rectangle b +ounding box my @baseTopColon = (8, 9, 14, 15); # Base Circle boun +ding box my @baseBotColon = (8, 21, 14, 27); # Base Circle boun +ding box my @scaledBox; # Scaled Rectangle my @scaledTopColon; # Scaled Circle To +p my @scaledBotColon; # Scaled Circle Bo +ttom my $scale = 1; # Base scale facto +r scale(\@scaledBox, \@scaledTopColon, \@scaledBotColon); # Initial scal +ing # Define the Widgets my $mw = MainWindow->new(); my $f1 = $mw->Frame; my $bnext = $f1->Button(-text => 'Next', -command => \&next) ->pack(-side => 'left'); my $bprev = $f1->Button(-text => 'Previous', -command => \&previous) ->pack(-side => 'left'); my $label = $f1->Label(-text => 'Scale:', -font => ['Ariel', 10]) ->pack(-side => 'left'); my $txt = $f1->Text(-height => 1, -width => 1, -font => ['Ariel', 10]) ->pack(-side => 'left'); my $bexit = $f1->Button(-text => 'Exit', -command => sub{exit}) ->pack(-side => 'left'); $txt->insert(0.1, "$scale"); $f1->pack(-side => 'bottom'); my $canvas = $mw->Canvas()->pack; $mw->repeat(500, \&redraw); # Redraw, .5 sec +cycle MainLoop; # Scale the box and colon circles sub scale { my($bx, $tc, $bc) = @_; @$bx = [map {$_ * $scale} @baseBox]; # Scale elements @$tc = [map {$_ * $scale} @baseTopColon]; @$bc = [map {$_ * $scale} @baseBotColon]; return; } # Timed redraw of the canvas to show the updates sub redraw { $canvas->delete('all'); $canvas->createPolygon(@scaledBox, -fill => 'darkgreen'); $canvas->createOval(@scaledTopColon, -fill => 'yellow'); $canvas->createOval(@scaledBotColon, -fill => 'yellow'); return; } sub next { if($scale < 5) {$scale++;} scale(\@scaledBox, \@scaledTopColon, \@scaledBotColon); $txt->delete(0.1, 'end'); $txt->insert(0.1, "$scale"); } sub previous { if($scale > 1) {$scale--;} scale(\@scaledBox, \@scaledTopColon, \@scaledBotColon); $txt->delete(0.1, 'end'); $txt->insert(0.1, "$scale"); }
#! /usr/bin/perl # colon1.pl - Draw a scalable : (colon) on a canvas # Test script for a planned addition to Tk::LCD.pm # Tk::LCD defines elements within a 22 x 36 pixel re +ctangle # The colon is drawn as two circles within this rect +angle # # @Base shapes are scaled and moved into @scaled sha +pes for display # Clicking the Next buttons rescales and redraws the + screen # # James M. Lynes, Jr. - KE4MIQ # Created: March 14, 2023 # Last Modified: 03/14/2023 - Initial Version # 03/15/2023 - First working version # # Environment: Ubuntu 22.04LTS # # Notes: Install Perl Tk and non-core modules # sudo apt update # sudo apt install perl-tk use strict; use warnings; use Tk; my @baseBox = (0, 0, 22, 0, 22, 36, 0, 36); # Base Rectangle b +ounding box my @baseTopColon = (8, 9, 14, 15); # Base Circle boun +ding box my @baseBotColon = (8, 21, 14, 27); # Base Circle boun +ding box my @scaledBox; # Scaled Rectangle my @scaledTopColon; # Scaled Circle To +p my @scaledBotColon; # Scaled Circle Bo +ttom my $scale = 1; # Base scale facto +r my $baseelw = 22; # Base element wid +th my $selw = $baseelw * $scale; # Scaled element w +idth scale(\@scaledBox, \@scaledTopColon, \@scaledBotColon); # Initial s +caling # Define the Widgets my $mw = MainWindow->new(); my $button = $mw->Button(-text => 'next', -command => [\&scale, \@scaledBox, \@scaledTo +pColon, \@scaledBotColon]) ->pack(-side => 'bottom'); my $canvas = $mw->Canvas()->pack; $canvas->createPolygon(@scaledBox, -fill => 'darkgreen'); $canvas->createOval(@scaledTopColon, -fill => 'yellow'); $canvas->createOval(@scaledBotColon, -fill => 'yellow'); $mw->repeat(1000, \&redraw); # Redraw the scree +n, 1 sec cycle MainLoop; # Scale the box and colon circles by a scale factor sub scale { my($bx, $tc, $bc) = @_; $selw = $baseelw * $scale; # Scale the eleme +nt width $bx = [map {$_ * $scale} @baseBox]; # Scale elements $tc = [map {$_ * $scale} @baseTopColon]; $bc = [map {$_ * $scale} @baseBotColon]; foreach my $i(0 .. $#$bx) { # Return scaled e +lements $_[0][$i] = @$bx[$i]; # via referenc +es } foreach my $i(0 .. $#$tc) { $_[1][$i] = @$tc[$i]; } foreach my $i(0 .. $#$bc) { $_[2][$i] = @$bc[$i]; } $scale = $scale + 1; # Bump for next c +ycle return; } # Timed redraw of the canvas to show the updates sub redraw { $canvas->delete('all'); $canvas->createPolygon(@scaledBox, -fill => 'darkgreen'); $canvas->createOval(@scaledTopColon, -fill => 'yellow'); $canvas->createOval(@scaledBotColon, -fill => 'yellow'); return; }
James
There's never enough time to do it right, but always enough time to do it over...
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Tk::LCD Investigations
by kcott (Archbishop) on Mar 16, 2023 at 08:11 UTC | |
by jmlynesjr (Deacon) on Mar 16, 2023 at 14:54 UTC | |
|
Re: Tk::LCD Investigations
by Tux (Canon) on Mar 16, 2023 at 15:59 UTC | |
by jmlynesjr (Deacon) on Mar 17, 2023 at 17:55 UTC | |
|
Re: Tk::LCD Investigations
by jwkrahn (Abbot) on Mar 16, 2023 at 21:32 UTC | |
by jmlynesjr (Deacon) on Mar 17, 2023 at 18:00 UTC | |
|
Re: Tk::LCD Investigations
by Anonymous Monk on Mar 16, 2023 at 11:38 UTC |