diff --git a/src/legend/legend.pri b/src/legend/legend.pri index 83910c3..3649007 100644 --- a/src/legend/legend.pri +++ b/src/legend/legend.pri @@ -10,7 +10,7 @@ SOURCES += \ $$PWD/qbarlegendmarker.cpp \ $$PWD/qxylegendmarker.cpp \ $$PWD/qarealegendmarker.cpp \ - $$PWD/mouseeventhandler.cpp + $$PWD/legendscroller.cpp PRIVATE_HEADERS += \ $$PWD/legendscroller_p.h \ @@ -21,8 +21,7 @@ PRIVATE_HEADERS += \ $$PWD/qpielegendmarker_p.h \ $$PWD/qbarlegendmarker_p.h \ $$PWD/qxylegendmarker_p.h \ - $$PWD/qarealegendmarker_p.h \ - $$PWD/mouseeventhandler_p.h + $$PWD/qarealegendmarker_p.h PUBLIC_HEADERS += \ diff --git a/src/legend/legendmarkeritem.cpp b/src/legend/legendmarkeritem.cpp index 39247db..efc3dc5 100644 --- a/src/legend/legendmarkeritem.cpp +++ b/src/legend/legendmarkeritem.cpp @@ -160,37 +160,6 @@ QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) return sh; } -void LegendMarkerItem::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - MouseEventHandler::handleMousePressEvent(event); - m_pressPos = event->screenPos(); -} - -void LegendMarkerItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - MouseEventHandler::handleMouseMoveEvent(event); -} - -void LegendMarkerItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - MouseEventHandler::handleMouseReleaseEvent(event); -} - -void LegendMarkerItem::mouseClicked() -{ - emit m_marker->q_func()->clicked(); -} - -void LegendMarkerItem::mouseMoved(const QPointF &delta) -{ - m_marker->m_legend->d_ptr->move(delta); -} - -void LegendMarkerItem::mouseReleased(const QPointF &pos) -{ - m_marker->m_legend->d_ptr->release(pos - m_pressPos); -} - #include "moc_legendmarkeritem_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/legend/legendmarkeritem_p.h b/src/legend/legendmarkeritem_p.h index 351d872..9bd1f5a 100644 --- a/src/legend/legendmarkeritem_p.h +++ b/src/legend/legendmarkeritem_p.h @@ -37,13 +37,12 @@ #include #include #include -#include "mouseeventhandler_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE class QLegendMarkerPrivate; -class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem, public MouseEventHandler +class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem { Q_OBJECT Q_INTERFACES(QGraphicsLayoutItem) @@ -66,23 +65,11 @@ public: QBrush labelBrush() const; void setGeometry(const QRectF &rect); - QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); - QSizeF sizeHint (Qt::SizeHint which, const QSizeF &constraint) const; - // Event handlers, logic delegated to MouseEventHandler - void mousePressEvent(QGraphicsSceneMouseEvent *event); - void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - - // Filtered callbacks from MouseEventHandler - void mouseClicked(); - void mouseMoved(const QPointF &delta); - void mouseReleased(const QPointF &pos); - protected: QLegendMarkerPrivate *m_marker; // Knows QRectF m_markerRect; diff --git a/src/legend/mouseeventhandler.cpp b/src/legend/legendscroller.cpp similarity index 79% rename from src/legend/mouseeventhandler.cpp rename to src/legend/legendscroller.cpp index f93e37f..579fe6a 100644 --- a/src/legend/mouseeventhandler.cpp +++ b/src/legend/legendscroller.cpp @@ -18,35 +18,47 @@ ** ****************************************************************************/ -#include "mouseeventhandler_p.h" +#include #include +#include +#include +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include "legendscroller_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE -MouseEventHandler::MouseEventHandler() : +LegendScroller::LegendScroller(QChart *chart) : QLegend(chart), m_lastPos(0, 0), m_state(Idle), m_treshold(10) { } -MouseEventHandler::~MouseEventHandler() +void LegendScroller::setOffset(const QPointF &point) { + d_ptr->setOffset(point); } -void MouseEventHandler::setMoveTreshold(qreal treshold) +QPointF LegendScroller::offset() const +{ + return d_ptr->offset(); +} + +void LegendScroller::setMoveTreshold(qreal treshold) { m_treshold = treshold; } -void MouseEventHandler::handleMousePressEvent(QGraphicsSceneMouseEvent *event) +void LegendScroller::mousePressEvent(QGraphicsSceneMouseEvent *event) { - m_lastPos = event->screenPos(); + m_pressPos = event->screenPos(); + m_lastPos = m_pressPos; m_state = Pressed; event->accept(); } -void MouseEventHandler::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) +void LegendScroller::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QPointF delta = event->screenPos() - m_lastPos; @@ -56,14 +68,14 @@ void MouseEventHandler::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (qAbs(delta.x()) > m_treshold || qAbs(delta.y()) > m_treshold) { m_state = Moved; m_lastPos = event->screenPos(); - mouseMoved(delta); + move(delta); } event->accept(); break; } case Moved: { m_lastPos = event->screenPos(); - mouseMoved(delta); + move(delta); event->accept(); break; } @@ -75,7 +87,7 @@ void MouseEventHandler::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) } } -void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) +void LegendScroller::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { m_lastPos = event->screenPos(); @@ -83,14 +95,21 @@ void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) case Pressed: { m_state = Idle; - mouseClicked(); + QList items = scene()->items(event->scenePos()); + + foreach (QGraphicsItem *i, items) { + if (d_ptr->m_markerHash.contains(i)) { + QLegendMarker *marker = d_ptr->m_markerHash.value(i); + emit marker->clicked(); + } + } + event->accept(); break; } case Moved: { - m_state = Idle; - mouseReleased(m_lastPos); + scrollTo(m_lastPos - m_pressPos); event->accept(); break; } @@ -103,4 +122,6 @@ void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) } } + +#include "moc_legendscroller_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/legend/legendscroller_p.h b/src/legend/legendscroller_p.h index 0306899..c8cecad 100644 --- a/src/legend/legendscroller_p.h +++ b/src/legend/legendscroller_p.h @@ -33,18 +33,39 @@ #include "qlegend.h" #include "qlegend_p.h" +#include "scroller_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE -class LegendScroller: public QLegend +class LegendScroller: public QLegend, public Scroller { + Q_OBJECT public: - LegendScroller(QChart *chart): QLegend(chart) { } + LegendScroller(QChart *chart); - void setOffset(const QPointF &point) { d_ptr->setOffset(point); } + void setOffset(const QPointF &point); + QPointF offset() const; - QPointF offset() const { return d_ptr->offset(); } + void setMoveTreshold(qreal treshold); + + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +private: + + enum State { + Idle, + Pressed, + Moved, + Released + }; + + QPointF m_pressPos; + QPointF m_lastPos; + State m_state; + qreal m_treshold; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/legend/mouseeventhandler_p.h b/src/legend/mouseeventhandler_p.h deleted file mode 100644 index 3c35dab..0000000 --- a/src/legend/mouseeventhandler_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://qt.digia.com -** -** This file is part of the Qt Commercial Charts Add-on. -** -** $QT_BEGIN_LICENSE$ -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. -** -** If you have questions regarding the use of this file, please use -** contact form at http://qt.digia.com -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// W A R N I N G -// ------------- -// -// This file is not part of the QtCommercial Chart API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. - -/* - Purpose of this class is to resolve what happens during MousePress - MouseMove - MouseRelease event chain. - Threre can be many MouseMove events and if they all are below our treshold, the result is clicked call. - If any move event goes over treshold, result will be many moved(QPointF delta) calls, - where delta is calculated from original position. - - Reason for this is, that legend marker don't know when it should emit clicked and when it should - allow legend to scroll. We only get this information when some move goes beyond treshold, but - then it will be too late to let the scroller handle events, because marker is already handling. - - By handling clicked calls in markers and moved calls in scroller, the problem is solved. - Derived class descides, should the virtual method be implemented as signal or not. - - This could be implemented in LegendMarkerItem, but this way the code is reusable and in one place only. -*/ - -#ifndef MOUSEEVENTHANDLER_H -#define MOUSEEVENTHANDLER_H - -#include "qchartglobal.h" -#include -#include -#include - -class QGraphicsSceneMouseEvent; - -QTCOMMERCIALCHART_BEGIN_NAMESPACE - -class MouseEventHandler -{ -public: - enum State { - Idle, - Pressed, - Moved, - Released - }; - - MouseEventHandler(); - virtual ~MouseEventHandler(); - - void setMoveTreshold(qreal treshold); - - virtual void mouseClicked() = 0; - virtual void mouseMoved(const QPointF &delta) = 0; - virtual void mouseReleased(const QPointF &pos) = 0; - - void handleMousePressEvent(QGraphicsSceneMouseEvent *event); - void handleMouseMoveEvent(QGraphicsSceneMouseEvent *event); - void handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event); - -private: - QPointF m_lastPos; - State m_state; - qreal m_treshold; -}; - -QTCOMMERCIALCHART_END_NAMESPACE - -#endif // MOUSEEVENTHANDLER_H diff --git a/src/legend/qlegend.cpp b/src/legend/qlegend.cpp index 61e917c..94263e8 100644 --- a/src/legend/qlegend.cpp +++ b/src/legend/qlegend.cpp @@ -584,6 +584,7 @@ void QLegendPrivate::addMarkers(QList markers) foreach (QLegendMarker *marker, markers) { m_items->addToGroup(marker->d_ptr.data()->item()); m_markers << marker; + m_markerHash.insert(marker->d_ptr->item(), marker); } } @@ -592,8 +593,9 @@ void QLegendPrivate::removeMarkers(QList markers) foreach (QLegendMarker *marker, markers) { marker->d_ptr->item()->setVisible(false); m_items->removeFromGroup(marker->d_ptr->item()); - delete marker; m_markers.removeOne(marker); + m_markerHash.remove(marker->d_ptr->item()); + delete marker; } } diff --git a/src/legend/qlegend_p.h b/src/legend/qlegend_p.h index f3c16f0..d696233 100644 --- a/src/legend/qlegend_p.h +++ b/src/legend/qlegend_p.h @@ -31,7 +31,6 @@ #define QLEGEND_P_H #include "qlegend.h" -#include "scroller_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -42,7 +41,7 @@ class LegendLayout; class Domain; class QLegendMarker; -class QLegendPrivate : public QObject, public Scroller +class QLegendPrivate : public QObject { Q_OBJECT public: @@ -90,10 +89,13 @@ private: QList m_markers; QList m_series; + QHash m_markerHash; + friend class QLegend; friend class LegendMarkerItem; friend class LegendLayout; friend class QLegendMarkerPrivate; + friend class LegendScroller; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/scroller.cpp b/src/scroller.cpp index b392247..d0e17f3 100644 --- a/src/scroller.cpp +++ b/src/scroller.cpp @@ -56,7 +56,7 @@ void Scroller::move(const QPointF &delta) setOffset(offset() - delta); } -void Scroller::release(const QPointF &delta) +void Scroller::scrollTo(const QPointF &delta) { // Starts scrolling, if at least m_timeTresholdMin msecs has gone since timestamp // current time is no more than m_timeTresholdMax from timestamp diff --git a/src/scroller_p.h b/src/scroller_p.h index 36376bb..7812725 100644 --- a/src/scroller_p.h +++ b/src/scroller_p.h @@ -73,7 +73,7 @@ public: virtual QPointF offset() const = 0; void move(const QPointF &delta); - void release(const QPointF &delta); + void scrollTo(const QPointF &delta); void scrollTick(); @@ -81,7 +81,6 @@ private: void startTicker(int interval); void stopTicker(); - private: void calculateSpeed(const QPointF &position); void lowerSpeed(QPointF &speed, qreal maxSpeed = 100);