rounded rectangles problem



Hi All,

I'm trying to subclass Gnome2::Canvas::Shape to get a rounded rectangle. No success yet. I need to set the Bpath for the shape. As far as I can tell the pathdef can not be set up in INIT_INSTANCE as this is too soon and the properties have not been passed in. I'm not sure if it's OK to instantiate a pathdef inside my RoundedRect or not, and I'm not sure how to call set_path_def. I've seen in the Mup::ColorButton example that an event is used to set the button color for the first time. I tried something similar but without success.

This software is new to me and maybe I'm being a bit too ambitious, and obviously I'm misunderstanding something. Any help would be appreciated.

Here is my subclass (without event handler):

#!/usr/bin/perl -w
#
# RoundedRect: add a rounded rectangle.
#
# TODO: Check size of corner radius.
# -------------------------------------------------------------------------
package RoundedRect;

use strict;
use Gnome2::Canvas;

use Glib ':constants';
use Glib::Object::Subclass
   Gnome2::Canvas::Shape::,
   properties => [
                  Glib::ParamSpec->int ('corner-radius',
                                        'Corner Radius',
                                        'Radius of corners',
                                        10,
                                        100,
                                        10,
                                        G_PARAM_READWRITE),
                  Glib::ParamSpec->int ('x1',
                                        'x1',
                                        'Upper left X coord',
                                        0,
                                        32767,
                                        0,
                                        G_PARAM_READWRITE),
                  Glib::ParamSpec->int ('y1',
                                        'y1',
                                        'Upper left Y coord',
                                        0,
                                        32767,
                                        0,
                                        G_PARAM_READWRITE),
                  Glib::ParamSpec->int ('x2',
                                        'x2',
                                        'Lower right X coord',
                                        0,
                                        32767,
                                        0,
                                        G_PARAM_READWRITE),
                  Glib::ParamSpec->int ('y2',
                                        'y2',
                                        'Lower right Y coord',
                                        0,
                                        32767,
                                        0,
                                        G_PARAM_READWRITE),
                  ]
   ;


sub INIT_INSTANCE
{
   my $self = @_;

   print "INIT_INSTANCE:\n";
}

sub GET_PROPERTY
{
   my ($self, $pspec) = @_;

print "GET_PROPERTY: " . $pspec->get_name . " value: " . $self->{$pspec->get_name} . "\n";

   return ($self->{$pspec->get_name} || $pspec->get_default_value);
}

sub SET_PROPERTY
{
# Do: Limit size of corner radius to 3/8ths of min(height,width) of rectangle.
   my ($self, $pspec, $newval) = @_;

   print "SET_PROPERTY: " . $pspec->get_name . "  newval: $newval\n";

   $self->{$pspec->get_name} = $newval;
}

# _roundedRect: return the rounded rectangle path.
# --------------------------------------------------------
sub _roundedRect
{
   my ($r, $x1, $y1, $x2, $y2) = @_;

   # Make sure (x1,y1) is upper left.

   if (($x1 < $x2) && ($y1 > $y2))
   {
       my $t1 = $y1; $y1 = $y2; $y2 = $t1;
   }

   if (($y1 < $y2) && ($x1 > $x2))
   {
       my $t1 = $x1; $x1 = $x2; $x2 = $t1;
   }

   print "x1: $x1  y1: $y1  x2: $x2  y2: $y2\n";

   # Get the points for the path.

   my @p = ();

   push @p, _bezier('UPPER_LEFT',  $r, $x1, $y1);
   push @p, _bezier('UPPER_RIGHT', $r, $x2, $y1);
   push @p, _bezier('LOWER_RIGHT', $r, $x2, $y2);
   push @p, _bezier('LOWER_LEFT',  $r, $x1, $y2);

   print "p: @p\n";

   # Build the rounded rectangle path. Problem?

   my $pathdef = Gnome2::Canvas::PathDef->new();

   $pathdef->moveto  ($p[0],  $p[1]);
   $pathdef->curveto ($p[2],  $p[3],  $p[4],  $p[5],  $p[6],  $p[7]);
   $pathdef->lineto  ($p[8],  $p[9]);
   $pathdef->curveto ($p[10], $p[11], $p[12], $p[13], $p[14], $p[15]);
   $pathdef->lineto  ($p[16], $p[17]);
   $pathdef->curveto ($p[18], $p[19], $p[20], $p[21], $p[22], $p[23]);
   $pathdef->lineto  ($p[24], $p[25]);
   $pathdef->curveto ($p[26], $p[27], $p[28], $p[29], $p[30], $p[31]);
   $pathdef->lineto  ($p[0],  $p[1]);

   return $pathdef;
}


# _bezier: return corner bezier points.
# --------------------------------------------------------
sub _bezier
{
   my $corner = shift(@_);
   my $r      = shift(@_);
   my $x      = shift(@_);
   my $y      = shift(@_);

   print "_bezier: $corner  r: $r  x: $x  y: $y\n";

   if ($corner == 'UPPER_LEFT')
   {
       return ($x,$y+$r, $x,$y+($r/2), $x+($r/2),$y, $x+$r, $y);
   }

   if ($corner == 'UPPER_RIGHT')
   {
       return ($x-$r,$y, $x-($r/2),$y, $x,$y+($r/2), $x, $y+$r);
   }

   if ($corner == 'LOWER_RIGHT')
   {
       return ($x,$y-$r, $x,$y-($r/2), $x-($r/2),$y, $x-$r, $y);
   }

   if ($corner == 'LOWER_LEFT')
   {
       return ($x+$r,$y, $x+($r/2),$y, $x,$y-($r/2), $x, $y-$r);
   }

   return ();
}


1;




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]