Merge branch 'master' into new_panels
[situare] / src / ui / indicatorbutton.cpp
index 2082dd4..efd28e8 100644 (file)
@@ -4,6 +4,7 @@
 
         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));
@@ -71,26 +61,9 @@ IndicatorButton::IndicatorButton(QWidget *parent)
     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);
 }
 
@@ -102,173 +75,113 @@ IndicatorButton::~IndicatorButton()
     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);
-}