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