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 void IndicatorButtonPanel::forceMouseRelease()
114 qDebug() << __PRETTY_FUNCTION__;
120 void IndicatorButtonPanel::mouseMoveEvent(QMouseEvent *event)
122 qDebug() << __PRETTY_FUNCTION__;
125 if (event->buttons() & Qt::LeftButton) {
126 QPoint newLocation = mapToParent(event->pos()) - m_dragPosition;
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;
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();
141 if (!rect().contains(event->pos()))
142 m_dragStartTimer->stop();
146 void IndicatorButtonPanel::mousePressEvent(QMouseEvent *event)
148 qDebug() << __PRETTY_FUNCTION__;
150 m_dragPosition = event->pos();
151 m_dragStartTimer->start();
154 void IndicatorButtonPanel::mouseReleaseEvent(QMouseEvent *event)
156 qDebug() << __PRETTY_FUNCTION__;
158 m_dragStartTimer->stop();
164 QSettings settings(DIRECTORY_NAME, FILE_NAME);
165 settings.setValue(DIRECTION_INDICATOR_BUTTON_POSITION, pos());
169 void IndicatorButtonPanel::paintEvent(QPaintEvent *event)
171 qDebug() << __PRETTY_FUNCTION__;
175 QPainter painter(this);
176 painter.setRenderHint(QPainter::Antialiasing);
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;
184 const int RADIUS_WIDTH = 5;
185 const int RADIUS_HEIGHT = 5;
187 QPainterPath backgroundPath;
188 QRect distanceLabelRect = m_distanceTextLabel->rect();
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));
198 const int ROUNDING_RADIUS = 9;
200 QPainterPath backgroundPath;
201 backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
202 painter.fillPath(backgroundPath, QBrush(Qt::Dense4Pattern));
203 painter.setPen(Qt::black);
207 void IndicatorButtonPanel::screenResized(const QSize &newSize)
209 qDebug() << __PRETTY_FUNCTION__;
214 if (m_screenSize.height() < 0)
215 oldHeight = DEFAULT_NON_FULLSCREEN_HEIGHT;
217 oldHeight = m_screenSize.height();
219 if (m_screenSize.width() < 0)
220 oldWidth = DEFAULT_SCREEN_WIDTH;
222 oldWidth = m_screenSize.width();
224 m_screenSize = newSize;
226 QPoint resizedPosition = pos();
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;
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();
238 if ((pos().y() + rect().center().y()) > (oldHeight / 2))
239 resizedPosition.ry() = newSize.height() - (oldHeight - pos().y());
241 if ((pos().x() + rect().center().x()) > (oldWidth / 2))
242 resizedPosition.rx() = newSize.width() - (oldWidth - pos().x());
244 move(resizedPosition);
247 void IndicatorButtonPanel::setDraggable(bool mode, QPoint eventPosition)
249 qDebug() << __PRETTY_FUNCTION__;
251 m_isDraggable = mode;
254 emit draggingModeTriggered();
256 m_forceReleaseTimer->start();
257 m_dragPosition = eventPosition;
260 m_forceReleaseTimer->stop();
261 m_indicatorButton->setDown(false);
266 void IndicatorButtonPanel::setIndicatorButtonEnabled(bool enabled)
268 qDebug() << __PRETTY_FUNCTION__;
270 m_indicatorButton->setChecked(enabled);
271 m_distanceTextLabel->setVisible(!enabled);
276 void IndicatorButtonPanel::timerExpired()
278 qDebug() << __PRETTY_FUNCTION__;
280 setDraggable(true, m_dragPosition);
283 void IndicatorButtonPanel::updateValues(qreal direction, qreal distance, bool draw)
285 qDebug() << __PRETTY_FUNCTION__;
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
292 QString UNIT_KILOMETER = " km";
293 QString UNIT_METER = " m";
295 m_indicatorButton->setDirection(direction, draw);
297 m_distance = distance;
299 if (m_distance < MIN_TO_METERS)
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);
311 m_distanceText.setNum(m_distance / M_TO_KM, 'f', 0);
312 m_distanceText.append(UNIT_KILOMETER);
315 m_distanceTextLabel->setText(m_distanceText);