2 Situare - A location system for Facebook
3 Copyright (C) 2010 Ixonos Plc. Authors:
5 Pekka Nissinen - pekka.nissinen@ixonos.com
6 Kaj Wallin - kaj.wallin@ixonos.com
7 Katri Kaikkonen - katri.kaikkonen@ixonos.com
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.
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.
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,
29 #include "indicatorbutton.h"
30 #include "panelcommon.h"
32 #include "indicatorbuttonpanel.h"
34 const QString DIRECTION_INDICATOR_BUTTON_POSITION = "DIRECTION_INDICATOR_POSITION";
36 IndicatorButtonPanel::IndicatorButtonPanel(QWidget *parent)
40 qDebug() << __PRETTY_FUNCTION__;
42 const int DIRECTION_INDICATOR_POSITION_X = 10;
43 const int DIRECTION_INDICATOR_POSITION_Y = 290;
45 const int INDICATOR_BUTTON_PANEL_SPACING = 5;
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;
54 const int PANEL_WIDTH = 90;
55 const int PANEL_HEIGHT = 100;
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);
62 m_indicatorButton = new IndicatorButton(this);
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
70 m_normalColor = new QColor(Qt::black);
71 m_normalColor->setAlpha(OPACITY * 255);
73 verticalLayout->addWidget(m_indicatorButton, 0, Qt::AlignHCenter);
74 verticalLayout->addWidget(m_distanceTextLabel, 0, Qt::AlignHCenter);
75 verticalLayout->addStretch();
77 setFixedSize(PANEL_WIDTH, PANEL_HEIGHT);
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();
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;
91 m_dragStartTimer = new QTimer(this);
92 m_dragStartTimer->setSingleShot(true);
93 m_dragStartTimer->setInterval(DRAG_INIT_TIME);
95 m_forceReleaseTimer = new QTimer(this);
96 m_forceReleaseTimer->setSingleShot(true);
97 m_forceReleaseTimer->setInterval(FORCE_RELEASE_TIME);
99 connect(m_dragStartTimer, SIGNAL(timeout()),
100 this, SLOT(timerExpired()));
102 connect(m_forceReleaseTimer, SIGNAL(timeout()),
103 this, SLOT(forceMouseRelease()));
105 connect(this, SIGNAL(directionIndicatorValuesUpdate(qreal, qreal, bool)),
106 this, SLOT(updateValues(qreal, qreal, bool)));
108 connect(m_indicatorButton, SIGNAL(autoCenteringTriggered(bool)),
109 this, SIGNAL(autoCenteringTriggered(bool)));
112 IndicatorButtonPanel::~IndicatorButtonPanel()
114 qDebug() << __PRETTY_FUNCTION__;
116 delete m_normalColor;
119 void IndicatorButtonPanel::forceMouseRelease()
121 qDebug() << __PRETTY_FUNCTION__;
127 void IndicatorButtonPanel::mouseMoveEvent(QMouseEvent *event)
129 qDebug() << __PRETTY_FUNCTION__;
132 if (event->buttons() & Qt::LeftButton) {
133 QPoint newLocation = mapToParent(event->pos()) - m_dragPosition;
135 if (newLocation.x() < 0)
136 newLocation.rx() = 0;
137 else if (newLocation.x() > (m_screenSize.width() - width() - PANEL_BAR_WIDTH))
138 newLocation.rx() = m_screenSize.width() - width() - PANEL_BAR_WIDTH;
140 if (newLocation.y() < 0)
141 newLocation.ry() = 0;
142 else if (newLocation.y() > (m_screenSize.height() - height()))
143 newLocation.ry() = m_screenSize.height() - height();
148 if (!rect().contains(event->pos()))
149 m_dragStartTimer->stop();
153 void IndicatorButtonPanel::mousePressEvent(QMouseEvent *event)
155 qDebug() << __PRETTY_FUNCTION__;
157 m_dragPosition = event->pos();
158 m_dragStartTimer->start();
161 void IndicatorButtonPanel::mouseReleaseEvent(QMouseEvent *event)
163 qDebug() << __PRETTY_FUNCTION__;
165 m_dragStartTimer->stop();
171 QSettings settings(DIRECTORY_NAME, FILE_NAME);
172 settings.setValue(DIRECTION_INDICATOR_BUTTON_POSITION, pos());
176 void IndicatorButtonPanel::paintEvent(QPaintEvent *event)
178 qDebug() << __PRETTY_FUNCTION__;
182 QPainter painter(this);
183 painter.setRenderHint(QPainter::Antialiasing);
185 if (!m_indicatorButton->isChecked()) {
186 const int EXTRA_SPACE_LEFT = -5;
187 const int EXTRA_SPACE_TOP = 0;
188 const int EXTRA_SPACE_RIGHT = +5;
189 const int EXTRA_SPACE_BOTTOM = 0;
191 const int RADIUS_WIDTH = 5;
192 const int RADIUS_HEIGHT = 5;
194 QPainterPath backgroundPath;
195 QRect distanceLabelRect = m_distanceTextLabel->rect();
197 distanceLabelRect.translate(m_distanceTextLabel->pos());
198 distanceLabelRect.adjust(EXTRA_SPACE_LEFT, EXTRA_SPACE_TOP, EXTRA_SPACE_RIGHT
199 , EXTRA_SPACE_BOTTOM);
200 backgroundPath.addRoundedRect(distanceLabelRect, RADIUS_WIDTH, RADIUS_HEIGHT);
201 painter.fillPath(backgroundPath, QBrush(*m_normalColor));
205 const int ROUNDING_RADIUS = 9;
207 QPainterPath backgroundPath;
208 backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
209 painter.fillPath(backgroundPath, QBrush(Qt::Dense4Pattern));
210 painter.setPen(Qt::black);
214 void IndicatorButtonPanel::screenResized(const QSize &newSize)
216 qDebug() << __PRETTY_FUNCTION__;
221 if (m_screenSize.height() < 0)
222 oldHeight = DEFAULT_NON_FULLSCREEN_HEIGHT;
224 oldHeight = m_screenSize.height();
226 if (m_screenSize.width() < 0)
227 oldWidth = DEFAULT_SCREEN_WIDTH;
229 oldWidth = m_screenSize.width();
231 m_screenSize = newSize;
233 QPoint resizedPosition = pos();
235 if (resizedPosition.x() < 0)
236 resizedPosition.rx() = 0;
237 else if (resizedPosition.x() > (newSize.width() - rect().width() - PANEL_BAR_WIDTH))
238 resizedPosition.rx() = newSize.width() - rect().width() - PANEL_BAR_WIDTH;
240 if (resizedPosition.y() < 0)
241 resizedPosition.ry() = 0;
242 else if (resizedPosition.y() > (newSize.height() - rect().height()))
243 resizedPosition.ry() = newSize.height() - rect().height();
245 if ((pos().y() + rect().center().y()) > (oldHeight / 2))
246 resizedPosition.ry() = newSize.height() - (oldHeight - pos().y());
248 if ((pos().x() + rect().center().x()) > (oldWidth / 2))
249 resizedPosition.rx() = newSize.width() - (oldWidth - pos().x());
251 move(resizedPosition);
254 void IndicatorButtonPanel::setDraggable(bool mode, QPoint eventPosition)
256 qDebug() << __PRETTY_FUNCTION__;
258 m_isDraggable = mode;
261 emit draggingModeTriggered();
263 m_forceReleaseTimer->start();
264 m_dragPosition = eventPosition;
267 m_forceReleaseTimer->stop();
268 m_indicatorButton->setDown(false);
273 void IndicatorButtonPanel::setIndicatorButtonEnabled(bool enabled)
275 qDebug() << __PRETTY_FUNCTION__;
277 m_indicatorButton->setChecked(enabled);
278 m_distanceTextLabel->setVisible(!enabled);
283 void IndicatorButtonPanel::timerExpired()
285 qDebug() << __PRETTY_FUNCTION__;
287 setDraggable(true, m_dragPosition);
290 void IndicatorButtonPanel::updateValues(qreal direction, qreal distance, bool draw)
292 qDebug() << __PRETTY_FUNCTION__;
294 const int MAX_TO_METERS = 999.5;
295 const int MAX_TO_KM_WITH_DESIMAL = 99950;
296 const int MIN_TO_METERS = 10;
297 const int M_TO_KM = 1000; ///< Meters to kilometers conversion
299 QString UNIT_KILOMETER = " km";
300 QString UNIT_METER = " m";
302 m_indicatorButton->setDirection(direction, draw);
304 m_distance = distance;
306 if (m_distance < MIN_TO_METERS) {
307 m_distanceText.setNum(10);
308 m_distanceText.prepend("< ");
309 m_distanceText.append(UNIT_METER);
310 } else if (m_distance < MAX_TO_METERS) {
311 m_distanceText.setNum(m_distance, 'f', 0);
312 m_distanceText.append(UNIT_METER);
313 } else if (m_distance < MAX_TO_KM_WITH_DESIMAL) {
314 m_distanceText.setNum(m_distance / M_TO_KM, 'f', 1);
315 m_distanceText.append(UNIT_KILOMETER);
317 m_distanceText.setNum(m_distance / M_TO_KM, 'f', 0);
318 m_distanceText.append(UNIT_KILOMETER);
321 m_distanceTextLabel->setText(m_distanceText);