The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# overrides rect3d calls for some classes

use strict;
use warnings;
use Prima qw(Themes);

package Prima::Themes::Round3D;
use vars qw(@ISA);
@ISA=qw(Prima::Themes::Proxy);

sub rect3d
{
	my ( $self, $x, $y, $x1, $y1, $width, $lColor, $rColor, $backColor) = @_;
	my $canvas = $self-> {object};
	if ( defined $backColor) {
		my $c = $canvas-> color;
		if ( ref($backColor)) {
			$backColor->clone(canvas => $self)->bar($x, $y, $x1, $y1);
		} else {
			$canvas-> color( $backColor);
			$canvas-> bar( $x, $y, $x1, $y1);
		}
		$canvas-> color( $c);
		
	}
	oval3d( $canvas, $x, $y, $x1, $y1, $width, $lColor, $rColor, 40);
}

sub oval3d
{
	my ( $self, $x, $y, $x1, $y1, $width, $lColor, $rColor, $maxd) = @_;
	( $x1, $x) = ( $x, $x1) if $x > $x1;
	( $y1, $y) = ( $y, $y1) if $y > $y1;
	my $bias = int($width / 2);
	$x += $bias;
	$y += $bias;
	$x1 -= $bias;
	$y1 -= $bias;
	my ( $dx, $dy) = ( $x1 - $x, $y1 - $y);
	$dx = $maxd if $dx > $maxd;
	$dy = $maxd if $dy > $maxd;
	my $d = ( $dx < $dy ) ? $dx : $dy;
	my $r = int($d/2);
#  plots 3-d roundrect:
# A'        B'
#  /------\  lines: AC, AB - light, BD, CD - dark
#  |A    B|  arcs: A - light, B - l/d, C - l/d, D - dark
#  |      |  arcs cannot have diameter larger than $maxd
#  |C    D|
#  \------/
# C'        D'
	my @r = ( 
		# coordinates of C and B, so A=r[0,3],B=r[2,3],C=r[0,1],D=[2,1]
		$x + $r, $y + $r,
		$x1 - $r, $y1 - $r,
		# coordinates of C' and B'
		$x, $y,
		$x1, $y1,
	);
	my $c = $self-> color;
	my $w = $self-> lineWidth;
	$self-> lineWidth( $width) if $width != $w;
	$self-> color( $lColor) if $lColor != $c;
	# light color
	$self-> line( @r[0,7,2,7]) if $r[0] < $r[2];
	$self-> line( @r[4,1,4,3]) if $r[1] < $r[3];
	$self-> arc( @r[0,3], $d, $d, 90, 180);
	$self-> arc( @r[2,3], $d, $d, 45, 90);
	$self-> arc( @r[0,1], $d, $d, 180, 225);
	$self-> color( $rColor);
	# dark color
	$self-> line( @r[0,5,2,5]) if $r[0] < $r[2];
	$self-> line( @r[6,1,6,3]) if $r[1] < $r[3];
	$self-> arc( @r[2,1], $d, $d, 270, 360);
	$self-> arc( @r[2,3], $d, $d, 0, 45);
	$self-> arc( @r[0,1], $d, $d, 225, 270);
	# restore pen style
	$self-> color( $c) if $c != $rColor;
	$self-> lineWidth( $w) if $width != $w;
}

my %wrap_paint = (
	onPaint => sub {
		$_[0]-> on_paint( Prima::Themes::Round3D-> new($_[1]));
	}
);

Prima::Themes::register( 'Prima::themes::round3d', 'round3d', [ 
		'Prima::Button' => \%wrap_paint,
		'Prima::ScrollBar' => \%wrap_paint,
		'Prima::InputLine' => \%wrap_paint,
		],
);