Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

ButtonFactory

by t0mas (Priest)
on Jun 28, 2000 at 16:40 UTC ( #20139=sourcecode: print w/ replies, xml ) Need Help??

Category: Utility Scripts
Author/Contact Info t0mas@netlords.net
Description: A package that creates custom png buttons.
#!/usr/local/bin/perl -w
#
# ButtonFactory package
# by t0mas@netlords.net
#

package ButtonFactory;

use strict;
use GD;

# libgd should be compiled with TrueType support. The built-in fonts a
+re
# pretty lame IMO (international characters work poorly).

######################################################################
# Config section start

# Location of my ttf fonts
# If set to "", the full path to the font file must be supplied. Windo
+ws
# users might want to set it to c:\\windows\\fonts\\ and *nix users to
# /my/path/to/the/ttf/fonts/
my $FONTDIR="c:\\windows\\fonts\\";

# Fonts will be black or white.
# This value is the breakpoint where it turns white. It is compared to
+ the
# sum of baseR+baseG+baseB. Fonts turn white when this sum drops below
# the breakpoint.
my $FONTCOLORBREAKPOINT=255;

# Height and width of the sides (4 by default)
# Use a sane value > 1 or UltraBad(tm) things will happen
my $SIDE_X_WIDTH=4;
my $SIDE_Y_WIDTH=4;

# Config section end
######################################################################

######################################################################
# My view of a button.
#
# Based on a 4 pixel wide side on all sides :)
#
# Map of the four corners (1-M refers to factors to use)
#
# 69333 333EB
# 97A22 22GCF
# 3A7A2 2GCH5
# 32A83 3DH45
# 32231 15445
#
# 32231 15445
# 32GD5 5KM45
# 3GCH4 4MJM5
# ECH44 44MJL
# BF555 555LI 
#
# Above is the map of the normal (up) state, the pressed state uses
# the same map rotated 180 degrees.
######################################################################

#
# Factors for colors                # on Map
#

my $dark_side_factor =                0.03;    # 4
my $lr_edge_bevel_factor =            0.03;    # M
my $lr_edge_factor =                0.04;    # J
my $llur_b_edge_bevel_factor =        0.24;    # H
my $lr_i_corner_factor =            0.31;    # K
my $dark_edge_factor =                0.44;    # 5
my $lr_o_corner_bevel_factor =        0.47;    # L
my $lr_o_corner_factor =            0.65;    # I
my $llur_edge_factor =                0.72;    # C
my $llur_b_o_corner_bevel_factor =    0.75;    # F
my $llur_i_corner_factor =            0.85;    # D
my $llur_o_corner_factor =            0.95;    # B
my $base_factor =                    1.00;    # 1
my $llur_l_o_corner_bevel_factor =    1.03;    # E
my $llur_l_edge_bevel_factor =        1.07;    # G
my $light_side_factor =                1.17;    # 2
my $light_edge_factor =                1.23;    # 3
my $ul_o_corner_factor =            1.26;    # 6
my $ul_edge_bevel_factor =            1.29;    # A
my $ul_o_corner_bevel_factor =        1.33;    # 9
my $ul_i_corner_factor =            1.39;    # 8
my $ul_edge_factor =                1.41;    # 7

######################################################################
sub new {

    #
    # Create new ButtonFactory
    #

    # Hello, this is me...
    my $self={};

    # Get class and parameters
    my $class=shift;
    
    # Set attributes or defaults 
    $self->{sizeX}=shift    || 100;
    $self->{sizeY}=shift    || 20;
    $self->{baseR}=shift    || 70;
    $self->{baseG}=shift    || 82;
    $self->{baseB}=shift    || 157;
    $self->{text}=shift     || "Hello World";
    $self->{font}=shift     || "arial.ttf";
    $self->{fontsize}=shift || 8;

    # Create images for normal and pressed state
    $self->{imNormal}=new GD::Image($self->{sizeX},$self->{sizeY});
    $self->{imNormalPrinted}=0;
    $self->{imPressed}=new GD::Image($self->{sizeX},$self->{sizeY});
    $self->{imPressedPrinted}=0;

    # Bless and return
    bless $self, $class;
    return $self;
};

######################################################################
sub color {

    #
    # Allocate colors for GD::Image
    #

    # Me
    my $self=shift;

    # Which state
    my $stateName=shift || "imNormal";

    # Factor for this color
    my $factor=shift || 1;

    # Multiply base colors with factor
    my $Red=int($self->{baseR}*$factor);
    my $Green=int($self->{baseG}*$factor);
    my $Blue=int($self->{baseB}*$factor);

    # Validity check
    $Red=$Red>255 ? 255 : $Red;
    $Green=$Green>255 ? 255 : $Green;
    $Blue=$Blue>255 ? 255 : $Blue;

    # Return allocated color
    return $self->{$stateName}->colorAllocate($Red,$Green,$Blue);
};

######################################################################
sub printNormal {

    #
    # Wrapper to print and/or create Normal (up) state
    #

    # Me
    my $self=shift;

    # Check if image is already generated
    if ($self->{imNormalPrinted}) {
        return $self->{imNormal}->png;
    } else {
        return $self->print(1);
        $self->{imNormalPrinted}=1;
    }
};

######################################################################
sub printPressed {

    #
    # Wrapper to print and/or create Pressed (down) state
    #

    # Me
    my $self=shift;

    # Check if image is already generated
    if ($self->{imPressedPrinted}) {
        return $self->{imPressed}->png;
    } else {
        return $self->print(0);
        $self->{imPressedPrinted}=1;
    }
};

######################################################################
sub print {

    #
    # Print a button
    # (Please, don't use me, use printNormal or printPressed instead.)
    #

    # Me
    my $self=shift;

    # Normal or Pressed state?
    my $state=shift;
    my $stateName=$state ? "imNormal" : "imPressed";

    # Allocate colors
    my $base = $self->color($stateName,$base_factor);
    my $light_edge = $self->color($stateName,$light_edge_factor);
    my $ul_o_corner = $self->color($stateName,$ul_o_corner_factor);
    my $ul_edge = $self->color($stateName,$ul_edge_factor);
    my $ul_i_corner = $self->color($stateName,$ul_i_corner_factor);
    my $ul_o_corner_bevel = $self->color($stateName,
        $ul_o_corner_bevel_factor);
    my $ul_edge_bevel = $self->color($stateName,$ul_edge_bevel_factor)
+;
    my $llur_o_corner = $self->color($stateName,$llur_o_corner_factor)
+;
    my $llur_edge = $self->color($stateName,$llur_edge_factor);
    my $llur_i_corner = $self->color($stateName,$llur_i_corner_factor)
+;
    my $llur_l_o_corner_bevel = $self->color($stateName,
        $llur_l_o_corner_bevel_factor);
    my $llur_b_o_corner_bevel = $self->color($stateName,
        $llur_b_o_corner_bevel_factor);
    my $llur_l_edge_bevel = $self->color($stateName,
        $llur_l_edge_bevel_factor);
    my $llur_b_edge_bevel = $self->color($stateName,
        $llur_b_edge_bevel_factor);
    my $dark_edge = $self->color($stateName,$dark_edge_factor);
    my $light_side = $self->color($stateName,$light_side_factor);
    my $dark_side = $self->color($stateName,$dark_side_factor);
    my $lr_o_corner = $self->color($stateName,$lr_o_corner_factor);
    my $lr_edge = $self->color($stateName,$lr_edge_factor);
    my $lr_i_corner = $self->color($stateName,$lr_i_corner_factor);
    my $lr_o_corner_bevel = $self->color($stateName,
        $lr_o_corner_bevel_factor);
    my $lr_edge_bevel = $self->color($stateName,$lr_edge_bevel_factor)
+;

    # Set the color of the fonts based on the value of $FONTCOLORBREAK
+POINT
    my $fontColor=($self->{baseR}+$self->{baseG}+$self->{baseB})>
        $FONTCOLORBREAKPOINT?$self->{$stateName}->colorAllocate(0,0,0)
+:
        $self->{$stateName}->colorAllocate(255,255,255);

    # Fill everything with base color
    $self->{$stateName}->fill(int($self->{sizeX}/2),int($self->{sizeY}
+/2),
        $base);

    # Draw edge and center rectangles
    $self->{$stateName}->rectangle(0,0,$self->{sizeX}-1,$self->{sizeY}
+-1,
        $light_edge);
    $self->{$stateName}->rectangle($SIDE_X_WIDTH-1,$SIDE_Y_WIDTH-1,
        $self->{sizeX}-$SIDE_X_WIDTH,$self->{sizeY}-$SIDE_Y_WIDTH,
        $light_edge);

    # Draw upper left corner
    $self->{$stateName}->setPixel(0,0,$state?$ul_o_corner:$lr_o_corner
+);
    $self->{$stateName}->line(1,1,$SIDE_X_WIDTH-2,$SIDE_Y_WIDTH-2,$sta
+te?
        $ul_edge:$lr_edge);
    $self->{$stateName}->setPixel($SIDE_X_WIDTH-1,$SIDE_Y_WIDTH-1,$sta
+te?
        $ul_i_corner:$lr_i_corner);
    $self->{$stateName}->line(0,1,1,0,$state?$ul_o_corner_bevel:
        $lr_o_corner_bevel);
    $self->{$stateName}->line(2,1,$SIDE_X_WIDTH-1,$SIDE_Y_WIDTH-2,$sta
+te?
        $ul_edge_bevel:$lr_edge_bevel);
    $self->{$stateName}->line(1,2,$SIDE_X_WIDTH-2,$SIDE_Y_WIDTH-1,$sta
+te?
        $ul_edge_bevel:$lr_edge_bevel);

    # Draw lower left corner
    $self->{$stateName}->setPixel(0,$self->{sizeY}-1,$llur_o_corner);
    $self->{$stateName}->line(1,$self->{sizeY}-2,$SIDE_X_WIDTH-2,
        $self->{sizeY}-$SIDE_Y_WIDTH+1,$llur_edge);
    $self->{$stateName}->setPixel($SIDE_X_WIDTH-1,$self->{sizeY}-$SIDE
+_Y_WIDTH,
        $llur_i_corner);
    $self->{$stateName}->setPixel(0,$self->{sizeY}-2,$state?
        $llur_l_o_corner_bevel:$llur_b_o_corner_bevel);
    $self->{$stateName}->setPixel(1,$self->{sizeY}-1,$state?
        $llur_b_o_corner_bevel:$llur_l_o_corner_bevel);
    $self->{$stateName}->line(1,$self->{sizeY}-3,$SIDE_X_WIDTH-2,
        $self->{sizeY}-$SIDE_Y_WIDTH,$state?$llur_l_edge_bevel:
        $llur_b_edge_bevel);
    $self->{$stateName}->line(2,$self->{sizeY}-2,$SIDE_X_WIDTH-1,
        $self->{sizeY}-$SIDE_Y_WIDTH+1,$state?$llur_b_edge_bevel:
        $llur_l_edge_bevel);

    # Draw upper right corner
    $self->{$stateName}->setPixel($self->{sizeX}-1,0,$llur_o_corner);
    $self->{$stateName}->line($self->{sizeX}-2,1,
        $self->{sizeX}-$SIDE_X_WIDTH+1,$SIDE_Y_WIDTH-2,$llur_edge);
    $self->{$stateName}->setPixel($self->{sizeX}-$SIDE_X_WIDTH,$SIDE_Y
+_WIDTH-1,
        $llur_i_corner);
    $self->{$stateName}->setPixel($self->{sizeX}-2,0,$state?
        $llur_l_o_corner_bevel:$llur_b_o_corner_bevel);
    $self->{$stateName}->setPixel($self->{sizeX}-1,1,$state?
        $llur_b_o_corner_bevel:$llur_l_o_corner_bevel);
    $self->{$stateName}->line($self->{sizeX}-3,1,$self->{sizeX}-$SIDE_
+X_WIDTH,
        $SIDE_Y_WIDTH-2,$state?$llur_l_edge_bevel:$llur_b_edge_bevel);
    $self->{$stateName}->line($self->{sizeX}-2,2,$self->{sizeX}-$SIDE_
+X_WIDTH+1,
        $SIDE_Y_WIDTH-1,$state?$llur_b_edge_bevel:$llur_l_edge_bevel);

    # Draw lower right corner
    $self->{$stateName}->setPixel($self->{sizeX}-1,$self->{sizeY}-1,$s
+tate?
        $lr_o_corner:$ul_o_corner);
    $self->{$stateName}->line($self->{sizeX}-2,$self->{sizeY}-2,
        $self->{sizeX}-$SIDE_X_WIDTH+1,$self->{sizeY}-$SIDE_Y_WIDTH+1,
        $state?$lr_edge:$ul_edge);
    $self->{$stateName}->setPixel($self->{sizeX}-$SIDE_X_WIDTH,
        $self->{sizeY}-$SIDE_Y_WIDTH,$state?$lr_i_corner:$ul_i_corner)
+;
    $self->{$stateName}->line($self->{sizeX}-1,$self->{sizeY}-2,
        $self->{sizeX}-2,$self->{sizeY}-1,$state?$lr_o_corner_bevel:
        $ul_o_corner_bevel);
    $self->{$stateName}->line($self->{sizeX}-3,$self->{sizeY}-2,
        $self->{sizeX}-$SIDE_X_WIDTH,$self->{sizeY}-$SIDE_Y_WIDTH+1,$s
+tate?
        $lr_edge_bevel:$ul_edge_bevel);
    $self->{$stateName}->line($self->{sizeX}-2,$self->{sizeY}-3,
        $self->{sizeX}-$SIDE_X_WIDTH+1,$self->{sizeY}-$SIDE_Y_WIDTH,$s
+tate?
        $lr_edge_bevel:$ul_edge_bevel);


    # Draw dark edges
    $self->{$stateName}->line(2,$state?$self->{sizeY}-1:0,$self->{size
+X}-3,
        $state?$self->{sizeY}-1:0,$dark_edge);
    $self->{$stateName}->line($state?$self->{sizeX}-1:0,2,$state?
        $self->{sizeX}-1:0,$self->{sizeY}-3,$dark_edge);
    $self->{$stateName}->line(
        $state?$self->{sizeX}-$SIDE_X_WIDTH:$SIDE_X_WIDTH-1,
        $SIDE_Y_WIDTH,
        $state?$self->{sizeX}-$SIDE_X_WIDTH:$SIDE_X_WIDTH-1,
        $self->{sizeY}-$SIDE_Y_WIDTH-1,
        $dark_edge);
    $self->{$stateName}->line(
        $SIDE_X_WIDTH,
        $state?$self->{sizeY}-$SIDE_Y_WIDTH:$SIDE_Y_WIDTH-1,
        $self->{sizeX}-$SIDE_X_WIDTH-1,
        $state?$self->{sizeY}-$SIDE_Y_WIDTH:$SIDE_Y_WIDTH-1,
        $dark_edge);

    # Fill sides
    $self->{$stateName}->fill(int($self->{sizeX}/2),1,
        $state?$light_side:$dark_side);
    $self->{$stateName}->fill(1,int($self->{sizeY}/2),
        $state?$light_side:$dark_side);
    $self->{$stateName}->fill($self->{sizeX}-2,int($self->{sizeY}/2),
        $state?$dark_side:$light_side);
    $self->{$stateName}->fill(int($self->{sizeX}/2),$self->{sizeY}-2,
        $state?$dark_side:$light_side);

    # Print text
    # The text must be able to be printed in a box of
    # @bounds[0,1]=5,$self->{sizeY}-7
    # @bounds[2,3]=$self->{sizeX}-7,$self->{sizeY}-7
    # @bounds[4,5]=$self->{sizeX}-7,5
    # @bounds[6,7]=5,5

    # Set wanted fontsize (could be smaller after TEXTRESIZE)
    my $textHeight=$self->{fontsize};
    my @bounds=[];

    # Loop to size text to button area
    TEXTRESIZE: while (1) {
        # See what bounds we get if we would print
        @bounds = GD::Image->stringTTF(
            $fontColor,
            $FONTDIR.$self->{font},
            $textHeight,
            0,
            ($SIDE_X_WIDTH+1),
            ($self->{sizeY}-($SIDE_Y_WIDTH+3)),
            $self->{text});
        if ($@) {
            # Some error (like no TTF support)
            last TEXTRESIZE;
        }

        # If text is out of bounds, try to resize it
        if ($bounds[4]>($self->{sizeX} - ($SIDE_X_WIDTH+3)) || 
            $bounds[4]<0 || 
            $bounds[5]<($SIDE_Y_WIDTH+1) || 
            $bounds[5]<0) {
            if (--$textHeight<1) {
                # Couldn't fit text in button
                last TEXTRESIZE;            
            }
            next TEXTRESIZE;
        }

        # Set fontsize to the new? value
        $self->{fontsize}=$textHeight;

        # Print the text (centered on button)
        $self->{$stateName}->stringTTF(
            $fontColor,
            $FONTDIR.$self->{font},
            $textHeight,
            0,
            ($SIDE_X_WIDTH+1)+
                int(($self->{sizeX}-($bounds[4]-$bounds[6])-
                (($SIDE_X_WIDTH*2)+2))/2),
            $self->{sizeY}-($SIDE_Y_WIDTH+3)-
                int(($self->{sizeY}-($bounds[1]-$bounds[7])-
                (($SIDE_Y_WIDTH*2)+2))/2),
            $self->{text});
        last TEXTRESIZE;
    }

    # Convert the image to PNG and return it
    return $self->{$stateName}->png;
};

######################################################################
1;

__END__


=head1 NAME

ButtonFactory - A button factory

=head1 DESCRIPTION

A package that creates custom png buttons.

=head1 SYNOPSIS

A non-web example to generate buttons to files:

 #!/usr/local/bin/perl -w
 use ButtonFactory;

 my $x=new ButtonFactory(100,20,70,82,157,"Hello World","arial.ttf",8)
+;

 open (FILE,">Normal.png") or die $!;
 binmode FILE;
 print FILE $x->printNormal();
 close (FILE);

 open (FILE,">Pressed.png") or die $!;
 binmode FILE;
 print FILE $x->printPressed();
 close (FILE);

A web example (let's call it getbutt.cgi :) to print buttons to a brow
+ser:

 #!/usr/local/bin/perl -w
 use ButtonFactory;
 use CGI qw(:standard);

 # Get query parameters
 my $query = new CGI;
 $x = $query->param('x');
 $y = $query->param('y');
 $r = $query->param('r');
 $g = $query->param('g');
 $b = $query->param('b');
 $txt = $query->param('txt');
 $ttf = $query->param('ttf');
 $fs = $query->param('fs');
 $state = $query->param('state');

 # Create the button
 my $butt=new ButtonFactory($x,$y,$r,$g,$b,$txt,$ttf,$fs);

 # Calculate size of button and pour it out to the user
 print "Content-Type: image/png\n\n";
 binmode STDOUT;
 print $state?$butt->printNormal():$butt->printPressed();

And a sample (pretty_silly.html) html page for it:    

 <html>
 <head><title>Buttons</title>
 <script language="JavaScript">
     // browser detection
     var OK = ((navigator.appName.charAt(0)=='N' && 
         navigator.appVersion.charAt(0)=='3') || 
         navigator.appVersion.charAt(0)=='4');
     // Preload clicked image
     if (OK) {
         preload = new Image();
         preload.src ='cgi-bin/getbutt.cgi?x=100&y=20&r=70&g=82&b=157&
+' + 
             'txt=Hello+World&ttf=arial.ttf&fs=8&state=0';
     }
     // mouseclick f/x
     function click(i) {if (OK) {document['butt'+i].src = 
         'cgi-bin/getbutt.cgi?x=100&y=20&r=70&g=82&b=157&txt=Hello+Wor
+ld&' +
         'ttf=arial.ttf&fs=8&state=0';}}
     function out(i) {if (OK) {document['butt'+i].src = 
         'cgi-bin/getbutt.cgi?x=100&y=20&r=70&g=82&b=157&txt=Hello+Wor
+ld&' +
         'ttf=arial.ttf&fs=8&state=1';}}
 </script>
 </head>
 <body bgcolor=#ffffff>
 A button test...<br>
 <a href="helloworld.html" onClick="click(0);alert('Click...');out(0);
+">
 <img name="butt0" src=
 "cgi-bin/getbutt.cgi?x=100&y=20&r=70&g=82&b=157&txt=Hello+World&ttf=a
+rial.ttf&fs=8&state=1" 
 alt="Hello World" width=100 height=20 border=0></a><br>
 </body>
 </html>

=head1 Methods

=over 4

=item new(sizeX,sizeY,red,green,blue,text,font,fontsize)

Creates a new ButtonFactory object with sizeX*sizeY pixel size. Values
+ for red,
green and blue in decimal range 0-255. ButtonFactory will try its best
+ to size
the font to make the text fit on the button, so the fontsize supplied 
+is the
largest size the text can have.
The font should be a TrueType font with its .ttf extension, 'arial.ttf
+'. In the
configuration section of ButtonFactory you may set $FONTDIR to the dir
+ectory
where you store your TrueType fonts. If $FONTDIR is set to '' (empty s
+tring)
you must supply the whole path to the font you want to use.   

=item printNormal()

Prints the button in its up state. The GD image is stored internaly so
+ the 
second time you use printNormal, ButtonFactory can use the stored imag
+e. This
improves speed if you need to get the size of the printed button befor
+e printing
it. Useful when you need to print Content-length before the image on a
+ 
multipart/x-mixed-replace HTML documet. 

=back

=head1 SEE ALSO

L<GD>

=head1 DISCLAIMER

I do not guarantee B<ANYTHING> with this package. If you use it you
are doing so B<AT YOUR OWN RISK>! I may or may not support this
depending on my time schedule...

=head1 AUTHOR

t0mas@netlords.net

=head1 COPYRIGHT

Copyright 1999-2000, t0mas@netlords.net

This package is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

Comment on ButtonFactory
Download Code
RE: ButtonFactory
by Intrepid (Deacon) on Jun 29, 2000 at 14:41 UTC

    I do not have any expert and insightful comment to make since all I can do right now is look at all this code (and whistle quietly between my teeth and go " WOW ") .. but I needed to write that I am simply impressed as heck. Thanks for contributing this great-looking, POD-documented application.

    I have to check and see if my GD module version has TrueType support compiled in. If so I may be going to town, absolutely having a riot with the ButtonFactory .

    BTW I wish I could say my trailing sig (if it works) was a button made with your app, but it isn't.

    Intrepid <IMG SRC="http://www.wonderstorm.com/cgi-bin/PiNGMe.pl?wonderstorm-com_stonebutton" WIDTH=150 HEIGHT=20 BORDER=0>
    www.wonderstorm.com
    How-To's on hacking PNG and other stuff on my Website img data served to some browsers as a PNG img
      Even if you don't have TrueType support, you can make textless buttons. You can supply text with your favorite image manipulation program (ie. GIMP). I havn't been able to work out how to recalculate and choose the best built-in font (haven't put much effort in it either), thats why they aren't supported yet.
      Thanks for your input :)

      /brother t0mas
RE: ButtonFactory
by Intrepid (Deacon) on Aug 14, 2000 at 06:50 UTC

    Updated 22 Oct 2005

    Brother t0mas -- Thanks so much for adding the button bevel size change to ButtonFactory. What was once good is even better!

    In the interest of sharing, just for fun, I am posting some code I quickly hacked up last night to do something a little different with ButtonFactory from the command line. Based on what you include as a sample command-line script in the POD, here is what I am doing:

    #!perl -w ## ------------------------------------------------------------ # MS Windoze-specific script. Sorry :-). ## ------------------------------------------------------------ # NOT like t0mas' original idea -- this makes buttons for # horizontal row use only bec if button text is longer # than 20 chars, it expands the length by 8 px for each one # (based on 8pt Myriad font). use ButtonFactory; use Win32::Clipboard; my ( $N_state $P_state @RGBt $BWi ); my $clipping; my $name_it = shift @ARGV; my $btnText = shift @ARGV; my $expsn = ((length ($btnText) - 20) > 0)? (length ($btnText) - 20) * 8 : 0 ; $BWi = 90 + $expsn; @RGBt = ($clipping=Win32::Clipboard::Get()) # Pick-'o-Color format for rgb triplet: "RGB(155, 50, 23)" ? grep /\d+/, (split /[^\d]/,$clipping) : split(/[^\w]/, shift @ARGV); if (scalar @RGBt == 3) { print "Using ", join( ', ',@RGBt ), " for color specification for b +uttons\n"; } else { die "No color as RGB triplet gotten! \nContents of \@RGBt if any: " ." $clipping ". "@RGBt"; } my $x=new ButtonFactory($BWi,21, $RGBt[0],$RGBt[1],$RGBt[2], $btnText =>"Myriad Web Bold.ttf"=>8); $N_state = $name_it .'N_state.png'; $P_state = $name_it .'P_state.png'; open (FILE,">$N_state") or die $!; binmode FILE; my $Ntime = time; print FILE $x->printNormal(); close (FILE); open (FILE,">$P_state") or die $!; binmode FILE; print FILE $x->printPressed(); close (FILE); utime $Ntime, $Ntime, ($N_state, $P_state); _END_

    Pick'o'Color is  (was) a  Windows app found at:
    http://www.itsme.de/software/index.html



     Best,
       soren      Intrepid

Back to Code Catacombs

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (19)
As of 2015-07-06 17:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (77 votes), past polls