Mercurial > hg > svgui
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 |