comparison widgets/LEDButton.cpp @ 983:04337eb34f23 osx-retina

Render LED button direct to widget, making it look OK on retina screen
author Chris Cannam
date Tue, 30 Jun 2015 15:00:23 +0100
parents 1a0dfcbffaf1
children e8949ccb4f4e
comparison
equal deleted inserted replaced
982:5d4730da0276 983:04337eb34f23
36 { 36 {
37 friend class LEDButton; 37 friend class LEDButton;
38 38
39 int dark_factor; 39 int dark_factor;
40 QColor offcolor; 40 QColor offcolor;
41 QPixmap *off_map;
42 QPixmap *on_map;
43 }; 41 };
44 42
45 43
46 LEDButton::LEDButton(QWidget *parent) : 44 LEDButton::LEDButton(QWidget *parent) :
47 QWidget(parent), 45 QWidget(parent),
49 { 47 {
50 QColor col(Qt::green); 48 QColor col(Qt::green);
51 d = new LEDButton::LEDButtonPrivate; 49 d = new LEDButton::LEDButtonPrivate;
52 d->dark_factor = 300; 50 d->dark_factor = 300;
53 d->offcolor = col.dark(300); 51 d->offcolor = col.dark(300);
54 d->off_map = 0;
55 d->on_map = 0;
56 52
57 setColor(col); 53 setColor(col);
58 } 54 }
59 55
60 56
63 led_state(true) 59 led_state(true)
64 { 60 {
65 d = new LEDButton::LEDButtonPrivate; 61 d = new LEDButton::LEDButtonPrivate;
66 d->dark_factor = 300; 62 d->dark_factor = 300;
67 d->offcolor = col.dark(300); 63 d->offcolor = col.dark(300);
68 d->off_map = 0;
69 d->on_map = 0;
70 64
71 setColor(col); 65 setColor(col);
72 } 66 }
73 67
74 LEDButton::LEDButton(const QColor& col, bool state, QWidget *parent) : 68 LEDButton::LEDButton(const QColor& col, bool state, QWidget *parent) :
76 led_state(state) 70 led_state(state)
77 { 71 {
78 d = new LEDButton::LEDButtonPrivate; 72 d = new LEDButton::LEDButtonPrivate;
79 d->dark_factor = 300; 73 d->dark_factor = 300;
80 d->offcolor = col.dark(300); 74 d->offcolor = col.dark(300);
81 d->off_map = 0;
82 d->on_map = 0;
83 75
84 setColor(col); 76 setColor(col);
85 } 77 }
86 78
87 LEDButton::~LEDButton() 79 LEDButton::~LEDButton()
88 { 80 {
89 delete d->off_map;
90 delete d->on_map;
91 delete d; 81 delete d;
92 } 82 }
93 83
94 void 84 void
95 LEDButton::mousePressEvent(QMouseEvent *e) 85 LEDButton::mousePressEvent(QMouseEvent *e)
133 width = this->height(); 123 width = this->height();
134 width -= 2; // leave one pixel border 124 width -= 2; // leave one pixel border
135 if (width < 0) 125 if (width < 0)
136 width = 0; 126 width = 0;
137 127
138 QPixmap *tmpMap = 0; 128 paint.begin(this);
139
140 if (led_state) {
141 if (d->on_map) {
142 if (d->on_map->size() == size()) {
143 paint.begin(this);
144 paint.drawPixmap(0, 0, *d->on_map);
145 paint.end();
146 return;
147 } else {
148 delete d->on_map;
149 d->on_map = 0;
150 }
151 }
152 } else {
153 if (d->off_map) {
154 if (d->off_map->size() == size()) {
155 paint.begin(this);
156 paint.drawPixmap(0, 0, *d->off_map);
157 paint.end();
158 return;
159 } else {
160 delete d->off_map;
161 d->off_map = 0;
162 }
163 }
164 }
165
166 int scale = 1;
167 width *= scale;
168
169 tmpMap = new QPixmap(width, width);
170 tmpMap->fill(palette().background().color());
171 paint.begin(tmpMap);
172 129
173 paint.setRenderHint(QPainter::Antialiasing, true); 130 paint.setRenderHint(QPainter::Antialiasing, true);
174 131
175 // Set the color of the LED according to given parameters 132 // Set the color of the LED according to given parameters
176 color = (led_state) ? led_color : d->offcolor; 133 color = (led_state) ? led_color : d->offcolor;
180 brush.setStyle(Qt::SolidPattern); 137 brush.setStyle(Qt::SolidPattern);
181 brush.setColor(color); 138 brush.setColor(color);
182 paint.setBrush(brush); 139 paint.setBrush(brush);
183 140
184 // Draws a "flat" LED with the given color: 141 // Draws a "flat" LED with the given color:
185 paint.drawEllipse( scale, scale, width - scale*2, width - scale*2 ); 142 paint.drawEllipse( 1, 1, width - 2, width - 2 );
186 143
187 // Draw the bright light spot of the LED now, using modified "old" 144 // Draw the bright light spot of the LED now, using modified "old"
188 // painter routine taken from KDEUI´s LEDButton widget: 145 // painter routine taken from KDEUI´s LEDButton widget:
189 146
190 // Setting the new width of the pen is essential to avoid "pixelized" 147 // Setting the new width of the pen is essential to avoid "pixelized"
191 // shadow like it can be observed with the old LED code 148 // shadow like it can be observed with the old LED code
192 pen.setWidth( 2 * scale ); 149 pen.setWidth( 2 );
193 150
194 // shrink the light on the LED to a size about 2/3 of the complete LED 151 // shrink the light on the LED to a size about 2/3 of the complete LED
195 int pos = width/5 + 1; 152 int pos = width/5 + 1;
196 int light_width = width; 153 int light_width = width;
197 light_width *= 2; 154 light_width *= 2;
219 176
220 // Drawing of bright spot finished, now draw a thin border 177 // Drawing of bright spot finished, now draw a thin border
221 // around the LED which resembles a shadow with light coming 178 // around the LED which resembles a shadow with light coming
222 // from the upper left. 179 // from the upper left.
223 180
224 // pen.setWidth( 2 * scale + 1 ); // ### shouldn't this value be smaller for smaller LEDs? 181 pen.setWidth(2);
225 pen.setWidth(2 * scale);
226 brush.setStyle(Qt::NoBrush); 182 brush.setStyle(Qt::NoBrush);
227 paint.setBrush(brush); // This avoids filling of the ellipse 183 paint.setBrush(brush); // This avoids filling of the ellipse
228 184
229 // Set the initial color value to colorGroup().light() (bright) and start 185 // Set the initial color value to colorGroup().light() (bright) and start
230 // drawing the shadow border at 45° (45*16 = 720). 186 // drawing the shadow border at 45° (45*16 = 720).
233 color = palette().light().color(); 189 color = palette().light().color();
234 190
235 for (int arc = 120; arc < 2880; arc += 240) { 191 for (int arc = 120; arc < 2880; arc += 240) {
236 pen.setColor(color); 192 pen.setColor(color);
237 paint.setPen(pen); 193 paint.setPen(pen);
238 int w = width - pen.width()/2 - scale + 1; 194 int w = width - pen.width()/2;
239 paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle + arc, 240); 195 paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle + arc, 240);
240 paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle - arc, 240); 196 paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle - arc, 240);
241 color = color.dark(110); //FIXME: this should somehow use the contrast value 197 color = color.dark(110); //FIXME: this should somehow use the contrast value
242 } // end for ( angle = 720; angle < 6480; angle += 160 ) 198 } // end for ( angle = 720; angle < 6480; angle += 160 )
243 199
244 paint.end(); 200 paint.end();
245 //
246 // painting done
247
248 QPixmap *&dest = led_state ? d->on_map : d->off_map;
249
250 if (scale > 1) {
251
252 QImage i = tmpMap->toImage();
253 width /= scale;
254 delete tmpMap;
255 dest = new QPixmap(QPixmap::fromImage
256 (i.scaled(width, width,
257 Qt::KeepAspectRatio,
258 Qt::SmoothTransformation)));
259
260 } else {
261
262 dest = tmpMap;
263 }
264
265 paint.begin(this);
266 paint.drawPixmap(0, 0, *dest);
267 paint.end();
268 } 201 }
269 202
270 bool 203 bool
271 LEDButton::state() const 204 LEDButton::state() const
272 { 205 {
301 LEDButton::setColor(const QColor& col) 234 LEDButton::setColor(const QColor& col)
302 { 235 {
303 if(led_color!=col) { 236 if(led_color!=col) {
304 led_color = col; 237 led_color = col;
305 d->offcolor = col.dark(d->dark_factor); 238 d->offcolor = col.dark(d->dark_factor);
306 delete d->on_map;
307 d->on_map = 0;
308 delete d->off_map;
309 d->off_map = 0;
310 update(); 239 update();
311 } 240 }
312 } 241 }
313 242
314 void 243 void