Just some small cosmetic chages (spacings and curly brackets)
[situare] / src / ui / indicatorbuttonpanel.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Pekka Nissinen - pekka.nissinen@ixonos.com
6        Kaj Wallin - kaj.wallin@ixonos.com
7        Katri Kaikkonen - katri.kaikkonen@ixonos.com
8
9    Situare is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License
11    version 2 as published by the Free Software Foundation.
12
13    Situare is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Situare; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
21    USA.
22 */
23
24 #include <QDebug>
25 #include <QPainter>
26 #include <QSettings>
27
28 #include "common.h"
29 #include "indicatorbutton.h"
30 #include "panelcommon.h"
31
32 #include "indicatorbuttonpanel.h"
33
34 const QString DIRECTION_INDICATOR_BUTTON_POSITION = "DIRECTION_INDICATOR_POSITION";
35
36 IndicatorButtonPanel::IndicatorButtonPanel(QWidget *parent)
37     : QWidget(parent),
38       m_isDraggable(false)
39 {
40     qDebug() << __PRETTY_FUNCTION__;
41
42     const int DIRECTION_INDICATOR_POSITION_X = 10;
43     const int DIRECTION_INDICATOR_POSITION_Y = 290;
44
45     const int INDICATOR_BUTTON_PANEL_SPACING = 5;
46
47     const qreal OPACITY = 0.50;
48     const int MARGIN_LEFT = 0;
49     const int MARGIN_TOP = 3;
50     const int MARGIN_RIGHT = 0;
51     const int MARGIN_BOTTOM = 0;
52     const int LABEL_MARGIN_TOP = 0;
53
54     const int PANEL_WIDTH = 90;
55     const int PANEL_HEIGHT = 100;
56
57     QVBoxLayout *verticalLayout = new QVBoxLayout;
58     setLayout(verticalLayout);
59     verticalLayout->setContentsMargins(MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM);
60     verticalLayout->setSpacing(INDICATOR_BUTTON_PANEL_SPACING);
61
62     m_indicatorButton = new IndicatorButton(this);
63
64     m_distanceTextLabel = new QLabel();
65     m_distanceTextLabel->setFont(QFont(NOKIA_FONT_SMALL));
66     m_distanceTextLabel->setAlignment(Qt::AlignHCenter);
67     m_distanceTextLabel->setContentsMargins(MARGIN_LEFT, LABEL_MARGIN_TOP, MARGIN_RIGHT
68                                             , MARGIN_BOTTOM);
69
70     m_normalColor = new QColor(Qt::black);
71     m_normalColor->setAlpha(OPACITY * 255);
72
73     verticalLayout->addWidget(m_indicatorButton, 0, Qt::AlignHCenter);
74     verticalLayout->addWidget(m_distanceTextLabel, 0, Qt::AlignHCenter);
75     verticalLayout->addStretch();
76
77     setFixedSize(PANEL_WIDTH, PANEL_HEIGHT);
78
79     QSettings settings(DIRECTORY_NAME, FILE_NAME);
80     QPoint savedLocation = settings.value(DIRECTION_INDICATOR_BUTTON_POSITION,
81                                           QPoint(DIRECTION_INDICATOR_POSITION_X,
82                                                  DIRECTION_INDICATOR_POSITION_Y)).toPoint();
83
84     if ((savedLocation.x() > DEFAULT_SCREEN_WIDTH) || (savedLocation.y() > DEFAULT_SCREEN_HEIGHT)) {
85         savedLocation.rx() = DIRECTION_INDICATOR_POSITION_X;
86         savedLocation.ry() = DIRECTION_INDICATOR_POSITION_Y;
87     }
88
89     move(savedLocation);
90
91     m_dragStartTimer = new QTimer(this);
92     m_dragStartTimer->setSingleShot(true);
93     m_dragStartTimer->setInterval(DRAG_INIT_TIME);
94
95     m_forceReleaseTimer = new QTimer(this);
96     m_forceReleaseTimer->setSingleShot(true);
97     m_forceReleaseTimer->setInterval(FORCE_RELEASE_TIME);
98
99     connect(m_dragStartTimer, SIGNAL(timeout()),
100             this, SLOT(timerExpired()));
101
102     connect(m_forceReleaseTimer, SIGNAL(timeout()),
103             this, SLOT(forceMouseRelease()));
104
105     connect(this, SIGNAL(directionIndicatorValuesUpdate(qreal, qreal, bool)),
106             this, SLOT(updateValues(qreal, qreal, bool)));
107
108     connect(m_indicatorButton, SIGNAL(autoCenteringTriggered(bool)),
109             this, SIGNAL(autoCenteringTriggered(bool)));
110 }
111
112 void IndicatorButtonPanel::forceMouseRelease()
113 {
114     qDebug() << __PRETTY_FUNCTION__;
115
116     releaseMouse();
117     setDraggable(false);
118 }
119
120 void IndicatorButtonPanel::mouseMoveEvent(QMouseEvent *event)
121 {
122     qDebug() << __PRETTY_FUNCTION__;
123
124     if (m_isDraggable) {
125         if (event->buttons() & Qt::LeftButton) {
126             QPoint newLocation = mapToParent(event->pos()) - m_dragPosition;
127
128             if (newLocation.x() < 0)
129                 newLocation.rx() = 0;
130             else if (newLocation.x() > (m_screenSize.width() - width() - PANEL_BAR_WIDTH))
131                 newLocation.rx() =  m_screenSize.width() - width() - PANEL_BAR_WIDTH;
132
133             if (newLocation.y() < 0)
134                 newLocation.ry() = 0;
135             else if (newLocation.y() > (m_screenSize.height() - height()))
136                 newLocation.ry() = m_screenSize.height() - height();
137
138             move(newLocation);
139         }
140     } else {
141         if (!rect().contains(event->pos()))
142             m_dragStartTimer->stop();
143     }
144 }
145
146 void IndicatorButtonPanel::mousePressEvent(QMouseEvent *event)
147 {
148     qDebug() << __PRETTY_FUNCTION__;
149
150     m_dragPosition = event->pos();
151     m_dragStartTimer->start();
152 }
153
154 void IndicatorButtonPanel::mouseReleaseEvent(QMouseEvent *event)
155 {
156     qDebug() << __PRETTY_FUNCTION__;
157
158     m_dragStartTimer->stop();
159
160     Q_UNUSED(event);
161     if (m_isDraggable) {
162         setDraggable(false);
163
164         QSettings settings(DIRECTORY_NAME, FILE_NAME);
165         settings.setValue(DIRECTION_INDICATOR_BUTTON_POSITION, pos());
166     }
167 }
168
169 void IndicatorButtonPanel::paintEvent(QPaintEvent *event)
170 {
171     qDebug() << __PRETTY_FUNCTION__;
172
173     Q_UNUSED(event);
174
175     QPainter painter(this);
176     painter.setRenderHint(QPainter::Antialiasing);
177
178     if (!m_indicatorButton->isChecked()) {
179         const int EXTRA_SPACE_LEFT = -5;
180         const int EXTRA_SPACE_TOP = 0;
181         const int EXTRA_SPACE_RIGHT = +5;
182         const int EXTRA_SPACE_BOTTOM = 0;
183
184         const int RADIUS_WIDTH = 5;
185         const int RADIUS_HEIGHT = 5;
186
187         QPainterPath backgroundPath;
188         QRect distanceLabelRect = m_distanceTextLabel->rect();
189
190         distanceLabelRect.translate(m_distanceTextLabel->pos());
191         distanceLabelRect.adjust(EXTRA_SPACE_LEFT, EXTRA_SPACE_TOP, EXTRA_SPACE_RIGHT
192                                  , EXTRA_SPACE_BOTTOM);
193         backgroundPath.addRoundedRect(distanceLabelRect, RADIUS_WIDTH, RADIUS_HEIGHT);
194         painter.fillPath(backgroundPath, QBrush(*m_normalColor));
195     }
196
197     if (m_isDraggable) {
198         const int ROUNDING_RADIUS = 9;
199
200         QPainterPath backgroundPath;
201         backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
202         painter.fillPath(backgroundPath, QBrush(Qt::Dense4Pattern));
203         painter.setPen(Qt::black);
204     }
205 }
206
207 void IndicatorButtonPanel::screenResized(const QSize &newSize)
208 {
209     qDebug() << __PRETTY_FUNCTION__;
210
211     int oldHeight = 0;
212     int oldWidth = 0;
213
214     if (m_screenSize.height() < 0)
215         oldHeight = DEFAULT_NON_FULLSCREEN_HEIGHT;
216     else
217         oldHeight = m_screenSize.height();
218
219     if (m_screenSize.width() < 0)
220         oldWidth = DEFAULT_SCREEN_WIDTH;
221     else
222         oldWidth = m_screenSize.width();
223
224     m_screenSize = newSize;
225
226     QPoint resizedPosition = pos();
227
228     if (resizedPosition.x() < 0)
229         resizedPosition.rx() = 0;
230     else if (resizedPosition.x() > (newSize.width() - rect().width() - PANEL_BAR_WIDTH))
231         resizedPosition.rx() = newSize.width() - rect().width() - PANEL_BAR_WIDTH;
232
233     if (resizedPosition.y() < 0)
234         resizedPosition.ry() = 0;
235     else if (resizedPosition.y() > (newSize.height() - rect().height()))
236         resizedPosition.ry() = newSize.height() - rect().height();
237
238     if ((pos().y() + rect().center().y()) > (oldHeight / 2))
239         resizedPosition.ry() = newSize.height() - (oldHeight - pos().y());
240
241     if ((pos().x() + rect().center().x()) > (oldWidth / 2))
242         resizedPosition.rx() = newSize.width() - (oldWidth - pos().x());
243
244     move(resizedPosition);
245 }
246
247 void IndicatorButtonPanel::setDraggable(bool mode, QPoint eventPosition)
248 {
249     qDebug() << __PRETTY_FUNCTION__;
250
251     m_isDraggable = mode;
252
253     if (mode) {
254         emit draggingModeTriggered();
255         grabMouse();
256         m_forceReleaseTimer->start();
257         m_dragPosition = eventPosition;
258     } else {
259         releaseMouse();
260         m_forceReleaseTimer->stop();
261         m_indicatorButton->setDown(false);
262     }
263     update();
264 }
265
266 void IndicatorButtonPanel::setIndicatorButtonEnabled(bool enabled)
267 {
268     qDebug() << __PRETTY_FUNCTION__;
269
270     m_indicatorButton->setChecked(enabled);
271     m_distanceTextLabel->setVisible(!enabled);
272
273     update();
274 }
275
276 void IndicatorButtonPanel::timerExpired()
277 {
278     qDebug() << __PRETTY_FUNCTION__;
279
280     setDraggable(true, m_dragPosition);
281 }
282
283 void IndicatorButtonPanel::updateValues(qreal direction, qreal distance, bool draw)
284 {
285     qDebug() << __PRETTY_FUNCTION__;
286
287     const int MAX_TO_METERS = 999.5;
288     const int MAX_TO_KM_WITH_DESIMAL = 99950;
289     const int MIN_TO_METERS = 10;
290     const int M_TO_KM = 1000;                   ///< Meters to kilometers conversion
291
292     QString UNIT_KILOMETER = " km";
293     QString UNIT_METER = " m";
294
295     m_indicatorButton->setDirection(direction, draw);
296
297     m_distance = distance;
298
299     if (m_distance < MIN_TO_METERS)
300     {
301         m_distanceText.setNum(10);
302         m_distanceText.prepend("< ");
303         m_distanceText.append(UNIT_METER);
304     } else if (m_distance < MAX_TO_METERS) {
305         m_distanceText.setNum(m_distance, 'f', 0);
306         m_distanceText.append(UNIT_METER);
307     } else if (m_distance < MAX_TO_KM_WITH_DESIMAL) {
308         m_distanceText.setNum(m_distance / M_TO_KM, 'f', 1);
309         m_distanceText.append(UNIT_KILOMETER);
310     } else {
311         m_distanceText.setNum(m_distance / M_TO_KM, 'f', 0);
312         m_distanceText.append(UNIT_KILOMETER);
313     }
314
315     m_distanceTextLabel->setText(m_distanceText);
316
317     update();
318 }