Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

wxPerl Simulated LinearPanel Meter

by jmlynesjr (Friar)
on Jan 22, 2013 at 00:35 UTC ( #1014525=CUFP: print w/ replies, xml ) Need Help??

Ok, last one for awhile...

This one is a linear panel meter that can be configured to display vertical or horizontal. Move your mouse up/down or left/right to animate the meter.

#! /home/pete/CitrusPerl/perl/bin/perl # # LinearMeter.pl # This script draws a simulated linear panel meter. # Meter can be configured to be vertical or horizontal # # Move mouse up/down to change the displayed value on vertical meter # (or left/right if reconfigured for horizontal meter) # # Written in wxPerl. Tested on Citrus Perl 5.16 with wxWidgets 2.8.x. # Ported by: James M. Lynes. Jr. # Last Modified Date: January 21, 2013 # # Adapted from LinearMeter.cpp by Marco Cavallini # based in part(mostly) on the work of # the KWIC project (http://www.koansoftware.com/kwic/index.htm). # Referenced on pg 596 of the "Wx Book" - # "Cross-Platform GUI Programming with wxWidgets", Smart, Hock, & Csom +or # # Added high-limit/alarm processing- red/green color change # Added animation # Added label display at bottom of meter # Set an initial value, high-limit, and tic array # # use 5.010; use strict; use warnings; use Wx qw(:everything :allclasses); use Wx::Event qw( EVT_PAINT EVT_ERASE_BACKGROUND EVT_MOTION ); # # Configuration Data ------------------------------------------------- +----------------- # my $MeterHeight = 400; # Swap these for horizontal +display my $MeterWidth = 100; my $ActiveBar = wxGREEN; my $PassiveBar = wxWHITE; my $ValueColour = wxBLACK; my $BorderColour = wxBLUE; my $LimitColour = wxBLACK; my $AlarmLimitColour = wxRED; my $TagsColour = wxBLACK; my $ScaledValue = 0; my $RealVal = 0; my $Limit = 75; # High-Limit setpoint my @TagsVal; my $TagsNum = 0; my $StartTag = 0; my $NumTags = 10; my $IncTag = 10; my $Max = 100; # Span my $Min = 0; my $ramp = 45; # Initial value displayed my $lastpos = 0; # Last mouse position my $DirHorizFlag = 0; # 0-Verticle, 1-Horizontal my $ShowCurrent = 1; my $ShowLimits = 0; my $ShowLabel = 1; my $Font = Wx::Font->new(10, wxFONTFAMILY_SWISS, wxNORMAL, wxNORMAL); my $Label = "Temp degC"; # # Main Application --------------------------------------------------- +-------------------- # my $app = Wx::SimpleApp->new; my $frame = Wx::Frame->new(undef, -1, "", [600,200], [$MeterWidth, $MeterHeight]); EVT_PAINT( $frame, \&onPaint ); EVT_ERASE_BACKGROUND( $frame, \&onEraseBackground ); EVT_MOTION( $frame, \&onMotion ); $frame->Show; $app->MainLoop; # # Dismiss an erase background event ---------------------------------- +------------------- # sub onEraseBackground { my($self, $event) = @_; $event->Skip(); } # # Paint the simulated LCD Display ------------------------------------ +---------------------- # sub onPaint { my($self, $event) = @_; my $dc = Wx::PaintDC->new($self); my $memdc = Wx::MemoryDC->new(); $memdc->SelectObject(Wx::Bitmap->new($MeterWidth, $MeterHeight)); my($w, $h) = $memdc->GetSizeWH(); my $brush = Wx::Brush->new($PassiveBar, wxSOLID); $memdc->SetBackground($brush); $memdc->Clear(); SetUp($memdc); # Set the initial value and +tic marks my $pen = Wx::Pen->new($BorderColour, 2, wxSOLID); $memdc->SetPen($pen); $memdc->DrawRectangle(0, 0, $w, $h); $pen = Wx::Pen->new($BorderColour, 2, wxSOLID); $memdc->SetPen($pen); $brush = Wx::Brush->new($ActiveBar, wxSOLID); if($RealVal > $Limit) {$brush = Wx::Brush->new($AlarmLimitColour, +wxSOLID)} $memdc->SetBrush($brush); my $yPoint; my $rectHeight; if($DirHorizFlag) { # Horizontal Orientatio +n $memdc->DrawRectangle(1, 1, $ScaledValue, $h-2); } else { # Vertical Orientation $yPoint = $h - $ScaledValue; if($ScaledValue == 0) { $rectHeight = $ScaledValue; } else { if($RealVal == $Max) { $rectHeight = $ScaledValue; $yPoint -= 1; } else { $rectHeight = $ScaledValue - 1; } $memdc->DrawRectangle(1, $yPoint, $w-2, $rectHeight); } } if($ShowCurrent) {DrawCurrent($memdc)} if($ShowLimits) {DrawLimits($memdc)} if($TagsNum > 0) {DrawTags($memdc)} if($ShowLabel) {DrawLabel($memdc)} $dc->Blit(0, 0, $w, $h, $memdc, 0, 0); } sub onMotion { # Change the setpoint value and +redraw my($self, $event) = @_; my $y = $event->GetPosition->y; # Current mouse positio +n, swap to (x) for horz if($y > $lastpos) {$ramp -= 1; $lastpos = $y} # Mouse down, dec +rement needle, swap (x/+=)for horz if($y < $lastpos) {$ramp += 1; $lastpos = $y} # Mouse up, incre +ment needle, swap(x/-=) for horz if($ramp >= $Max) {$ramp = $Max;} # Clamp to max range if($ramp <= $Min) {$ramp = $Min;} # Clamp to min range $self->Refresh; $self->Update; } sub SetUp { # Set and update the displayed valu +e my($dc) = @_; SetValue($dc, $ramp); if($TagsNum == 0) { # Build tic marks 1st time +through for($StartTag..$NumTags) { # Quick and dirty AddTag($_ * $IncTag); } } } sub DrawCurrent { # Draw the current value as text my($dc) = @_; my($w, $h) = $dc->GetSizeWH(); my $valuetext = sprintf("%d", $RealVal); my ($tw, $th) = $dc->GetTextExtent($valuetext); $dc->SetTextForeground($ValueColour); $dc->DrawText($valuetext, $w/2-$tw/2, $h/2-$th/2); } sub DrawLimits { # Draw Min and Max as text my($dc) = @_; my($w, $h) = $dc->GetSizeWH(); $dc->SetFont($Font); $dc->SetTextForeground($LimitColour); if($DirHorizFlag) { my $valuetext = sprintf("%d", $Min); my ($tw, $th) = $dc->GetTextExtent($valuetext); $dc->DrawText($valuetext, 5, $h/2-$th/2); $valuetext = sprintf("%d", $Max); ($tw, $th) = $dc->GetTextExtent($valuetext); $dc->DrawText($valuetext, $w-$tw-5, $h/2-$th/2); } else { my $valuetext = sprintf("%d", $Min); my ($tw, $th) = $dc->GetTextExtent($valuetext); $dc->DrawText($valuetext, $w/2-$tw/2, $h-$th-5); $valuetext = sprintf("%d", $Max); ($tw, $th) = $dc->GetTextExtent($valuetext); $dc->DrawText($valuetext, $w/2-$tw/2, 5); } } sub DrawTags { # Draw tic marks and labels my($dc, $Value) = @_; my($w, $h) = $dc->GetSizeWH(); my $tcoeff; if($DirHorizFlag) { $tcoeff = ($w-2)/($Max-$Min); } else { $tcoeff = ($h-2)/($Max-$Min); } my $pen = Wx::Pen->new($TagsColour, 1, wxSOLID); $dc->SetPen($pen); my $brush = Wx::Brush->new($TagsColour, wxSOLID); $dc->SetBrush($brush); $dc->SetTextForeground($TagsColour); my $tag = 0; while($tag < $TagsNum) { my $scalval = ($TagsVal[$tag]-$Min) * $tcoeff; my $textvalue = sprintf("%d", $TagsVal[$tag]); if($DirHorizFlag) { $dc->DrawLine($scalval+1, $h-2, $scalval+1, $h-10); my($tw, $th) = $dc->GetTextExtent($textvalue); $dc->DrawText($textvalue, $scalval+1-($tw/2), $h-10-$th); } else { $dc->DrawLine($w-2, $h-$scalval+1, $w-10, $h-$scalval); my($tw, $th) = $dc->GetTextExtent($textvalue); $dc->DrawText($textvalue, $w-10-$tw, $h-$scalval-($th/2)); } $tag++; } } sub AddTag { # Add a tic mark to array my($val) = @_; push(@TagsVal, $val); $TagsNum = @TagsVal; } sub SetValue { # Scale the value for display my($dc, $Value) = @_; my($w, $h) = $dc->GetSizeWH(); my $coeff; if($DirHorizFlag) { $coeff = ($w-2)/($Max-$Min); } else { $coeff = ($h-2)/($Max-$Min); } $ScaledValue = (($Value-$Min) * $coeff); $RealVal = $Value; } sub DrawLabel { # Draw a label at bottom of met +er my($dc) = @_; my($w, $h) = $dc->GetSizeWH(); my @te = $dc->GetTextExtent($Label); my $x = ($w-$te[0])/2; $dc->DrawText($Label, $x, $h-20); }

James

There's never enough time to do it right, but always enough time to do it over...

Comment on wxPerl Simulated LinearPanel Meter
Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://1014525]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (9)
As of 2014-12-26 22:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls