@@ -1,92 +1,97 | |||
|
1 | 1 | /****************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2015 The Qt Company Ltd. |
|
4 | 4 | ** Contact: http://www.qt.io/licensing/ |
|
5 | 5 | ** |
|
6 | 6 | ** This file is part of the Qt Charts module. |
|
7 | 7 | ** |
|
8 | 8 | ** $QT_BEGIN_LICENSE:COMM$ |
|
9 | 9 | ** |
|
10 | 10 | ** Commercial License Usage |
|
11 | 11 | ** Licensees holding valid commercial Qt licenses may use this file in |
|
12 | 12 | ** accordance with the commercial license agreement provided with the |
|
13 | 13 | ** Software or, alternatively, in accordance with the terms contained in |
|
14 | 14 | ** a written agreement between you and The Qt Company. For licensing terms |
|
15 | 15 | ** and conditions see http://www.qt.io/terms-conditions. For further |
|
16 | 16 | ** information use the contact form at http://www.qt.io/contact-us. |
|
17 | 17 | ** |
|
18 | 18 | ** $QT_END_LICENSE$ |
|
19 | 19 | ** |
|
20 | 20 | ******************************************************************************/ |
|
21 | 21 | |
|
22 | 22 | #include <private/charttitle_p.h> |
|
23 | 23 | #include <private/chartpresenter_p.h> |
|
24 | 24 | #include <QtGui/QFont> |
|
25 | 25 | #include <QtGui/QFontMetrics> |
|
26 | 26 | #include <QtCore/QDebug> |
|
27 | 27 | #include <QtGui/QTextDocument> |
|
28 | 28 | |
|
29 | 29 | QT_CHARTS_BEGIN_NAMESPACE |
|
30 | 30 | |
|
31 | 31 | ChartTitle::ChartTitle(QGraphicsItem *parent) |
|
32 | 32 | : QGraphicsTextItem(parent) |
|
33 | 33 | { |
|
34 | 34 | document()->setDocumentMargin(ChartPresenter::textMargin()); |
|
35 | 35 | } |
|
36 | 36 | |
|
37 | 37 | ChartTitle::~ChartTitle() |
|
38 | 38 | { |
|
39 | 39 | |
|
40 | 40 | } |
|
41 | 41 | |
|
42 | 42 | void ChartTitle::setText(const QString &text) |
|
43 | 43 | { |
|
44 | 44 | m_text = text; |
|
45 | 45 | } |
|
46 | 46 | |
|
47 | 47 | QString ChartTitle::text() const |
|
48 | 48 | { |
|
49 | 49 | return m_text; |
|
50 | 50 | } |
|
51 | 51 | |
|
52 | 52 | void ChartTitle::setGeometry(const QRectF &rect) |
|
53 | 53 | { |
|
54 | 54 | QRectF truncatedRect; |
|
55 | QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), | |
|
56 | rect.width(), rect.height(), | |
|
57 | truncatedRect)); | |
|
58 | QGraphicsTextItem::setTextWidth(truncatedRect.width()); | |
|
55 | if (m_text.isEmpty()) { | |
|
56 | QGraphicsTextItem::setHtml(m_text); | |
|
57 | QGraphicsTextItem::setTextWidth(0.0); | |
|
58 | } else { | |
|
59 | QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), | |
|
60 | rect.width(), rect.height(), | |
|
61 | truncatedRect)); | |
|
62 | QGraphicsTextItem::setTextWidth(truncatedRect.width()); | |
|
63 | } | |
|
59 | 64 | setPos(rect.topLeft()); |
|
60 | 65 | } |
|
61 | 66 | |
|
62 | 67 | |
|
63 | 68 | QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
64 | 69 | { |
|
65 | 70 | Q_UNUSED(constraint); |
|
66 | 71 | QSizeF sh; |
|
67 | 72 | |
|
68 | 73 | switch (which) { |
|
69 | 74 | case Qt::MinimumSize: { |
|
70 | 75 | QRectF titleRect = ChartPresenter::textBoundingRect(font(), QStringLiteral("...")); |
|
71 | 76 | sh = QSizeF(titleRect.width(), titleRect.height()); |
|
72 | 77 | break; |
|
73 | 78 | } |
|
74 | 79 | case Qt::PreferredSize: |
|
75 | 80 | case Qt::MaximumSize: { |
|
76 | 81 | QRectF titleRect = ChartPresenter::textBoundingRect(font(), m_text); |
|
77 | 82 | sh = QSizeF(titleRect.width(), titleRect.height()); |
|
78 | 83 | break; |
|
79 | 84 | } |
|
80 | 85 | case Qt::MinimumDescent: { |
|
81 | 86 | QFontMetrics fn(font()); |
|
82 | 87 | sh = QSizeF(0, fn.descent()); |
|
83 | 88 | break; |
|
84 | 89 | } |
|
85 | 90 | default: |
|
86 | 91 | break; |
|
87 | 92 | } |
|
88 | 93 | |
|
89 | 94 | return sh; |
|
90 | 95 | } |
|
91 | 96 | |
|
92 | 97 | QT_CHARTS_END_NAMESPACE |
@@ -1,206 +1,210 | |||
|
1 | 1 | /****************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2015 The Qt Company Ltd. |
|
4 | 4 | ** Contact: http://www.qt.io/licensing/ |
|
5 | 5 | ** |
|
6 | 6 | ** This file is part of the Qt Charts module. |
|
7 | 7 | ** |
|
8 | 8 | ** $QT_BEGIN_LICENSE:COMM$ |
|
9 | 9 | ** |
|
10 | 10 | ** Commercial License Usage |
|
11 | 11 | ** Licensees holding valid commercial Qt licenses may use this file in |
|
12 | 12 | ** accordance with the commercial license agreement provided with the |
|
13 | 13 | ** Software or, alternatively, in accordance with the terms contained in |
|
14 | 14 | ** a written agreement between you and The Qt Company. For licensing terms |
|
15 | 15 | ** and conditions see http://www.qt.io/terms-conditions. For further |
|
16 | 16 | ** information use the contact form at http://www.qt.io/contact-us. |
|
17 | 17 | ** |
|
18 | 18 | ** $QT_END_LICENSE$ |
|
19 | 19 | ** |
|
20 | 20 | ******************************************************************************/ |
|
21 | 21 | |
|
22 | 22 | #include <private/abstractchartlayout_p.h> |
|
23 | 23 | #include <private/chartpresenter_p.h> |
|
24 | 24 | #include <private/qlegend_p.h> |
|
25 | 25 | #include <private/chartaxiselement_p.h> |
|
26 | 26 | #include <private/charttitle_p.h> |
|
27 | 27 | #include <private/chartbackground_p.h> |
|
28 | 28 | #include <QtCore/QDebug> |
|
29 | 29 | |
|
30 | 30 | QT_CHARTS_BEGIN_NAMESPACE |
|
31 | 31 | |
|
32 | 32 | static const qreal golden_ratio = 0.4; |
|
33 | 33 | |
|
34 | 34 | AbstractChartLayout::AbstractChartLayout(ChartPresenter *presenter) |
|
35 | 35 | : m_presenter(presenter), |
|
36 | 36 | m_margins(20, 20, 20, 20), |
|
37 | 37 | m_minChartRect(0, 0, 200, 200) |
|
38 | 38 | { |
|
39 | 39 | } |
|
40 | 40 | |
|
41 | 41 | AbstractChartLayout::~AbstractChartLayout() |
|
42 | 42 | { |
|
43 | 43 | } |
|
44 | 44 | |
|
45 | 45 | void AbstractChartLayout::setGeometry(const QRectF &rect) |
|
46 | 46 | { |
|
47 | 47 | if (!rect.isValid()) |
|
48 | 48 | return; |
|
49 | 49 | |
|
50 | 50 | if (m_presenter->chart()->isVisible()) { |
|
51 | 51 | QList<ChartAxisElement *> axes = m_presenter->axisItems(); |
|
52 | 52 | ChartTitle *title = m_presenter->titleElement(); |
|
53 | 53 | QLegend *legend = m_presenter->legend(); |
|
54 | 54 | ChartBackground *background = m_presenter->backgroundElement(); |
|
55 | 55 | |
|
56 | 56 | QRectF contentGeometry = calculateBackgroundGeometry(rect, background); |
|
57 | 57 | |
|
58 | 58 | contentGeometry = calculateContentGeometry(contentGeometry); |
|
59 | 59 | |
|
60 |
if (title && title->isVisible() |
|
|
60 | if (title && title->isVisible()) | |
|
61 | 61 | contentGeometry = calculateTitleGeometry(contentGeometry, title); |
|
62 | 62 | |
|
63 | 63 | if (legend->isAttachedToChart() && legend->isVisible()) |
|
64 | 64 | contentGeometry = calculateLegendGeometry(contentGeometry, legend); |
|
65 | 65 | |
|
66 | 66 | contentGeometry = calculateAxisGeometry(contentGeometry, axes); |
|
67 | 67 | |
|
68 | 68 | m_presenter->setGeometry(contentGeometry); |
|
69 | 69 | if (m_presenter->chart()->chartType() == QChart::ChartTypeCartesian) |
|
70 | 70 | static_cast<QGraphicsRectItem *>(m_presenter->plotAreaElement())->setRect(contentGeometry); |
|
71 | 71 | else |
|
72 | 72 | static_cast<QGraphicsEllipseItem *>(m_presenter->plotAreaElement())->setRect(contentGeometry); |
|
73 | 73 | } |
|
74 | 74 | |
|
75 | 75 | QGraphicsLayout::setGeometry(rect); |
|
76 | 76 | } |
|
77 | 77 | |
|
78 | 78 | QRectF AbstractChartLayout::calculateContentGeometry(const QRectF &geometry) const |
|
79 | 79 | { |
|
80 | 80 | return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom()); |
|
81 | 81 | } |
|
82 | 82 | |
|
83 | 83 | QRectF AbstractChartLayout::calculateContentMinimum(const QRectF &minimum) const |
|
84 | 84 | { |
|
85 | 85 | return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom()); |
|
86 | 86 | } |
|
87 | 87 | |
|
88 | 88 | |
|
89 | 89 | QRectF AbstractChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const |
|
90 | 90 | { |
|
91 | 91 | qreal left; |
|
92 | 92 | qreal top; |
|
93 | 93 | qreal right; |
|
94 | 94 | qreal bottom; |
|
95 | 95 | getContentsMargins(&left, &top, &right, &bottom); |
|
96 | 96 | QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom); |
|
97 | 97 | if (background) |
|
98 | 98 | background->setRect(backgroundGeometry); |
|
99 | 99 | return backgroundGeometry; |
|
100 | 100 | } |
|
101 | 101 | |
|
102 | 102 | QRectF AbstractChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const |
|
103 | 103 | { |
|
104 | 104 | qreal left; |
|
105 | 105 | qreal top; |
|
106 | 106 | qreal right; |
|
107 | 107 | qreal bottom; |
|
108 | 108 | getContentsMargins(&left, &top, &right, &bottom); |
|
109 | 109 | return minimum.adjusted(0, 0, left + right, top + bottom); |
|
110 | 110 | } |
|
111 | 111 | |
|
112 | 112 | QRectF AbstractChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const |
|
113 | 113 | { |
|
114 | 114 | QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); |
|
115 | 115 | QRectF legendRect; |
|
116 | 116 | QRectF result; |
|
117 | 117 | |
|
118 | 118 | switch (legend->alignment()) { |
|
119 | 119 | case Qt::AlignTop: { |
|
120 | 120 | legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height())); |
|
121 | 121 | result = geometry.adjusted(0, legendRect.height(), 0, 0); |
|
122 | 122 | break; |
|
123 | 123 | } |
|
124 | 124 | case Qt::AlignBottom: { |
|
125 | 125 | legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height())); |
|
126 | 126 | result = geometry.adjusted(0, 0, 0, -legendRect.height()); |
|
127 | 127 | break; |
|
128 | 128 | } |
|
129 | 129 | case Qt::AlignLeft: { |
|
130 | 130 | qreal width = qMin(size.width(), geometry.width() * golden_ratio); |
|
131 | 131 | legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height())); |
|
132 | 132 | result = geometry.adjusted(width, 0, 0, 0); |
|
133 | 133 | break; |
|
134 | 134 | } |
|
135 | 135 | case Qt::AlignRight: { |
|
136 | 136 | qreal width = qMin(size.width(), geometry.width() * golden_ratio); |
|
137 | 137 | legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height())); |
|
138 | 138 | result = geometry.adjusted(0, 0, -width, 0); |
|
139 | 139 | break; |
|
140 | 140 | } |
|
141 | 141 | default: { |
|
142 | 142 | legendRect = QRectF(0, 0, 0, 0); |
|
143 | 143 | result = geometry; |
|
144 | 144 | break; |
|
145 | 145 | } |
|
146 | 146 | } |
|
147 | 147 | |
|
148 | 148 | legend->setGeometry(legendRect); |
|
149 | 149 | |
|
150 | 150 | return result; |
|
151 | 151 | } |
|
152 | 152 | |
|
153 | 153 | QRectF AbstractChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const |
|
154 | 154 | { |
|
155 | 155 | QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1)); |
|
156 | 156 | return geometry.adjusted(0, 0, minSize.width(), minSize.height()); |
|
157 | 157 | } |
|
158 | 158 | |
|
159 | 159 | QRectF AbstractChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const |
|
160 | 160 | { |
|
161 | 161 | title->setGeometry(geometry); |
|
162 | // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases | |
|
163 | QPointF center((geometry.center() - title->boundingRect().center()).toPoint()); | |
|
164 | ||
|
165 | title->setPos(center.x(), title->pos().y()); | |
|
166 | return geometry.adjusted(0, title->boundingRect().height()+1, 0, 0); | |
|
162 | if (title->text().isEmpty()) { | |
|
163 | return geometry; | |
|
164 | } else { | |
|
165 | // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases | |
|
166 | QPointF center((geometry.center() - title->boundingRect().center()).toPoint()); | |
|
167 | ||
|
168 | title->setPos(center.x(), title->pos().y()); | |
|
169 | return geometry.adjusted(0, title->boundingRect().height() + 1, 0, 0); | |
|
170 | } | |
|
167 | 171 | } |
|
168 | 172 | |
|
169 | 173 | QRectF AbstractChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const |
|
170 | 174 | { |
|
171 | 175 | QSizeF min = title->sizeHint(Qt::MinimumSize); |
|
172 | 176 | return minimum.adjusted(0, 0, min.width(), min.height()); |
|
173 | 177 | } |
|
174 | 178 | |
|
175 | 179 | QSizeF AbstractChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
176 | 180 | { |
|
177 | 181 | Q_UNUSED(constraint); |
|
178 | 182 | if (which == Qt::MinimumSize) { |
|
179 | 183 | QList<ChartAxisElement *> axes = m_presenter->axisItems(); |
|
180 | 184 | ChartTitle *title = m_presenter->titleElement(); |
|
181 | 185 | QLegend *legend = m_presenter->legend(); |
|
182 | 186 | QRectF minimumRect(0, 0, 0, 0); |
|
183 | 187 | minimumRect = calculateBackgroundMinimum(minimumRect); |
|
184 | 188 | minimumRect = calculateContentMinimum(minimumRect); |
|
185 | 189 | minimumRect = calculateTitleMinimum(minimumRect, title); |
|
186 | 190 | minimumRect = calculateLegendMinimum(minimumRect, legend); |
|
187 | 191 | minimumRect = calculateAxisMinimum(minimumRect, axes); |
|
188 | 192 | return minimumRect.united(m_minChartRect).size().toSize(); |
|
189 | 193 | } |
|
190 | 194 | return QSize(-1, -1); |
|
191 | 195 | } |
|
192 | 196 | |
|
193 | 197 | void AbstractChartLayout::setMargins(const QMargins &margins) |
|
194 | 198 | { |
|
195 | 199 | if (m_margins != margins) { |
|
196 | 200 | m_margins = margins; |
|
197 | 201 | updateGeometry(); |
|
198 | 202 | } |
|
199 | 203 | } |
|
200 | 204 | |
|
201 | 205 | QMargins AbstractChartLayout::margins() const |
|
202 | 206 | { |
|
203 | 207 | return m_margins; |
|
204 | 208 | } |
|
205 | 209 | |
|
206 | 210 | QT_CHARTS_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now