##// END OF EJS Templates
Fix attempt to wrong graphics items hadnling
Michal Klocek -
r790:68c6a254cbfa
parent child
Show More
@@ -1,26 +1,29
1 #include "legendscrollbutton_p.h"
1 #include "legendscrollbutton_p.h"
2 #include "qlegend.h"
2 #include <QGraphicsSceneEvent>
3 #include <QGraphicsSceneEvent>
3
4
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
6
6 LegendScrollButton::LegendScrollButton(ScrollButtonId id, QGraphicsItem *parent)
7 LegendScrollButton::LegendScrollButton(ScrollButtonId id, QLegend *legend)
7 : QGraphicsPolygonItem(parent)
8 : QGraphicsPolygonItem(legend),
8 ,m_id(id)
9 m_id(id),
10 m_ledgend(legend)
9 {
11 {
10 setAcceptedMouseButtons(Qt::LeftButton);
12 setAcceptedMouseButtons(Qt::LeftButton);
11 }
13 }
12
14
13 LegendScrollButton::ScrollButtonId LegendScrollButton::id()
15 LegendScrollButton::ScrollButtonId LegendScrollButton::id()
14 {
16 {
15 return m_id;
17 return m_id;
16 }
18 }
17
19
18 void LegendScrollButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
20 void LegendScrollButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
19 {
21 {
20 emit clicked(event);
22 Q_UNUSED(event);
23 m_ledgend->scrollButtonClicked(this);
21 }
24 }
22
25
23 #include "moc_legendscrollbutton_p.cpp"
26 #include "moc_legendscrollbutton_p.cpp"
24
27
25 QTCOMMERCIALCHART_END_NAMESPACE
28 QTCOMMERCIALCHART_END_NAMESPACE
26
29
@@ -1,38 +1,34
1 #ifndef LEGENDSCROLLBUTTON_P_H
1 #ifndef LEGENDSCROLLBUTTON_P_H
2 #define LEGENDSCROLLBUTTON_P_H
2 #define LEGENDSCROLLBUTTON_P_H
3
3
4 #include <QObject>
4 #include <QObject>
5 #include <qchartglobal.h>
5 #include <qchartglobal.h>
6 #include <QGraphicsPolygonItem>
6 #include <QGraphicsPolygonItem>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class LegendScrollButton : public QObject, public QGraphicsPolygonItem
10 class QLegend;
11
12 class LegendScrollButton : public QGraphicsPolygonItem
11 {
13 {
12 Q_OBJECT
13 public:
14 public:
14 enum ScrollButtonId {
15 enum ScrollButtonId {
15 ScrollButtonIdLeft,
16 ScrollButtonIdLeft,
16 ScrollButtonIdRight,
17 ScrollButtonIdRight,
17 ScrollButtonIdUp,
18 ScrollButtonIdUp,
18 ScrollButtonIdDown
19 ScrollButtonIdDown
19 };
20 };
20
21
21 explicit LegendScrollButton(ScrollButtonId id, QGraphicsItem *parent = 0);
22 explicit LegendScrollButton(ScrollButtonId id, QLegend *legend);
22 ScrollButtonId id();
23 ScrollButtonId id();
23
24
24 virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
25 virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
25
26
26 Q_SIGNALS:
27 void clicked(QGraphicsSceneMouseEvent* event);
28
29 public Q_SLOTS:
30
31 private:
27 private:
32
33 ScrollButtonId m_id;
28 ScrollButtonId m_id;
29 QLegend *m_ledgend;
34 };
30 };
35
31
36 QTCOMMERCIALCHART_END_NAMESPACE
32 QTCOMMERCIALCHART_END_NAMESPACE
37
33
38 #endif // LEGENDSCROLLBUTTON_P_H
34 #endif // LEGENDSCROLLBUTTON_P_H
@@ -1,115 +1,116
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 #ifndef QCHART_H
21 #ifndef QCHART_H
22 #define QCHART_H
22 #define QCHART_H
23
23
24 #include <QSeries>
24 #include <QSeries>
25 #include <QGraphicsWidget>
25 #include <QGraphicsWidget>
26
26
27 class QGraphicsSceneResizeEvent;
27 class QGraphicsSceneResizeEvent;
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 class QSeries;
31 class QSeries;
32 class QChartAxis;
32 class QChartAxis;
33 class QLegend;
33 class QLegend;
34 struct QChartPrivate;
34 struct QChartPrivate;
35
35
36 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
36 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
37 {
37 {
38 Q_OBJECT
38 Q_OBJECT
39 public:
39 public:
40 enum ChartTheme {
40 enum ChartTheme {
41 ChartThemeDefault,
41 ChartThemeDefault,
42 ChartThemeLight,
42 ChartThemeLight,
43 ChartThemeBlueCerulean,
43 ChartThemeBlueCerulean,
44 ChartThemeDark,
44 ChartThemeDark,
45 ChartThemeBrownSand,
45 ChartThemeBrownSand,
46 ChartThemeBlueNcs,
46 ChartThemeBlueNcs,
47 ChartThemeHighContrast,
47 ChartThemeHighContrast,
48 ChartThemeBlueIcy,
48 ChartThemeBlueIcy,
49 ChartThemeCount
49 ChartThemeCount
50 };
50 };
51
51
52 enum AnimationOption {
52 enum AnimationOption {
53 NoAnimation = 0x0,
53 NoAnimation = 0x0,
54 GridAxisAnimations = 0x1,
54 GridAxisAnimations = 0x1,
55 SeriesAnimations =0x2,
55 SeriesAnimations =0x2,
56 AllAnimations = 0x3
56 AllAnimations = 0x3
57 };
57 };
58
58
59 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
59 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
60
60
61 public:
61 public:
62 explicit QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
62 explicit QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
63 ~QChart();
63 ~QChart();
64
64
65 void addSeries(QSeries *series, QChartAxis *axisY = 0);
65 void addSeries(QSeries *series, QChartAxis *axisY = 0);
66 void removeSeries(QSeries *series);
66 void removeSeries(QSeries *series);
67 void removeAllSeries();
67 void removeAllSeries();
68
68
69 void setTheme(QChart::ChartTheme theme);
69 void setTheme(QChart::ChartTheme theme);
70 QChart::ChartTheme theme() const;
70 QChart::ChartTheme theme() const;
71
71
72 void setTitle(const QString& title);
72 void setTitle(const QString& title);
73 QString title() const;
73 QString title() const;
74 void setTitleFont(const QFont& font);
74 void setTitleFont(const QFont& font);
75 QFont titleFont() const;
75 QFont titleFont() const;
76 void setTitleBrush(const QBrush &brush);
76 void setTitleBrush(const QBrush &brush);
77 QBrush titleBrush() const;
77 QBrush titleBrush() const;
78 void setBackgroundBrush(const QBrush &brush);
78 void setBackgroundBrush(const QBrush &brush);
79 QBrush backgroundBrush() const;
79 QBrush backgroundBrush() const;
80 void setBackgroundPen(const QPen &pen);
80 void setBackgroundPen(const QPen &pen);
81 QPen backgroundPen() const;
81 QPen backgroundPen() const;
82
82
83 void setBackgroundVisible(bool visible);
83 void setBackgroundVisible(bool visible);
84 bool isBackgroundVisible() const;
84 bool isBackgroundVisible() const;
85
85
86 void setAnimationOptions(AnimationOptions options);
86 void setAnimationOptions(AnimationOptions options);
87 AnimationOptions animationOptions() const;
87 AnimationOptions animationOptions() const;
88
88
89 void zoomIn();
89 void zoomIn();
90 void zoomIn(const QRectF &rect);
90 void zoomIn(const QRectF &rect);
91 void zoomOut();
91 void zoomOut();
92 void scrollLeft();
92 void scrollLeft();
93 void scrollRight();
93 void scrollRight();
94 void scrollUp();
94 void scrollUp();
95 void scrollDown();
95 void scrollDown();
96
96
97 QChartAxis* axisX() const;
97 QChartAxis* axisX() const;
98 QChartAxis* axisY() const;
98 QChartAxis* axisY() const;
99
99
100 QLegend* legend() const;
100 QLegend* legend() const;
101
101
102 protected:
102 protected:
103 void resizeEvent(QGraphicsSceneResizeEvent *event);
103 void resizeEvent(QGraphicsSceneResizeEvent *event);
104
104
105 protected:
105 protected:
106 QScopedPointer<QChartPrivate> d_ptr;
106 QScopedPointer<QChartPrivate> d_ptr;
107 friend class QChartView;
107 friend class QChartView;
108 friend class QLegend;
108 Q_DISABLE_COPY(QChart)
109 Q_DISABLE_COPY(QChart)
109 };
110 };
110
111
111 QTCOMMERCIALCHART_END_NAMESPACE
112 QTCOMMERCIALCHART_END_NAMESPACE
112
113
113 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
114 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
114
115
115 #endif
116 #endif
@@ -1,706 +1,693
1 #include "qchartglobal.h"
2 #include "qlegend.h"
1 #include "qlegend.h"
2 #include "qchart_p.h"
3 #include "qseries.h"
3 #include "qseries.h"
4 #include "legendmarker_p.h"
4 #include "legendmarker_p.h"
5 #include "legendscrollbutton_p.h"
5 #include "legendscrollbutton_p.h"
6 #include "qxyseries.h"
6 #include "qxyseries.h"
7 #include "qlineseries.h"
7 #include "qlineseries.h"
8 #include "qareaseries.h"
8 #include "qareaseries.h"
9 #include "qscatterseries.h"
9 #include "qscatterseries.h"
10 #include "qsplineseries.h"
10 #include "qsplineseries.h"
11 #include "qbarseries.h"
11 #include "qbarseries.h"
12 #include "qstackedbarseries.h"
12 #include "qstackedbarseries.h"
13 #include "qpercentbarseries.h"
13 #include "qpercentbarseries.h"
14 #include "qbarset.h"
14 #include "qbarset.h"
15 #include "qpieseries.h"
15 #include "qpieseries.h"
16 #include "qpieslice.h"
16 #include "qpieslice.h"
17 #include "chartpresenter_p.h"
17 #include "chartpresenter_p.h"
18 #include <QPainter>
18 #include <QPainter>
19 #include <QPen>
19 #include <QPen>
20
20
21 #include <QGraphicsSceneEvent>
21 #include <QGraphicsSceneEvent>
22
22
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24
24
25 /*!
25 /*!
26 \class QLegend
26 \class QLegend
27 \brief part of QtCommercial chart API.
27 \brief part of QtCommercial chart API.
28
28
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
31 handle the drawing manually.
31 handle the drawing manually.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
33
33
34 \mainclass
34 \mainclass
35
35
36 \sa QChart, QSeries
36 \sa QChart, QSeries
37 */
37 */
38
38
39 /*!
39 /*!
40 \enum QLegend::Layout
40 \enum QLegend::Layout
41
41
42 This enum describes the possible position for legend inside chart.
42 This enum describes the possible position for legend inside chart.
43
43
44 \value LayoutTop
44 \value LayoutTop
45 \value LayoutBottom
45 \value LayoutBottom
46 \value LayoutLeft
46 \value LayoutLeft
47 \value LayoutRight
47 \value LayoutRight
48 */
48 */
49
49
50
50
51 /*!
51 /*!
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
53 \brief Notifies when series has been clicked on legend \a series \a button
53 \brief Notifies when series has been clicked on legend \a series \a button
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
58 \brief Notifies when barset has been clicked on legend \a barset \a button
58 \brief Notifies when barset has been clicked on legend \a barset \a button
59 */
59 */
60
60
61 /*!
61 /*!
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs the legend object and sets the parent to \a parent
67 Constructs the legend object and sets the parent to \a parent
68 */
68 */
69 QLegend::QLegend(QGraphicsItem *parent) : QGraphicsObject(parent),
69 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart->d_ptr->m_presenter->rootItem()),
70 m_margin(5),
70 m_margin(5),
71 m_pos(0,0),
71 m_pos(0,0),
72 m_minimumSize(50,20), // TODO: magic numbers
72 m_minimumSize(50,20), // TODO: magic numbers
73 m_maximumSize(150,100),
73 m_maximumSize(150,100),
74 m_size(m_minimumSize),
74 m_size(m_minimumSize),
75 m_brush(Qt::darkGray), // TODO: default should come from theme
75 m_brush(Qt::darkGray), // TODO: default should come from theme
76 m_alignment(QLegend::LayoutTop),
76 m_alignment(QLegend::LayoutTop),
77 mFirstMarker(0)
77 mFirstMarker(0)
78 {
78 {
79 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
79 m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
80 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
80 m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
81 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
81 m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
82 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
82 m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
83
84 connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
85 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
86 connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
87 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
88 connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
89 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
90 connect(m_scrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
91 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
92
93 setZValue(ChartPresenter::LegendZValue);
83 setZValue(ChartPresenter::LegendZValue);
94 }
84 }
95
85
96 /*!
86 /*!
97 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
87 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
98 */
88 */
99 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
89 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
100 {
90 {
101 Q_UNUSED(option)
91 Q_UNUSED(option)
102 Q_UNUSED(widget)
92 Q_UNUSED(widget)
103
93
104 painter->setOpacity(opacity());
94 painter->setOpacity(opacity());
105 painter->setPen(m_pen);
95 painter->setPen(m_pen);
106 painter->setBrush(m_brush);
96 painter->setBrush(m_brush);
107 // painter->drawRect(boundingRect());
97 // painter->drawRect(boundingRect());
108 }
98 }
109
99
110 /*!
100 /*!
111 Bounding rect of legend.
101 Bounding rect of legend.
112 */
102 */
113 QRectF QLegend::boundingRect() const
103 QRectF QLegend::boundingRect() const
114 {
104 {
115 return QRectF(m_pos,m_size);
105 return QRectF(m_pos,m_size);
116 }
106 }
117
107
118 /*!
108 /*!
119 Sets the \a brush of legend. Brush affects the background of legend.
109 Sets the \a brush of legend. Brush affects the background of legend.
120 */
110 */
121 void QLegend::setBrush(const QBrush &brush)
111 void QLegend::setBrush(const QBrush &brush)
122 {
112 {
123 if (m_brush != brush) {
113 if (m_brush != brush) {
124 m_brush = brush;
114 m_brush = brush;
125 update();
115 update();
126 }
116 }
127 }
117 }
128
118
129 /*!
119 /*!
130 Returns the brush used by legend.
120 Returns the brush used by legend.
131 */
121 */
132 QBrush QLegend::brush() const
122 QBrush QLegend::brush() const
133 {
123 {
134 return m_brush;
124 return m_brush;
135 }
125 }
136
126
137 /*!
127 /*!
138 Sets the \a pen of legend. Pen affects the legend borders.
128 Sets the \a pen of legend. Pen affects the legend borders.
139 */
129 */
140 void QLegend::setPen(const QPen &pen)
130 void QLegend::setPen(const QPen &pen)
141 {
131 {
142 if (m_pen != pen) {
132 if (m_pen != pen) {
143 m_pen = pen;
133 m_pen = pen;
144 update();
134 update();
145 }
135 }
146 }
136 }
147
137
148 /*!
138 /*!
149 Returns the pen used by legend
139 Returns the pen used by legend
150 */
140 */
151
141
152 QPen QLegend::pen() const
142 QPen QLegend::pen() const
153 {
143 {
154 return m_pen;
144 return m_pen;
155 }
145 }
156
146
157 /*!
147 /*!
158 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
148 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
159 \sa QLegend::Layout
149 \sa QLegend::Layout
160 */
150 */
161 void QLegend::setAlignmnent(QLegend::Layout alignment)
151 void QLegend::setAlignmnent(QLegend::Layout alignment)
162 {
152 {
163 m_alignment = alignment;
153 m_alignment = alignment;
164 updateLayout();
154 updateLayout();
165 }
155 }
166
156
167 /*!
157 /*!
168 Returns the preferred layout for legend
158 Returns the preferred layout for legend
169 */
159 */
170 QLegend::Layout QLegend::alignment() const
160 QLegend::Layout QLegend::alignment() const
171 {
161 {
172 return m_alignment;
162 return m_alignment;
173 }
163 }
174
164
175 /*!
165 /*!
176 Returns the maximum size of legend.
166 Returns the maximum size of legend.
177 */
167 */
178 QSizeF QLegend::maximumSize() const
168 QSizeF QLegend::maximumSize() const
179 {
169 {
180 return m_maximumSize;
170 return m_maximumSize;
181 }
171 }
182
172
183 /*!
173 /*!
184 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
174 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
185 more series than legend can fit to this size, scroll buttons are displayed.
175 more series than legend can fit to this size, scroll buttons are displayed.
186 */
176 */
187 void QLegend::setMaximumSize(const QSizeF size)
177 void QLegend::setMaximumSize(const QSizeF size)
188 {
178 {
189 m_maximumSize = size;
179 m_maximumSize = size;
190 updateLayout();
180 updateLayout();
191 }
181 }
192
182
193 /*!
183 /*!
194 Returns the current size of legend.
184 Returns the current size of legend.
195 */
185 */
196 QSizeF QLegend::size() const
186 QSizeF QLegend::size() const
197 {
187 {
198 return m_size;
188 return m_size;
199 }
189 }
200
190
201 /*!
191 /*!
202 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
192 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
203 \sa setMmaximumSize()
193 \sa setMmaximumSize()
204 */
194 */
205 void QLegend::setSize(const QSizeF size)
195 void QLegend::setSize(const QSizeF size)
206 {
196 {
207 m_size = size;
197 m_size = size;
208 if (m_size.width() > m_maximumSize.width()) {
198 if (m_size.width() > m_maximumSize.width()) {
209 m_size.setWidth(m_maximumSize.width());
199 m_size.setWidth(m_maximumSize.width());
210 }
200 }
211 if (m_size.height() > m_maximumSize.height()) {
201 if (m_size.height() > m_maximumSize.height()) {
212 m_size.setHeight(m_maximumSize.height());
202 m_size.setHeight(m_maximumSize.height());
213 }
203 }
214 }
204 }
215
205
216 /*!
206 /*!
217 Sets position of legend to \a pos
207 Sets position of legend to \a pos
218 */
208 */
219 void QLegend::setPos(const QPointF &pos)
209 void QLegend::setPos(const QPointF &pos)
220 {
210 {
221 m_pos = pos;
211 m_pos = pos;
222 updateLayout();
212 updateLayout();
223 }
213 }
224
214
225 /*!
215 /*!
226 \internal \a series \a domain Should be called when series is added to chart.
216 \internal \a series \a domain Should be called when series is added to chart.
227 */
217 */
228 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
218 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
229 {
219 {
230 Q_UNUSED(domain)
220 Q_UNUSED(domain)
231
221
232 createMarkers(series);
222 createMarkers(series);
233 connectSeries(series);
223 connectSeries(series);
234 updateLayout();
224 updateLayout();
235 }
225 }
236
226
237 /*!
227 /*!
238 \internal \a series Should be called when series is removed from chart.
228 \internal \a series Should be called when series is removed from chart.
239 */
229 */
240 void QLegend::handleSeriesRemoved(QSeries *series)
230 void QLegend::handleSeriesRemoved(QSeries *series)
241 {
231 {
242 disconnectSeries(series);
232 disconnectSeries(series);
243
233
244 if (series->type() == QSeries::SeriesTypeArea) {
234 if (series->type() == QSeries::SeriesTypeArea) {
245 // This is special case. Area series has upper and lower series, which each have markers
235 // This is special case. Area series has upper and lower series, which each have markers
246 QAreaSeries* s = static_cast<QAreaSeries *> (series);
236 QAreaSeries* s = static_cast<QAreaSeries *> (series);
247 deleteMarkers(s->upperSeries());
237 deleteMarkers(s->upperSeries());
248 deleteMarkers(s->lowerSeries());
238 deleteMarkers(s->lowerSeries());
249 } else {
239 } else {
250 deleteMarkers(series);
240 deleteMarkers(series);
251 }
241 }
252
242
253 updateLayout();
243 updateLayout();
254 }
244 }
255
245
256 /*!
246 /*!
257 \internal \a slices Should be called when slices are added to pie chart.
247 \internal \a slices Should be called when slices are added to pie chart.
258 */
248 */
259 void QLegend::handleAdded(QList<QPieSlice *> slices)
249 void QLegend::handleAdded(QList<QPieSlice *> slices)
260 {
250 {
261 QPieSeries* series = static_cast<QPieSeries *> (sender());
251 QPieSeries* series = static_cast<QPieSeries *> (sender());
262 foreach(QPieSlice* s, slices) {
252 foreach(QPieSlice* s, slices) {
263 LegendMarker* marker = new LegendMarker(series, s, this);
253 LegendMarker* marker = new LegendMarker(series, s, this);
264 marker->setName(s->label());
254 marker->setName(s->label());
265 marker->setBrush(s->brush());
255 marker->setBrush(s->brush());
266 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
256 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
267 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
257 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
268 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
258 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
269 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
259 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
270 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
260 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
271 m_markers.append(marker);
261 m_markers.append(marker);
272 childItems().append(marker);
262 childItems().append(marker);
273 }
263 }
274 updateLayout();
264 updateLayout();
275 }
265 }
276
266
277 /*!
267 /*!
278 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
268 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
279 because removed slices are also deleted and we listen destroyed signal
269 because removed slices are also deleted and we listen destroyed signal
280 */
270 */
281 void QLegend::handleRemoved(QList<QPieSlice *> slices)
271 void QLegend::handleRemoved(QList<QPieSlice *> slices)
282 {
272 {
283 Q_UNUSED(slices)
273 Q_UNUSED(slices)
284 }
274 }
285
275
286
276
287 /*!
277 /*!
288 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
278 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
289 */
279 */
290 void QLegend::handleMarkerDestroyed()
280 void QLegend::handleMarkerDestroyed()
291 {
281 {
292 LegendMarker* m = static_cast<LegendMarker *> (sender());
282 LegendMarker* m = static_cast<LegendMarker *> (sender());
293 m_markers.removeOne(m);
283 m_markers.removeOne(m);
294 updateLayout();
284 updateLayout();
295 }
285 }
296
286
297 /*!
287 /*!
298 \internal \a event Handles clicked signals from scroll buttons
288 \internal \a event Handles clicked signals from scroll buttons
299 */
289 */
300 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
290 void QLegend::scrollButtonClicked(LegendScrollButton *scrollButton)
301 {
291 {
302 Q_UNUSED(event); // Maybe later something happens with right click...
292 Q_ASSERT(scrollButton);
303
304 LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender());
305 Q_ASSERT(scrollButton);
306
293
307 switch (scrollButton->id()) {
294 switch (scrollButton->id()) {
308 case LegendScrollButton::ScrollButtonIdLeft:
295 case LegendScrollButton::ScrollButtonIdLeft:
309 case LegendScrollButton::ScrollButtonIdUp: {
296 case LegendScrollButton::ScrollButtonIdUp: {
310 // Lower limit is same in these cases
297 // Lower limit is same in these cases
311 mFirstMarker--;
298 mFirstMarker--;
312 checkFirstMarkerBounds();
299 checkFirstMarkerBounds();
313 break;
300 break;
314 }
301 }
315 case LegendScrollButton::ScrollButtonIdRight:
302 case LegendScrollButton::ScrollButtonIdRight:
316 case LegendScrollButton::ScrollButtonIdDown: {
303 case LegendScrollButton::ScrollButtonIdDown: {
317 mFirstMarker++;
304 mFirstMarker++;
318 checkFirstMarkerBounds();
305 checkFirstMarkerBounds();
319 break;
306 break;
320 }
307 }
321 default: {
308 default: {
322 break;
309 break;
323 }
310 }
324 }
311 }
325 updateLayout();
312 updateLayout();
326 }
313 }
327
314
328 /*!
315 /*!
329 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
316 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
330 Not all series notify about events
317 Not all series notify about events
331 */
318 */
332 void QLegend::connectSeries(QSeries *series)
319 void QLegend::connectSeries(QSeries *series)
333 {
320 {
334 // Connect relevant signals from series. Currently only pie series has interesting signals
321 // Connect relevant signals from series. Currently only pie series has interesting signals
335 // TODO: bar chart may have
322 // TODO: bar chart may have
336 if (series->type() == QSeries::SeriesTypePie) {
323 if (series->type() == QSeries::SeriesTypePie) {
337 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
324 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
338 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
325 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
339 }
326 }
340 }
327 }
341
328
342 /*!
329 /*!
343 \internal Disconnects \a series from legend. No more status updates from series to legend.
330 \internal Disconnects \a series from legend. No more status updates from series to legend.
344 */
331 */
345 void QLegend::disconnectSeries(QSeries *series)
332 void QLegend::disconnectSeries(QSeries *series)
346 {
333 {
347 if (series->type() == QSeries::SeriesTypePie) {
334 if (series->type() == QSeries::SeriesTypePie) {
348 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
335 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
349 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
336 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
350 }
337 }
351 }
338 }
352
339
353 /*!
340 /*!
354 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
341 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
355 With pie chart, created markers depend on pie slices.
342 With pie chart, created markers depend on pie slices.
356 With bar chart, created markers depend on bar sets.
343 With bar chart, created markers depend on bar sets.
357 */
344 */
358 void QLegend::createMarkers(QSeries *series)
345 void QLegend::createMarkers(QSeries *series)
359 {
346 {
360 switch (series->type())
347 switch (series->type())
361 {
348 {
362 case QSeries::SeriesTypeLine: {
349 case QSeries::SeriesTypeLine: {
363 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
350 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
364 appendMarkers(lineSeries);
351 appendMarkers(lineSeries);
365 break;
352 break;
366 }
353 }
367 case QSeries::SeriesTypeArea: {
354 case QSeries::SeriesTypeArea: {
368 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
355 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
369 appendMarkers(areaSeries->upperSeries());
356 appendMarkers(areaSeries->upperSeries());
370 if(areaSeries->lowerSeries())
357 if(areaSeries->lowerSeries())
371 appendMarkers(areaSeries->lowerSeries());
358 appendMarkers(areaSeries->lowerSeries());
372 break;
359 break;
373 }
360 }
374 case QSeries::SeriesTypeBar: {
361 case QSeries::SeriesTypeBar: {
375 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
362 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
376 appendMarkers(barSeries);
363 appendMarkers(barSeries);
377 break;
364 break;
378 }
365 }
379 case QSeries::SeriesTypeStackedBar: {
366 case QSeries::SeriesTypeStackedBar: {
380 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
367 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
381 appendMarkers(stackedBarSeries);
368 appendMarkers(stackedBarSeries);
382 break;
369 break;
383 }
370 }
384 case QSeries::SeriesTypePercentBar: {
371 case QSeries::SeriesTypePercentBar: {
385 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
372 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
386 appendMarkers(percentBarSeries);
373 appendMarkers(percentBarSeries);
387 break;
374 break;
388 }
375 }
389 case QSeries::SeriesTypeScatter: {
376 case QSeries::SeriesTypeScatter: {
390 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
377 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
391 appendMarkers(scatterSeries);
378 appendMarkers(scatterSeries);
392 break;
379 break;
393 }
380 }
394 case QSeries::SeriesTypePie: {
381 case QSeries::SeriesTypePie: {
395 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
382 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
396 appendMarkers(pieSeries);
383 appendMarkers(pieSeries);
397 break;
384 break;
398 }
385 }
399 case QSeries::SeriesTypeSpline: {
386 case QSeries::SeriesTypeSpline: {
400 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
387 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
401 appendMarkers(splineSeries);
388 appendMarkers(splineSeries);
402 break;
389 break;
403 }
390 }
404 default: {
391 default: {
405 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
392 qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type.";
406 break;
393 break;
407 }
394 }
408 }
395 }
409 }
396 }
410
397
411 /*!
398 /*!
412 \internal Helper function. Appends markers from \a series to legend.
399 \internal Helper function. Appends markers from \a series to legend.
413 */
400 */
414 void QLegend::appendMarkers(QXYSeries* series)
401 void QLegend::appendMarkers(QXYSeries* series)
415 {
402 {
416 LegendMarker* marker = new LegendMarker(series,this);
403 LegendMarker* marker = new LegendMarker(series,this);
417 marker->setName(series->name());
404 marker->setName(series->name());
418 marker->setPen(series->pen());
405 marker->setPen(series->pen());
419 marker->setBrush(series->brush());
406 marker->setBrush(series->brush());
420 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
407 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
421 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
408 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
422 m_markers.append(marker);
409 m_markers.append(marker);
423 childItems().append(marker);
410 childItems().append(marker);
424 }
411 }
425
412
426 /*!
413 /*!
427 \internal Helper function. Appends markers from \a series to legend.
414 \internal Helper function. Appends markers from \a series to legend.
428 */
415 */
429 void QLegend::appendMarkers(QBarSeries *series)
416 void QLegend::appendMarkers(QBarSeries *series)
430 {
417 {
431 foreach(QBarSet* set, series->barSets()) {
418 foreach(QBarSet* set, series->barSets()) {
432 LegendMarker* marker = new LegendMarker(series, set, this);
419 LegendMarker* marker = new LegendMarker(series, set, this);
433 marker->setName(set->name());
420 marker->setName(set->name());
434 marker->setPen(set->pen());
421 marker->setPen(set->pen());
435 marker->setBrush(set->brush());
422 marker->setBrush(set->brush());
436 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
423 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
437 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
424 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
438 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
425 connect(set, SIGNAL(valueChanged()), marker, SLOT(changed()));
439 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
426 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
440 m_markers.append(marker);
427 m_markers.append(marker);
441 childItems().append(marker);
428 childItems().append(marker);
442 }
429 }
443 }
430 }
444
431
445 /*!
432 /*!
446 \internal Helper function. Appends markers from \a series to legend.
433 \internal Helper function. Appends markers from \a series to legend.
447 */
434 */
448 void QLegend::appendMarkers(QPieSeries *series)
435 void QLegend::appendMarkers(QPieSeries *series)
449 {
436 {
450 foreach(QPieSlice* slice, series->slices()) {
437 foreach(QPieSlice* slice, series->slices()) {
451 LegendMarker* marker = new LegendMarker(series, slice, this);
438 LegendMarker* marker = new LegendMarker(series, slice, this);
452 marker->setName(slice->label());
439 marker->setName(slice->label());
453 marker->setPen(slice->pen());
440 marker->setPen(slice->pen());
454 marker->setBrush(slice->brush());
441 marker->setBrush(slice->brush());
455 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
442 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
456 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
443 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
457 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
444 connect(slice, SIGNAL(changed()), marker, SLOT(changed()));
458 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
445 connect(slice, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
459 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
446 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
460 m_markers.append(marker);
447 m_markers.append(marker);
461 childItems().append(marker);
448 childItems().append(marker);
462 }
449 }
463 }
450 }
464
451
465 /*!
452 /*!
466 \internal Deletes all markers that are created from \a series
453 \internal Deletes all markers that are created from \a series
467 */
454 */
468 void QLegend::deleteMarkers(QSeries *series)
455 void QLegend::deleteMarkers(QSeries *series)
469 {
456 {
470 // Search all markers that belong to given series and delete them.
457 // Search all markers that belong to given series and delete them.
471 foreach (LegendMarker *m, m_markers) {
458 foreach (LegendMarker *m, m_markers) {
472 if (m->series() == series) {
459 if (m->series() == series) {
473 m_markers.removeOne(m);
460 m_markers.removeOne(m);
474 delete m;
461 delete m;
475 }
462 }
476 }
463 }
477 }
464 }
478
465
479 /*!
466 /*!
480 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
467 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
481 If items don't fit, sets the visibility of scroll buttons accordingly.
468 If items don't fit, sets the visibility of scroll buttons accordingly.
482 Causes legend to be resized.
469 Causes legend to be resized.
483 */
470 */
484 void QLegend::updateLayout()
471 void QLegend::updateLayout()
485 {
472 {
486 // Calculate layout for markers and text
473 // Calculate layout for markers and text
487 if (m_markers.count() <= 0) {
474 if (m_markers.count() <= 0) {
488 // Nothing to do
475 // Nothing to do
489 return;
476 return;
490 }
477 }
491
478
492 // Find out widest item.
479 // Find out widest item.
493 QSizeF markerMaxSize = maximumMarkerSize();
480 QSizeF markerMaxSize = maximumMarkerSize();
494 checkFirstMarkerBounds();
481 checkFirstMarkerBounds();
495
482
496 // Use max height as scroll button size
483 // Use max height as scroll button size
497 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
484 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
498
485
499 qreal totalWidth = 0;
486 qreal totalWidth = 0;
500 qreal totalHeight = 0;
487 qreal totalHeight = 0;
501 switch (m_alignment)
488 switch (m_alignment)
502 {
489 {
503 // Both cases organise items horizontally
490 // Both cases organise items horizontally
504 case QLegend::LayoutBottom:
491 case QLegend::LayoutBottom:
505 case QLegend::LayoutTop: {
492 case QLegend::LayoutTop: {
506
493
507 qreal xStep = markerMaxSize.width();
494 qreal xStep = markerMaxSize.width();
508 qreal x = m_pos.x() + m_margin;
495 qreal x = m_pos.x() + m_margin;
509 qreal y = m_pos.y() + m_margin;
496 qreal y = m_pos.y() + m_margin;
510 int column = 0;
497 int column = 0;
511 int maxColumns = 1;
498 int maxColumns = 1;
512 qreal scrollButtonWidth = 0;
499 qreal scrollButtonWidth = 0;
513
500
514 // Set correct visibility for scroll scrollbuttons
501 // Set correct visibility for scroll scrollbuttons
515 if (scrollButtonsVisible()) {
502 if (scrollButtonsVisible()) {
516 m_scrollButtonLeft->setVisible(true);
503 m_scrollButtonLeft->setVisible(true);
517 m_scrollButtonRight->setVisible(true);
504 m_scrollButtonRight->setVisible(true);
518 // scrollbuttons visible, so add their width to total width
505 // scrollbuttons visible, so add their width to total width
519 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
506 totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2;
520 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
507 scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin;
521 // start position changes by scrollbutton width
508 // start position changes by scrollbutton width
522 x += scrollButtonWidth;
509 x += scrollButtonWidth;
523 } else {
510 } else {
524 m_scrollButtonLeft->setVisible(false);
511 m_scrollButtonLeft->setVisible(false);
525 m_scrollButtonRight->setVisible(false);
512 m_scrollButtonRight->setVisible(false);
526 }
513 }
527 m_scrollButtonUp->setVisible(false);
514 m_scrollButtonUp->setVisible(false);
528 m_scrollButtonDown->setVisible(false);
515 m_scrollButtonDown->setVisible(false);
529
516
530 for (int i=0; i < m_markers.count(); i++) {
517 for (int i=0; i < m_markers.count(); i++) {
531 LegendMarker *m = m_markers.at(i);
518 LegendMarker *m = m_markers.at(i);
532 if (i < mFirstMarker) {
519 if (i < mFirstMarker) {
533 // Markers before first are not visible.
520 // Markers before first are not visible.
534 m->setVisible(false);
521 m->setVisible(false);
535 } else {
522 } else {
536 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
523 if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) {
537 // This marker would go outside legend rect.
524 // This marker would go outside legend rect.
538 m->setVisible(false);
525 m->setVisible(false);
539 } else {
526 } else {
540 // This marker is ok
527 // This marker is ok
541 m->setVisible(true);
528 m->setVisible(true);
542 m->setPos(x, y);
529 m->setPos(x, y);
543 x += xStep;
530 x += xStep;
544 column++;
531 column++;
545 }
532 }
546 }
533 }
547 maxColumns = column;
534 maxColumns = column;
548 }
535 }
549
536
550 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
537 m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y);
551 m_scrollButtonRight->setPos(x + m_margin, y);
538 m_scrollButtonRight->setPos(x + m_margin, y);
552
539
553 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
540 totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2;
554 totalHeight = markerMaxSize.height() + m_margin * 2;
541 totalHeight = markerMaxSize.height() + m_margin * 2;
555
542
556 break;
543 break;
557 }
544 }
558 // Both cases organize items vertically
545 // Both cases organize items vertically
559 case QLegend::LayoutLeft:
546 case QLegend::LayoutLeft:
560 case QLegend::LayoutRight: {
547 case QLegend::LayoutRight: {
561 qreal yStep = markerMaxSize.height();
548 qreal yStep = markerMaxSize.height();
562 qreal x = m_pos.x() + m_margin;
549 qreal x = m_pos.x() + m_margin;
563 qreal y = m_pos.y() + m_margin;
550 qreal y = m_pos.y() + m_margin;
564 int row = 1;
551 int row = 1;
565 int maxRows = 1;
552 int maxRows = 1;
566 qreal scrollButtonHeight = 0;
553 qreal scrollButtonHeight = 0;
567
554
568 // Set correct visibility for scroll scrollbuttons
555 // Set correct visibility for scroll scrollbuttons
569 if (scrollButtonsVisible()) {
556 if (scrollButtonsVisible()) {
570 m_scrollButtonUp->setVisible(true);
557 m_scrollButtonUp->setVisible(true);
571 m_scrollButtonDown->setVisible(true);
558 m_scrollButtonDown->setVisible(true);
572 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
559 totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height
573 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
560 scrollButtonHeight = m_scrollButtonUp->boundingRect().height();
574 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
561 y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height
575 } else {
562 } else {
576 m_scrollButtonUp->setVisible(false);
563 m_scrollButtonUp->setVisible(false);
577 m_scrollButtonDown->setVisible(false);
564 m_scrollButtonDown->setVisible(false);
578 }
565 }
579 m_scrollButtonLeft->setVisible(false);
566 m_scrollButtonLeft->setVisible(false);
580 m_scrollButtonRight->setVisible(false);
567 m_scrollButtonRight->setVisible(false);
581
568
582 for (int i=0; i < m_markers.count(); i++) {
569 for (int i=0; i < m_markers.count(); i++) {
583 LegendMarker* m = m_markers.at(i);
570 LegendMarker* m = m_markers.at(i);
584 if (i < mFirstMarker) {
571 if (i < mFirstMarker) {
585 // Markers before first are not visible.
572 // Markers before first are not visible.
586 m->setVisible(false);
573 m->setVisible(false);
587 } else {
574 } else {
588 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
575 if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) {
589 // This marker would go outside legend rect.
576 // This marker would go outside legend rect.
590 m->setVisible(false);
577 m->setVisible(false);
591 } else {
578 } else {
592 // This marker is ok
579 // This marker is ok
593 m->setVisible(true);
580 m->setVisible(true);
594 m->setPos(x, y);
581 m->setPos(x, y);
595 y += yStep;
582 y += yStep;
596 row++;
583 row++;
597 }
584 }
598 }
585 }
599 maxRows = row;
586 maxRows = row;
600 }
587 }
601
588
602 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
589 m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin);
603 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
590 m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin);
604
591
605 totalWidth += markerMaxSize.width() + m_margin * 2;
592 totalWidth += markerMaxSize.width() + m_margin * 2;
606 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
593 totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this
607 break;
594 break;
608 }
595 }
609 default: {
596 default: {
610 break;
597 break;
611 }
598 }
612 }
599 }
613
600
614 m_size.setWidth(totalWidth);
601 m_size.setWidth(totalWidth);
615 m_size.setHeight(totalHeight);
602 m_size.setHeight(totalHeight);
616
603
617 update();
604 update();
618 }
605 }
619
606
620 /*!
607 /*!
621 \internal Sets the size of scroll buttons to \a size
608 \internal Sets the size of scroll buttons to \a size
622 */
609 */
623 void QLegend::rescaleScrollButtons(const QSize &size)
610 void QLegend::rescaleScrollButtons(const QSize &size)
624 {
611 {
625 QPolygonF left;
612 QPolygonF left;
626 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
613 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
627 QPolygonF right;
614 QPolygonF right;
628 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
615 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
629 QPolygonF up;
616 QPolygonF up;
630 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
617 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
631 QPolygonF down;
618 QPolygonF down;
632 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
619 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
633
620
634 m_scrollButtonLeft->setPolygon(left);
621 m_scrollButtonLeft->setPolygon(left);
635 m_scrollButtonRight->setPolygon(right);
622 m_scrollButtonRight->setPolygon(right);
636 m_scrollButtonUp->setPolygon(up);
623 m_scrollButtonUp->setPolygon(up);
637 m_scrollButtonDown->setPolygon(down);
624 m_scrollButtonDown->setPolygon(down);
638 }
625 }
639
626
640 /*!
627 /*!
641 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
628 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
642 */
629 */
643 QSizeF QLegend::maximumMarkerSize()
630 QSizeF QLegend::maximumMarkerSize()
644 {
631 {
645 QSizeF max(0,0);
632 QSizeF max(0,0);
646 foreach (LegendMarker* m, m_markers) {
633 foreach (LegendMarker* m, m_markers) {
647 if (m->boundingRect().width() > max.width())
634 if (m->boundingRect().width() > max.width())
648 max.setWidth(m->boundingRect().width());
635 max.setWidth(m->boundingRect().width());
649 if (m->boundingRect().height() > max.height())
636 if (m->boundingRect().height() > max.height())
650 max.setHeight(m->boundingRect().height());
637 max.setHeight(m->boundingRect().height());
651 }
638 }
652 return max;
639 return max;
653 }
640 }
654
641
655 /*!
642 /*!
656 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
643 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
657 If scrollbuttons are visible, they affect the number of visible markers.
644 If scrollbuttons are visible, they affect the number of visible markers.
658 */
645 */
659 void QLegend::checkFirstMarkerBounds()
646 void QLegend::checkFirstMarkerBounds()
660 {
647 {
661 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
648 if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
662 // Bounds limited by height.
649 // Bounds limited by height.
663 int max;
650 int max;
664 if (scrollButtonsVisible()) {
651 if (scrollButtonsVisible()) {
665 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
652 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
666 } else {
653 } else {
667 max = m_maximumSize.height() / maximumMarkerSize().height();
654 max = m_maximumSize.height() / maximumMarkerSize().height();
668 }
655 }
669
656
670 if (mFirstMarker > m_markers.count() - max)
657 if (mFirstMarker > m_markers.count() - max)
671 mFirstMarker = m_markers.count() - max;
658 mFirstMarker = m_markers.count() - max;
672 } else {
659 } else {
673 // Bounds limited by width
660 // Bounds limited by width
674 int max;
661 int max;
675 if (scrollButtonsVisible()) {
662 if (scrollButtonsVisible()) {
676 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
663 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
677 } else {
664 } else {
678 max = m_maximumSize.width() / maximumMarkerSize().width();
665 max = m_maximumSize.width() / maximumMarkerSize().width();
679 }
666 }
680
667
681 if (mFirstMarker > m_markers.count() - max)
668 if (mFirstMarker > m_markers.count() - max)
682 mFirstMarker = m_markers.count() - max;
669 mFirstMarker = m_markers.count() - max;
683 }
670 }
684
671
685 if (mFirstMarker < 0)
672 if (mFirstMarker < 0)
686 mFirstMarker = 0;
673 mFirstMarker = 0;
687 }
674 }
688
675
689 /*!
676 /*!
690 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
677 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
691 */
678 */
692 bool QLegend::scrollButtonsVisible()
679 bool QLegend::scrollButtonsVisible()
693 {
680 {
694 // Just a helper to clarify, what the magic below means :)
681 // Just a helper to clarify, what the magic below means :)
695 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
682 if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) {
696 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
683 return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width());
697 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
684 } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) {
698 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
685 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
699 }
686 }
700
687
701 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
688 return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height());
702 }
689 }
703
690
704 #include "moc_qlegend.cpp"
691 #include "moc_qlegend.cpp"
705
692
706 QTCOMMERCIALCHART_END_NAMESPACE
693 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,111 +1,116
1 #ifndef QLEGEND_H
1 #ifndef QLEGEND_H
2 #define QLEGEND_H
2 #define QLEGEND_H
3
3
4 #include <qchartglobal.h>
4 #include <QChartGlobal>
5 #include <QGraphicsObject>
5 #include <QGraphicsWidget>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class Domain;
11 class Domain;
12 class LegendMarker;
12 class LegendMarker;
13 class QPieSlice;
13 class QPieSlice;
14 class QXYSeries;
14 class QXYSeries;
15 class QBarSet;
15 class QBarSet;
16 class QBarSeries;
16 class QBarSeries;
17 class QPieSeries;
17 class QPieSeries;
18 class LegendScrollButton;
18 class LegendScrollButton;
19 class QSeries;
19 class QSeries;
20 class QChart;
20
21
21 // TODO: This as widget
22 // TODO: This as widget
22 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
23 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
23 {
24 {
24 Q_OBJECT
25 Q_OBJECT
25 public:
26 public:
26
27
27 // We only support these alignments (for now)
28 // We only support these alignments (for now)
28 enum Layout {
29 enum Layout {
29 LayoutTop = Qt::AlignTop,
30 LayoutTop = Qt::AlignTop,
30 LayoutBottom = Qt::AlignBottom,
31 LayoutBottom = Qt::AlignBottom,
31 LayoutLeft = Qt::AlignLeft,
32 LayoutLeft = Qt::AlignLeft,
32 LayoutRight = Qt::AlignRight
33 LayoutRight = Qt::AlignRight
33 };
34 };
35 private:
36 explicit QLegend(QChart *chart);
34
37
35 explicit QLegend(QGraphicsItem *parent = 0);
38 public:
36
37 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
39 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
38 QRectF boundingRect() const;
40 QRectF boundingRect() const;
39
41
40 void setBrush(const QBrush &brush);
42 void setBrush(const QBrush &brush);
41 QBrush brush() const;
43 QBrush brush() const;
42
44
43 void setPen(const QPen &pen);
45 void setPen(const QPen &pen);
44 QPen pen() const;
46 QPen pen() const;
45
47
46 void setAlignmnent(QLegend::Layout alignment);
48 void setAlignmnent(QLegend::Layout alignment);
47 QLegend::Layout alignment() const;
49 QLegend::Layout alignment() const;
48
50
49 QSizeF maximumSize() const;
51 QSizeF maximumSize() const;
50 void setMaximumSize(const QSizeF size);
52 void setMaximumSize(const QSizeF size);
51
53
52 QSizeF size() const;
54 QSizeF size() const;
53 void setSize(const QSizeF size);
55 void setSize(const QSizeF size);
54 void setPos(const QPointF &pos);
56 void setPos(const QPointF &pos);
55
57
58 void scrollButtonClicked(LegendScrollButton *scrollButton);
59
56 Q_SIGNALS:
60 Q_SIGNALS:
57 // for interactions.
61 // for interactions.
58 void clicked(QSeries *series, Qt::MouseButton button);
62 void clicked(QSeries *series, Qt::MouseButton button);
59 void clicked(QBarSet *barset, Qt::MouseButton button);
63 void clicked(QBarSet *barset, Qt::MouseButton button);
60 void clicked(QPieSlice *slice, Qt::MouseButton button);
64 void clicked(QPieSlice *slice, Qt::MouseButton button);
61
65
62 public Q_SLOTS:
66 public Q_SLOTS:
63 // PIMPL --->
67 // PIMPL --->
64 void handleSeriesAdded(QSeries *series, Domain *domain);
68 void handleSeriesAdded(QSeries *series, Domain *domain);
65 void handleSeriesRemoved(QSeries *series);
69 void handleSeriesRemoved(QSeries *series);
66 void handleAdded(QList<QPieSlice *> slices);
70 void handleAdded(QList<QPieSlice *> slices);
67 void handleRemoved(QList<QPieSlice *> slices);
71 void handleRemoved(QList<QPieSlice *> slices);
68 void handleMarkerDestroyed();
72 void handleMarkerDestroyed();
69 void handleScrollButtonClicked(QGraphicsSceneMouseEvent *event);
73
70 // PIMPL <---
74 // PIMPL <---
71
75
72 private:
76 private:
73 // PIMPL --->
77 // PIMPL --->
74 void connectSeries(QSeries *series);
78 void connectSeries(QSeries *series);
75 void disconnectSeries(QSeries *series);
79 void disconnectSeries(QSeries *series);
76 void createMarkers(QSeries *series);
80 void createMarkers(QSeries *series);
77 void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now
81 void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now
78 void appendMarkers(QBarSeries *series);
82 void appendMarkers(QBarSeries *series);
79 void appendMarkers(QPieSeries *series);
83 void appendMarkers(QPieSeries *series);
80 void deleteMarkers(QSeries *series);
84 void deleteMarkers(QSeries *series);
81 void updateLayout();
85 void updateLayout();
82 void rescaleScrollButtons(const QSize &size);
86 void rescaleScrollButtons(const QSize &size);
83 QSizeF maximumMarkerSize();
87 QSizeF maximumMarkerSize();
84 void checkFirstMarkerBounds();
88 void checkFirstMarkerBounds();
85 bool scrollButtonsVisible();
89 bool scrollButtonsVisible();
86
90
87 qreal m_margin;
91 qreal m_margin;
88 QPointF m_pos;
92 QPointF m_pos;
89 QSizeF m_minimumSize;
93 QSizeF m_minimumSize;
90 QSizeF m_maximumSize;
94 QSizeF m_maximumSize;
91 QSizeF m_size;
95 QSizeF m_size;
92
96
93 QList<LegendMarker *> m_markers;
97 QList<LegendMarker *> m_markers;
94
98
95 QBrush m_brush;
99 QBrush m_brush;
96 QPen m_pen;
100 QPen m_pen;
97 QLegend::Layout m_alignment;
101 QLegend::Layout m_alignment;
98
102
99 int mFirstMarker;
103 int mFirstMarker;
100
104
101 LegendScrollButton *m_scrollButtonLeft;
105 LegendScrollButton *m_scrollButtonLeft;
102 LegendScrollButton *m_scrollButtonRight;
106 LegendScrollButton *m_scrollButtonRight;
103 LegendScrollButton *m_scrollButtonUp;
107 LegendScrollButton *m_scrollButtonUp;
104 LegendScrollButton *m_scrollButtonDown;
108 LegendScrollButton *m_scrollButtonDown;
105
109
110 friend class QChart;
106 // <--- PIMPL
111 // <--- PIMPL
107 };
112 };
108
113
109 QTCOMMERCIALCHART_END_NAMESPACE
114 QTCOMMERCIALCHART_END_NAMESPACE
110
115
111 #endif // QLEGEND_H
116 #endif // QLEGEND_H
General Comments 0
You need to be logged in to leave comments. Login now