Kaj Wallin - kaj.wallin@ixonos.com
Katri Kaikkonen - katri.kaikkonen@ixonos.com
+ Sami Rämö - sami.ramo@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#include <QPainter>
#include <QSettings>
-#include "math.h"
-
-#include "indicatorbutton.h"
-
#include "common.h"
+#include "math.h"
#include "panelcommon.h"
-enum State {OFF, ON}; ///< Enumerator for led state
-
-const int ROUNDING_RADIUS = 9; ///< Roundness of the rounded edge
-const int BUTTON_WIDTH = 66; ///< Button width
-const int BUTTON_HEIGHT = 66; ///< Button height
+#include "indicatorbutton.h"
-const qreal OPACITY = 0.50; ///< Opacity of the background in percents
+enum State {OFF, ON}; ///< Enumerator for led state
IndicatorButton::IndicatorButton(QWidget *parent)
: QToolButton(parent),
- m_isDraggable(false)
+ m_drawTriangle(false),
+ m_direction(0)
{
- m_indicatorLeds[OFF].load(":res/images/gps_position.png");
- m_indicatorLeds[ON].load(":res/images/gps_position_s.png");
- setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ qDebug() << __PRETTY_FUNCTION__;
- QSettings settings(DIRECTORY_NAME, FILE_NAME);
- QPoint savedLocation = settings.value(DIRECTION_INDICATOR_BUTTON_POSITION,
- QPoint(DIRECTION_INDICATOR_POSITION_X,
- DIRECTION_INDICATOR_POSITION_Y)).toPoint();
+ const qreal OPACITY = 0.50;
+ const int BUTTON_WIDTH = 66;
+ const int BUTTON_HEIGHT = 66;
- if(savedLocation.x() > DEFAULT_SCREEN_WIDTH || savedLocation.y() > DEFAULT_SCREEN_HEIGHT) {
- savedLocation.rx() = DIRECTION_INDICATOR_POSITION_X;
- savedLocation.ry() = DIRECTION_INDICATOR_POSITION_Y;
- }
+ m_indicatorLeds[OFF].load(":res/images/gps_position.png");
+ m_indicatorLeds[ON].load(":res/images/gps_position_s.png");
- move(savedLocation);
+ setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
// Normal background
m_normalColor = new QColor(Qt::black);
m_normalColor->setAlpha(floor(OPACITY * 255));
- // Selected bakcground
+ // Selected background
m_selectedGradient = new QLinearGradient(0, 0, 0, this->height());
m_selectedGradient->setColorAt(0.02, QColor(0, 113, 181));
m_selectedGradient->setColorAt(0.25, QColor(24, 142, 214));
m_selectedGradient->setColorAt(0.75, QColor(82, 195, 255));
m_selectedGradient->setColorAt(0.98, QColor(115, 215, 255));
- m_dragStartTimer = new QTimer(this);
- m_dragStartTimer->setSingleShot(true);
- m_dragStartTimer->setInterval(DRAG_INIT_TIME);
-
- m_forceReleaseTimer = new QTimer(this);
- m_forceReleaseTimer->setSingleShot(true);
- m_forceReleaseTimer->setInterval(FORCE_RELEASE_TIME);
-
- connect(this, SIGNAL(pressed()),
- m_dragStartTimer, SLOT(start()));
- connect(this, SIGNAL(released()),
- m_dragStartTimer, SLOT(stop()));
connect(this, SIGNAL(clicked(bool)),
this, SIGNAL(autoCenteringTriggered(bool)));
- connect(m_dragStartTimer, SIGNAL(timeout()),
- this, SLOT(timerExpired()));
- connect(m_forceReleaseTimer, SIGNAL(timeout()),
- this, SLOT(forceMouseRelease()));
-
setCheckable(true);
}
delete m_selectedGradient;
}
-void IndicatorButton::mousePressEvent(QMouseEvent *event)
+const QPoint& IndicatorButton::eventPosition()
{
qDebug() << __PRETTY_FUNCTION__;
- if (event->button() == Qt::LeftButton)
- m_dragPosition = event->pos();
-
- m_eventPosition = mapToParent(event->pos());
- m_dragStartTimer->start();
- setDown(true);
+ return m_eventPosition;
}
void IndicatorButton::mouseMoveEvent(QMouseEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
- if(m_isDraggable) {
- if (event->buttons() & Qt::LeftButton) {
- QPoint newLocation = mapToParent(event->pos()) - m_dragPosition;
-
- if (newLocation.x() < 0)
- newLocation.rx() = 0;
- else if (newLocation.x() > m_screenSize.width() - width() - PANEL_BAR_WIDTH)
- newLocation.rx() = m_screenSize.width() - width() - PANEL_BAR_WIDTH;
-
- if (newLocation.y() < 0)
- newLocation.ry() = 0;
- else if (newLocation.y() > m_screenSize.height() - height())
- newLocation.ry() = m_screenSize.height() - height();
+ QToolButton::mouseMoveEvent(event);
- move(newLocation);
- }
- } else {
- if(!rect().contains(event->pos())) {
- m_dragStartTimer->stop();
- setDown(false);
- }
- }
+ event->ignore();
}
-void IndicatorButton::mouseReleaseEvent(QMouseEvent *event)
+void IndicatorButton::mousePressEvent(QMouseEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
- m_dragStartTimer->stop();
+ QToolButton::mousePressEvent(event);
- if(m_isDraggable) {
- setDraggable(false);
- QSettings settings(DIRECTORY_NAME, FILE_NAME);
- settings.setValue(DIRECTION_INDICATOR_BUTTON_POSITION, pos());
- } else {
- if(this->rect().contains(event->pos())) {
- if(isChecked()) {
- setChecked(false);
- emit autoCenteringTriggered(false);
- } else {
- setChecked(true);
- emit autoCenteringTriggered(true);
- }
- }
- }
- setDown(false);
+ event->ignore();
}
-void IndicatorButton::setDraggable(bool mode, QPoint eventPosition)
+void IndicatorButton::mouseReleaseEvent(QMouseEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
- m_isDraggable = mode;
+ QToolButton::mouseReleaseEvent(event);
- if(mode) {
- emit draggingModeTriggered();
- m_forceReleaseTimer->start();
- m_dragPosition = eventPosition;
- } else {
- m_forceReleaseTimer->stop();
- }
- update();
+ event->ignore();
}
-void IndicatorButton::screenResized(const QSize &newSize)
+void IndicatorButton::paintEvent(QPaintEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
- int oldHeight = 0;
- int oldWidth = 0;
+ const int ROUNDING_RADIUS = 9;
- if(m_screenSize.height() < 0)
- oldHeight = DEFAULT_NON_FULLSCREEN_HEIGHT;
- else
- oldHeight = m_screenSize.height();
+ Q_UNUSED(event);
- if(m_screenSize.width() < 0)
- oldWidth = DEFAULT_SCREEN_WIDTH;
+ QPainterPath backgroundPath;
+ backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ if (isDown())
+ painter.fillPath(backgroundPath, QBrush(*m_selectedGradient));
else
- oldWidth = m_screenSize.width();
+ painter.fillPath(backgroundPath, QBrush(*m_normalColor));
- m_screenSize = newSize;
+ const QPointF CENTER = QPointF(this->width(), this->height()) / 2;
- QPoint resizedPosition = pos();
+ if (isChecked()) {
+ const QPointF offset = QPointF(m_indicatorLeds[ON].width(),
+ m_indicatorLeds[ON].height()) / 2;
- if (resizedPosition.x() < 0)
- resizedPosition.rx() = 0;
- else if(resizedPosition.x() > (newSize.width() - rect().width()))
- resizedPosition.rx() = newSize.width() - rect().width();
+ painter.drawPixmap(CENTER - offset, m_indicatorLeds[ON]);
+ } else {
+ const QPointF offset = QPointF(m_indicatorLeds[OFF].width(),
+ m_indicatorLeds[OFF].height()) / 2;
- if (resizedPosition.y() < 0)
- resizedPosition.ry() = 0;
- else if(resizedPosition.y() > (newSize.height() - rect().height()))
- resizedPosition.ry() = newSize.height() - rect().height();
+ painter.drawPixmap(CENTER - offset, m_indicatorLeds[OFF]);
+ }
- if((pos().y() + rect().center().y()) > (oldHeight/2))
- resizedPosition.ry() = newSize.height() - (oldHeight - pos().y());
+ // draw the direction indicator triangle only when autocentering is disabled and MapEngine
+ // doesn't deny drawing (because GPS location item is visible)
+ if (!isChecked() && m_drawTriangle) {
+ const int TRIANGLE_WIDTH = 10;
+ const int TRIANGLE_HEIGHT = 10;
+ const int TRIANGLE_DISTANCE_FROM_CENTER = 15;
- if((pos().x() + rect().center().x()) > (oldWidth/2))
- resizedPosition.rx() = newSize.width() - (oldWidth - pos().x());
+ const int POINTS = 3;
+ const QPointF points[POINTS] = {
+ QPointF(-TRIANGLE_WIDTH / 2, -TRIANGLE_DISTANCE_FROM_CENTER),
+ QPointF(0, -(TRIANGLE_DISTANCE_FROM_CENTER + TRIANGLE_HEIGHT)),
+ QPointF(TRIANGLE_WIDTH / 2, -TRIANGLE_DISTANCE_FROM_CENTER)
+ };
- move(resizedPosition);
-}
+ // base triangle is facing up, and needs to be rotated to the required direction
+ QTransform rotationTransform;
+ rotationTransform.rotate(m_direction);
-const QPoint& IndicatorButton::eventPosition()
-{
- qDebug() << __PRETTY_FUNCTION__;
+ // origin is in the top left corner of the button, and needs to be translated to the
+ // center of the button
+ QTransform translateTransform;
+ translateTransform.translate(CENTER.x(), CENTER.y());
- return m_eventPosition;
-}
+ painter.setTransform(rotationTransform * translateTransform);
-void IndicatorButton::forceMouseRelease()
-{
- qDebug() << __PRETTY_FUNCTION__;
+ // setting the look of the triangle
+ painter.setBrush(Qt::red);
+ painter.setPen(Qt::red);
- releaseMouse();
- setDraggable(false);
+ painter.drawPolygon(points, POINTS);
+ }
}
-void IndicatorButton::paintEvent(QPaintEvent *event)
+void IndicatorButton::setDirection(qreal direction, bool draw)
{
qDebug() << __PRETTY_FUNCTION__;
- Q_UNUSED(event);
-
- QPainterPath backgroundPath;
- backgroundPath.addRoundedRect(this->rect(), ROUNDING_RADIUS, ROUNDING_RADIUS);
-
- QPainter painter(this);
- painter.setRenderHint(QPainter::Antialiasing);
-
- if(m_isDraggable)
- painter.fillPath(backgroundPath, QBrush(Qt::Dense4Pattern));
- else if (isDown())
- painter.fillPath(backgroundPath, QBrush(*m_selectedGradient));
- else
- painter.fillPath(backgroundPath, QBrush(*m_normalColor));
+ m_direction = direction;
+ m_drawTriangle = draw;
- if(isChecked())
- painter.drawPixmap((this->width() / 2) - (m_indicatorLeds[ON].width() / 2),
- (this->height() / 2) - (m_indicatorLeds[ON].height() / 2),
- m_indicatorLeds[ON]);
- else
- painter.drawPixmap((this->width() / 2) - (m_indicatorLeds[OFF].width() / 2),
- (this->height() / 2) - (m_indicatorLeds[OFF].height() / 2),
- m_indicatorLeds[OFF]);
+ update();
}
-void IndicatorButton::timerExpired()
-{
- qDebug() << __PRETTY_FUNCTION__;
-
- setDraggable(true, m_dragPosition);
-}