Fine tuned the direction indicator arrow look
[situare] / src / ui / indicatorbutton.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Katri Kaikkonen - katri.kaikkonen@ixonos.com
6         Sami Rämö - sami.ramo@ixonos.com
7
8     Situare is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License
10     version 2 as published by the Free Software Foundation.
11
12     Situare is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with Situare; if not, write to the Free Software
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20     USA.
21 */
22
23 #include "math.h"
24
25 #include <QDebug>
26 #include <QPainter>
27 #include <QSettings>
28
29 #include "common.h"
30 #include "panelcommon.h"
31
32 #include "indicatorbutton.h"
33
34 enum State {OFF, ON};                       ///< Enumerator for led state
35
36 IndicatorButton::IndicatorButton(QWidget *parent)
37     : QToolButton(parent),
38       m_drawTriangle(false),
39       m_direction(0)
40 {
41     qDebug() << __PRETTY_FUNCTION__;
42
43     const qreal OPACITY = 0.50;
44     const int BUTTON_WIDTH = 66;
45     const int BUTTON_HEIGHT = 66;
46
47     m_indicatorLeds[OFF].load(":res/images/gps_position.png");
48     m_indicatorLeds[ON].load(":res/images/gps_position_s.png");
49
50     setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
51
52     // Normal background
53     m_normalColor = new QColor(Qt::black);
54     m_normalColor->setAlpha(floor(OPACITY * 255));
55
56     // Selected background
57     m_selectedGradient = new QLinearGradient(0, 0, 0, this->height());
58     m_selectedGradient->setColorAt(0.02, QColor(0, 113, 181));
59     m_selectedGradient->setColorAt(0.25, QColor(24, 142, 214));
60     m_selectedGradient->setColorAt(0.5, QColor(41, 162, 239));
61     m_selectedGradient->setColorAt(0.75, QColor(82, 195, 255));
62     m_selectedGradient->setColorAt(0.98, QColor(115, 215, 255));
63
64     connect(this, SIGNAL(clicked(bool)),
65             this, SIGNAL(autoCenteringTriggered(bool)));
66
67     setCheckable(true);
68 }
69
70 IndicatorButton::~IndicatorButton()
71 {
72     qDebug() << __PRETTY_FUNCTION__;
73
74     delete m_normalColor;
75     delete m_selectedGradient;
76 }
77
78 const QPoint& IndicatorButton::eventPosition()
79 {
80     qDebug() << __PRETTY_FUNCTION__;
81
82     return m_eventPosition;
83 }
84
85 void IndicatorButton::mousePressEvent(QMouseEvent *event)
86 {
87     qDebug() << __PRETTY_FUNCTION__;
88
89     QToolButton::mousePressEvent(event);
90
91     event->ignore();
92 }
93
94 void IndicatorButton::mouseReleaseEvent(QMouseEvent *event)
95 {
96     qDebug() << __PRETTY_FUNCTION__;
97
98     QToolButton::mouseReleaseEvent(event);
99
100     event->ignore();
101 }
102
103 void IndicatorButton::paintEvent(QPaintEvent *event)
104 {
105     qDebug() << __PRETTY_FUNCTION__;
106
107     const int ROUNDING_RADIUS = 9;
108
109     Q_UNUSED(event);
110
111     QPainterPath backgroundPath;
112     backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
113
114     QPainter painter(this);
115     painter.setRenderHint(QPainter::Antialiasing);
116
117     if (isDown())
118         painter.fillPath(backgroundPath, QBrush(*m_selectedGradient));
119     else
120         painter.fillPath(backgroundPath, QBrush(*m_normalColor));
121
122     const QPointF CENTER = QPointF(this->width(), this->height()) / 2;
123
124     if (isChecked()) {
125         const QPointF offset = QPointF(m_indicatorLeds[ON].width(),
126                                        m_indicatorLeds[ON].height()) / 2;
127
128         painter.drawPixmap(CENTER - offset, m_indicatorLeds[ON]);
129     } else {
130         const QPointF offset = QPointF(m_indicatorLeds[OFF].width(),
131                                        m_indicatorLeds[OFF].height()) / 2;
132
133         painter.drawPixmap(CENTER - offset, m_indicatorLeds[OFF]);
134     }
135
136     // draw the direction indicator triangle only when autocentering is disabled and MapEngine
137     // doesn't deny drawing (because GPS location item is visible)
138     if (!isChecked() && m_drawTriangle) {
139         const int TRIANGLE_WIDTH = 14;
140         const int TRIANGLE_HEIGHT = 15;
141         const int TRIANGLE_DISTANCE_FROM_CENTER = 13;
142
143         const int POINTS = 3;
144         const QPointF points[POINTS] = {
145             QPointF(-TRIANGLE_WIDTH / 2, -TRIANGLE_DISTANCE_FROM_CENTER),
146             QPointF(0, -(TRIANGLE_DISTANCE_FROM_CENTER + TRIANGLE_HEIGHT)),
147             QPointF(TRIANGLE_WIDTH / 2, -TRIANGLE_DISTANCE_FROM_CENTER)
148         };
149
150         // base triangle is facing up, and needs to be rotated to the required direction
151         QTransform rotationTransform;
152         rotationTransform.rotate(m_direction);
153
154         // origin is in the top left corner of the button, and needs to be translated to the
155         // center of the button
156         QTransform translateTransform;
157         translateTransform.translate(CENTER.x(), CENTER.y());
158
159         painter.setTransform(rotationTransform * translateTransform);
160
161         // setting the look of the triangle
162         const QColor TRIANGLE_BACKGROUND_COLOR = QColor("#68d0f8");
163         painter.setBrush(QBrush(TRIANGLE_BACKGROUND_COLOR));
164         painter.setPen(Qt::black);
165
166         painter.drawPolygon(points, POINTS);
167     }
168 }
169
170 void IndicatorButton::setDirection(qreal direction, bool draw)
171 {
172     qDebug() << __PRETTY_FUNCTION__;
173
174     m_direction = direction;
175     m_drawTriangle = draw;
176
177     update();
178 }