Prev
Next

Delegation

Some possible Perl code for ColorSlider:
  1 use AWT;
  2 use AWT::Event;
  3 use artofillusion qw (RGBColor);
  4 
  5 use strict;
  6 
  7 package ColorSlider;
  8 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  9 
 10 @ISA = qw (Component);
 11 @EXPORT = qw (); #defer this
 12 
 13 $ColorSlider::HORIZONTAL = 1;
 14 $ColorSlider::VERTICAL = 0;
 15 
 16 sub new {
 17 
 18     my $self = {
 19 		preferredMajor => 200,
 20 		preferredMinor => 18,
 21 
 22 		bubblePos => 50,
 23 		tempBubblePos => 50,
 24 
 25 		dragging => 0,
 26 
 27 		orientation => 0,
 28 		mode => $RGBColor::HSV_MODE,
 29 
 30 		baseImpl => new Canvas ()
 31 	       };
 32 
 33     my ($minimum,  $maximum,  $value, $orientation, $c1, $c2) = @_;
 34 
 35     $self->{minimum} = $minimum;
 36     $self->{maximum} = $maximum;
 37     $self->{value} = $value;
 38     $self->{orientation} = $orientation;
 39     $self->{startColor} = new RGBColor ($c1);
 40     $self->{endColor} = new RGBColor ($c2);
 41 
 42     my $canvas = $self->baseImpl;
 43     $canvas->setSize (200, 18);
 44     $canvas->addMouseListener ($self);
 45     $canvas->addMouseMotionListener ($self);
 46     $canvas->setOnPaint (\&paint);
 47     $canvas->setSubImpl ($self);
 48 
 49     #So that routines that deal with components know where
 50     #to go for native widget stuff
 51     $self->setBaseImpl ($canvas);
 52     $self->setOnSetSize (sub {$_[0]->_drawImage ()});
 53 }
 54 
 55 
 56 sub getPreferredSize {
 57   my ($w, $h) = (200, 18);
 58   $_[0]->getOrientation ? ($w, $h) :  ($h, $w);
 59 }
 60 
 61 
 62 sub setColors {
 63   my ($self, $c1, $c2) = @_;
 64   $self->{startColor}->copy ($c1);
 65   $self->{endColor}->copy ($c2);
 66   $self->_drawImage ();
 67 }
 68 
 69 sub setMode {
 70   my ($self, $mode) = @_;
 71   $self->{mode} = $mode;
 72   $self->_drawImage ();
 73 }
 74 
 75 sub _drawImage {
 76   my $self = shift;
 77   my ($w, $h) = getSize ();
 78   my $startColor = $self->{startColor};
 79   my $endColor = $self->{endColor};
 80   my $mode = $self->{mode};
 81   my $pixels = new PixelArray ($w, $h);
 82 
 83   if ($self->{orientation}) {
 84     $pixels->map (sub { 
 85 		    my ($x, $y, $p) = @_; #or they could be auto-assigned?
 86 		    my $c = RGBColor::interp ($startColor, $endColor, 
 87                             $mode, $x / $w)->getARGB | 0xff000000; 
 88 		  });
 89   } else {
 90     $pixels->map (sub { 
 91 		    my ($x, $y, $p) = @_; 
 92 		    my $c = RGBColor::interp ($startColor, $endColor, 
 93 			    $mode,  $y / $h)->getARGB | 0xff000000;
 94 		  });
 95 }
 96 
 97   $self->{image} = new Image (@pixels);
 98 }
 99 
