comparison widgets/LEDButton.cpp @ 32:c53b949ef142

* Add LED button * Add note model playback (currently assuming that value == MIDI pitch) * Reorganise PlayParameters and move repository from ViewManager to new PlayParameterRepository class
author Chris Cannam
date Wed, 15 Feb 2006 17:58:35 +0000
parents
children 651e4e868bcc
comparison
equal deleted inserted replaced
31:fc802f7b112e 32:c53b949ef142
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 A waveform viewer and audio annotation editor.
5 Chris Cannam, Queen Mary University of London, 2005-2006
6
7 This is experimental software. Not for distribution.
8 */
9
10 /*
11 This is a modified version of a source file from the KDE
12 libraries. Copyright (c) 1998-2004 Jörg Habenicht, Richard J
13 Moore, Chris Cannam and others, distributed under the GNU Lesser
14 General Public License.
15
16 Ported to Qt4 by Chris Cannam.
17 */
18
19
20 #include "LEDButton.h"
21
22 #include <QPainter>
23 #include <QImage>
24 #include <QColor>
25
26
27 class LEDButton::LEDButtonPrivate
28 {
29 friend class LEDButton;
30
31 int dark_factor;
32 QColor offcolor;
33 QPixmap *off_map;
34 QPixmap *on_map;
35 };
36
37
38 LEDButton::LEDButton(QWidget *parent) :
39 QWidget(parent),
40 led_state(On)
41 {
42 QColor col(Qt::green);
43 d = new LEDButton::LEDButtonPrivate;
44 d->dark_factor = 300;
45 d->offcolor = col.dark(300);
46 d->off_map = 0;
47 d->on_map = 0;
48
49 setColor(col);
50 }
51
52
53 LEDButton::LEDButton(const QColor& col, QWidget *parent) :
54 QWidget(parent),
55 led_state(On)
56 {
57 d = new LEDButton::LEDButtonPrivate;
58 d->dark_factor = 300;
59 d->offcolor = col.dark(300);
60 d->off_map = 0;
61 d->on_map = 0;
62
63 setColor(col);
64 }
65
66 LEDButton::LEDButton(const QColor& col, LEDButton::State state, QWidget *parent) :
67 QWidget(parent),
68 led_state(state)
69 {
70 d = new LEDButton::LEDButtonPrivate;
71 d->dark_factor = 300;
72 d->offcolor = col.dark(300);
73 d->off_map = 0;
74 d->on_map = 0;
75
76 setColor(col);
77 }
78
79 LEDButton::~LEDButton()
80 {
81 delete d->off_map;
82 delete d->on_map;
83 delete d;
84 }
85
86 void
87 LEDButton::paintEvent(QPaintEvent *)
88 {
89 QPainter paint;
90 QColor color;
91 QBrush brush;
92 QPen pen;
93
94 // First of all we want to know what area should be updated
95 // Initialize coordinates, width, and height of the LED
96 int width = this->width();
97
98 // Make sure the LED is round!
99 if (width > this->height())
100 width = this->height();
101 width -= 2; // leave one pixel border
102 if (width < 0)
103 width = 0;
104
105 // maybe we could stop HERE, if width <=0 ?
106
107 int scale = 1;
108 QPixmap *tmpMap = 0;
109 bool smooth = true;
110
111 if (smooth) {
112 if (led_state) {
113 if (d->on_map) {
114 paint.begin(this);
115 paint.drawPixmap(0, 0, *d->on_map);
116 paint.end();
117 return;
118 }
119 } else {
120 if (d->off_map) {
121 paint.begin(this);
122 paint.drawPixmap(0, 0, *d->off_map);
123 paint.end();
124 return;
125 }
126 }
127
128 scale = 3;
129 width *= scale;
130
131 tmpMap = new QPixmap(width, width);
132 tmpMap->fill(palette().background().color());
133 paint.begin(tmpMap);
134
135 } else {
136 paint.begin(this);
137 }
138
139 paint.setRenderHint(QPainter::Antialiasing, false);
140
141 // Set the color of the LED according to given parameters
142 color = (led_state) ? led_color : d->offcolor;
143
144 // Set the brush to SolidPattern, this fills the entire area
145 // of the ellipse which is drawn first
146 brush.setStyle(Qt::SolidPattern);
147 brush.setColor(color);
148 paint.setBrush(brush);
149
150 // Draws a "flat" LED with the given color:
151 paint.drawEllipse( scale, scale, width - scale*2, width - scale*2 );
152
153 // Draw the bright light spot of the LED now, using modified "old"
154 // painter routine taken from KDEUI´s LEDButton widget:
155
156 // Setting the new width of the pen is essential to avoid "pixelized"
157 // shadow like it can be observed with the old LED code
158 pen.setWidth( 2 * scale );
159
160 // shrink the light on the LED to a size about 2/3 of the complete LED
161 int pos = width/5 + 1;
162 int light_width = width;
163 light_width *= 2;
164 light_width /= 3;
165
166 // Calculate the LED´s "light factor":
167 int light_quote = (130*2/(light_width?light_width:1))+100;
168
169 // Now draw the bright spot on the LED:
170 while (light_width) {
171 color = color.light( light_quote ); // make color lighter
172 pen.setColor( color ); // set color as pen color
173 paint.setPen( pen ); // select the pen for drawing
174 paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle)
175 light_width--;
176 if (!light_width)
177 break;
178 paint.drawEllipse( pos, pos, light_width, light_width );
179 light_width--;
180 if (!light_width)
181 break;
182 paint.drawEllipse( pos, pos, light_width, light_width );
183 pos++; light_width--;
184 }
185
186 // Drawing of bright spot finished, now draw a thin border
187 // around the LED which resembles a shadow with light coming
188 // from the upper left.
189
190 pen.setWidth( 2 * scale + 1 ); // ### shouldn't this value be smaller for smaller LEDs?
191 brush.setStyle(Qt::NoBrush);
192 paint.setBrush(brush); // This avoids filling of the ellipse
193
194 // Set the initial color value to colorGroup().light() (bright) and start
195 // drawing the shadow border at 45° (45*16 = 720).
196
197 int angle = -720;
198 color = palette().light().color();
199
200 for (int arc = 120; arc < 2880; arc += 240) {
201 pen.setColor(color);
202 paint.setPen(pen);
203 int w = width - pen.width()/2 - scale + 1;
204 paint.drawArc(pen.width()/2, pen.width()/2, w, w, angle + arc, 240);
205 paint.drawArc(pen.width()/2, pen.width()/2, w, w, angle - arc, 240);
206 color = color.dark(110); //FIXME: this should somehow use the contrast value
207 } // end for ( angle = 720; angle < 6480; angle += 160 )
208
209 paint.end();
210 //
211 // painting done
212
213 if (smooth) {
214 QPixmap *&dest = led_state ? d->on_map : d->off_map;
215 QImage i = tmpMap->toImage();
216 width /= 3;
217 i = i.scaled(width, width,
218 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
219 delete tmpMap;
220 dest = new QPixmap(QPixmap::fromImage(i));
221 paint.begin(this);
222 paint.drawPixmap(0, 0, *dest);
223 paint.end();
224 }
225 }
226
227 LEDButton::State
228 LEDButton::state() const
229 {
230 return led_state;
231 }
232
233 QColor
234 LEDButton::color() const
235 {
236 return led_color;
237 }
238
239 void
240 LEDButton::setState( State state )
241 {
242 if (led_state != state)
243 {
244 led_state = state;
245 update();
246 }
247 }
248
249 void
250 LEDButton::toggleState()
251 {
252 led_state = (led_state == On) ? Off : On;
253 // setColor(led_color);
254 update();
255 }
256
257 void
258 LEDButton::setColor(const QColor& col)
259 {
260 if(led_color!=col) {
261 led_color = col;
262 d->offcolor = col.dark(d->dark_factor);
263 delete d->on_map;
264 d->on_map = 0;
265 delete d->off_map;
266 d->off_map = 0;
267 update();
268 }
269 }
270
271 void
272 LEDButton::setDarkFactor(int darkfactor)
273 {
274 if (d->dark_factor != darkfactor) {
275 d->dark_factor = darkfactor;
276 d->offcolor = led_color.dark(darkfactor);
277 update();
278 }
279 }
280
281 int
282 LEDButton::darkFactor() const
283 {
284 return d->dark_factor;
285 }
286
287 void
288 LEDButton::toggle()
289 {
290 toggleState();
291 }
292
293 void
294 LEDButton::on()
295 {
296 setState(On);
297 }
298
299 void
300 LEDButton::off()
301 {
302 setState(Off);
303 }
304
305 QSize
306 LEDButton::sizeHint() const
307 {
308 return QSize(16, 16);
309 }
310
311 QSize
312 LEDButton::minimumSizeHint() const
313 {
314 return QSize(16, 16 );
315 }
316