annotate widgets/LEDButton.cpp @ 1534:bfd8b22fd67c

Fix #1904 Scrolling colour 3d plot does not always work when in View normalisation mode. We shouldn't imagine we've just invalidated the cache if the truth is that we've only just created the renderer
author Chris Cannam
date Wed, 09 Oct 2019 13:45:17 +0100
parents d39db4673676
children
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@1174 26 #include "WidgetScale.h"
Chris@32 27
Chris@32 28 #include <QPainter>
Chris@32 29 #include <QImage>
Chris@32 30 #include <QColor>
Chris@33 31 #include <QMouseEvent>
Chris@32 32
Chris@34 33 #include <iostream>
Chris@34 34
Chris@32 35
Chris@32 36 class LEDButton::LEDButtonPrivate
Chris@32 37 {
Chris@32 38 friend class LEDButton;
Chris@32 39
Chris@32 40 int dark_factor;
Chris@32 41 QColor offcolor;
Chris@32 42 };
Chris@32 43
Chris@32 44
Chris@32 45 LEDButton::LEDButton(QWidget *parent) :
Chris@32 46 QWidget(parent),
Chris@34 47 led_state(true)
Chris@32 48 {
Chris@32 49 QColor col(Qt::green);
Chris@32 50 d = new LEDButton::LEDButtonPrivate;
Chris@32 51 d->dark_factor = 300;
Chris@1478 52 d->offcolor = col.darker(300);
Chris@32 53
Chris@32 54 setColor(col);
Chris@32 55 }
Chris@32 56
Chris@32 57
Chris@32 58 LEDButton::LEDButton(const QColor& col, QWidget *parent) :
Chris@32 59 QWidget(parent),
Chris@34 60 led_state(true)
Chris@32 61 {
Chris@32 62 d = new LEDButton::LEDButtonPrivate;
Chris@32 63 d->dark_factor = 300;
Chris@1478 64 d->offcolor = col.darker(300);
Chris@32 65
Chris@32 66 setColor(col);
Chris@32 67 }
Chris@32 68
Chris@34 69 LEDButton::LEDButton(const QColor& col, bool state, QWidget *parent) :
Chris@32 70 QWidget(parent),
Chris@32 71 led_state(state)
Chris@32 72 {
Chris@32 73 d = new LEDButton::LEDButtonPrivate;
Chris@32 74 d->dark_factor = 300;
Chris@1478 75 d->offcolor = col.darker(300);
Chris@32 76
Chris@32 77 setColor(col);
Chris@32 78 }
Chris@32 79
Chris@32 80 LEDButton::~LEDButton()
Chris@32 81 {
Chris@32 82 delete d;
Chris@32 83 }
Chris@32 84
Chris@32 85 void
Chris@33 86 LEDButton::mousePressEvent(QMouseEvent *e)
Chris@33 87 {
Chris@682 88 cerr << "LEDButton(" << this << ")::mousePressEvent" << endl;
Chris@34 89
Chris@33 90 if (e->buttons() & Qt::LeftButton) {
Chris@1266 91 toggle();
Chris@1266 92 bool newState = state();
Chris@1266 93 SVDEBUG << "emitting new state " << newState << endl;
Chris@1266 94 emit stateChanged(newState);
Chris@33 95 }
Chris@33 96 }
Chris@33 97
Chris@33 98 void
Chris@189 99 LEDButton::enterEvent(QEvent *)
Chris@189 100 {
Chris@189 101 emit mouseEntered();
Chris@189 102 }
Chris@189 103
Chris@189 104 void
Chris@189 105 LEDButton::leaveEvent(QEvent *)
Chris@189 106 {
Chris@189 107 emit mouseLeft();
Chris@189 108 }
Chris@189 109
Chris@189 110 void
Chris@32 111 LEDButton::paintEvent(QPaintEvent *)
Chris@32 112 {
Chris@32 113 QPainter paint;
Chris@32 114 QColor color;
Chris@32 115 QBrush brush;
Chris@32 116 QPen pen;
Chris@1266 117
Chris@32 118 // First of all we want to know what area should be updated
Chris@32 119 // Initialize coordinates, width, and height of the LED
Chris@1266 120 int width = this->width();
Chris@32 121
Chris@32 122 // Make sure the LED is round!
Chris@32 123 if (width > this->height())
Chris@1266 124 width = this->height();
Chris@32 125 width -= 2; // leave one pixel border
Chris@32 126 if (width < 0)
Chris@1266 127 width = 0;
Chris@32 128
Chris@983 129 paint.begin(this);
Chris@32 130
Chris@33 131 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@32 132
Chris@32 133 // Set the color of the LED according to given parameters
Chris@32 134 color = (led_state) ? led_color : d->offcolor;
Chris@32 135
Chris@32 136 // Set the brush to SolidPattern, this fills the entire area
Chris@32 137 // of the ellipse which is drawn first
Chris@32 138 brush.setStyle(Qt::SolidPattern);
Chris@32 139 brush.setColor(color);
Chris@32 140 paint.setBrush(brush);
Chris@32 141
Chris@32 142 // Draws a "flat" LED with the given color:
Chris@983 143 paint.drawEllipse( 1, 1, width - 2, width - 2 );
Chris@32 144
Chris@32 145 // Draw the bright light spot of the LED now, using modified "old"
Chris@32 146 // painter routine taken from KDEUI´s LEDButton widget:
Chris@32 147
Chris@32 148 // Setting the new width of the pen is essential to avoid "pixelized"
Chris@32 149 // shadow like it can be observed with the old LED code
Chris@983 150 pen.setWidth( 2 );
Chris@32 151
Chris@32 152 // shrink the light on the LED to a size about 2/3 of the complete LED
Chris@32 153 int pos = width/5 + 1;
Chris@32 154 int light_width = width;
Chris@32 155 light_width *= 2;
Chris@32 156 light_width /= 3;
Chris@1266 157
Chris@32 158 // Calculate the LED´s "light factor":
Chris@32 159 int light_quote = (130*2/(light_width?light_width:1))+100;
Chris@32 160
Chris@32 161 // Now draw the bright spot on the LED:
Chris@32 162 while (light_width) {
Chris@1478 163 color = color.lighter( light_quote ); // make color lighter
Chris@1266 164 pen.setColor( color ); // set color as pen color
Chris@1266 165 paint.setPen( pen ); // select the pen for drawing
Chris@1266 166 paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle)
Chris@1266 167 light_width--;
Chris@1266 168 if (!light_width)
Chris@1266 169 break;
Chris@1266 170 paint.drawEllipse( pos, pos, light_width, light_width );
Chris@1266 171 light_width--;
Chris@1266 172 if (!light_width)
Chris@1266 173 break;
Chris@1266 174 paint.drawEllipse( pos, pos, light_width, light_width );
Chris@1266 175 pos++; light_width--;
Chris@32 176 }
Chris@32 177
Chris@984 178 paint.drawPoint(pos, pos);
Chris@984 179
Chris@32 180 // Drawing of bright spot finished, now draw a thin border
Chris@32 181 // around the LED which resembles a shadow with light coming
Chris@32 182 // from the upper left.
Chris@32 183
Chris@983 184 pen.setWidth(2);
Chris@32 185 brush.setStyle(Qt::NoBrush);
Chris@32 186 paint.setBrush(brush); // This avoids filling of the ellipse
Chris@32 187
Chris@32 188 // Set the initial color value to colorGroup().light() (bright) and start
Chris@32 189 // drawing the shadow border at 45° (45*16 = 720).
Chris@32 190
Chris@32 191 int angle = -720;
Chris@32 192 color = palette().light().color();
Chris@32 193
Chris@32 194 for (int arc = 120; arc < 2880; arc += 240) {
Chris@1266 195 pen.setColor(color);
Chris@1266 196 paint.setPen(pen);
Chris@1266 197 int w = width - pen.width()/2;
Chris@1266 198 paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle + arc, 240);
Chris@1266 199 paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle - arc, 240);
Chris@1478 200 color = color.darker(110); //FIXME: this should somehow use the contrast value
Chris@1266 201 } // end for ( angle = 720; angle < 6480; angle += 160 )
Chris@32 202
Chris@32 203 paint.end();
Chris@32 204 }
Chris@32 205
Chris@34 206 bool
Chris@32 207 LEDButton::state() const
Chris@32 208 {
Chris@32 209 return led_state;
Chris@32 210 }
Chris@32 211
Chris@32 212 QColor
Chris@32 213 LEDButton::color() const
Chris@32 214 {
Chris@32 215 return led_color;
Chris@32 216 }
Chris@32 217
Chris@32 218 void
Chris@34 219 LEDButton::setState( bool state )
Chris@32 220 {
Chris@32 221 if (led_state != state)
Chris@32 222 {
Chris@1266 223 led_state = state;
Chris@1266 224 update();
Chris@32 225 }
Chris@32 226 }
Chris@32 227
Chris@32 228 void
Chris@32 229 LEDButton::toggleState()
Chris@32 230 {
Chris@34 231 led_state = (led_state == true) ? false : true;
Chris@32 232 // setColor(led_color);
Chris@32 233 update();
Chris@32 234 }
Chris@32 235
Chris@32 236 void
Chris@32 237 LEDButton::setColor(const QColor& col)
Chris@32 238 {
Chris@32 239 if(led_color!=col) {
Chris@1266 240 led_color = col;
Chris@1478 241 d->offcolor = col.darker(d->dark_factor);
Chris@1266 242 update();
Chris@32 243 }
Chris@32 244 }
Chris@32 245
Chris@32 246 void
Chris@32 247 LEDButton::setDarkFactor(int darkfactor)
Chris@32 248 {
Chris@32 249 if (d->dark_factor != darkfactor) {
Chris@1266 250 d->dark_factor = darkfactor;
Chris@1478 251 d->offcolor = led_color.darker(darkfactor);
Chris@1266 252 update();
Chris@32 253 }
Chris@32 254 }
Chris@32 255
Chris@32 256 int
Chris@32 257 LEDButton::darkFactor() const
Chris@32 258 {
Chris@32 259 return d->dark_factor;
Chris@32 260 }
Chris@32 261
Chris@32 262 void
Chris@32 263 LEDButton::toggle()
Chris@32 264 {
Chris@32 265 toggleState();
Chris@32 266 }
Chris@32 267
Chris@32 268 void
Chris@32 269 LEDButton::on()
Chris@32 270 {
Chris@34 271 setState(true);
Chris@32 272 }
Chris@32 273
Chris@32 274 void
Chris@32 275 LEDButton::off()
Chris@32 276 {
Chris@34 277 setState(false);
Chris@32 278 }
Chris@32 279
Chris@32 280 QSize
Chris@32 281 LEDButton::sizeHint() const
Chris@32 282 {
Chris@1174 283 return WidgetScale::scaleQSize(QSize(17, 17));
Chris@32 284 }
Chris@32 285
Chris@32 286 QSize
Chris@32 287 LEDButton::minimumSizeHint() const
Chris@32 288 {
Chris@1174 289 return WidgetScale::scaleQSize(QSize(17, 17));
Chris@32 290 }
Chris@32 291