@@ -0,0 +1,10 | |||
|
1 | !include( ../examples.pri ) { | |
|
2 | error( "Couldn't find the examples.pri file!" ) | |
|
3 | } | |
|
4 | ||
|
5 | TARGET = legendmarkers | |
|
6 | SOURCES += main.cpp \ | |
|
7 | mainwidget.cpp | |
|
8 | ||
|
9 | HEADERS += \ | |
|
10 | mainwidget.h |
@@ -0,0 +1,35 | |||
|
1 | /**************************************************************************** | |
|
2 | ** | |
|
3 | ** Copyright (C) 2012 Digia Plc | |
|
4 | ** All rights reserved. | |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
|
6 | ** | |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
|
8 | ** | |
|
9 | ** $QT_BEGIN_LICENSE$ | |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
|
13 | ** a written agreement between you and Digia. | |
|
14 | ** | |
|
15 | ** If you have questions regarding the use of this file, please use | |
|
16 | ** contact form at http://qt.digia.com | |
|
17 | ** $QT_END_LICENSE$ | |
|
18 | ** | |
|
19 | ****************************************************************************/ | |
|
20 | ||
|
21 | #include "mainwidget.h" | |
|
22 | ||
|
23 | #include <QApplication> | |
|
24 | #include <QMainWindow> | |
|
25 | ||
|
26 | int main(int argc, char *argv[]) | |
|
27 | { | |
|
28 | QApplication a(argc, argv); | |
|
29 | ||
|
30 | MainWidget w; | |
|
31 | w.resize(720, 480); | |
|
32 | w.show(); | |
|
33 | ||
|
34 | return a.exec(); | |
|
35 | } |
@@ -0,0 +1,181 | |||
|
1 | /**************************************************************************** | |
|
2 | ** | |
|
3 | ** Copyright (C) 2012 Digia Plc | |
|
4 | ** All rights reserved. | |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
|
6 | ** | |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
|
8 | ** | |
|
9 | ** $QT_BEGIN_LICENSE$ | |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
|
13 | ** a written agreement between you and Digia. | |
|
14 | ** | |
|
15 | ** If you have questions regarding the use of this file, please use | |
|
16 | ** contact form at http://qt.digia.com | |
|
17 | ** $QT_END_LICENSE$ | |
|
18 | ** | |
|
19 | ****************************************************************************/ | |
|
20 | ||
|
21 | #include "mainwidget.h" | |
|
22 | #include <QChart> | |
|
23 | #include <QChartView> | |
|
24 | #include <QPushButton> | |
|
25 | #include <QLabel> | |
|
26 | #include <QDebug> | |
|
27 | #include <QLegend> | |
|
28 | #include <QFormLayout> | |
|
29 | #include <QLegendMarker> | |
|
30 | #include <QLineSeries> | |
|
31 | #include <QXYLegendMarker> | |
|
32 | #include <qmath.h> | |
|
33 | ||
|
34 | QTCOMMERCIALCHART_USE_NAMESPACE | |
|
35 | ||
|
36 | MainWidget::MainWidget(QWidget *parent) : | |
|
37 | QWidget(parent) | |
|
38 | { | |
|
39 | // Create buttons for ui | |
|
40 | m_buttonLayout = new QGridLayout(); | |
|
41 | ||
|
42 | QPushButton *addSliceButton = new QPushButton("add series"); | |
|
43 | connect(addSliceButton, SIGNAL(clicked()), this, SLOT(addSeries())); | |
|
44 | m_buttonLayout->addWidget(addSliceButton, 1, 0); | |
|
45 | ||
|
46 | QPushButton *removeSliceButton = new QPushButton("remove series"); | |
|
47 | connect(removeSliceButton, SIGNAL(clicked()), this, SLOT(removeSeries())); | |
|
48 | m_buttonLayout->addWidget(removeSliceButton, 2, 0); | |
|
49 | ||
|
50 | QPushButton *connectButton = new QPushButton("Connect markers"); | |
|
51 | connect(connectButton, SIGNAL(clicked()), this, SLOT(connectMarkers())); | |
|
52 | m_buttonLayout->addWidget(connectButton, 3, 0); | |
|
53 | ||
|
54 | QPushButton *disConnectButton = new QPushButton("Disconnect markers"); | |
|
55 | connect(disConnectButton, SIGNAL(clicked()), this, SLOT(disconnectMarkers())); | |
|
56 | m_buttonLayout->addWidget(disConnectButton, 4, 0); | |
|
57 | ||
|
58 | // Create chart view with the chart | |
|
59 | m_chart = new QChart(); | |
|
60 | m_chartView = new QChartView(m_chart, this); | |
|
61 | ||
|
62 | // Create layout for grid and detached legend | |
|
63 | m_mainLayout = new QGridLayout(); | |
|
64 | m_mainLayout->addLayout(m_buttonLayout, 0, 0); | |
|
65 | m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1); | |
|
66 | setLayout(m_mainLayout); | |
|
67 | ||
|
68 | // Add few series | |
|
69 | addSeries(); | |
|
70 | addSeries(); | |
|
71 | addSeries(); | |
|
72 | addSeries(); | |
|
73 | ||
|
74 | // Set the title and show legend | |
|
75 | m_chart->setTitle("Legendmarker example"); | |
|
76 | m_chart->legend()->setVisible(true); | |
|
77 | m_chart->legend()->setAlignment(Qt::AlignBottom); | |
|
78 | ||
|
79 | m_chartView->setRenderHint(QPainter::Antialiasing); | |
|
80 | } | |
|
81 | ||
|
82 | void MainWidget::addSeries() | |
|
83 | { | |
|
84 | QLineSeries *series = new QLineSeries(); | |
|
85 | m_series.append(series); | |
|
86 | ||
|
87 | series->setName(QString("line " + QString::number(m_series.count()))); | |
|
88 | ||
|
89 | // Make some sine wave for data | |
|
90 | QList<QPointF> data; | |
|
91 | int offset = m_chart->series().count(); | |
|
92 | for (int i = 0; i < 360; i++) { | |
|
93 | qreal x = offset * 20 + i; | |
|
94 | data.append(QPointF(i, qSin(2.0 * 3.141592 * x / 360.0))); | |
|
95 | } | |
|
96 | ||
|
97 | series->append(data); | |
|
98 | m_chart->addSeries(series); | |
|
99 | ||
|
100 | if (m_series.count() == 1) { | |
|
101 | m_chart->createDefaultAxes(); | |
|
102 | } | |
|
103 | } | |
|
104 | ||
|
105 | void MainWidget::removeSeries() | |
|
106 | { | |
|
107 | // Remove last series from chart | |
|
108 | if (m_series.count() > 0) { | |
|
109 | QLineSeries *series = m_series.last(); | |
|
110 | m_chart->removeSeries(series); | |
|
111 | m_series.removeLast(); | |
|
112 | delete series; | |
|
113 | } | |
|
114 | } | |
|
115 | ||
|
116 | void MainWidget::connectMarkers() | |
|
117 | { | |
|
118 | //![1] | |
|
119 | // Connect all markers to handler | |
|
120 | foreach (QLegendMarker* marker, m_chart->legend()->markers()) { | |
|
121 | // Disconnect possible existing connection to avoid multiple connections | |
|
122 | QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(handleMarkerClicked())); | |
|
123 | QObject::connect(marker, SIGNAL(clicked()), this, SLOT(handleMarkerClicked())); | |
|
124 | } | |
|
125 | //![1] | |
|
126 | } | |
|
127 | ||
|
128 | void MainWidget::disconnectMarkers() | |
|
129 | { | |
|
130 | //![2] | |
|
131 | foreach (QLegendMarker* marker, m_chart->legend()->markers()) { | |
|
132 | QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(handleMarkerClicked())); | |
|
133 | } | |
|
134 | //![2] | |
|
135 | } | |
|
136 | ||
|
137 | void MainWidget::handleMarkerClicked() | |
|
138 | { | |
|
139 | //![3] | |
|
140 | QLegendMarker* marker = qobject_cast<QLegendMarker*> (sender()); | |
|
141 | Q_ASSERT(marker); | |
|
142 | //![3] | |
|
143 | ||
|
144 | ||
|
145 | //![4] | |
|
146 | switch (marker->type()) | |
|
147 | //![4] | |
|
148 | { | |
|
149 | case QLegendMarker::LegendMarkerTypeXY: | |
|
150 | { | |
|
151 | //![5] | |
|
152 | // Toggle visibility of series | |
|
153 | marker->series()->setVisible(!marker->series()->isVisible()); | |
|
154 | ||
|
155 | // Turn legend marker back to visible, since hiding series also hides the marker | |
|
156 | // and we don't want it to happen now. | |
|
157 | marker->setVisible(true); | |
|
158 | //![5] | |
|
159 | ||
|
160 | //![6] | |
|
161 | // Dim the marker, if series is not visible | |
|
162 | QXYLegendMarker *xymarker = qobject_cast<QXYLegendMarker *> (marker); | |
|
163 | QColor color = xymarker->labelBrush().color(); | |
|
164 | ||
|
165 | if (marker->series()->isVisible()) { | |
|
166 | color.setAlphaF(1.0); | |
|
167 | } else { | |
|
168 | color.setAlphaF(0.5); | |
|
169 | } | |
|
170 | ||
|
171 | xymarker->setLabelBrush(QBrush(color)); | |
|
172 | //![6] | |
|
173 | break; | |
|
174 | } | |
|
175 | default: | |
|
176 | { | |
|
177 | qDebug() << "Unknown marker type"; | |
|
178 | break; | |
|
179 | } | |
|
180 | } | |
|
181 | } |
@@ -0,0 +1,63 | |||
|
1 | /**************************************************************************** | |
|
2 | ** | |
|
3 | ** Copyright (C) 2012 Digia Plc | |
|
4 | ** All rights reserved. | |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
|
6 | ** | |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
|
8 | ** | |
|
9 | ** $QT_BEGIN_LICENSE$ | |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
|
13 | ** a written agreement between you and Digia. | |
|
14 | ** | |
|
15 | ** If you have questions regarding the use of this file, please use | |
|
16 | ** contact form at http://qt.digia.com | |
|
17 | ** $QT_END_LICENSE$ | |
|
18 | ** | |
|
19 | ****************************************************************************/ | |
|
20 | ||
|
21 | #ifndef MAINWIDGET_H | |
|
22 | #define MAINWIDGET_H | |
|
23 | ||
|
24 | #include "qchartglobal.h" | |
|
25 | #include "qchart.h" | |
|
26 | #include "qchartview.h" | |
|
27 | #include <QWidget> | |
|
28 | #include <QGraphicsWidget> | |
|
29 | #include <QGridLayout> | |
|
30 | #include <QGraphicsGridLayout> | |
|
31 | #include <QDoubleSpinBox> | |
|
32 | #include <QGroupBox> | |
|
33 | #include <QLineSeries> | |
|
34 | ||
|
35 | QTCOMMERCIALCHART_USE_NAMESPACE | |
|
36 | ||
|
37 | class MainWidget : public QWidget | |
|
38 | { | |
|
39 | Q_OBJECT | |
|
40 | public: | |
|
41 | explicit MainWidget(QWidget *parent = 0); | |
|
42 | ||
|
43 | public slots: | |
|
44 | void addSeries(); | |
|
45 | void removeSeries(); | |
|
46 | void connectMarkers(); | |
|
47 | void disconnectMarkers(); | |
|
48 | ||
|
49 | void handleMarkerClicked(); | |
|
50 | ||
|
51 | private: | |
|
52 | ||
|
53 | QChart *m_chart; | |
|
54 | QList<QLineSeries *> m_series; | |
|
55 | ||
|
56 | QChartView *m_chartView; | |
|
57 | QGridLayout *m_mainLayout; | |
|
58 | QGridLayout *m_buttonLayout; | |
|
59 | QGridLayout *m_fontLayout; | |
|
60 | ||
|
61 | }; | |
|
62 | ||
|
63 | #endif // MAINWIDGET_H |
@@ -1,41 +1,42 | |||
|
1 | 1 | CURRENTLY_BUILDING_COMPONENTS = "examples" |
|
2 | 2 | !include( ../config.pri ) { |
|
3 | 3 | error( "Couldn't find the config.pri file!" ) |
|
4 | 4 | } |
|
5 | 5 | |
|
6 | 6 | TEMPLATE = subdirs |
|
7 | 7 | SUBDIRS += \ |
|
8 | 8 | areachart \ |
|
9 | 9 | customchart \ |
|
10 | 10 | linechart \ |
|
11 | 11 | percentbarchart \ |
|
12 | 12 | piechart \ |
|
13 | 13 | piechartdrilldown \ |
|
14 | 14 | presenterchart \ |
|
15 | 15 | scatterchart \ |
|
16 | 16 | scatterinteractions \ |
|
17 | 17 | splinechart \ |
|
18 | 18 | stackedbarchart \ |
|
19 | 19 | stackedbarchartdrilldown \ |
|
20 | 20 | zoomlinechart \ |
|
21 | 21 | modeldata \ |
|
22 | 22 | barchart \ |
|
23 | 23 | legend \ |
|
24 | 24 | barmodelmapper \ |
|
25 | 25 | qmlpiechart \ |
|
26 | 26 | lineandbar \ |
|
27 | 27 | horizontalbarchart \ |
|
28 | 28 | horizontalstackedbarchart \ |
|
29 | 29 | horizontalpercentbarchart \ |
|
30 | 30 | donutbreakdown \ |
|
31 | 31 | scrollchart \ |
|
32 | 32 | temperaturerecords \ |
|
33 | 33 | donutchart \ |
|
34 | 34 | multiaxis \ |
|
35 | 35 | callout \ |
|
36 | newlegend | |
|
36 | newlegend \ | |
|
37 | legendmarkers | |
|
37 | 38 | |
|
38 | 39 | !linux-arm*: { |
|
39 | 40 | SUBDIRS += \ |
|
40 | 41 | datetimeaxis |
|
41 | 42 | } |
@@ -1,399 +1,408 | |||
|
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 "legendlayout_p.h" |
|
22 | 22 | #include "chartpresenter_p.h" |
|
23 | 23 | #include "qlegend_p.h" |
|
24 | 24 | #include "chartlayout_p.h" |
|
25 | 25 | |
|
26 | 26 | #include "qlegendmarker_p.h" |
|
27 | 27 | #include "legendmarkeritem_p.h" |
|
28 | 28 | #include "qlegendmarker.h" |
|
29 | 29 | |
|
30 | 30 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
31 | 31 | |
|
32 | 32 | LegendLayout::LegendLayout(QLegend *legend) |
|
33 | : m_legend(legend) | |
|
33 | : m_legend(legend), | |
|
34 | m_offsetX(0), | |
|
35 | m_offsetY(0) | |
|
34 | 36 | { |
|
35 | 37 | |
|
36 | 38 | } |
|
37 | 39 | |
|
38 | 40 | LegendLayout::~LegendLayout() |
|
39 | 41 | { |
|
40 | 42 | |
|
41 | 43 | } |
|
42 | 44 | |
|
43 | 45 | void LegendLayout::setOffset(qreal x, qreal y) |
|
44 | 46 | { |
|
45 | 47 | bool scrollHorizontal = true; |
|
46 | 48 | switch (m_legend->alignment()) { |
|
47 | 49 | case Qt::AlignTop: |
|
48 | 50 | case Qt::AlignBottom: |
|
49 | 51 | scrollHorizontal = true; |
|
50 | 52 | break; |
|
51 | 53 | case Qt::AlignLeft: |
|
52 | 54 | case Qt::AlignRight: |
|
53 | 55 | scrollHorizontal = false; |
|
54 | 56 | break; |
|
55 | 57 | } |
|
56 | 58 | |
|
57 | 59 | // If detached, the scrolling direction is vertical instead of horizontal and vice versa. |
|
58 | 60 | if (!m_legend->isAttachedToChart()) |
|
59 | 61 | scrollHorizontal = !scrollHorizontal; |
|
60 | 62 | |
|
61 | 63 | QRectF boundingRect = geometry(); |
|
62 | 64 | qreal left, top, right, bottom; |
|
63 | 65 | getContentsMargins(&left, &top, &right, &bottom); |
|
64 | 66 | boundingRect.adjust(left, top, -right, -bottom); |
|
65 | 67 | |
|
66 | 68 | // Limit offset between m_minOffset and m_maxOffset |
|
67 | 69 | if (scrollHorizontal) { |
|
68 | 70 | if (m_width <= boundingRect.width()) |
|
69 | 71 | return; |
|
70 | 72 | |
|
71 | 73 | if (x != m_offsetX) { |
|
72 | 74 | m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX); |
|
73 | 75 | m_legend->d_ptr->items()->setPos(-m_offsetX, boundingRect.top()); |
|
74 | 76 | } |
|
75 | 77 | } else { |
|
76 | 78 | if (m_height <= boundingRect.height()) |
|
77 | 79 | return; |
|
78 | 80 | |
|
79 | 81 | if (y != m_offsetY) { |
|
80 | 82 | m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY); |
|
81 | 83 | m_legend->d_ptr->items()->setPos(boundingRect.left(), -m_offsetY); |
|
82 | 84 | } |
|
83 | 85 | } |
|
84 | 86 | } |
|
85 | 87 | |
|
86 | 88 | QPointF LegendLayout::offset() const |
|
87 | 89 | { |
|
88 | 90 | return QPointF(m_offsetX, m_offsetY); |
|
89 | 91 | } |
|
90 | 92 | |
|
91 | 93 | void LegendLayout::invalidate() |
|
92 | 94 | { |
|
93 | 95 | QGraphicsLayout::invalidate(); |
|
94 | 96 | if (m_legend->isAttachedToChart()) |
|
95 | 97 | m_legend->d_ptr->m_presenter->layout()->invalidate(); |
|
96 | 98 | } |
|
97 | 99 | |
|
98 | 100 | void LegendLayout::setGeometry(const QRectF &rect) |
|
99 | 101 | { |
|
100 | 102 | m_legend->d_ptr->items()->setVisible(m_legend->isVisible()); |
|
101 | 103 | |
|
102 | 104 | QGraphicsLayout::setGeometry(rect); |
|
103 | 105 | |
|
104 | 106 | if (m_legend->isAttachedToChart()) |
|
105 | 107 | setAttachedGeometry(rect); |
|
106 | 108 | else |
|
107 | 109 | setDettachedGeometry(rect); |
|
108 | 110 | } |
|
109 | 111 | |
|
110 | 112 | void LegendLayout::setAttachedGeometry(const QRectF &rect) |
|
111 | 113 | { |
|
112 | 114 | if (!rect.isValid()) |
|
113 | 115 | return; |
|
114 | 116 | |
|
117 | qreal oldOffsetX = m_offsetX; | |
|
118 | qreal oldOffsetY = m_offsetY; | |
|
115 | 119 | m_offsetX = 0; |
|
116 | 120 | m_offsetY = 0; |
|
117 | 121 | |
|
118 | 122 | QSizeF size(0, 0); |
|
119 | 123 | |
|
120 | 124 | if (m_legend->d_ptr->markers().isEmpty()) { |
|
121 | 125 | return; |
|
122 | 126 | } |
|
123 | 127 | |
|
124 | 128 | m_width = 0; |
|
125 | 129 | m_height = 0; |
|
126 | 130 | |
|
127 | 131 | qreal left, top, right, bottom; |
|
128 | 132 | getContentsMargins(&left, &top, &right, &bottom); |
|
129 | 133 | |
|
130 | 134 | QRectF geometry = rect.adjusted(left, top, -right, -bottom); |
|
131 | 135 | |
|
132 | 136 | switch(m_legend->alignment()) { |
|
133 | 137 | case Qt::AlignTop: |
|
134 | 138 | case Qt::AlignBottom: { |
|
135 | 139 | QPointF point(0,0); |
|
136 | 140 | foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
137 | 141 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
138 | 142 | if (item->isVisible()) { |
|
139 | 143 | item->setGeometry(geometry); |
|
140 | 144 | item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2); |
|
141 | 145 | const QRectF &rect = item->boundingRect(); |
|
142 | 146 | size = size.expandedTo(rect.size()); |
|
143 | 147 | qreal w = rect.width(); |
|
144 | 148 | m_width+=w; |
|
145 | 149 | point.setX(point.x() + w); |
|
146 | 150 | } |
|
147 | 151 | } |
|
148 | 152 | if (m_width < geometry.width()) |
|
149 | 153 | m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top()); |
|
150 | 154 | else |
|
151 | 155 | m_legend->d_ptr->items()->setPos(geometry.topLeft()); |
|
152 | 156 | m_height = size.height(); |
|
153 | 157 | } |
|
154 | 158 | break; |
|
155 | 159 | case Qt::AlignLeft: |
|
156 | 160 | case Qt::AlignRight: { |
|
157 | 161 | QPointF point(0,0); |
|
158 | 162 | foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
159 | 163 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
160 | 164 | if (item->isVisible()) { |
|
161 | 165 | item->setGeometry(geometry); |
|
162 | 166 | item->setPos(point); |
|
163 | 167 | const QRectF &rect = item->boundingRect(); |
|
164 | 168 | qreal h = rect.height(); |
|
165 | 169 | size = size.expandedTo(rect.size()); |
|
166 | 170 | m_height+=h; |
|
167 | 171 | point.setY(point.y() + h); |
|
168 | 172 | } |
|
169 | 173 | } |
|
170 | 174 | |
|
171 | 175 | if (m_height < geometry.height()) |
|
172 | 176 | m_legend->d_ptr->items()->setPos(geometry.left(), geometry.height() / 2 - m_height / 2); |
|
173 | 177 | else |
|
174 | 178 | m_legend->d_ptr->items()->setPos(geometry.topLeft()); |
|
175 | 179 | m_width = size.width(); |
|
176 | 180 | break; |
|
177 | 181 | } |
|
178 | 182 | } |
|
179 | 183 | |
|
180 | 184 | m_minOffsetX = -left; |
|
181 | 185 | m_minOffsetY = - top; |
|
182 | 186 | m_maxOffsetX = m_width - geometry.width() - right; |
|
183 | 187 | m_maxOffsetY = m_height - geometry.height() - bottom; |
|
188 | ||
|
189 | setOffset(oldOffsetX, oldOffsetY); | |
|
184 | 190 | } |
|
185 | 191 | |
|
186 | 192 | void LegendLayout::setDettachedGeometry(const QRectF &rect) |
|
187 | 193 | { |
|
188 | 194 | if (!rect.isValid()) |
|
189 | 195 | return; |
|
190 | 196 | |
|
191 | 197 | // Detached layout is different. |
|
192 | 198 | // In detached mode legend may have multiple rows and columns, so layout calculations |
|
193 | 199 | // differ a log from attached mode. |
|
194 | 200 | // Also the scrolling logic is bit different. |
|
195 | 201 | |
|
202 | qreal oldOffsetX = m_offsetX; | |
|
203 | qreal oldOffsetY = m_offsetY; | |
|
196 | 204 | m_offsetX = 0; |
|
197 | 205 | m_offsetY = 0; |
|
198 | 206 | |
|
199 | 207 | qreal left, top, right, bottom; |
|
200 | 208 | getContentsMargins(&left, &top, &right, &bottom); |
|
201 | 209 | QRectF geometry = rect.adjusted(left, top, -right, -bottom); |
|
202 | 210 | |
|
203 | 211 | QSizeF size(0, 0); |
|
204 | 212 | |
|
205 | 213 | QList<QLegendMarker *> markers = m_legend->d_ptr->markers(); |
|
206 | 214 | |
|
207 | 215 | if (markers.isEmpty()) |
|
208 | 216 | return; |
|
209 | 217 | |
|
210 | 218 | switch (m_legend->alignment()) { |
|
211 | 219 | case Qt::AlignTop: { |
|
212 | 220 | QPointF point(0, 0); |
|
213 | 221 | m_width = 0; |
|
214 | 222 | m_height = 0; |
|
215 | 223 | for (int i = 0; i < markers.count(); i++) { |
|
216 | 224 | LegendMarkerItem *item = markers.at(i)->d_ptr->item(); |
|
217 | 225 | if (item->isVisible()) { |
|
218 | 226 | item->setGeometry(geometry); |
|
219 | 227 | item->setPos(point.x(),point.y()); |
|
220 | 228 | const QRectF &boundingRect = item->boundingRect(); |
|
221 | 229 | qreal w = boundingRect.width(); |
|
222 | 230 | qreal h = boundingRect.height(); |
|
223 | 231 | m_width = qMax(m_width,w); |
|
224 | 232 | m_height = qMax(m_height,h); |
|
225 | 233 | point.setX(point.x() + w); |
|
226 | 234 | if (point.x() + w > geometry.left() + geometry.width() - right) { |
|
227 | 235 | // Next item would go off rect. |
|
228 | 236 | point.setX(0); |
|
229 | 237 | point.setY(point.y() + h); |
|
230 | 238 | if (i+1 < markers.count()) { |
|
231 | 239 | m_height += h; |
|
232 | 240 | } |
|
233 | 241 | } |
|
234 | 242 | } |
|
235 | 243 | } |
|
236 | 244 | m_legend->d_ptr->items()->setPos(geometry.topLeft()); |
|
237 | 245 | |
|
238 | 246 | m_minOffsetX = -left; |
|
239 | 247 | m_minOffsetY = -top; |
|
240 | 248 | m_maxOffsetX = m_width - geometry.width() - right; |
|
241 | 249 | m_maxOffsetY = m_height - geometry.height() - bottom; |
|
242 | 250 | } |
|
243 | 251 | break; |
|
244 | 252 | case Qt::AlignBottom: { |
|
245 | 253 | QPointF point(0, geometry.height()); |
|
246 | 254 | m_width = 0; |
|
247 | 255 | m_height = 0; |
|
248 | 256 | for (int i = 0; i < markers.count(); i++) { |
|
249 | 257 | LegendMarkerItem *item = markers.at(i)->d_ptr->item(); |
|
250 | 258 | if (item->isVisible()) { |
|
251 | 259 | item->setGeometry(geometry); |
|
252 | 260 | const QRectF &boundingRect = item->boundingRect(); |
|
253 | 261 | qreal w = boundingRect.width(); |
|
254 | 262 | qreal h = boundingRect.height(); |
|
255 | 263 | m_width = qMax(m_width,w); |
|
256 | 264 | m_height = qMax(m_height,h); |
|
257 | 265 | item->setPos(point.x(),point.y() - h); |
|
258 | 266 | point.setX(point.x() + w); |
|
259 | 267 | if (point.x() + w > geometry.left() + geometry.width() - right) { |
|
260 | 268 | // Next item would go off rect. |
|
261 | 269 | point.setX(0); |
|
262 | 270 | point.setY(point.y() - h); |
|
263 | 271 | if (i+1 < markers.count()) { |
|
264 | 272 | m_height += h; |
|
265 | 273 | } |
|
266 | 274 | } |
|
267 | 275 | } |
|
268 | 276 | } |
|
269 | 277 | m_legend->d_ptr->items()->setPos(geometry.topLeft()); |
|
270 | 278 | |
|
271 | 279 | m_minOffsetX = -left; |
|
272 | 280 | m_minOffsetY = -m_height + geometry.height() - top; |
|
273 | 281 | m_maxOffsetX = m_width - geometry.width() - right; |
|
274 | 282 | m_maxOffsetY = -bottom; |
|
275 | 283 | } |
|
276 | 284 | break; |
|
277 | 285 | case Qt::AlignLeft: { |
|
278 | 286 | QPointF point(0, 0); |
|
279 | 287 | m_width = 0; |
|
280 | 288 | m_height = 0; |
|
281 | 289 | qreal maxWidth = 0; |
|
282 | 290 | for (int i = 0; i < markers.count(); i++) { |
|
283 | 291 | LegendMarkerItem *item = markers.at(i)->d_ptr->item(); |
|
284 | 292 | if (item->isVisible()) { |
|
285 | 293 | item->setGeometry(geometry); |
|
286 | 294 | const QRectF &boundingRect = item->boundingRect(); |
|
287 | 295 | qreal w = boundingRect.width(); |
|
288 | 296 | qreal h = boundingRect.height(); |
|
289 | 297 | m_height = qMax(m_height,h); |
|
290 | 298 | maxWidth = qMax(maxWidth,w); |
|
291 | 299 | item->setPos(point.x(),point.y()); |
|
292 | 300 | point.setY(point.y() + h); |
|
293 | 301 | if (point.y() + h > geometry.bottom() - bottom) { |
|
294 | 302 | // Next item would go off rect. |
|
295 | 303 | point.setX(point.x() + maxWidth); |
|
296 | 304 | point.setY(0); |
|
297 | 305 | if (i+1 < markers.count()) { |
|
298 | 306 | m_width += maxWidth; |
|
299 | 307 | maxWidth = 0; |
|
300 | 308 | } |
|
301 | 309 | } |
|
302 | 310 | } |
|
303 | 311 | } |
|
304 | 312 | m_width += maxWidth; |
|
305 | 313 | m_legend->d_ptr->items()->setPos(geometry.topLeft()); |
|
306 | 314 | |
|
307 | 315 | m_minOffsetX = -left; |
|
308 | 316 | m_minOffsetY = -top; |
|
309 | 317 | m_maxOffsetX = m_width - geometry.width() - right; |
|
310 | 318 | m_maxOffsetY = m_height - geometry.height() - bottom; |
|
311 | 319 | } |
|
312 | 320 | break; |
|
313 | 321 | case Qt::AlignRight: { |
|
314 | 322 | QPointF point(geometry.width(), 0); |
|
315 | 323 | m_width = 0; |
|
316 | 324 | m_height = 0; |
|
317 | 325 | qreal maxWidth = 0; |
|
318 | 326 | for (int i = 0; i < markers.count(); i++) { |
|
319 | 327 | LegendMarkerItem *item = markers.at(i)->d_ptr->item(); |
|
320 | 328 | if (item->isVisible()) { |
|
321 | 329 | item->setGeometry(geometry); |
|
322 | 330 | const QRectF &boundingRect = item->boundingRect(); |
|
323 | 331 | qreal w = boundingRect.width(); |
|
324 | 332 | qreal h = boundingRect.height(); |
|
325 | 333 | m_height = qMax(m_height,h); |
|
326 | 334 | maxWidth = qMax(maxWidth,w); |
|
327 | 335 | item->setPos(point.x() - w,point.y()); |
|
328 | 336 | point.setY(point.y() + h); |
|
329 | 337 | if (point.y() + h > geometry.bottom()-bottom) { |
|
330 | 338 | // Next item would go off rect. |
|
331 | 339 | point.setX(point.x() - maxWidth); |
|
332 | 340 | point.setY(0); |
|
333 | 341 | if (i+1 < markers.count()) { |
|
334 | 342 | m_width += maxWidth; |
|
335 | 343 | maxWidth = 0; |
|
336 | 344 | } |
|
337 | 345 | } |
|
338 | 346 | } |
|
339 | 347 | } |
|
340 | 348 | m_width += maxWidth; |
|
341 | 349 | m_legend->d_ptr->items()->setPos(geometry.topLeft()); |
|
342 | 350 | |
|
343 | 351 | m_minOffsetX = - m_width + geometry.width() - left; |
|
344 | 352 | m_minOffsetY = -top; |
|
345 | 353 | m_maxOffsetX = - right; |
|
346 | 354 | m_maxOffsetY = m_height - geometry.height() - bottom; |
|
347 | 355 | } |
|
348 | 356 | break; |
|
349 | 357 | default: |
|
350 | 358 | break; |
|
351 | 359 | } |
|
352 | 360 | |
|
361 | setOffset(oldOffsetX, oldOffsetY); | |
|
353 | 362 | } |
|
354 | 363 | |
|
355 | 364 | QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
356 | 365 | { |
|
357 | 366 | QSizeF size(0, 0); |
|
358 | 367 | qreal left, top, right, bottom; |
|
359 | 368 | getContentsMargins(&left, &top, &right, &bottom); |
|
360 | 369 | |
|
361 | 370 | if(constraint.isValid()) { |
|
362 | 371 | foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
363 | 372 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
364 | 373 | size = size.expandedTo(item->effectiveSizeHint(which)); |
|
365 | 374 | } |
|
366 | 375 | size = size.boundedTo(constraint); |
|
367 | 376 | } |
|
368 | 377 | else if (constraint.width() >= 0) { |
|
369 | 378 | qreal width = 0; |
|
370 | 379 | qreal height = 0; |
|
371 | 380 | foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
372 | 381 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
373 | 382 | width+=item->effectiveSizeHint(which).width(); |
|
374 | 383 | height=qMax(height,item->effectiveSizeHint(which).height()); |
|
375 | 384 | } |
|
376 | 385 | |
|
377 | 386 | size = QSizeF(qMin(constraint.width(),width), height); |
|
378 | 387 | } |
|
379 | 388 | else if (constraint.height() >= 0) { |
|
380 | 389 | qreal width = 0; |
|
381 | 390 | qreal height = 0; |
|
382 | 391 | foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
383 | 392 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
384 | 393 | width=qMax(width,item->effectiveSizeHint(which).width()); |
|
385 | 394 | height+=height,item->effectiveSizeHint(which).height(); |
|
386 | 395 | } |
|
387 | 396 | size = QSizeF(width,qMin(constraint.height(),height)); |
|
388 | 397 | } |
|
389 | 398 | else { |
|
390 | 399 | foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
391 | 400 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
392 | 401 | size = size.expandedTo(item->effectiveSizeHint(which)); |
|
393 | 402 | } |
|
394 | 403 | } |
|
395 | 404 | size += QSize(left + right, top + bottom); |
|
396 | 405 | return size; |
|
397 | 406 | } |
|
398 | 407 | |
|
399 | 408 | QTCOMMERCIALCHART_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now