annotate widgets/LEDButton.cpp @ 959:2633a1d73e39

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