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