100 
101 sub _drawImageFast {
102   my $self = shift;
103   my ($w, $h) = getSize ();
104   my $startColor = $self->{startColor};
105   my $endColor = $self->{endColor};
106   my $mode = $self->{mode};
107   my $pixels = new PixelArray ($w * $h);
108 
109   if ($self->{orientation}) {
110     for (my $x = 0; $x < $w; $x++) {
111       my $c = RGBColor::interp ($startColor, $endColor, 
112               $mode, $x / $w)->getARGB | 0xff000000;
113       $pixels->[$x + $_ * $w] = $c for (1..$h);
114     }
115   } else {
116     my $i = 0;
117     for (my $y = 0; $y < $h; $y++) {
118       my $c = RGBColor::interp ($startColor, $endColor, 
119               $mode,  $y / $h)->getARGB | 0xff000000;
120       $pixels->[$i++] = $c for (1..$w);
121     }
122   }
123 
124   $self->{image} = new Image (@pixels);
125 }
126 
127 sub _dragging {
128   $_[0]->{dragging};
129 }
130 
131 sub mouseDragged {
132   my ($self, $event) = @_;
133   return if (!$self->_dragging);
134 
135   my ($minor, $major) = ColorSlider::_getAxes ($event);
136 
137   my ($w, $h) = $self->getSize ();
138   my $minorMax = $self->{orientation} ? $h : $w;
139   if ($minor > 0 && $minor < $minorMax) {
140     if ($major < 0) {
141       $self->setTempBubblePos (0);
142     } elsif ($major > 200) {
143       $self->setTempBubblePos (200);
144     } else {
145       $self->setTempBubblePos ($major);
146     }
147     $self->repaint;
148   }
149 }
150 sub setTempBubblePos {
151   $_[0]->{tempBubblePos} = $_[1];
152 }
153 
154 sub mouseReleased {
155   my ($self, $event) = @_;
156 
157   $self->{bubblePos} = $self->{tempBubblePos};
158 
159   $self->{dragging} = 0;
160   $self->repaint;
161   $self->fireAdjustmentPerformed ();
162 }
163 
164 sub _getAxes {
165   my $event = shift;
166   $_[0]->{orientation} ? ($event->{w}, $event->{h})
167     : ($event->{h}, $event->{w});
168 }
169 
170 sub mousePressed {
171   my ($self, $event) = @_;
172 
173   my ($minor, $major) = _getAxes ();
174   $self->{tempBubblePos} = $major;
175   $self->{dragging} = 1;
176   $self->repaint;
177 }
178 
179 sub paint {
180 
181   my ($self, $gc) = @_;
182 
183   my ($width, $height) = $self->getSize ();
184 
185   $self->drawImage () unless $self->{image};
186 
187   my ($bubblePos, $tempBubblePos) = 
188     ($self->{bubblePos}, $self->{tempBubblePos});
189 
190   if ($self->{orientation}) {
191     my $h = $self->{preferredMinor};
192     my $w = $width;
193     my $top = ($height - $h) / 2;
194     $gc->drawImage ($self->{image}, 0, 6 + $top);
195 
196     #outline
197     $gc->drawRect (0, 6 + $top,  200, 6);
198 
199     #top of position marker
200     $gc->fillRect ($bubblePos, $top,  2, 6);
201 
202     #bottom of position marker
203     $gc->fillRect ($bubblePos, 12 + $top, 2, $h - 12);
204 
205     #top of temp position marker
206     $gc->fillRect ($tempBubblePos, $top, 2, 6);
207 
208     #bottom of temp position marker
209     $gc->fillRect ($tempBubblePos, 12 + $top, 2, $h - 12);
210 
211   } else {
212     #literate programming lets me ignore this case for now
213   }
214 }
215 
216 sub getValue {
217   my $self = shift;
218   my $value = $self->{bubblePos} / 200;
219   $self->{value} = $value;
220   $value * $self->{maximum} + $self->{minimum};
221 }
222 
223 
224 sub setValue {
225   my ($self, $value) = @_;
226   $value = ($value - $self->{minimum}) / $self->{maximum};
227   $self->{bubblePos} = $value * 200;
228   $self->{tempBubblePos} = $self->{bubblePos};
229   $self->{value} = $value;
230   $self->repaint;
231 }


Prev
Next