Re: rounded rectangles problem



muppet wrote:

James Muir said:
I've written a similar program using composition rather than inheritance
and I get a rounded rectangle. I'd use this rectangle except that I am
unable to set the 'fill-color', and I get events only when the mouse is
placed directly on the outline. No signals when the mouse is moved
inside the rounded rectangle. Is this the correct behavior of the
Gnome2::Canvas::Shape ? If so, I shall have to come up with a "plan b".

If you use just a plain Gnome2::Canvas::Rect, you get mouse events inside the
rectangle only if fill-color is set.  The basic trick, then, is to figure out
how to get fill-color set.  Can you post some current code so we know what you
are and aren't doing?

Here is the latest code. I managed to get the rectangle to display since my last posting. I had forgotten to set the 'outline-color' and so nothing was displayed. I am still not able to set the 'fill-color'.

#!/usr/bin/perl -w
#
# RoundedRect1: add a rounded rectangle.
#
# This version uses inheritance to create the rect.
#
# TODO: Check size of corner radius.
#       Fill rect with color.
#       Capture events inside rect.
# -------------------------------------------------------------------------
package RoundedRect1;

use strict;
use Gnome2::Canvas;

use Glib ':constants';
use Glib::Object::Subclass
   Gnome2::Canvas::Shape::,
   properties => [
          Glib::ParamSpec->int ('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
{
   my ($self, $pspec, $newval) = @_;

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

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

   if ((defined $self->{'radius'}) &&
   (defined $self->{x1}) && (defined $self->{y1}) &&
   (defined $self->{x2}) && (defined $self->{y2}))
   {
   $self->set_path_def(_roundedRect($self->{'radius'},
                    $self->{x1}, $self->{y1},
                    $self->{x2}, $self->{y2}));

   $self->set('outline-color'=>'black'); # default.

#    $self->set('fill-color'=>'white');

   my $color = Gtk2::Gdk::Color->new(255,255,255);

   $self->set('fill-color-gdk'=>$color);
   }
}


# _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);

   # 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(@_);

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

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

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

   if ($corner eq '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]