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