Added missing default values to PanelBar, PanelBase and TabbedPanel constructors
[situare] / src / ui / indicatorbutton.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Kaj Wallin - kaj.wallin@ixonos.com
6         Katri Kaikkonen - katri.kaikkonen@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 <QDebug>
24 #include <QPainter>
25 #include <QSettings>
26
27 #include "math.h"
28
29 #include "indicatorbutton.h"
30
31 #include "common.h"
32 #include "panelcommon.h"
33
34 enum State {OFF, ON};           ///< Enumerator for led state
35
36 const int ROUNDING_RADIUS = 9;  ///< Roundness of the rounded edge
37 const int BUTTON_WIDTH = 66;    ///< Button width
38 const int BUTTON_HEIGHT = 66;   ///< Button height
39
40 const qreal OPACITY = 0.50;     ///< Opacity of the background in percents
41
42 IndicatorButton::IndicatorButton(QWidget *parent)
43     : QToolButton(parent),
44       m_isDraggable(false)
45 {
46     m_indicatorLeds[OFF].load(":res/images/gps_position.png");
47     m_indicatorLeds[ON].load(":res/images/gps_position_s.png");
48     setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
49
50     QSettings settings(DIRECTORY_NAME, FILE_NAME);
51     QPoint savedLocation = settings.value(DIRECTION_INDICATOR_BUTTON_POSITION,
52                                           QPoint(DIRECTION_INDICATOR_POSITION_X,
53                                                  DIRECTION_INDICATOR_POSITION_Y)).toPoint();
54
55     if(savedLocation.x() > DEFAULT_SCREEN_WIDTH || savedLocation.y() > DEFAULT_SCREEN_HEIGHT) {
56         savedLocation.rx() = DIRECTION_INDICATOR_POSITION_X;
57         savedLocation.ry() = DIRECTION_INDICATOR_POSITION_Y;
58     }
59
60     move(savedLocation);
61
62     // Normal background
63     m_normalColor = new QColor(Qt::black);
64     m_normalColor->setAlpha(floor(OPACITY * 255));
65
66     // Selected bakcground
67     m_selectedGradient = new QLinearGradient(0, 0, 0, this->height());
68     m_selectedGradient->setColorAt(0.02, QColor(0, 113, 181));
69     m_selectedGradient->setColorAt(0.25, QColor(24, 142, 214));
70     m_selectedGradient->setColorAt(0.5, QColor(41, 162, 239));
71     m_selectedGradient->setColorAt(0.75, QColor(82, 195, 255));
72     m_selectedGradient->setColorAt(0.98, QColor(115, 215, 255));
73
74     m_dragStartTimer = new QTimer(this);
75     m_dragStartTimer->setSingleShot(true);
76     m_dragStartTimer->setInterval(DRAG_INIT_TIME);
77
78     m_forceReleaseTimer = new QTimer(this);
79     m_forceReleaseTimer->setSingleShot(true);
80     m_forceReleaseTimer->setInterval(FORCE_RELEASE_TIME);
81
82     connect(this, SIGNAL(pressed()),
83             m_dragStartTimer, SLOT(start()));
84     connect(this, SIGNAL(released()),
85             m_dragStartTimer, SLOT(stop()));
86     connect(this, SIGNAL(clicked(bool)),
87             this, SIGNAL(autoCenteringTriggered(bool)));
88
89     connect(m_dragStartTimer, SIGNAL(timeout()),
90             this, SLOT(timerExpired()));
91     connect(m_forceReleaseTimer, SIGNAL(timeout()),
92             this, SLOT(forceMouseRelease()));
93
94     setCheckable(true);
95 }
96
97 IndicatorButton::~IndicatorButton()
98 {
99     qDebug() << __PRETTY_FUNCTION__;
100
101     delete m_normalColor;
102     delete m_selectedGradient;
103 }
104
105 void IndicatorButton::mousePressEvent(QMouseEvent *event)
106 {
107     qDebug() << __PRETTY_FUNCTION__;
108
109     if (event->button() == Qt::LeftButton)
110         m_dragPosition = event->pos();
111
112     m_eventPosition = mapToParent(event->pos());
113     m_dragStartTimer->start();
114     setDown(true);
115 }
116
117 void IndicatorButton::mouseMoveEvent(QMouseEvent *event)
118 {
119     qDebug() << __PRETTY_FUNCTION__;
120
121     if(m_isDraggable) {
122         if (event->buttons() & Qt::LeftButton) {
123             QPoint newLocation = mapToParent(event->pos()) - m_dragPosition;
124
125             if (newLocation.x() < 0)
126                 newLocation.rx() = 0;
127             else if (newLocation.x() > m_screenSize.width() - width() - PANEL_BAR_WIDTH)
128                 newLocation.rx() =  m_screenSize.width() - width() - PANEL_BAR_WIDTH;
129
130             if (newLocation.y() < 0)
131                 newLocation.ry() = 0;
132             else if (newLocation.y() > m_screenSize.height() - height())
133                 newLocation.ry() = m_screenSize.height() - height();
134
135             move(newLocation);
136         }
137     } else {
138         if(!rect().contains(event->pos())) {
139             m_dragStartTimer->stop();
140             setDown(false);
141         }
142     }
143 }
144
145 void IndicatorButton::mouseReleaseEvent(QMouseEvent *event)
146 {
147     qDebug() << __PRETTY_FUNCTION__;
148
149     m_dragStartTimer->stop();
150
151     if(m_isDraggable) {
152         setDraggable(false);
153         QSettings settings(DIRECTORY_NAME, FILE_NAME);
154         settings.setValue(DIRECTION_INDICATOR_BUTTON_POSITION, pos());
155     } else {
156         if(this->rect().contains(event->pos())) {
157             if(isChecked()) {
158                 setChecked(false);
159                 emit autoCenteringTriggered(false);
160             } else {
161                 setChecked(true);
162                 emit autoCenteringTriggered(true);
163             }
164         }
165     }
166     setDown(false);
167 }
168
169 void IndicatorButton::setDraggable(bool mode, QPoint eventPosition)
170 {
171     qDebug() << __PRETTY_FUNCTION__;
172
173     m_isDraggable = mode;
174
175     if(mode) {
176         emit draggingModeTriggered();
177         m_forceReleaseTimer->start();
178         m_dragPosition = eventPosition;
179     } else {
180         m_forceReleaseTimer->stop();
181     }
182     update();
183 }
184
185 void IndicatorButton::screenResized(const QSize &newSize)
186 {
187     qDebug() << __PRETTY_FUNCTION__;
188
189     int oldHeight = 0;
190     int oldWidth = 0;
191
192     if(m_screenSize.height() < 0)
193         oldHeight = DEFAULT_NON_FULLSCREEN_HEIGHT;
194     else
195         oldHeight = m_screenSize.height();
196
197     if(m_screenSize.width() < 0)
198         oldWidth = DEFAULT_SCREEN_WIDTH;
199     else
200         oldWidth = m_screenSize.width();
201
202     m_screenSize = newSize;
203
204     QPoint resizedPosition = pos();
205
206     if (resizedPosition.x() < 0)
207         resizedPosition.rx() = 0;
208     else if(resizedPosition.x() > (newSize.width() - rect().width()))
209         resizedPosition.rx() = newSize.width() - rect().width();
210
211     if (resizedPosition.y() < 0)
212         resizedPosition.ry() = 0;
213     else if(resizedPosition.y() > (newSize.height() - rect().height()))
214         resizedPosition.ry() = newSize.height() - rect().height();
215
216     if((pos().y() + rect().center().y()) > (oldHeight/2))
217         resizedPosition.ry() = newSize.height() - (oldHeight - pos().y());
218
219     if((pos().x() + rect().center().x()) > (oldWidth/2))
220         resizedPosition.rx() = newSize.width() - (oldWidth - pos().x());
221
222     move(resizedPosition);
223 }
224
225 const QPoint& IndicatorButton::eventPosition()
226 {
227     qDebug() << __PRETTY_FUNCTION__;
228
229     return m_eventPosition;
230 }
231
232 void IndicatorButton::forceMouseRelease()
233 {
234     qDebug() << __PRETTY_FUNCTION__;
235
236     releaseMouse();
237     setDraggable(false);
238 }
239
240 void IndicatorButton::paintEvent(QPaintEvent *event)
241 {
242     qDebug() << __PRETTY_FUNCTION__;
243
244     Q_UNUSED(event);
245
246     QPainterPath backgroundPath;
247     backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
248
249     QPainter painter(this);
250     painter.setRenderHint(QPainter::Antialiasing);
251
252     if(m_isDraggable)
253         painter.fillPath(backgroundPath, QBrush(Qt::Dense4Pattern));
254     else if (isDown())
255         painter.fillPath(backgroundPath, QBrush(*m_selectedGradient));
256     else
257         painter.fillPath(backgroundPath, QBrush(*m_normalColor));
258
259     if(isChecked())
260         painter.drawPixmap((this->width() / 2) - (m_indicatorLeds[ON].width() / 2),
261                            (this->height() / 2) - (m_indicatorLeds[ON].height() / 2),
262                            m_indicatorLeds[ON]);
263     else
264         painter.drawPixmap((this->width() / 2) - (m_indicatorLeds[OFF].width() / 2),
265                            (this->height() / 2) - (m_indicatorLeds[OFF].height() / 2),
266                            m_indicatorLeds[OFF]);
267 }
268
269 void IndicatorButton::timerExpired()
270 {
271     qDebug() << __PRETTY_FUNCTION__;
272
273     setDraggable(true, m_dragPosition);
274 }