##// END OF EJS Templates
Callout example: added extra space around the text
Marek Rosa -
r2378:c144d02c5537
parent child
Show More
@@ -1,102 +1,104
1 1 #include "callout.h"
2 2 #include <QPainter>
3 3 #include <QFontMetrics>
4 4 #include <QGraphicsSceneMouseEvent>
5 5 #include <QMouseEvent>
6 6
7 7 Callout::Callout(QGraphicsItem * parent):
8 8 QGraphicsItem(parent)
9 9 {
10 10 }
11 11
12 12 QRectF Callout::boundingRect() const
13 13 {
14 14 QPointF anchor = mapFromParent(m_anchor);
15 15 QRectF rect;
16 rect.setLeft(qMin(m_textRect.left(), anchor.x()));
17 rect.setRight(qMax(m_textRect.right() + 8, anchor.x()));
18 rect.setTop(qMin(m_textRect.top(), anchor.y()));
19 rect.setBottom(qMax(m_textRect.bottom() + 8, anchor.y()));
16 rect.setLeft(qMin(m_rect.left(), anchor.x()));
17 rect.setRight(qMax(m_rect.right(), anchor.x()));
18 rect.setTop(qMin(m_rect.top(), anchor.y()));
19 rect.setBottom(qMax(m_rect.bottom(), anchor.y()));
20 20 return rect;
21 21 }
22 22
23 23 void Callout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
24 24 {
25 25 Q_UNUSED(option)
26 26 Q_UNUSED(widget)
27 27 QPainterPath path;
28 path.addRoundedRect(m_textRect, 5, 5);
28 path.addRoundedRect(m_rect, 5, 5);
29 29
30 30 QPointF anchor = mapFromParent(m_anchor);
31 if (!m_textRect.contains(anchor)) {
31 if (!m_rect.contains(anchor)) {
32 32 QPointF point1, point2;
33 33
34 34 // establish the position of the anchor point in relation to m_textRect
35 bool above = anchor.y() <= m_textRect.top();
36 bool aboveCenter = anchor.y() > m_textRect.top() && anchor.y() <= m_textRect.center().y();
37 bool belowCenter = anchor.y() > m_textRect.center().y() && anchor.y() <= m_textRect.bottom();
38 bool below = anchor.y() > m_textRect.bottom();
35 bool above = anchor.y() <= m_rect.top();
36 bool aboveCenter = anchor.y() > m_rect.top() && anchor.y() <= m_rect.center().y();
37 bool belowCenter = anchor.y() > m_rect.center().y() && anchor.y() <= m_rect.bottom();
38 bool below = anchor.y() > m_rect.bottom();
39 39
40 bool onLeft = anchor.x() <= m_textRect.left();
41 bool leftOfCenter = anchor.x() > m_textRect.left() && anchor.x() <= m_textRect.center().x();
42 bool rightOfCenter = anchor.x() > m_textRect.center().x() && anchor.x() <= m_textRect.right();
43 bool onRight = anchor.x() > m_textRect.right();
40 bool onLeft = anchor.x() <= m_rect.left();
41 bool leftOfCenter = anchor.x() > m_rect.left() && anchor.x() <= m_rect.center().x();
42 bool rightOfCenter = anchor.x() > m_rect.center().x() && anchor.x() <= m_rect.right();
43 bool onRight = anchor.x() > m_rect.right();
44 44
45 45 // get the nearest m_textRect corner.
46 qreal x = (onRight + rightOfCenter) * m_textRect.width();
47 qreal y = (below + belowCenter) * m_textRect.height();
46 qreal x = (onRight + rightOfCenter) * m_rect.width();
47 qreal y = (below + belowCenter) * m_rect.height();
48 48 bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight);
49 49 bool vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y);
50 50
51 51 qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20);
52 52 qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);;
53 53 point1.setX(x1);
54 54 point1.setY(y1);
55 55
56 56 qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);;
57 57 qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);;
58 58 point2.setX(x2);
59 59 point2.setY(y2);
60 60
61 61 path.moveTo(point1);
62 62 path.lineTo(mapFromParent(m_anchor));
63 63 path.lineTo(point2);
64 64 path = path.simplified();
65 65 }
66 66 painter->setBrush(QColor(255, 255, 255));
67 67 painter->drawPath(path);
68 painter->drawText(m_textRect.adjusted(4, 4, 0, 0), m_text);
68 painter->drawText(m_textRect, m_text);
69 69 }
70 70
71 71 void Callout::mousePressEvent(QGraphicsSceneMouseEvent *event)
72 72 {
73 if (m_textRect.contains(event->pos())) {
73 if (m_rect.contains(event->pos())) {
74 74 m_clickOffset = event->pos();
75 75 event->setAccepted(true);
76 76 } else {
77 77 event->setAccepted(false);
78 78 }
79 79 }
80 80
81 81 void Callout::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
82 82 {
83 if (m_textRect.contains(event->pos())){
83 if (event->buttons() & Qt::LeftButton){
84 84 setPos(mapToParent(event->pos() - m_clickOffset));
85 85 event->setAccepted(true);
86 86 } else {
87 87 event->setAccepted(false);
88 88 }
89 89 }
90 90
91 91 void Callout::setText(const QString &text)
92 92 {
93 93 m_text = text;
94 94 QFontMetrics metrics(m_font);
95 prepareGeometryChange();
96 m_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt::AlignLeft, m_text).adjusted(0, 0, 4, 4);
95 m_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt::AlignLeft, m_text);
96 m_textRect.translate(5, 5);
97 prepareGeometryChange();
98 m_rect = m_textRect.adjusted(-5, -5, 5, 5);
97 99 }
98 100
99 101 void Callout::setAnchor(QPointF point)
100 102 {
101 103 m_anchor = point;
102 104 }
@@ -1,32 +1,33
1 1 #ifndef CALLOUT_H
2 2 #define CALLOUT_H
3 3
4 4 #include <QGraphicsItem>
5 5 #include <QFont>
6 6
7 7 class QGraphicsSceneMouseEvent;
8 8
9 9 class Callout : public QGraphicsItem
10 10 {
11 11 public:
12 12 Callout(QGraphicsItem * parent = 0);
13 13
14 14 void setText(const QString &text);
15 15 void setAnchor(QPointF point);
16 16
17 17 QRectF boundingRect() const;
18 18 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
19 19
20 20 protected:
21 21 void mousePressEvent(QGraphicsSceneMouseEvent *event);
22 22 void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
23 23
24 24 private:
25 25 QString m_text;
26 26 QRectF m_textRect;
27 QRectF m_rect;
27 28 QPointF m_anchor;
28 29 QFont m_font;
29 30 QPointF m_clickOffset;
30 31 };
31 32
32 33 #endif // CALLOUT_H
@@ -1,125 +1,123
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "view.h"
22 22 #include <QResizeEvent>
23 23 #include <QGraphicsScene>
24 24 #include <QChart>
25 25 #include <QLineSeries>
26 26 #include <QSplineSeries>
27 27 #include <QGraphicsTextItem>
28 28 #include "callout.h"
29 29 #include <QMouseEvent>
30 30
31 31 View::View(QWidget *parent)
32 32 : QGraphicsView(new QGraphicsScene, parent),
33 33 m_coordX(0),
34 34 m_coordY(0),
35 35 m_chart(0),
36 36 m_tooltip(0)
37 37 {
38 38 setDragMode(QGraphicsView::NoDrag);
39 39 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
40 40 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
41 41
42 42 // chart
43 43 m_chart = new QChart;
44 44 m_chart->setMinimumSize(640, 480);
45 45 m_chart->setTitle("Hover the line to show callout. Click the line to make it stay");
46 46 m_chart->legend()->hide();
47 47 QLineSeries *series = new QLineSeries;
48 48 series->append(1, 3);
49 49 series->append(4, 5);
50 50 series->append(5, 4.5);
51 51 series->append(7, 1);
52 52 series->append(11, 2);
53 53 m_chart->addSeries(series);
54 54
55 55 QSplineSeries *series2 = new QSplineSeries;
56 56 series2->append(1.6, 1.4);
57 57 series2->append(2.4, 3.5);
58 58 series2->append(3.7, 2.5);
59 59 series2->append(7, 4);
60 60 series2->append(10, 2);
61 61 m_chart->addSeries(series2);
62 62
63 63 m_chart->createDefaultAxes();
64 64 m_chart->setAcceptHoverEvents(true);
65 65
66 66 setRenderHint(QPainter::Antialiasing);
67 67 scene()->addItem(m_chart);
68 68
69 69 m_coordX = new QGraphicsSimpleTextItem(m_chart);
70 70 m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height());
71 71 m_coordX->setText("X: ");
72 72 m_coordY = new QGraphicsSimpleTextItem(m_chart);
73 73 m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height());
74 74 m_coordY->setText("Y: ");
75 75
76 76 connect(series, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
77 77 connect(series, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
78 78
79 79 connect(series2, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
80 80 connect(series2, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
81 81
82 82 this->setMouseTracking(true);
83 83 }
84 84
85 85 void View::resizeEvent(QResizeEvent *event)
86 86 {
87 87 if (scene()) {
88 88 scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
89 89 m_chart->resize(event->size());
90 90 m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height() - 20);
91 91 m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height() - 20);
92 // for (int i = 0; i < children().count(); i++)
93 // if ()
94 92 }
95 93 QGraphicsView::resizeEvent(event);
96 94 }
97 95
98 96 void View::mouseMoveEvent(QMouseEvent *event)
99 97 {
100 98 m_coordX->setText(QString("X: %1").arg(m_chart->mapToValue(event->pos()).x()));
101 99 m_coordY->setText(QString("Y: %1").arg(m_chart->mapToValue(event->pos()).y()));
102 100 QGraphicsView::mouseMoveEvent(event);
103 101 }
104 102
105 103 void View::keepCallout()
106 104 {
107 105 m_tooltip = new Callout(m_chart);
108 106 }
109 107
110 108 void View::tooltip(QPointF point, bool state)
111 109 {
112 110 if (m_tooltip == 0)
113 111 m_tooltip = new Callout(m_chart);
114 112
115 113 if (state) {
116 114 m_tooltip->setText(QString("X: %1 \nY: %2 ").arg(point.x()).arg(point.y()));
117 115 QXYSeries *series = qobject_cast<QXYSeries *>(sender());
118 116 m_tooltip->setAnchor(m_chart->mapToPosition(point, series));
119 117 m_tooltip->setPos(m_chart->mapToPosition(point, series) + QPoint(10, -50));
120 118 m_tooltip->setZValue(11);
121 119 m_tooltip->show();
122 120 } else {
123 121 m_tooltip->hide();
124 122 }
125 123 }
General Comments 0
You need to be logged in to leave comments. Login now